Stephen Smith's Blog

Musings on Machine Learning…

Counting on my RISC-V FPGA CPU

with one comment


Last time, I talked about getting a minimal RISC-V CPU up and running on my Basys FPGA development board. In this article, we’ll connect up the seven segment displays as memory mapped I/O and write a simple RISC-V Assembly Language program to count on the display.

Connecting the Seven Segment Display

To support the four seven segment displays, I took the code from the book “FPGA Programming for Beginners” by Frank Bruno, and connected it to the RISC-V CPU from the book “Digital Design and Computer Architecture: RISC-V Edition” by Sarah L. Harris and David Harris. This turned out to be quite easy. Just needed to add a case statement in where if the address is 0x100 then it goes to the seven segment display routine. I chose the rather low address 0x100 since that fits in an immediate argument saving additional code.

  always @(negedge clk_25)
        if(MemWrite) begin
                16'h100: encoded = WriteData;
            led[7:0] = WriteData[7:0];  
            led[15:8] = DataAdr[7:0];

To test this, I needed to write a RISC-V Assembly Language program, only using the instructions that my mini RISC-V CPU supports.

Writing RISC-V Assembly Language

I wrote the simple program:

# Simple program to count on the 7-segment display
      addi x2, x0, 0     #initialize counter to 0
      addi x3, x0, 0x100 # memory address of seven seg display
main: addi x2, x2, 1     # add 1 to counter
      sw x2, (x3)        # save to the display
      addi x4, x0, 0x7ff # delay loop counter
      addi x6, x0, 9     # ready to shift left 9 bits
      sll x4, x4, x6     # shift left 9 bits
      addi x5, x0, 1     # will subtract from x4
loop: sub x4, x4, x5     # decrement counter
      beq x4, x0, next   # loop done, proceed
      beq x4, x4, loop   # repeat loop
next: beq x2, x2, main   # jump back to loop forever

The first version of this didn’t have the delay loop, so was simpler. With this nice Assembly Language source code, I needed a way to assemble it. I googled and found RARS (Risc-V Assembler and Runtime Simulator). RARS compiled the program fine and I could copy the compiled programs to the instruction memory in the SoC source code.

When I first ran the program, it was way too fast and the seven segment display just showed all eights (all segments lit up). So I added a delay loop, but due to the limited instruction set, I could only loop 0x7ff times, this slowed it down so the high order LED counted. I needed a way to create bigger numbers, so I implemented the SLL (shift logical left) instruction, which was easy to add to the ALU. I could have loaded a larger number from memory or could have written an outer loop to have two nested loops, but chose this instead. With this all done it works fairly well.


Below is the utilization report for the hardware resources being used. Notice that with this simple CPU implementation that we are using a small percentage of the available resources. Hence, we have a lot of headroom to keep developing this simple CPU/computer.

|          Site Type         | Used | Fixed | Prohibited | Available | Util% |
| Slice LUTs*                |  347 |     0 |          0 |     20800 |  1.67 |
|   LUT as Logic             |  299 |     0 |          0 |     20800 |  1.44 |
|   LUT as Memory            |   48 |     0 |          0 |      9600 |  0.50 |
|     LUT as Distributed RAM |   48 |     0 |            |           |       |
|     LUT as Shift Register  |    0 |     0 |            |           |       |
| Slice Registers            |   93 |     0 |          0 |     41600 |  0.22 |
|   Register as Flip Flop    |   93 |     0 |          0 |     41600 |  0.22 |
|   Register as Latch        |    0 |     0 |          0 |     41600 |  0.00 |
| F7 Muxes                   |    2 |     0 |          0 |     16300 |  0.01 |
| F8 Muxes                   |    1 |     0 |          0 |      8150 |  0.01 |


Developing a CPU is a lot of work, but a lot of fun. It’s amazing that with a low cost FPGA development board you can design a CPU and start building a computer around it. This was a small increment in my RISC-V CPU, but nice to see that the tools are quite easy to work with to accomplish my goal.


Written by smist08

March 8, 2023 at 6:41 pm

One Response

Subscribe to comments with RSS.

  1. […] Last time, we assembled a small RISC-V program to run on my FPGA RISC-V core running on a Digilent Basys3 development board. To do this we used RARS, which is a quite good Assembler, Debugger, Simulator for RISC-V; in this article I thought I’d point out some other tools available from the official RISC-V github page, including the full GNU C toolchain. […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: