Sie sind auf Seite 1von 5

Combinational Logic Examples

Dr DC Hendry

February 2006

This lecture will provide a number of examples of combinational logic descriptions. The
intention is to provide a number of small but realistic examples of the use of VHDL.

1 Multiplexors

First well look at a multiplexor using a selection of coding techniques.

For a four-to-one multiplexor, that is, a multiplexor with four input ports and a single
output port and two input select lines, the following entity header applies.

library ieee;
use ieee.std logic 1164.all;

entity mux4to1 is
port(
i0, i1, i2, i3 : in std logic;
s0, s1 : in std logic;
y : out std logic);
end entity mux4to1;

For a first implementation well use the selected assignment statement, as in a previous
lecture:
architecture rtl of mux4to1 is
signal selvec : std logic vector(1 downto 0);
begin
selvec(1) <= s1;
selvec(0) <= s0;
with selvec select
y <= i0 when 00,
i1 when 01,
i2 when 10,
i3 when others;
end architecture rtl;
CL Examples

The signal selvec avoids a problem with the type of the expression s1 & s0 as the selection
expression of the with statement. This can be avoided, but we have not yet studied the
syntax required. The others clause is required since the expression selvec has values other
than 00, 01 etc, due to the additional values of type std logic such as U, X etc.

Here is an alternative version of the architecture body using a process with a case statement:

architecture rtl of mux4to1 is


begin
mp : process(i0, i1, i2, i3, s0, s1)
variable selvec : std logic vector(1 downto 0);
begin
selvec(1) := s1;
selvec(0) := s0;
case selvec is
when 00 => y <= i0;
when 01 => y <= i1;
when 10 => y <= i2;
when others => y <= i3;
end case;
end process mp;
end architecture rtl;

It is a simple matter to expand this multiplexor from dealing with four single bit inputs
and a single bit output, to dealing with multibit inputs and a multibit output, with either
of the above architecture bodies the following entity header may be used:

entity mux4to1n is
generic(N : integer);
port(
i0, i1, i2, i3 : in std logic vector(N 1 downto 0);
s0, s1 : in std logic;
y : out std logic vector(N 1 downto 0));
end entity mux4to1n;

It is also possible to construct a design for an m to 1 multiplexor, but additional syntax is


required.

2 Decoders

A decoder circuit has as input a binary number which selects one output to become active.
The most common discrete decoder circuit has a three bit binary number as input, and
eight outputs, only one of which is active at a time. Also as input is a single bit enable line
which must be active for any output to be active. Further, the single bit enable line and
the output lines are active low. The schematic symbol for a decoder is:

Revision : 1.1 Page 2of 5 Dr DC Hendry


CL Examples

y0
s0 y1
s1
s2 y2
y3
y4
y5
y6
g y7

Here is an entity header for a decoder circuit:

library ieee;
use ieee.std logic 1164.all;

entity decoder3to8 is
port(
sel : in std logic vector(2 downto 0);
g n : in std logic; active low!
y n : out std logic vector(7 downto 0)
active low!);
end entity decoder3to8;

In this case Ive chosen to make the output a vector, rather than eight single bit lines. Ill
start with an architecture body which while correct in the sense that the required logic is
synthesised, is I think the wrong way to solve this problem (this solution I should say is
taken from one of the recommended text books - so make up your own minds about this!).

architecture poor of decoder3to8 is


begin
y n(0) <= not(not sel(2) and not sel(1) and not sel(0)) or g n;
y n(1) <= not(not sel(2) and not sel(1) and sel(0)) or g n;
y n(2) <= not(not sel(2) and sel(1) and not sel(0)) or g n;
y n(3) <= not(not sel(2) and sel(1) and sel(0)) or g n;
y n(4) <= not(sel(2) and not sel(1) and not sel(0)) or g n;
y n(5) <= not(sel(2) and not sel(1) and sel(0)) or g n;
y n(6) <= not(sel(2) and sel(1) and not sel(0)) or g n;
y n(7) <= not(sel(2) and sel(1) and sel(0)) or g n;
end architecture poor;

This circuit synthesises perfectly well and produces as good a circuit (as measured by area,
speed or power) as the next solution. Lets look at the next solution and compare the two.

Revision : 1.1 Page 3of 5 Dr DC Hendry


CL Examples

Here is what I consider to be a better solution:

use ieee.numeric std.all;


architecture rtl of decoder3to8 is
begin

decode : process(sel, g n)
begin
y n <= (others => 1);
y n(to integer(unsigned(sel))) <= g n;
end process decode;

end architecture rtl;

Why is this a better solution? First because it is simple to change the number of select lines
and number of outputs, the architecture body does not use the fact that there are eight
outputs explicitly, rather the number of outputs and the number of select lines is obtained
through range. Consider for example how much amendments are needed to the first design
to increase the number of outputs from 8 to 10, compared to the second.

Secondly, it is much less prone to typos. An error in the index of sel in the first design
will not be detected until simulation time, whereas most typos in the second design will
cause catastophic failure of the design, probably detected at compile time.

3 Encoders

An encoder circuit has n single bit inputs, and the output is a code indicating which of the
inputs is active. Thus if we have four input signals, say i0 through i3, then if i2 is the
only input at logic 1, the output should be the binary number 10 (i.e. decimal 2). A
variation on the encoder circuit is the priority encoder, to be discussed below.

The basic encoder assumes that one and only one of the input lines is active at a time. First
an entity header:

library ieee;
use ieee.std logic 1164.all;

entity encoder is
port(
d : in std logic vector(7 downto 0);
y : out std logic vector(2 downto 0));
end entity encoder;

Revision : 1.1 Page 4of 5 Dr DC Hendry


CL Examples

and an architecture body, first, the wrong way to do it:

architecture poor of encoder is


Decimal Binary
0 000
1 001
2 010
3 011
4 100
5 101
6 110
7 111
begin
y(0) <= d(1) or d(3) or d(5) or d(7);
y(1) <= d(2) or d(3) or d(6) or d(7);
y(2) <= d(4) or d(5) or d(6) or d(7);
end architecture poor;

In this design we have derived the Boolean equations from the specification, and we leave
the synthesis tool to optimise and then map these equations onto logic gates. Now for a
second solution:

use ieee.numeric std.all;


architecture rtl of encoder is
begin
encode : process(d)
variable yvar : std logic vector(yrange);
begin
yvar := (others => 0);
for n in drange loop
if d(n) = 1 then
yvar <= std logic vector(to unsigned(n, ylength));
exit;
end if ;
end loop;
y <= yvar;
end process encode;
end architecture rtl;

Again we have largely separated the function of the code from the details of bit count.

There is however a difference between the two designs, consider the case when two or more
of the inputs are high at the same time, with the first code, the output data is the logical
OR of the two individual results, probably not of any use. With the second design, the
output is the code of the lowest input set true (its trivally modified to use the highest input
set true). This is known as a priority encoder.

Revision : 1.1 Page 5of 5 Dr DC Hendry

Das könnte Ihnen auch gefallen