Skip to content

Instantly share code, notes, and snippets.

@hidsh
Created December 4, 2012 07:07
Show Gist options
  • Save hidsh/4201433 to your computer and use it in GitHub Desktop.
Save hidsh/4201433 to your computer and use it in GitHub Desktop.
VHDL: half adder and full adder
-- full_adder.vhdl
-- desc: 1bit full adder
entity FULL_ADDER is
port(A, B, CIN: in bit;
SUM, COUT: out bit);
end FULL_ADDER;
architecture STRUCT of FULL_ADDER is
component HALF_ADDER
port(A, B: in bit;
SUM, CARRY: out bit);
end component;
signal U0_CARRY, U0_SUM, U1_CARRY: bit;
begin
U0: HALF_ADDER port map (A => A, B => B, SUM => U0_SUM, CARRY => U0_CARRY);
U1: HALF_ADDER port map (A => U0_SUM, B => CIN, SUM => SUM, CARRY => U1_CARRY);
COUT <= U0_CARRY or U1_CARRY;
end STRUCT;
-- full_adder2.vhdl
-- desc: 1bit full adder from scratch
entity FULL_ADDER is
port(A, B, CIN: in bit;
SUM, COUT: out bit);
end FULL_ADDER;
architecture DATAFLOW of FULL_ADDER is
begin
SUM <= ((not CIN) and (not A) and B ) or
((not CIN) and A and (not B)) or
( CIN and (not A) and (not B)) or
( CIN and A and B );
COUT <= ((not CIN) and A and B ) or
( CIN and (not A) and B ) or
( CIN and A and (not B)) or
( CIN and B and B );
end DATAFLOW;
-- full_adder2b.vhdl
-- desc: 1bit full adder from truth table
library IEEE;
use IEEE.std_logic_1164.all; -- for std_logic_vector, to_stdulogic
entity FULL_ADDER is
port(A, B, CIN: in bit;
SUM, COUT: out bit);
end FULL_ADDER;
architecture RTL of FULL_ADDER is
begin
process(A, B, CIN)
variable indata: std_logic_vector(2 downto 0);
begin
indata := to_stdulogic(CIN) & to_stdulogic(A) & to_stdulogic(B);
case indata is
when "000" => COUT <= '0'; SUM <= '0';
when "001" => COUT <= '0'; SUM <= '1';
when "010" => COUT <= '0'; SUM <= '1';
when "011" => COUT <= '1'; SUM <= '0';
when "100" => COUT <= '0'; SUM <= '1';
when "101" => COUT <= '1'; SUM <= '0';
when "110" => COUT <= '1'; SUM <= '0';
when "111" => COUT <= '1'; SUM <= '1';
when others => COUT <= '0'; SUM <= '0';
end case;
end process;
end RTL;
-- full_adder_test.vhdl
--
-- test vector for full_adder.vhdl
-- A testbench has no ports.
entity ftest is
end ftest;
architecture behav of ftest is
-- Declaration of the component that will be instantiated.
component FULL_ADDER
port(A, B, CIN: in bit;
SUM, COUT: out bit);
end component;
-- Specifies which entity is bound with the component.
for adder_0: FULL_ADDER use entity work.FULL_ADDER;
signal i0, i1, s, co, ci : bit;
begin
-- Component instantiation.
adder_0: FULL_ADDER port map (A => i0, B => i1, CIN => ci, SUM => s, COUT => co);
-- This process does the real job.
process
type pattern_type is record
-- The inputs of the adder.
i0, i1, ci : bit;
-- The expected outputs of the adder.
s, co : bit;
end record;
-- The patterns to apply.
type pattern_array is array (natural range <>) of pattern_type;
constant patterns : pattern_array :=
(('0', '0', '0', '0', '0'),
('0', '0', '1', '1', '0'),
('0', '1', '0', '1', '0'),
('0', '1', '1', '0', '1'),
('1', '0', '0', '1', '0'),
('1', '0', '1', '0', '1'),
('1', '1', '0', '0', '1'),
('1', '1', '1', '1', '1'));
begin
report " A , B ,CI :CO ,SUM";
-- Check each pattern.
for i in patterns'range loop
-- Set the inputs.
i0 <= patterns(i).i0;
i1 <= patterns(i).i1;
ci <= patterns(i).ci;
-- Wait for the results.
wait for 1 ns;
report bit'image(i0) & "," & bit'image(i1) & "," & bit'image(ci) & ":" & bit'image(co) & "," & bit'image(s);
-- Check the outputs.
--assert s = patterns(i).s
--report "bad sum value" severity error;
--assert co = patterns(i).co
--report "bad carray out value" severity error;
end loop;
assert false report "end of test" severity note;
-- Wait forever; this will finish the simulation.
wait;
end process;
end behav;
-- half_adder.vhdl
-- desc: 1bit half adder from scratch
entity HALF_ADDER is
port(A, B: in bit;
SUM, CARRY: out bit);
end HALF_ADDER;
architecture DATAFLOW of HALF_ADDER is
begin
SUM <= A xor B;
CARRY <= A and B;
end DATAFLOW;
-- half_adder_test.vhdl
--
-- test vector for half_adder.vhdl
-- A testbench has no ports.
library ieee;
use ieee.std_logic_1164.all;
entity test is
end test;
architecture behav of test is
-- Declaration of the component that will be instantiated.
component HALF_ADDER
port(A, B: in bit;
SUM, CARRY: out bit);
end component;
-- Specifies which entity is bound with the component.
for adder_0: HALF_ADDER use entity work.HALF_ADDER;
signal i0, i1, s, co, ci : bit;
begin
-- Component instantiation.
adder_0: HALF_ADDER port map (A => i0, B => i1, SUM => s, CARRY => co);
-- This process does the real job.
process
type pattern_type is record
-- The inputs of the adder.
i0, i1, ci : bit;
-- The expected outputs of the adder.
s, co : bit;
end record;
-- The patterns to apply.
type pattern_array is array (natural range <>) of pattern_type;
constant patterns : pattern_array :=
(('0', '0', '0', '0', '0'),
('0', '0', '1', '1', '0'), -- not use
('0', '1', '0', '1', '0'),
('0', '1', '1', '0', '1'), -- not use
('1', '0', '0', '1', '0'),
('1', '0', '1', '0', '1'), -- not use
('1', '1', '0', '0', '1'),
('1', '1', '1', '1', '1')); -- not use
begin
report " A , B : C ,SUM";
-- Check each pattern.
for i in patterns'range loop
-- Set the inputs.
i0 <= patterns(i).i0;
i1 <= patterns(i).i1;
ci <= patterns(i).ci;
-- Wait for the results.
wait for 1 ns;
report bit'image(i0) & "," & bit'image(i1) & ":" & bit'image(co) & "," & bit'image(s);
-- Check the outputs.
--assert s = patterns(i).s
--report "bad sum value" severity error;
--assert co = patterns(i).co
--report "bad carray out value" severity error;
end loop;
assert false report "end of test" severity note;
-- Wait forever; this will finish the simulation.
wait;
end process;
end behav;
$ghdl -a half_adder.vhdl; ghdl -a half_adder_test.vhdl; ghdl -e test; ghdl -r test
half_adder_test.vhdl:44:5:@0ms:(report note): A , B : C ,SUM
half_adder_test.vhdl:53:7:@1ns:(report note): '0','0':'0','0'
half_adder_test.vhdl:53:7:@2ns:(report note): '0','0':'0','0'
half_adder_test.vhdl:53:7:@3ns:(report note): '0','1':'0','1'
half_adder_test.vhdl:53:7:@4ns:(report note): '0','1':'0','1'
half_adder_test.vhdl:53:7:@5ns:(report note): '1','0':'0','1'
half_adder_test.vhdl:53:7:@6ns:(report note): '1','0':'0','1'
half_adder_test.vhdl:53:7:@7ns:(report note): '1','1':'1','0'
half_adder_test.vhdl:53:7:@8ns:(report note): '1','1':'1','0'
half_adder_test.vhdl:60:5:@8ns:(assertion note): end of test
$ghdl -a half_adder.vhdl full_adder.vhdl; ghdl -a full_adder_test.vhdl; ghdl -e ftest; ghdl -r ftest
full_adder_test.vhdl:41:5:@0ms:(report note): A , B ,CI :CO ,SUM
full_adder_test.vhdl:50:7:@1ns:(report note): '0','0','0':'0','0'
full_adder_test.vhdl:50:7:@2ns:(report note): '0','0','1':'0','1'
full_adder_test.vhdl:50:7:@3ns:(report note): '0','1','0':'0','1'
full_adder_test.vhdl:50:7:@4ns:(report note): '0','1','1':'1','0'
full_adder_test.vhdl:50:7:@5ns:(report note): '1','0','0':'0','1'
full_adder_test.vhdl:50:7:@6ns:(report note): '1','0','1':'1','0'
full_adder_test.vhdl:50:7:@7ns:(report note): '1','1','0':'1','0'
full_adder_test.vhdl:50:7:@8ns:(report note): '1','1','1':'1','1'
full_adder_test.vhdl:57:5:@8ns:(assertion note): end of test
$ghdl -a full_adder2.vhdl; ghdl -a full_adder_test.vhdl; ghdl -e ftest; ghdl -r ftest
full_adder_test.vhdl:41:5:@0ms:(report note): A , B ,CI :CO ,SUM
full_adder_test.vhdl:50:7:@1ns:(report note): '0','0','0':'0','0'
full_adder_test.vhdl:50:7:@2ns:(report note): '0','0','1':'0','1'
full_adder_test.vhdl:50:7:@3ns:(report note): '0','1','0':'0','1'
full_adder_test.vhdl:50:7:@4ns:(report note): '0','1','1':'1','0'
full_adder_test.vhdl:50:7:@5ns:(report note): '1','0','0':'0','1'
full_adder_test.vhdl:50:7:@6ns:(report note): '1','0','1':'1','0'
full_adder_test.vhdl:50:7:@7ns:(report note): '1','1','0':'1','0'
full_adder_test.vhdl:50:7:@8ns:(report note): '1','1','1':'1','1'
full_adder_test.vhdl:57:5:@8ns:(assertion note): end of test
$ghdl -a full_adder2b.vhdl; ghdl -a full_adder_test.vhdl; ghdl -e ftest; ghdl -r ftest
full_adder_test.vhdl:41:5:@0ms:(report note): A , B ,CI :CO ,SUM
full_adder_test.vhdl:50:7:@1ns:(report note): '0','0','0':'0','0'
full_adder_test.vhdl:50:7:@2ns:(report note): '0','0','1':'0','1'
full_adder_test.vhdl:50:7:@3ns:(report note): '0','1','0':'0','1'
full_adder_test.vhdl:50:7:@4ns:(report note): '0','1','1':'1','0'
full_adder_test.vhdl:50:7:@5ns:(report note): '1','0','0':'0','1'
full_adder_test.vhdl:50:7:@6ns:(report note): '1','0','1':'1','0'
full_adder_test.vhdl:50:7:@7ns:(report note): '1','1','0':'1','0'
full_adder_test.vhdl:50:7:@8ns:(report note): '1','1','1':'1','1'
full_adder_test.vhdl:57:5:@8ns:(assertion note): end of test
$ghdl --version
GHDL 0.29 (20100109) [Sokcho edition]
Compiled with GNAT Version: 4.4.0 20080314 (experimental)
mcode code generator
Written by Tristan Gingold.
Copyright (C) 2003 - 2010 Tristan Gingold.
GHDL is free software, covered by the GNU General Public License. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment