FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > FPGA

FPGA comp.arch.fpga newsgroup (usenet)

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 04-09-2006, 01:58 AM
kelvins
Guest
 
Posts: n/a
Default asynchronous FIFO design

As I have a problem in asynchronous FIFO design.
My case is described as below,

I want to design a FIFO as write in clock VD domain, and read in clock
CP domain.
And there is a signal (VD domain) informs 32-bytes is completed write
to FIFO, then
can be read out in clock CP domain, and guarantee there is not any data
coming in
the read out phase.

The RTL code is below, It's passed in simulation phase. My problem is
can it
pass the synthesis phase? Will it have any issue? Thanks.

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// assume clk_cp = 50 Mhz, clk_vd = 30 Mhz.
// input data and enable
input datain_en; // based on clk_vd, high active
input [7:0] datain; // based on clk_vd;

// assuming write 32 bytes data, will send a completed packet_end
signal
// for informing we can read out in clk_cp clock domain. And make sure
// there is not any datain_en coming in the read out phase.
input pkt_end; // based on clk_vd;

output dataout_valid;
output [7:0] dataout;

reg [4:0] wptr; // based on clk_vd
reg [4:0] rptr; // based on clk_cp
reg [7:0] mem [4:0];
always @(negedge vd_rst_n or posedge clk_vd)
begin
if(~vd_rst_n) begin
wptr <=5'b0;
end else begin
if(datain_en) begin
mem[wptr] <= datain;
wptr <= wptr + 1;
end
end
end

// assume clk_cp = 50 Mhz, clk_vd = 30 Mhz.
// avoid the metastable
reg [3:0] pkt_end_cp;
always @(negedge cp_rst_n or posedge clk_cp)
begin
if(~cp_rst_n) begin
pkt_end_cp <= 4'b0;
end else begin
pkt_end_cp <= { pkt_end_cp[2:0], pkt_end};
end
end

wire pkt_end_cp_en = ~pkt_end_cp[3] & pkt_end_cp[2] ;

reg dataout_valid;
reg [4:0] data_vld_cnt;
always @(negedge cp_rst_n or posedge clk_cp)
begin
if(~cp_rst_n) begin
dataout_valid <= 1'b0;
end else begin
if (dataout_valid && data_vld_cnt==5'd31)
dataout_valid <= 1'b0;
else if(pkt_end_cp_en)
dataout_valid <= 1'b1;
end
end

always @(negedge cp_rst_n or posedge clk_cp)
begin
if(~cp_rst_n) begin
data_vld_cnt <= 5'b0;
end else begin
if (dataout_valid && data_vld_cnt==5'd31)
data_vld_cnt <= 5'b0;
else if(dataout_valid)
data_vld_cnt <= data_vld_cnt + 1;
end
end


always @(negedge cp_rst_n or posedge clk_cp)
begin
if(~cp_rst_n) begin
rptr <=5'b0;
end else begin
if(dataout_valid) begin
rptr <= rptr + 1;
end
end
end

assign dataout = mem[rptr];

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Reply With Quote
  #2 (permalink)  
Old 04-09-2006, 04:29 AM
Peter Alfke
Guest
 
Posts: n/a
Default Re: asynchronous FIFO design

Basically, your design is very simple. You just use one BlockRAM port
to write with one clock, and the other port to read using the other
clock.

The devil is in the handshaking logic, where you must send a signal
from one clock domain to the other, and back.
Concentrate on this handshake signal. The rest is trivial.
Peter Alfke

Reply With Quote
  #3 (permalink)  
Old 04-10-2006, 08:09 PM
Brian Philofsky
Guest
 
Posts: n/a
Default Re: asynchronous FIFO design


The code you have provided will use LUT RAMs when targeting Xilinx
architectures as the asynchronous read does not allow BlockRAM
inference. If you desire BlockRAM, you should change the reading of the
memory array to be synchronous (including synchronous reset if desired
although for the depth you are using though (32-bits) LUT RAMs are
probably not necessarily a bad thing. At first glance, I see one issue
with your code. You have within an always block with a reset the
writing to the RAM. If you do not separate out this code into an always
block without a reset, you could have synthesis - simulation mismatch.
I suggest changing the following:

always @(negedge vd_rst_n or posedge clk_vd)
begin
if(~vd_rst_n) begin
wptr <=5'b0;
end else begin
if(datain_en) begin
mem[wptr] <= datain;
wptr <= wptr + 1;
end
end
end

To:

always @(negedge vd_rst_n or posedge clk_vd)
if(~vd_rst_n) begin
wptr <=5'b0;
else if (datain_en)
wptr <= wptr + 1;

always @(posedge clk_vd)
if(datain_en) begin
mem[wptr] <= datain;

There are other things that can be done to make this slightly more
efficient as well. If you get rid of the reset on any shift register
code like this:

always @(negedge cp_rst_n or posedge clk_cp)
begin
if(~cp_rst_n) begin
pkt_end_cp <= 4'b0;
end else begin
pkt_end_cp <= { pkt_end_cp[2:0], pkt_end};
end
end

To:

always @(posedge clk_cp)
pkt_end_cp <= { pkt_end_cp[2:0], pkt_end};

You would have opportunities to infer SRLs and thus save some resources.
In this particular case, it would not be a big difference but in
others it may make a bigger difference. There are also cases where
changing to a synchronous reset from an asynchronous reset can also
improve area and performance. For this piece of code, again, probably
would not see much but is still a good general suggestion. I would
suggest though to keep the reset asynchronous for the boundary crossing
logic since that should probably be considered asynchronous any ways.

-- Brian


kelvins wrote:
> As I have a problem in asynchronous FIFO design.
> My case is described as below,
>
> I want to design a FIFO as write in clock VD domain, and read in clock
> CP domain.
> And there is a signal (VD domain) informs 32-bytes is completed write
> to FIFO, then
> can be read out in clock CP domain, and guarantee there is not any data
> coming in
> the read out phase.
>
> The RTL code is below, It's passed in simulation phase. My problem is
> can it
> pass the synthesis phase? Will it have any issue? Thanks.
>


<Snip>
Reply With Quote
  #4 (permalink)  
Old 04-10-2006, 08:35 PM
Peter Alfke
Guest
 
Posts: n/a
Default Re: asynchronous FIFO design

If data comes in 8-bit parallel, and 32 bytes deep, then you can use
SRL16 shift registers for storage.
So you need to cascade two SRL16 per parallel bit, which makes it a
total of 16 LUTs.
Then, considering the low clock rate, you can design a clock-gating
controller that carefully switches between the two clock domains.
(see TechXclusives: "Six Easy Pieces" for glitch-free clock
multiplexing).
Total: less than 3 CLBs @ 8 LUTs per CLB..
Peter Alfke, Xilinx Applications

Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Asynchronous FIFO - Different widths of Input & Output Ports. Gokul Verilog 1 08-25-2008 07:33 PM
Asynchronous FIFO with depth that is not a power of 2 googler Verilog 6 05-15-2008 11:10 AM
Asynchronous FIFO design question [email protected] FPGA 12 03-08-2006 05:32 PM
Generating Asynchronous FIFO in Block Memory of Sparatn-II in CoreGen Atif FPGA 0 09-03-2003 06:30 AM


All times are GMT +1. The time now is 01:42 AM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved