Author Topic: VHDL Case Statement  (Read 12241 times)

0 Members and 1 Guest are viewing this topic.

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
VHDL Case Statement
« on: February 27, 2021, 01:44:34 pm »
I am trying to implement a 74150, 16 to 1 multiplexer, using a case statement and while I do not get any errors, it is not working.
1183000-0
Code: [Select]
architecture Behavioral of U_74150 is

begin
process (E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13,E14,E15,SEL)
begin
case SEL is
when "0000" => W <= NOT E0;
when "0001" => W <= NOT E1;
when "0010" => W <= NOT E2;
when "0011" => W <= NOT E3;
when "0100" => W <= NOT E4;
when "0101" => W <= NOT E5;
when "0110" => W <= NOT E6;
when "0111" => W <= NOT E7;
when "1000" => W <= NOT E8;
when "1001" => W <= NOT E9;
when "1010" => W <= NOT E10;
when "1011" => W <= NOT E11;
when "1100" => W <= NOT E12;
when "1101" => W <= NOT E13;
when "1110" => W <= NOT E14;
when "1111" => W <= NOT E15;
when others => W <= NOT '0';
end case;
end process;

end Behavioral;

If I send the input straight through and do not invert it, everything works fine.
1183004-1
I does work using a select statement, but why does it not using the case statement?
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4277
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: VHDL Case Statement
« Reply #1 on: February 27, 2021, 02:15:28 pm »
In what specific way is it "not working"?

What tools are you using? Are you simulating the code, or synthesizing it and loading it onto a real device?

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: VHDL Case Statement
« Reply #2 on: February 27, 2021, 04:44:04 pm »
show us your simulation results, please.

Synthesis output is not interesting.
 

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
Re: VHDL Case Statement
« Reply #3 on: February 27, 2021, 04:49:21 pm »
I am just doing simulations for now, do not have anything to load it onto. I only started learning VHDL this week and this is my first design other than an and gate, an or gate, and an inverter. I just reran it and it worked this time. Before I was getting undefined results, even on the select bus. The RTL schematic is still wrong though. I am not sure how much of a difference that makes?

I am using ISE because this is just a component in a project using a CPLD.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: VHDL Case Statement
« Reply #4 on: February 27, 2021, 06:14:17 pm »
What about the surrounding code?  Signal declarations, that sort of thing.

In synthesis, which probably generated those block diagrams, unused logic is eliminated.  For example, if SEL doesn't show up in the top level PORT list (assuming you are using the component directly from the top level), the logic will be eliminated.  Why it works for one incantation and not another may be one of life's mysteries.

The inputs, and particularly the output, need to show up in the PORT list as well.  You have to PROVE to the synthesizer that the logic levels can change internally and this change results from something ultimately happening to signals on the PORT list.

Bottom line:  Post the entire code.

This is just a thought, I haven't tried it but I have seen examples where logic is removed during synthesis.
« Last Edit: February 27, 2021, 06:20:05 pm by rstofer »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15215
  • Country: fr
Re: VHDL Case Statement
« Reply #5 on: February 27, 2021, 06:58:29 pm »
Yes, I can't see a problem with the piece of code the OP posted. But if they are looking at synthesis result, then the most likely cause here is pruned logic as rstofer suggested.

Route all input and output signals to external pins of your FPGA to make sure it can't make any assumption about any signal.

