Friday, 6 October 2017

FPGA VHDL 8 bit datapath testbench structural design





8 BIT DATAPATH
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY datapath IS PORT (
clock: IN STD_LOGIC;
input: IN STD_LOGIC_VECTOR( 7 DOWNTO 0 );
IE, WE: IN STD_LOGIC;
WA: IN STD_LOGIC_VECTOR (1 DOWNTO 0);
RAE: IN STD_LOGIC;
RAA: IN STD_LOGIC_VECTOR (1 DOWNTO 0);
RBE: IN STD_LOGIC;
RBA: IN STD_LOGIC_VECTOR (1 DOWNTO 0);
aluSel: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
shSel: IN STD_LOGIC_VECTOR (1 DOWNTO 0);
OE: IN STD_LOGIC;
output: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END datapath;
ARCHITECTURE Structural OF datapath IS
COMPONENT mux2 PORT (
S: IN STD_LOGIC; -- select lines
D1, D0: IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- data bus input
Y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- data bus output
END COMPONENT;
COMPONENT regfile PORT (
clk: IN STD_LOGIC; --clock
WE: IN STD_LOGIC; --write enable
WA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --write address
input: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --input
RAE: IN STD_LOGIC; --read enable ports A & B
RAA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --read address port A & B
RBE: IN STD_LOGIC; --read enable ports A & B
RBA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --read address port A & B
Aout, Bout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --output port A & B
END COMPONENT;
COMPONENT alu PORT (
ALUSel: IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- select for operations
A, B: IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- input operands
F: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- output
END COMPONENT;
COMPONENT shifter PORT (
SHSel: IN STD_LOGIC_VECTOR(1 DOWNTO 0); -- select for operations
input: IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- input operands
output: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- output
END COMPONENT;
COMPONENT tristatebuffer PORT (
E: IN STD_LOGIC;
D: IN STD_LOGIC_VECTOR(7 downto 0);
Y: OUT STD_LOGIC_VECTOR(7 downto 0));
END COMPONENT;
SIGNAL muxout, rfAout, rfBout: STD_LOGIC_VECTOR( 7 DOWNTO 0 );
SIGNAL aluout, shiftout, tristateout: STD_LOGIC_VECTOR( 7 DOWNTO 0 );
BEGIN
-- doing structural modeling here
U0: mux2 PORT MAP( IE, input, shiftout, muxout );
U1: regfile PORT MAP(clock,WE,WA,muxout,RAE,RAA,RBE,RBA,rfAout,rfBout );
U2: alu PORT MAP( ALUsel, rfAout, rfBout, aluout );
U3: shifter PORT MAP(SHSel,aluout,shiftout);
U4: tristatebuffer PORT MAP(OE, shiftout, tristateout);
output <= tristateout;
END Structural;

2 TO 1 MULTIPLEXER
-- 2-to-1 MUX
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux2 IS PORT (
S: IN STD_LOGIC; -- select line
D1, D0: IN STD_LOGIC_VECTOR(7 downto 0); -- data bus input
Y: OUT STD_LOGIC_VECTOR(7 downto 0)); -- data bus output
END mux2;
ARCHITECTURE Behavioral OF mux2 IS
BEGIN
PROCESS(S, D1, D0)
BEGIN
IF(S = '0' )THEN
Y <= D0;
ELSE
Y <= D1;
END IF;
END PROCESS;
END Behavioral;

REGISTER FILE
-- Register File
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY regfile IS PORT (
clk: IN STD_LOGIC; --clock
WE: IN STD_LOGIC; --write enable
WA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --write address
input: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --input
RAE: IN STD_LOGIC; --read enable ports A & B
RAA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --read address port A & B
RBE: IN STD_LOGIC; --read enable ports A & B
RBA: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --read address port A & B
Aout, Bout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --output port A & B
END regfile;
ARCHITECTURE Behavioral OF regfile IS
SUBTYPE reg IS STD_LOGIC_VECTOR(7 DOWNTO 0);
TYPE regArray IS array(0 TO 3) OF reg;
SIGNAL RF: regArray; --register file contents
BEGIN
WritePort: PROCESS (clk)
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF (WE = '1') THEN
RF(CONV_INTEGER(WA)) <= input;
END IF;
END IF;
END PROCESS;
ReadPortA: PROCESS (RAE, RAA)
BEGIN
IF (RAE = '1') then
Aout <= RF(CONV_INTEGER(RAA)); -- convert bit VECTOR to integer
ELSE
Aout <= (others => '0');
END IF;
END PROCESS;
ReadPortB: PROCESS (RBE, RBA)
BEGIN
IF (RBE = '1') then
Bout <= RF(CONV_INTEGER(RBA)); -- convert bit VECTOR to integer
ELSE
Bout <= (others => '0');
END IF;
END PROCESS;
END Behavioral;

ARITHMETIC LOGIC UNIT
-- ALU
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
-- need the following to perform arithmetics on STD_LOGIC_VECTORs
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY alu IS PORT (
ALUSel: IN STD_LOGIC_VECTOR(2 DOWNTO 0); -- select for operations
A, B: IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- input operands
F: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- output
END alu;
ARCHITECTURE Behavior OF alu IS
BEGIN
PROCESS(ALUSel, A, B)
BEGIN
CASE ALUSel IS
WHEN "000" => -- pass A through
F <= A;
WHEN "001" => -- AND
F <= A AND B;
WHEN "010" => -- OR
F <= A OR B;
WHEN "011" => -- NOT
F <= NOT A;
WHEN "100" => -- add
F <= A + B;
WHEN "101" => -- subtract
F <= A - B;
WHEN "110" => -- increment
F <= A + 1;
WHEN others => -- decrement
F <= A - 1;
END CASE;
END PROCESS;
END Behavior;

SHIFTER
-- Shifter
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY shifter IS PORT (
SHSel: IN STD_LOGIC_VECTOR(1 DOWNTO 0); -- select for operations

input: IN STD_LOGIC_VECTOR(7 DOWNTO 0); -- input operands
output: OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); -- output
END shifter;
ARCHITECTURE Behavior OF shifter IS
BEGIN
PROCESS(SHSel, input)
BEGIN
CASE SHSel IS
WHEN "00" => -- pass through
output <= input;
WHEN "01" => -- shift right
output <= input(6 DOWNTO 0) & '0';
WHEN "10" => -- shift left
output <= '0' & input(7 DOWNTO 1);
WHEN OTHERS => -- rotate right
output <= input(0) & input(7 DOWNTO 1);
END CASE;
END PROCESS;
END Behavior;

TRI STATE BUFFER
-- Tri-state buffer
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY TriStateBuffer IS PORT (
E: IN STD_LOGIC;
D: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Y: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END TriStateBuffer;
ARCHITECTURE Behavioral OF TriStateBuffer IS
BEGIN
PROCESS (E, D) -- get error message if no d
BEGIN
IF (E = '1') THEN
Y <= D;
ELSE
Y <= (OTHERS => 'Z'); -- to get 8 Z values
END IF;
END PROCESS;
END Behavioral;

8 BIT DATAPATH TESTBENCH

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY datapath_test IS
END datapath_test;
 
ARCHITECTURE behavior OF datapath_test IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT datapath
    PORT(
         clock : IN  std_logic;
         input : IN  std_logic_vector(7 downto 0);
         IE : IN  std_logic;
         WE : IN  std_logic;
         WA : IN  std_logic_vector(1 downto 0);
         RAE : IN  std_logic;
         RAA : IN  std_logic_vector(1 downto 0);
         RBE : IN  std_logic;
         RBA : IN  std_logic_vector(1 downto 0);
         aluSel : IN  std_logic_vector(2 downto 0);
         shSel : IN  std_logic_vector(1 downto 0);
         OE : IN  std_logic;
         output : OUT  std_logic_vector(7 downto 0)
        );
    END COMPONENT;
    

   --inputs
   signal clock : std_logic := '0';
   signal input : std_logic_vector(7 downto 0) := (others => '0');
   signal IE : std_logic := '0';
   signal WE : std_logic := '0';
   signal WA : std_logic_vector(1 downto 0) := (others => '0');
   signal RAE : std_logic := '0';
   signal RAA : std_logic_vector(1 downto 0) := (others => '0');
   signal RBE : std_logic := '0';
   signal RBA : std_logic_vector(1 downto 0) := (others => '0');
   signal aluSel : std_logic_vector(2 downto 0) := (others => '0');
   signal shSel : std_logic_vector(1 downto 0) := (others => '0');
   signal OE : std_logic := '0';

  --Outputs
   signal output : std_logic_vector(7 downto 0);

   -- Clock period definitions
   constant clock_period : time := 50 ns;
 

 begin
 -- Instantiate the Unit Under Test (UUT)
   uut: datapath PORT MAP (
          clock => clock,
          input => input,
          IE => IE,
          WE => WE,
          WA => WA,
          RAE => RAE,
          RAA => RAA,
          RBE => RBE,
          RBA => RBA,
          aluSel => aluSel,
          shSel => shSel,
          OE => OE,
          output => output
        );

   -- Clock process definitions
   clock_process :process
   begin
  clock <= '0';
  wait for clock_period/2;
  clock <= '1';
  wait for clock_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin  
      -- hold reset state for 100 ns.
        --Initialize inputs
 
  input <= "00000000";-- input binary 4
  IE <= '0';       --input enabled
  WA <= "00"; -- input stored in address binary 0
  WE <= '0';--write enabled
  RAA <= "00";
  RAE <= '0';
  RBA <= "00";
  RBE <= '0';
  aluSel <= "000";
  shSel <= "00";
  OE <= '0';
    
  --------------------------------------------------
  
  wait for 50 ns;
  input <= "00000100";-- input binary 4
  IE <= '1';       --input enabled
  WA <= "00"; -- input stored in address binary 0
  WE <= '1';--write enabled
  RAA <= "00";
  RAE <= '0';
  RBA <= "00";
  RBE <= '0';
  aluSel <= "000";
  shSel <= "00";
  OE <= '0';
    
  wait for 50 ns;
  input <= "00000000";
  IE <= '0';
  WA <= "01";--store result of the operation done in the ALU in address binary 1 the result is 1000
  WE <= '1';--write in address enabled
  RAA <= "00";--read address 0 in A
  RAE <= '1';--read enabled
  RBA <= "00";--read address 0 in B
  RBE <= '1';--read enabled
  aluSel <= "100";--add A + B = 100+100=1000
  shSel <= "00";
  OE <= '1';
      -- insert stimulus here 

      wait;
   end process;

END;

--addresses 00 = 00000100 binary 4
--addresses 01 = 00001000 result binary 8 
--addresses 10
--addresses 11

No comments:

Post a Comment