・axi4_master_inf_tb.v がテストベンチ
・UUTの axi_master_inf.v がトップファイル(AXI4 Master Interfaceモジュール)
・wadfifo が Writeアドレス転送用の非同期FIFO
・アドレス転送が16個ネストできるので、アドレス転送の情報を保存しておく wadfifo_outs
・wdfifo は Writeデータ転送用の非同期FIFO
・radfifo が Readアドレス転送用の非同期FIFO
・アドレス転送が16個ネストできるので、アドレス転送の情報を保存しておく radfifo_outs
・rdfifo が Readデータ転送用の非同期FIFO
・uut_slave の axi_slave_bfm.v がAXI4 Bus Slave の Bus Functional Model
`default_nettype none
`timescale 100ps / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 03:57:39 11/05/2013
// Design Name: axi4_master_inf
// Module Name: D:/HDL/FndtnISEWork/Zynq-7000/ZedBoard/AXI4_bus/axi4_master_inf/axi4_master_inf_tb.v
// Project Name: axi4_master_inf
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: axi4_master_inf
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module axi4_master_inf_tb;
parameter DELAY = 10;
// Inputs
wire ACLK;
wire ARESETN;
wire M_AXI_AWREADY;
wire M_AXI_WREADY;
wire [0:0] M_AXI_BID;
wire [1:0] M_AXI_BRESP;
wire [0:0] M_AXI_BUSER;
wire M_AXI_BVALID;
wire M_AXI_ARREADY;
wire [0:0] M_AXI_RID;
wire [63:0] M_AXI_RDATA;
wire [1:0] M_AXI_RRESP;
wire M_AXI_RLAST;
wire [0:0] M_AXI_RUSER;
wire M_AXI_RVALID;
wire write_clk;
wire write_rst;
reg write_adfifo_wr_ena;
reg [31:0] write_adfifo_addr;
reg [7:0] write_adfifo_awlen;
reg write_fifo_wr_ena;
reg [63:0] write_fifo_write_data;
reg [7:0] write_fifo_wstrb;
wire read_clk;
wire read_rst;
reg read_adfifo_wr_ena;
reg [31:0] read_adfifo_addr;
reg [7:0] read_adfifo_arlen;
wire read_fifo_rd_ena;
reg init_done;
// Outputs
wire [0:0] M_AXI_AWID;
wire [31:0] M_AXI_AWADDR;
wire [7:0] M_AXI_AWLEN;
wire [2:0] M_AXI_AWSIZE;
wire [1:0] M_AXI_AWBURST;
wire M_AXI_AWLOCK;
wire [3:0] M_AXI_AWCACHE;
wire [2:0] M_AXI_AWPROT;
wire [3:0] M_AXI_AWQOS;
wire [0:0] M_AXI_AWUSER;
wire M_AXI_AWVALID;
wire [63:0] M_AXI_WDATA;
wire [7:0] M_AXI_WSTRB;
wire M_AXI_WLAST;
wire [0:0] M_AXI_WUSER;
wire M_AXI_WVALID;
wire M_AXI_BREADY;
wire [0:0] M_AXI_ARID;
wire [31:0] M_AXI_ARADDR;
wire [7:0] M_AXI_ARLEN;
wire [2:0] M_AXI_ARSIZE;
wire [1:0] M_AXI_ARBURST;
wire [1:0] M_AXI_ARLOCK;
wire [3:0] M_AXI_ARCACHE;
wire [2:0] M_AXI_ARPROT;
wire [3:0] M_AXI_ARQOS;
wire [0:0] M_AXI_ARUSER;
wire M_AXI_ARVALID;
wire M_AXI_RREADY;
wire write_adfifo_full;
wire write_fifo_full;
wire wirte_fifo_almost_full;
wire read_adfifo_full;
wire [63:0] read_fifo_read_data;
wire read_fifo_empty_n;
wire read_fifo_almost_empty_n;
wire wr_resp_err;
// Instantiate the Unit Under Test (UUT)
axi4_master_inf #(
.C_M_AXI_DATA_WIDTH(64)
) uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.M_AXI_AWID(M_AXI_AWID),
.M_AXI_AWADDR(M_AXI_AWADDR),
.M_AXI_AWLEN(M_AXI_AWLEN),
.M_AXI_AWSIZE(M_AXI_AWSIZE),
.M_AXI_AWBURST(M_AXI_AWBURST),
.M_AXI_AWLOCK(M_AXI_AWLOCK),
.M_AXI_AWCACHE(M_AXI_AWCACHE),
.M_AXI_AWPROT(M_AXI_AWPROT),
.M_AXI_AWQOS(M_AXI_AWQOS),
.M_AXI_AWUSER(M_AXI_AWUSER),
.M_AXI_AWVALID(M_AXI_AWVALID),
.M_AXI_AWREADY(M_AXI_AWREADY),
.M_AXI_WDATA(M_AXI_WDATA),
.M_AXI_WSTRB(M_AXI_WSTRB),
.M_AXI_WLAST(M_AXI_WLAST),
.M_AXI_WUSER(M_AXI_WUSER),
.M_AXI_WVALID(M_AXI_WVALID),
.M_AXI_WREADY(M_AXI_WREADY),
.M_AXI_BID(M_AXI_BID),
.M_AXI_BRESP(M_AXI_BRESP),
.M_AXI_BUSER(M_AXI_BUSER),
.M_AXI_BVALID(M_AXI_BVALID),
.M_AXI_BREADY(M_AXI_BREADY),
.M_AXI_ARID(M_AXI_ARID),
.M_AXI_ARADDR(M_AXI_ARADDR),
.M_AXI_ARLEN(M_AXI_ARLEN),
.M_AXI_ARSIZE(M_AXI_ARSIZE),
.M_AXI_ARBURST(M_AXI_ARBURST),
.M_AXI_ARLOCK(M_AXI_ARLOCK),
.M_AXI_ARCACHE(M_AXI_ARCACHE),
.M_AXI_ARPROT(M_AXI_ARPROT),
.M_AXI_ARQOS(M_AXI_ARQOS),
.M_AXI_ARUSER(M_AXI_ARUSER),
.M_AXI_ARVALID(M_AXI_ARVALID),
.M_AXI_ARREADY(M_AXI_ARREADY),
.M_AXI_RID(M_AXI_RID),
.M_AXI_RDATA(M_AXI_RDATA),
.M_AXI_RRESP(M_AXI_RRESP),
.M_AXI_RLAST(M_AXI_RLAST),
.M_AXI_RUSER(M_AXI_RUSER),
.M_AXI_RVALID(M_AXI_RVALID),
.M_AXI_RREADY(M_AXI_RREADY),
.write_clk(write_clk),
.write_rst(write_rst),
.write_adfifo_wr_ena(write_adfifo_wr_ena),
.write_adfifo_addr(write_adfifo_addr),
.write_adfifo_awlen(write_adfifo_awlen),
.write_adfifo_full(write_adfifo_full),
.write_fifo_wr_ena(write_fifo_wr_ena),
.write_fifo_write_data(write_fifo_write_data),
.write_fifo_wstrb(write_fifo_wstrb),
.write_fifo_full(write_fifo_full),
.wirte_fifo_almost_full(wirte_fifo_almost_full),
.read_clk(read_clk),
.read_rst(read_rst),
.read_adfifo_wr_ena(read_adfifo_wr_ena),
.read_adfifo_addr(read_adfifo_addr),
.read_adfifo_arlen(read_adfifo_arlen),
.read_adfifo_full(read_adfifo_full),
.read_fifo_rd_ena(read_fifo_rd_ena),
.read_fifo_read_data(read_fifo_read_data),
.read_fifo_empty_n(read_fifo_empty_n),
.read_fifo_almost_empty_n(read_fifo_almost_empty_n),
.wr_resp_err(wr_resp_err),
.init_done(init_done)
);
// Write
initial begin
// Initialize Inputs
write_adfifo_wr_ena = 0;
write_adfifo_addr = 0;
write_adfifo_awlen = 0;
write_fifo_wr_ena = 0;
write_fifo_write_data = 0;
write_fifo_wstrb = 0;
init_done = 0;
// Wait 100 ns for global reset to finish
#1000;
// Add stimulus here
init_done = 1'b1;
AXI4_Write_Trans_Auto(32'h11220000, 8'd0, 64'h2233445566778890, 8'hf0);
AXI4_Write_Trans_Auto(32'h12340000, 8'd7, 64'h123456789ABCDEF0, 8'hff);
AXI4_Write_Trans_Auto(32'h56780000, 8'd15, 64'h1122334455667788, 8'hff);
AXI4_Write_Addr_Trans(32'h67890000, 8'd31);
AXI4_Write_Addr_Trans(32'h789A0000, 8'd63);
AXI4_Write_Data_Trans(64'h33445566778899A0, 8'hff, 8'd31);
AXI4_Write_Data_Trans(64'h445566778899AAB0, 8'hff, 8'd63);
end
// Read
assign read_fifo_rd_ena = read_fifo_empty_n;
initial begin
// Initialize Inputs
read_adfifo_wr_ena = 0;
read_adfifo_addr = 0;
read_adfifo_arlen = 0;
// Wait 100 ns for global reset to finish
#1000;
// Add stimulus here
AXI4_Read_Trans_Auto(32'h11220000, 8'd0);
AXI4_Read_Trans_Auto(32'h12340000, 8'd7);
AXI4_Read_Trans_Auto(32'h56780000, 8'd15);
AXI4_Read_Trans_Auto(32'h67890000, 8'd127);
end
// Write Channel Task
task AXI4_Write_Trans_Auto;
input [31:0] write_addr;
input [7:0] awlen; // 転送長-1
input [63:0] start_wdata; // wdataは1バーストごとに+1される
input [7:0] wstb;
integer i;
begin
AXI4_Write_Addr_Trans(write_addr, awlen);
AXI4_Write_Data_Trans(start_wdata, wstb, awlen);
end
endtask
task AXI4_Write_Addr_Trans;
input [31:0] write_addr;
input [7:0] awlen; // 転送長-1
begin
// アドレスと転送長をWrite
write_adfifo_addr = write_addr;
write_adfifo_awlen = awlen;
while(write_adfifo_full) begin // fullが0になるまでWait
@(posedge write_clk); // 次のクロックへ
#DELAY;
end
@(posedge write_clk); // 次のクロックへ
#DELAY;
write_adfifo_wr_ena = 1'b1;
@(posedge write_clk); // 次のクロックへ
#DELAY;
write_adfifo_wr_ena = 1'b0;
end
endtask
task AXI4_Write_Data_Trans;
input [63:0] start_wdata; // wdataは1バーストごとに+1される
input [7:0] wstb;
input [7:0] awlen;
integer i;
begin
// 転送データをWrite、データは+1する
write_fifo_wstrb = wstb;
write_fifo_wr_ena = 1'b1;
for (i=0; i<awlen+1; i=i+1) begin
while(write_fifo_full) begin // fullが0になるまでWait
@(posedge write_clk); // 次のクロックへ
#DELAY;
end
write_fifo_write_data = start_wdata;
@(posedge write_clk); // 次のクロックへ
#DELAY;
start_wdata = start_wdata + 1;
end
write_fifo_wr_ena = 1'b0;
@(posedge write_clk); // 次のクロックへ
#DELAY;
end
endtask
// Read Channel Task
task AXI4_Read_Trans_Auto;
input [31:0] read_addr;
input [7:0] arlen; // 転送長-1
begin
// アドレスと転送長をWrite
read_adfifo_addr = read_addr;
read_adfifo_arlen = arlen;
while(read_adfifo_full) begin // fullが0になるまでWait
@(posedge read_clk); // 次のクロックへ
#DELAY;
end
@(posedge read_clk); // 次のクロックへ
#DELAY;
read_adfifo_wr_ena = 1'b1;
@(posedge read_clk); // 次のクロックへ
#DELAY;
read_adfifo_wr_ena = 1'b0;
end
endtask
// clk_gen のインスタンス(ACLK)
clk_gen #(
.CLK_PERIOD(50), // 10nsec, 100MHz
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) ACLKi (
.clk_out(ACLK)
);
// reset_gen のインスタンス
reset_gen #(
.RESET_STATE(1'b0),
.RESET_TIME(1000) // 100nsec
) RESETi (
.reset_out(ARESETN),
.init_done()
);
// clk_gen のインスタンス(write_clk, read_clk)
clk_gen #(
.CLK_PERIOD(67), // 6.7nsec, 149.3MHz(本当は148.5MHz)
.CLK_DUTY_CYCLE(0.5),
.CLK_OFFSET(0),
.START_STATE(1'b0)
) WRITE_CLKi (
.clk_out(write_clk)
);
assign read_clk = write_clk;
// reset_gen のインスタンス
reset_gen #(
.RESET_STATE(1'b1),
.RESET_TIME(1000) // 100nsec
) WRITE_RSTi (
.reset_out(write_rst),
.init_done()
);
assign read_rst = write_rst;
// Instantiate the Unit Under Test (UUT_slave)
axi_slave_bfm # (
.C_M_AXI_DATA_WIDTH(64),
.WRITE_RANDOM_WAIT(1), // Write Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
.READ_RANDOM_WAIT(1), // Read Transaction のデータ転送の時にランダムなWaitを発生させる=1, Waitしない=0
.READ_DATA_IS_INCREMENT(1), // ReadトランザクションでRAMの内容をReadする = 0(RAMにWriteしたものをReadする)、Readデータを+1する = 1(データは+1したデータをReadデータとして使用する
.RUNDAM_BVALID_WAIT(1)
) uut_slave (
.ACLK(ACLK),
.ARESETN(ARESETN),
.M_AXI_AWID(M_AXI_AWID),
.M_AXI_AWADDR(M_AXI_AWADDR),
.M_AXI_AWLEN(M_AXI_AWLEN),
.M_AXI_AWSIZE(M_AXI_AWSIZE),
.M_AXI_AWBURST(M_AXI_AWBURST),
.M_AXI_AWLOCK({1'b0, M_AXI_AWLOCK}),
.M_AXI_AWCACHE(M_AXI_AWCACHE),
.M_AXI_AWPROT(M_AXI_AWPROT),
.M_AXI_AWQOS(M_AXI_AWQOS),
.M_AXI_AWUSER(M_AXI_AWUSER),
.M_AXI_AWVALID(M_AXI_AWVALID),
.M_AXI_AWREADY(M_AXI_AWREADY),
.M_AXI_WDATA(M_AXI_WDATA),
.M_AXI_WSTRB(M_AXI_WSTRB),
.M_AXI_WLAST(M_AXI_WLAST),
.M_AXI_WUSER(M_AXI_WUSER),
.M_AXI_WVALID(M_AXI_WVALID),
.M_AXI_WREADY(M_AXI_WREADY),
.M_AXI_BID(M_AXI_BID),
.M_AXI_BRESP(M_AXI_BRESP),
.M_AXI_BUSER(M_AXI_BUSER),
.M_AXI_BVALID(M_AXI_BVALID),
.M_AXI_BREADY(M_AXI_BREADY),
.M_AXI_ARID(M_AXI_ARID),
.M_AXI_ARADDR(M_AXI_ARADDR),
.M_AXI_ARLEN(M_AXI_ARLEN),
.M_AXI_ARSIZE(M_AXI_ARSIZE),
.M_AXI_ARBURST(M_AXI_ARBURST),
.M_AXI_ARLOCK(M_AXI_ARLOCK),
.M_AXI_ARCACHE(M_AXI_ARCACHE),
.M_AXI_ARPROT(M_AXI_ARPROT),
.M_AXI_ARQOS(M_AXI_ARQOS),
.M_AXI_ARUSER(M_AXI_ARUSER),
.M_AXI_ARVALID(M_AXI_ARVALID),
.M_AXI_ARREADY(M_AXI_ARREADY),
.M_AXI_RID(M_AXI_RID),
.M_AXI_RDATA(M_AXI_RDATA),
.M_AXI_RRESP(M_AXI_RRESP),
.M_AXI_RLAST(M_AXI_RLAST),
.M_AXI_RUSER(M_AXI_RUSER),
.M_AXI_RVALID(M_AXI_RVALID),
.M_AXI_RREADY(M_AXI_RREADY)
);
endmodule
module clk_gen #(
parameter CLK_PERIOD = 100,
parameter real CLK_DUTY_CYCLE = 0.5,
parameter CLK_OFFSET = 0,
parameter START_STATE = 1'b0 )
(
output reg clk_out
);
begin
initial begin
#CLK_OFFSET;
forever
begin
clk_out = START_STATE;
#(CLK_PERIOD-(CLK_PERIOD*CLK_DUTY_CYCLE)) clk_out = ~START_STATE;
#(CLK_PERIOD*CLK_DUTY_CYCLE);
end
end
end
endmodule
module reset_gen #(
parameter RESET_STATE = 1'b1,
parameter RESET_TIME = 100 )
(
output reg reset_out,
output reg init_done
);
begin
initial begin
reset_out = RESET_STATE;
init_done = 1'b0;
#RESET_TIME;
reset_out = ~RESET_STATE;
init_done = 1'b1;
end
end
endmodule
`default_nettype wire
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | - | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |