tests: add axi4l_reg test wrapper
This commit is contained in:
163
axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv
Normal file
163
axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
module tb_axi4l_reg_map;
|
||||||
|
|
||||||
|
localparam int unsigned ADDR_W = 16;
|
||||||
|
localparam int unsigned DATA_W = 32;
|
||||||
|
localparam int unsigned USER_W = 1;
|
||||||
|
localparam int unsigned N_REGS = 3;
|
||||||
|
|
||||||
|
localparam logic [2:0] REG_BIT_RSVD = 3'd0;
|
||||||
|
localparam logic [2:0] REG_BIT_RO = 3'd1;
|
||||||
|
localparam logic [2:0] REG_BIT_RW = 3'd2;
|
||||||
|
localparam logic [2:0] REG_BIT_W1S = 3'd3;
|
||||||
|
localparam logic [2:0] REG_BIT_W1C = 3'd4;
|
||||||
|
|
||||||
|
function automatic logic [N_REGS-1:0][31:0][2:0] make_reg_mode();
|
||||||
|
logic [N_REGS-1:0][31:0][2:0] mode;
|
||||||
|
|
||||||
|
mode = '{default: REG_BIT_RSVD};
|
||||||
|
|
||||||
|
// REG0 - 0x00: mixed control register
|
||||||
|
// bit 0 : W1S
|
||||||
|
// bit 1 : RW
|
||||||
|
// bit 2 : W1C
|
||||||
|
mode[0][0] = REG_BIT_W1S;
|
||||||
|
mode[0][1] = REG_BIT_RW;
|
||||||
|
mode[0][2] = REG_BIT_W1C;
|
||||||
|
|
||||||
|
// REG1 - 0x04: status register
|
||||||
|
// bit 0 : RO busy
|
||||||
|
// bits 15:8 : RO error_code
|
||||||
|
mode[1][0] = REG_BIT_RO;
|
||||||
|
for (int i = 8; i < 16; i++) begin
|
||||||
|
mode[1][i] = REG_BIT_RO;
|
||||||
|
end
|
||||||
|
|
||||||
|
// REG2 - 0x08: full RW config register
|
||||||
|
for (int i = 0; i < 32; i++) begin
|
||||||
|
mode[2][i] = REG_BIT_RW;
|
||||||
|
end
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic logic [N_REGS-1:0][31:0] make_reg_rst();
|
||||||
|
logic [N_REGS-1:0][31:0] rst;
|
||||||
|
|
||||||
|
rst = '{default: 32'h0000_0000};
|
||||||
|
rst[0] = 32'h0000_0004; // W1C sticky bit starts set
|
||||||
|
rst[2] = 32'h1234_5678; // RW config reset value
|
||||||
|
|
||||||
|
return rst;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
localparam logic [N_REGS-1:0][31:0][2:0] REG_MODE = make_reg_mode();
|
||||||
|
localparam logic [N_REGS-1:0][31:0] REG_RST = make_reg_rst();
|
||||||
|
|
||||||
|
logic clk = 1'b0;
|
||||||
|
logic rst = 1'b0;
|
||||||
|
logic rst_n;
|
||||||
|
|
||||||
|
assign rst_n = ~rst;
|
||||||
|
|
||||||
|
always #5ns clk = ~clk;
|
||||||
|
|
||||||
|
// flat axil
|
||||||
|
logic [ADDR_W-1:0] s_axil_awaddr;
|
||||||
|
logic [2:0] s_axil_awprot;
|
||||||
|
logic s_axil_awvalid;
|
||||||
|
logic s_axil_awready;
|
||||||
|
|
||||||
|
logic [DATA_W-1:0] s_axil_wdata;
|
||||||
|
logic [DATA_W/8-1:0] s_axil_wstrb;
|
||||||
|
logic s_axil_wvalid;
|
||||||
|
logic s_axil_wready;
|
||||||
|
|
||||||
|
logic [1:0] s_axil_bresp;
|
||||||
|
logic s_axil_bvalid;
|
||||||
|
logic s_axil_bready;
|
||||||
|
|
||||||
|
logic [ADDR_W-1:0] s_axil_araddr;
|
||||||
|
logic [2:0] s_axil_arprot;
|
||||||
|
logic s_axil_arvalid;
|
||||||
|
logic s_axil_arready;
|
||||||
|
|
||||||
|
logic [DATA_W-1:0] s_axil_rdata;
|
||||||
|
logic [1:0] s_axil_rresp;
|
||||||
|
logic s_axil_rvalid;
|
||||||
|
logic s_axil_rready;
|
||||||
|
|
||||||
|
// simple external status inputs driven from cocotb
|
||||||
|
logic busy_i;
|
||||||
|
logic [7:0] error_code_i;
|
||||||
|
|
||||||
|
logic [N_REGS-1:0][31:0] reg_i;
|
||||||
|
logic [N_REGS-1:0][31:0] reg_o;
|
||||||
|
|
||||||
|
// debug probes visible from cocotb. they are useful for checking W1S pulse-like behavior
|
||||||
|
logic [31:0] reg0_o;
|
||||||
|
logic [31:0] reg1_o;
|
||||||
|
logic [31:0] reg2_o;
|
||||||
|
|
||||||
|
assign reg0_o = reg_o[0];
|
||||||
|
assign reg1_o = reg_o[1];
|
||||||
|
assign reg2_o = reg_o[2];
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
reg_i = '0;
|
||||||
|
reg_i[1][0] = busy_i;
|
||||||
|
reg_i[1][15:8] = error_code_i;
|
||||||
|
end
|
||||||
|
|
||||||
|
axi4l_if #(
|
||||||
|
.ADDR_W(ADDR_W),
|
||||||
|
.DATA_W(DATA_W),
|
||||||
|
.USER_W(USER_W)
|
||||||
|
) s_axil_if (
|
||||||
|
.aclk (clk),
|
||||||
|
.aresetn (rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assign s_axil_if.req.aw.addr = s_axil_awaddr;
|
||||||
|
assign s_axil_if.req.aw.prot = s_axil_awprot;
|
||||||
|
assign s_axil_if.req.aw.user = '0;
|
||||||
|
assign s_axil_if.req.aw.valid = s_axil_awvalid;
|
||||||
|
assign s_axil_awready = s_axil_if.resp.aw_ready;
|
||||||
|
|
||||||
|
assign s_axil_if.req.w.data = s_axil_wdata;
|
||||||
|
assign s_axil_if.req.w.strb = s_axil_wstrb;
|
||||||
|
assign s_axil_if.req.w.user = '0;
|
||||||
|
assign s_axil_if.req.w.valid = s_axil_wvalid;
|
||||||
|
assign s_axil_wready = s_axil_if.resp.w_ready;
|
||||||
|
|
||||||
|
assign s_axil_bresp = s_axil_if.resp.b.resp;
|
||||||
|
assign s_axil_bvalid = s_axil_if.resp.b.valid;
|
||||||
|
assign s_axil_if.req.b_ready = s_axil_bready;
|
||||||
|
|
||||||
|
assign s_axil_if.req.ar.addr = s_axil_araddr;
|
||||||
|
assign s_axil_if.req.ar.prot = s_axil_arprot;
|
||||||
|
assign s_axil_if.req.ar.user = '0;
|
||||||
|
assign s_axil_if.req.ar.valid = s_axil_arvalid;
|
||||||
|
assign s_axil_arready = s_axil_if.resp.ar_ready;
|
||||||
|
|
||||||
|
assign s_axil_rdata = s_axil_if.resp.r.data;
|
||||||
|
assign s_axil_rresp = s_axil_if.resp.r.resp;
|
||||||
|
assign s_axil_rvalid = s_axil_if.resp.r.valid;
|
||||||
|
assign s_axil_if.req.r_ready = s_axil_rready;
|
||||||
|
|
||||||
|
axi4l_reg_map #(
|
||||||
|
.ADDR_W (ADDR_W),
|
||||||
|
.DATA_W (DATA_W),
|
||||||
|
.USER_W (USER_W),
|
||||||
|
.N_REGS (N_REGS),
|
||||||
|
.REG_MODE(REG_MODE),
|
||||||
|
.REG_RST (REG_RST)
|
||||||
|
) u_reg_map (
|
||||||
|
.clk (clk),
|
||||||
|
.rst_n (rst_n),
|
||||||
|
.s_axil (s_axil_if.slave),
|
||||||
|
.reg_i (reg_i),
|
||||||
|
.reg_o (reg_o)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
Reference in New Issue
Block a user