Created
February 21, 2026 02:43
-
-
Save neilzheng/53bdc330972f31835864e456550ad779 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * a mem checker | |
| * when activiated, check memory content according to filler result | |
| * pattern is current bytes already filled | |
| * in 32 data width | |
| * that's 0, 4, 8, 12, 16, ... | |
| */ | |
| module axi_rd # | |
| ( | |
| // Width of data bus in bits | |
| parameter DATA_WIDTH = 32, | |
| // Width of address bus in bits | |
| parameter ADDR_WIDTH = 32, | |
| // Width of wstrb (width of data bus in words) | |
| parameter STRB_WIDTH = (DATA_WIDTH/8), | |
| // Width of ID signal, not really used | |
| parameter ID_WIDTH = 1, | |
| // Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengths | |
| parameter M_AXI_BURST_LEN = 16, | |
| // burst mode incr | |
| parameter M_AXI_BURST_INCR = 2'b01 | |
| ) | |
| ( | |
| input wire clk, | |
| input wire rst_n, | |
| // control | |
| output wire txn_done, | |
| output wire txn_error, | |
| input wire [ADDR_WIDTH-1:0] txn_addr, | |
| input wire init_txn, | |
| /* | |
| * AXI master read interface | |
| */ | |
| output wire [ID_WIDTH-1:0] m_axi_arid, | |
| output wire [ADDR_WIDTH-1:0] m_axi_araddr, | |
| output wire [7:0] m_axi_arlen, | |
| output wire [2:0] m_axi_arsize, | |
| output wire [1:0] m_axi_arburst, | |
| output wire m_axi_arlock, | |
| output wire [3:0] m_axi_arcache, | |
| output wire [2:0] m_axi_arprot, | |
| output wire [3:0] m_axi_arqos, | |
| output wire [3:0] m_axi_arregion, | |
| output wire [0:0] m_axi_aruser, // not used | |
| output wire m_axi_arvalid, | |
| input wire m_axi_arready, | |
| input wire [ID_WIDTH-1:0] m_axi_rid, | |
| input wire [DATA_WIDTH-1:0] m_axi_rdata, | |
| input wire [1:0] m_axi_rresp, | |
| input wire m_axi_rlast, | |
| input wire [0:0] m_axi_ruser, // not used | |
| input wire m_axi_rvalid, | |
| output wire m_axi_rready | |
| ); | |
| // unused consts | |
| assign m_axi_aruser = '0; | |
| // const state/ unsupported features | |
| assign m_axi_arid = '0; | |
| assign m_axi_arlock = '0; | |
| // Normal, Non-cacheable, Bufferable | |
| assign m_axi_arcache = 4'b0011; | |
| // Unprivileged, Secure, Data access | |
| assign m_axi_arprot = '0; | |
| assign m_axi_arqos = '0; | |
| assign m_axi_arregion = '0; | |
| // handshakes | |
| wire addr_read_en; | |
| wire data_read_en; | |
| // xfer counter | |
| reg [7:0] xfer_counter_reg; | |
| reg [7:0] next_xfer_counter; | |
| // output regs | |
| reg [ADDR_WIDTH-1:0] araddr_reg; | |
| reg [7:0] arlen_reg; | |
| reg [2:0] arsize_reg; | |
| reg [1:0] arburst_reg; | |
| reg arvalid_reg; | |
| reg rready_reg; | |
| reg txn_done_reg; | |
| reg txn_error_reg; | |
| assign addr_read_en = m_axi_arready & arvalid_reg; | |
| assign data_read_en = m_axi_rvalid & rready_reg; | |
| // next state generation | |
| localparam STATE_READ_IDLE = 2'b00; | |
| localparam STATE_READ_ADDR = 2'b01; | |
| localparam STATE_READ_DATA = 2'b10; | |
| reg [1:0] current_state_reg; | |
| reg [1:0] next_state; | |
| always @* begin | |
| next_state = current_state_reg; | |
| case(current_state_reg) | |
| STATE_READ_IDLE: begin | |
| if (init_txn) begin | |
| next_state = STATE_READ_ADDR; | |
| end | |
| end | |
| STATE_READ_ADDR: begin | |
| if (addr_read_en) begin | |
| next_state = STATE_READ_DATA; | |
| end | |
| end | |
| STATE_READ_DATA: begin | |
| if (data_read_en & m_axi_rlast) begin | |
| next_state = STATE_READ_IDLE; | |
| end | |
| end | |
| default: ; | |
| endcase | |
| end | |
| // output generation | |
| reg [ADDR_WIDTH-1:0] next_araddr; | |
| reg next_arvalid; | |
| reg next_rready; | |
| reg next_txn_done; | |
| reg next_txn_error; | |
| // output generation | |
| always @* begin | |
| next_xfer_counter = xfer_counter_reg; | |
| next_araddr = '0; | |
| next_arvalid = 1'b0; | |
| next_rready = 1'b0; | |
| next_txn_done = txn_done_reg; | |
| next_txn_error = txn_error_reg; | |
| // secondary state, the counter, increment on read enabled | |
| // and error state | |
| if (data_read_en) begin | |
| next_xfer_counter = xfer_counter_reg + 1'b1; | |
| // error on any mismatch or response error | |
| if (m_axi_rdata[7:0] != xfer_counter_reg | m_axi_rresp[1]) begin | |
| next_txn_error = 1'b1; | |
| end | |
| end | |
| case (next_state) | |
| STATE_READ_ADDR: begin | |
| next_arvalid = 1'b1; | |
| next_araddr = txn_addr; | |
| next_txn_done = 1'b0; | |
| next_txn_error = 1'b0; | |
| end | |
| STATE_READ_DATA: begin | |
| // only validate read in read state | |
| // note this avoids early data read (combitional data read on same cycle of address assert) | |
| next_rready = 1'b1; | |
| end | |
| STATE_READ_IDLE: if (current_state_reg == STATE_READ_DATA) begin | |
| next_xfer_counter = 0; | |
| next_txn_done = 1'b1; | |
| end | |
| default:; | |
| endcase | |
| end | |
| // output logic | |
| always @(posedge clk or negedge rst_n) | |
| begin | |
| if (~rst_n) begin | |
| // reset logic | |
| current_state_reg <= STATE_READ_IDLE; | |
| // default parameters | |
| xfer_counter_reg <= '0; | |
| arlen_reg <= M_AXI_BURST_LEN-1; | |
| arsize_reg <= 3'($clog2(STRB_WIDTH)); | |
| arburst_reg <= M_AXI_BURST_INCR; | |
| araddr_reg <= '0; | |
| arvalid_reg <= '0; | |
| rready_reg <= '0; | |
| txn_done_reg <= '0; | |
| txn_error_reg <= '0; | |
| end else begin | |
| // actually output | |
| current_state_reg <= next_state; | |
| xfer_counter_reg <= next_xfer_counter; | |
| araddr_reg <= next_araddr; | |
| arvalid_reg <= next_arvalid; | |
| rready_reg <= next_rready; | |
| txn_done_reg <= next_txn_done; | |
| txn_error_reg <= next_txn_error; | |
| end | |
| end | |
| assign m_axi_araddr = araddr_reg; | |
| assign m_axi_arlen = arlen_reg; | |
| assign m_axi_arsize = arsize_reg; | |
| assign m_axi_arburst = arburst_reg; | |
| assign m_axi_arvalid = arvalid_reg; | |
| assign m_axi_rready = rready_reg; | |
| assign txn_done = txn_done_reg; | |
| assign txn_error = txn_error_reg; | |
| endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment