5024 views|5 replies

1372

Posts

2

Resources
The OP
 

Anlu SparkRoad Development Board Review (8) MCU Soft-core RISC-V Programming [Copy link]

 

  I have already guessed that the program of Agile RISC-V soft core is placed in the BRAM IP, in units of 32-bit words, and starts from 99 (decimal) of BRAM after reset. The entry address converted into byte address is 0x18C.

  It is more convenient to use .mif files to initialize BRAM, so I slightly modified cpu_gate.v and changed the four EG_LOGIC_BRAM module parameters INIT_FILE to "init1.mif", "init2.mif", "init3.mif", and "init4.mif" respectively, and no longer embedded the data in the .v file in string form.

  As a preparatory work, I also need to write a tool to convert the .bin file generated by the RISC-V compiler into a .mif file. Because this is a special purpose, the 32-bit word needs to be split into four bytes and scattered into four files. Write one in C:

  The first test program tests whether the loop can be executed:

  Compilation instruction: riscv gcc -c -O2 -march=rv32i -mabi=ilp32 test0.c

  Generate ELF file: riscv ld -Ttext 0x18c test0.o -o test0.elf

  Disassemble and view the compilation results: riscv objdump -d test0.elf

test0.elf:     file format elf32-littleriscv

Disassembly of section .text:

0000018c <_start>:
 18c:   00100693                li      a3,1
 190:   00200713                li      a4,2
 194:   00300793                li      a5,3
 198:   00000013                nop
 19c:   10002023                sw      zero,256(zero) # 100 <_start-0x8c>
 1a0:   10d02223                sw      a3,260(zero) # 104 <_start-0x88>
 1a4:   10e02423                sw      a4,264(zero) # 108 <_start-0x84>
 1a8:   10f02623                sw      a5,268(zero) # 10c <_start-0x80>
 1ac:   fedff06f                j       198 <_start+0xc>

  GCC compilation instructions: Because the instruction set implemented by Agile RISC-V is unknown, the most basic 32-bit instruction architecture is used, specified with -march=rv32i. No other code is required when linking. In order to set the _start entry address at 0x18c, the .text segment address is specified as 0x18c.

  Generate .bin file: riscv objcopy -Obinary test0.elf test0.bin

2022-05-07 19:02 36 test0.bin

         1 file 36 bytes

  The program has 9 instructions in total, each 4 bytes. In order to put these 9 instructions at the address 0x18c in RAM, you need to put the program content from the 99th byte when generating the .mif file. This has been done in the conversion program I posted above.

  For example, the generated init1.mif file content is as follows

DEPTH=1024;
WIDTH=8;
ADDRESS_RADIX=UNS;
DATA_RADIX=HEX;

CONTENT BEGIN
0 : 00;
1 : 00;
2 : 00;
3 : 00;
…省略若干行…
97 : 00;
98 : 00;
99 : 93;
100 : 13;
101 : 93;
102 : 13;
103 : 23;
104 : 23;
105 : 23;
106 : 23;
107 : 6F;
END;

  Copy the four .mif files to the FPGA project directory, re-synthesize, and download. Observe the running effect:

  It can be seen that the instruction fetch address starts at 99, increases to 107, then changes to 102, and then loops between 102 and 107. This is consistent with the last instruction (0x1ac) in the code I wrote, which jumps to 0x198. It can be determined that the loop is executed correctly. In the loop, numbers are written to addresses 0x100, 0x104, 0x108, and 0x10c, and the result of this operation cannot be verified yet.

  Next, find the external bus address of the soft core. Because the bus_addr width of the soft core is 28-bit, the data is 32-bit, and the address range is 1GB. First guess that the external bus address is aligned to the 256MB boundary, that is, it starts at an integer multiple of 0x10000000. Write a program to try to write to certain addresses, and then watch the signals on the external bus. If there are address and data outputs and write signals, the address mapping relationship can be inferred.

  Second test program:

  Disassembled code after compilation:

Disassembly of section .text:

