A simple 3:8 decoder

Status
Not open for further replies.

embeddedlover

Full Member level 5
Joined
Aug 10, 2007
Messages
277
Helped
46
Reputation
92
Reaction score
38
Trophy points
1,308
Visit site
Activity points
3,155
Beginner to VHDL here....

I have written a simple 3:8 decoder using VHDL.

The following is the code...

entity dec3to8 is
Port ( A1 : in STD_LOGIC;
A2 : in STD_LOGIC;
A3 : in STD_LOGIC;
O1 : out STD_LOGIC;
O2 : out STD_LOGIC;
O3 : out STD_LOGIC;
O4 : out STD_LOGIC;
O5 : out STD_LOGIC;
O6 : out STD_LOGIC;
O7 : out STD_LOGIC;
O8 : out STD_LOGIC;
CTRL1 : in STD_LOGIC;
CTRL2 : in STD_LOGIC;
EN : in STD_LOGIC);
end dec3to8;

architecture Behavioral of dec3to8 is

begin

process(A1,A2,A3,CTRL1,CTRL2,EN)
begin

if ((CTRL1 = '1') or (CTRL2 = '1') or (EN = '0'))then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '0';

else
if((A1 = '0') and (A2 = '0') and (A3 = '0')) then
O1 <= '1';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '1') and (A2 = '0') and (A3 = '0')) then
O1 <= '0';O2 <= '1';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '0') and (A2 = '1') and (A3 = '0')) then
O1 <= '0';O2 <= '0';
O3 <= '1';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '1') and (A2 = '1') and (A3 = '0')) then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '1';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '0') and (A2 = '0') and (A3 = '1')) then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '1';O6 <= '0';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '1') and (A2 = '0') and (A3 = '1')) then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '1';
O7 <= '0';O8 <= '0';
end if;
if((A1 = '0') and (A2 = '1') and (A3 = '1')) then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '1';O8 <= '0';
end if;
if((A1 = '1') and (A2 = '1') and (A3 = '1')) then
O1 <= '0';O2 <= '0';
O3 <= '0';O4 <= '0';
O5 <= '0';O6 <= '0';
O7 <= '0';O8 <= '1';
end if;
end if;

end process;


end Behavioral;


The problem i face when i run isim is that OUTPUT doesn't toggle even though i force INPUTS to some value. Please, help me where i am going wrong.

Attached is the isim output
 

Attachments

  • isim_output.JPG
    98.9 KB · Views: 206

The problem is because A2 and A3 are 'U', so in simulation it wont take any if statement.
You need to assign values to A2 and A3.
 
Your logic is all wrong; you can't use a whole bunch of IF statements like you did, you need to use a single IF-THEN-ELSE. But rather than doing that, I'd use a CASE statement.
 
Actually you can do that fine. It will just create a load of latches because this code doesnt really describe a single mux. If you want to avoid the latches, then yes, you should use if/elsif/else or a case statement.
 
@trickydicky

Thanks, didnit click to mind.. Done!!!!!!!!!!

@barry

This was the input i was looking for.. I want more and more faults to be input to make it more efficient..
Basically transitioning some of my C skills... So, whole logic may go wierd..
I want more and more inputs so that i can make the logic with least gates used..

Even i too was using IF-THEN-ELSE, can you throw little hint and help me in making logic better!!
 

Actually you can do that fine. It will just create a load of latches because this code doesnt really describe a single mux. If you want to avoid the latches, then yes, you should use if/elsif/else or a case statement.
No latches will be created, a mux is described. All of the 8 possible synthesizable cases of A1, A2, A3 are covered in the large else branch. All synthesizable cases of CTRL1, CTRL2 and EN are covered in the outermost 'if' statement.

Kevin Jennings
 

    V

    Points: 2
    Helpful Answer Positive Rating
Actually you can do that fine. It will just create a load of latches because this code doesnt really describe a single mux. If you want to avoid the latches, then yes, you should use if/elsif/else or a case statement.

I thought that code would create a bunch of drivers driving a single signal? Regardless, not the way to make a mux.
 

