`timescale 1ns / 1ps module modexpa7_simple_fifo # ( parameter BUS_WIDTH = 128, parameter DEPTH_BITS = 2 ) ( input clk, input rst, input wr_en, input rd_en, input [BUS_WIDTH-1:0] d_in, output [BUS_WIDTH-1:0] d_out ); // // Locals // localparam NUM_WORDS = 2 ** DEPTH_BITS; localparam [DEPTH_BITS:0] PTR_ZERO = {DEPTH_BITS{1'b0}}; localparam [DEPTH_BITS:0] PTR_LAST = {DEPTH_BITS{1'b1}}; // // Memory // (* RAM_STYLE="DISTRIBUTED" *) reg [BUS_WIDTH-1:0] fifo[0:NUM_WORDS-1]; // // Pointers // reg [DEPTH_BITS-1:0] ptr_wr; reg [DEPTH_BITS-1:0] ptr_rd; // // Output // reg [BUS_WIDTH-1:0] d_out_reg; assign d_out = d_out_reg; // // Write Pointer // always @(posedge clk) // if (rst) ptr_wr <= PTR_ZERO; else if (wr_en) ptr_wr <= ptr_wr + 1'b1; // // Read Pointer // always @(posedge clk) // if (rst) ptr_rd <= PTR_ZERO; else if (rd_en) ptr_rd <= ptr_rd + 1'b1; // // Read Logic // always @(posedge clk) // if (rst) d_out_reg <= {BUS_WIDTH{1'b0}}; else if (rd_en) d_out_reg <= fifo[ptr_rd]; // // Write Logic // always @(posedge clk) // if (!rst && wr_en) fifo[ptr_wr] <= d_in; /* generic_dpram #(aw,dw) u0( .rclk( clk ), .rrst( !rst ), .rce( 1'b1 ), .oe( 1'b1 ), .raddr( rp ), .do( dout ), .wclk( clk ), .wrst( !rst ), .wce( 1'b1 ), .we( we ), .waddr( wp ), .di( din ) ); //////////////////////////////////////////////////////////////////// // // Misc Logic // always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) wp <= #1 {aw{1'b0}}; else if(clr) wp <= #1 {aw{1'b0}}; else if(we) wp <= #1 wp_pl1; assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1}; assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10}; always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) rp <= #1 {aw{1'b0}}; else if(clr) rp <= #1 {aw{1'b0}}; else if(re) rp <= #1 rp_pl1; assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1}; //////////////////////////////////////////////////////////////////// // // Combinatorial Full & Empty Flags // assign empty = ((wp == rp) & !gb); assign full = ((wp == rp) & gb); // Guard Bit ... always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) gb <= #1 1'b0; else if(clr) gb <= #1 1'b0; else if((wp_pl1 == rp) & we) gb <= #1 1'b1; else if(re) gb <= #1 1'b0; //////////////////////////////////////////////////////////////////// // // Registered Full & Empty Flags // // Guard Bit ... always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) gb2 <= #1 1'b0; else if(clr) gb2 <= #1 1'b0; else if((wp_pl2 == rp) & we) gb2 <= #1 1'b1; else if((wp != rp) & re) gb2 <= #1 1'b0; always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) full_r <= #1 1'b0; else if(clr) full_r <= #1 1'b0; else if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1; else if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0; always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) empty_r <= #1 1'b1; else if(clr) empty_r <= #1 1'b1; else if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0; else if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1; //////////////////////////////////////////////////////////////////// // // Combinatorial Full_n & Empty_n Flags // assign empty_n = cnt < n; assign full_n = !(cnt < (max_size-n+1)); assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2]; // N entries status always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) cnt <= #1 {aw+1{1'b0}}; else if(clr) cnt <= #1 {aw+1{1'b0}}; else if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1}; else if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1}; //////////////////////////////////////////////////////////////////// // // Registered Full_n & Empty_n Flags // always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) empty_n_r <= #1 1'b1; else if(clr) empty_n_r <= #1 1'b1; else if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0; else if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1; always @(posedge clk `SC_FIFO_ASYNC_RESET) if(!rst) full_n_r <= #1 1'b0; else if(clr) full_n_r <= #1 1'b0; else if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1; else if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0; */ endmodule