From: rickman on
On Feb 17, 8:05 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
> On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> > Fight fire with fire! The two reports below show that both the
> > missing else and the missing assignment (which is also missing 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, probably
> > 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, probably
> > 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
> > port(
> > CLK : in std_logic ;
> > RESET : in std_logic ;
> > C01 : in std_logic ;
> > C02 : in std_logic ;
> > LatchOutput : out std_logic ;
> > CombOutput : out std_logic
> > );
> > end LatchSynthTest ;
>
> > architecture behavior of LatchSynthTest is
> > SIGNAL Latch : std_logic;
> > SIGNAL Comb : std_logic;
> > SIGNAL LatchReg : std_logic;
> > SIGNAL CombReg : std_logic;
>
> > begin
>
> > CombOutput <= CombReg;
> > LatchOutput <= LatchReg;
>
> > Process_1 : process(RESET, CLK)
> > begin
> > if (RESET = '1') then
> > LatchReg <= '0';
> > CombReg <= '0';
> > elsif (rising_edge(CLK)) then
> > LatchReg <= Latch;
> > CombReg <= Comb;
> > end if;
> > end process;
>
> > CombProc : process(CombReg, C01, C02)
> > begin
> > case CombReg is
> > when '0' =>
> > if (C01 = '1') then
> > Comb <= '0';
> > elsif (C02 = '1') then
> > Comb <= '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 =>
> > Comb <= '1';
> > end case;
> > end process;
>
> > LatchProc : process(LatchReg, C01, C02)
> > begin
> > case LatchReg is
> > when '0' =>
> > if C01 = '1' then
> > Latch <= '0';
> > elsif C02 = '1' then
> > Latch <= '1';
> > -- Here the else is missing, and it does
> > -- generate latch. It is treated as a null statement.
> > end if;
> > when others =>
> > Latch <= '1';
> > end case;
> > end process;
>
> > end behavior;
>
> Hi,
> Thank you, Andy, Rick and everyone, I am wrong in the second point:
> missing "else" or missing an assignment statement.
>
> But my first point is how to generate a latch for a compiler. Rick,
> 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". Are you asking about the detail
of how it is implemented in the FPGA? In the Lattice part they used a
FF as a latch. A register is between the latch and the output. They
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 you
think is the clock? I don't see why they did it the way they did, but
it works correctly according to the VHDL. With only four inputs I
would expect they could have just used a single LUT4 and the latch
with the clock always enabled.

Din == '1'
Latch Enable == CombReg + C02
Async Clear == ~CombReg * C01

Is this what you are asking?

Rick
From: Weng Tianxiang on
On Feb 17, 7:51 pm, rickman <gnu...(a)gmail.com> wrote:
> On Feb 17, 8:05 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
>
>
>
>
> > On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> > > Fight fire with fire!  The two reports below show that both the
> > > missing else and the missing assignment (which is also missing 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, probably
> > > 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, probably
> > > 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
> > >   port(
> > >           CLK                   : in    std_logic ;
> > >           RESET                 : in    std_logic ;
> > >           C01                   : in    std_logic ;
> > >           C02                   : in    std_logic ;
> > >           LatchOutput   : out   std_logic ;
> > >           CombOutput    : out   std_logic
> > >           );
> > > end LatchSynthTest ;
>
> > > architecture behavior of LatchSynthTest is
> > >   SIGNAL Latch          : std_logic;
> > >   SIGNAL Comb           : std_logic;
> > >   SIGNAL LatchReg       : std_logic;
> > >   SIGNAL CombReg        : std_logic;
>
> > > begin
>
> > >   CombOutput    <= CombReg;
> > >   LatchOutput   <= LatchReg;
>
> > >   Process_1 : process(RESET, CLK)
> > >   begin
> > >     if (RESET = '1') then
> > >       LatchReg  <= '0';
> > >       CombReg   <= '0';
> > >     elsif (rising_edge(CLK)) then
> > >       LatchReg  <= Latch;
> > >       CombReg   <= Comb;
> > >     end if;
> > >   end process;
>
> > >   CombProc : process(CombReg, C01, C02)
> > >   begin
> > >     case CombReg is
> > >       when '0' =>
> > >         if (C01 = '1') then
> > >           Comb <= '0';
> > >         elsif (C02 = '1') then
> > >           Comb <= '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 =>
> > >         Comb <= '1';
> > >     end case;
> > >   end process;
>
> > >   LatchProc : process(LatchReg, C01, C02)
> > >   begin
> > >     case LatchReg is
> > >       when '0' =>
> > >         if C01 = '1' then
> > >           Latch <= '0';
> > >         elsif C02 = '1' then
> > >           Latch <= '1';
> > >           -- Here the else is missing, and it does
> > >           -- generate latch.  It is treated as a null statement.
> > >         end if;
> > >       when others =>
> > >         Latch <= '1';
> > >     end case;
> > >   end process;
>
> > > end behavior;
>
> > Hi,
> > Thank you, Andy, Rick and everyone, I am wrong in the second point:
> > missing "else" or missing an assignment statement.
>
> > But my first point is how to generate a latch for a compiler. Rick,
> > 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".  Are you asking about the detail
> of how it is implemented in the FPGA?  In the Lattice part they used a
> FF as a latch.  A register is between the latch and the output.  They
> 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 you
> think is the clock?  I don't see why they did it the way they did, but
> it works correctly according to the VHDL.  With only four inputs I
> would expect they could have just used a single LUT4 and the latch
> with the clock always enabled.
>
> Din == '1'
> Latch Enable == CombReg + C02
> Async Clear  == ~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
From: rickman on
On Feb 18, 11:10 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
> On Feb 17, 7:51 pm, rickman <gnu...(a)gmail.com> wrote:
>
>
>
> > On Feb 17, 8:05 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> > > > Fight fire with fire!  The two reports below show that both the
> > > > missing else and the missing assignment (which is also missing 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, probably
> > > > 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, probably
> > > > 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
> > > >   port(
> > > >           CLK                   : in    std_logic ;
> > > >           RESET                 : in    std_logic ;
> > > >           C01                   : in    std_logic ;
> > > >           C02                   : in    std_logic ;
> > > >           LatchOutput   : out   std_logic ;
> > > >           CombOutput    : out   std_logic
> > > >           );
> > > > end LatchSynthTest ;
>
> > > > architecture behavior of LatchSynthTest is
> > > >   SIGNAL Latch          : std_logic;
> > > >   SIGNAL Comb           : std_logic;
> > > >   SIGNAL LatchReg       : std_logic;
> > > >   SIGNAL CombReg        : std_logic;
>
> > > > begin
>
> > > >   CombOutput    <= CombReg;
> > > >   LatchOutput   <= LatchReg;
>
> > > >   Process_1 : process(RESET, CLK)
> > > >   begin
> > > >     if (RESET = '1') then
> > > >       LatchReg  <= '0';
> > > >       CombReg   <= '0';
> > > >     elsif (rising_edge(CLK)) then
> > > >       LatchReg  <= Latch;
> > > >       CombReg   <= Comb;
> > > >     end if;
> > > >   end process;
>
> > > >   CombProc : process(CombReg, C01, C02)
> > > >   begin
> > > >     case CombReg is
> > > >       when '0' =>
> > > >         if (C01 = '1') then
> > > >           Comb <= '0';
> > > >         elsif (C02 = '1') then
> > > >           Comb <= '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 =>
> > > >         Comb <= '1';
> > > >     end case;
> > > >   end process;
>
> > > >   LatchProc : process(LatchReg, C01, C02)
> > > >   begin
> > > >     case LatchReg is
> > > >       when '0' =>
> > > >         if C01 = '1' then
> > > >           Latch <= '0';
> > > >         elsif C02 = '1' then
> > > >           Latch <= '1';
> > > >           -- Here the else is missing, and it does
> > > >           -- generate latch.  It is treated as a null statement.
> > > >         end if;
> > > >       when others =>
> > > >         Latch <= '1';
> > > >     end case;
> > > >   end process;
>
> > > > end behavior;
>
> > > Hi,
> > > Thank you, Andy, Rick and everyone, I am wrong in the second point:
> > > missing "else" or missing an assignment statement.
>
> > > But my first point is how to generate a latch for a compiler. Rick,
> > > 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".  Are you asking about the detail
> > of how it is implemented in the FPGA?  In the Lattice part they used a
> > FF as a latch.  A register is between the latch and the output.  They
> > 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 you
> > think is the clock?  I don't see why they did it the way they did, but
> > it works correctly according to the VHDL.  With only four inputs I
> > would expect they could have just used a single LUT4 and the latch
> > with the clock always enabled.
>
> > Din == '1'
> > Latch Enable == CombReg + C02
> > Async Clear  == ~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. I posted the full code a couple of
posts back. What is it that you want a screen shot of? The text I
quoted was from the Synthesis report. If you want an image of the
chip editor, the latch only shows in the logic block editor dialog
box. It is just a check box on a schematic of the functional elements
in the logic block. Is that of any value to you?

Rick
From: Weng Tianxiang on
On Feb 18, 1:13 pm, rickman <gnu...(a)gmail.com> wrote:
> On Feb 18, 11:10 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
>
>
>
>
> > On Feb 17, 7:51 pm, rickman <gnu...(a)gmail.com> wrote:
>
> > > On Feb 17, 8:05 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> > > > > Fight fire with fire!  The two reports below show that both the
> > > > > missing else and the missing assignment (which is also missing 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, probably
> > > > > 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, probably
> > > > > 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
> > > > >   port(
> > > > >           CLK                   : in    std_logic ;
> > > > >           RESET                 : in    std_logic ;
> > > > >           C01                   : in    std_logic ;
> > > > >           C02                   : in    std_logic ;
> > > > >           LatchOutput   : out   std_logic ;
> > > > >           CombOutput    : out   std_logic
> > > > >           );
> > > > > end LatchSynthTest ;
>
> > > > > architecture behavior of LatchSynthTest is
> > > > >   SIGNAL Latch          : std_logic;
> > > > >   SIGNAL Comb           : std_logic;
> > > > >   SIGNAL LatchReg       : std_logic;
> > > > >   SIGNAL CombReg        : std_logic;
>
> > > > > begin
>
> > > > >   CombOutput    <= CombReg;
> > > > >   LatchOutput   <= LatchReg;
>
> > > > >   Process_1 : process(RESET, CLK)
> > > > >   begin
> > > > >     if (RESET = '1') then
> > > > >       LatchReg  <= '0';
> > > > >       CombReg   <= '0';
> > > > >     elsif (rising_edge(CLK)) then
> > > > >       LatchReg  <= Latch;
> > > > >       CombReg   <= Comb;
> > > > >     end if;
> > > > >   end process;
>
> > > > >   CombProc : process(CombReg, C01, C02)
> > > > >   begin
> > > > >     case CombReg is
> > > > >       when '0' =>
> > > > >         if (C01 = '1') then
> > > > >           Comb <= '0';
> > > > >         elsif (C02 = '1') then
> > > > >           Comb <= '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 =>
> > > > >         Comb <= '1';
> > > > >     end case;
> > > > >   end process;
>
> > > > >   LatchProc : process(LatchReg, C01, C02)
> > > > >   begin
> > > > >     case LatchReg is
> > > > >       when '0' =>
> > > > >         if C01 = '1' then
> > > > >           Latch <= '0';
> > > > >         elsif C02 = '1' then
> > > > >           Latch <= '1';
> > > > >           -- Here the else is missing, and it does
> > > > >           -- generate latch.  It is treated as a null statement.
> > > > >         end if;
> > > > >       when others =>
> > > > >         Latch <= '1';
> > > > >     end case;
> > > > >   end process;
>
> > > > > end behavior;
>
> > > > Hi,
> > > > Thank you, Andy, Rick and everyone, I am wrong in the second point:
> > > > missing "else" or missing an assignment statement.
>
> > > > But my first point is how to generate a latch for a compiler. Rick,
> > > > 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".  Are you asking about the detail
> > > of how it is implemented in the FPGA?  In the Lattice part they used a
> > > FF as a latch.  A register is between the latch and the output.  They
> > > 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 you
> > > think is the clock?  I don't see why they did it the way they did, but
> > > it works correctly according to the VHDL.  With only four inputs I
> > > would expect they could have just used a single LUT4 and the latch
> > > with the clock always enabled.
>
> > > Din == '1'
> > > Latch Enable == CombReg + C02
> > > Async Clear  == ~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.  I posted the full code a couple of
> posts back.  What is it that you want a screen shot of?  The text I
> quoted was from the Synthesis report.  If you want an image of the
> chip editor, the latch only shows in the logic block editor dialog
> box.  It is just a check box on a schematic of the functional elements
> in the logic block.  Is 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 == '1'
Latch Enable == CombReg + C02
Async Clear == ~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



From: rickman on
On Feb 22, 9:41 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
> On Feb 18, 1:13 pm, rickman <gnu...(a)gmail.com> wrote:
>
>
>
> > On Feb 18, 11:10 am, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > On Feb 17, 7:51 pm, rickman <gnu...(a)gmail.com> wrote:
>
> > > > On Feb 17, 8:05 pm, Weng Tianxiang <wtx...(a)gmail.com> wrote:
>
> > > > > On Feb 17, 4:29 pm, rickman <gnu...(a)gmail.com> wrote:
> > > > > > Fight fire with fire! The two reports below show that both the
> > > > > > missing else and the missing assignment (which is also missing 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, probably
> > > > > > 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, probably
> > > > > > 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
> > > > > > port(
> > > > > > CLK : in std_logic ;
> > > > > > RESET : in std_logic ;
> > > > > > C01 : in std_logic ;
> > > > > > C02 : in std_logic ;
> > > > > > LatchOutput : out std_logic ;
> > > > > > CombOutput : out std_logic
> > > > > > );
> > > > > > end LatchSynthTest ;
>
> > > > > > architecture behavior of LatchSynthTest is
> > > > > > SIGNAL Latch : std_logic;
> > > > > > SIGNAL Comb : std_logic;
> > > > > > SIGNAL LatchReg : std_logic;
> > > > > > SIGNAL CombReg : std_logic;
>
> > > > > > begin
>
> > > > > > CombOutput <= CombReg;
> > > > > > LatchOutput <= LatchReg;
>
> > > > > > Process_1 : process(RESET, CLK)
> > > > > > begin
> > > > > > if (RESET = '1') then
> > > > > > LatchReg <= '0';
> > > > > > CombReg <= '0';
> > > > > > elsif (rising_edge(CLK)) then
> > > > > > LatchReg <= Latch;
> > > > > > CombReg <= Comb;
> > > > > > end if;
> > > > > > end process;
>
> > > > > > CombProc : process(CombReg, C01, C02)
> > > > > > begin
> > > > > > case CombReg is
> > > > > > when '0' =>
> > > > > > if (C01 = '1') then
> > > > > > Comb <= '0';
> > > > > > elsif (C02 = '1') then
> > > > > > Comb <= '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 =>
> > > > > > Comb <= '1';
> > > > > > end case;
> > > > > > end process;
>
> > > > > > LatchProc : process(LatchReg, C01, C02)
> > > > > > begin
> > > > > > case LatchReg is
> > > > > > when '0' =>
> > > > > > if C01 = '1' then
> > > > > > Latch <= '0';
> > > > > > elsif C02 = '1' then
> > > > > > Latch <= '1';
> > > > > > -- Here the else is missing, and it does
> > > > > > -- generate latch. It is treated as a null statement.
> > > > > > end if;
> > > > > > when others =>
> > > > > > Latch <= '1';
> > > > > > end case;
> > > > > > end process;
>
> > > > > > end behavior;
>
> > > > > Hi,
> > > > > Thank you, Andy, Rick and everyone, I am wrong in the second point:
> > > > > missing "else" or missing an assignment statement.
>
> > > > > But my first point is how to generate a latch for a compiler. Rick,
> > > > > 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". Are you asking about the detail
> > > > of how it is implemented in the FPGA? In the Lattice part they used a
> > > > FF as a latch. A register is between the latch and the output. They
> > > > 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 you
> > > > think is the clock? I don't see why they did it the way they did, but
> > > > it works correctly according to the VHDL. With only four inputs I
> > > > would expect they could have just used a single LUT4 and the latch
> > > > with the clock always enabled.
>
> > > > Din == '1'
> > > > Latch Enable == CombReg + C02
> > > > Async Clear == ~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. I posted the full code a couple of
> > posts back. What is it that you want a screen shot of? The text I
> > quoted was from the Synthesis report. If you want an image of the
> > chip editor, the latch only shows in the logic block editor dialog
> > box. It is just a check box on a schematic of the functional elements
> > in the logic block. Is 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 == '1'
> Latch Enable == CombReg + C02
> Async Clear == ~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. For 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
when '0' =>
if (C01 = '1') then
Comb <= '0';
elsif (C02 = '1') then
Comb <= '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 =>
Comb <= '1';
end case;

Notice that once the latch is set to a '1' in the VHDL, there is no
way to clear it. When CombReg is a '1', the "others" clause of the
case is executed which only allows it to be a '1'. The async clear
can only be asserted when CombReg is a '0'. Of 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". A LUT4 can
implement ***ANY*** logic function of 4 inputs. So there certainly is
a way to implement the above VHDL in a single LUT4. In fact, you
don't even need the latch.

Comb <= 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 <= CombReg or C01 or C02;
DataIn <= 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. I think
it may avoid potential race conditions when only one input switches.
My logic will have some problems, for example CombReg = 0, C02 = 0 and
C01 = 1. Bring C01 low and it will either stay clear or set the latch
depending on which of the two paths are faster. Hmmm, maybe the tools
aren't so stupid after all. In essence, they are using the enable as
a set and the async reset as a... well, a reset!

Rick