You are on page 1of 4

Module fifo1 #(parameter dsize = 8, parameter assize = 8)(

Input wclk,rclk,w_rst,r_rst, [dsize-1:0] data_in,r_en,w_en,


Output rempty, wfull,[dsize-1:0] data_out);

Wire [asize-1:0] waddr,raddr;


Wire[asize:0] wq2_rptr,rq2_wptr,wptr,rptr;

fifomem #(dsize, asize)


fifomem(.data_in(data_in),.wclk(wclk),.w_en(w_en),.w_full(w_full),.waddr(waddr),.raddr(ra
ddr),.data_out(data_out));

sync_r2w #(asize) sync_r2w(.wclk(wclk),.w_rst(w_rst),.rptr(rptr),.wq2_rptr(wq2_rptr));

sync_w2r #(asize) sync_w2r(.rclk(rclk),.r_rst(r_rst),.wptr(wptr),.rq2_wptr(rq2_wptr));

r_empty #(asize)
r_empty(.rq2_wptr(rq2_wptr),.r_en(r_en),.rclk(rclk),.r_rst(r_rst),.raddr(raddr),.rptr(rptr),.re
mpty(rempty));

w_full #(asize)
(.wq2_rptr(wq2_rptr),.w_en(w_en),.wclk( wclk),.w_rst( w_rst),.wfull(wfull),.waddr(waddr),.
wptr(wptr));

endmodule

module fifomem #(parameter dsize = 8, parameter asize = 8) (


input [dsize-1:0] data_in,
input wclk,w_en,wfull,
input [asize-1:0] waddr, raddr,
output [dsize-1:0] data_out);

localparam depth = 1<<asize;


reg [dsize-1:0] mem [depth-1:0];

assign rdata = mem[raddr];


always @(posedge wclk)
begin
if (w_en && !wfull)
mem[waddr] <= wdata;
end
endmodule

module sync_r2w #(parameter asize = 8)(


input wclk,w_rst, [asize-1:0] rptr;
output reg [asize-1:0] wq2_rptr);

reg [asize-1:0] wq1_rptr;

always@(posedge wclk,negedge w_rst)


begin
if(!w_rst)
{wq2_rptr,wq1_rptr}<= 0;
else
{wq2_rptr,wq1_rptr}<= {wq1_rptr,rptr};
end
endmodule

module sync_w2r #(parameter asize = 8)(


input rclk,r_rst, [asize-1:0] wptr;
output reg [asize-1:0] rq2_wptr);

reg [asize-1:0] rq1_wptr;

always@(posedge rclk,negedge r_rst)


begin
if(!r_rst)
{rq2_wptr,rq1_aptr}<= 0;
else
{rq2_wptr,rq1_wptr}<= {rq1_wptr,wptr};
end
endmodule

module r_empty #(parameter asize = 8)(


input [ADDRSIZE :0] rq2_wptr,
input r_en, rclk, r_rst);
output [asize-1:0] raddr,
output reg [asize-1 :0] rptr
output reg rempty);

reg [asize:0] r_bin;


wire [asize:0] r_nxt_gry, r_nxt_bin;
wire mt_val;

always@(posedge rclk, negedge r_rst)


begin
if(!rst)
{r_bin, rptr} <= 0;
else
{r_bin, rptr} <= {r_nxt_bin, r_nxt_gry};
end
assign raddr = rbin[asize-1:0];
assign r_nxt_bin = rbin + {r_en & ~rempty};
assign r_nxt_gry = (r_nxt_bin>>1)^r_nxt_bin;
assign mt_val = (r_nxt_gry == rq2_wptr);

always @(posedge rclk,negedge r_rst)


begin
if (!r_rst)
rempty <= 1'b1;
else
rempty <= mt_val;
endmodule

module w_full #(parameter asize = 8)(


input [asize:0] wq2_rptr,
input w_en, wclk, w_rst,
output reg wfull,
output [asize-1:0] waddr,
output reg [asize :0] wptr);

reg [asize:0] w_bin;


wire [asize:0] w_nxt_gry, w_nxt_bin;
wire full_val;

always@(posedge clk, negedge w_rst)


begin
if(!w_rst)
{w_bin, wptr} <= 0;
else
{w_bin, wptr} <= {w_nxt_bin, w_nxt_gry};
end
assign w_nxt_bin = w_bin + {w_en & ~wfull};
assign w_nxt_gry = (w_nxt_bin>>1)^w_nxt_bin;
assign full_val = ((w_nxt_gry[asize] != wq2_rptr[asize])&&(w_nxt_gry[asize-1] !=
wq2_rptr[asize-1])&&(w_nxt_gry[asize-2:0] != wq2_rptr[asize-2:0]));

always@(posedge clk, negedge w_rst)


begin
if(!w_rst)
wfull <= 0;
else
wfull = full_val;
end
endmodule

You might also like