0
votes

I'm currently learning about writing testbenchs for my VHDL components. I am trying to test a clock synchronizer, just made up of two cascaded D-type flip flops. I have written a testbench, supplying a clock and appropriate input signal stimuli but I see no output changing when I simulate, it just remains at "00".

I would be very grateful for any assistance!

EDIT: the dff component is a standard Quartus component, not quite sure how to get at the internal code.

Here is the component VHDL:

    library ieee;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;


--This device is to synchronize external signals that are asynchronous to the 
--system by use of two cascaded D-Type flip flops, in order to avoid metastability issues.

--Set the generic term Nbits as required for the number of asynchronous inputs to
--be synchronized to the system clock OUTPUT(0) corresponds to INPUT(0), ect.

entity CLOCK_SYNCHRONIZER is

    generic(Nbits : positive := 2);

    port
    (
        --Define inputs
        SYS_CLOCK   : in std_logic;
        RESET       : in std_logic;
        INPUT       : in std_logic_vector(Nbits-1 downto 0);

        --Define output
        OUTPUT      : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')
    );
end entity;



architecture v1 of CLOCK_SYNCHRONIZER is

    --Declare signal for structural VHDL component wiring 
    signal A : std_logic_vector(Nbits-1 downto 0);

    --Declare D-Type Flip-Flop
    component dff
        port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
    end component;

begin

    --Generate and wire number of synchronizers required
    g1 : for n in Nbits-1 downto 0 generate 
        c1 : dff port map(D=>input(n), CLK=>sys_clock, Q=>A(n), CLRN=>reset);
        c2 : dff port map(D=>A(n), CLK=>sys_clock, Q=>output(n), CLRN=>reset);
    end generate;


end architecture v1;

And here is the testbench:

   library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity testbench is
end entity;


architecture v1 of testbench is 

    component CLOCK_SYNCHRONIZER

        generic(Nbits : positive := 2);

        port
        (
            --Define inputs
            SYS_CLOCK   : in std_logic;
            RESET       : in std_logic;
            INPUT       : in std_logic_vector(Nbits-1 downto 0);

            --Define output
            OUTPUT      : out std_logic_vector(Nbits-1 downto 0)
        );
    end component;

    constant Bus_width      : integer := 2;
    signal SYS_CLOCK        : std_logic := '0';
    signal RESET            : std_logic := '1';
    signal INPUT        : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');
    signal OUTPUT       : std_logic_vector(Bus_width-1 downto 0) := (others=>'0');

begin

    C1 : CLOCK_SYNCHRONIZER
    generic map(Nbits=>Bus_width)
    port map(SYS_CLOCK=>SYS_CLOCK, RESET=>RESET, INPUT=>INPUT, OUTPUT=>OUTPUT);


    always : process
    begin
        for i in 0 to 50 loop
            INPUT <= "11";
            wait for 24ns;
            INPUT <= "00";
            wait for 24ns;
        end loop;
    WAIT;
    end process;

    clk : process
    begin

        for i in 0 to 50 loop
            SYS_CLOCK <= '1';
            wait for 5ns;
            SYS_CLOCK <= '0';
            wait for 5ns;
        end loop;
    WAIT;
    end process;






end architecture v1;
1
You haven't given the code for dff. - Matthew Taylor
Hmm, not sure how to get at it. Its a standard component in Quartus. I know the component works I have it operating in a physical design, its just the testbench that I cant figure out. - synth002
Maybe try to generate clock in one of the standard ways: clk <= not clk after 10 ns;? Same for INPUT. - Staszek
IEEE Std 1076-2008 15.3 Lexical elements, separators, and delimiters, para 2 - In some cases an explicit separator is required to separate adjacent lexical elements (namely when, without separation, interpretation as a single lexical element is possible). ..., para 4 - ...At least one separator is required between an identifier or an abstract literal and an adjacent identifier or abstract literal. 5ns is required to be 5 ns or could be identified as an abstract literal containing a non-base character. A portability issue ignored in favor of vendor lock-in. - user1155120

1 Answers

0
votes

The problem is that you have not compiled an entity to bind to the dff component. See this example on EDA Playground, where you see the following warnings:

ELAB1 WARNING ELAB1_0026: "There is no default binding for component "dff". (No entity named "dff" was found)." "design.vhd" 45 0 ... ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c1 : dff not bound. ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__1/c2 : dff not bound. ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c1 : dff not bound. ELBREAD: Warning: ELBREAD_0037 Component /testbench/C1/g1__0/c2 : dff not bound.

Given you have no configuration, this needs to have be called dff and must have exactly the same ports as the dff component, ie:

entity dff is
        port(D : in std_logic; CLK : in std_logic; CLRN : in std_logic; Q : out std_logic);
end entity;

(Google "VHDL default binding rules")

This needs to model the functionality of the dff flip-flop. I have assumed the following functionality:

architecture v1 of dff is
begin

  process (CLK, CLRN)
  begin
    if CLRN = '0' then
      Q <= '0';
    elsif rising_edge(CLK) then
      Q <= D;
    end if;
  end process;

end architecture v1;

You can see this now does something more sensible on EDA Playground. (I haven't checked to see whether it is doing the right thing.)

BTW: why are you initialising this output? That seems a strange thing to do:

OUTPUT      : out std_logic_vector(Nbits-1 downto 0) := (others=>'0')