【国产FPGA评测】安路 基于RISC-V内核驱动OLED、AHB总线和DDS的程序以及问题.
[复制链接]
在前面的几篇测评中对基于SF1 RISC-V使用C语言和基于FPGA的Verilog驱动OLED、使用FPGA设计了DDS模块,之前纯粹由FPGA侧完成OLED驱动和DDS模块设计的程序,将DDS模块产生的频率和幅度信号传递到OLED部分导致综合出来的程序无法正常运行。这次在完成PS侧驱动OLED屏幕后,想再次尝试一下,在PS完成OLED部分的功能(虽然失败了)。
1.如何从PL向PS侧传递数据
在官方的直播中,安路的工程师介绍了通过AHB总线在PS侧读取PL侧数据的示例,参考官方的例程添加自己的工程中,相关的代码如下:
/*
* pl_register_control.h
*
*/
#ifndef APPLICATION_INC_PL_REGISTER_CONTROL_H_
#define APPLICATION_INC_PL_REGISTER_CONTROL_H_
#include "nuclei.h"
#define AHB_REGISTER_BASE_ADDR 0x40000000
volatile uint32_t *PL_VERSION = AHB_REGISTER_BASE_ADDR + 0x0;
volatile uint32_t *PL_LED = AHB_REGISTER_BASE_ADDR + 0x4;
#define pl_version *PL_VERSION
#define pl_led *PL_LED
#endif /* APPLICATION_INC_PL_REGISTER_CONTROL_H_ */
int main(void)
{
all_io_config();
OLED_Init();
while(1)
{
for(int i=0; i<LEDn; i++)
{
gpio_toggle(GPIO,LED_CLORK[i]);
delay_1ms(1000);
anl_printf("gpio_toggle %d\r\n",pl_version);
OLED_Clear();
OLED_ShowString(0,0,"DDS Demo",12,1);
OLED_ShowString(0,12,"Freq:",12,1);
OLED_ShowString(0,24,"Amp:",12,1);
OLED_ShowNum(0,36,pl_version,9,12,1);
delay_1ms(1000);
OLED_Refresh();
}
}
return 0;
}
在FPGA侧相关的代码如下:
module ahb_to_register (
input I_ahb_clk,
input I_rst,
input [1:0] I_ahb_htrans,
input I_ahb_hwrite,
input [31:0] I_ahb_haddr, //synthesis keep
input [2:0] I_ahb_hsize,
input [2:0] I_ahb_hburst,
input [3:0] I_ahb_hprot,
input I_ahb_hmastlock,
input [31:0] I_ahb_hwdata, //synthesis keep
output reg [31:0] O_ahb_hrdata, //synthesis keep
output wire[1:0] O_ahb_hresp,
output reg O_ahb_hready,
input wire[31:0] I_pl_version, ///0x0
output wire O_pl_led ///0x4
);
reg S_ahb_wr_trig;
reg S_ahb_wr_trig_1d;
reg[31:0] S_ahb_wr_addr;
reg[31:0] S_ahb_wr_data;
reg S_ahb_rd_trig;
reg S_ahb_rd_trig_1d;
reg[31:0] S_ahb_rd_addr;
reg[31:0] S_ahb_rd_data;
reg[31:0] S_reg_0;
reg[31:0] S_reg_1;
reg[31:0] S_reg_2;
reg[31:0] S_reg_3;
reg[31:0] S_reg_4;
reg[31:0] S_reg_5;
reg[31:0] S_reg_6;
reg[31:0] S_reg_7;
reg[31:0] S_reg_8;
reg[31:0] S_reg_9;
reg[31:0] S_reg_10;
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
O_ahb_hready <= 1'b1;
else
if(I_ahb_htrans == 2'b10)
O_ahb_hready <= 1'b0;
else if(S_ahb_wr_trig_1d || S_ahb_rd_trig_1d)
O_ahb_hready <= 1'b1;
else
O_ahb_hready <= O_ahb_hready;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
S_ahb_wr_trig <= 1'b0;
else
if(I_ahb_htrans == 2'b10 && I_ahb_hwrite)
S_ahb_wr_trig <= 1'b1;
else
S_ahb_wr_trig <= 1'b0;
end
always @(posedge I_ahb_clk) begin
S_ahb_wr_trig_1d <= S_ahb_wr_trig;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
S_ahb_wr_addr <= 'd0;
else
if(S_ahb_wr_trig)
S_ahb_wr_addr <= I_ahb_haddr;
else
S_ahb_wr_addr <= S_ahb_wr_addr;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
S_ahb_wr_data <= 'd0;
else
if(S_ahb_wr_trig)
S_ahb_wr_data <= I_ahb_hwdata;
else
S_ahb_wr_data <= S_ahb_wr_data;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
begin
S_reg_0 <= 'd0;
S_reg_1 <= 'd0;
S_reg_2 <= 'd0;
S_reg_3 <= 'd0;
S_reg_4 <= 'd0;
S_reg_5 <= 'd0;
S_reg_6 <= 'd0;
S_reg_7 <= 'd0;
S_reg_8 <= 'd0;
S_reg_9 <= 'd0;
S_reg_10 <= 'd0;
end
else
begin
if(S_ahb_wr_trig_1d)
begin
case(S_ahb_wr_addr[7:0])
8'h00: S_reg_0 <= S_ahb_wr_data;
8'h04: S_reg_1 <= S_ahb_wr_data;
8'h08: S_reg_2 <= S_ahb_wr_data;
8'h0C: S_reg_3 <= S_ahb_wr_data;
8'h10: S_reg_4 <= S_ahb_wr_data;
8'h14: S_reg_5 <= S_ahb_wr_data;
8'h18: S_reg_6 <= S_ahb_wr_data;
8'h1C: S_reg_7 <= S_ahb_wr_data;
8'h20: S_reg_8 <= S_ahb_wr_data;
8'h24: S_reg_9 <= S_ahb_wr_data;
8'h28: S_reg_10 <= S_ahb_wr_data;
endcase
end
else
begin
S_reg_0 <= S_reg_0;
S_reg_1 <= S_reg_1;
S_reg_2 <= S_reg_2;
S_reg_3 <= S_reg_3;
S_reg_4 <= S_reg_4;
S_reg_5 <= S_reg_5;
S_reg_6 <= S_reg_6;
S_reg_7 <= S_reg_7;
S_reg_8 <= S_reg_8 ;
S_reg_9 <= S_reg_9 ;
S_reg_10 <= S_reg_10;
end
end
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
S_ahb_rd_trig <= 1'b0;
else
if(I_ahb_htrans == 2'b10 && (!I_ahb_hwrite))
S_ahb_rd_trig <= 1'b1;
else
S_ahb_rd_trig <= 1'b0;
end
always @(posedge I_ahb_clk) begin
S_ahb_rd_trig_1d <= S_ahb_rd_trig;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
S_ahb_rd_addr <= 'd0;
else
if(S_ahb_rd_trig)
S_ahb_rd_addr <= I_ahb_haddr;
else
S_ahb_rd_addr <= S_ahb_rd_addr;
end
always @(posedge I_ahb_clk or posedge I_rst) begin
if(I_rst)
O_ahb_hrdata <= 'd0;
else
begin
if(S_ahb_rd_trig_1d)
begin
case(S_ahb_rd_addr[7:0])
8'h00: O_ahb_hrdata <= I_pl_version;
8'h04: O_ahb_hrdata <= S_reg_1;
8'h08: O_ahb_hrdata <= S_reg_2;
8'h0C: O_ahb_hrdata <= S_reg_3;
8'h10: O_ahb_hrdata <= S_reg_4;
8'h14: O_ahb_hrdata <= S_reg_5;
8'h18: O_ahb_hrdata <= S_reg_6;
8'h1C: O_ahb_hrdata <= S_reg_7;
8'h20: O_ahb_hrdata <= S_reg_8;
8'h24: O_ahb_hrdata <= S_reg_9;
8'h28: O_ahb_hrdata <= S_reg_10;
endcase
end
else
O_ahb_hrdata <= O_ahb_hrdata;
end
end
assign O_pl_led = S_reg_1[0];
endmodule
2.综合工程
将之前写的程序全部统一起来,组成一个缝合怪,还是和之前一样的问题,DDS模块输出的频率和幅度信息,通过AHB总线向PS侧传递数据时,数据传递失败,同时整个程序无法正常运行。
去掉传递频率数据的连接后,程序可以正常运行,万能的坛友或者官方的FAE能看看怎么回事吗?
测评报告10
工程文件
|