-
Couldn't load subscription status.
- Fork 298
Description
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]));