AXI总线实验

基本功能:测试平台向AXI Lite从机写入写起始地址,读起始地址以及开始信号,AXI Full主机检测到开始信号之后,根据配置的起始地址进行测试,AXI Full主机根据配置的读起始地址,从测试平台突发读取32个数据,然后将它们加1,再按照配置的写起始地址,将其突发写入测试平台。
具体的代码如下:
AXI Lite从机代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/03/08 22:32:21
// Design Name: 
// Module Name: axi_lite_slave
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module axi_lite_slave(   //AXI Lite从机
//全局信号
input logic ACLK,
input logic ARESETn,
//写地址通道
input logic AWVALID,
input logic [31:0]AWADDR, 
input logic [2:0]AWPROT, 
output logic AWREADY,
//写数据通道
input logic WVALID,
input logic [31:0] WDATA, 
input logic [3:0] WSTRB,
output logic WREADY,
//写响应通道
input logic BREADY,
output logic BVALID,
output logic [1:0] BRESP,
//读地址通道
input logic ARVALID,
input logic [31:0] ARADDR, 
input logic [2:0] ARPROT, 
output logic ARREADY,
//读数据通道
input logic RREADY,
output logic RVALID,
output logic [31:0] RDATA, 
output logic [1:0] RRESP,
//其他
output logic [31:0] rd_base_addr,
output logic [31:0] wr_base_addr,
output logic [31:0] done_signal,
output logic [31:0] start_signal,
output logic busy                      //主机往从机写数据时,busy为高,直至数据被写入寄存器
    );

parameter N=4;                         //四个寄存器

logic [31:0] DataReg [0:N-1];              //DataReg 0存放start信号,1存放done信号,2存放写起始地址,3存放读起始地址

logic [31:0]rd_addr;             
logic [31:0]wr_addr;
logic [31:0]rd_data;
logic [31:0]wr_data;
logic [1:0] wr_reg_sel;
logic [1:0] rd_reg_sel;
logic wr_en;

assign wr_reg_sel=wr_addr[3:2];
assign rd_reg_sel=rd_addr[3:2];

assign rd_base_addr=DataReg[3];
assign wr_base_addr=DataReg[2];
assign start_signal=DataReg[0];
assign done_signal=DataReg[1]; 

//初始化寄存器
initial 
begin
    for(int i=0;i<N;i++)
        DataReg[i]=0;    
end
//wr_en
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_en<=0;
else if(WVALID&&WREADY&&AWVALID&&AWREADY)
    wr_en<=1;                            //此时写数据地址和写数据均被暂存,可以进行写入
else 
    wr_en<=0;
//busy
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    busy<=0;
else if(AWVALID||WVALID)
    busy<=1;
else if(wr_en)
    busy<=0;
//响应来自主机的写请求
//写地址通道
//AWREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    AWREADY<=0;
else if(AWVALID&&WVALID&&~AWREADY)                        //写地址和写数据均有效时才拉高
    AWREADY<=1;
else if(AWVALID&&AWREADY&&WVALID)                         //写地址通道数据传输结束
    AWREADY<=0;
//wr_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_addr<=0;
else if(AWVALID&&AWREADY)
    wr_addr<=AWADDR;
//写数据通道
//wr_data
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_data<=0;
else if(WVALID&&WREADY)
    wr_data<=WDATA;
//WREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    WREADY<=0;
else if(WVALID&&AWVALID&&~WREADY)
    WREADY<=1;
else if(WVALID&&WREADY&&AWVALID)
    WREADY<=0;
//将数据写入寄存器
always_ff@(posedge ACLK)
if(wr_en)
    DataReg[wr_reg_sel]<=wr_data;
//写响应通道
//BVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    BVALID<=0;
else if(WVALID&&WREADY)
    BVALID<=1;
else if(BVALID&&BREADY&&BRESP==2'b00)
    BVALID<=0;
//BRESP
always_comb 
begin
    BRESP=2'b00;                      //OKEY    
end
//响应来自主机的读请求
//读地址通道
//ARREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    ARREADY<=0;
else if(ARVALID&&~ARREADY)
    ARREADY<=1;
else if(ARVALID&&ARREADY)         //读地址通道数据接受完毕
    ARREADY<=0;
//rd_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_addr<=0;
else if(ARVALID&&ARREADY)           //数据有效,存储地址
    rd_addr<=ARADDR;
//读数据通道
//RVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    RVALID<=0;
else if(ARREADY&&ARVALID)                //读地址通道结束,拉高RVALID发送数据
    RVALID<=1;
else if(RVALID&&RREADY)                  //数据发送完毕
    RVALID<=0;
//RRESP
always_comb
begin
    RRESP=2'b00;
end
//RDATA
always_comb 
begin
    if(RVALID)
        RDATA=DataReg[rd_reg_sel];
    else
        RDATA=32'd0;    
end
endmodule


AXI Full主机代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/03/08 15:26:05
// Design Name: 
// Module Name: PL_DDR_Test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

/*
本程序功能为:从start_addr地址开始处连续读取32个数据至buffer,然后分别将其加1,写回原地址处
*/

module axi_full_master(
//全局信号
input logic ACLK,
input logic ARESETn,
//写地址通道信号
output logic AWVALID,           
output logic [31:0]AWADDR,
output logic [7:0]AWLEN,
output logic AWID,              //dont care
output logic [2:0]AWSIZE,       //dont care
output logic [1:0]AWBURST,      //dont care
output logic AWLOCK,            //dont care
output logic [3:0]AWCACHE,      //dont care
output logic [2:0]AWPROT,       //dont care
output logic [3:0]AWQOS,        //dont care
output logic AWUSER,            //dont care
input logic AWREADY,
//写数据通道信号
output logic [63:0]WDATA,
output logic [7:0]WSTRB,
output logic WLAST,
output logic WUSER,             //dont care
output logic WVALID,
input logic WREADY,
//写应答通道信号
output logic BREADY,
input logic BID,                //dont care
input logic [1:0]BRESP,
input logic BUSER,              //dont care
input logic BVALID,
//读地址通道信号
output logic ARID,              //dont care
output logic [31:0]ARADDR,
output logic [7:0]ARLEN,
output logic [2:0]ARSIZE,       //dont care
output logic [1:0]ARBURST,      //dont care
output logic ARLOCK,            //dont care
output logic [3:0]ARCACHE,      //dont care
output logic [2:0]ARPROT,       //dont care
output logic [3:0]ARQOS,        //dont care
output logic ARUSER,            //done care
output logic ARVALID,       
input logic ARREADY,
//读数据通道
output logic RREADY,
input logic RID,                //dont care
input logic [63:0]RDATA,   
input logic [1:0]RRESP,         //dont care   
input logic RLAST,          
input logic RUSER,              //dont care
input logic RVALID,
//其他
input logic start,
input logic [31:0] wr_base_addr,
input logic [31:0] rd_base_addr,
output logic done
    );

assign AWID = 1'b0;
assign AWSIZE  = 3'b011;
assign AWBURST = 2'b01;
assign AWLOCK  = 1'b0;
assign AWCACHE = 4'b0011;
assign AWPROT = 3'b000;
assign AWQOS = 4'b0000;
assign AWUSER = 1'b1;
assign WUSER = 1'b1;

assign ARID = 1'b0;
assign ARSIZE = 3'b011;
assign ARBURST = 2'b01;
assign ARLOCK = 1'b0;
assign ARCACHE = 4'b0011;
assign ARPROT = 3'b000;
assign ARQOS = 4'b0000;
assign ARUSER = 1'b1;

//计数器
logic [9:0]wr_cnt;
logic [9:0]rd_cnt;
//中间信号
logic rd_done;
logic wr_done;
logic read_start;
logic write_start;
//与PS交互的信号
logic test_start;                   //start
logic test_done;                    //done
logic [31:0] rd_base_addr_r;        //rd_base_addr
logic [31:0] wr_base_addr_r;        //wr_base_addr
//固定
logic [9:0] test_len;            //=31,即突发传输长度32
logic [63:0] data_buffer [0:31];

enum {IDLE,READ,WRITE,DONE} State,NextState;
//*************************************************************************//
//test_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    test_len<=31;
//test_start
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    test_start<=0;
else
    test_start<=start;
//wr_base_addr_r
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_base_addr_r<=0;
else
    wr_base_addr_r<=wr_base_addr;
//rd_base_addr_r
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_base_addr_r<=0;
else
    rd_base_addr_r<=rd_base_addr;
//done
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    done<=0;
else 
    done<=test_done;
//***********************************************************************//
//FSM
always_ff@(posedge ACLK,negedge ARESETn)
begin
    if(!ARESETn)
        State<=IDLE;
    else
        State<=NextState;
end
//FSM
always@(*)
case(State)
    IDLE:if(test_start)
             NextState=READ;
         else
             NextState=IDLE;
    READ:if(rd_done)
             NextState=WRITE;
         else
             NextState=READ;
    WRITE:if(wr_done)
             NextState=DONE;
          else
             NextState=WRITE;
    DONE:NextState=IDLE;
    default:NextState=IDLE;
endcase
//读地址通道
always_comb
   read_start=test_start;
//ARVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    ARVALID<=1'b0;
else if(NextState==READ&&read_start)                      //read_start为一个宽一个周期的脉冲
    ARVALID<=1'b1;
else if(ARVALID==1'b1&&ARREADY==1'b1)                     //读通道数据传输完成
    ARVALID<=1'b0;
//ARADDR
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    ARADDR<=32'd0;
else if(NextState==READ&&read_start)
    ARADDR<=rd_base_addr_r;
//ARLEN
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   ARLEN<=8'd0;
else if(NextState==READ&&read_start)
   ARLEN<=test_len;
//读数据通道
//rd_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_cnt<=10'd0;
else if(RVALID&&RREADY)      //完成一个数据的读取,计数器加1
    if(RLAST)
        rd_cnt<=0;
    else
        rd_cnt<=rd_cnt+1'b1;
//data_buffer
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    for(int i=0;i<32;i++)
        data_buffer[i]<=32'd0;
else if(RVALID&&RREADY)
    data_buffer[rd_cnt]<=RDATA;
//RREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    RREADY<=0;
else if(RVALID&&~RREADY)
    RREADY<=1;
else if(RVALID&&RREADY&&RLAST)                       //最后一个数据读取完成
    RREADY<=0;
//rd_done
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_done<=0;
else if(RLAST)
    rd_done<=1;
else 
    rd_done<=0;
//写地址通道
//write_start
always_comb 
begin
    write_start=rd_done;    
end
//AWVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   AWVALID<=0;
else if(NextState==WRITE&&write_start)
   AWVALID<=1;
else if(AWVALID&&AWREADY)                         //写地址通道传输完成
   AWVALID<=0;
//AWADDR
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   AWADDR<=32'd0;
else if(NextState==WRITE&&write_start)
   AWADDR<=wr_base_addr_r;
//AWLEN
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   AWLEN<=8'd0;
else if(NextState==WRITE&&write_start)
   AWLEN<=test_len;                                      //写突发传输长度为32
//写数据通道
//wr_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_cnt<=10'd0;
else if(WVALID&&WREADY)                         //完成一个数据的写入,计数器加1
    if(WLAST)
        wr_cnt<=0;
    else
        wr_cnt<=wr_cnt+1;
//WVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    WVALID<=0;
else if(AWVALID&&AWREADY)                      //写地址通道传输完成,开始写数据
    WVALID<=1;
else if(WLAST&&WVALID&&WREADY)                 //最后一个数据传输完成
    WVALID<=0;
//WSTRB
always_ff@(posedge ACLK,negedge ARESETn)                  //
if(!ARESETn)
    WSTRB<=8'd0;
else if(AWVALID&&AWREADY)                
    WSTRB<=8'hff;
//WDATA
always_comb 
begin
   if(WVALID&&WREADY)                                  //此时写入数据有效
       WDATA=data_buffer[wr_cnt]+1;    
   else
       WDATA=0;
end
//WLAST
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   WLAST<=0;
else if(wr_cnt==test_len-1&&WVALID&&WREADY)                           //31-1=30
   WLAST<=1;
else if(WLAST&&WVALID&&WREADY)                                        //写数据结束
   WLAST<=0;
//写响应通道
//BREAY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   BREADY<=0;
else if(AWVALID&&AWREADY)
   BREADY<=1;
else if(BVALID&&BRESP==2'b00)                      //BRESP=OKEY
   BREADY<=0;
//wr_done
always_comb 
begin
    if(BREADY&&BVALID&&BRESP==2'b00)
        wr_done=1;
    else
        wr_done=0;    
end
//test_done
always_comb
    test_done=wr_done;

endmodule

设计的顶层模块代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/03/10 10:05:58
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module top(
input logic ACLK,
input logic ARESETn,
//写地址通道
input logic axilite_AWVALID,
input logic [31:0] axilite_AWADDR, 
input logic [2:0] axilite_AWPROT, 
output logic axilite_AWREADY,
//写数据通道
input logic axilite_WVALID,
input logic [31:0] axilite_WDATA, 
input logic [3:0] axilite_WSTRB,
output logic axilite_WREADY,
//写响应通道
input logic axilite_BREADY,
output logic axilite_BVALID,
output logic [1:0] axilite_BRESP,
//读地址通道
input logic axilite_ARVALID,
input logic [31:0] axilite_ARADDR, 
input logic [2:0] axilite_ARPROT, 
output logic axilite_ARREADY,
//读数据通道
input logic axilite_RREADY,
output logic axilite_RVALID,
output logic [31:0] axilite_RDATA, 
output logic [1:0] axilite_RRESP,
//其他
output logic busy,                           //主机往从机写数据时,busy为高,直至数据被写入寄存器
/****************************************************************************************************************************************/
//AXI FULL MASTER
//写地址通道信号
output logic axifull_AWVALID,           
output logic [31:0] axifull_AWADDR,
output logic [7:0] axifull_AWLEN,
output logic axifull_AWID,              //dont care
output logic [2:0] axifull_AWSIZE,            //dont care
output logic [1:0] axifull_AWBURST,           //dont care
output logic axifull_AWLOCK,            //dont care
output logic [3:0] axifull_AWCACHE,           //dont care
output logic [2:0] axifull_AWPROT,            //dont care
output logic [3:0] axifull_AWQOS,             //dont care
output logic axifull_AWUSER,            //dont care
input logic axifull_AWREADY,
//写数据通道信号
output logic [63:0] axifull_WDATA,
output logic [7:0] axifull_WSTRB,
output logic axifull_WLAST,
output logic axifull_WUSER,             //dont care
output logic axifull_WVALID,
input logic axifull_WREADY,
//写应答通道信号
output logic axifull_BREADY,
input logic axifull_BID,                //dont care
input logic [1:0] axifull_BRESP,
input logic axifull_BUSER,              //dont care
input logic axifull_BVALID,
//读地址通道信号
output logic axifull_ARID,               //dont care
output logic [31:0] axifull_ARADDR,
output logic [7:0] axifull_ARLEN,
output logic [2:0] axifull_ARSIZE,            //dont care
output logic [1:0] axifull_ARBURST,           //dont care
output logic axifull_ARLOCK,            //dont care
output logic [3:0] axifull_ARCACHE,           //dont care
output logic [2:0] axifull_ARPROT,            //dont care
output logic [3:0] axifull_ARQOS,             //dont care
output logic axifull_ARUSER,            //done care
output logic axifull_ARVALID,       
input logic axifull_ARREADY,
//读数据通道
output logic axifull_RREADY,
input logic axifull_RID,                //dont care
input logic [63:0] axifull_RDATA,   
input logic [1:0] axifull_RRESP,              //dont care   
input logic axifull_RLAST,          
input logic axifull_RUSER,              //dont care
input logic axifull_RVALID,
//其他
output logic done
);

logic [31:0] rd_base_addr;
logic [31:0] wr_base_addr;
logic [31:0] start_signal;
logic [31:0] start_signal_ff;
logic [31:0] done_signal;
logic start;

//start
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    start<=0;
else if(start_signal[0]&&~start_signal_ff[0])          //上升沿
    start<=1;
else 
    start<=0;
//start_signnal_ff
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    start_signal_ff<=0;
else 
    start_signal_ff<=start_signal;
//例化
axi_lite_slave U(   //AXI Lite从机
//全局信号
.ACLK(ACLK),
.ARESETn(ARESETn),
//写地址通道
.AWVALID(axilite_AWVALID),
.AWADDR(axilite_AWADDR), 
.AWPROT(axilite_AWPROT), 
.AWREADY(axilite_AWREADY),
//写数据通道
.WVALID(axilite_WVALID),
.WDATA(axilite_WDATA), 
.WSTRB(axilite_WSTRB),
.WREADY(axilite_WREADY),
//写响应通道
.BREADY(axilite_BREADY),
.BVALID(axilite_BVALID),
.BRESP(axilite_BRESP),
//读地址通道
.ARVALID(axilite_ARVALID),
.ARADDR(axilite_ARADDR), 
.ARPROT(axilite_ARPROT), 
.ARREADY(axilite_ARREADY),
//读数据通道
.RREADY(axilite_RREADY),
.RVALID(axilite_RVALID),
.RDATA(axilite_RDATA), 
.RRESP(axilite_RRESP),
//其他
.rd_base_addr(rd_base_addr),
.wr_base_addr(wr_base_addr),
.done_signal(done_signal),
.start_signal(start_signal),
.busy(busy)                      //主机往从机写数据时,busy为高,直至数据被写入寄存器
);
//************************************************************************************************************//
axi_full_master V(
//全局信号
.ACLK(ACLK),
.ARESETn(ARESETn),
//写地址通道信号
.AWVALID(axifull_AWVALID),           
.AWADDR(axifull_AWADDR),
.AWLEN(axifull_AWLEN),
.AWID(axifull_AWID),              //dont care
.AWSIZE(axifull_AWSIZE),       //dont care
.AWBURST(axifull_AWBURST),      //dont care
.AWLOCK(axifull_AWLOCK),            //dont care
.AWCACHE(axifull_AWCACHE),      //dont care
.AWPROT(axifull_AWPROT),       //dont care
.AWQOS(axifull_AWQOS),        //dont care
.AWUSER(axifull_AWUSER),            //dont care
.AWREADY(axifull_AWREADY),
//写数据通道信号
.WDATA(axifull_WDATA),
.WSTRB(axifull_WSTRB),
.WLAST(axifull_WLAST),
.WUSER(axifull_WUSER),             //dont care
.WVALID(axifull_WVALID),
.WREADY(axifull_WREADY),
//写应答通道信号
.BREADY(axifull_BREADY),
.BID(axifull_BID),                //dont care
.BRESP(axifull_BRESP),
.BUSER(axifull_BUSER),              //dont care
.BVALID(axifull_BVALID),
//读地址通道信号
.ARID(axifull_ARID),              //dont care
.ARADDR(axifull_ARADDR),
.ARLEN(axifull_ARLEN),
.ARSIZE(axifull_ARSIZE),       //dont care
.ARBURST(axifull_ARBURST),      //dont care
.ARLOCK(axifull_ARLOCK),       //dont care
.ARCACHE(axifull_ARCACHE),      //dont care
.ARPROT(axifull_ARPROT),       //dont care
.ARQOS(axifull_ARQOS),        //dont care
.ARUSER(axifull_ARUSER),            //done care
.ARVALID(axifull_ARVALID),       
.ARREADY(axifull_ARREADY),
//读数据通道
.RREADY(axifull_RREADY),
.RID(axifull_RID),                //dont care
.RDATA(axifull_RDATA),   
.RRESP(axifull_RRESP),         //dont care   
.RLAST(axifull_RLAST),          
.RUSER(axifull_RUSER),              //dont care
.RVALID(axifull_RVALID),
//其他
.start(start),
.wr_base_addr(wr_base_addr),
.rd_base_addr(rd_base_addr),
.done(done)
);
endmodule

测试平台文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/03/09 22:20:51
// Design Name: 
// Module Name: test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module test;
logic ACLK;
logic ARESETn;
//AXI Lite信号定义
//写地址通道
logic axilite_AWVALID;
logic [31:0] axilite_AWADDR; 
logic [2:0] axilite_AWPROT; 
logic axilite_AWREADY;
//写数据通道
logic axilite_WVALID;
logic [31:0] axilite_WDATA; 
logic [3:0] axilite_WSTRB;
logic axilite_WREADY;
//写响应通道
logic axilite_BREADY;
logic axilite_BVALID;
logic [1:0] axilite_BRESP;
//读地址通道
logic axilite_ARVALID;
logic [31:0] axilite_ARADDR; 
logic [2:0] axilite_ARPROT; 
logic axilite_ARREADY;
//读数据通道
logic axilite_RREADY;
logic axilite_RVALID;
logic [31:0] axilite_RDATA; 
logic [1:0] axilite_RRESP;
//AXI Full信号定义
//写地址通道
logic axifull_AWVALID;
logic axifull_AWID;
logic [2:0] axifull_AWSIZE;
logic axifull_AWUSER;
logic [3:0]axifull_AWCACHE;
logic [1:0]axifull_AWBURST;
logic axifull_AWLOCK;
logic [2:0] axifull_AWPROT;
logic [3:0] axifull_AWQOS;
logic [31:0] axifull_AWADDR;
logic [7:0] axifull_AWLEN;                  //突发传输长度,实际长度为AWLEN+1
logic axifull_AWREADY;
//写数据通道
logic axifull_WUSER;
logic [63:0] axifull_WDATA;
logic axifull_WVALID;
logic [7:0] axifull_WSTRB;                //dont care
logic axifull_WLAST;
logic axifull_WREADY;
//写响应通道
logic axifull_BID;
logic axifull_BUSER;
logic axifull_BVALID;
logic axifull_BREADY;
logic [1:0] axifull_BRESP;
//读数据通道
logic axifull_ARID;
logic [2:0] axifull_ARSIZE;
logic axifull_ARUSER;
logic [3:0]axifull_ARCACHE;
logic [1:0]axifull_ARBURST;
logic axifull_ARLOCK;
logic [2:0] axifull_ARPROT;
logic [3:0] axifull_ARQOS;
logic [63:0] axifull_RDATA;
logic axifull_RVALID;
logic axifull_RREADY;
logic axifull_RLAST;
//读地址通道
logic axifull_RID;
logic axifull_RUSER;
logic [1:0] axifull_RRESP;
logic [31:0] axifull_ARADDR;
logic [7:0] axifull_ARLEN;
logic axifull_ARVALID;
logic axifull_ARREADY;
//
logic busy;
logic done;
//
logic start_config;                          //配置读起始地址、写起始地址,最后写start信号
logic test_done;                             //表明一次测试完成

logic [63:0] mem [0:1023];                   //模拟DDR
logic [31:0] rd_base_addr;                   //本次测试的读起始地址,写入axilite_slave
logic [31:0] wr_base_addr;                   //本次测试的写起始地址,写入axilite_salve
logic [31:0] start_signal;                   //本次测试的开始信号,写入axilite_slave
logic [31:0] done_signal;                    //本次测试的结束信号,从axilite_slave读取

logic write_rd_addr_done;                    //配置读起始地址完毕
logic write_wr_addr_done;                    //配置写起始地址完毕
logic write_start_done;                      //配置开始信号完毕
logic [9:0]count;                            //计数器,以区分当前是在配置什么寄存器

logic [31:0] wr_addr;                       //axifull从机接受主机的写请求,锁存写起始地址
logic [31:0] rd_addr;                       //axifull从机接受主机的读请求,锁存读起始地址
logic [9:0] wr_len;                         //axifull从机接受主机的写请求,锁存写突发长度
logic [9:0] rd_len;                         //axifull从机接受主机的读请求, 锁存读突发长度
logic [9:0] wr_cnt;                         //axifull从机接受主机的写请求,记录写入数据个数,即从机接收数据个数
logic [9:0] rd_cnt;                         //axifull从机接受主机的读请求,记录读取数据个数,即从机发送数据个数
//test_done
assign test_done=done;
//count
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    count<=0;
else if(axilite_BRESP==2'b00&&axilite_BREADY&&axilite_BVALID)             //1次配置完成,count++
    count<=count+1;                                       
//start_config
initial begin
    start_config=0;
    #20
    start_config=1;
    #10
    start_config=0;
end
//ACLK
initial begin
    ACLK=0;
    forever begin
        #5 ACLK=~ACLK;
    end
end
//ARESETn
initial begin
    ARESETn=0;
    #10
    ARESETn=1;
end
//mem
initial begin
    for(int i=0;i<1024;i++)
       mem[i]=i;
end
//rd_base_addr
initial begin
    rd_base_addr=32'd0;
end
//wr_base_addr
initial begin
    wr_base_addr=32'd32;
end
//start_signal
initial begin
    start_signal=32'd1;
end
//done_signal

//先写读起始地址,再写写起始地址,最后写start
//写地址通道
//AWVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axilite_AWVALID<=0;
else if(start_config||write_rd_addr_done||write_wr_addr_done)
    axilite_AWVALID<=1;
else if(axilite_AWVALID&&axilite_AWREADY)
    axilite_AWVALID<=0;
//AWADDR
always_ff@(posedge ACLK,negedge ARESETn)                           //0号寄存器:start,1号寄存器:done,2号寄存器:写起始地址,3号寄存器:读起始地址
if(!ARESETn)
    axilite_AWADDR<=0;
else if(start_config)
    axilite_AWADDR<=32'd12;                //12/4=3,3号寄存器,配置读起始地址
else if(write_rd_addr_done)
    axilite_AWADDR<=32'd8;                 //8/4=2,2号寄存器,配置写起始地址
else if(write_wr_addr_done)
    axilite_AWADDR<=32'd0;                 //0/4=0,0号寄存器,配置开始信号
//AWPROT
always_comb 
begin
    axilite_AWPROT=3'b000;    
end
//写数据通道
//WDATA
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axilite_WDATA<=0;
else if(start_config)
    axilite_WDATA<=rd_base_addr;
else if(write_rd_addr_done)
    axilite_WDATA<=wr_base_addr;
else if(write_wr_addr_done)
    axilite_WDATA<=start_signal;
//WVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axilite_WVALID<=0;
else if(start_config||write_rd_addr_done||write_wr_addr_done)
    axilite_WVALID<=1;
else if(axilite_WVALID&&axilite_WREADY)
    axilite_WVALID<=0;
//WSTRB
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
   axilite_WSTRB<=0;
else if(start_config||write_rd_addr_done||write_wr_addr_done)
   axilite_WSTRB<=4'b1111;
//write_rd_addr_done,write_rd_addr_done,write_start_done
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
begin
    write_rd_addr_done<=0;
    write_wr_addr_done<=0;
    write_start_done<=0;
end
else if(axilite_BRESP==2'b00&&axilite_BVALID&&axilite_BREADY)
case(count)
    0:write_rd_addr_done<=1;
    1:write_wr_addr_done<=1;
    2:write_start_done<=1;
    default:;
endcase
else
begin
    write_rd_addr_done<=0;
    write_wr_addr_done<=0;
    write_start_done<=0;
end
//写响应通道
//BREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axilite_BREADY<=0;
else if(axilite_AWREADY&&axilite_AWVALID)
    axilite_BREADY<=1;
else if(axilite_BREADY&&axilite_BVALID&&axilite_BRESP==2'b00)                     //
    axilite_BREADY<=0;

/**********************************************************************************************************************************************
**********************************************************************************************************************************************/
//axifull从机
//写地址通道
//axifull_AWREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_AWREADY<=0;
else if(axifull_AWVALID&&~axifull_AWREADY)
    axifull_AWREADY<=1;
else if(axifull_AWREADY&&axifull_AWVALID)                        //读地址通道完成
    axifull_AWREADY<=0;
//wr_adrr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_addr<=0;
else if(axifull_AWREADY&&axifull_AWVALID)                        //锁存写起始地址
    wr_addr<=axifull_AWADDR;
//wr_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_len<=0;
else if(axifull_AWVALID&&axifull_AWREADY)
    wr_len<=axifull_AWLEN;
//wr_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    wr_cnt<=0;
else if(axifull_WREADY&&axifull_WVALID)
    if(axifull_WLAST)
        wr_cnt<=0;
    else
        wr_cnt<=wr_cnt+1;
//写数据通道
//mem
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    ;
else if(axifull_WVALID&&axifull_WREADY)
    mem[wr_addr+wr_cnt]<=axifull_WDATA;
//WREAY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_WREADY<=0;
else if(axifull_AWVALID&&axifull_AWREADY)
    axifull_WREADY<=1;
else if(axifull_WVALID&&axifull_WREADY&&axifull_WLAST)
    axifull_WREADY<=0;
//写响应通道
//BRESP
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_BRESP<=2'b01;
else if(axifull_WLAST&&axifull_WVALID&&axifull_WREADY)
    axifull_BRESP<=2'b00;
else if(axifull_BRESP==2'b00&&axifull_BVALID&&axifull_BREADY)
    axifull_BRESP<=2'b01;
//BVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_BVALID<=0;
else if(axifull_WLAST&&axifull_WREADY&&axifull_WVALID)
    axifull_BVALID<=1;
else if(axifull_BVALID&&axifull_BRESP==2'b00&&axifull_BREADY)
    axifull_BVALID<=0;
//读地址通道
//axifull_ARREADY
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_ARREADY<=0;
else if(axifull_ARVALID&&~axifull_ARREADY)
    axifull_ARREADY<=1;
else if(axifull_ARREADY&&axifull_ARVALID)                    //读地址通道结束
    axifull_ARREADY<=0;
//rd_addr
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_addr<=0;
else if(axifull_ARREADY&&axifull_ARVALID)                   //锁存读起始地址
    rd_addr<=axifull_ARADDR;
//rd_len
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_len<=0;
else if(axifull_ARREADY&&axifull_ARVALID)
    rd_len<=axifull_ARLEN;
//读数据通道
//rd_cnt
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    rd_cnt<=0;
else if(axifull_RVALID&&axifull_RREADY)
    if(axifull_RLAST)
        rd_cnt<=0;
    else 
        rd_cnt<=rd_cnt+1;
//RVALID
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_RVALID<=0;
else if(axifull_ARREADY&&axifull_ARVALID)            //读地址通道结束即开始发送读数据
    axifull_RVALID<=1;
else if(axifull_RVALID&&axifull_RREADY&&axifull_RLAST)
    axifull_RVALID<=0;
//RDATA
always_comb
begin
    if(axifull_RVALID)
        axifull_RDATA=mem[rd_addr+rd_cnt];
    else
        axifull_RDATA=0;
end
//RLAST
always_ff@(posedge ACLK,negedge ARESETn)
if(!ARESETn)
    axifull_RLAST<=0;
else if(rd_cnt==rd_len-1&&axifull_RREADY&&axifull_RVALID)                      //倒数第二个数据发送并被接收,则RLAST拉高
    axifull_RLAST<=1; 
else if(axifull_RLAST&&axifull_RREADY&&axifull_RVALID)                         //最后一个数据发送并被接收,RLAST拉低
    axifull_RLAST<=0;

/***************************************************************************************************************************************/
//例化
top U(.*);
/* 
top U(
 ACLK,
 ARESETn,
//写地址通道
 axilite_AWVALID,
 axilite_AWADDR, 
 axilite_AWPROT, 
 axilite_AWREADY,
//写数据通道
 axilite_WVALID,
 axilite_WDATA, 
 axilite_WSTRB,
 axilite_WREADY,
//写响应通道
 axilite_BREADY,
 axilite_BVALID,
 axilite_BRESP,
//读地址通道
 axilite_ARVALID,
 axilite_ARADDR, 
 axilite_ARPROT, 
 axilite_ARREADY,
//读数据通道
 axilite_RREADY,
 axilite_RVALID,
 axilite_RDATA, 
 axilite_RRESP,
//其他
 busy,                           //主机往从机写数据时,busy为高,直至数据被写入寄存器
/****************************************************************************************************************************************/
/*
//AXI FULL MASTER
//写地址通道信号
 axifull_AWVALID,           
 axifull_AWADDR,
 axifull_AWLEN,
 axifull_AWID,              //dont care
 axifull_AWSIZE,            //dont care
 axifull_AWBURST,           //dont care
 axifull_AWLOCK,            //dont care
 axifull_AWCACHE,           //dont care
 axifull_AWPROT,            //dont care
 axifull_AWQOS,             //dont care
 axifull_AWUSER,            //dont care
 axifull_AWREADY,
//写数据通道信号
 axifull_WDATA,
 axifull_WSTRB,
 axifull_WLAST,
 axifull_WUSER,             //dont care
 axifull_WVALID,
 axifull_WREADY,
//写应答通道信号
 axifull_BREADY,
 axifull_BID,                //dont care
 axifull_BRESP,
 axifull_BUSER,              //dont care
 axifull_BVALID,
//读地址通道信号
 axifull_ARID,               //dont care
 axifull_ARADDR,
 axifull_ARLEN,
 axifull_ARSIZE,            //dont care
 axifull_ARBURST,           //dont care
 axifull_ARLOCK,            //dont care
 axifull_ARCACHE,           //dont care
 axifull_ARPROT,            //dont care
 axifull_ARQOS,             //dont care
 axifull_ARUSER,            //done care
 axifull_ARVALID,       
 axifull_ARREADY,
//读数据通道
 axifull_RREADY,
 axifull_RID,                //dont care
 axifull_RDATA,   
 axifull_RRESP,              //dont care   
 axifull_RLAST,          
 axifull_RUSER,              //dont care
 axifull_RVALID,
//其他
 done
);
*/
endmodule

上一篇:Cloud Native Weekly | TiKV加入CNCF沙箱托管项目,微软发布Windows


下一篇:1.k8s介绍