Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential glitch and failure possible in generic_fifo: combinational logic output passed to the other clock domain #101

Open
pbazarnik opened this issue Apr 24, 2017 · 0 comments

Comments

@pbazarnik
Copy link

Consider path from wr_addr (clk_wr domain register) ---> oh_bin2gray (combinational logic) -> oh_dsync (clk_rd domain register)

Glitch may be generated in oh_bin2gray (logic deays) or due to clock skew in wr_addr register
(binary so multiple bits changing at the same time) and may be latched by clk_rd domain register causing failure (incorrect value of wr_addr_gray_sync).

The occurrence of the failure will depend on target device (clock/signal skews) and clock source (if all clocks come from common source via division it will be less likely)

Solution:
Gray code signal must be registered before being sent to clk_rd domain register.
It could be achieved by directly implementing Gray code counter using wr_addr_gray as registered signal and generating wr_addr via oh_gray2bin (both signals are in the same clock domain)

Relevant code:

always @ ( posedge wr_clk or negedge wr_nreset)
if(!wr_nreset)
wr_addr[AW:0] <= 'b0;
else if(wr_en)
wr_addr[AW:0] <= wr_addr[AW:0] + 'd1;
.
.
.
// convert to gray code (only one bit can toggle)
oh_bin2gray #(.DW(AW+1))
wr_b2g (.out (wr_addr_gray[AW:0]),
.in (wr_addr[AW:0]));

// synchronize to read clock
oh_dsync wr_sync[AW:0] (.dout (wr_addr_gray_sync[AW:0]),
.clk (rd_clk),
.nreset(rd_nreset),
.din (wr_addr_gray[AW:0]));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant