Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] FPGA: Different behavior after synthesis

Status
Not open for further replies.

birbal

Newbie level 5
Joined
Oct 30, 2014
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
72
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.
 

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.
 

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.
 

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

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.

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.
 
  • Like
Reactions: birbal

    birbal

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top