I thought that code would create a bunch of drivers driving a single signal? Regardless, not the way to make a mux.
A process can create only one driver for any signal. Functionally there is nothing wrong with the OP's use of multiple if/endif statements or the mux that is intended.

From the perspective of having to create and later support a bunch of code that may have some typo that down the road may make it 'not a mux', then this is not the way to write it...but that's a totally different discussion. Here would be a better way to write it...but again, it is functionally equivalent to what the OP descibed

Redefine A as being a three element unsigned vector and O being an eight element vector both starting from index 0.

Code:
process(A,CTRL1,CTRL2,EN)
begin
   O <= (others => '0');
   if not((CTRL1 = '1') or (CTRL2 = '1') or (EN = '0'))then
      O(to_integer(A)) <= '1';
   end if;
end process;

Kevin Jennings
 

    V

    Points: 2
    Helpful Answer Positive Rating
No latches will be created, a mux is described. All of the 8 possible synthesizable cases of A1, A2, A3 are covered in the large else branch. All synthesizable cases of CTRL1, CTRL2 and EN are covered in the outermost 'if' statement.

Kevin Jennings

I thought that, then compiled it with quartus. I got latches.
If you think about the code, you actually have a load of latches connected to a priority encoder.
 

I thought that, then compiled it with quartus. I got latches.
If you think about the code, you actually have a load of latches connected to a priority encoder.

You don't get latches in synthesized code. You just get latches in the RTL schematic and erroneous warnings (that might compromise your confidence in the tool's analyzing competencies).

The gate level netlist is a pure decoder as analyzed by K-J.
 

    V

    Points: 2
    Helpful Answer Positive Rating
I must admit that I use to trust Quartus warnings in a first instance and probably had searched for an error in the code, too.

You can study the erroneous Quartus latch warnings in the below example. It also give warnings for O1 and O2. However, if you remove X from the sensitivity list, with or without actually using it inside the process, the warning disappears.

Code:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity dec1to2 is
Port ( 
  A1 : in STD_LOGIC;
  X : in STD_LOGIC;
  O1 : out STD_LOGIC;
  O2 : out STD_LOGIC;
  Z : out STD_LOGIC);
end dec1to2;

architecture Behavioral of dec1to2 is

begin
  process(A1,X)
  begin
    if A1 = '0' then
      O1 <= '1';O2 <= '0';
    end if;
    if A1 = '1' then
      O1 <= '0';O2 <= '1';
    end if;
    Z <= NOT X;
  end process;
end Behavioral;

The best work around is of course to avoid error-prone constructs like the parallel "if then" where a fully decoded "if then else" should be used.
 

    V

    Points: 2
    Helpful Answer Positive Rating
Just a basic question.. How to link my code with architecture.. You guys based on experience are able to say it creates latches, mux, etc.. Can someone explain..

I read that we have fine grained and coarse grained architectures, where you guys are talking about coarse grained... In a coarse grained architecture, a CLB comprises LOGICAL CELL (LC) and SLICE, LC is a logical block which comprises LUT, MUX.. Am i correct in understanding? What i want to understand is, in processors we have cores like ARM, x86.. Does, FPGA manufacturers have their own defined CLB?
 

Just a basic question.. How to link my code with architecture.. You guys based on experience are able to say it creates latches, mux, etc.. Can someone explain..
An output from a combinatorial circuit only depends on the current state of the inputs. The output from a latch depends on what has happened before. A latch is not combinatorial. There exist some feedback where some signal is used to generate itself.
In VHDL, a latch is described in an unclocked process if there is a path where an output is not assigned a value.
In the mux example in the original post, it is not easy to see that the outputs are always assigned a value.
What happens if you only want to decode 5 outputs?

