Wednesday, June 12, 2013

Step 2b: Priority Encoder

1. Less Efficient Code in VHDL



library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity PE4to2 is
port 
(
    w         : in  std_logic_vector(3 downto 0);
    z         : out std_logic_vector(1 downto 0);
    valid    : out std_logic    
);
end PE4to2;

architecture Behavioral of PE4to2 is

begin

pen : with w select
    z <=
        "00" when "0001",
        "01" when "0010",
        "01" when "0011",
        "10" when "0100",
        "10" when "0101",
        "10" when "0110",
        "10" when "0111",
        "11" when others;
        
validsig : with w select
    valid <=
        '0' when "0000",                
        '1' when others;
    
end Behavioral;


Note that to express 001x we had to use two lines, this makes the above code inefficient

2. Test Bench for code in above section 1
library ieee;
use ieee.std_logic_1164.all;
use IEEE.Std_Logic_Unsigned.all ;
use IEEE.Std_Logic_Arith.all;
use std.textio.all;
use work.simpkg.all;


entity tb_PE4to2 is
end tb_PE4to2;

architecture Test of tb_PE4to2 is
-- Declare/Import DUT
component PE4to2
    port(w     : in  std_logic_vector(3 downto 0);
         z     : out std_logic_vector(1 downto 0);
         valid : out std_logic);
end component PE4to2;

-- Functions
function leading1 (s : std_logic_vector) return integer is
begin
    for i in s'range loop
        if (s(i) = '1') then
            return i; -- Return for loop index
        end if;
    end loop;
    return 0;
end function leading1;

-- Declare Internal Signals which act as Input and Output to DUT
    signal clk : std_logic;     --- clock driver signal

-- Constants ---
    constant period     : time := 10 ns;
    constant update     : time := 1 ns;
    signal w : std_logic_vector(3 downto 0);
    signal z : std_logic_vector(1 downto 0);
    signal valid : std_logic;
--Start of Test Bench
begin

-- Define the Clock required for simulation --
testbenchclk : process
begin
    clk <= '0';
    wait for period / 2;
    clk <= '1';
    wait for period / 2;
end process testbenchclk;

-- Instantiate DUT -----
dut:component PE4to2
    port map(w     => w,
             z     => z,
             valid => valid);

-- Response Equation


-- Stim Loop --
 stim_loop : process
 variable expected: integer:=0;
 begin
     for i in 0 to 15 loop
         -- Apply Stim to DUT Inputs & update
         w <= CONV_STD_LOGIC_VECTOR(i,4);
        wait for update ;
         --report "Input =" & integer'image(i);
        
         -- Equations for response
         expected:= leading1(w);
         
         --- Check response
         if ( w /= "0000") then
             assert (z = expected) 
                  report "Test Failed " & CR &
                  "dut.stimulus= "& vec2str(w) & "; " &"dut.response =" & vec2str(z) & "; "&"expected =" & integer'image(expected)&"; "    
                  severity error;
        else
            -- Input = 0000 is  a special where output is don't cares and valid signal should be false
            assert (valid = '0')
            report "Test failed" & CR &
            "dut stimulus = 0000, Expected Valid to be false" & "found expected to be = " & std2str(valid)
            severity error;
          
          end if;
         
         -- Next Stim after a delay
         wait for period;    
     end loop;
     
     -- Wait Indefinitely No more Stim
     wait;
 end process stim_loop;

--End of Test Bench --
end architecture Test;


Note the usage of function in the above. Functions have to be declared in the architecture section before begin. Notice how leading1 function is used to detect the position of first '1' in the for loop.
Loop runs in reverse order, for i in s'range loop.
Notice that it is not for i in s'range to 0 loop



No comments:

Post a Comment