08-11-2016 03:31 AM
IBUFG SPI_CLKBUF ( .I(RTD_SCK), .O(SPI_CLKIN)); //RTD_SCK is a clock capable input pin ODDR2 #( .DDR_ALIGNMENT("NONE"), // Sets output alignment to "NONE", "C0" or "C1" .INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1 .SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset ) DQ_3_OBUF ( .Q(DQ), // 1-bit DDR output data .C0(SPI_CLKIN), // 1-bit clock input .C1(~SPI_CLKIN), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D0(1'b1), // 1-bit data input (associated with C0) .D1(1'b0), // 1-bit data input (associated with C1) .R(1'b0), // 1-bit reset input .S(1'b0) // 1-bit set input );
It only happens for the first clock input after configuration (only tried JTAG, dont have SPI setup right now), here is logic analyzer capture (first signal is ODDR2 output pin, 2nd is input pin, and third is a reset signal):
Interestingly, tying the reset port of the ODDR2 to the reset signal doesnt change anything, i can have it reset every N clocks (or have it reset before the first clock comes) and it doesnt matter, it always just eats the FIRST CLOCK after CONFIGURATION, regardless.
When i just do assign DQ = SPI_CLKIN; (however, this introduces additional delay since the GCLK network cannot directly reach the IOB pin without routing, so the delay ends up being 5ns instead of 2ns for this case, not really visible on the image):
Also, the CE port doesnt matter for this "initialization clock" either, so I can work around it using a hack like this:
wire CLK_OSC; STARTUP_SPARTAN6 start(.CLK(1'b0), .GSR(1'b0), .KEYCLEARB(1'b1), .GTS(1'b0), .CFGMCLK(CLK_OSC)); wire CLK_OSC_50; BUFG CLK_OSC_BUF(.I(CLK_OSC), .O(CLK_OSC_50)); reg [1:0] clk_sel_hack = 2'b00; wire clk_sel_hack_done = clk_sel_hack; always@(posedge CLK_OSC_50) begin if (!clk_sel_hack_done) begin clk_sel_hack <= clk_sel_hack + 2'b01; end end IBUFG SPI_CLKBUF ( .I(PCLK), .O(SPI_CLKIN)); wire REAL_SPI_CLK; BUFGMUX #(.CLK_SEL_TYPE("ASYNC")) REAL_SPI_CLKBUF(.I0(CLK_OSC_50), .I1(SPI_CLKIN), .S(clk_sel_hack_done), .O(REAL_SPI_CLK)); //Now use REAL_SPI_CLK instead of SPI_CLKIN as you would normally, it will have 2 clock pulses at the beginning, luckily you can mask those out with CE low
However, this brings me no additional benefit over just assign, as the delay introduced by the 2 clocks and BUFGMUX adds the delay back to 5ns anyway.
Changing the initial state of the ODDR2 to 1 or switching around both the clock and data inputs doesnt really help me, the output signal still has the same amount of transitions, just that maybe the first "hump" ends up being longer or different.
It might have something to do with my startup order ?
However i cannot change this (well i tried swapping WREN and TRISTATE but it changed nothing), and also, it does not matter how long the FPGA has been running before the input clock starts going, it will still eat the first clock.
09-16-2016 05:52 AM
Can you check if this happens in Post impl timing simulation?