Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Testbench for negative logic edge triggered flip flop

Status
Not open for further replies.

bitprolix

Junior Member level 2
Joined
Sep 19, 2013
Messages
24
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
235
Hi,

I'm referring this book from Peter J Ashenden on Digital Design and to make my understanding solid, I'm trying to write the testbench and verify my model, However, As I've already posted this in past that, I'm really struggling with test bench at this moment, therefore would really appreciate if someone can give me some pointers on writing testbenches from the prospective of a beginner. You'll find below, both the design model and the testbench, but I think this particular testbench that i came up with is very very primitive. Please help me improve this testbench.


The model for negative edge-triggered flip flop with clock enable, negative-logic asynchronous preset and clear and both active high and active low outputs with an additional condition that, both the preset and clear cannot be active together.

Code:
library ieee;
use ieee.std_logic_1164.all;

entity flip_flop is
	port (	d: in std_logic;
		clk: in std_logic;
		ce: in std_logic;
		pre, clr: in std_logic;
		q, q_n: out std_logic	);
end entity flip_flop;

architecture behave of flip_flop is
signal tmp_q : std_logic;

begin

neg_edge_flip: process(clk, pre, clr)
begin
	assert not (pre = '0' and clr = '0')
	 report "illegal combination";
	 
	if (pre = '0') then
		tmp_q <= '1';
	elsif (clr = '0') then
		tmp_q <= '0';
	elsif (rising_edge(clk)) then
		if (ce = '1') then		
			q <= d;
		end if;
	end if;	
end process neg_edge_flip;

q <= tmp_q;
q_n <= not tmp_q;

end architecture behave;

And the testbench:
Code:
library ieee;
use ieee.std_logic_1164.all;

entity verify_neg_logic_flip_flop is
end entity verify_neg_logic_flip_flop;

architecture verify of verify_neg_logic_flip_flop is
  signal d, clk, ce, pre, clr: std_logic;
  signal q, q_n: std_logic;
    
begin
  duv : entity work.flip_flop(behave)
    port map (d => d,
              clk => clk,
              ce => ce,
              pre => pre,
              clr => clr,
              q => q,
              q_n => q_n);
              --tmp_q => tmp_q);
              
  apply_test_case: process is
  begin
    pre <= '1'; d <= '0'; wait for 1 sec;
    pre <= '1'; d <= '1'; wait for 1 sec;
    pre <= '0'; d <= '0'; wait for 1 sec;
    pre <= '0'; d <= '0'; wait for 1 sec;              
    
    wait on clk until clk = '1';         
    clr <= '1'; d <= '0'; wait for 1 sec;
    clr <= '1'; d <= '1'; wait for 1 sec;
    clr <= '0'; d <= '0'; wait for 1 sec;
    clr <= '0'; d <= '0'; wait for 1 sec;
    
    wait on clk until clk = '1';
    ce <= '1'; d <= '0'; wait for 1 sec;
    ce <= '1'; d <= '1'; wait for 1 sec;
    ce <= '0'; d <= '0'; wait for 1 sec;
    ce <= '0'; d <= '0'; wait for 1 sec;
    
    wait;
  end process apply_test_case;
  
  check_outputs: process is
  begin
    wait on pre, clr, clk, ce;
    wait for 10 ms;
    assert not (pre = '0' and clr = '0');
  end process check_outputs;
  
end architecture verify;

Thank you.

- - - Updated - - -

The model for negative edge-triggered flip flop with clock enable, negative-logic asynchronous preset and clear and both active high and active low outputs with an additional condition that, both the preset and clear cannot be active together.

There was one typo from the post above. As the model is for negative edge triggered flip-flop, therefore the falling edge of the clock should be taken into account rather than the rising edge of the clock. Therefore the correct model would be:

Code:
	elsif (falling_edge(clk)) then

instead of,
Code:
	elsif (rising_edge(clk)) then


And in the testbench:
Code:
    wait on clk until clk = '0';

instead of
Code:
    wait on clk until clk = '1';
 

One big problem is that your testbench doesnt seem to generate a clock, which is fundamental to the whole design.

I dont really understand what you're asking for. This testbench seems fine (when you add a clock) for generating signals for input and verifying the design by looking at the waveform.
 

Since the updates in your posts, it's now solved? If not, could you provide a screenshot of the testbench results? That makes it a lot easier to communicate.
 

One big problem is that your testbench doesnt seem to generate a clock, which is fundamental to the whole design.

Thank you for pointing out the missing clk signal generation. I've now added a clock signal generator process and have also modified the testbench a little. With this changed testbench, I never see the output "q" to become high("1") and is rather underfined or zero all the time.

The modified testbench:
Code:
library ieee;
use ieee.std_logic_1164.all;

