这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » FPGA » FIFO的verilog实现

共2条 1/1 1 跳转至

FIFO的verilog实现

高工
2008-11-15 01:06:34     打赏

// FIFO的verilog实现

module fifo1 (rdata, wfull, rempty, wdata,
winc, wclk, wrst_n, rinc, rclk, rrst_n);
parameter DSIZE = 8;
parameter ASIZE = 4;
output [DSIZE-1:0] rdata;
output wfull;
output rempty;
input [DSIZE-1:0] wdata;
input winc, wclk, wrst_n;
input rinc, rclk, rrst_n;
wire [ASIZE-1:0] waddr, raddr;
wire [ASIZE:0] wptr, rptr, wrptr2, rwptr2;
sync_r2w sync_r2w
   (.wrptr2(wrptr2),

    .rptr(rptr),
    .wclk(wclk),

    .wrst_n(wrst_n));
sync_w2r sync_w2r
   (.rwptr2(rwptr2),

    .wptr(wptr),
    .rclk(rclk),

    .rrst_n(rrst_n));
fifomem #(DSIZE, ASIZE) fifomem
   (.rdata(rdata),

     .wdata(wdata),
    .waddr(waddr),

    .raddr(raddr),
    .wclken(winc),

    .wclk(wclk));
rptr_empty #(ASIZE) rptr_empty
   (.rempty(rempty),

     .raddr(raddr),
     .rptr(rptr),

     .rwptr2(rwptr2),
     .rinc(rinc),

     .rclk(rclk),

     .rrst_n(rrst_n));
wptr_full #(ASIZE) wptr_full
  (.wfull(wfull),

   .waddr(waddr),
   .wptr(wptr),

   .wrptr2(wrptr2),
   .winc(winc),

   .wclk(wclk),

   .wrst_n(wrst_n));
endmodule

 

module fifomem (rdata, wdata, waddr, raddr, wclken, wclk);
parameter DATASIZE = 8; // Memory data word width
parameter ADDRSIZE = 4; // Number of memory address bits
output [DATASIZE-1:0] rdata;
input [DATASIZE-1:0] wdata;
input [ADDRSIZE-1:0] waddr, raddr;
input wclken, wclk;
`ifdef VENDORRAM
// instantiation of a vendor's dual-port RAM
VENDOR_RAM MEM (.dout(rdata), .din(wdata),
.waddr(waddr), .raddr(raddr),
.wclken(wclken), .clk(wclk));
`else
reg [DATASIZE-1:0] MEM [0:(1<<ADDRSIZE)-1];
assign rdata = MEM[raddr];
always @(posedge wclk)
if (wclken) MEM[waddr] <= wdata;
`endif
endmodule

 

module sync_r2w (wrptr2, rptr, wclk, wrst_n);
parameter ADDRSIZE = 4;
output [ADDRSIZE:0] wrptr2;
input [ADDRSIZE:0] rptr;
input wclk, wrst_n;
reg [ADDRSIZE:0] wrptr2, wrptr1;
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) {wrptr2,wrptr1} <= 0;
else {wrptr2,wrptr1} <= {wrptr1,rptr};
endmodule

 

module sync_w2r (rwptr2, wptr, rclk, rrst_n);
parameter ADDRSIZE = 4;
output [ADDRSIZE:0] rwptr2;
input [ADDRSIZE:0] wptr;
input rclk, rrst_n;
reg [ADDRSIZE:0] rwptr2, rwptr1;
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) {rwptr2,rwptr1} <= 0;
else {rwptr2,rwptr1} <= {rwptr1,wptr};
endmodule

 

module rptr_empty (rempty, raddr, rptr, rwptr2, rinc, rclk, rrst_n);
parameter ADDRSIZE = 4;
output rempty;
output [ADDRSIZE-1:0] raddr;
output [ADDRSIZE:0] rptr;
input [ADDRSIZE:0] rwptr2;
input rinc, rclk, rrst_n;
reg [ADDRSIZE:0] rptr, rbin, rgnext, rbnext;
reg rempty, raddrmsb;
//-------------------
// GRAYSTYLE1 pointer
//-------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) begin
rptr <= 0;
raddrmsb <= 0;
end
else begin
rptr <= rgnext;
raddrmsb <= rgnext[ADDRSIZE]^rgnext[ADDRSIZE-1];
end
always @(rptr or rinc) begin: Gray_inc
integer i;
for (i=0; i<=ADDRSIZE; i=i+1)
rbin[i] = ^(rptr>>i);
if (!rempty) rbnext = rbin + rinc;
else rbnext = rbin;
rgnext = (rbnext>>1) ^ rbnext;
end
// Memory read-address pointer
assign raddr = {raddrmsb,rptr[ADDRSIZE-2:0]};
//---------------------------------------------------------------
// FIFO empty on reset or when the next rptr == synchronized wptr
//---------------------------------------------------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) rempty <= 1'b1;
else rempty <= (rgnext == rwptr2);
endmodule

 

module wptr_full (wfull, waddr, wptr, wrptr2, winc, wclk, wrst_n);
parameter ADDRSIZE = 4;
output wfull;
output [ADDRSIZE-1:0] waddr;
output [ADDRSIZE:0] wptr;
input [ADDRSIZE:0] wrptr2;
input winc, wclk, wrst_n;
reg [ADDRSIZE:0] wptr, wbin, wgnext, wbnext;
reg wfull, waddrmsb;
// GRAYSTYLE1 pointer
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) begin
wptr <= 0;
waddrmsb <= 0;
end
else begin
wptr <= wgnext;
waddrmsb <= wgnext[ADDRSIZE]^wgnext[ADDRSIZE-1];
end
always @(wptr or winc) begin: Gray_inc
integer i;
for (i=0; i<=ADDRSIZE; i=i+1)
wbin[i] = ^(wptr>>i);
if (!wfull) wbnext = wbin + winc;
else wbnext = wbin;
wgnext = (wbnext>>1) ^ wbnext;
end
// Memory write-address pointer
assign waddr = {waddrmsb,wptr[ADDRSIZE-2:0]};
wire w_2ndmsb = wgnext[ADDRSIZE] ^ wgnext[ADDRSIZE-1];
wire wr_2ndmsb = wrptr2[ADDRSIZE] ^ wrptr2[ADDRSIZE-1];
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) wfull<=0;
else wfull<=((wgnext[ADDRSIZE] !=wrptr2[ADDRSIZE]) &&
(w_2ndmsb ==wr_2ndmsb ) &&
(wgnext[ADDRSIZE-2:0]==wrptr2[ADDRSIZE-2:0]));
endmodule




关键词: verilog     实现     output     input     w    

菜鸟
2008-11-18 00:32:40     打赏
2楼
FIFO在数据流中是很有用处的,谢谢楼主哈

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]