0000018c <_start>:
 18c:   01000613                li      a2,16
 190:   00000013                nop
 194:   00000793                li      a5,0
 198:   01c79713                slli    a4,a5,0x1c
 19c:   00578693                addi    a3,a5,5
 1a0:   00d72e23                sw      a3,28(a4)
 1a4:   00178793                addi    a5,a5,1
 1a8:   fec798e3                bne     a5,a2,198 <_start+0xc>
 1ac:   fe5ff06f                j       190 <_start+0x4>

  To observe the bus action, connect to the LED on the board:

  Operation effect:


  Four bus write operations are captured in a large loop. Through the address and data indicated by the LED, it can be determined that the external bus mapping address is in the range of 0x80000000~0xBFFFFFFC. Because there is no bit mask, only 32-bit read and write are supported.

In this way, the external bus can be accessed in the program, and hardware devices can be written in the FPGA for program operation.

  We also need to determine the address of the SRAM in the soft core. The above program does not use SRAM, so it is okay if we do not know its address. Now guess that the SRAM is located at an address below 0x80000000. First search the address aligned with 128MB (a total of 16 addresses) and determine whether it is a readable and writable address: if the written number is consistent with the read number, it is considered that the SRAM exists. Use the external bus output to indicate the valid address found.

  The third test program:

  When running, write external bus address 1, data 0x80. Therefore, SRAM is found when i=0 in the program. Therefore, SRAM is located at the beginning of address 0x0.

  Finally, a test program is used to read the contents of the SRAM and write them to the external bus, so that the contents of the SRAM can be viewed through the LED. Reading the external bus is to read the states of 16 switches, and the SRAM address to be read is selected through the switches.

  Disassembled code:

Disassembly of section .text:

0000018c <_start>:
 18c:   00000793                li      a5,0
 190:   800006b7                lui     a3,0x80000
 194:   00f687b3                add     a5,a3,a5
 198:   0007a783                lw      a5,0(a5)
 19c:   0007c703                lbu     a4,0(a5)
 1a0:   00279793                slli    a5,a5,0x2
 1a4:   00f68633                add     a2,a3,a5
 1a8:   0ff77713                andi    a4,a4,255
 1ac:   00e62023                sw      a4,0(a2)
 1b0:   fe5ff06f                j       194 <_start+0x8>

  Running effect (speeding up the clock to improve response speed)


  It can be found that most of the contents of SRAM are 0, and the value 0x93 is read at the address 0x18c, and the data at several other locations are consistent with the corresponding addresses of the program code. Therefore, it shows that SRAM and the ROM storing the program are the same storage, which also indirectly verifies the purpose of using dual-port BRAM in the soft core: the program and data use the same RAM space.

  Knowing the RAM address and program address, you can write more complex programs.

  This MCU soft core also has GPIO and UART, as well as external interrupt input functions. However, due to the lack of information, it is difficult to find out how to use them.

This post is from Domestic Chip Exchange

Latest reply

Does picorv32 have a jtag interface? I don't think so.   Details Published on 2023-9-4 16:44
 
 

9717

Posts

24

Resources
2
 

Why not try picorv32, someone seems to have ported it.

This post is from Domestic Chip Exchange
 
 
 

2870

Posts

4

Resources
3
 

It seems that picorv32 also has a jtag interface, so there is no need to use the built-in method to write programs

This post is from Domestic Chip Exchange
 
 
 

1372

Posts

2

Resources
4
 

To get pico risc-v, just use any FPGA, which is not in line with the purpose of this review.

This post is from Domestic Chip Exchange
 
 
 

13

Posts

0

Resources
5
 

The boss is so strong. There are not many development boards that can be used for RISCV chips.

This post is from Domestic Chip Exchange
 
 
 

1

Posts

0

Resources
6
 
bigbat posted on 2022-5-13 16:35 picorv32 seems to have a jtag interface, so there is no need to use the built-in method to write programs

Does picorv32 have a jtag interface? I don't think so.

This post is from Domestic Chip Exchange
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list