diff options
Diffstat (limited to 'src/rtl/modexpa7_simple_fifo.v')
-rw-r--r-- | src/rtl/modexpa7_simple_fifo.v | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/rtl/modexpa7_simple_fifo.v b/src/rtl/modexpa7_simple_fifo.v new file mode 100644 index 0000000..84c21a9 --- /dev/null +++ b/src/rtl/modexpa7_simple_fifo.v @@ -0,0 +1,209 @@ +`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 + // + 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 |