08-28-2016 05:50 AM
I would like to enable/disable part of the design with gated clock. I implemented gating using the: BUFGCE port map (I=>clk_i, CE=>clk_gated_enable, O=>clk_gated).
Then I simulated the process(clk_gated) that tries to access the register in the non-gated region. The simulation does not work as I thought it will. It seems that the gated and non-gated clocks are not in phase, even though this is not seen in the simulation.
I am simply copying the register value: if (ir_wren = '1') then ir_ff <= instr_i; end if;
I case of common clock (no gating), everything is as expected:
But in case of gated clock, the register is not copied:
Why is that? What is the source clk to gated clk relation (inside the fpga and in the simulation)? How can I fix this?
08-28-2016 07:41 AM
First, you have to make sure that you are generating the gated clock correctly. You have given us the instantiation of the BUFGCE, but you haven't told us what "clk_i" is, nor how you are buffering the ungated clock. Structurally, there is only one "right" way to do this; If the clk_i is the .I input of the BUFGCE, then it also must be the input of a BUFG (see figure) - your clk_i would be "inClk" in the diagram and clk_gated would be "slowClk"...
As for why the simulation isn't behaving, it may be related to this (or not), but ultimately it is the VHDL language's concept of "delta-cycles"; within the same simulation time, the simulator can go through many delta-cycles, in which subsequently scheduled events for the same cycle are executed. For example, if you use the "clk_i" directly (and not through a BUFG), then logic running on the BUFGCE's output runs one delta-cycle later than the logic running on clk_i directly - this can affect the functionality of the simulation.
So, first make sure your design is structurally correct and let us know if that fixes the problem.
08-28-2016 09:28 AM
Thank you for your reply.
The clk_I is the clock generated by the Clocking Wizard (it uses MMCM). The BUFG is already included in the wizard output instance. So in my case I connected the fastClk to BUFGCE/I.
I assume a can not use the signals within the wizard, so should I "wire" the MMCM manually (to get the signal that is connecting MMCM/O to BUFG/I?
I am not sure if I should add also the constraints as described in create_generated_clock command? I did try to add the: create_generated_clock -name clk_gated -source [get_pins gated_clock/I] divide_by 1 [get_pins gated_clock/O]. But it returned critical warning: [Common 17-165] Too many positional options when parsing 'gated_clock/O', please type 'create_generated_clock -help' for usage info.
08-28-2016 10:03 AM
So what you have now is not correct - you have ended up with the output of the BUFG driving the input of the BUFGCE, which would lead to real clock skew in the system, and also (I am guessing) the delta-delay clock skew in the VHDL simulation.
You can still use the clock wizard, but you have to select the option to use "No buffer" for the MMCM output, and then manually instantiate both the BUFG and the BUFGCE outside the clock wizard (like my earlier picture).
As for the create_generated_clock, it depends on what you want to do with the clock. By default, as long as the input clock to the MMCM is constrained (and the clock wizard will create a constraint for you), the outputs of the MMCM will have clocks. These clocks will propagate through all buffers, including the BUFGCE - so the output of the BUFG and BUFGCE will carry the same clock (without any additional constraints needed).
If, however, you are using the gated clock as a "decimated" clock (where the CE Is asserted periodically, like one every 3 main clock cycles) then you do need a create_generated_clock so that the tools can take advantage of the longer clock period of the generated clock. This would be done by
create_generated_clock -name clkdiv3 -divide_by 3 -source [get_pins <name_of_bufgce>/I] [get_pins <name_of_bufgce/O]
08-28-2016 11:53 AM - edited 08-28-2016 01:47 PM
Thank you for your reply. I did what you suggested. I checked the Schematics and everything looks OK (the BUFGCE was implemented by BUFGCTRL).
I tested the simulation once again, but still no luck - the result is the same as shown on the two waveforms above. The register is still not copied when I run the process using gated clock.
08-28-2016 03:14 PM - edited 08-28-2016 03:16 PM
you are seeing a race-condition in the form of a hold-violation because you have two different clock sources and the simulator is free to order them in anyway it chooses. With a single clock, the simulator rules are such that this can't happen but when you have two separate sources, even if they have a single unit-delay from the same source, things can (and in your case do) break.
One way to make it work is to add a very small delay on the clock which is doing the read so that its edge will actually be further in time even if they are actually supposed to be in perfect phase.
Another solution, which is the actual way why chips work, is to add clock to output delays to the source flops to beat this race.
08-29-2016 12:24 PM - edited 08-29-2016 12:30 PM
Thank you for your reply.
Did you think the clock that does the read should come before the other (and not vice versa)?
I did try to delay the non-gated clock signal with "after 1ns", but the result is still the same :(
I also tried to "report_clocks" and the clk_gated is not listed - is that suppose to be? In the schematics everything looks ok.
08-29-2016 02:20 PM
I also tried to "report_clocks" and the clk_gated is not listed - is that suppose to be?
There are a whole bunch of things getting muddled together here.
First, lets look at the schematic/Vivado representation. Don't confuse the concept of a Vivado clock with a net that is carrying a clock. If you look at my diagram with the BUFG and BUFGCE, you have two nets (the output of the BUFG and the output of the BUFGCE) that are routed to clock pins of flip-flops. However, there is (at least unless you constrain it differently) one Vivado clock; that is the clock generated by the MMCM output - it propagates through both the BUFG and the BUFGCE to get to flip-flops. Depending on how the clock was generated, it may get a name that is similar to some net in the design, but they are different objects:
get_nets <name_of_net_carrying_clock>; # This returns an object of class net
get_clocks <name_of_clock>; # This returns an object of class clock
return different objects - they are not the same. A clock can be carried by multiple nets (for example the output of the BUFGCE and BUFG and even more so as nets traverse hierarchy). Furthermore, a single net can carry more than one clock!
Now, on to any confusion with VHDL simulation. Whatever weirdness VHDL has with event propagation on different signals has nothing to do with the Vivado concept of clocks (or even clock nets).
08-29-2016 08:49 PM
Thank you for the explanation, so the report_clocks is ok.
Does that mean that there is a bug in the vivado simulation tool? Is there some other free or trail version of the simulator that I could try?