This is a very large error. You must fix it with a design change. The fact that the design works in the lab means nothing. It can fail randomly at any time.
From the error message and the number of logic levels, we can draw the conclusion that this the gray encoding of a counter with many bits. probably for a clock domain crossing.
You can fix it with pipelining or simply by sampling the counter every n (2 or greater) clock cycles, and updating the register with the gray value at the same time.
There is no need to transfer FIFO read/write pointers to another clock domain every clock cycle.
thanks.
How is this done in the real world out there?
I have updated the design a bit but I cannot get the slack better than -12.
Are such things just ignored in FPGA designs if they are tested fine in the lab for some time?
For example the tool complains about every asynchronous reset, I don't even have a permanent clock on all the input modules so I have to use an asynchronous reset approach no?
How is this done in the real world out there?
I have updated the design a bit but I cannot get the slack better than -12.
Are such things just ignored in FPGA designs if they are tested fine in the lab for some time?
For example the tool complains about every asynchronous reset, I don't even have a permanent clock on all the input modules so I have to use an asynchronous reset approach no?
conv_bin_rd_addr_i_1 <= conv_bin_rd_addr_i;
bin_enc_wr_addr_i_1 <= bin_enc_wr_addr_i;
if (bin_enc_wr_addr_i_1 > conv_bin_rd_addr_i_1)
w_ptr_diff_i <= bin_enc_wr_addr_i_1 - conv_bin_rd_addr_i_1;
else if (conv_bin_rd_addr_i_1 > bin_enc_wr_addr_i_1)
w_ptr_diff_i <= ((FIFO_DEPTH - conv_bin_rd_addr_i_1) + bin_enc_wr_addr_i_1);
else
w_ptr_diff_i <= 14'b0;
Path Begin : dcfx/fifo/conv_bin_rd_addr_i_1_i0/Q
Path End : dcfx/fifo/w_ptr_diff_i__i13/D
Source Clock : clk_in
Destination Clock : clk_in
Logic Level : 33
Delay Ratio : 62.3% (route), 37.7% (logic)
Setup Constraint : 16666 ps
Path Slack : -14969 ps (Failed)
Destination Clock Arrival Time (clk_in:R#2): 16666
+ Destination Clock Source Latency : 0
- Destination Clock Uncertainty : 0
+ Destination Clock Path Delay : 6020
- Setup Time : 199
--------------------------------------------- --------
End-of-path required time( ps ) : 22487
Source Clock Arrival Time (clk_in:R#1) : 0
+ Source Clock Source Latency : 0
+ Source Clock Path Delay : 6020
+ Data Path Delay : 31437
--------------------------------------------- --------
End-of-path arrival time( ps ) : 37457
conv_bin_rd_addr_i_1 <= conv_bin_rd_addr_i;
bin_enc_wr_addr_i_1 <= bin_enc_wr_addr_i;
fifo_depth_minus_rd_addr_i_1 <= FIFO_DEPTH - conv_bin_rd_addr_i;
if (bin_enc_wr_addr_i_1 > conv_bin_rd_addr_i_1)
w_ptr_diff_i <= bin_enc_wr_addr_i_1 - conv_bin_rd_addr_i_1;
else if (conv_bin_rd_addr_i_1 > bin_enc_wr_addr_i_1)
w_ptr_diff_i <= fifo_depth_minus_rd_addr_i_1 + bin_enc_wr_addr_i_1;
else
w_ptr_diff_i <= 14'b0;
conv_bin_rd_addr_i_1 <= conv_bin_rd_addr_i;
bin_enc_wr_addr_i_1 <= bin_enc_wr_addr_i;
common_subtraction <= bin_enc_wr_addr_i_1 - conv_bin_rd_addr_i_1;
if (!common_subtraction[msb]) // this does >= here as there is no need to have an extra else at the end
w_ptr_diff_i <= common_subtraction;
else // this also basically used common_subtraction in the original version.
w_ptr_diff_i <= FIFO_DEPTH + common_subtraction;
Are the tools inferring block ram for this? 61440 bit is basically 2 BRAM -- there doesn't seem to be any savings by having a custom size. The custom size seems only to complicate things while possibly forcing the tools into a suboptimal non-bram implementation. (once I had something like a 4097 element ram which the tools forced into a register implementation...)
It also appears to have the same read/write clocks, so I'm not sure why this is done with gray code other than the file being somewhat generic. In that case, you could just keep track of the fifo-size without gray code, or external to the fifo if you have some need to get a specific number of elements before processing.
Also, looking at the logic, it shouldn't have been that bad from just what is shown. every term is basically "bin_enc_wr_addr_i_1 - conv_bin_rd_addr_i_1"
Code:conv_bin_rd_addr_i_1 <= conv_bin_rd_addr_i; bin_enc_wr_addr_i_1 <= bin_enc_wr_addr_i; common_subtraction <= bin_enc_wr_addr_i_1 - conv_bin_rd_addr_i_1; if (!common_subtraction[msb]) // this does >= here as there is no need to have an extra else at the end w_ptr_diff_i <= common_subtraction; else // this also basically used common_subtraction in the original version. w_ptr_diff_i <= FIFO_DEPTH + common_subtraction;
And I have a hard time believing a 3 input 16 bit adder/subtractor being so close to failing 60MHz by itself.
thanks again for the great hint to subtract the value and check for the negative MSB.
Is it really that difficult to make an FPGA design work properly?
No it's not difficult.
e.g. a 4kx30 FIFO in Xilinx would be implemented as 4096x36 or four 4096x9 BRAMs, as opposed to a multiplexed implementation of four 1024x36 BRAMs.
If that wasn't a typo and you really have a 30 deep FIFO with 4096 bits then you are probably having problems because you don't have a RAM and it is being implemented in FFs.
Path Begin : dcfx/fifo/gray_bin_conv_wr_addr_u/o_gray_cnt_out_i0/Q
Path End : dcfx/fifo/d1_gray_enc_wr_addr_i_i0/D
Source Clock : clk_in
Destination Clock : spi_clk
Logic Level : 2
Delay Ratio : 48.5% (route), 51.5% (logic)
Setup Constraint : 2083 ps
Path Slack : -1745 ps (Failed)
Destination Clock Arrival Time (spi_clk:R#8): 218750
+ Destination Clock Source Latency : 0
- Destination Clock Uncertainty : 0
+ Destination Clock Path Delay : 6020
- Setup Time : 199
--------------------------------------------- --------
End-of-path required time( ps ) : 224571
Source Clock Arrival Time (clk_in:R#14) : 216666
+ Source Clock Source Latency : 0
+ Source Clock Path Delay : 6020
+ Data Path Delay : 3630
--------------------------------------------- --------
End-of-path arrival time( ps ) : 226316
This is a clock domain crossing. If this is correctly designed as a gray transfer of the address, the cross clock domain transfer should use only use a max delay between source and destination registers. Your multiple clock domains should have an asynchronous clock groupings or have false paths set between them to remove them from producing impossible to meet timing paths.
Asynchronous clocks will be looked at over many cycles to find the worst case transfer between them and that will inevitably ALWAYS fail timing on both the setup and hold. Hence why the arrival times of the clocks are 218.750 ns for the spi_clk and 216.666 for the clk_in for the source and destination registers.
This issue is caused by having an improperly constrained design.
NBR Summary
-----------
Number of unrouted connections : 0 (0.00%)
Number of connections with timing violations : 0 (0.00%)
Estimated worst slack<setup> : 0.454ns
Timing score<setup> : 0
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?