I am trying to implement and simulate ring oscillators in Xilinx Vivado with the LUT6 primitive. When running the Behavioral Simulation it runs fine, and I can see the signal switch every 5 ns due to my added delay. For doing the Power Simulation I need to be able to run the Timing Simulation. Both the Post-Synthesis and Post-Implementation timing simulations produce the result X
indicating an error.
I have tried the ring oscillator from this answer as well, and I have the same issue where the Behavioral Simulation works, but the Timing Simulation doesn't. The constraints file should allow ring oscillators. The target language in Vivado is Verilog as Timing Simulation only works on that.
RO_LUT_I0.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity RO_LUT_I0 is
Port (
EndAND : out STD_LOGIC
);
end RO_LUT_I0;
architecture rtl of RO_LUT_I0 is
--amount of ROs
constant size : integer := 2;
--input signal for specific LUT
signal I0 : std_logic_vector(0 to size - 1) := (others => '0');
--output signal
signal O : std_logic_vector(0 to size - 1);
--connect inputs to ground
signal I1 : std_logic := '0';
signal I2 : std_logic := '0';
signal I3 : std_logic := '0';
signal I4 : std_logic := '0';
signal I5 : std_logic := '0';
begin
--instantiation LUT
gen_LUT6: for i in 0 to size - 1 generate
LUT6_inst : LUT6
generic map (
INIT => X"0000000000000001") -- Only when every input is 0, produce 1. Otherwise produce 0.
port map (
O => O(i), -- LUT general output
I0 => I0(i), -- LUT input
I1 => I1, -- LUT input
I2 => I2, -- LUT input
I3 => I3, -- LUT input
I4 => I4, -- LUT input
I5 => I5 -- LUT input
);
end generate gen_LUT6;
-- End of LUT6_inst instantiation
--Create RO and combine into END gate
process(O)
variable TempAND : std_logic;
begin
--set output as input to create RO
I0 <= O after 1 ns;
--combine all
TempAND := '1';
for i in 0 to size - 1 loop
TempAND := TempAND and O(i);
end loop;
EndAND <= TempAND;
end process;
end rtl;
RO_LUT_I0_TB.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity RO_LUT_I0_TB is
end RO_LUT_I0_TB;
architecture sim of RO_LUT_I0_TB is
signal EndAND : STD_LOGIC := 'U';
begin
--DUT
i_RO_LUT_I0 : entity work.RO_LUT_I0(rtl) port map(
EndAND => EndAND);
process is
begin
wait;
end process;
end architecture;
RO_LUT_constr.xdc
set_property IOSTANDARD LVCMOS33 [get_ports EndAND]
set_property PACKAGE_PIN A2 [get_ports EndAND]
#Don't touch LUTS
set_property DONT_TOUCH TRUE [get_cells *LUT6*]
# Allow combinatorial loops for all nets
set_property ALLOW_COMBINATORIAL_LOOPS true [get_nets]
set_property SEVERITY {Warning} [get_drc_checks LUTLP-1]
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
TL;DR: this isn't a ring oscillator, and you can't synthesise 'after 1ns'. You should read your log files.
There's too much here for a simple SO question. I think (correct me if I'm wrong) that you're instantiating 2 LUTs, each of which is an inverter. Each input is driven from its own output after a delay which is "after 1ns". The two inverters aren't conencted to each other. The module output in the AND of the two inverter outputs. Correct?
i+1
, i-1
, whatever, to connect to the next element. You also have to handle the end condition to wrap around the whole thing.X
s you'll need to inject a reset value somehow.