Sunday, June 16, 2013

Step 2c: Regular Encoder 4 to 2 (Problem of NULL discovered)

Encoder Code:


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity encoder4to2 is
port 
(
     ilines    : in std_logic_vector(3 downto 0);
     dout     : out std_logic_vector(1 downto 0);
     valid    : out std_logic
);
end encoder4to2;

architecture Behavioral of encoder4to2 is

begin

encoder4 : with ilines select
    dout <=
        "00" when "0001",
        "01" when "0010",
        "10" when "0100",
        "11" when "1000",
        "11" when others;
        
validout : with ilines select
    valid <=
        '1' when "0001",
        '1' when "0010",
        '1' when "0100",
        '1' when "1000",
        '0' when others;

end Behavioral;


Test bench for Encoder: Attempt 1 using case statement



library ieee;
use ieee.std_logic_1164.all;
use IEEE.Std_Logic_Unsigned.all ;
use IEEE.Std_Logic_Arith.all;
use work.simpkg.all;

entity tb_encoder4to2 is
end tb_encoder4to2;

architecture Test of tb_encoder4to2 is
-- Declare/Import DUT
component encoder4to2
    port(ilines : in  std_logic_vector(3 downto 0);
         dout   : out std_logic_vector(1 downto 0);
         valid  : out std_logic);
end component encoder4to2;
-- 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 ilines : std_logic_vector(3 downto 0);
    signal dout : 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 encoder4to2
    port map(ilines => ilines,
             dout   => dout,
             valid  => valid);

-- Stim Loop --
 stim_loop : process
 variable expected:std_logic_vector(1 downto 0);
 begin
     for i in 0 to 15 loop
         -- Apply Stim to DUT Inputs & update
         ilines <= CONV_STD_LOGIC_VECTOR(i,4);
         
         wait for update ;
         
         -- Equations for expected response
         case ilines is
             when "0001" => expected := "00";
             when "0010" => expected := "01";
             when "0100" => expected := "10";
             when "1000" => expected := "11";
             when others => null;
         end case;
          
         --- Check response
         assert (expected = dout ) 
              report "Test Failed" & CR &
              "dut.stimulus= "& vec2str(ilines) & "; " &"dut.response =" & vec2str(dout) & "; "&"expected =" & vec2str(expected)&"; "
              severity error;
         
         -- 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;


Xilinx ISE Simulator Output:


at 1 ns: Error: Test Failed
dut.stimulus= 0000; dut.response =11; expected =XX; 
at 34 ns: Error: Test Failed
dut.stimulus= 0011; dut.response =11; expected =01; 
at 56 ns: Error: Test Failed
dut.stimulus= 0101; dut.response =11; expected =10; 
at 67 ns: Error: Test Failed
dut.stimulus= 0110; dut.response =11; expected =10; 
at 78 ns: Error: Test Failed
dut.stimulus= 0111; dut.response =11; expected =10; 

Insight into the problem:
The DUT response seems to be as expected, however the expected response has been calculated incorrectly. To debug this problem, I have stepped through the code in debugger mode of Xilinx ISE.
Here is what I found

Notice the case structure in expected response :
when others => null
This was the culprit, what it was doing was that whenever the input wasn't one-hot encoded, it would enter the case when others => null.
What null does is that doesn't change the previous output, this poses problem
was we want the dut to send 11 not the previous values

Solution:
To fix the problem, change the statement as follows
when others => expected := "11";

Final Modified test bench



library ieee;
use ieee.std_logic_1164.all;
use IEEE.Std_Logic_Unsigned.all ;
use IEEE.Std_Logic_Arith.all;
use work.simpkg.all;

entity tb_encoder4to2 is
end tb_encoder4to2;

architecture Test of tb_encoder4to2 is
-- Declare/Import DUT
component encoder4to2
    port(ilines : in  std_logic_vector(3 downto 0);
         dout   : out std_logic_vector(1 downto 0);
         valid  : out std_logic);
end component encoder4to2;
-- 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 ilines : std_logic_vector(3 downto 0);
    signal dout : 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 encoder4to2
    port map(ilines => ilines,
             dout   => dout,
             valid  => valid);

-- Stim Loop --
 stim_loop : process
 variable expected:std_logic_vector(1 downto 0);
 begin
     for i in 0 to 15 loop
         -- Apply Stim to DUT Inputs & update
         ilines <= CONV_STD_LOGIC_VECTOR(i,4);
         
         wait for update ;
         
         -- Equations for expected response
         case ilines is
             when "0001" => expected := "00";
             when "0010" => expected := "01";
             when "0100" => expected := "10";
             when "1000" => expected := "11";
             when others => expected := "11";
         end case;
          
         --- Check response
         assert (expected = dout ) 
              report "Test Failed" & CR &
              "dut.stimulus= "& vec2str(ilines) & "; " &"dut.response =" & vec2str(dout) & "; "&"expected =" & vec2str(expected)&"; "
              severity error;
         
         -- 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;


No comments:

Post a Comment