Author Topic: Custom SoC made with an ICE40 FPGA, and an Assembler  (Read 1387 times)

0 Members and 1 Guest are viewing this topic.

Offline Omega GloryTopic starter

  • Regular Contributor
  • *
  • Posts: 86
  • Country: us
    • Ezra's Robots
Custom SoC made with an ICE40 FPGA, and an Assembler
« on: September 02, 2020, 01:41:43 am »
    This summer between semesters I decided to learn more about FPGAs so I began working on a simple SoC. It consists of an 8-bit CPU, an 80 column VGA graphics card, GPIO and counter/timer peripherals, and a UART, all implemented on an ice40lp8k FPGA. It also comes with an assembler and utilities for loading programs into the internal block memory without having to rerun synthesis and place-and-route.
    The CPU is an 8-bit RISC core, with a Harvard architecture. It has a 16-bit wide instruction memory, an 8-bit wide data memory, and both have a 16-bit address. The CPU has 16 general purpose 8-bit registers along with a 4-bit status register. The processor is not fully pipelined, but does fetch the next instruction while executing the current one. Most instructions execute in a single clock cycle, but a few take two or three. Nextpnr says that it can be clocked up to about 17 or 18MHz, but I've only tested it at 16Mhz.
    The GPU operates in a monochrome 80 column text mode, and outputs a VGA signal at a resolution of 640 by 480 at 60 frames per second. The GPU contains an ASCII buffer which the user can write to in order to display messages on the screen. A control register allows the user to set the text to one of 7 colors, and to enable an interrupt to the CPU which fires every time a frame finishes and enters the blanking period. The GPU uses a 25Mhz clock, because it's to derive the synchronization signals from it.
    The assembler is written in Python, and generates code in two passes of the source file. It can handle things like symbol definitions, and has expression evaluation, and some helpful directives.
    Documentation is in progress, but I made some colorful diagrams of the CPU data-path and the GPU, as well as some diagrams showing how the assembly instructions are encoded in binary. If you're curious you can find more info on my GitHub at: https://github.com/ept221/tinySoC.  I would love to hear what you guys think, good or bad. I'm especially interested in what you think are good features or flaws of the instruction set, and how I might improve if I were to make a design in the future. Also, this was my first serious project in Verilog (or FPGAs for that matter), so if you happen to see something terrible while browsing the source, your criticism would be appreciated.

« Last Edit: September 04, 2020, 12:05:08 am by Omega Glory »
 
The following users thanked this post: paf, edavid, rstofer

Offline Omega GloryTopic starter

  • Regular Contributor
  • *
  • Posts: 86
  • Country: us
    • Ezra's Robots
Re: Custom SoC made for an ICE40 FPGA, with Assembler
« Reply #1 on: September 02, 2020, 02:03:59 am »
Here's a picture of the SoC running a simple demo program, along with the source file, and the debugging output of the assembler. The program polls the UART, and when a char is received, it displays it on the screen, while handling backspaces as delete and displaying a cursor. It also displays each char in binary on the LEDs attached to the GPIO, and echos the char back over the UART. This is a simple demo of most of the features, except it doesn't include the use of counter/timers, or the interrupt system. The Arduino that you see in the picture is only acting as a USB to serial bridge for the FPGA.

Code: [Select]
;******************************************************************************
        .define dir_reg, 0x00
        .define port_reg, 0x01
        .define pin_reg, 0x02

        .define uart_baud, 0x0A
        .define uart_ctrl, 0x0B
        .define uart_buffer, 0x0C

        .define gpu_addr, 0x2000
        .define gpu_ctrl_reg, 0x80
;******************************************************************************

        .code

        ldi r0, 0xff            ; set all gpio to output
        out r0, dir_reg

        ldi r0, 0b00011100      ; setup the gpu
        out r0, gpu_ctrl_reg

        ldi r2, gpu_addr[l]     ; setup the pointer to the v-ram
        ldi r3, gpu_addr[h]

stable: in r0, gpu_ctrl_reg     ; wait for gpu clock to become stable
        ani r0, 0x80
        jz stable

        ldi r0, 103             ; set the baud rate to 9600
        out r0, uart_baud

loop1:  in r0, uart_ctrl        ; poll for full rx buffer
        ani r0, 1
        jz loop1               

        in r0, uart_buffer      ; capture the data

loop2:  in r1, uart_ctrl        ; poll for empty tx buffer
        ani r1, 2
        jz loop2
        out r0, uart_buffer     ; echo the char back over the uart

        out r0, port_reg        ; write the data to the gpio port

        cpi r0, 8               ; check if delete was sent
        jnz normal
       
        ldi r0, 32
        srd r0, p2              ; print space to clear cursor, and move back
        ldi r0, 95
        str r0, p2              ; delete char and print cursor
        jmp loop1

normal: sri r0, p2              ; write the data to the screen
        ldi r0, 95
        str r0, p2
        jmp loop1               ; go get another char
;******************************************************************************
« Last Edit: September 02, 2020, 02:24:43 am by Omega Glory »
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21696
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #2 on: September 02, 2020, 10:18:10 am »
Big project, well done!
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 
The following users thanked this post: Omega Glory

Offline voltsandjolts

  • Supporter
  • ****
  • Posts: 2300
  • Country: gb
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #3 on: September 02, 2020, 10:34:02 am »
Nice project, very well done.
I predict a bright future and an interesting career ahead of you!
 
The following users thanked this post: Omega Glory

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9890
  • Country: us
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #4 on: September 02, 2020, 11:41:31 pm »
This is a great project!  I wonder if there should be a link to this thread from the FPGA forum.
 
The following users thanked this post: Omega Glory

Offline lintweaker

  • Contributor
  • Posts: 23
  • Country: nl
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #5 on: September 03, 2020, 06:57:01 am »
Cool project! Impressive for a first FPGA project.
 
The following users thanked this post: Omega Glory

Offline chickenHeadKnob

  • Super Contributor
  • ***
  • Posts: 1056
  • Country: ca
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #6 on: September 03, 2020, 08:37:43 am »
Nice, you put some love into this. I did not easily see which ice40 and what kind clock rate you are achieving. I would recommend making that prominent in your post and github landing page.   I would assume ice40up5k for the built in memory. I understand this is a slow chip.
 
The following users thanked this post: Omega Glory

Offline Omega GloryTopic starter

  • Regular Contributor
  • *
  • Posts: 86
  • Country: us
    • Ezra's Robots
Re: Custom SoC made with an ICE40 FPGA, and an Assembler
« Reply #7 on: September 03, 2020, 10:24:43 pm »
Okay, good to know, I'll add that information. Right now I'm synthesizing it on an ice40lp8k. The main processor runs at 16MHz, though nextpnr's timing says that I could clock it at about 17 or 18 MHz. I'm not entirely sure what the critical path is, (or how to find it), but I suspect that my control logic is likely the source of some of the longer propagation delays. The GPU is running at 25MHz, because it's convenient for generating the VGA signals. The fact that I had two clocks in the design made it tricky when I had to pass signals from one clock domain to another, but I needed to learn how to do that sometime anyway.
« Last Edit: September 03, 2020, 10:27:40 pm by Omega Glory »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf