Created
February 21, 2026 02:43
-
-
Save neilzheng/b4320882c05f2981da3214dbbfbc2eab 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 filler | |
| * when activiated, fill a memory region | |
| * with current bytes already filled | |
| * in 32 data width | |
| * that's 0, 4, 8, 12, 16, ... | |
| */ | |
| module axi_wr # | |
| ( | |
| // 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 write interface | |
| */ | |
| output wire [ID_WIDTH-1:0] m_axi_awid, | |
| output wire [ADDR_WIDTH-1:0] m_axi_awaddr, | |
| output wire [7:0] m_axi_awlen, | |
| output wire [2:0] m_axi_awsize, | |
| output wire [1:0] m_axi_awburst, | |
| output wire m_axi_awlock, | |
| output wire [3:0] m_axi_awcache, | |
| output wire [2:0] m_axi_awprot, | |
| output wire [3:0] m_axi_awqos, | |
| output wire [3:0] m_axi_awregion, | |
| output wire [0:0] m_axi_awuser, // not used | |
| output wire m_axi_awvalid, | |
| input wire m_axi_awready, | |
| output wire [DATA_WIDTH-1:0] m_axi_wdata, | |
| output wire [STRB_WIDTH-1:0] m_axi_wstrb, | |
| output wire m_axi_wlast, | |
| output wire [0:0] m_axi_wuser, // not used | |
| output wire m_axi_wvalid, | |
| input wire m_axi_wready, | |
| input wire [ID_WIDTH-1:0] m_axi_bid, | |
| input wire [1:0] m_axi_bresp, | |
| input wire [0:0] m_axi_buser, // not used | |
| input wire m_axi_bvalid, | |
| output wire m_axi_bready | |
| ); | |
| // unused consts | |
| assign m_axi_awuser = 0; | |
| assign m_axi_wuser = 0; | |
| // const state/ unsupported features | |
| assign m_axi_awid = 0; | |
| assign m_axi_awlock = 0; | |
| // Normal, Non-cacheable, Bufferable | |
| assign m_axi_awcache = 4'b0011; | |
| // Unprivileged, Secure, Data access | |
| assign m_axi_awprot = 0; | |
| assign m_axi_awqos = 0; | |
| assign m_axi_awregion = 0; | |
| // always ready to receive response | |
| assign m_axi_bready = 1'b1; | |
| // always word write | |
| assign m_axi_wstrb = {STRB_WIDTH{1'b1}}; | |
| // handshakes | |
| wire addr_write_en; | |
| wire data_write_en; | |
| wire resp_read_en; | |
| assign addr_write_en = m_axi_awready & awvalid_reg; | |
| assign data_write_en = m_axi_wready & wvalid_reg; | |
| assign resp_read_en = m_axi_bready & m_axi_bvalid; | |
| // xfer counter | |
| reg [7:0] xfer_counter_reg; | |
| reg [7:0] next_xfer_counter; | |
| // output regs | |
| reg [ADDR_WIDTH-1:0] awaddr_reg; | |
| reg [7:0] awlen_reg; | |
| reg [2:0] awsize_reg; | |
| reg [1:0] awburst_reg; | |
| reg awvalid_reg; | |
| reg [DATA_WIDTH-1:0] wdata_reg; | |
| reg wlast_reg; | |
| reg wvalid_reg; | |
| reg txn_done_reg; | |
| reg txn_error_reg; | |
| // next state generation | |
| localparam STATE_WRITE_IDLE = 2'b00; | |
| localparam STATE_WRITE_ADDR = 2'b01; | |
| localparam STATE_WRITE_DATA = 2'b10; | |
| localparam STATE_WRITE_DONE = 2'b11; | |
| reg [1:0] current_state_reg; | |
| reg [1:0] next_state; | |
| always @* begin | |
| next_state = current_state_reg; | |
| case(current_state_reg) | |
| STATE_WRITE_IDLE: begin | |
| if (init_txn) begin | |
| next_state = STATE_WRITE_ADDR; | |
| end | |
| end | |
| STATE_WRITE_ADDR: begin | |
| if (addr_write_en) begin | |
| next_state = STATE_WRITE_DATA; | |
| end | |
| end | |
| STATE_WRITE_DATA: begin | |
| if (data_write_en & wlast_reg) begin | |
| next_state = STATE_WRITE_DONE; | |
| end | |
| end | |
| STATE_WRITE_DONE: begin | |
| if (resp_read_en) begin | |
| next_state = STATE_WRITE_IDLE; | |
| end | |
| end | |
| default: ; | |
| endcase | |
| end | |
| // output generation | |
| reg [ADDR_WIDTH-1:0] next_awaddr; | |
| reg next_awvalid; | |
| reg [DATA_WIDTH-1:0] next_wdata; | |
| reg next_wlast; | |
| reg next_wvalid; | |
| reg next_txn_done; | |
| reg next_txn_error; | |
| // output generation | |
| always @* begin | |
| next_xfer_counter = xfer_counter_reg; | |
| next_awaddr = 0; | |
| next_awvalid = 1'b0; | |
| next_wdata = 0; | |
| next_wlast = 1'b0; | |
| next_wvalid = 1'b0; | |
| next_txn_done = txn_done_reg; | |
| next_txn_error = txn_error_reg; | |
| // secondary state, the counter, increment on write enabled | |
| if (data_write_en) begin | |
| next_xfer_counter = xfer_counter_reg + 1'b1; | |
| end | |
| // state output | |
| case (next_state) | |
| STATE_WRITE_ADDR: begin | |
| next_awvalid = 1'b1; | |
| next_awaddr = txn_addr; | |
| next_txn_done = 1'b0; | |
| next_txn_error = 1'b0; | |
| end | |
| STATE_WRITE_DATA: begin | |
| next_wvalid = 1'b1; | |
| next_wdata = {{(DATA_WIDTH-8){1'b0}}, next_xfer_counter}; | |
| if (next_xfer_counter == M_AXI_BURST_LEN-1'b1) begin | |
| next_wlast = 1'b1; | |
| end | |
| end | |
| STATE_WRITE_IDLE: if (current_state_reg == STATE_WRITE_DONE) begin | |
| next_xfer_counter = 0; | |
| next_txn_done = 1'b1; | |
| next_txn_error = m_axi_bresp[1]; | |
| end | |
| default:; | |
| endcase | |
| end | |
| // output logic | |
| always @(posedge clk or negedge rst_n) | |
| begin | |
| if (~rst_n) begin | |
| // reset logic | |
| current_state_reg <= STATE_WRITE_IDLE; | |
| // default parameters | |
| xfer_counter_reg <= 0; | |
| awlen_reg <= M_AXI_BURST_LEN-1; | |
| awsize_reg <= 3'($clog2(STRB_WIDTH)); | |
| awburst_reg <= M_AXI_BURST_INCR; | |
| awaddr_reg <= 0; | |
| awvalid_reg <= 0; | |
| wdata_reg <= 0; | |
| wlast_reg <= 0; | |
| wvalid_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; | |
| awaddr_reg <= next_awaddr; | |
| awvalid_reg <= next_awvalid; | |
| wdata_reg <= next_wdata; | |
| wlast_reg <= next_wlast; | |
| wvalid_reg <= next_wvalid; | |
| txn_done_reg <= next_txn_done; | |
| txn_error_reg <= next_txn_error; | |
| end | |
| end | |
| assign m_axi_awaddr = awaddr_reg; | |
| assign m_axi_awlen = awlen_reg; | |
| assign m_axi_awsize = awsize_reg; | |
| assign m_axi_awburst = awburst_reg; | |
| assign m_axi_awvalid = awvalid_reg; | |
| assign m_axi_wdata = wdata_reg; | |
| assign m_axi_wlast = wlast_reg; | |
| assign m_axi_wvalid = wvalid_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