Majority gate example

gates.vhd

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity nand2 is

Port ( x1 : in std_logic;

x2 : in std_logic;

f : out std_logic);

end nand2;

architecture arch of nand2 is

begin

f <= x1 nand x2 after 1 ns;

end architecture arch;

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity nand3 is

Port ( x1 : in std_logic;

x2 : in std_logic;

x3 : in std_logic;

f : out std_logic);

end nand3;

architecture arch of nand3 is

begin

f <= not(x1 and x2 and x3) after 1 ns;

end architecture arch;


Majority.vhd

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity majority is

Port ( x : in std_logic;

y : in std_logic;

z : in std_logic;

f : out std_logic);

end majority;

-- Architecture using equation for majority circuit

architecture RTL of majority is

begin

f <= (x and y) or (x and z) or (y and z) after 2 ns;

end architecture RTL;

-- Structural architecture using nand gates in gates.vhd

architecture struc of majority is

signal F1, F2, F3: std_logic;

begin

U1: ENTITY work.nand2(arch) PORT MAP(X, Y, F1);

U2: ENTITY work.nand2(arch) PORT MAP(X1 => X, X2 => Z, F => F2);

U3: ENTITY work.nand2(arch) PORT MAP(Y, Z, F3);

U4: ENTITY work.nand3(arch) PORT MAP(F1, F2, F3, F);

end architecture struc;

-- Using the select version of a case statement.

architecture arch1 of majority is

signal s: std_logic_vector(2 downto 0);

begin

s <= x&y&z after 2 ns;

with s select

f <= '0' when "000",

'0' when "001",

'0' when "010",

'1' when "011",

'0' when "100",

'1' when "101",

'1' when "110",

'1' when "111",

'-' when others;

end architecture arch1;


-- Using a propcess and a case statement

architecture arch2 of majority is

signal s: std_logic_vector(2 downto 0);

begin

s <= x&y&z after 2 ns;

process(s)

begin

case S is

when "000" => f <= '0';

when "001" => f <= '0';

when "010" => f <= '0';

when "011" => f <= '1';

when "100" => f <= '0';

when "101" => f <= '1';

when "110" => f <= '1';

when "111" => f <= '1';

when others => f <= '-';

end case;

end process;

end architecture arch2;


-- Using a variable to count the number of 1's

architecture arch3 of majority is

begin

maj: process(x, y, z)

variable n: integer range 0 to 3;

begin

n := 0;

if x = '1' then

n := n + 1;

end if;

if y = '1' then

n := n + 1;

end if;

if z = '1' then

n := n + 1;

end if;

if n < 2 then

f <= '0' after 2 ns;

else

f <= '1' after 2 ns;

end if;

end process;

end architecture arch3;

-- Using a look up table

architecture arch4 of majority is

type LUT is array (0 to 7) of std_logic;

CONSTANT Maj: LUT :=

('0', '0', '0', '1', '0', '1', '1', '1');

signal T: std_logic_vector(2 downto 0);

begin

T <= X & Y & Z;

F <= Maj(CONV_Integer(T)) after 2 ns;

-- F <= Maj(CONV_Integer(unsigned(X & Y & Z)));

end architecture;


tb_majority.vhd

LIBRARY IEEE;

USE work.all;

USE IEEE.Std_Logic_1164.all;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY tb IS END ENTITY tb;

Architecture TEST of tb is

SIGNAL X: std_logic_vector (2 downto 0) := "000";

SIGNAL F_r, F_s, F_1, F_2, F_3, F_4: std_logic;

begin

Ur: ENTITY work.majority(RTL) PORT MAP(X(2), X(1), X(0), F_r);

Us: ENTITY work.majority(struc) PORT MAP(X(2), X(1), X(0), F_s);

U1: ENTITY work.majority(arch1) PORT MAP(X(2), X(1), X(0), F_1);

U2: ENTITY work.majority(arch2) PORT MAP(X(2), X(1), X(0), F_2);

U3: ENTITY work.majority(arch3) PORT MAP(X(2), X(1), X(0), F_3);

U4: ENTITY work.majority(arch4) PORT MAP(X(2), X(1), X(0), F_4);

X <= X + 1 after 10 ns;

process

begin

wait on X; -- wait till x changes

wait for 5 ns; -- wait till stable

-- Check that all architectures produce same result

assert not(F_r or F_s or F_1 or F_2 or F_3 or F_4) = '1'

or (F_r and F_s and F_1 and F_2 and F_3 and F_4) = '1'

Report "Error: not all the same!";

end process;

end test;


To simulate the above:

1.  Create a VHDL source directory and copy all files in majority.zip to your VHDL source directory.

2.  Start Modelsim.

3.  Be sure you are in the VHDL source directory

a. Use File à Source directory

b.  Or create a ModelSim shortcut and specify the start directory to be your source directory.

4.  If the “work” directory does not exist create it by typing “vlib work” in the transcript window. (Do this only once for each source directory!)

5.  Compile the files in the following order: gates.vhd, majority.vhd, and tb_majority.vhd.

6.  type “do all”

7.  You should see a waveform that can be adjusted to be similar to that shown below.

Homework: Change one of the architectures so that it produces the wrong output. Run a simulation and verify that the assert statement flags the error.

2

2