picorv32 risc-v 在 vivado 2018.2 中的实现
picorv32 risc-v implementation in vivado 2018.2
这是核心:
https://github.com/cliffordwolf/picorv32
我在 vivado 中实现核心时遇到问题。
我已经安装了 riscv gnu 工具链,我确信它工作正常,我修改了 Makefile ($TOOLCHAINPREFIX)。
我 运行 makfile 的 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 上输出零和一,并且在两者之间有一个小的延迟以使电路板的 LED 闪烁。
然而,de LED 不闪烁,唯一的影响是当我按下复位按钮时陷阱信号打开(我将复位放在 FPGA 的按钮 0 上,陷阱信号放在绿色 LED 0 上).
所以,无论我做什么,唯一的结果是当我按下重置键时我的绿色 LED 亮起,仅此而已。
我可能遗漏了什么...
请帮助我,我不知道如何解决这个问题!
提前致谢!
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
我还尝试通过 while(1) 在 LED 上写入 0xFF 来点亮 LED,但这也不起作用:
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,输出字节的蓝色 LED 仅在模式 0x0F 中点亮(二进制为 00001111,因此只有后者8 点亮)
肯定是哪里出了问题,我好像没查出来。
如果您尝试使用 64 位编译器(如大多数发行版提供的那样)为 32 位 RISC-V rv32i 内核构建代码,那么您需要添加 -mabi=ilp32 -march=rv32i
以将其置于 rv32i 模式.
如果您使用 "linux" 变体编译器来创建裸机二进制文件,则需要在 [=12] 之后使用 ,--build-id=none
删除构建 ID(这会破坏平面二进制输出) =].
这是核心: https://github.com/cliffordwolf/picorv32
我在 vivado 中实现核心时遇到问题。 我已经安装了 riscv gnu 工具链,我确信它工作正常,我修改了 Makefile ($TOOLCHAINPREFIX)。
我 运行 makfile 的 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 上输出零和一,并且在两者之间有一个小的延迟以使电路板的 LED 闪烁。
然而,de LED 不闪烁,唯一的影响是当我按下复位按钮时陷阱信号打开(我将复位放在 FPGA 的按钮 0 上,陷阱信号放在绿色 LED 0 上).
所以,无论我做什么,唯一的结果是当我按下重置键时我的绿色 LED 亮起,仅此而已。
我可能遗漏了什么...
请帮助我,我不知道如何解决这个问题!
提前致谢!
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
我还尝试通过 while(1) 在 LED 上写入 0xFF 来点亮 LED,但这也不起作用:
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,输出字节的蓝色 LED 仅在模式 0x0F 中点亮(二进制为 00001111,因此只有后者8 点亮) 肯定是哪里出了问题,我好像没查出来。
如果您尝试使用 64 位编译器(如大多数发行版提供的那样)为 32 位 RISC-V rv32i 内核构建代码,那么您需要添加 -mabi=ilp32 -march=rv32i
以将其置于 rv32i 模式.
如果您使用 "linux" 变体编译器来创建裸机二进制文件,则需要在 [=12] 之后使用 ,--build-id=none
删除构建 ID(这会破坏平面二进制输出) =].