cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
kmshah93
Observer
Observer
1,052 Views
Registered: ‎08-12-2019

Unexpected Counter Behavior

Hi,

I am having a Spartan 7 FPGA (XC7S50). I have implemented a counter, just to check basics.

Here is my code.

module counter (clk, rst, q, led);
  // Ports
  input logic clk;
  input logic rst;
  output logic [2:0] q;
  output logic led;

  // Internal Nets
  logic [2:0] temp_q;

  // Continuous Assignments
  assign q = temp_q;
  assign led = (rst == 1'b1) ? 1'b0 : 1'bz; // 0 - LED On, Z - LED Off

  // Sequential Block
  always @(posedge clk, negedge rst)
  begin
    if (~rst)
      temp_q <= 3'd0;
    else
      temp_q <= temp_q + 3'd1;
  end
endmodule

Here is my constraint file.

set PERIOD 90; # 100 = 10.0MHz

create_clock -name "CLK" -add -period $PERIOD [get_ports clk]

set all_clock_ports [get_ports [list clk]]

set_clock_uncertainty -setup 5.0 [all_clocks]
set_clock_uncertainty -hold 0.2 [all_clocks]

set_output_delay 15.0 -clock CLK [all_outputs]; ; # Dummy delay to clear warnings

set_load 0.40 [all_outputs]; # max load cap for a inv_f2_1p8v = 0.406

set_property IOSTANDARD LVCMOS33 [get_ports]

# Configuration Bank 0 Voltage Levels - 1.8V
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]

# Setting Up Property of Non Clock Ports
set bufg_cells [get_cells -filter {PRIMITIVE_TYPE==CLK.GCLK.BUFG}]
set no_clock_dedicated_nets {}
set no_clock_ports {"q" "rst"}

foreach i $bufg_cells {
set pin [get_pins -of_objects $i -filter {DIRECTION == in}]
set fanin [all_fanin $pin -startpoints_only]
set name [get_property NAME $fanin]
if {[lsearch $no_clock_ports $name] > -1} {
set net [get_nets -of_objects $pin]
lappend no_clock_dedicated_nets $net
set_property CLOCK_DEDICATED_ROUTE FALSE $net
}
}

# -------------------------------------
# VIVADO Pin Placement
# -------------------------------------
# Clock Pins
set_property PACKAGE_PIN F14 [get_ports {clk}]

# Input
set_property PACKAGE_PIN G18 [get_ports {rst}]

# Output
set_property PACKAGE_PIN H17 [get_ports {q[2]}]
set_property PACKAGE_PIN C13 [get_ports {q[1]}]
set_property PACKAGE_PIN E16 [get_ports {q[0]}]

# LED Port
set_property PACKAGE_PIN L13 [get_ports {led}]

 

However, I checked the outputs in oscilloscope and it seems something unexpected behavior. Here is the snapshot from oscilloscope.

counter_temp_3bit.png

The topmost blue signal is clock and rest all are 3 bit outputs. 

There are so many glitches and so many transitions in single clock cycles. It is such that most probably this output is of no help for the subsequent connected logic.

Can anyone please help me to find whats wrong here?

0 Kudos
19 Replies
avrumw
Guide
Guide
1,002 Views
Registered: ‎01-23-2009

You haven't really given us much information...

You don't tell us what board you are using, so its hard to see if what you are doing is right. For example, you are telling the tools that the clock is 11MHz, but does pin F14 really carry an 11MHz clock? A create_clock does not actually "create" a clock on the board, it merely describes the clock that exists on the board to the tools.

