FPGARelated.com
Forums

How a state machine is constructed using latches?

Started by Weng Tianxiang February 17, 2010
On Feb 24, 5:33=A0pm, rickman <gnu...@gmail.com> wrote:
> On Feb 22, 9:41 pm, Weng Tianxiang <wtx...@gmail.com> wrote: > > > > > > > On Feb 18, 1:13 pm, rickman <gnu...@gmail.com> wrote: > > > > On Feb 18, 11:10 am, Weng Tianxiang <wtx...@gmail.com> wrote: > > > > > On Feb 17, 7:51 pm, rickman <gnu...@gmail.com> wrote: > > > > > > On Feb 17, 8:05 pm, Weng Tianxiang <wtx...@gmail.com> wrote: > > > > > > > On Feb 17, 4:29 pm, rickman <gnu...@gmail.com> wrote: > > > > > > > Fight fire with fire! =A0The two reports below show that both=
the
> > > > > > > missing else and the missing assignment (which is also missin=
g in the
> > > > > > > missing else case) produce latches. > > > > > > > > @W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.=
vhd":
> > > > > > > 57:4:57:7|Latch generated from process for signal Latch, prob=
ably
> > > > > > > caused by a missing assignment in an if or case stmt > > > > > > > @W: CL117 :"C:\arius\boards\tdc_upgrade\tests\latchsynthtest.=
vhd":
> > > > > > > 40:4:40:7|Latch generated from process for signal Comb, proba=
bly
> > > > > > > caused by a missing assignment in an if or case stmt > > > > > > > > library ieee; > > > > > > > use ieee.std_logic_1164.all; > > > > > > > use ieee.numeric_std.all; > > > > > > > > entity LatchSynthTest is > > > > > > > =A0 port( > > > > > > > =A0 =A0 =A0 =A0 =A0 CLK =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :=
in =A0 =A0std_logic ;
> > > > > > > =A0 =A0 =A0 =A0 =A0 RESET =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 : i=
n =A0 =A0std_logic ;
> > > > > > > =A0 =A0 =A0 =A0 =A0 C01 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :=
in =A0 =A0std_logic ;
> > > > > > > =A0 =A0 =A0 =A0 =A0 C02 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 :=
in =A0 =A0std_logic ;
> > > > > > > =A0 =A0 =A0 =A0 =A0 LatchOutput =A0 : out =A0 std_logic ; > > > > > > > =A0 =A0 =A0 =A0 =A0 CombOutput =A0 =A0: out =A0 std_logic > > > > > > > =A0 =A0 =A0 =A0 =A0 ); > > > > > > > end LatchSynthTest ; > > > > > > > > architecture behavior of LatchSynthTest is > > > > > > > =A0 SIGNAL Latch =A0 =A0 =A0 =A0 =A0: std_logic; > > > > > > > =A0 SIGNAL Comb =A0 =A0 =A0 =A0 =A0 : std_logic; > > > > > > > =A0 SIGNAL LatchReg =A0 =A0 =A0 : std_logic; > > > > > > > =A0 SIGNAL CombReg =A0 =A0 =A0 =A0: std_logic; > > > > > > > > begin > > > > > > > > =A0 CombOutput =A0 =A0<=3D CombReg; > > > > > > > =A0 LatchOutput =A0 <=3D LatchReg; > > > > > > > > =A0 Process_1 : process(RESET, CLK) > > > > > > > =A0 begin > > > > > > > =A0 =A0 if (RESET =3D '1') then > > > > > > > =A0 =A0 =A0 LatchReg =A0<=3D '0'; > > > > > > > =A0 =A0 =A0 CombReg =A0 <=3D '0'; > > > > > > > =A0 =A0 elsif (rising_edge(CLK)) then > > > > > > > =A0 =A0 =A0 LatchReg =A0<=3D Latch; > > > > > > > =A0 =A0 =A0 CombReg =A0 <=3D Comb; > > > > > > > =A0 =A0 end if; > > > > > > > =A0 end process; > > > > > > > > =A0 CombProc : process(CombReg, C01, C02) > > > > > > > =A0 begin > > > > > > > =A0 =A0 case CombReg is > > > > > > > =A0 =A0 =A0 when '0' =3D> > > > > > > > =A0 =A0 =A0 =A0 if (C01 =3D '1') then > > > > > > > =A0 =A0 =A0 =A0 =A0 Comb <=3D '0'; > > > > > > > =A0 =A0 =A0 =A0 elsif (C02 =3D '1') then > > > > > > > =A0 =A0 =A0 =A0 =A0 Comb <=3D '1'; > > > > > > > =A0 =A0 =A0 =A0 else > > > > > > > =A0 =A0 =A0 =A0 =A0 -- Here an assignment statement is missin=
g, but it doesn't
> > > > > > > =A0 =A0 =A0 =A0 =A0 -- generate latch. =A0It is treated as a =
null statement. -
> > > > > > > Weng > > > > > > > =A0 =A0 =A0 =A0 end if; > > > > > > > =A0 =A0 =A0 when others =3D> > > > > > > > =A0 =A0 =A0 =A0 Comb <=3D '1'; > > > > > > > =A0 =A0 end case; > > > > > > > =A0 end process; > > > > > > > > =A0 LatchProc : process(LatchReg, C01, C02) > > > > > > > =A0 begin > > > > > > > =A0 =A0 case LatchReg is > > > > > > > =A0 =A0 =A0 when '0' =3D> > > > > > > > =A0 =A0 =A0 =A0 if C01 =3D '1' then > > > > > > > =A0 =A0 =A0 =A0 =A0 Latch <=3D '0'; > > > > > > > =A0 =A0 =A0 =A0 elsif C02 =3D '1' then > > > > > > > =A0 =A0 =A0 =A0 =A0 Latch <=3D '1'; > > > > > > > =A0 =A0 =A0 =A0 =A0 -- Here the else is missing, and it does > > > > > > > =A0 =A0 =A0 =A0 =A0 -- generate latch. =A0It is treated as a =
null statement.
> > > > > > > =A0 =A0 =A0 =A0 end if; > > > > > > > =A0 =A0 =A0 when others =3D> > > > > > > > =A0 =A0 =A0 =A0 Latch <=3D '1'; > > > > > > > =A0 =A0 end case; > > > > > > > =A0 end process; > > > > > > > > end behavior; > > > > > > > Hi, > > > > > > Thank you, Andy, Rick and everyone, I am wrong in the second po=
int:
> > > > > > missing "else" or missing an assignment statement. > > > > > > > But my first point is how to generate a latch for a compiler. R=
ick,
> > > > > > can you see the floor plan to show how the latch is generated: =
for the
> > > > > > state only or for full states? > > > > > > > Weng > > > > > > I'm not clear what you mean by "how". =A0Are you asking about the=
detail
> > > > > of how it is implemented in the FPGA? =A0In the Lattice part they=
used a
> > > > > FF as a latch. =A0A register is between the latch and the output.=
=A0They
> > > > > drive the latch oddly driving both the clock and the async reset > > > > > inputs with logic, but then if you look at the code what would yo=
u
> > > > > think is the clock? =A0I don't see why they did it the way they d=
id, but
> > > > > it works correctly according to the VHDL. =A0With only four input=
s I
> > > > > would expect they could have just used a single LUT4 and the latc=
h
> > > > > with the clock always enabled. > > > > > > Din =3D=3D '1' > > > > > Latch Enable =3D=3D CombReg + C02 > > > > > Async Clear =A0=3D=3D ~CombReg * C01 > > > > > > Is this what you are asking? > > > > > > Rick > > > > > Rick, > > > > Yes, that is what I want. > > > > > Could you please send the code and a window screen frame using > > > > Window's Paint so that I can see the full picture. > > > > > Thank you. > > > > > Weng > > > > I'm not clear on what you want. =A0I posted the full code a couple of > > > posts back. =A0What is it that you want a screen shot of? =A0The text=
I
> > > quoted was from the Synthesis report. =A0If you want an image of the > > > chip editor, the latch only shows in the logic block editor dialog > > > box. =A0It is just a check box on a schematic of the functional eleme=
nts
> > > in the logic block. =A0Is that of any value to you? > > > > Rick > > > Rick, > > Thank you for your help. > > > This time I really understand what the Lattice does with your source > > code in the previous poster. > > > Lattice generates a latch for the process of CombProc, paying no > > attention to what is used. > > > And I think Lattice compiler does a very good job by generating the > > following equations: > > > Din =3D=3D '1' > > Latch Enable =3D=3D CombReg + C02 > > Async Clear =A0=3D=3D ~CombReg * C01 > > > "With only four inputs I > > would expect they could have just used a single LUT4 and the latch > > with the clock always enabled. " > > > No. What you suggest may not work. Or it may work, but is not as > > simple as the Lattice equations show. > > > I would like to see how you would write a LUT4 equation for a latch. > > > Weng > > Actually, I'm not certain the code you show (that I got from the > Lattice Logic Block Editor) is exactly the same as my VHDL > description. =A0For them to match, the latch enable would have to have > priority over the reset and that is not a very normal feature in a > latch. > > case CombReg is > =A0 when '0' =3D> > =A0 =A0 if (C01 =3D '1') then > =A0 =A0 =A0 Comb <=3D '0'; > =A0 =A0 elsif (C02 =3D '1') then > =A0 =A0 =A0 Comb <=3D '1'; > =A0 =A0 else > =A0 =A0 =A0 -- Here an assignment statement is missing, but it doesn't > =A0 =A0 =A0 -- generate latch. =A0It is treated as a null statement. -Wen=
g
> =A0 =A0 end if; > =A0 when others =3D> > =A0 =A0 Comb <=3D '1'; > end case; > > Notice that once the latch is set to a '1' in the VHDL, there is no > way to clear it. =A0When CombReg is a '1', the "others" clause of the > case is executed which only allows it to be a '1'. =A0The async clear > can only be asserted when CombReg is a '0'. =A0Of course, Comb and > CombReg are not the same signals, so there is a window between the > latch being set and the Register output going high where the latch can > be reset by C01. > > There are only four inputs to this logic function "Comb". =A0A LUT4 can > implement ***ANY*** logic function of 4 inputs. =A0So there certainly is > a way to implement the above VHDL in a single LUT4. =A0In fact, you > don't even need the latch. > > Comb <=3D CombReg or (C02 and not C01) or (Comb and not C01); > > If you want to use the built in Latch in the FPGA, then I guess you > have to use a LUT4 to generate the enable and another to generate the > data (or async clear). > > Enable <=3D CombReg or C01 or C02; > DataIn <=3D CombReg or not C01; > > There is no savings by only using 2 of the 4 inputs on a LUT4 but > there is some advantage to using the reset input to a Latch. =A0I think > it may avoid potential race conditions when only one input switches. > My logic will have some problems, for example CombReg =3D 0, C02 =3D 0 an=
d
> C01 =3D 1. =A0Bring C01 low and it will either stay clear or set the latc=
h
> depending on which of the two paths are faster. =A0Hmmm, maybe the tools > aren't so stupid after all. =A0In essence, they are using the enable as > a set and the async reset as a... well, a reset! > > Rick
Rick Actually it is not the fault of Lattice, but of your VHDL code. In your example, case CombReg is when '0' =3D> if (C01 =3D '1') then Comb <=3D '0'; elsif (C02 =3D '1') then Comb <=3D '1'; else -- Here an assignment statement is missing, but it doesn't -- generate latch. It is treated as a null statement. -Weng end if; when others =3D> Comb <=3D '1'; <-- lock here by VHDL, not by Lattice compiler end case; Process_1 : process(RESET, CLK) begin if (RESET =3D '1') then LatchReg <=3D '0'; CombReg <=3D '0'; elsif (rising_edge(CLK)) then LatchReg <=3D Latch; CombReg <=3D Comb; <-- lock here by VHDL, not by Lattice compiler end if; end process; Weng
On Feb 24, 9:49=A0pm, Weng Tianxiang <wtx...@gmail.com> wrote:
> =A0 =A0 =A0 CombReg =A0 <=3D Comb; <-- lock here by VHDL, not by Lattice > > Weng
Who said anything about it be the fault of the tools? I said that it appeared there was a difference, but then I realized that the async reset must have priority over the latch enable because it can still be reset once set up to the point that the value of Comb is captured by CombReg. Then there is no longer a way to reset the latch. This is the sort of stuff that makes working with latches difficult. If the combinatorial logic had been described in the sequential process, there would have been no possibility of generating a latch. Rick
On Feb 25, 5:49=A0am, rickman <gnu...@gmail.com> wrote:
> If the combinatorial logic had been described in the sequential > process, there would have been no possibility of generating a latch.
Amen! Andy
On Feb 25, 11:34=A0am, Andy <jonesa...@comcast.net> wrote:
> On Feb 25, 5:49=A0am, rickman <gnu...@gmail.com> wrote: > > > If the combinatorial logic had been described in the sequential > > process, there would have been no possibility of generating a latch. > > Amen! > > Andy
Rick, Try this one and there is no lock problem any more in VHDL. See what happens. CombProc : process(CombReg, C01, C02) begin case CombReg is when '1' =3D> <-- only change, and not locked again if (C01 =3D '1') then Comb <=3D '0'; elsif (C02 =3D '1') then Comb <=3D '1'; else null; end if; when others =3D> Comb <=3D '1'; end case; end process; Thank you. Weng