As a learning exercise I am doing some HDMI experiments on an FPGA using VHDL. When coming to implement it in Vivado (2017.1) I am encountering the following warning in the timing report:
There are 11 register/latch pins with no clock driven by root clock pin: Hsync_i_reg/Q (HIGH)
I have opened the implemented schematic and looked for the pin in question. It seems to be connected to the same clock that everything else is connected to (and those are not flagged in the timing report), so I am confused as to what the errors above are referring to. Here are some shots from the schematics:
Here is the VHDL code of the offending design:
library ieee;
use ieee.std_logic_1164.all;
entity ctrl_gen is
generic (
ha: integer := 96; --hpulse
hb: integer := 144; --hpulse+hbp
hc: integer := 784; --hpulse+hbp+hactive
hd: integer := 800; --hpulse+hbp+hactive+hfp
va: integer := 2; --vpulse
vb: integer := 35; --vpulse+vbp
vc: integer := 515; --vpulse+vbp+vactive
vd: integer := 525 --vpulse+vbp+vactive+vfp
);
port (
clk25: in std_logic; --tmds clock (25mhz)
hsync: out std_logic; --horizontal sync
vsync: out std_logic; --vertical sync
hactive: out std_logic; --active portion of hsync
vactive: out std_logic; --active portion of vsync
dena: out std_logic --display enable
);
end entity;
architecture behavioral of ctrl_gen is
signal hsync_i, hactive_i, vactive_i, vsync_i : std_logic;
begin
-- horizontal signals generation
hproc : process (clk25)
variable hcount: integer range 0 to hd := 0;
begin
if rising_edge(clk25) then
hcount := hcount + 1;
if (hcount=ha) then
hsync_i <= '1';
elsif (hcount=hb) then
hactive_i <= '1';
elsif (hcount=hc) then
hactive_i <= '0';
elsif (hcount=hd) then
hsync_i <= '0';
hcount := 0;
end if;
end if;
end process;
-- vertical signals generation
vproc : process (hsync_i)
variable vcount: integer range 0 to vd := 0;
begin
if falling_edge(hsync_i) then
vcount := vcount + 1;
if (vcount=va) then
vsync_i <= '1';
elsif (vcount=vb) then
vactive_i <= '1';
elsif (vcount=vc) then
vactive_i <= '0';
elsif (vcount=vd) then
vsync_i <= '0';
vcount := 0;
end if;
end if;
end process;
dena <= hactive_i and vactive_i;
hsync <= hsync_i;
vactive <= vactive_i;
hactive <= hactive_i;
end behavioral;
On reflection, I think that the warning is telling me that Hsync_i_reg/Q is the clock used for the Vcount registers, not that Hsync_i_reg itself if not connected to the root clock pin?
Is the method I have used bad practice and unlikely to work? The overall design is not working and I'm trying to understand whether this is the cause.
Thanks.
I see potential design issues. First being the use of variable
for objects that are actually clocked signals. Secondly, you're using a generated signal as a clock input. That's also not nice.
I would modify your code to the following (not tested if it completely does what your code did before)
library ieee;
use ieee.std_logic_1164.all;
entity ctrl_gen is
generic (
ha: integer := 96; --hpulse
hb: integer := 144; --hpulse+hbp
hc: integer := 784; --hpulse+hbp+hactive
hd: integer := 800; --hpulse+hbp+hactive+hfp
va: integer := 2; --vpulse
vb: integer := 35; --vpulse+vbp
vc: integer := 515; --vpulse+vbp+vactive
vd: integer := 525 --vpulse+vbp+vactive+vfp
);
port (
clk25: in std_logic; --tmds clock (25mhz)
hsync: out std_logic; --horizontal sync
vsync: out std_logic; --vertical sync
hactive: out std_logic; --active portion of hsync
vactive: out std_logic; --active portion of vsync
dena: out std_logic --display enable
);
end entity;
architecture behavioral of ctrl_gen is
signal hsync_i, hactive_i, vactive_i, vsync_i : std_logic;
signal hcount: integer range 0 to hd-1 := 0;
signal vcount: integer range 0 to vd-1 := 0;
begin
-- horizontal signals generation
hproc : process (clk25)
begin
if rising_edge(clk25) then
if hcount < hd-1 then
hcount <= hcount + 1;
else
hcount <= 0;
end if;
if (hcount=ha-1) then
hsync <= '1';
end if;
if (hcount=hb-1) then
hactive_i <= '1';
end if;
if (hcount=hc-1) then
hactive_i <= '0';
end if;
if (hcount=hd-1) then
hsync <= '0';
end if;
end if;
end process;
-- vertical signals generation
vproc : process (clk25)
begin
if rising_edge(clk25) then
if hcount = hd-1 then -- moment of falling_edge hsync.
if vcount < vd-1 then
vcount <= vcount + 1;
else
vcount <= 0;
end if;
if (vcount=va-1) then
vsync <= '1';
end if;
if (vcount=vb-1) then
vactive_i <= '1';
end if;
if (vcount=vc-1) then
vactive_i <= '0';
end if;
if (vcount=vd-1) then
vsync <= '0';
end if;
end if;
end if;
end process;
dena <= hactive_i and vactive_i;
vactive <= vactive_i;
hactive <= hactive_i;
end behavioral;