But even if the clock is really 90ns, how are you using your oscilloscope? Its hard to understand the settings, but I think it is saying that the time setting is 1us/division. If this is correct, then your scope is set to be too slow to be able to see these signals (and if, as I suspect the clock isn't really 11MHz, but is actually 100MHz or more then it is way too slow). In which case, your scope is probably aliasing - the "square wave envelope" you are seeing isn't real, but is merely an artifact due to the aliasing - you need to either run this scope faster, or use a faster scope to be able to see signals that are that fast...

Avrum

0 Kudos
kmshah93
Observer
Observer
1,000 Views
Registered: ‎08-12-2019

@avrumw ,

I am using Opal Kelly XEM7305 board.

In the constraints, clock is of 10MHz. But actually clock is of 1MHz (blue signal in the scope).

0 Kudos
bruce_karaffa
Scholar
Scholar
974 Views
Registered: ‎06-21-2017

How are you creating that 1MHz clock?  That is too slow for an MMCM.  Using a clock generated by dividing another clock using the FPGA fabric can lead to problems like this because of clock skew. 

0 Kudos
kmshah93
Observer
Observer
972 Views
Registered: ‎08-12-2019

@bruce_karaffa 

Yes. Internal PLL doesn't allow me to  go below some 6MHz or 4MHz.

I am giving clock from external port through signal generator.

0 Kudos
allanherriman
Mentor
Mentor
935 Views
Registered: ‎01-08-2012

"A clock from a signal generator" is probably the cause.  Poor signal integrity will cause the FPGA to see multiple edges (when you expect it to see a single edge), and the counter will do strange things.

Here's what you do to solve this in extreme cases:

  • Only clock the FPGA from a source on the same PCB.
  • Use a differential signal for the clock.
  • Control the impedance of the clock traces on the PCB.
  • Don't have any stubs on the clock traces on the PCB.  (Use a fanout buffer on the PCB if you have multiple loads.)
  • Terminate the clock input (preferably on die, although you might get away with using a resistor on the PCB close to the FPGA).
  • Don't have any FPGA output signals close to the clock inputs.  Here "close" means within a few pins on the die and on the BGA.
  • Only clock the internal FPGA logic from a BUFG (or other clock buffer) driven from an MMCM or other internal PLL, not from a pin.

Some subset of those will make your counter work.

kmshah93
Observer
Observer
927 Views
Registered: ‎08-12-2019

@allanherriman ,

PFA. Here I have taken the clocks on oscilloscope. Relevant signals are in blue & yellow.

Blue Signal - sys_clk (Original 1MHz Clock from Signal Generator)

Yellow Signal - clk_o (where assign clk_o = sys_clk)

From the oscilloscope, it seems in good condition. Still do I need to think from clock prospective, which you have mentioned?

clk_1M_in_out.png

0 Kudos
allanherriman
Mentor
Mentor
919 Views
Registered: ‎01-08-2012

500ns/division means the possible clock glitches are smaller than a pixel wide at those settings.

You are unlikely to see the signal integrity issues that matter with those probes.  (The ringing on the edges is from the probes or the probing technique.)

It's also possible to have a clock glitch that can trigger a FF, yet is too short to appear on an output pin.

0 Kudos
dpaul24
Scholar
Scholar
916 Views
Registered: ‎08-07-2014

@kmshah93,

Yes. Internal PLL doesn't allow me to go below some 6MHz or 4MHz. I am giving clock from external port through signal generator.

Generate the lowest clock output of the available MMCM/PLL for the FPGA in use. If you need lower clocks, just use RTL to generate clock_enables that would give you 1MHz (or lower) operating frequency. Will save you a lot of headaches.

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem

kmshah93
Observer
Observer
894 Views
Registered: ‎08-12-2019

@dpaul24 ,

>> Generate the lowest clock output of the available MMCM/PLL for the FPGA in use. If you need lower clocks, just use RTL to generate clock_enables that would give you 1MHz (or lower) operating frequency. Will save you a lot of headaches

[KS] - You mean min freq through PLL and then using a counter to further divide that freq in RTL?

0 Kudos
dpaul24
Scholar
Scholar
887 Views
Registered: ‎08-07-2014

@kmshah93 

You mean min freq through PLL and then using a counter to further divide that freq in RTL?

Yes. But don't generate a new clock. Keep the MMCM/PLL output clock as the clock to be distributed, and via a counter generate clock_enable signals for your logic.

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem

0 Kudos
drjohnsmith
Teacher
Teacher
880 Views
Registered: ‎07-09-2009

Show us the simulation please
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
kmshah93
Observer
Observer
860 Views
Registered: ‎08-12-2019

@dpaul24 ,

>> Yes. But don't generate a new clock. Keep the MMCM/PLL output clock as the clock to be distributed, and via a counter generate clock_enable signals for your logic.

[KS] - What I understood is that let's say we have 4MHz PLL output clock, then you want to enable that clock on every 4th cycle (counter = 11). 

Please correct me, if wrong.

However in this case, the final clock won't have 50% duty cycle, which I'll require. Also I am internally inverting the clock too.

Is there any specific reason to not generate ( and use that) a new clock with frequence divider? Because with frequency divider, we can generate a new clock of less frequency and then can put that clock onto global clock network through BUFG.

0 Kudos
drjohnsmith
Teacher
Teacher
834 Views
Registered: ‎07-09-2009

Your correct, the "clock" generated by a counter carry is not 50:50

But dont us it as a clock, but an enable,

so you distribute the master clock every where,
but the bits you want to run at 1/4 the clock, you only enable every 4th clock,

The reason to minimise the number of clocks ,
Its one of those key differences between and FPGA and an ASIC.
An FPGA has dedicated resources to distribute clocks,
designed for fast, low scew propagation, directly connected to the clk input of the registers in the FPGA,

 

// Sequential Block
  always @(posedge clk, negedge rst)
  begin
    if (~rst)
      temp_q <= 3'd0;
    elsif

             clk_divided_enable = 1 then
        temp_q <= temp_q + 3'd1;
  end



An ASIC , you can do what you want,

so one of the overridding design rules in FPGAs is , minimise the clocks,

If you have one clock, , and many enables, all one clock wide, that works just great,

It also makes timing and constraints much easier to have one clock , no clock crossing to consider.

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
dpaul24
Scholar
Scholar
804 Views
Registered: ‎08-07-2014

@kmshah93, The reason for not using a new clock, but the use clock_enables is mentioned above.

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem

0 Kudos
kmshah93
Observer
Observer
779 Views
Registered: ‎08-12-2019

@drjohnsmith ,

RTL is of someone else's. There are multiple instances and each with flops, so it's very difficult to add clock_enable logic in all flops. 

0 Kudos
drjohnsmith
Teacher
Teacher
767 Views
Registered: ‎07-09-2009

i would suggest strongly that the code is not fit for the job, and as its only 6 lines of code u write your own.

( you can blame me if you have to get approval )
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
kmshah93
Observer
Observer
751 Views
Registered: ‎08-12-2019

@drjohnsmith ,

Yes in the counter code I can change easily. No problem in that.

However counter is just to check setup and all and my original RTL, which I want to dump is of someone else. 

0 Kudos
drjohnsmith
Teacher
Teacher
744 Views
Registered: ‎07-09-2009

Is it not your counter that you have the problem with ?
If not, I suggest you mark this as closed and start a new topic with a representative title as to what problem you have.
<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
dpaul24
Scholar
Scholar
741 Views
Registered: ‎08-07-2014

@kmshah93,

RTL is of someone else's. There are multiple instances and each with flops, so it's very difficult to add clock_enable logic in all flops.

Either you fix it or ask the "someone else's" to do it the proper way!

------------FPGA enthusiast------------
Consider giving "Kudos" if you like my answer. Please mark my post "Accept as solution" if my answer has solved your problem

0 Kudos