entity verify_neg_logic_flip_flop is
end entity verify_neg_logic_flip_flop;

architecture verify of verify_neg_logic_flip_flop is
  signal d, clk, ce, pre, clr: std_logic;
  signal q, q_n: std_logic;  
begin
  duv : entity work.flip_flop(behave)
    port map (d => d,
              clk => clk,
              ce => ce,
              pre => pre,
              clr => clr,
              q => q,
              q_n => q_n);              
  
  apply_test_case: process
  begin
    wait on clk until clk = '0';
    ce <= '0'; wait for 1 sec;
    clr <= '1'; wait for 1 sec;
    pre <= '1';  d <= '0'; wait for 1 sec;
    pre <= '1';  d <= '1'; wait for 1 sec;
    pre <= '0';  d <= '0'; wait for 1 sec;
    pre <= '0';  d <= '0'; wait for 1 sec;              
    
    wait on clk until clk = '0';
    pre <= '1';  wait for 1 sec;
    clr <= '1'; d <= '0'; wait for 1 sec;
    clr <= '1'; d <= '1'; wait for 1 sec;
    clr <= '0'; d <= '0';  wait for 1 sec;
    clr <= '0'; d <= '0'; wait for 1 sec;
    
    wait on clk until clk = '0';
    pre <= '1'; clr <= '0'; wait for 1 sec;
    ce <= '1'; d <= '0'; wait for 1 sec;
    ce <= '1'; d <= '1'; wait for 1 sec;
    ce <= '0'; d <= '0'; wait for 1 sec;
    ce <= '0'; d <= '0'; wait for 1 sec;
    
    wait on clk until clk = '0';
    clr <= '1'; wait for 1 sec;
    ce <= '1'; wait for 1 sec;
    pre <= '0'; wait for 1 sec;
    pre <= '0';  d <= '0'; wait for 1 sec;
    pre <= '0';  d <= '1'; wait for 1 sec;
    wait;
  end process apply_test_case;
  
  check_outputs: process
  begin
    wait on pre, clr, clk, ce;
    wait for 10 ms;
    -- assert not (pre = '0' and clr = '0');
  end process check_outputs;
  
  
  --Clock generator
  clock_generator: process
  begin
    clk <= '0';
    wait for 500 ms;
    clk <= '1';
    wait for 500 ms;
  end process clock_generator;
    
end architecture verify;

And the waveform:
forum_1.png
 

You are assinging Q from inside and outside the process, meaning you're probably getting 'X' later on rather than 'U'. You should assign tmp_q in the process and q outside (or why not just assign q inside the process and get rid of temp_q all together.
 

You are assinging Q from inside and outside the process, meaning you're probably getting 'X' later on rather than 'U'. You should assign tmp_q in the process and q outside (or why not just assign q inside the process and get rid of temp_q all together.

This negative edge triggered flip flop has both active low and active high output ( q and q_n), and as VHDL will not allow me to put a output signal on the right side of the assignment (<=) operation. i.e.

Code:
q_n <= not q; -- would be wrong

Therefore I'm using a temporary signal and for the concurrency purposes, kept this assignment outside of the process block.
Code:
q <= tmp_q;
q_n <= not tmp_q;
 

But then you need to assign only tmp_q in the process as q is being assigned from tmp_q. In your code, q has multiple drivers which causes the problem.
 
Thank you for your reply. I've now changed the design model as:

Code:
library ieee;
use ieee.std_logic_1164.all;

entity flip_flop is
	port (	d: in std_logic;
		clk: in std_logic;
		ce: in std_logic;
		pre, clr: in std_logic;
		q, q_n: out std_logic	);
end entity flip_flop;

architecture behave of flip_flop is
signal tmp_q : std_logic;

begin

neg_edge_flip: process(clk, pre, clr)
begin
	assert not (pre = '0' and clr = '0')
	 report "illegal combination" severity error;
	 
	if (pre = '0') then
		tmp_q <= '1';
	elsif (clr = '0') then
		tmp_q <= '0';
	elsif (falling_edge(clk)) then
		if (ce = '1') then		
			q <= d;
		end if;
	end if;	
q <= tmp_q;
end process neg_edge_flip;


q_n <= not tmp_q;

end architecture behave;

Basically everything is same, except that the assignment on "q" happens inside the process and q_n outside the process. With this modification, I could see significant changes in the waveform(attached below). Coming back to the original question of steps involved in writing the testbench, I really would like to know that are there any books or tutorials available which covers this topic from a very beginner level to a an advanced level?

forum_2.png
 

You should not do it like this. You should have:

tmp_q <= d;

inside the process

q <= tmp_q;

outside the process;

With your current code tmp_q is never assigned to anyother other than the reset states, so Q_n will not be correct.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top