// Everything on sram_clk module fifo_extram (input reset, input clear, input [17:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, input [15:0] occ_in, output [17:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, input [15:0] space_in, input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we, output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe, output sram_mode, output sram_zz); localparam AWIDTH = 19; // 1 MB in x18 localparam RAMSIZE = ((1<<AWIDTH) - 1); wire do_store, do_retrieve; reg [1:0] do_store_del, do_retr_del; reg [AWIDTH-1:0] addr_retrieve, addr_store; always @(posedge sram_clk) if(reset | clear) addr_retrieve <= 0; else if (do_retrieve) addr_retrieve <= addr_retrieve + 1; always @(posedge sram_clk) if(reset | clear) addr_store <= 0; else if(do_store) addr_store <= addr_store + 1; //wire [AWIDTH-1:0] fullness = (addr_store - addr_retrieve); reg [AWIDTH-1:0] fullness; always @(posedge sram_clk) if(reset | clear) fullness <= 0; else if(do_store) fullness <= fullness + 1; else if(do_retrieve) fullness <= fullness - 1; // wire empty = (fullness == 0); //wire full = (fullness == RAMSIZE); // 19'h7FF); reg empty, full; // The math in the following functions is 'AWIDTH wide. Use // continuous assignments to prevent the numbers from being // promoted to 32-bit (which would make it wrap wrong). // wire [AWIDTH-1:0] addr_retrieve_p1, addr_store_p2; assign addr_retrieve_p1 = addr_retrieve + 1; assign addr_store_p2 = addr_store + 2; always @(posedge sram_clk) if(reset | clear) empty <= 1; else if(do_store) empty <= 0; else if(do_retrieve & (/*(addr_retrieve + 1)*/ addr_retrieve_p1 == addr_store)) empty <= 1; always @(posedge sram_clk) if(reset | clear) full <= 0; else if(do_retrieve) full <= 0; else if(do_store & (/*(addr_store+2)*/ addr_store_p2 == addr_retrieve)) full <= 1; reg can_store; always @* if(full | ~src_rdy_i) can_store <= 0; else if(do_store_del == 0) can_store <= 1; else if((do_store_del == 1) || (do_store_del == 2)) can_store <= (occ_in > 1); else can_store <= (occ_in > 2); reg can_retrieve; always @* if(empty | ~dst_rdy_i) can_retrieve <= 0; else if(do_retr_del == 0) can_retrieve <= 1; else if((do_retr_del == 1) || (do_retr_del == 2)) can_retrieve <= (space_in > 1); else can_retrieve <= (space_in > 2); reg [1:0] state; localparam IDLE_STORE_NEXT = 0; localparam STORE = 1; localparam IDLE_RETR_NEXT = 2; localparam RETRIEVE = 3; reg [7:0] countdown; wire countdown_done = (countdown == 0); localparam CYCLE_SIZE = 6; assign do_store = can_store & (state == STORE); assign do_retrieve = can_retrieve & (state == RETRIEVE); always @(posedge sram_clk) if(reset) do_store_del <= 0; else do_store_del <= {do_store_del[0],do_store}; always @(posedge sram_clk) if(reset) do_retr_del <= 0; else do_retr_del <= {do_retr_del[0],do_retrieve}; always @(posedge sram_clk) if(reset | clear) begin state <= IDLE_STORE_NEXT; countdown <= 0; end else case(state) IDLE_STORE_NEXT : if(can_store) begin state <= STORE; countdown <= CYCLE_SIZE; end else if(can_retrieve) begin state <= RETRIEVE; countdown <= CYCLE_SIZE; end STORE : if(~can_store | (can_retrieve & countdown_done)) state <= IDLE_RETR_NEXT; else if(~countdown_done) countdown <= countdown - 1; IDLE_RETR_NEXT : if(can_retrieve) begin state <= RETRIEVE; countdown <= CYCLE_SIZE; end else if(can_store) begin state <= STORE; countdown <= CYCLE_SIZE; end RETRIEVE : if(~can_retrieve | (can_store & countdown_done)) state <= IDLE_STORE_NEXT; else if(~countdown_done) countdown <= countdown - 1; endcase // case (state) // RAM wires assign sram_bw = 0; assign sram_adv = 0; assign sram_mode = 0; assign sram_zz = 0; assign sram_ce = 0; assign sram_a = (state==STORE) ? addr_store : addr_retrieve; assign sram_we = ~do_store; assign sram_oe = ~do_retr_del[1]; assign my_oe = do_store_del[1] & sram_oe; assign sram_d = my_oe ? datain : 18'bz; // FIFO wires assign dataout = sram_d; assign src_rdy_o = do_retr_del[1]; assign dst_rdy_o = do_store_del[1]; endmodule // fifo_extram //wire have_1 = (fullness == 1); //wire have_2 = (fullness == 2); //wire have_atleast_1 = ~empty; //wire have_atleast_2 = ~(empty | have_1); //wire have_atleast_3 = ~(empty | have_1 | have_2); //wire full_minus_1 = (fullness == (RAMSIZE-1)); // 19'h7FE); //wire full_minus_2 = (fullness == (RAMSIZE-2)); // 19'h7FD); //wire spacefor_atleast_1 = ~full; //wire spacefor_atleast_2 = ~(full | full_minus_1); //wire spacefor_atleast_3 = ~(full | full_minus_1 | full_minus_2);