[Place 30-568] A LUT 'xn_inferred_i_1' is driving clock pin of 51 registers. This could lead to large hold time violations. First few involved registers are:
prd_contr/delay_reg_reg {FDCE}
prd_contr/p_reg_reg[0] {FDCE}
prd_contr/p_reg_reg[10] {FDCE}
prd_contr/p_reg_reg[11] {FDCE}
prd_contr/p_reg_reg[12] {FDCE}
I'm not sure if I mentioned this in your other thread.
If you don't use a global or regional clock buffer and use general purpose routing for your clock, then clock skew will be a problem and you will need to use a ripple T-FF counter if you want something that sort of works. But you'll have to disable the ring oscillator if you ever want to see a valid count value (the ripple propagation is probably longer than the clock period). I'm not entirely sure if you can route a clock like this without ever using a clock buffer (well I've never had an occasion where I needed to do such a thing).
I still think this is a ridiculous and probably totally useless experiment, which teaches students nothing about design.
I could understand if this was something involving process variation across the die, but then you would have to do something like another poster here was doing and use Tcl to generate the design, placement, and routing all by hand so the implementation of each ring osc/counter are identical across the entire die. So that any die process variations will be the major contributor to any differences. You would also want to run this on 100's of devices over many different lots to get any meaningful results.
Hence, this is useless (IMO) as a teaching aid.
-- Listing 6.7
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY period_counter IS
PORT(clk, reset : IN std_logic;
start, si : IN std_logic;
ready, done_tick : OUT std_logic;
prd : OUT std_logic_vector(31 DOWNTO 0)); -- was (9 DOWNTO 0)
END period_counter;
ARCHITECTURE arch OF period_counter IS
--mostafa
attribute KEEP : string;
attribute S : string;
--mostafa
CONSTANT CLK_MS_COUNT : integer := 5; -- 50000; -- 1 ms tick
TYPE state_type IS (idle, waite, count, done);
SIGNAL state_reg, state_next : state_type;
SIGNAL t_reg, t_next : unsigned(15 DOWNTO 0); -- up to 50000
SIGNAL p_reg, p_next : unsigned(31 DOWNTO 0); -- up to 1 sec -- was unsigned(9 DOWNTO 0);
SIGNAL delay_reg : std_logic;
SIGNAL edge : std_logic;
attribute KEEP of state_reg : signal is "TRUE";
attribute S of state_reg : signal is "TRUE";
attribute KEEP of state_next : signal is "TRUE";
attribute S of state_next : signal is "TRUE";
attribute KEEP of t_reg : signal is "TRUE";
attribute S of t_reg : signal is "TRUE";
attribute KEEP of t_next : signal is "TRUE";
attribute S of t_next : signal is "TRUE";
attribute KEEP of p_reg : signal is "TRUE";
attribute S of p_reg : signal is "TRUE";
attribute KEEP of p_next : signal is "TRUE";
attribute S of p_next : signal is "TRUE";
attribute KEEP of delay_reg : signal is "TRUE";
attribute S of delay_reg : signal is "TRUE";
attribute KEEP of edge : signal is "TRUE";
attribute S of edge : signal is "TRUE";
BEGIN
-- state and data register
PROCESS(clk, reset)
BEGIN
IF reset = '1' THEN
state_reg <= idle;
t_reg <= (OTHERS => '0');
p_reg <= (OTHERS => '0');
delay_reg <= '0';
ELSIF (clk'event AND clk = '1') THEN
state_reg <= state_next;
t_reg <= t_next;
p_reg <= p_next;
delay_reg <= si;
END IF;
END PROCESS;
edge <= (NOT delay_reg) AND si;
PROCESS(start, edge, state_reg, t_reg, t_next, p_reg)
BEGIN
ready <= '0';
done_tick <= '0';
state_next <= state_reg;
p_next <= p_reg;
t_next <= t_reg;
CASE state_reg IS
WHEN idle =>
ready <= '1';
IF (start = '1') THEN
state_next <= waite;
END IF;
WHEN waite => -- wait for the first edge
IF (edge = '1') THEN
state_next <= count;
t_next <= (OTHERS => '0');
p_next <= (OTHERS => '0');
----- added by me
if (p_reg = "00000101111101011110000011110110") then
p_next <= (others => '0');
t_next <= (others => '0');
end if;
------ end of added by me
END IF;
WHEN count =>
IF (edge = '1') THEN -- 2nd edge arrived
state_next <= done;
ELSE -- otherwise count
IF t_reg = CLK_MS_COUNT-1 THEN -- 1ms tick
t_next <= (OTHERS => '0');
p_next <= p_reg + 1;
ELSE
t_next <= t_reg + 1;
END IF;
END IF;
WHEN done =>
done_tick <= '1';
state_next <= idle;
END CASE;
END PROCESS;
prd <= std_logic_vector(p_reg);
END arch;
You have stated nothing that proves or disproves any claims about your circuit functioning. How was this "does not count anything" claim determined? Simulation, hardware? where? Are you sure your counter and your ring oscillator exists in the implemented design. Are there any signals getting removed in synthesis, in implementation?However, using a BUFG, did not solve the problem and still the regsters in period counter have no clock signal and that's why the period counter does not count anything !!!
This: **broken link removed**msdarvishi said:Somewhere in your comments, you have talked about using asynchronous counter using T-flip-flops. Here is the code that I am using as a period counter that is so accurate in post PR simulation. This is a synchronous period counter. Can you please help me what modifications I must do to change it to a, asynchronous period countrer??
You have stated nothing that proves or disproves any claims about your circuit functioning. How was this "does not count anything" claim determined? Simulation, hardware? where? Are you sure your counter and your ring oscillator exists in the implemented design. Are there any signals getting removed in synthesis, in implementation?
This: **broken link removed**
as long as the first FF can toggle at the rate of the ring oscillator the rest of the FFs should also toggle correctly, but you have to stop the clock to read the output as each bit of the count has a Tco+Troute delay added to it. Once n_counter_bits*(Tco+Troute) >= Tperiod you can't read all the bits in the same clock cycle.
Did you do as another on this thread suggested and apply a clock constraint to the output of the ring oscillator? You will have to use a set_generated_clock for that, which I think will require a virtual clock constraint as you need to specify a source clock. You will probably also need to set a false path for the ring oscillator loop as you don't want it trying to make timing around the loop.I receive the former critical warning message that all registers in my 32-bit counter have no clock signal !! I do not know exactly WHY???
Did you do as another on this thread suggested and apply a clock constraint to the output of the ring oscillator? You will have to use a set_generated_clock for that, which I think will require a virtual clock constraint as you need to specify a source clock. You will probably also need to set a false path for the ring oscillator loop as you don't want it trying to make timing around the loop.
create_generated_clock -name osc_clk -source [get_pins ringosc/y] -multiply_by 1 [get_pins ringosc/y]
[Timing 38-285] Generated clock osc_clk with source pin ringosc/y does not have a valid master clock or valid waveform.
You need to use create_clock and create a virtual clock to generate the master clock used by the create_generated_clock, that is why you have an error. You are trying to create a clock on a specific node in the design based on that same node being the master clock.
- - - Updated - - -
Actually after checking some sdc examples, you can probably get away just with create_clock on an input node of the RO.
create_clock -period 13.506 -name virtual_clk -waveform {0.000 6.753} [get_pins ringosc/inv/x]
set_property IOSTANDARD LVCMOS33 [get_ports prd*]
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?