0

First I synthesized a CPU that supports RISCV32IM using verilog, but I can't test if the CPU is working properly. I hope a compiler(such as GCC) can generate instructions to help me test, but normal compilers can only generate EXE files that require the operating system. Obviously, my FPGA can't do this.

I only need a series of RISCV32IM instructions that can run on FPGA and can implement the corresponding functions. If I can, I want his first instruction to be the program entry, which will save me energy.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • The easiest way to get a working rv32im toolchain is to follow the instructions from PicoRV32 readme, there is a scrip tthat'll do everything for you: https://github.com/YosysHQ/picorv32#building-a-pure-rv32i-toolchain – SK-logic Dec 13 '22 at 10:06

1 Answers1

0

Of course you can it is somewhat trivial, you did or someone selected baremetal tab for you, it is a baremetal program I assume you want to run.

so.s

lui x2,0x22222
lui x3,0x33333
lui x4,0x44444
lui x5,0x55555
lui x6,0x66666
j .

riscv32-none-elf-as so.s -o so.o
riscv32-none-elf-objdump -d -Mnumeric so.o
 
so.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <.text>:
   0:   22222137            lui x2,0x22222
   4:   333331b7            lui x3,0x33333
   8:   44444237            lui x4,0x44444
   c:   555552b7            lui x5,0x55555
  10:   66666337            lui x6,0x66666
  14:   0000006f            j   14 <.text+0x14>

now you can just

riscv32-none-elf-ld -Ttext=0 so.o -o so.elf
riscv32-none-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000000
riscv32-none-elf-objdump -d -Mnumeric so.elf

so.elf:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <__BSS_END__-0x1018>:
   0:   22222137            lui x2,0x22222
   4:   333331b7            lui x3,0x33333
   8:   44444237            lui x4,0x44444
   c:   555552b7            lui x5,0x55555
  10:   66666337            lui x6,0x66666
  14:   0000006f            j   14 <__BSS_END__-0x1004>

but at least with arm and not sure about other binutils targets there are very very old, longstanding bugs in the tools when used like that (get gaps in the binary, etc). So

memmap

MEMORY
{
    hello : ORIGIN = 0x00000000, LENGTH = 0x3000
}

SECTIONS
{
    .text : { *(.text*) } > hello
    .rodata : { *(.rodata*) } > hello
    .bss : { *(.bss*) } > hello
    .data : { *(.data*) } > hello
}

and

riscv32-none-elf-ld -T memmap so.o -o so.elf
riscv32-none-elf-objdump -d -Mnumeric so.elf

so.elf:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <.text>:
   0:   22222137            lui x2,0x22222
   4:   333331b7            lui x3,0x33333
   8:   44444237            lui x4,0x44444
   c:   555552b7            lui x5,0x55555
  10:   66666337            lui x6,0x66666
  14:   0000006f            j   14 <.text+0x14>

so now you have an elf (or exe or whatever) you can

riscv32-none-elf-objcopy so.elf -O binary so.bin
hexdump -C so.bin
00000000  37 21 22 22 b7 31 33 33  37 42 44 44 b7 52 55 55  |7!"".1337BDD.RUU|
00000010  37 63 66 66 6f 00 00 00                           |7cffo...|
00000018

or

riscv32-none-elf-objcopy --srec-forceS3 so.elf -O srec  so.srec
cat so.srec
S00A0000736F2E7372656338
S3150000000037212222B731333337424444B75255554C
S30D00000010376366666F0000000D
S70500000000FA

or

riscv32-none-elf-objcopy so.elf -O ihex  so.ihex
cat so.ihex
:1000000037212222B731333337424444B752555552
:08001000376366666F00000013

and so on.

Then you can also...

so.s

    lui x2,0x00002
    jal notmain
    j .


.globl hello
hello:
    ret

notmain.c

void hello ( unsigned int );
void notmain ( void )
{
    unsigned int r;

    for (r=0;r<32;r++)
    {
        hello(r);
    }
}

build with commands like these

riscv32-none-elf-as -march=rv32im so.s -o so.o
riscv32-none-elf-gcc -O2 -c -fomit-frame-pointer -march=rv32im -mabi=ilp32 notmain.c -o notmain.o
riscv32-none-elf-ld -T memmap so.o notmain.o -o so.elf
riscv32-none-elf-objdump -D -Mnumeric so.elf
riscv32-none-elf-objcopy -O binary so.elf so.bin

giving

Disassembly of section .text:

00000000 <hello-0xc>:
   0:   00002137            lui x2,0x2
   4:   00c000ef            jal x1,10 <notmain>
   8:   0000006f            j   8 <hello-0x4>

0000000c <hello>:
   c:   00008067            ret

00000010 <notmain>:
  10:   ff010113            addi    x2,x2,-16 # 1ff0 <notmain+0x1fe0>
  14:   00812423            sw  x8,8(x2)
  18:   00912223            sw  x9,4(x2)
  1c:   00112623            sw  x1,12(x2)
  20:   00000413            li  x8,0
  24:   02000493            li  x9,32
  28:   00040513            mv  x10,x8
  2c:   00140413            addi    x8,x8,1
  30:   fddff0ef            jal x1,c <hello>
  34:   fe941ae3            bne x8,x9,28 <notmain+0x18>
  38:   00c12083            lw  x1,12(x2)
  3c:   00812403            lw  x8,8(x2)
  40:   00412483            lw  x9,4(x2)
  44:   01010113            addi    x2,x2,16
  48:   00008067            ret

and you can use the .bin file or .srec or whatever you prefer.

basic bare metal stuff...gnu works great for this, very easy to use. llvm/clang is more complicated to figure out but technically will work as well.

I changed the line to

for (r=0;r<3200;r++)

because it was unrolling the loop. I gave up trying to keep track of the ever changing generic llvm tool command line options, so now I build specific for riscv32 and can then use the generic program names as cross tools...

clang -c -march=rv32im so.s -o so.o
clang -c -O2 -march=rv32im notmain.c -o notmain.o
ld.lld -T memmap so.o notmain.o -o so.elf
llvm-objcopy -O binary so.elf so.bin
llvm-objdump -D -Mnumeric so.elf

so.elf: file format elf32-littleriscv

Disassembly of section .text:

00000000 <.text>:
       0: 37 21 00 00   lui x2, 2
       4: ef 00 c0 00   jal 0x10 <notmain>
       8: 6f 00 00 00   j   0x8 <.text+0x8>

0000000c <hello>:
       c: 67 80 00 00   ret

00000010 <notmain>:
      10: 13 01 01 ff   addi    x2, x2, -16
      14: 23 26 11 00   sw  x1, 12(x2)
      18: 23 24 81 00   sw  x8, 8(x2)
      1c: 23 22 91 00   sw  x9, 4(x2)
      20: 13 04 00 00   li  x8, 0
      24: 37 15 00 00   lui x10, 1
      28: 93 04 05 c8   addi    x9, x10, -896

0000002c <.LBB0_1>:
      2c: 13 05 04 00   mv  x10, x8
      30: ef f0 df fd   jal 0xc <hello>
      34: 13 04 14 00   addi    x8, x8, 1
      38: e3 1a 94 fe   bne x8, x9, 0x2c <.LBB0_1>
      3c: 83 20 c1 00   lw  x1, 12(x2)
      40: 03 24 81 00   lw  x8, 8(x2)
      44: 83 24 41 00   lw  x9, 4(x2)
      48: 13 01 01 01   addi    x2, x2, 16
      4c: 67 80 00 00   ret
old_timer
  • 69,149
  • 8
  • 89
  • 168