0
\$\begingroup\$

I'm trying to delay an input data coming from ADC component in DDR to my FPGA, afterwards output it in the clock rising edge. The ADC Im using: ADS5463: enter image description here

Im using Lattice ECP3 FPGA, based on the fpga datasheet this fpga have delay module built in called DELAYB:

enter image description here

The reason why Im trying to delay the inputs is to maximize the setup time and hold time as the ADS5463 recommends to do.

My code for trying to use this delay module and output the delayed data in rising edge clock:

module top(
 input rstn,
 input dry, //DRY=fs/2 -> fs=300Mhz -> DRY=150MHz 
 input [11:0] data_input, 
 output clk2,
 output [11:0] data_output
 );
 wire clk2;
 wire rst;
 wire [11:0] data_input_delay;
 reg [11:0] posedge_data;
 reg [11:0] negedge_data;
 reg [23:0] data_output;
 assign rst = ~rstn;
 //divide clk. clk2=dry_i/2=75MHz.
 CLKDIVB div2 (
 .CLKI (dry),
 .RST (rst),
 .RELEASE(1'b1),
 .CDIV1 (),
 .CDIV2 (clk2),
 .CDIV4 (),
 .CDIV8 ()
 ); 
 //delay data => 35ps steps. 
 genvar i;
 generate 
 for (i = 0; i < 12; i = i + 1) begin
 DELAYB delay (
 .A(data_input[i]),
 .DEL0(1'b1),
 .DEL1(1'b1),
 .DEL2(1'b0),
 .DEL3(1'b0),
 .Z(data_input_delay[i])
 ); 
 end
 endgenerate
 always @(posedge dry, posedge rst)
 begin
 if (rst) begin
 posedge_data <= 12'b100000000000;
 end else begin
 posedge_data <= data_input_delay;
 end
 end
 always @(negedge dry, posedge rst)
 begin
 if (rst) begin
 negedge_data <= 12'b100000000000;
 end else begin
 negedge_data <= data_input_delay;
 end
 end 
 always @(posedge clk2, posedge rst)
 begin
 if (rst) begin
 data_output <= 24'b100000000000100000000000;
 end else begin
 data_output <= {posedge_data, negedge_data};
 end
 end 
endmodule 

When Im trying to synthesize this code, I'm getting this error message from Diamond Lattice:

ERROR - Dynamic delay cell 'genblk1[0].delay' cannot drive component 'negedge_data[0]'.

ERROR - Dynamic delay cell 'genblk1[11].delay' cannot drive component 'negedge_data[11]'.

ERROR - Dynamic delay cell 'genblk1[10].delay' cannot drive component 'negedge_data[10]'.

ERROR - Dynamic delay cell 'genblk1[9].delay' cannot drive component 'negedge_data[9]'.

ERROR - Dynamic delay cell 'genblk1[8].delay' cannot drive component 'negedge_data[8]'.

ERROR - Dynamic delay cell 'genblk1[7].delay' cannot drive component 'negedge_data[7]'.

ERROR - Dynamic delay cell 'genblk1[6].delay' cannot drive component 'negedge_data[6]'.

ERROR - Dynamic delay cell 'genblk1[5].delay' cannot drive component 'negedge_data[5]'.

ERROR - Dynamic delay cell 'genblk1[4].delay' cannot drive component 'negedge_data[4]'.

ERROR - Dynamic delay cell 'genblk1[3].delay' cannot drive component 'negedge_data[3]'.

ERROR - Dynamic delay cell 'genblk12.delay' cannot drive component 'negedge_data2'.

ERROR - Dynamic delay cell 'genblk11.delay' cannot drive component 'negedge_data1'.

INFO - Errors found in user's design. Output files not written. Check map report for more details.

Someone please can help me see my thats happening? I have ref design which using this components and there its working fine, whats wrong?

Edit After Rakend comment:

okay after adding IFS1P3IX instances to the output registers of DELAYB module like the ref advised. It did fix the errors mentioned above, but now my design putting the data_input's in High-Z mode, its still not working, the design is pass the synthesises but giving me this warning which makes the design now working.

the new code:

module top (rstn,dry,data_input,clk2,led_clk,led_rst,data_output);
 input rstn;
 input dry; //DRY=fs/2 -> fs=300Mhz -> DRY=150MHz 
 input [11:0] data_input; 
 output wire clk2;
 output led_clk;
 output reg led_rst;
 output reg [23:0] data_output;
 wire rst;
 wire [11:0] data_input_temp;
 wire [11:0] data_input_delay;
 reg [25:0] adc_clk_count = 26'b0;
 assign rst = ~rstn;
 //divide clk. clk2=dry_i/2=75MHz.
 CLKDIVB div2 (
 .CLKI (dry),
 .RST (rst),
 .RELEASE(1'b1),
 .CDIV1 (),
 .CDIV2 (clk2),
 .CDIV4 (),
 .CDIV8 ()
 ); 
 genvar i;
 generate 
 for (i = 0; i < 12; i = i + 1) begin
 DELAYB delay (
 .A(data_input[i]),
 .DEL0(1'b1),
 .DEL1(1'b1),
 .DEL2(1'b0),
 .DEL3(1'b0),
 .Z(data_input_temp[i])
 ); 
 end
 endgenerate
 genvar j;
 generate 
 for (j = 0; j < 12; j = j + 1) begin
 IFS1P3IX data_reg (
 .Q(data_input_delay[j]),
 .SP(1'b1),
 .CD(rst),
 .SCLK(dry),
 .D(data_input_temp[j])
 ); 
 end
 endgenerate
endmodule 

the critical warning Diamond drop on me:

2019991 WARNING - CL168 :"C:\----\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[11].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[10].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[9].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[8].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[7].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[6].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[5].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[4].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[3].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[2].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[1].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":51:12:51:19|Removing instance genblk2[0].data_reg because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\-------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[11].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[10].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[9].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[8].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[7].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[6].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[5].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\---------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[4].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[3].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\--------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[2].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[1].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019991 WARNING - CL168 :"C:\-----------\ADC_Interface\src\top.v":37:10:37:14|Removing instance genblk1[0].delay because it does not drive other instances. To preserve this instance, use the syn_noprune synthesis directive.
2019993 WARNING - MT420 |Found inferred clock top|dry with period 5.00ns. Please declare a user-defined clock on port dry.
1166052 WARNING - logical net 'CDIV1' has no load.
1166052 WARNING - logical net 'CDIV4' has no load.
1166052 WARNING - logical net 'CDIV8' has no load.
1166052 WARNING - logical net 'data_input_c[0]' has no load.
1166052 WARNING - logical net 'data_input_c[1]' has no load.
1166052 WARNING - logical net 'data_input_c[2]' has no load.
1166052 WARNING - logical net 'data_input_c[3]' has no load.
1166052 WARNING - logical net 'data_input_c[4]' has no load.
1166052 WARNING - logical net 'data_input_c[5]' has no load.
1166052 WARNING - logical net 'data_input_c[6]' has no load.
1166052 WARNING - logical net 'data_input_c[7]' has no load.
1166052 WARNING - logical net 'data_input_c[8]' has no load.
1166052 WARNING - logical net 'data_input_c[9]' has no load.
1166052 WARNING - logical net 'data_input_c[10]' has no load.
1166052 WARNING - logical net 'data_input_c[11]' has no load.
1163101 WARNING - DRC complete with 15 warnings.
1100523 WARNING - C:/--------/ADC_Interface
51001030 WARNING - Using local reset signal 'rstn_c' to infer global GSR net.

Any Idea why it happening?

asked Feb 26, 2020 at 7:02
\$\endgroup\$
7
  • 1
    \$\begingroup\$ 1) the delay modules are normally not instanced by hand afaik but are part of the automatic DDR instantiation process via IPExpress. 2) over the course of your questions I get the feeling that you try to implement a DDR interface "by hand". The intended way is described here: latticesemi.com/~/media/LatticeSemi/Documents/ApplicationNotes/… - look for ddr generic. \$\endgroup\$ Commented Feb 26, 2020 at 7:24
  • \$\begingroup\$ @ChristianB. thanks for the comment. I familiar with this PDF, I did tried to create Generic DDR with LVDS inputs and when its created its became my top module of the project without any success to assign anyother file as top module. Should I keep it as top module and assign the FPGA pins to the signals this IP created? I created: "GDDRX1_RX.SCLK.Aligned" \$\endgroup\$ Commented Feb 26, 2020 at 7:48
  • 1
    \$\begingroup\$ I tried to (ab)use the delay instances as well for a delay line but it turns out that lattice diamond/technology lib is rather rigid if it comes to constraints. So did you manage to use the IPExpress generated DDR by now? Sometimes one has to manually change the main module via the project settings. \$\endgroup\$ Commented Feb 26, 2020 at 19:49
  • \$\begingroup\$ @ChristianB. Thanks for the effort and the concern man. I also did understand that using these lattice modules manually its just a big headache. I did had sucess using the IPexpress, I generated the file for this interface and changed it a bit and copy it to another project and in this way overcome the problem that it became top module. Tomorrow I want to try again and open a new project using the IPexpress without any tricks. I think the problem maybe because Im choosing LVDS inputs for the interface so it has to be top module? what you think? \$\endgroup\$ Commented Feb 26, 2020 at 20:08
  • \$\begingroup\$ anyway ill try tomorrow and open new question if ill had another problem. \$\endgroup\$ Commented Feb 26, 2020 at 20:09

1 Answer 1

1
\$\begingroup\$

Based on the error and the description "Data going to DDR registers", the DELAYB modules can only be used before PIO register. This may not be able to drive the other registers.

This example is also showing that the DELAYB driving IO register.

Edited :

Further check at the FPGA ref guide shows:

The DELAYB block can also be used to delay non-DDR inputs that use the input PIO register.

This means that the DELAYB block can be used for DDR (probably the IDDR and ODDR components) and PIO registers.

Each PIO includes a sysIO buffer and I/O logic (IOLOGIC). The I/O logic includes input, output and tri-state registers that implement both single data rate (SDR) and double data rate (DDR) applications along with the necessary clock and data selection logic.

Refer http://www.latticesemi.com/en/Support/AnswerDatabase/1/9/4/1946

answered Feb 26, 2020 at 10:23
\$\endgroup\$
5
  • \$\begingroup\$ @Rakned Thanks! its helped with the errors but now Im facing new warning which makes the design not to work, can you look on the edited post? \$\endgroup\$ Commented Feb 26, 2020 at 11:31
  • \$\begingroup\$ @MichaelAstahov May be something wrong with the connections or reset caused the tool to optimize the signals. But I believe it's better to put it as a different question since it may not be due to DELAYB module and some other persons can help. Also, what happened to the adc codes? I hope it's not an xy problem \$\endgroup\$ Commented Feb 26, 2020 at 12:02
  • \$\begingroup\$ ok ill take your advice and open another question. I commented for now the ADC code (the 3 alwyas block which put rising/falling delayed data in the output register) because for now all I want to see is that the DELAY module works and transfer the data to the 'data_input_delay' register. \$\endgroup\$ Commented Feb 26, 2020 at 13:02
  • 1
    \$\begingroup\$ @MichaelAstahov why don't you try using IDDR for latching ADC data instead of using normal flip flops? This is what we usually do. \$\endgroup\$ Commented Feb 26, 2020 at 13:36
  • \$\begingroup\$ ok thanks, I had problems with it but I overcome them now in the second try when using the generic DDR lattice provide in IPexpress. So I have some valid data to work with now. Anyways its still intresting why its not working manually :( \$\endgroup\$ Commented Feb 26, 2020 at 13:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.