AXI4 Traffic Generator仿真研究与自定义IP(之五) - minichao9901/TangNano-20k-Zynq-7020 GitHub Wiki
- 将自定义的uart_tx/rx ip,用axi4_lite接口封装起来
- 用ATG进行仿真,确认功能正确
- 用mb写软件驱动,确认功能正确
接口部分
// Users to add ports here
input wire rx,
output wire tx,
// User ports ends
信号定义部分,特别要注意,多位宽的wire型一定要定义才能使用,否则会出错。定义要放在开头部分。
wire [7:0] po_data;
wire pi_flag;
wire po_flag;
寄存器读写部分(只需要在寄存器写部分,增加相关逻辑即可)
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
slv_reg0 <= 0;
slv_reg1 <= 0;
slv_reg2 <= 0;
slv_reg3 <= 0;
slv_reg4 <= 0;
slv_reg5 <= 0;
slv_reg6 <= 0;
slv_reg7 <= 0;
end
else if(po_flag) begin //增加的部分
slv_reg1[7:0]<=po_data; //增加的部分
slv_reg2[0]<=1; //增加的部分
end //增加的部分
else begin
if (slv_reg_wren)
模块例化部分
// Add user logic here
uart_rx uart_rx_inst(
.sys_clk(S_AXI_ACLK),
.sys_rst_n(S_AXI_ARESETN),
.rx(rx),
.po_data(po_data),
.po_flag(po_flag)
);
uart_tx uart_tx_inst(
.sys_clk(S_AXI_ACLK),
.sys_rst_n(S_AXI_ARESETN),
.pi_data(slv_reg0[7:0]),
.pi_flag(pi_flag),
.tx(tx)
);
/* tx_reg: reg0
rx_reg: reg1
rx_flag: re2
*/
assign pi_flag=(slv_reg_wren && axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]==2'h0)? 1:0;
- 当时出错了,通过这个仿真找到了错误。这个还是很实用的。
- 另一个问题,不要在底层IP中使用ILA,会导致上层调用IP仿真的时候报错。如果要使用ILA,可以用mark_debug模式,不用修改代码,也能看到底层信号。
引脚定义pin_local.xdc
set_property -dict {PACKAGE_PIN B20 IOSTANDARD LVCMOS33} [get_ports led]
set_property -dict {PACKAGE_PIN D20 IOSTANDARD LVCMOS33} [get_ports done_pulse]
set_property -dict {PACKAGE_PIN H18 IOSTANDARD LVCMOS33} [get_ports {start_pulse[0]}]
set_property -dict {PACKAGE_PIN F20 IOSTANDARD LVCMOS33} [get_ports {start_pulse[1]}]
set_property -dict {PACKAGE_PIN G20 IOSTANDARD LVCMOS33} [get_ports {start_pulse[2]}]
set_property -dict {PACKAGE_PIN H20 IOSTANDARD LVCMOS33} [get_ports {start_pulse[3]}]
# GPIO1-EDA_V3
set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVCMOS33} [get_ports txd]
set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVCMOS33} [get_ports rxd]
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "sleep.h"
#define UART_IP_BASEADDR XPAR_MY_UART_0_S00_AXI_BASEADDR
void test_wr()
{
Xil_Out32(UART_IP_BASEADDR, 0x1);
Xil_Out32(UART_IP_BASEADDR+0x4, 0xAA);
Xil_Out32(UART_IP_BASEADDR+0x8, 0x55);
xil_printf("%x\r\n", Xil_In32(UART_IP_BASEADDR));
xil_printf("%x\r\n", Xil_In32(UART_IP_BASEADDR+0x4));
xil_printf("%x\r\n", Xil_In32(UART_IP_BASEADDR+0x8));
while(1);
}
void send_str(char *str)
{
char *p=str;
while(*p){
Xil_Out8(UART_IP_BASEADDR+0x0, *p++);
usleep(1000);
}
}
void recv_char()
{
u8 done=Xil_In8(UART_IP_BASEADDR+0x8); //po_flag
if(done){
char c=Xil_In8(UART_IP_BASEADDR+0x4);
Xil_Out8(UART_IP_BASEADDR+0x0, c);
Xil_Out8(UART_IP_BASEADDR+0x8, 0);
}
}
int main()
{
init_platform();
//test_wr();
send_str("hello world!\r\n");
send_str("hello world!\r\n");
send_str("hello world!\r\n");
sleep(1);
while(1){
recv_char();
}
cleanup_platform();
return 0;
}
mark_debug会修改pin_local.xdc文件,添加很多语句。存在的问题,综合后一些信号找不到了。
为了避免综合后信号找不到,另一种更好的方式是,在接口定义前面加上(mark_debug="true")
综合后,直接打开mark_debug界面,可见它自动找到所有我们mark_debug的信号,非常方便。
设置完后,所有mark的信号都显示为已分配。
调试结果