Note: this would be a good opportunity to start making a habit of looking at the synthesis reports. Yes they are usually pretty annoying to read and telling the important info from the minor warnings is hard (especially when you're not familiar yet), but if any logic is eliminated, if any signal is assumed at a fixed level (the report will usually express this as "<xxx signal> is stuck at Zero/One"), then you'll see that there.
« Last Edit: February 27, 2021, 07:44:02 pm by SiliconWizard »
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #6 on: February 27, 2021, 07:56:34 pm »
Yes, I can't see a problem with the piece of code the OP posted. But if they are looking at synthesis result, then the most likely cause here is pruned logic as rstofer suggested.

Route all input and output signals to external pins of your FPGA to make sure it can't make any assumption about any signal.

Note: this would be a good opportunity to start making a habit of looking at the synthesis reports. Yes they are usually pretty annoying to read and telling the important info from the minor warnings is hard (especially when you're not familiar yet), but if any logic is eliminated, if any signal is assumed at a fixed level (the report will usually express this as "<xxx signal> is stuck at Zero/One"), then you'll see that there.

Synthesis reports are such a piece of crap!  I'm not saying they aren't important, but they generate so much dross that it is at best time consuming to go through them and at worse impractical.  I recall working on a design where every counter that didn't use the carry out would generate a pruned logic warning.  So I had to note them and check off each warning against the list of acceptable warnings.  Of course any new warnings would have to be investigated to see if it was "intentional" or not. 

Fortunately in that case the identifier was consistent, so there was a way to relate the pruned logic to the source code.  I've seen times when every iteration the names changed!  This is one of the reasons to use labels on everything hierarchical. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: VHDL Case Statement
« Reply #7 on: February 27, 2021, 08:53:43 pm »
I've seen times when every iteration the names changed!  This is one of the reasons to use labels on everything hierarchical.
This is a really good idea.  I'll incorporate it the next time I write some VHDL.
 

Offline pgo

  • Regular Contributor
  • *
  • Posts: 81
  • Country: au
Re: VHDL Case Statement
« Reply #8 on: February 27, 2021, 09:03:41 pm »
Hi,

The ISE schematics are often misleading with missing components or connections so they cannot be used to confirm a result although useful in simple designs to indicate results.
It is surprisingly easy to simulate a stale design that has not been re-synthesised.  I suspect this accounts for some of your inconsistent results i.e. it works now but not before.  Make sure the design files have been saved!
You do not need to worry about pruning due to unused inputs if you are synthesising this component in isolation unless the design is actually has redundant internal circuitry.
You need to provide the test-bench and simulation results to allow judgement on the simulation.

bye
 

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
Re: VHDL Case Statement
« Reply #9 on: February 28, 2021, 12:15:18 am »
The only changes I remember making were to remove the "NOT"s and then put them back in, but it did not work when I first put them back in.
Component
Code: [Select]
entity U_74150 is
    Port ( E0 : in  STD_LOGIC;
           E1 : in  STD_LOGIC;
           E2 : in  STD_LOGIC;
           E3 : in  STD_LOGIC;
           E4 : in  STD_LOGIC;
           E5 : in  STD_LOGIC;
           E6 : in  STD_LOGIC;
           E7 : in  STD_LOGIC;
           E8 : in  STD_LOGIC;
           E9 : in  STD_LOGIC;
           E10 : in  STD_LOGIC;
           E11 : in  STD_LOGIC;
           E12 : in  STD_LOGIC;
           E13 : in  STD_LOGIC;
           E14 : in  STD_LOGIC;
           E15 : in  STD_LOGIC;
  SEL : in STD_LOGIC_VECTOR(4-1 downto 0);
           W : out  STD_LOGIC);
end U_74150;

architecture Behavioral of U_74150 is

begin
process (E0,E1,E2,E3,E4,E5,E6,E7,E8,E9,E10,E11,E12,E13,E14,E15,SEL)
begin
case SEL is
when "0000" => W <= NOT E0;
when "0001" => W <= NOT E1;
when "0010" => W <= NOT E2;
when "0011" => W <= NOT E3;
when "0100" => W <= NOT E4;
when "0101" => W <= NOT E5;
when "0110" => W <= NOT E6;
when "0111" => W <= NOT E7;
when "1000" => W <= NOT E8;
when "1001" => W <= NOT E9;
when "1010" => W <= NOT E10;
when "1011" => W <= NOT E11;
when "1100" => W <= NOT E12;
when "1101" => W <= NOT E13;
when "1110" => W <= NOT E14;
when "1111" => W <= NOT E15;
when others => W <= NOT '0';
end case;
end process;

end Behavioral;

and test bench
Code: [Select]
ENTITY U_74150_tb IS
END U_74150_tb;
 
ARCHITECTURE behavior OF U_74150_tb IS
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT U_74150
    PORT(
         E0 : IN  std_logic;
         E1 : IN  std_logic;
         E2 : IN  std_logic;
         E3 : IN  std_logic;
         E4 : IN  std_logic;
         E5 : IN  std_logic;
         E6 : IN  std_logic;
         E7 : IN  std_logic;
         E8 : IN  std_logic;
         E9 : IN  std_logic;
         E10 : IN  std_logic;
         E11 : IN  std_logic;
         E12 : IN  std_logic;
         E13 : IN  std_logic;
         E14 : IN  std_logic;
         E15 : IN  std_logic;
         SEL : IN  std_logic_vector(3 downto 0);
         W : OUT  std_logic
        );
    END COMPONENT;
   

   --Inputs
   signal E0 : std_logic := '0';
   signal E1 : std_logic := '0';
   signal E2 : std_logic := '0';
   signal E3 : std_logic := '0';
   signal E4 : std_logic := '0';
   signal E5 : std_logic := '0';
   signal E6 : std_logic := '0';
   signal E7 : std_logic := '0';
   signal E8 : std_logic := '0';
   signal E9 : std_logic := '0';
   signal E10 : std_logic := '0';
   signal E11 : std_logic := '0';
   signal E12 : std_logic := '0';
   signal E13 : std_logic := '0';
   signal E14 : std_logic := '0';
   signal E15 : std_logic := '0';
   signal SEL : std_logic_vector(3 downto 0) := (others => '0');

  --Outputs
   signal W : std_logic;
 
BEGIN
 
-- Instantiate the Unit Under Test (UUT)
   uut: U_74150 PORT MAP (
          E0 => E0,
          E1 => E1,
          E2 => E2,
          E3 => E3,
          E4 => E4,
          E5 => E5,
          E6 => E6,
          E7 => E7,
          E8 => E8,
          E9 => E9,
          E10 => E10,
          E11 => E11,
          E12 => E12,
          E13 => E13,
          E14 => E14,
          E15 => E15,
          SEL => SEL,
          W => W
        );


   -- Stimulus process
   stim_proc: process
   begin
      -- hold reset state for 100 ns.
      wait for 100 ns;

      -- insert stimulus here
E0 <= '1';
E1 <= '1';
E2 <= '1';
E3 <= '1';
E4 <= '1';
E5 <= '0';
E6 <= '1';
E7 <= '1';
E8 <= '1';
E9 <= '1';
E10 <= '1';
E11 <= '0';
E12 <= '0';
E13 <= '0';
E14 <= '0';
E15 <= '0';
SEL <= "0000";
wait for 10 ns;
SEL <= "0001";
wait for 10 ns;
SEL <= "0010";
wait for 10 ns;
SEL <= "0011";
wait for 10 ns;
SEL <= "0100";
wait for 10 ns;
SEL <= "0101";
wait for 10 ns;
SEL <= "0110";
wait for 10 ns;
SEL <= "0111";
wait for 10 ns;
SEL <= "1000";
wait for 10 ns;
SEL <= "1001";
wait for 10 ns;
SEL <= "1010";
wait for 10 ns;
SEL <= "1011";
wait for 10 ns;
SEL <= "1100";
wait for 10 ns;
SEL <= "1101";
wait for 10 ns;
SEL <= "1110";
wait for 10 ns;
SEL <= "1111";
wait for 10 ns;
SEL <= "0000";

      wait;
   end process;

END;
The test bench never changed. It is not hierarchical at this point because I wanted to get the first component working before I moved on. 

@SiliconWizard what synthesis reports are you referring to? In the console it says it is disregarding this line
            
Code: [Select]
when "1111" => W <= NOT E15;as unnecessary, which makes sense to an extent since there are no more cases and I have to include a with others case.

 
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #10 on: February 28, 2021, 02:35:25 am »
The only changes I remember making were to remove the "NOT"s and then put them back in, but it did not work when I first put them back in.
Component
...
and test bench
...
The test bench never changed. It is not hierarchical at this point because I wanted to get the first component working before I moved on. 

@SiliconWizard what synthesis reports are you referring to? In the console it says it is disregarding this line
            
Code: [Select]
when "1111" => W <= NOT E15;as unnecessary, which makes sense to an extent since there are no more cases and I have to include a with others case.

This is not correct.  There is nothing about that line which is unnecessary.  The others case covers cases in simulation, but since all logical combinations of zeros and ones have been covered the others case is not needed in synthesis, so maybe it is referring to the others line.  I suggest you track down what is mean by the warning.  At least I assume it is a warning.  If you didn't assign it a value of NOT E15, what value would it have?  NOT '0'? 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #11 on: February 28, 2021, 02:37:55 am »
I've seen times when every iteration the names changed!  This is one of the reasons to use labels on everything hierarchical.
This is a really good idea.  I'll incorporate it the next time I write some VHDL.

Just to be clear I was referring to "hierarchy" as including all the structure inside a design entity.  Every process has a name as well as pretty much anything that can be named.  Beats having to go back into the code to find the line that you need to stick a name onto.  It's kinda like in schematics where the default name is node1, node2, etc.  I don't know how people can use a simulation without net names.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
Re: VHDL Case Statement
« Reply #12 on: February 28, 2021, 03:08:07 am »
This is not correct.  There is nothing about that line which is unnecessary.  The others case covers cases in simulation, but since all logical combinations of zeros and ones have been covered the others case is not needed in synthesis, so maybe it is referring to the others line.  I suggest you track down what is mean by the warning.  At least I assume it is a warning.  If you didn't assign it a value of NOT E15, what value would it have?  NOT '0'?

It was not a warning or error, just an info.
Quote
INFO:Xst:1561 - ... line 74: Mux is complete : default of case is discarded
Entity <U_74150> analyzed. Unit <U_74150> generated.
Maybe I read it wrong and it was line 75 that was discarded? That was the one with with others.
 

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
Re: VHDL Case Statement
« Reply #13 on: February 28, 2021, 03:17:06 am »
I am going to chalk this up to what ever the problem was, it is gone now, and move on. I would like to thank you all for your input and not trying to redesign my project.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #14 on: February 28, 2021, 04:33:29 am »
Oh yeah, I almost forgot  ;) 

I would not insert all that code to generate an incrementing count.  I would infer a counter and have a simple case for decoding. 

Someone on my project actually codes like that.  He explicitly wrote out the logic for a many bit counter that loops around at some counts I know nothing about because he wrote out the ands and ors for each bit!!!  His test bench, which is emulating an I2C device, is done as waveforms rather than constructing a simple I2C device to return results.  Now he expects me to debug his code.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline pgo

  • Regular Contributor
  • *
  • Posts: 81
  • Country: au
Re: VHDL Case Statement
« Reply #15 on: February 28, 2021, 07:57:09 am »
Hi GnuARM,

A comment on your comment on synthesising a counter for a testbench,
I would not think this a good choice for a testbench - just use a for loop.
There is no need for it to be synthesiable.

For loops with arrays of test vectors, is another easy approach for testing simple components.
I agree that a higher-level testbench is good for complex designs - the extra smarts pays off in the long run.

bye

e.g.
 
The following users thanked this post: Bassman59

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #16 on: February 28, 2021, 08:07:38 am »
Yes, I didn't mean to imply the test bench needed to be synthesizable.  By all means use a for loop.  Or whatever you are comfortable working with. 

Oh, and add lots of comments explaining what is going on.  It's hard enough returning to your own code a month or few later.  Trying to read someone else's code is much harder without clear comments.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9931
  • Country: us
Re: VHDL Case Statement
« Reply #17 on: February 28, 2021, 02:39:54 pm »
It was not a warning or error, just an info.
Quote
INFO:Xst:1561 - ... line 74: Mux is complete : default of case is discarded
Entity <U_74150> analyzed. Unit <U_74150> generated.
Maybe I read it wrong and it was line 75 that was discarded? That was the one with with others.

That is normal whenever you have fully covered the input signal range and then add a 'default' condition.  To be pedantic about it, I always add the default case and expect to see the INFO.

This becomes a little less obvious when you are creating finite state machines with MANY states and allowing the compiler to select one-hot encoding.  For 100 states, the state word is 100 bits wide but, by definition, only 1 bit is set per state index.  It sometimes happens that in the state type declaration, a state is named which hasn't yet been written.  The default case will trap those, don't overlook or remove the default case.

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15215
  • Country: fr
Re: VHDL Case Statement
« Reply #18 on: February 28, 2021, 04:02:16 pm »
Maybe I read it wrong and it was line 75 that was discarded? That was the one with with others.

Yes, it refers to the "when others" case.

Note that this case is actually ONLY discarded by synthesis. Simulation would not discard it, and in simulation, this case would actually be potentially covered. Why? std_logic can have other states than '1' and '0'! Such as 'Z' (high impedance), 'U' (uninitialiazed), and a few others. In simulation, that would matter, as your inputs could be in one of those other states, and thus your "case" would be incomplete without the "when others".

In synthesis, for *read* signals of std_logic type, only the states '1' and '0' can be handled for obvious reasons. The inputs of logic cells can't determine if a signal is in any other state than this. So for synthesis, your "case" would be complete without the "when others". Keeping it anyway for simulation needs is a good idea. You may want to choose something else than "not '0'" as the default state for the output though, so it's easier to spot in simulation. Again, in synthesis, this won't matter.
« Last Edit: February 28, 2021, 04:04:18 pm by SiliconWizard »
 
The following users thanked this post: Bassman59

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15215
  • Country: fr
Re: VHDL Case Statement
« Reply #19 on: February 28, 2021, 04:12:21 pm »
As a side note, there is a much less clunky way of implementing the same.

Declare your "En" ports as a single "E : in std_logc_vector(15 downto 0)".
Then the body of your entity could be a one-liner:
Code: [Select]
W <= not E(to_integer(unsigned(SEL)));

You'll just need to add "use IEEE.numeric_std.all;" along with other IEEE libraries you're using.

I'm pretty sure this would synthesize exactly the same as your long "case" approach, but it'll be interesting to compare both and report back. AFAIK, MUXes in FPGAs are usually optimized for those indexed selections and the tools try to map your MUXes to that anyway.

 

Offline admiralkTopic starter

  • Regular Contributor
  • *
  • Posts: 178
  • Country: us
Re: VHDL Case Statement
« Reply #20 on: February 28, 2021, 09:40:32 pm »
Thanks again for the suggestions. As I said, I have only been learning VHDL for a week and have a lot to learn. My only other experience with a HDL was the nand2tetris site.
 

Offline Evan.Cornell

  • Regular Contributor
  • *
  • Posts: 188
  • Country: us
Re: VHDL Case Statement
« Reply #21 on: March 01, 2021, 01:30:51 pm »
Thanks again for the suggestions. As I said, I have only been learning VHDL for a week and have a lot to learn. My only other experience with a HDL was the nand2tetris site.

I would highly recommend https://vhdlwhiz.com/ for learning. I have paid for the Dot Matrix VHDL and FPGA Course as well as the new continuing membership. The explanations are quite thorough and easy to understand. Worth the money if you're just getting into VHDL.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #22 on: March 01, 2021, 04:09:52 pm »
Thanks again for the suggestions. As I said, I have only been learning VHDL for a week and have a lot to learn. My only other experience with a HDL was the nand2tetris site.

When you find educational sources, make sure they include coverage of VHDL-2008.  That was a significant improvement in the language with many usability features that make life with VHDL much better.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 15215
  • Country: fr
Re: VHDL Case Statement
« Reply #23 on: March 01, 2021, 04:32:40 pm »
Thanks again for the suggestions. As I said, I have only been learning VHDL for a week and have a lot to learn. My only other experience with a HDL was the nand2tetris site.

When you find educational sources, make sure they include coverage of VHDL-2008.  That was a significant improvement in the language with many usability features that make life with VHDL much better.

That's true. But I'm often surprised how far behind many courses and tutorials are. Heck, there are still many out there that don't even cover VHDL-93 properly and still stick to the original VHDL-87!
 
The following users thanked this post: Bassman59

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2247
  • Country: pr
Re: VHDL Case Statement
« Reply #24 on: March 01, 2021, 06:36:51 pm »
Thanks again for the suggestions. As I said, I have only been learning VHDL for a week and have a lot to learn. My only other experience with a HDL was the nand2tetris site.

When you find educational sources, make sure they include coverage of VHDL-2008.  That was a significant improvement in the language with many usability features that make life with VHDL much better.

That's true. But I'm often surprised how far behind many courses and tutorials are. Heck, there are still many out there that don't even cover VHDL-93 properly and still stick to the original VHDL-87!

And those are the ones that show up high in the Google list!  There is a university in Germany I think, that had a bunch of good web pages on VHDL perhaps two decades ago.  So clearly not covering 2008.  The pages are gone, but Google continues to show them in a search and will gladly present the ancient page for your enjoyment.  It is actually a good site, well organized and no errors that I can recall, just missing the last two or three updates to the language.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf