module asram_top #( parameter SRAM_ADDR_WIDTH = 18, ) ( // Clock and reset input clk_i, input rst_i, // Wishbone side interface input [2:0] ASRAM_CTI_I, input [1:0] ASRAM_BTE_I, input [31:0] ASRAM_ADR_I, input [32-1:0] ASRAM_DAT_I, input [32/8-1:0] ASRAM_SEL_I, input ASRAM_WE_I, input ASRAM_STB_I, input ASRAM_CYC_I, input ASRAM_LOCK_I, output ASRAM_ACK_O, output [32-1:0] ASRAM_DAT_O, output ASRAM_ERR_O, output ASRAM_RTY_O, // SRAM side interface input [32-1:0] sram_data_in, output [SRAM_ADDR_WIDTH-1:0] sram_addr, output [32-1:0] sram_data_out, output sram_csn, output [4-1:0] sram_be, output sram_wen, output sram_oen ); assign ASRAM_ERR_O = 1'b0; assign ASRAM_RTY_O = 1'b0; asram_core #( .SRAM_ADDR_WIDTH (SRAM_ADDR_WIDTH), ) core_inst (.clk_i (clk_i), .rst_i (rst_i), .cti_i (ASRAM_CTI_I), .bte_i (ASRAM_BTE_I), .addr_i (ASRAM_ADR_I), .dat_i (ASRAM_DAT_I), .sel_i (ASRAM_SEL_I), .we_i (ASRAM_WE_I), .stb_i (ASRAM_STB_I), .cyc_i (ASRAM_CYC_I), .ack_o (ASRAM_ACK_O), .dat_o (ASRAM_DAT_O), .sram_addr (sram_addr), .sram_data_in (sram_data_in), .sram_data_out (sram_data_out), .sram_csn (sram_csn), .sram_be (sram_be), .sram_wen (sram_wen), .sram_oen (sram_oen)); wire [32-1: 0] zwire; generate genvar i; for ( i = 0 ; i < 32; i = i + 1) begin : zwa assign zwire[i] = 1'bz; end endgenerate endmodule module asram_core #(parameter 32 = 32, parameter 32 = 32, parameter SRAM_ADDR_WIDTH = 32, parameter 4 = 4, ) ( input clk_i, input rst_i, // WISHBONE input cyc_i, input stb_i, input [2:0] cti_i, input [1:0] bte_i, input [31:0] addr_i, input [32-1:0] dat_i, input [32/8-1:0] sel_i, input we_i, output reg ack_o, output [31:0] dat_o, // SRAM output reg [SRAM_ADDR_WIDTH-1:0] sram_addr, output reg [32-1:0] sram_data_out, output reg [4-1:0] sram_be, output reg sram_csn, output reg sram_oen, output reg sram_wen, input [32-1:0] sram_data_in ); reg [SRAM_ADDR_WIDTH-1:0] sram_addr_nxt; reg [32-1:0] sram_data_out_nxt; reg [4-1:0] sram_be_nxt; reg [32-1:0] tmp_dat_o, tmp_dat_o_nxt; reg tmp_ack_o, tmp_ack_o_nxt; reg [3:0] dly, dly_nxt; reg [1:0] state, state_nxt; parameter SM_IDLE = 2'b00; parameter SM_BUSY = 2'b01; parameter SM_WAIT = 2'b10; always @(/*AUTOSENSE*/ack_o or cti_i or cyc_i or dly or state or stb_i or we_i) casez (state) SM_IDLE: if (cyc_i && stb_i && (ack_o == 1'b0)) state_nxt = SM_BUSY; else state_nxt = state; SM_BUSY: if ((dly == 1) && ((cti_i == 3'b000) || (cti_i == 3'b111))) state_nxt = SM_IDLE; else if ((we_i && (dly == 1)) || ((we_i == 0) && (dly == 1) && (cti_i == 3'b010))) state_nxt = SM_WAIT; else state_nxt = state; SM_WAIT: state_nxt = SM_BUSY; default: state_nxt = SM_IDLE; endcase /*---------------------------------------------------------------------- Compute Delay (the time required to complete an SRAM access) ----------------------------------------------------------------------*/ always @(/*AUTOSENSE*/ dly or state or we_i) begin if ((state == SM_IDLE) || (state == SM_WAIT)) dly_nxt = 1; else if (state == SM_BUSY) dly_nxt = dly - 1'b1; else dly_nxt = dly; end /*---------------------------------------------------------------------- Sequential logic ----------------------------------------------------------------------*/ always @(posedge clk_i or posedge rst_i) if (rst_i) begin state <= #1 SM_IDLE; dly <= #1 4'b0000; end else begin state <= #1 state_nxt; dly <= #1 dly_nxt; end /*---------------------------------------------------------------------- SRAM signals ----------------------------------------------------------------------*/ always @(/*AUTOSENSE*/cyc_i or state or we_i) begin sram_csn = ~(state == SM_BUSY); sram_oen = ~((state == SM_BUSY) && ~we_i); sram_wen = ~(cyc_i && we_i && (state == SM_BUSY)); end always @(ack_o or addr_i or dat_i or sel_i or sram_addr or state or stb_i) begin if ((state == SM_IDLE) || (stb_i && (ack_o == 0) && (state == SM_WAIT))) sram_addr_nxt = {addr_i[SRAM_ADDR_WIDTH-1:2], 2'b00}; else sram_addr_nxt = sram_addr; sram_be_nxt = ~sel_i; sram_data_out_nxt = dat_i[31:0]; end always @(posedge clk_i or posedge rst_i) if (rst_i) begin sram_addr <= #1 0; sram_be <= #1 4'b1111; sram_data_out <= #1 32'b0; end else begin sram_addr <= #1 sram_addr_nxt; sram_be <= #1 sram_be_nxt; sram_data_out <= #1 sram_data_out_nxt; end end /*---------------------------------------------------------------------- Return data on WISHBONE ----------------------------------------------------------------------*/ always @(dly or sram_data_in or state or tmp_dat_o) if ((state == SM_BUSY) && (dly == 1)) tmp_dat_o_nxt = sram_data_in; else tmp_dat_o_nxt = tmp_dat_o; always @(posedge clk_i or posedge rst_i) if (rst_i) tmp_dat_o <= #1 32'b0; else tmp_dat_o <= #1 tmp_dat_o_nxt; if (DATA_OUTPUT_REG == 1) assign dat_o = tmp_dat_o; /*---------------------------------------------------------------------- WISHBONE ACK ----------------------------------------------------------------------*/ if (((((state == SM_IDLE) && cyc_i && stb_i && (ack_o == 0)) || ((state == SM_WAIT) && stb_i && (ack_o == 0)))) ||) tmp_ack_o_nxt = 1'b1; else tmp_ack_o_nxt = 1'b0; always @(posedge clk_i or posedge rst_i) if (rst_i) tmp_ack_o <= #1 1'b0; else tmp_ack_o <= #1 tmp_ack_o_nxt; reg tmp_ack_o_d; always @(posedge clk_i or posedge rst_i) if (rst_i) tmp_ack_o_d <= #1 1'b0; else tmp_ack_o_d <= #1 tmp_ack_o; always @(/*AUTOSENSE*/tmp_ack_o or tmp_ack_o_d or we_i) ack_o = we_i ? tmp_ack_o : tmp_ack_o_d; endmodule