vhdlshift-register

why my shift register show the result in one clock instead of 4?


this is my code for dff and multiplexer and shift register, which should rich the output in 4 clocks but it does it in one clock and I could not fix it myself. this is my dff code:

use IEEE.STD_LOGIC_1164.ALL;


entity DFLipFlop is
    Port ( d : in  STD_LOGIC;
           clock : in  STD_LOGIC;
              reset : in STD_LOGIC;
           q : out  STD_LOGIC);
end DFLipFlop;

architecture Behavioral of DFLipFlop is

begin
process(clock,reset)
begin
if(reset ='1')then
q <= '0';
elsif(CLOCK='1' and CLOCK'EVENT)then
q <= d;
end if;
end process;
end Behavioral;

this is my multiplexer code:

-- Company: 
-- Engineer: 
-- 
-- Create Date:    08:37:48 04/27/2022 
-- Design Name: 
-- Module Name:    multiplexer - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity multiplexer is
    Port ( DataIn : in  STD_LOGIC;
           P_in : in  STD_LOGIC;
           Selector : in  STD_LOGIC;
           Output : out  STD_LOGIC);
end multiplexer;

architecture Behavioral of multiplexer is

begin

process(Selector)
begin 
   
    if Selector = '0' then
       Output <= DataIn ;

    else        
        OutPut <= P_in ;
   
    end if;
 end process;


end Behavioral;

this is my shift register code:

-- Company: 
-- Engineer: 
-- 
-- Create Date:    08:35:05 04/27/2022 
-- Design Name: 
-- Module Name:    shiftRegister - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity shiftRegister is
    Port ( DataIn : in  STD_LOGIC;
           Selector : in  STD_LOGIC;
           P_in : in  STD_LOGIC_VECTOR (3 downto 0);
           Clk : in  STD_LOGIC;
           OutPut : out  STD_LOGIC);
end shiftRegister;

architecture structural of shiftRegister is

component DFLipFlop is
    Port ( d : in  STD_LOGIC;
           clock : in  STD_LOGIC;
              reset : in STD_LOGIC;
           q : out  STD_LOGIC);
end component DFLipFlop;

component multiplexer is
    Port ( DataIn : in  STD_LOGIC;
           P_in : in  STD_LOGIC;
           Selector : in  STD_LOGIC;
           Output : out  STD_LOGIC);
end component multiplexer;


signal DFFOutput :  STD_LOGIC_VECTOR(3 downto 0);
signal MuxOutput :  STD_LOGIC_VECTOR(3 downto 0);

begin 

multiplexer0 : multiplexer Port map( DataIn => DataIn , P_in => P_in(3) , Selector => Selector , Output =>  MuxOutput(0) );
dff_interface0 : DFLipFlop port map( d => MuxOutput(0) , clock => Clk , reset => '0' , q => DFFOutput(0));

multiplexer1 : multiplexer Port map( DataIn => DFFOutput(0) , P_in => P_in(2) , Selector => Selector , Output =>  MuxOutput(1) );
dff_interface1 : DFLipFlop port map( d => MuxOutput(1) , clock => Clk  , reset => '0' , q => DFFOutput(1));

multiplexer2 : multiplexer Port map( DataIn => DFFOutput(1) , P_in => P_in(1) , Selector => Selector , Output =>  MuxOutput(2) );
dff_interface2 : DFLipFlop port map( d => MuxOutput(2) , clock => Clk  , reset => '0' , q => DFFOutput(2));

multiplexer3 : multiplexer Port map( DataIn => DFFOutput(2) , P_in => P_in(0) , Selector => Selector , Output =>  MuxOutput(3) );
dff_interface3 : DFLipFlop port map( d => MuxOutput(3) , clock => Clk  , reset => '0' , q => Output);

end structural;

and this is my test bench:

-- Company: 
-- Engineer:
--
-- Create Date:   09:12:38 04/27/2022
-- Design Name:   
-- Module Name:   C:/Users/ABTIN/Documents/amirkabir un/term 4/Computer Architecture/Lab/HW8/HW8/TestBench.vhd
-- Project Name:  HW8
-- Target Device:  
-- Tool versions:  
-- Description:   
-- 
-- VHDL Test Bench Created by ISE for module: shiftRegister
-- 
-- Dependencies:
-- 
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
-- Notes: 
-- This testbench has been automatically generated using types std_logic and
-- std_logic_vector for the ports of the unit under test.  Xilinx recommends
-- that these types always be used for the top-level I/O of a design in order
-- to guarantee that the testbench will bind correctly to the post-implementation 
-- simulation model.
--------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
 
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;
 
ENTITY TestBench IS
END TestBench;
 
ARCHITECTURE behavior OF TestBench IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT shiftRegister
    PORT(
         DataIn : IN  std_logic;
         Selector : IN  std_logic;
         P_in : IN  std_logic_vector(3 downto 0);
         Clk : IN  std_logic;
         OutPut : OUT  std_logic
        );
    END COMPONENT;
    

   --Inputs
   signal DataIn : std_logic := '0';
   signal Selector : std_logic := '0';
   signal P_in : std_logic_vector(3 downto 0) := "1011";
   signal Clk : std_logic := '0';

    --Outputs
   signal OutPut : std_logic;

   -- Clock period definitions
   constant Clk_period : time := 5 ns;
 
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: shiftRegister PORT MAP (
          DataIn => DataIn,
          Selector => Selector,
          P_in => P_in,
          Clk => Clk,
          OutPut => OutPut
        );

   -- Clock process definitions
   Clk_process :process
   begin
        Clk <= '0';
        wait for Clk_period/2;
        Clk <= '1';
        wait for Clk_period/2;
   end process;
 

   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.


      wait for Clk_period*10;
      DataIn <= '0' ; P_in <= "1011" ; Selector <= '1' ;wait for Clk_period*1;
      DataIn <= '1' ; P_in <= "1001"  ;wait for Clk_period*2;
      
      -- insert stimulus here 

      wait;
   end process;

END;

I can not figure out what the problem is. please help.


Solution

  • Your data input signal is not propagated across the shift register in a single clock.

    When looking at this simulation, you can see it is the upper bit of your preload data that gets loaded at the clock edge where the cursor is placed. The behavior is consistent with the code.

    The detailled explanation is:

    If you wanted to propagate a 1 across the shift-register, you should first reset it (to set it to zero) and then give it a 1 on the input.

    You should use a proper reset at the begin of the testbench. This way your design gets into a known state.

    In your testbench, you assign initial values to the signals but use them in sensitivity lists (the main culprit is selector). Because of this, the output of the multiplexers are undefined as the process was not triggered by a change on the signal.

    You should change the testbench to look like this:

    -- hold reset state for 100 ns.
         wait for Clk_period * 10;
         selector <= '0'; -- this assignment triggers the multiplexer processes
         p_in <= "1011";
    

    I would also strongly suggest simulating your entire design and exploring the signals inside (I see you use Vivado, it has an integrated simulator; otherwise Intel provides a free Modelsim license if you need it).

    If you want to use the Vivado simulator, have a look at UG937.


    To get examples of how to implement a particular component in Vivado, you can also look at the Synthesis Guide (UG901). There is an example of the implementation to use for shift registers to make optimal use of the FPGA's resources (other FPGA manufacturers have similar guides, look for synthesis guide in your favorite search engine).

    For Vivado, there are also integrated code examples under Tools > Language templates.