硬件平台:Zedboard
软件环境:Vivado 2015.2
仿真工具:XSIM
//*****************************************************************
1、AXI Uartlite IP核设置
注意 AXI CLK Frequency = 110MHz
2、Testbench
在Testbench中,定义了一个状态机,向uartlite写入数据。首先CTRL_REG寄存器写入TX fifo复位命令,接着再向TX fifo中写入要发送的数据。Testbench中例化了一个UART接收模块,用来接收uartlite发送是串行数据并完成串并转换,方便观察。代码如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2016/08/25 14:27:31
// Design Name:
// Module Name: uartlite
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uartlite();
reg s_axi_aclk;
reg s_axi_aresetn;
wire interrupt;
reg [3 : 0] s_axi_awaddr;
reg s_axi_awvalid;
wire s_axi_awready;
reg [31 : 0] s_axi_wdata;
reg [3 : 0] s_axi_wstrb;
reg s_axi_wvalid;
wire s_axi_wready;
wire [1 : 0] s_axi_bresp;
wire s_axi_bvalid;
reg s_axi_bready ;
reg [3 : 0] s_axi_araddr;
reg s_axi_arvalid = 0;
wire s_axi_arready;
wire [31 : 0] s_axi_rdata;
wire [1 : 0] s_axi_rresp;
wire s_axi_rvalid;
reg s_axi_rready ;
reg rx ;
wire tx;
wire dv;
wire [7:0] dout;
//***************************************************************************
parameter Clockperiod = 9.091; //110M
parameter IDLE = 0;
parameter SETUP = 1;
parameter WDATA_WVALID = 2;
parameter W_WAIT = 3;
parameter AWADDR_AWVALID = 4;
parameter AW_WAIT = 5;
parameter JUDGE_AWREADY = 6;
parameter INC = 7;
parameter WAIT_100 = 8;
parameter WAIT_NUM = 10;
reg [7:0] CS = IDLE,NS = IDLE;
reg [7:0] wait_cnt = 0;
initial begin
s_axi_aresetn <= 1’b0;
#30;
s_axi_aresetn <= 1’b1;
s_axi_aclk = 1’b1;
forever s_axi_aclk = #(Clockperiod/2) ~s_axi_aclk;;
end
//
always@(posedge s_axi_aclk)begin
CS <= NS;
end
//
always@(*)begin
case(CS)
IDLE: NS = SETUP;
SETUP: NS = WDATA_WVALID;
WDATA_WVALID: NS = W_WAIT;
W_WAIT: NS = AWADDR_AWVALID;
AWADDR_AWVALID: NS = AW_WAIT;
AW_WAIT: NS = JUDGE_AWREADY;
JUDGE_AWREADY: begin
if(s_axi_awready & s_axi_wready) NS = INC;
else NS = JUDGE_AWREADY;
end
INC: NS = WAIT_100;
WAIT_100: begin
if(wait_cnt == WAIT_NUM) NS = SETUP;
else NS = WAIT_100;
end
default: NS = IDLE;
endcase
end
//
always@(posedge s_axi_aclk)begin
if(CS == IDLE)begin
s_axi_awaddr <= 4’hC;
s_axi_awvalid <= 1’b0;
s_axi_wdata <= 32’h00000003;
s_axi_wvalid <= 1’b0;
s_axi_bready <= 1’b1;
s_axi_wstrb <= 4’hf;
end
end
//
always@(posedge s_axi_aclk)begin
if(CS == SETUP)begin
end
end
//
always@(posedge s_axi_aclk)begin
if(CS == WDATA_WVALID)begin
s_axi_wvalid <= 1’b1;
end
end
//
always@(posedge s_axi_aclk)begin
if(CS == AWADDR_AWVALID)begin
s_axi_awvalid <= 1’b1;
end
end
//
always@(posedge s_axi_aclk)begin
if(CS == JUDGE_AWREADY)begin
if(s_axi_awready & s_axi_wready) begin
s_axi_awvalid <= 1’b0;
s_axi_wvalid <= 1’b0;
end
end
end
always@(posedge s_axi_aclk)begin
if(CS == INC)begin
s_axi_awaddr <= 4’h4;
s_axi_wdata <= s_axi_wdata+1;
end
end
always@(posedge s_axi_aclk)begin
if(CS == WAIT_100)begin
if(wait_cnt == WAIT_NUM) wait_cnt <= 0;
else wait_cnt <= wait_cnt+1;
end
end
//****************************************************************************
//———– Begin Cut here for INSTANTIATION Template —// INST_TAG
axi_uartlite_0 unt (
.s_axi_aclk(s_axi_aclk), // input wire s_axi_aclk
.s_axi_aresetn(s_axi_aresetn), // input wire s_axi_aresetn
.interrupt(interrupt), // output wire interrupt
.s_axi_awaddr(s_axi_awaddr), // input wire [3 : 0] s_axi_awaddr
.s_axi_awvalid(s_axi_awvalid), // input wire s_axi_awvalid
.s_axi_awready(s_axi_awready), // output wire s_axi_awready
.s_axi_wdata(s_axi_wdata), // input wire [31 : 0] s_axi_wdata
.s_axi_wstrb(s_axi_wstrb), // input wire [3 : 0] s_axi_wstrb
.s_axi_wvalid(s_axi_wvalid), // input wire s_axi_wvalid
.s_axi_wready(s_axi_wready), // output wire s_axi_wready
.s_axi_bresp(s_axi_bresp), // output wire [1 : 0] s_axi_bresp
.s_axi_bvalid(s_axi_bvalid), // output wire s_axi_bvalid
.s_axi_bready(s_axi_bready), // input wire s_axi_bready
.s_axi_araddr(s_axi_araddr), // input wire [3 : 0] s_axi_araddr
.s_axi_arvalid(s_axi_arvalid), // input wire s_axi_arvalid
.s_axi_arready(s_axi_arready), // output wire s_axi_arready
.s_axi_rdata(s_axi_rdata), // output wire [31 : 0] s_axi_rdata
.s_axi_rresp(s_axi_rresp), // output wire [1 : 0] s_axi_rresp
.s_axi_rvalid(s_axi_rvalid), // output wire s_axi_rvalid
.s_axi_rready(s_axi_rready), // input wire s_axi_rready
.rx(rx), // input wire rx
.tx(tx) // output wire tx
);
//**************************************************************************
//**************************************************************************
UAR_115200 uar_inst(
.CLK(s_axi_aclk),
.DI(tx),
.DV(dv),
.DO(dout));
endmodule
3、仿真波形
在Testbench中,我们发送的数据为:4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22……
uar模块输出的数据为:4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,249,243,236,229……
这是因为TX fifo深度为16,我们向uartlite中写入太快,uartlite来不及发完,因此数丢了。
//*******************************************************
参考资料:
[1]pg142-axi-uartlite.pdf
<div class="blog-detail-action hide-owner-dom hide">
<a title="编辑" href="/blog/article/edit/id-389789"><i class="fa fa-pencil"></i> 编辑</a> |
<a title="删除" onclick="return window.confirm('您确定要删除吗?');" href="/blog/article/delete/id-389789"><i class="fa fa-minus"></i> 删除</a>