・AXI_LiteM_1Seq_Write(Write Address, Write Data, Write Response をシーケンシャルにオーバーラップせずに行う)
・AXI_LiteM_WAC(Write Address Channel の Transaction を実行する)
・AXI_LiteM_WDC(Write Data Channel の Transaction を実行する)
・AXI_LiteM_WRC(Write Response Channel の Transaction を実行する)
・AXI_LiteM_1Seq_Read(Read Address, Read Data をシーケンシャルに行う)
・AXI_LiteM_RAC(Read Address Channel の Transaction を実行する)
・AXI_LiteM_RDC(Read Data Channel の Transaction を実行する)
// AXI4 bus Lite Master Bus Fucntion Mode
// 2013/12/14
// AXI4_Master_BFM のラッパー
//
//
`default_nettype none
`timescale 100ps / 1ps
module AXI4_Lite_Master_BFM #(
parameter DELAY = 10 )
(
input wire ACLK,
output wire [31:0] S_AXI_AWADDR,
output wire [2:0] S_AXI_AWPROT,
output wire S_AXI_AWVALID,
output wire [31:0] S_AXI_WDATA,
output wire [3:0] S_AXI_WSTRB,
output wire S_AXI_WVALID,
output wire S_AXI_BREADY,
output wire [31:0] S_AXI_ARADDR,
output wire [2:0] S_AXI_ARPROT,
output wire S_AXI_ARVALID,
output wire S_AXI_RREADY,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [1:0] S_AXI_BRESP,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RVALID
);
parameter ASIZE_BT_4 = 3'd2; // 32 bit width
parameter ASIZE_BT_2 = 3'd1; // 16 bit width
parameter ASIZE_BT_1 = 3'd0; // 8 bit width
parameter ABURST_FIXED = 2'd0;
parameter ABURST_INCR = 2'd1;
parameter ABURST_WRAP = 2'd2;
// RESP の値の定義
parameter RESP_OKAY = 2'b00;
parameter RESP_EXOKAY = 2'b01;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
reg [7:0] awlen_hold = 0;
reg [0:0] wid_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
// AXI4_BFM のインスタンス
AXI4_Master_BFM #(.DELAY(DELAY)) MBFMi(
.ACLK(ACLK),
.S_AXI_AWID(),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWLEN(),
.S_AXI_AWSIZE(),
.S_AXI_AWBURST(),
.S_AXI_AWLOCK(),
.S_AXI_AWCACHE(),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWREGION(),
.S_AXI_AWQOS(),
.S_AXI_AWUSER(),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WID(),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WLAST(),
.S_AXI_WUSER(),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BID(1'b0),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BUSER(1'b0),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARID(),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARLEN(),
.S_AXI_ARSIZE(),
.S_AXI_ARBURST(),
.S_AXI_ARLOCK(),
.S_AXI_ARCACHE(),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARREGION(),
.S_AXI_ARQOS(),
.S_AXI_ARUSER(),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RID(1'b0),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RLAST(1'b1),
.S_AXI_RUSER(1'b0),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// Write Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_LiteM_1Seq_Write; // Write Address, Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [31:0] awaddr;
input [31:0] wdata;
input [7:0] wait_clk_bready;
input [7:0] wmax_wait;
begin
MBFMi.AXI_Master_1Seq_Write(1'b0, awaddr, 8'd0, ASIZE_BT_4, ABURST_INCR, wdata, wait_clk_bready, wmax_wait);
end
endtask
// Write Address Channel
task AXI_LiteM_WAC;
input [31:0] awaddr;
begin
MBFMi.AXI_MASTER_WAC(1'b0, awaddr, 8'd0, ASIZE_BT_4, ABURST_INCR);
end
endtask
// Write Data Channel
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_LiteM_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
input [7:0] wmax_wait; // Write時の最大wait数
begin
MBFMi.AXI_MASTER_WDC(wdata, wmax_wait);
end
endtask
// Write Response Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
task AXI_LiteM_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
begin
MBFMi.AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Read Channel
task AXI_LiteM_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [31:0] araddr;
input [7:0] rmax_wait; // Read時の最大wait数
begin
MBFMi.AXI_Master_1Seq_Read(1'b0, araddr, 8'd0, ASIZE_BT_4, ABURST_INCR);
end
endtask
// Read Address Channel
task AXI_LiteM_RAC;
input [31:0] araddr;
begin
MBFMi.AXI_MASTER_RAC(1'b0, araddr, 8'd0, ASIZE_BT_4, ABURST_INCR);
end
endtask
// Read Data Channel
task AXI_LiteM_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
input [7:0] rmax_wait; // Read時の最大wait数
begin
MBFMi.AXI_MASTER_RDC(rmax_wait);
end
endtask
endmodule
`default_nettype wire
// OVL_Checker.v
// 2012/10/25:書き込みトランザクションの時に、MasterがAWREADYを待って、WVALIDをアサートしていけないというルールがあったので、修正した。
//
`default_nettype none
`timescale 100ps / 1ps
`include "std_ovl_defines.h"
module OVL_Checker (
input wire ACLK,
input wire ARESETN,
input wire [0:0] S_AXI_AWID,
input wire [31:0] S_AXI_AWADDR,
input wire [7:0] S_AXI_AWLEN,
input wire [2:0] S_AXI_AWSIZE,
input wire [1:0] S_AXI_AWBURST,
input wire [1:0] S_AXI_AWLOCK,
input wire [3:0] S_AXI_AWCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_AWPROT,
input wire [3:0] S_AXI_AWREGION,
input wire [3:0] S_AXI_AWQOS,
input wire [0:0] S_AXI_AWUSER,
input wire S_AXI_AWVALID,
input wire [0:0] S_AXI_WID,
input wire [31:0] S_AXI_WDATA,
input wire [3:0] S_AXI_WSTRB,
input wire S_AXI_WLAST,
input wire [0:0] S_AXI_WUSER,
input wire S_AXI_WVALID,
input wire S_AXI_BREADY,
input wire [0:0] S_AXI_ARID,
input wire [31:0] S_AXI_ARADDR,
input wire [7:0] S_AXI_ARLEN,
input wire [2:0] S_AXI_ARSIZE,
input wire [1:0] S_AXI_ARBURST,
input wire [1:0] S_AXI_ARLOCK,
input wire [3:0] S_AXI_ARCACHE, // Normal Non-cacheable Non-bufferable
input wire [2:0] S_AXI_ARPROT,
input wire [3:0] S_AXI_ARREGION,
input wire [3:0] S_AXI_ARQOS,
input wire [0:0] S_AXI_ARUSER,
input wire S_AXI_ARVALID,
input wire S_AXI_RREADY,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
wire [`OVL_FIRE_WIDTH-1:0] fire_wr_data, fire_rd_data;
wire [`OVL_FIRE_WIDTH-1:0] fire_aw_hcheck, fire_ar_hcheck;
wire [`OVL_FIRE_WIDTH-1:0] fire_awvalid_cont, fire_wd_sig_assert;
wire [`OVL_FIRE_WIDTH-1:0] fire_ar_never;
reg [7:0] countw, countr;
parameter idle_wts = 3'b001,
wr_data_tran = 3'b010,
wr_resp_tran = 3'b100;
reg [2:0] wr_tran_cs;
parameter idle_rts = 1'b0,
rd_data_tran = 1'b1;
reg rd_trans_cs;
// Wirte Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Write data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) wr_data_check (
ACLK, // clock
~ARESETN | (S_AXI_AWVALID & S_AXI_AWREADY), // reset, Write のアドレス転送でリセット
S_AXI_WVALID & S_AXI_WREADY, // enable
S_AXI_WDATA, // test_expr
fire_wr_data // fire parameter
);
// Read Transaction データが+1されていることをチェックする(BFM Check)
ovl_increment #(
`OVL_ERROR, // severity_level
32, // width
1, // value
`OVL_ASSERT, // property_type
"Error: Read data has not been incremented", // msg
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_HIGH, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) rd_data_check (
ACLK, // clock
~ARESETN | (S_AXI_ARVALID & S_AXI_ARREADY), // reset, Read のアドレス転送でリセット
S_AXI_RVALID & S_AXI_RREADY, // enable
S_AXI_RDATA, // test_expr
fire_rd_data // fire parameter
);
// S_AXI_AWVALID とS_AXI_AWREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_AWREADY and S_AXI_AWVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) aw_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // req
S_AXI_AWREADY, // ack
fire_aw_hcheck // fire parameter
);
// S_AXI_ARVALID とS_AXI_ARREADY のハンドシェークのテスト
ovl_handshake #(
`OVL_ERROR, // severity_level
1, // min_ack_cycle
32, // max_ack_cycle
1, // req_drop
1, // deassert_count
1, // max_ack_length
`OVL_ASSERT, // property_type
"Error: Handshake Error of S_AXI_ARREADY and S_AXI_ARVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock_edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_handshake_check (
ACLK, // clock
ARESETN, // reset
1'b1, // enable
S_AXI_ARVALID, // req
S_AXI_ARREADY, // ack
fire_ar_hcheck // fire parameter
);
// Write, S_AXI_AWREADY がアサートされるとき、次のクロックでS_AXI_AWVALIDがディアサートされる
ovl_transition #(
`OVL_ERROR, // severity_level
1, // width
`OVL_ASSERT, // property_type
"Error : Assert of S_AXI_AWVALID",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) awvalid_cont_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // test_expr
S_AXI_AWREADY & S_AXI_AWVALID, // start_state
~S_AXI_AWVALID, // next_state
fire_awvalid_cont
);
// Write, S_AXI_WVALID, S_AXI_WLAST, S_AXI_WREADYがアサートされるとき、次のクロックで、それらの信号がディアサートされる
ovl_transition #(
`OVL_ERROR, // severity_level
1, // width
`OVL_ASSERT, // property_type
"Error : Assert of S_AXI_WVALID or S_AXI_WLAST or S_AXI_WREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) wd_sig_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_AWVALID, // test_expr
S_AXI_WVALID & S_AXI_WLAST & S_AXI_WREADY, // start_state
~(S_AXI_WVALID | S_AXI_WLAST | S_AXI_WREADY), // next_state
fire_wd_sig_assert
);
// Read, S_AXI_RREADY がアサートされるときは、 S_AXI_RVALID, S_AXI_RREADY, S_AXI_RLAST はアサートされない
ovl_never #(
`OVL_ERROR, // severity_level
`OVL_ASSERT, // property_type
"Read, Assert Error of S_AXI_RREADY",
`OVL_COVER_DEFAULT, // coverage_level
`OVL_POSEDGE, // clock edge
`OVL_ACTIVE_LOW, // reset_polarity
`OVL_GATE_CLOCK // gating_type
) ar_never_assert (
ACLK, // clock_edge
ARESETN, // reset
1'b1, // enable
S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST),
fire_ar_never
);
// Write の転送数をカウントして、 S_AXI_WLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countw <= 0;
else begin
if (S_AXI_AWVALID & S_AXI_AWREADY) begin // countw へロード
countw <= S_AXI_AWLEN;
end else if (S_AXI_WVALID & S_AXI_WREADY) begin // データ転送
if (countw==0) begin // データ転送終了
if (~S_AXI_WLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countw==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Read の転送数をカウントして、 S_AXI_RLAST の出力を確認するアサーション
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
countr <= 0;
else begin
if (S_AXI_ARVALID & S_AXI_ARREADY) begin // countw へロード
countr <= S_AXI_ARLEN;
end else if (S_AXI_RVALID & S_AXI_RREADY) begin // データ転送
if (countr==0) begin // データ転送終了
if (~S_AXI_RLAST) begin // countw==0 でS_AXI_WLASTが立たない
$display("%m: at time %t Error: countr==0 でS_AXI_WLASTが立たない",$time);
end
end
end
end
end
// Write 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
wr_tran_cs <= idle_wts;
else begin
case (wr_tran_cs)
idle_wts :
if (S_AXI_AWREADY & (S_AXI_BREADY)) // エラー
$display("%m: at time %t S_AXI_AWREADY がアサートされた時に、BREADY信号がアサートされた",$time);
else if (S_AXI_AWVALID & S_AXI_AWREADY) // アドレス転送終了
wr_tran_cs <= wr_data_tran;
wr_data_tran :
if (S_AXI_BREADY) // エラー
$display("%m: at time %t Write データ転送中に、S_AXI_BREADY がアサートされた",$time);
else if (S_AXI_WVALID & S_AXI_WREADY & S_AXI_WLAST) // データ転送終了
wr_tran_cs <= wr_resp_tran;
wr_resp_tran :
if (S_AXI_AWREADY | S_AXI_WVALID | S_AXI_WREADY | S_AXI_WLAST) // エラー
$display("%m: at time %t Write Response Channel 転送時に関連しない信号がアサートされた",$time);
else if (S_AXI_BVALID & S_AXI_BREADY) // Write Response Channel 転送終了
wr_tran_cs <= idle_wts;
endcase
end
end
// Read 動作用ステートマシン
always @(posedge ACLK) begin
if (ARESETN == 1'b0)
rd_trans_cs <= idle_rts;
else begin
case (rd_trans_cs)
idle_rts :
if (S_AXI_ARREADY & (S_AXI_RVALID | S_AXI_RREADY | S_AXI_RLAST)) // エラー
$display("%m: at time %t S_AXI_ARREADY がアサートされた時に、その他のVALID, READY信号がアサートされた",$time);
else if (S_AXI_ARVALID & S_AXI_ARREADY) // アドレス転送終了
rd_trans_cs <= rd_data_tran;
rd_data_tran :
if (S_AXI_ARREADY) // エラー
$display("%m: at time %t Read データ転送中に、S_AXI_ARREADY がアサートされた",$time);
else if (S_AXI_RVALID & S_AXI_RREADY & S_AXI_RLAST) // データ転送終了
rd_trans_cs <= idle_rts;
endcase
end
end
endmodule
`default_nettype wire
Command Line: fuse -intstyle ise -incremental -i K:/HDL/OVL/std_ovl_v2p6 -d OVL_VERILOG -d OVL_ASSERT_ON -d OVL_FINISH_OFF -lib unisims_ver -lib unimacro_ver -lib xilinxcorelib_ver -lib secureip -o H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_isim_beh.exe -prj H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_beh.prj work.CDC_axi_slave_tb work.glbl {-L accellera_ovl_vlog=K:\HDL\Xilinx\13.4\ISE_DS\ISE\verilog\hdp\nt\accellera_ovl_vlog}
Running: K:\HDL\Xilinx\14.1\ISE_DS\ISE\bin\nt\unwrapped\fuse.exe -intstyle ise -incremental -i K:/HDL/OVL/std_ovl_v2p6 -d OVL_VERILOG -d OVL_ASSERT_ON -d OVL_FINISH_OFF -lib unisims_ver -lib unimacro_ver -lib xilinxcorelib_ver -lib secureip -o H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_isim_beh.exe -prj H:/HDL/FndtnISEWork/Spartan6/Atlys/Atlys_XPS_CDC_SVGA_141/pcores/cdc_axi_slave_v1_00_a/CDC_axi_slave/CDC_axi_slave_tb_beh.prj work.CDC_axi_slave_tb work.glbl -L accellera_ovl_vlog=K:\HDL\Xilinx\13.4\ISE_DS\ISE\verilog\hdp\nt\accellera_ovl_vlog
// AXI4 bus Master Bus Fucntion Mode
// 2012/10/24 : 修正、S_AXI_AWREADYが1になるのを確認してからS_AXI_WVALIDを1にしていたのでは、AXIバスの非標準となる。
// よって、AXI_MASTER_WAC とAXI_MASTER_WDC をfork ~ join で並列に実行する
// 2013/12/14 : input に DELAYを入れるように変更
//
`default_nettype none
`timescale 100ps / 1ps
module AXI4_Master_BFM #(
parameter DELAY = 10 )
(
input wire ACLK,
output reg [0:0] S_AXI_AWID = 0,
output reg [31:0] S_AXI_AWADDR = 0,
output reg [7:0] S_AXI_AWLEN = 0,
output reg [2:0] S_AXI_AWSIZE = 0,
output reg [1:0] S_AXI_AWBURST = 0,
output reg [1:0] S_AXI_AWLOCK = 0,
output reg [3:0] S_AXI_AWCACHE = 3, // Normal Non-cacheable bufferable
output reg [2:0] S_AXI_AWPROT = 0,
output reg [3:0] S_AXI_AWREGION = 0,
output reg [3:0] S_AXI_AWQOS = 0,
output reg [0:0] S_AXI_AWUSER = 0,
output reg S_AXI_AWVALID = 0,
output reg [0:0] S_AXI_WID = 0,
output reg [31:0] S_AXI_WDATA = 0,
output reg [3:0] S_AXI_WSTRB = 0,
output reg S_AXI_WLAST = 0,
output reg [0:0] S_AXI_WUSER = 0,
output reg S_AXI_WVALID = 0,
output reg S_AXI_BREADY = 0,
output reg [0:0] S_AXI_ARID = 0,
output reg [31:0] S_AXI_ARADDR = 0,
output reg [7:0] S_AXI_ARLEN = 0,
output reg [2:0] S_AXI_ARSIZE = 0,
output reg [1:0] S_AXI_ARBURST = 0,
output reg [1:0] S_AXI_ARLOCK = 0,
output reg [3:0] S_AXI_ARCACHE = 2, // Normal Non-cacheable bufferable
output reg [2:0] S_AXI_ARPROT = 0,
output reg [3:0] S_AXI_ARREGION = 0,
output reg [3:0] S_AXI_ARQOS = 0,
output reg [0:0] S_AXI_ARUSER = 0,
output reg S_AXI_ARVALID = 0,
output reg S_AXI_RREADY = 0,
input wire S_AXI_AWREADY,
input wire S_AXI_WREADY,
input wire [0:0] S_AXI_BID,
input wire [1:0] S_AXI_BRESP,
input wire [0:0] S_AXI_BUSER,
input wire S_AXI_BVALID,
input wire S_AXI_ARREADY,
input wire [0:0] S_AXI_RID,
input wire [31:0] S_AXI_RDATA,
input wire [1:0] S_AXI_RRESP,
input wire S_AXI_RLAST,
input wire [0:0] S_AXI_RUSER,
input wire S_AXI_RVALID
);
reg [7:0] awlen_hold = 0;
reg [0:0] wid_hold = 0;
reg axi_w_transaction_active = 0;
reg axi_r_transaction_active = 0;
reg [7:0] arlen_hold = 0;
reg S_AXI_AWREADY_d;
reg S_AXI_WREADY_d;
reg [0:0] S_AXI_BID_d;
reg [1:0] S_AXI_BRESP_d;
reg [0:0] S_AXI_BUSER_d;
reg S_AXI_BVALID_d;
reg S_AXI_ARREADY_d;
reg [0:0] S_AXI_RID_d;
reg [31:0] S_AXI_RDATA_d;
reg [1:0] S_AXI_RRESP_d;
reg S_AXI_RLAST_d;
reg [0:0] S_AXI_RUSER_d;
reg S_AXI_RVALID_d;
always @* S_AXI_AWREADY_d <= #DELAY S_AXI_AWREADY;
always @* S_AXI_WREADY_d <= #DELAY S_AXI_WREADY;
always @* S_AXI_BID_d <= #DELAY S_AXI_BID;
always @* S_AXI_BRESP_d <= #DELAY S_AXI_BRESP;
always @* S_AXI_BUSER_d <= #DELAY S_AXI_BUSER;
always @* S_AXI_BVALID_d <= #DELAY S_AXI_BVALID;
always @* S_AXI_ARREADY_d <= #DELAY S_AXI_ARREADY;
always @* S_AXI_RID_d <= #DELAY S_AXI_RID;
always @* S_AXI_RDATA_d <= #DELAY S_AXI_RDATA;
always @* S_AXI_RRESP_d <= #DELAY S_AXI_RRESP;
always @* S_AXI_RLAST_d <= #DELAY S_AXI_RLAST;
always @* S_AXI_RUSER_d <= #DELAY S_AXI_RUSER;
always @* S_AXI_RVALID_d <= #DELAY S_AXI_RVALID;
// Write Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_Master_1Seq_Write; // Write Address; Write Data, Write Response をシーケンシャルにオーバーラップせずに行う。
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
input [31:0] wdata;
input [7:0] wait_clk_bready;
input [7:0] wmax_wait;
begin
fork
AXI_MASTER_WAC(awid, awaddr, awlen, awsize, awburst);
AXI_MASTER_WDC(wdata, wmax_wait);
join
AXI_MASTER_WRC(wait_clk_bready);
end
endtask
// Write Address Channel
task AXI_MASTER_WAC;
input [0:0] awid;
input [31:0] awaddr;
input [7:0] awlen;
input [2:0] awsize;
input [1:0] awburst;
begin
S_AXI_AWID = awid;
S_AXI_AWADDR = awaddr;
S_AXI_AWLEN = awlen;
S_AXI_AWSIZE = awsize;
S_AXI_AWBURST = awburst;
S_AXI_AWVALID = 1'b1;
if (axi_w_transaction_active == 1'b0) begin // AXI Write トランザクションが開始されている場合は戻る
axi_w_transaction_active = 1'b1; // AXIトランザクション開始
awlen_hold = awlen; // Write Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_AWREADY_d) begin // S_AXI_AWREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_AWID = 0;
S_AXI_AWADDR = 0;
S_AXI_AWLEN = 0;
S_AXI_AWSIZE = 0;
S_AXI_AWBURST = 0;
S_AXI_AWVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
end
endtask
// Write Data Channel
// wmax_wait : 0 - wvalid の Wait は無し、0以外 - wmax_wait を最大値とするランダムな値の Wait が wvalid に入る
task AXI_MASTER_WDC; // WDATA は+1する
// とりあえず、WSTRBはオール1にする
input [31:0] wdata;
input [7:0] wmax_wait; // Write時の最大wait数
integer i, j, val;
begin
i = 0; j = 0;
S_AXI_WSTRB = 4'b1111;
while (~S_AXI_AWVALID) begin // S_AXI_AWVALID が1になるまで待つ
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
while (i<=awlen_hold) begin
if (wmax_wait == 0) // wmax_wait が0の時は$random を実行しない
val = 0;
else
val = $unsigned($random) % (wmax_wait+1);
if (val == 0) begin // waitなし
S_AXI_WVALID = 1'b1;
end else begin // waitあり
S_AXI_WVALID = 1'b0;
for (j=0; j<val; j=j+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_WVALID = 1'b1; // wait終了
end
if (i == awlen_hold)
S_AXI_WLAST = 1'b1;
else
S_AXI_WLAST = 1'b0;
S_AXI_WDATA = wdata;
wdata = wdata + 1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_WREADY_d) begin // S_AXI_WREADY が0の時は1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
i = i + 1;
end
S_AXI_WVALID = 1'b0;
S_AXI_WLAST = 1'b0;
S_AXI_WSTRB = 4'b0000;
end
endtask
// Write Response Channel
// wait_clk_bready : 0 - bready の Wait は無し、0以外 - bready の Wait は wait_clk_bready の値の Wait が入る
task AXI_MASTER_WRC; // wait_clk_bready
input [7:0] wait_clk_bready;
integer i;
begin
for (i=0; i<wait_clk_bready; i=i+1) begin
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_BREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_BVALID_d) begin // S_AXI_BVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_BREADY = 1'b0;
axi_w_transaction_active = 1'b0; // AXIトランザクション終了
@(posedge ACLK);
#DELAY;
end
endtask
// Read Channel
task AXI_Master_1Seq_Read; // Read Address, Read Data をシーケンシャルに行う。
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
input [7:0] rmax_wait; // Read時の最大wait数
begin
AXI_MASTER_RAC(arid, araddr, arlen, arsize, arburst);
AXI_MASTER_RDC(rmax_wait);
end
endtask
// Read Address Channel
task AXI_MASTER_RAC;
input [0:0] arid;
input [31:0] araddr;
input [7:0] arlen;
input [2:0] arsize;
input [1:0] arburst;
begin
S_AXI_ARID = arid;
S_AXI_ARADDR = araddr;
S_AXI_ARLEN = arlen;
S_AXI_ARSIZE = arsize;
S_AXI_ARBURST = arburst;
S_AXI_ARVALID = 1'b1;
if (axi_r_transaction_active == 1'b0) begin // AXI Read トランザクションが開始されている場合は戻る
arlen_hold =arlen; // Read Data Channel のためにバースト数を取っておく
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY_d) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARID = 0;
S_AXI_ARADDR = 0;
S_AXI_ARLEN = 0;
S_AXI_ARSIZE = 0;
S_AXI_ARBURST = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
axi_r_transaction_active = 1'b1; // AXIトランザクション開始
end
end
endtask
// Read Data Channel
task AXI_MASTER_RDC; // S_AXI_RLAST がアサートされるまでS_AXI_RREADY をアサートする
input [7:0] rmax_wait; // Read時の最大wait数
integer i, val;
begin
while (~(S_AXI_RLAST_d & S_AXI_RVALID_d & S_AXI_RREADY)) begin // S_AXI_RLAST & S_AXI_RVALID & S_AXI_RREADY で終了
if (rmax_wait == 0) begin // rmax_wait が0の時は$random を実行しない
val = 0;
S_AXI_RREADY = 1'b1;
end else begin
val = $unsigned($random) % (rmax_wait+1);
if (val == 0)
S_AXI_RREADY = 1'b1;
else
S_AXI_RREADY = 1'b0;
end
#DELAY;
for (i=0; i<val; i=i+1) begin // ランダム値でWait、val=0の時はスキップ
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_RVALID_d) begin // S_AXI_RVALID が1になるまでWait
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
end
#DELAY;
S_AXI_RREADY = 1'b0;
axi_r_transaction_active = 1'b0; // AXIトランザクション終了
@(posedge ACLK);
#DELAY;
end
endtask
endmodule
`default_nettype wire
/* * char_rom_axi_lite_test.c * * Created on: 2012/06/17 * Author: Masaaki */
#include "xbasic_types.h"
#include "xio.h"
#include "mb_interface.h"
#include "xparameters.h"
#include "stdio.h"
int main()
{
unsigned char c;
unsigned char hex_char[20];
unsigned int addr, cr_data;
int j;
for(;;){
xil_printf("Please input Character ROM Address ");
for(j=0; j<19; j++){
c = getc(stdin);
if (c == '\r'){
hex_char[j] = c;
break;
}else
hex_char[j] = c; // 文字列に代入
}
addr = 0;
for(j=0; j<19; j+=2){ // 文字の解析
if (hex_char[j] == '\r')
break;
else{
addr = addr << 4; // 4ビット左シフト
if (hex_char[j]>=0x30 && hex_char[j]<=0x39) // 数字
addr += hex_char[j] - 0x30;
else if (hex_char[j]>=0x41 && hex_char[j]<=0x46) // A ~ F
addr += hex_char[j] - 0x41 + 10;
else if (hex_char[j]>=0x61 && hex_char[j]<=0x66) // a ~ f
addr += hex_char[j] - 0x61 + 10;
}
}
xil_printf("\n");
cr_data = *(volatile unsigned int *)(XPAR_CHAR_ROM_AXI_LITE_0_S_AXI_RNG00_BASEADDR+addr);
xil_printf("Character ROM Data = %x\n", cr_data);
}
}
`timescale 100ps / 1ps
`default_nettype wire
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 18:53:35 06/14/2012
// Design Name: char_rom_axi_lite
// Module Name: H:/HDL/FndtnISEWork/Spartan6/Atlys/test/Atlys_EDK_test_PA/Atlys_EDK_test_PA.srcs/sources_1/edk/system/pcores/char_rom_axi_lite_v1_00_a/char_rom_axi_lite/char_rom_axi_lite_tb.v
// Project Name: char_rom_axi_lite
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: char_rom_axi_lite
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
module char_rom_axi_lite_tb;
// Inputs
wire ACLK;
wire ARESETN;
reg [31:0] S_AXI_AWADDR = 0;
reg [2:0] S_AXI_AWPROT = 0;
reg S_AXI_AWVALID = 0;
reg [31:0] S_AXI_WDATA = 0;
reg [3:0] S_AXI_WSTRB = 0;
reg S_AXI_WVALID = 0;
reg S_AXI_BREADY = 0;
reg [31:0] S_AXI_ARADDR = 0;
reg [2:0] S_AXI_ARPROT = 0;
reg S_AXI_ARVALID = 0;
reg S_AXI_RREADY = 0;
// Outputs
wire S_AXI_AWREADY;
wire S_AXI_WREADY;
wire [1:0] S_AXI_BRESP;
wire S_AXI_BVALID;
wire S_AXI_ARREADY;
wire [31:0] S_AXI_RDATA;
wire [1:0] S_AXI_RRESP;
wire S_AXI_RVALID;
parameter DELAY = 10;
// Instantiate the Unit Under Test (UUT)
char_rom_axi_lite uut (
.ACLK(ACLK),
.ARESETN(ARESETN),
.S_AXI_AWADDR(S_AXI_AWADDR),
.S_AXI_AWPROT(S_AXI_AWPROT),
.S_AXI_AWVALID(S_AXI_AWVALID),
.S_AXI_AWREADY(S_AXI_AWREADY),
.S_AXI_WDATA(S_AXI_WDATA),
.S_AXI_WSTRB(S_AXI_WSTRB),
.S_AXI_WVALID(S_AXI_WVALID),
.S_AXI_WREADY(S_AXI_WREADY),
.S_AXI_BRESP(S_AXI_BRESP),
.S_AXI_BVALID(S_AXI_BVALID),
.S_AXI_BREADY(S_AXI_BREADY),
.S_AXI_ARADDR(S_AXI_ARADDR),
.S_AXI_ARPROT(S_AXI_ARPROT),
.S_AXI_ARVALID(S_AXI_ARVALID),
.S_AXI_ARREADY(S_AXI_ARREADY),
.S_AXI_RDATA(S_AXI_RDATA),
.S_AXI_RRESP(S_AXI_RRESP),
.S_AXI_RVALID(S_AXI_RVALID),
.S_AXI_RREADY(S_AXI_RREADY)
);
// clk_gen のインスタンス
clk_gen #(
.CLK_PERIOD(100), // 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)
);
initial begin
// Initialize Inputs
S_AXI_AWADDR = 0;
S_AXI_AWPROT = 0;
S_AXI_AWVALID = 0;
S_AXI_WDATA = 0;
S_AXI_WSTRB = 0;
S_AXI_WVALID = 0;
S_AXI_BREADY = 0;
S_AXI_ARADDR = 0;
S_AXI_ARPROT = 0;
S_AXI_ARVALID = 0;
S_AXI_RREADY = 0;
// Wait Reset rising edge
@(posedge ARESETN);
// Add stimulus here
@(posedge ACLK); // 次のクロックへ
#DELAY;
AXI_MASTER_RAC(32'h0000_0100);
AXI_MASTER_RDC;
#DELAY;
@(posedge ACLK); // 次のクロックへ
#DELAY;
AXI_MASTER_RAC(32'h0000_0180);
AXI_MASTER_RDC;
#DELAY;
AXI_MASTER_RAC(32'h0000_0181);
@(posedge ACLK); // 次のクロックへ
#DELAY;
AXI_MASTER_RDC;
end
// Read Address Channel
task AXI_MASTER_RAC;
input [31:0] araddr;
begin
S_AXI_ARADDR = araddr;
S_AXI_ARVALID = 1'b1;
@(posedge ACLK); // 次のクロックへ
while (~S_AXI_ARREADY) begin // S_AXI_ARREADY が1になるまで待つ
#DELAY;
@(posedge ACLK); // 次のクロックへ
end
#DELAY;
S_AXI_ARADDR = 0;
S_AXI_ARVALID = 1'b0;
@(posedge ACLK); // 次のクロックへ
#DELAY;
end
endtask
// Read Data Channel
task AXI_MASTER_RDC;
begin
S_AXI_RREADY = 1'b1;
@(posedge ACLK); // 次のクロックへ
#DELAY;
S_AXI_RREADY = 1'b0;
end
endtask
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
);
begin
initial begin
reset_out = RESET_STATE;
#RESET_TIME;
reset_out = ~RESET_STATE;
end
end
endmodule
`default_nettype wire
`timescale 1ns/1ps
module char_rom_axi_lite #
(
parameter integer C_S_AXI_ADDR_WIDTH = 32,
parameter integer C_S_AXI_DATA_WIDTH = 32
)
(
// System Signals
input wire ACLK,
input wire ARESETN,
// Slave Interface Write Address Ports
input wire [C_S_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
input wire [3-1:0] S_AXI_AWPROT,
input wire S_AXI_AWVALID,
output wire S_AXI_AWREADY,
// Slave Interface Write Data Ports
input wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
input wire [C_S_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
input wire S_AXI_WVALID,
output wire S_AXI_WREADY,
// Slave Interface Write Response Ports
output wire [2-1:0] S_AXI_BRESP,
output wire S_AXI_BVALID,
input wire S_AXI_BREADY,
// Slave Interface Read Address Ports
input wire [C_S_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR,
input wire [3-1:0] S_AXI_ARPROT,
input wire S_AXI_ARVALID,
output wire S_AXI_ARREADY,
// Slave Interface Read Data Ports
output wire [C_S_AXI_DATA_WIDTH-1:0] S_AXI_RDATA,
output wire [2-1:0] S_AXI_RRESP,
output wire S_AXI_RVALID,
input wire S_AXI_RREADY
);
// RESP の値の定義
parameter RESP_OKAY = 2'b00;
parameter RESP_EXOKAY = 2'b01;
parameter RESP_SLVERR = 2'b10;
parameter RESP_DECERR = 2'b11;
parameter IDLE_RD = 3'b001,
AR_DATA_WAIT = 3'b010,
AR_DATA_VALID = 3'b100;
reg [2:0] rdt_cs;
wire [7:0] char_data;
reg [31:0] char_data_1d;
reg rvalid;
// char_gen_rom のインスタンス
char_gen_rom char_gen_rom_inst (
.clk(ACLK),
.reset(~ARESETN),
.char_addr(S_AXI_ARADDR[11:5]),
.row_addr(S_AXI_ARADDR[4:2]),
.dout(char_data)
);
// AXI4 LITEのReadトランザクション用ステートマシン
always @(posedge ACLK) begin
if (~ARESETN) begin
rdt_cs <= IDLE_RD;
rvalid <= 1'b0;
end else begin
case (rdt_cs)
IDLE_RD :
if (S_AXI_ARVALID)
rdt_cs <= AR_DATA_WAIT;
AR_DATA_WAIT : begin
rdt_cs <= AR_DATA_VALID;
rvalid <= 1'b1;
end
AR_DATA_VALID :
if (S_AXI_RREADY) begin
rdt_cs <= IDLE_RD;
rvalid <= 1'b0;
end
endcase
end
end
assign S_AXI_RVALID = rvalid;
always @(posedge ACLK) begin
if (~ARESETN)
char_data_1d <= 8'd0;
else begin
if (rdt_cs == AR_DATA_WAIT)
char_data_1d <= {24'd0, char_data};
end
end
assign S_AXI_RDATA = char_data_1d;
assign S_AXI_ARREADY = 1'b1;
assign S_AXI_RRESP = RESP_OKAY;
// Writeポートの処理、Writeが間違ってきた時にデッドロックしないように、すべてイネーブルとした
assign S_AXI_AWREADY = 1'b1;
assign S_AXI_WREADY = 1'b1;
assign S_AXI_BRESP = RESP_OKAY;
assign S_AXI_BVALID = 1'b1;
endmodule
//-----------------------------------------------------------------------------
// system_stub.v
//-----------------------------------------------------------------------------
module system_stub
(
RESET,
Led,
CLK,
axi_uartlite_0_RX_pin,
axi_uartlite_0_TX_pin
);
input RESET;
output [0:7] Led;
input CLK;
input axi_uartlite_0_RX_pin;
output axi_uartlite_0_TX_pin;
(* BOX_TYPE = "user_black_box" *)
system
system_i (
.RESET ( RESET ),
.Led ( Led ),
.CLK ( CLK ),
.axi_uartlite_0_RX_pin ( axi_uartlite_0_RX_pin ),
.axi_uartlite_0_TX_pin ( axi_uartlite_0_TX_pin )
);
endmodule
NET "CLK" LOC = "L15" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L42P_GCLK7_M1UDM, Type = GCLK, Sch name = GCLK
NET "RESET" LOC = "T15" | IOSTANDARD = LVCMOS33; # Bank = 2, Pin name = IO_L1N_M0_CMPMISO_2, Sch name = M0/RESET
NET "Led<0>" LOC = "U18" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L52N_M1DQ15, Sch name = LD0
NET "Led<1>" LOC = "M14" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L53P, Sch name = LD1
NET "Led<2>" LOC = "N14" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L53N_VREF, Sch name = LD2
NET "Led<3>" LOC = "L14" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L61P, Sch name = LD3
NET "Led<4>" LOC = "M13" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L61N, Sch name = LD4
NET "Led<5>" LOC = "D4" | IOSTANDARD = LVCMOS33; # Bank = 0, Pin name = IO_L1P_HSWAPEN_0, Sch name = HSWAP/LD5
NET "Led<6>" LOC = "P16" | IOSTANDARD = LVCMOS33; # Bank = 1, Pin name = IO_L74N_DOUT_BUSY_1, Sch name = LD6
NET "Led<7>" LOC = "N12" | IOSTANDARD = LVCMOS33; # Bank = 2, Pin name = IO_L13P_M1_2, Sch name = M1/LD7
NET "axi_uartlite_0_RX_pin" IOSTANDARD = LVCMOS33;
NET "axi_uartlite_0_RX_pin" LOC = A16;
NET "axi_uartlite_0_TX_pin" IOSTANDARD = LVCMOS33;
NET "axi_uartlite_0_TX_pin" LOC = B16;
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | - | - | 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 | - |