1

Counting on my RISC-V FPGA CPU

 1 year ago
source link: https://smist08.wordpress.com/2023/03/08/counting-on-my-risc-v-fpga-cpu/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Introduction

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 soc.sv 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)
    begin
        if(MemWrite) begin
            case(DataAdr)
                16'h100: encoded = WriteData;
            endcase
            led[7:0] = WriteData[7:0];  
            led[15:8] = DataAdr[7:0];
        end
    end

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.

rarssource.png?w=1024

rarsexe.png?w=1024

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.

Utilization

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 |
+----------------------------+------+-------+------------+-----------+-------+

Summary

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.

Loading...

Related

RISC-V on a Basys 3 FPGA Development BoardFebruary 17, 2023In "assembly language"

Battling US Export ControlsJanuary 15, 2023In "Business"

Introduction to FPGAsFebruary 4, 2023In "Electronics"


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK