Problem:
module usbif (….. input ram_rd_sel_a;… ..sync sync_ram_rd_sel_a (
.clk (clk),
.rst (rst),
.in (ram_rd_sel_a),
.out (ram_rd_sel_sync_a)
);
endmodule
module usbpath (
…
.
.
input ram_rd_sel_a;
…
.
.
sync sync_ram_rd_sel_a (
.clk (clk),
.rst (rst),
.in (ram_rd_sel_a),
.out (ram_rd_sel_sync_a)
);
endmodule
Solution:
Synchronize signal (ram_rd_sel_a) to only one synchronizer.
Explanation:
Signals should always be synchronized to the destination clock domain only once. If two synchronizers, belonging to the same clock domain, synchronized a signal, t is possible that after the chip is laid out, each synchronizer could capture ram_rd_sel_a at different times causing downstream logic for each synchronizer to execute at different times with different values. Simply put, a race condition could occur.
Articles like these contain snippets of Verilog RTL code that identify redundant, useless, incorrect, or unnecessary code. They’ll be posted as I catch them in real-life Verilog code that was used in producing an ASIC. Part of being a good ASIC designer and of having a good development process is to regularly have code reviews – either by yourself or with your team. Often times, RTL like the example above are missed and should be corrected.