jason63
Newbie level 3
Hi,
I've written some code for a CPLD to perform the functions of a frequency counter. The code is working fine, but I'm getting some warnings about inferred latches. I understand why the compiler is generating the latches, but I'm wondering if there is a better way to do it. Here is the relevant code snippet:
The compiler warns me that clk_edge and count_shadow_* have inferred latches associated with them, but I actually want this behavior. The issue stems from the fact that I'm dealing with two asynchronous inputs and I need to change one output in response to one input, but not the other. Otherwise I would just split it apart into two separate processes.
I initially tried to write the code to be synchronous with the input fin like this:
But when I did this, I noticed that occasionally count_h would not be reset in initial if statement. I discovered this by hooking up a logic analyzer to the output and could see that every now and then count would fail to reset to zeros at the same time clk_edge was set to '0' (clk_edge was always set to '0' successfully).
I realize that the second block of code above also has a the same inferred latches in it to the first and that perhaps this is related to the above not always working correctly, but it's not clear to me how to eliminate them because I can't change count_shadow_* in the outermost else statement and count_h should only change when count_l rolls over.
The first code snippet works fine with the inferred latches -- I've run it for extended periods of time with the logic analyzer set to trigger on any failures and I never seen any. However, I would love to know how to get rid of the inferred latches which I have read are evidence of bad design. I'm even more curious as to what is going on in the second block of code that is causing the glitches I describe above and how it might be fixed.
--
Jason
I've written some code for a CPLD to perform the functions of a frequency counter. The code is working fine, but I'm getting some warnings about inferred latches. I understand why the compiler is generating the latches, but I'm wondering if there is a better way to do it. Here is the relevant code snippet:
Code:
-- port ( fin : in STD_LOGIC ); -- signal to be measured
-- signal clk_gate STD_LOGIC; -- gate clock
-- signal count_shadow_l UNSIGNED(15 downto 0); -- holds last full value of count
-- signal count_shadow_h UNSIGNED(15 downto 0);
process(fin,clk_gate)
variable clk_edge : STD_LOGIC := '1'; -- edge detection
variable count_l : UNSIGNED(15 downto 0);
variable count_h : UNSIGNED(15 downto 0);
begin
if (clk_gate='1' and clk_edge='1') then
clk_edge :='0'; -- only reset once per gate period
count_shadow_l <= count_l; -- save current count
count_shadow_h <= count_h;
count_l := (others => '0'); -- reset counter
count_h := (others => '0');
elsif (clk_gate='0' and clk_edge='0') then
clk_edge := '1'; -- enable edge detection
elsif rising_edge(fin) then
if count /= 65535 then
count_l := count_l + 1; -- increment low word
else
count_l := 0;
count_h := count_h + 1; -- increment high word
end if;
end if;
end process;
The compiler warns me that clk_edge and count_shadow_* have inferred latches associated with them, but I actually want this behavior. The issue stems from the fact that I'm dealing with two asynchronous inputs and I need to change one output in response to one input, but not the other. Otherwise I would just split it apart into two separate processes.
I initially tried to write the code to be synchronous with the input fin like this:
Code:
process
variable clk_edge : STD_LOGIC := '1';
variable count_l : UNSIGNED(15 downto 0);
variable count_h : UNSIGNED(15 downto 0);
begin
wait until rising_edge(fin);
if (clk_gate='1' and clk_edge='1') then
clk_edge := '0';
count_shadow_l <= count_l;
count_shadow_h <= count_h;
count_l := (others => '0');
count_h := (others => '0');
else
if count /= 65535 then
count_l := count_l + 1;
else
count_l := 0;
count_h := count_h + 1;
end if;
if (clk_gate='0' and clk_edge='0') then
clk_edge := '1';
end if;
end if;
end process;
But when I did this, I noticed that occasionally count_h would not be reset in initial if statement. I discovered this by hooking up a logic analyzer to the output and could see that every now and then count would fail to reset to zeros at the same time clk_edge was set to '0' (clk_edge was always set to '0' successfully).
I realize that the second block of code above also has a the same inferred latches in it to the first and that perhaps this is related to the above not always working correctly, but it's not clear to me how to eliminate them because I can't change count_shadow_* in the outermost else statement and count_h should only change when count_l rolls over.
The first code snippet works fine with the inferred latches -- I've run it for extended periods of time with the logic analyzer set to trigger on any failures and I never seen any. However, I would love to know how to get rid of the inferred latches which I have read are evidence of bad design. I'm even more curious as to what is going on in the second block of code that is causing the glitches I describe above and how it might be fixed.
--
Jason