+ Post New Thread
Results 1 to 5 of 5
  1. #1
    Newbie level 5
    Points: 519, Level: 4

    Join Date
    Oct 2014
    Posts
    8
    Helped
    0 / 0
    Points
    519
    Level
    4

    FPGA: Different behavior after synthesis

    I'm using a Digilent Nexys4 development board with Vivado v2017.1 and verilog for the code. My design uses a master clock (clk) of 100MHz. In of my modules I generate a 2 MHz clock (sclk) as follow:
    Code:
    always @ (posedge clk) begin
       if (adc_en) begin
    	if (clock_count < TICKS_SCLK -1)
            	clock_count <= clock_count + 1;
    	else 
    		clock_count <= 16'b0;			
    	end
    end
    
    assign sclk = clock_count > ((TICKS_SCLK-1)/2);
    Where in this case TICKS_SCLK is set to 50 to generate a 2 MHz clock. Then I use the sclk in the same module to have an FSM process as:

    Code:
    always @ (negedge sclk) begin
       ...
       ...
    end
    Inside of this FSM are only non-blocking assignments (<=). In simulation everything works fine. After implementation, when I upload the desing into the board, the circuit behaves differently. I hooked up a logic analyzer to understand what is happening. The sclk is indeed 2 MHz with 50% duty cycle as intended. However everything what is inside of that process with negedge sclk seems to happen at any edge of sclk (posedge or negedge). I can't figure it out where is the problem.

    - - - Updated - - -

    After a bit more research I found out that I need to put a user defined generated clock constraint. Something like: create_generated_clock -name sclk [get_nets MCP3208/sclk_OBUF] . However at the moment I have issues in getting the net quite right. Not sure why this is giving me an error. I can see in the shcematic after synthesis that MCP3208/sclk_OBUF is the name of the net of generated clock.

    •   Alt12th June 2017, 22:23

      advertising

        
       

  2. #2
    Super Moderator
    Points: 26,817, Level: 39
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,096
    Helped
    1495 / 1495
    Points
    26,817
    Level
    39

    Re: FPGA: Different behavior after synthesis

    create_generate_clock is not applied to a net it's applied to a pin. Use the get_pins and use the hierarchical pin name for the output of the sclk logic.

    I also think using a combinational circuit to generate a clock (i.e., sclk = clock_count > ((TICKS_SCLK-1)/2);) is a bad idea. I would at least use a registered output. I also suspect that the original problem is due to this combinatorial circuit, with different delays on each bit of clock_count you are likely see a bunch of clock glitches on the clock as clock_count increments through it's values and has absolutely nothing to do with the lack of a generated clock constraint.

    I doubt you would even need to constrain a 2 MHz clock unless you like to write code that always results in 1000+ levels of LUTs between FFs. A 500 ns clock period is pretty much eternity in an FPGA.

    You seem to be coding with a software engineer mindset and believe (wrongly) that every signal changes cleanly when each HDL statement is executed, unfortunately hardware doesn't work that way and delays between logic paths to the same destination are to be expected.



    •   Alt12th June 2017, 23:07

      advertising

        
       

  3. #3
    Newbie level 5
    Points: 519, Level: 4

    Join Date
    Oct 2014
    Posts
    8
    Helped
    0 / 0
    Points
    519
    Level
    4

    Re: FPGA: Different behavior after synthesis

    I kind of realized that is not an optimal way to generate a clock. But my question is how do I generate a 2 MHz based on the master 100 MHz? I would also like to be parametrizable...not always is going to be a 2 MHz, in some instances the freq might vary.

    I also tried with the pin name for constraint but I always get this error:

    ERROR: [Constraints 18-851] Could not find an automatically derived clock matching the supplied criteria for renaming.
    Resolution: Review the create_generated_clock renaming specification. Use the report_clocks command to obtain the details of currently defined clocks and ensure that the create_generated_clock rename constraint specifies appropriate data to select one generated clock for renaming. Verify that you are attempting to rename a tool derived generated clock, and not a user defined generated clock.

    Even though the pin (or net) exist.



    •   Alt12th June 2017, 23:18

      advertising

        
       

  4. #4
    Newbie level 5
    Points: 519, Level: 4

    Join Date
    Oct 2014
    Posts
    8
    Helped
    0 / 0
    Points
    519
    Level
    4

    Re: FPGA: Different behavior after synthesis

    Update: Modified the clock generation by using a register (instead of the combinational way) and this seems to solve the problem.



  5. #5
    Super Moderator
    Points: 26,817, Level: 39
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,096
    Helped
    1495 / 1495
    Points
    26,817
    Level
    39

    Re: FPGA: Different behavior after synthesis

    Quote Originally Posted by birbal View Post
    I kind of realized that is not an optimal way to generate a clock. But my question is how do I generate a 2 MHz based on the master 100 MHz? I would also like to be parametrizable...not always is going to be a 2 MHz, in some instances the freq might vary.
    Non-optimal?, no I said it is non-functional. It will never function in an FPGA. A compare operation on the output of a counter will always glitch no matter what you do with the placement and routing. Use a FF as the output preferably something simple like a toggle FF with the toggle control set to toggle the "clock" when the counter reaches the terminal count value and rolls over.

    Quote Originally Posted by birbal View Post
    I also tried with the pin name for constraint but I always get this error:

    ERROR: [Constraints 18-851] Could not find an automatically derived clock matching the supplied criteria for renaming.
    Resolution: Review the create_generated_clock renaming specification. Use the report_clocks command to obtain the details of currently defined clocks and ensure that the create_generated_clock rename constraint specifies appropriate data to select one generated clock for renaming. Verify that you are attempting to rename a tool derived generated clock, and not a user defined generated clock.

    Even though the pin (or net) exist.
    Then you aren't using the actual pin name, have you looked for it via the schematic view in synthesis settings? That is how I find out how the synthesis tool mangles a name, though in this case the pin name should be the output of some LUT.

    I still think you are wasting time trying to add this silly constraint, it won't do anything and is totally unnecessary for your design to work.

    - - - Updated - - -

    Code:
    assign sclk = clock_count > ((TICKS_SCLK-1)/2);
    Besides everything else this is a bad way to do the compare to determine the high or low state of sclk.

    If TICKS_SCLK == 10 then you get 9/2 = 4.5 which is not what you should have it compute.

    You should be doing the following TICKS_SCLK/2 (find half of the TICKS_SCLK, TICKS_SCLK should always be a even number) then subtract 1, i.e TICKS_SCLK/2 -1 that gives you an integer value every time, unless you use an odd number of counts.


    1 members found this post helpful.

--[[ ]]--