The code from K-J is the most elegant solution, but the original code could be "saved" like this:
(note that it is now possible to remove the code for some outputs without creating latches)


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
process(A1,A2,A3,CTRL1,CTRL2,EN)
begin
 
  O1 <= '0';
  O2 <= '0';
  O3 <= '0';
  O4 <= '0';
  O5 <= '0';
  O6 <= '0';
  O7 <= '0';
  O8 <= '0';
  if ((CTRL1 = '1') or (CTRL2 = '1') or (EN = '0'))then
    null;
  else
    if((A1 = '0') and (A2 = '0') and (A3 = '0')) then
      O1 <= '1';
    end if;
    if((A1 = '1') and (A2 = '0') and (A3 = '0')) then
      O2 <= '1';
    end if;
    if((A1 = '0') and (A2 = '1') and (A3 = '0')) then
      O3 <= '1';
    end if;
    if((A1 = '1') and (A2 = '1') and (A3 = '0')) then
      O4 <= '1';
    end if;
    if((A1 = '0') and (A2 = '0') and (A3 = '1')) then
      O5 <= '1';
    end if;
    if((A1 = '1') and (A2 = '0') and (A3 = '1')) then
      O6 <= '1';
    end if;
    if((A1 = '0') and (A2 = '1') and (A3 = '1')) then
      O7 <= '1';
    end if;
    if((A1 = '1') and (A2 = '1') and (A3 = '1')) then
      O8 <= '1';
    end if;
  end if;
 
end process;

 
Last edited:
@std_latch

This reminds me of unassigned variables in micro controller program. totally different scenario.. But reminding me of
unassigned global variables causing problems..

Have a small doubt here. As you are mentioning, some unassigned output scenarios, giving latches.. but if i have taken care that all output scenarios are covered with another logic, does the synthesis transition into a same RTL schematic?
I mean to ask, if i write a logic with if-else-then and SWITCH case, does both transition into a same RTL schematic after synthesis?
 

I mean to ask, if i write a logic with if-else-then and SWITCH case, does both transition into a same RTL schematic after synthesis?
Yes it does. As shown in above posts, this is also the case for the code in your original post.

But instead of having to check for full coverage of all input combinations, it's much easier to define a default action that will also apply to possibly left-out cases.
 
process(A,CTRL1,CTRL2,EN)
begin
O <= (others => '0');
if not((CTRL1 = '1') or (CTRL2 = '1') or (EN = '0'))then
O(to_integer(A)) <= '1';
end if;
end process;

Intially, didn't go through properly.. this code is so simple, expereince matters, thanks @J-K

- - - Updated - - -

@FvM

Thanks for the input.. This was what i was looking for.. Wasn't too clear previously, whether they lead to same RTL schematic or not.. I have another question here..

Let us assume i haven't written any code in the architecture section (process).. that means no logic.. and just inputs and outputs are declared in entity.. In this case as far as i understand, there must be simple latches in the output RTL schematic to hold the output value.. Hope i am correct in understanding.. Then assume another case, in which i will be assigning initial values for inputs.. and this intialization i do in a process... Here, all inputs are covered and assigned default values.. In this case also, we will have latches in the RTL schematic because there is no other logic implemented in the process.. So, here what i mean to ask is.. if we don't have a unassigned input-output combination which results in latches in RTL schematic, is that an error?
 

Maybe you're not clearly describing what you mean, but if you have written nothing in the architecture, then nothing will be synthesized. No latch, no flip flop, no gates, nothing at all.

Hope i am correct in understanding..
I don't think so.

Then assume another case, in which i will be assigning initial values for inputs..
Again, you're probably not saying what you mean. You can't assign to any inputs. Only outputs can be assigned.

Not sure, but maybe you're meaning to say 'output' rather than 'input' and that you have a process that only assigns default values which would mean something like this...
Code:
process(Gazinta)
begin
   Gazouta <= '0'; -- Default value
   -- But nothing else
end process;
IF this is what you meant, then again no latches are created. This will synthesize to the signal 'Gazouta' being set to '0'. If Gazouta is an output of the top level, then that's what you get. If Gazouta is the output of some entity then the above code will likely synthesize to nothing in terms of resources because the logic reduction process will take this into account in computing the result of any downstream logic that is connected to Gazouta.

Kevin Jennings
 
Reactions: FvM

    FvM

    Points: 2
    Helpful Answer Positive Rating
Again, I completely agree with Kevin.

To avoid possible misunderstandings, please give an example code that illustrates the question.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…