zynq-sandbox

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit df2453b0daf06aa5e470309269315876566e1e31
parent f36bd94cb922823b9ae840fa08d1f66800729d8a
Author: Brian Swetland <swetland@frotz.net>
Date:   Tue, 29 Jul 2014 23:00:50 -0700

axi-registers: add testcase, move to more conservative read cycle

do not depend on register to maintain value beyond the clock after rd

Diffstat:
MMakefile | 6++++++
Mhdl/axi_registers.sv | 28++++++++++++++++------------
Ahdl/test/axi_registers_test.sv | 228+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 250 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile @@ -61,6 +61,12 @@ MODULE_SRCS += hdl/eth_rmii_tx.sv MODULE_SRCS += hdl/eth_rmii_rx.sv include build/verilator-sim.mk +MODULE_NAME := axi-regs-test +MODULE_SRCS := hdl/test/axi_registers_test.sv +MODULE_SRCS += hdl/axi_ifc.sv +MODULE_SRCS += hdl/axi_registers.sv +include build/verilator-sim.mk + MODULE_NAME := eth-capture-test MODULE_SRCS := hdl/test/eth_capture_test.sv MODULE_SRCS += hdl/test/eth_packet_gen.sv diff --git a/hdl/axi_registers.sv b/hdl/axi_registers.sv @@ -33,12 +33,12 @@ module axi_registers ( axi_ifc.slave s, // Register File Interface - output reg [R_ADDR_WIDTH-1:0]o_rreg, - output reg [R_ADDR_WIDTH-1:0]o_wreg, + output reg [R_ADDR_WIDTH-1:0]o_rreg = 0, + output reg [R_ADDR_WIDTH-1:0]o_wreg = 0, input wire [31:0]i_rdata, - output reg [31:0]o_wdata, - output reg o_rd, - output reg o_wr + output reg [31:0]o_wdata = 0, + output wire o_rd, + output wire o_wr ); parameter integer R_ADDR_WIDTH = 2; @@ -103,7 +103,7 @@ always_comb begin endcase end -typedef enum { R_ADDR, R_CAPTURE, R_DATA } rstate_t; +typedef enum { R_ADDR, R_CAPTURE, R_CAPTURE2, R_DATA } rstate_t; rstate_t rstate = R_ADDR; rstate_t rstate_next; @@ -112,9 +112,9 @@ reg arready_next; reg rvalid_next; reg rlast_next; -//reg [31:0]rdata; -//reg [31:0]rdata_next; -assign s.rdata = i_rdata; +reg [31:0]rdata = 0; +reg [31:0]rdata_next; +assign s.rdata = rdata; reg rd_next; @@ -124,7 +124,7 @@ assign s.rid = trid; always_comb begin rstate_next = rstate; - //rdata_next = rdata; + rdata_next = rdata; rreg_next = o_rreg; trid_next = trid; arready_next = 0; @@ -143,10 +143,14 @@ always_comb begin end R_CAPTURE: begin // present address and rd to register file + rstate_next = R_CAPTURE2; + end + R_CAPTURE2: begin + // capture register file output rstate_next = R_DATA; rvalid_next = 1; rlast_next = 1; - //rdata_next = i_rdata; + rdata_next = i_rdata; end R_DATA: if (s.rready) begin // present register data to AXI @@ -169,7 +173,7 @@ always_ff @(posedge clk) begin o_wreg <= wreg_next; rstate <= rstate_next; - //rdata <= rdata_next; + rdata <= rdata_next; trid <= trid_next; s.arready <= arready_next; s.rvalid <= rvalid_next; diff --git a/hdl/test/axi_registers_test.sv b/hdl/test/axi_registers_test.sv @@ -0,0 +1,228 @@ + +module testbench(input clk); + + +axi_ifc axi0(); + + +wire [1:0]rreg; +wire [1:0]wreg; +reg [31:0]rdata = 32'hdeadbeef; +wire [31:0]wdata; +wire rrd; +wire rwr; + +axi_registers regs( + .clk(clk), + .s(axi0), + .o_rreg(rreg), + .o_wreg(wreg), + .i_rdata(rdata), + .o_wdata(wdata), + .o_rd(rrd), + .o_wr(rwr) + ); + +wire [31:0]tmp; + +always_ff @(posedge clk) begin + if (rrd) case(rreg) + 0: rdata <= 32'h10101010; + 1: rdata <= 32'h20202020; + 2: rdata <= 32'h30303030; + 3: rdata <= tmp; + endcase + if (rwr & (wreg == 3)) + tmp <= wdata; +end + + +integer tick = 0; +reg [31:0]addr = 32'hffffffff; +reg [31:0]next_addr; +reg [31:0]data = 32'hffffffff; +reg [31:0]next_data; +reg do_rd = 0; +reg next_do_rd; +reg do_wr = 0; +reg next_do_wr; + +axi_rw_engine engine0( + .clk(clk), + .m(axi0), + .rd(do_rd), + .wr(do_wr), + .addr(addr), + .data(data) + ); + +always_comb begin + next_do_rd = 0; + next_do_wr = 0; + next_addr = 32'hffffffff; + next_data = 32'hffffffff; + if (tick == 10) begin + next_do_rd = 1; + next_addr = 4; + end else if (tick == 20) begin + next_do_rd = 1; + next_addr = 0; + end else if (tick == 30) begin + next_do_wr = 1; + next_data = 32'haabbccdd; + next_addr = 12; + end else if (tick == 40) begin + next_do_rd = 1; + next_addr = 4; + end else if (tick == 50) begin + next_do_rd = 1; + next_addr = 12; + end else if (tick == 60) begin + $finish; + end +end + +always_ff @(posedge clk) begin + do_rd <= next_do_rd; + do_wr <= next_do_wr; + addr <= next_addr; + data <= next_data; + tick <= tick + 1; +end + +endmodule + + +module axi_rw_engine( + input clk, + axi_ifc.master m, + input rd, + input wr, + input [31:0]addr, + input [31:0]data + ); + +typedef enum { IDLE, RADDR, RDATA, WADDR, WDATA, WRESP } state_t; +state_t state = IDLE; +state_t next_state; + +reg [31:0]awaddr = 0; +reg [31:0]next_awaddr; +reg [31:0]wdata = 0; +reg [31:0]next_wdata; +reg [31:0]araddr = 0; +reg [31:0]next_araddr; +reg arvalid = 0; +reg next_arvalid; +reg rready = 0; +reg next_rready; +reg awvalid = 0; +reg next_awvalid; +reg wvalid = 0; +reg next_wvalid; +reg bready = 0; +reg next_bready; + +always_comb begin + next_state = state; + next_araddr = araddr; + next_awaddr = awaddr; + next_wdata = wdata; + next_awvalid = 0; + next_wvalid = 0; + next_bready = 0; + next_arvalid = 0; + next_rready = 0; + case (state) + IDLE: begin + if (rd) begin + next_state = RADDR; + next_araddr = addr; + next_arvalid = 1; + end else if (wr) begin + next_state = WADDR; + next_awaddr = addr; + next_wdata = data; + next_awvalid = 1; + end + end + WADDR: begin + if (m.awready) begin + next_state = WDATA; + next_wvalid = 1; + end else begin + next_awvalid = 1; + end + end + WDATA: begin + if (m.wready) begin + next_state = WRESP; + next_bready = 1; + end else begin + next_wvalid = 1; + end + end + WRESP: begin + if (m.bvalid) begin + next_state = IDLE; + $display("wr %x -> %x (status %x)", wdata, awaddr, m.bresp); + end else begin + next_bready = 1; + end + end + RADDR: begin + if (m.arready) begin + next_state = RDATA; + next_rready = 1; + end else begin + next_arvalid = 1; + end + end + RDATA: begin + if (m.rvalid) begin + next_state = IDLE; + $display("rd %x <- %x (status %x)", m.rdata, m.araddr, m.rresp); + end else begin + next_rready = 1; + end + end + endcase +end + +always_ff @(posedge clk) begin + state <= next_state; + araddr <= next_araddr; + awaddr <= next_awaddr; + arvalid <= next_arvalid; + awvalid <= next_awvalid; + rready <= next_rready; + wvalid <= next_wvalid; + bready <= next_bready; + wdata <= next_wdata; +end + +assign m.awid = 0; +assign m.awaddr = awaddr; +assign m.awvalid = awvalid; +assign m.wdata = wdata; +assign m.wstrb = 4'b1111; +assign m.wvalid = wvalid; +assign m.bready = bready; +assign m.awburst = 1; // INCR +assign m.awcache = 0; +assign m.awlen = 0; +assign m.awsize = 2; // 4 bytes +assign m.awlock = 0; +assign m.wlast = 1; + +assign m.arid = 0; +assign m.araddr = araddr; +assign m.arvalid = arvalid; +assign m.rready = rready; +assign m.arburst = 1; // INCR +assign m.arcache = 0; +assign m.arlen = 0; +assign m.arsize = 2; // 4 bytes +assign m.arlock = 0; + +endmodule