tests: add axi4l_reg test wrapper

This commit is contained in:
Phil
2026-06-17 17:16:07 +03:00
parent 7cc0b19657
commit 600fba5d3e

View 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