EmbDev.net

Forum: FPGA, VHDL & Verilog Removing Latches


von Rob (Guest)


Rate this post
useful
not useful
Hallo,

I have a logic which infers latches for the signals flag_r and ctr_r. 
The signal flag_r is read in another process. Trying to remove latches 
changes the logic. Any tips on how to remove these latches?

Thanks!
1
    flag_r_gen: process(reset_n,in_o,reg_q, ctr_r) 
2
    begin
3
      if reset_n_i = '0' or (reg_q.cs_adc_1_n = '1' and reg_q.cs_adc_2_n = '1') then 
4
        ctr_r <= 0;
5
        flag_r <= '0';
6
      elsif (reg_q.cs_adc_1_n = '0' or reg_q.cs_adc_2_n= '0') then 
7
      if reg_q.wr_n = '0' then
8
      --   flag_r <= '0';  -- Removes Latch but logic does not work
9
        --   ctr_r <= 0;     -- Removes Latch but logic does not work
10
           if ((in_o(0) = '0') or (in_o(0) = '1'))  then
11
            if (ctr_r < 3) then  
12
           ctr_r <= ctr_r +1;
13
           flag_r <= '0';
14
        else
15
        flag_r <= '1';
16
            end if;
17
       end if;
18
      else
19
          flag_r <= '0';  
20
          ctr_r <= 0;    
21
        end if;
22
    else
23
          flag_r <= '0';  
24
          ctr_r <= 0;
25
         
26
    end if;
27
    end process;

von Achim S. (Guest)


Rate this post
useful
not useful
you use flag_r and ctr_r to store information. If you store information 
in a design without clock, you have a latch (and cannot avoid that).

If this storage is really needed (and at least for ctr_r it is needed 
for sure) you can remove the latch by storing the information in a 
Flipflop. I.e. use a clock and make a synchronous design (the "standard 
way" to work with an FPGA)

At least for the counter this is a real necessity. Cause
 ctr_r <= ctr_r +1;
forms a combinatorial loop. The latch in your design might still work in 
real hard, but this combinatorial loop will never do the things you want 
it to do.

By the way: you are aware, that the following if statement does not make 
much sense either?
           if ((in_o(0) = '0') or (in_o(0) = '1'))  then

And: a good indentation of your code would improve the readability very 
much.

von Rob (Guest)


Rate this post
useful
not useful
Unfortunately, the restriction is to use only one process with a clock. 
I want the counter to count on both the edges. So I have implemented a 
dual edge counter (in_o) and use in_o to increment the counter on both 
the edges.


1
in_o <= cnt(cnt'left downto 1) & (not clk_i); -- Dual edge detection
2
   
3
   reg : process(clk_i, reset_n_i)
4
   begin
5
      -- Asynchronous Reset
6
    
7
      if(reset_n_i = '0') then
8
         cnt(cnt'left downto 1) <= (others => '0');
9
   -- Clock the Register on Rising Edge
10
      elsif RISING_EDGE(clk_i) then    
11
   -- Dual Edge counter
12
         cnt(cnt'left downto 1) <= std_logic_vector(unsigned(cnt(cnt'left downto 1)) + 1);
13
         
14
      end if;
15
    
16
   end process;

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Achim S. wrote:
> Cause
>  ctr_r <= ctr_r +1;
> forms a combinatorial loop. The latch in your design might still work in
> real hard, but this combinatorial loop will never do the things you want
> it to do.
A combinatorial loop usually results from a misunderstood 
"2-process-coding-style" with split up registered and related 
combinatorial processes. Try this with google translator: 
http://www.lothar-miller.de/s9y/archives/42-Kombinatorische-Schleifen.html

Rob wrote:
> Trying to remove latches changes the logic.
How did you find that out? Do you run a simulation on that code?

BTW: does xxx_r mean, that the signal xxx_r should be in a register? 
If so, then you MUST use a clock. Only a clock infers a register. But 
keep in mind: a beginners design has exactly ONE clock. That "one and 
only" clock is used throughout the WHOLE design.

BTW: those_under_scores make your_code nearly_un_read_able!

von Achim S. (Guest)


Rate this post
useful
not useful
Rob wrote:
> Unfortunately, the restriction is to use only one process with a clock.
> I want the counter to count on both the edges.

don't mix the things. You raise two new topics and probable have not yet 
understood the problem of the code you showed in the beginning.

Having only one process with a clock is fine. Then everything, which 
must be stored in flipflops, has to be assigned inside that process.

But the process you showed in the beginning has no clock at all. Try to 
imagine, how fast ctr_r tries to count upwards (cause it has no clock 
that defines the pace of the counter).

Having a Counter which counts on both clock edges is in general not 
fine: it works only in those very special cases, where the hardware 
supports dual edge triggerd Flipflops. Most hardware does not support 
this.

But it's a different thing, if you have a fast clock and count the 
transistions (rising and falling) of a slower input signal: that can be 
done without problems by an edge detection.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
useful
not useful
Achim S. wrote:
> Try to imagine, how fast ctr_r tries to count upwards
In reality such a counter does NOT count at all. It's just a random 
noise generator.

> Having a Counter which counts on both clock edges is in general not
> fine: it works only in those very special cases, where the hardware
> supports dual edge triggerd Flipflops.
Usually FPGA nowadays support that only in IO-cells. And the 
"double-datarate" flipflops there are just a "workaround" consisting of 
two flipflops and a multiplexter.

> Most hardware does not support this.
Afaik only some Xilinx Coolrunner CPLD have such flipflops inside the 
chip.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.