Реализация picorv32 risc-v в vivado 2018.2

Это ядро: https://github.com/cliffordwolf/picorv32

У меня проблема с реализацией ядра в vivado. Я установил набор инструментов riscv gnu и уверен, что он работает нормально, я изменил Makefile ($ TOOLCHAINPREFIX).

Я запустил make firmware.hex из мак-файла (из папки scripts / vivado), а затем выполнил команду make synth_system, чтобы запустить synth_system.tcl в vivado и сгенерировать поток битов для моего fpga.

Моя fpga - это плата для разработки arty a7-35t, и я изменил файл ограничений synth_system.xdc, чтобы он соответствовал выводам arty a7, а не basys 3 (как по умолчанию). Я также изменил название платы в скрипте .tcl. Я также модифицировал firmware.c, чтобы выводить только нули и единицы по адресу 0x10000000 и с небольшой задержкой между ними, чтобы светодиоды платы мигали.

Однако светодиоды де не мигают, и единственный недостаток заключается в том, что сигнал ловушки включается, когда я нажимаю кнопку сброса (я кладу сброс на button0 ПЛИС, а сигнал ловушки на зеленый светодиод 0).

Итак, что бы я ни делал, единственный результат - это то, что у меня загорается зеленый светодиод, когда я нажимаю сброс, и все.

Возможно, я что-то упускаю ...

Пожалуйста, помогите мне, я не знаю, что делать, чтобы это исправить!

Заранее спасибо !

P.S. Прикрепляю модифицированные файлы из папки scripts / vivado.

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

Я также пытался зажечь светодиоды только при (1) написании на них 0xFF, но это тоже не сработало:

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;
    }

}

Вывод: хотя программа .C пишет по адресу 0x1000_0000, синие светодиоды для выходного байта светятся только в шаблоне 0x0F (00001111 в двоичном формате, поэтому светятся только последние 8) Что-то должно быть не так, я не Кажется, я не понимаю, что именно.


person Andrei_Vasile_Avram    schedule 18.05.2020    source источник
comment
Я настоятельно рекомендую сначала попробовать симуляцию дизайна.   -  person gatecat    schedule 18.05.2020
comment
Кроме того, на какой префикс инструментальной цепочки вы его изменили? Если это gcc типа linux, вам нужно будет добавить ,--build-id=none после -Wl в команде сборки микропрограммы.   -  person gatecat    schedule 18.05.2020
comment
TOOLCHAIN_PREFIX = riscv64-unknown-linux-gnu- `` firmware.hex: firmware.S firmware.c firmware.lds $ (TOOLCHAIN_PREFIX) gcc -Os -ffreestanding -nostdlib -o firmware.elf firmware.S firmware.c \ - -std = gnu99 -Wl, -Bstatic, -T, firmware.lds, -Map, firmware.map, - strip-debug -lgcc $ (TOOLCHAIN_PREFIX) objcopy -O binary firmware.elf firmware.bin python3 ../. ./firmware/makehex.py firmware.bin 4096 ›firmware.hex` `` `Это из make-файла, который я использую для создания файла firmware.hex. Использую на ubuntu 19.   -  person Andrei_Vasile_Avram    schedule 18.05.2020
comment
Кроме того, все скрипты, которые я использовал, находятся в папке scripts / vivado репозитория, остальные вызываются в скрипте tcl или в make-файле из папки scripts / vivado   -  person Andrei_Vasile_Avram    schedule 18.05.2020
comment
Поскольку вы используете linux набор инструментов, попробуйте build-id=none трюк, описанный выше, и посмотрите, поможет ли он.   -  person gatecat    schedule 18.05.2020
comment
Я попробовал, решение build-id = none, также попытался выполнить проект vivado вручную, чтобы посмотреть, не изменится ли что-нибудь. Никаких изменений в поведении ...   -  person Andrei_Vasile_Avram    schedule 18.05.2020
comment
Можете выложить свой firmware.hex на pastebin или аналогичный?   -  person gatecat    schedule 18.05.2020
comment
pastebin.com/FDYrd1CN Я прикрепил файлы .lds и .s, которые необходимы для создания .hex из. c файл.   -  person Andrei_Vasile_Avram    schedule 18.05.2020
comment
Я думаю, вам также нужно добавить -mabi=ilp32 -march=rv32i в командную строку gcc, поскольку вы используете 64-битный компилятор и вам нужно установить его в 32-битный режим rv32i.   -  person gatecat    schedule 18.05.2020
comment
Да, это ответ, теперь он работает как мечта. Код не был правильно синтезирован. Не могли бы вы сформулировать это как ответ на проблему для всех, кто использует riscv64? Спасибо !   -  person Andrei_Vasile_Avram    schedule 18.05.2020
comment
рад что работает, ответ добавил.   -  person gatecat    schedule 19.05.2020


Ответы (1)


Если вы пытаетесь создать код для 32-разрядного ядра RISC-V rv32i с использованием 64-разрядного компилятора (как предусмотрено в большинстве дистрибутивов), вам необходимо добавить -mabi=ilp32 -march=rv32i, чтобы перевести его в режим rv32i.

Если вы используете компилятор варианта "linux" для создания двоичного файла с нуля, вам необходимо удалить идентификатор сборки (который нарушает плоский двоичный вывод), используя ,--build-id=none после -Wl.

person gatecat    schedule 18.05.2020