picorv32 risc-v implementation in vivado 2018.2

0

This is the core: https://github.com/cliffordwolf/picorv32

I'm having a problem implementing the core in vivado. I have installed the riscv gnu toolchain and I am sure that it works ok, I modified the Makefile ($TOOLCHAINPREFIX).

I ran the makfile's make firmware.hex (from the scripts/vivado folder) and then I ran the make synth_system command to run synth_system.tcl in vivado and generate the bitstream for my fpga.

My fpga is an arty a7-35t development board and I have modified the synth_system.xdc constraints file to match the arty a7 pins and not the basys 3 (like it is by default). I also changed the name of the board in the .tcl script. I also modified the firmware.c to only output zeros and ones on the adress 0x10000000 and with a small delay in between to blink the board's LED's.

However, de LED's don't blink, and the only efect is that the trap signal is on when I press the reset button (I put the reset on button0 of the FPGA and the trap signal on the green led 0).

So, whatever I do, the only result is the fact that I get a green LED light up when I press reset and that's all.

I may be missing something...

Please help me, I do not know what to do to fix this !

Thank you in advance !

P.S. I'm attaching the modified files from the scripts/vivado folder.

////////////////////////
firmware.c
///////////////////
void putc(int c)
{
(volatile int)0x10000000 = c;
}

void puts(const char *s)
{
while (*s) putc(*s++);
}

void *memcpy(void dest, const void src, int n)
{
while (n) {
n--;
((char)dest)[n] = ((char)src)[n];
}
return dest;
}

int message1=0xFFFFFFFF;
int message2=0x00000000;
int flag=1;

void main()
{

while(1)
{ 
    if(flag)
    {
        //putc(message2);
        *(volatile int*)0x10000000 = message2;
        flag=0;
    }
    else
    {   
        *(volatile int*)0x10000000 = message1;
        //putc(message1);
        flag=1;

    }

    for (long int i = 0; i=500000; i++);

}
}
////////////////////////////////////
synth_system.tcl
///////////////////////////////////

read_verilog system.v
read_verilog ../../picorv32.v
read_xdc synth_system.xdc

synth_design -part xc7a35ti-csg324-1L -top system
opt_design
place_design
route_design

report_utilization
report_timing

write_verilog -force synth_system.v
write_bitstream -force synth_system.bit
//////////////////////////////////////////////
synth_system.xdc
/////////////////////////////////////

XDC File for Arty A7 Board
###########################

set_property PACKAGE_PIN E3 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
create_clock -period 10.00 [get_ports clk]

Blue from RGB LEDS and also regular LEDS from Arty A7
set_property PACKAGE_PIN E1 [get_ports {out_byte[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[0]}]
set_property PACKAGE_PIN G4 [get_ports {out_byte[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[1]}]
set_property PACKAGE_PIN H4 [get_ports {out_byte[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[2]}]
set_property PACKAGE_PIN K2 [get_ports {out_byte[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[3]}]
set_property PACKAGE_PIN H5 [get_ports {out_byte[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[4]}]
set_property PACKAGE_PIN J5 [get_ports {out_byte[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[5]}]
set_property PACKAGE_PIN T9 [get_ports {out_byte[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[6]}]
set_property PACKAGE_PIN T10 [get_ports {out_byte[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[7]}]

first is buton 0 trap and out_byte_en is on green LEDS from the RGB leds
set_property PACKAGE_PIN D9 [get_ports {resetn}]
set_property IOSTANDARD LVCMOS33 [get_ports {resetn}]
set_property PACKAGE_PIN F6 [get_ports {trap}]
set_property IOSTANDARD LVCMOS33 [get_ports {trap}]
set_property PACKAGE_PIN J4 [get_ports {out_byte_en}]
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte_en}]

set_property CONFIG_VOLTAGE 3.3 [current_design]
#where value2 is the voltage provided to configuration bank 0

set_property CFGBVS VCCO [current_design]
#where value1 is either VCCO or GND

//////////////////////////////////////////////////////////////////

I also modified the code for system.v to see if the project works at all.
end else begin
//////////////////
last part of system.v
//////////////////////
always @(posedge clk) begin
m_read_en <= 0;
mem_ready <= mem_valid && !mem_ready && m_read_en;

        m_read_data <= memory[mem_addr >> 2];
        mem_rdata <= m_read_data;

        out_byte_en <= 0;
                    out_byte<=8'h0F;  ////MODIFIED PART
        (* parallel_case *)
        case (1)
            mem_valid && !mem_ready && !mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin
                m_read_en <= 1;
            end
            mem_valid && !mem_ready && |mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin
                if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
                if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
                if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
                if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
                mem_ready <= 1;
            end
            mem_valid && !mem_ready && |mem_wstrb && mem_addr == 32'h1000_0000: begin
                out_byte_en <= 1;
                out_byte <= 8'h01;  ///////////MODIFIED PART
                mem_ready <= 1;
            end
        endcase
    end
end endgenerate
endmodule

I also tried to only lit the LEDs by while(1) writing 0xFF on them but that did not work either:

void putc(int c)
{
    *(volatile int*)0x10000000 = c;
}

void puts(const char *s)
{
    while (*s) putc(*s++);
}

void *memcpy(void *dest, const void *src, int n)
{
    while (n) {
        n--;
        ((char*)dest)[n] = ((char*)src)[n];
    }
    return dest;
}

int message1=0xFFFFFFFF;
int message2=0x00000000;
int flag=1;

void main()
{
    while(1)
    {
    *(volatile int*)0x10000000 = message1;
    }

}

Conclusion: even though the .C program writes at adress 0x1000_0000, the blue leds for the out byte only lit up in the pattern 0x0F (00001111 in binary, so only the latter 8 lit up) Something must be wrong, I don't seem to find out what.

c++
c
verilog
hdl
vivado
asked on Stack Overflow May 18, 2020 by Andrei_Vasile_Avram • edited May 18, 2020 by Andrei_Vasile_Avram

1 Answer

0

If you are trying to build code for a 32-bit RISC-V rv32i core using a 64-bit compiler (as most distributions provide) then you need to add -mabi=ilp32 -march=rv32i to put it into rv32i mode.

If you are using a "linux" variant compiler to create a bare metal binary, you need to remove the build ID (which breaks the flat binary output) by using ,--build-id=none after -Wl.

answered on Stack Overflow May 18, 2020 by David Shah

User contributions licensed under CC BY-SA 3.0