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.

VHDL test bench code freeze

Status
Not open for further replies.

shaiko

Advanced Member level 5
Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Hello,

I'm trying to run the following test bench in Modelsim - I write: "run 1ms"
Modelsim freezes at 0 ns with no progress...


Code:
write_cpu <= '0' , '1' after 100 ns , '0' after 120 ns , '1' after 300 ns , '0' after 320 ns ;
read_cpu <= '0' , '1' after 700000 ns , '0' after 700020 ns ; 
cpu_address <= X"000114" , X"000054" after 200 ns , X"000034" after 700000 ns ;
cpu_data <= "00000000000000000010000011100111" , "11101000000000000000000011011001"  after 200 ns ;

cpu_transactions : process
begin
	if write_cpu = '1' then
	   address_out <= cpu_address ;
	   data_out <= cpu_data ;	
	   read_or_write <= '0' ;
		wait for 40 ns ;
	   cs <= '0' ;
		wait for 100 ns ;
	   address_out <= ( others => '0' ) ;	
	   data_out <= ( others => 'Z' ) ;	
	   read_or_write <= '1' ;
	   cs <= '1' ;
	elsif read_cpu = '1' then	
	   address_out <= cpu_address ;
	   data_out <= ( others => 'Z' ) ;	
	   read_or_write <= '1' ;
		wait for 40 ns ;
	   cs <= '0' ;
		wait for 100 ns ;
	   address_out <= ( others => '0' ) ;	
	   cs <= '1' ;	
	else
	   address_out <= ( others => '0' ) ;
	   data_out <= ( others => 'Z' ) ;	
	   read_or_write <= '0' ;	
	  cs <= '1' ;	
	end if ;	
end process cpu_transactions ;
 

Freezing at 0 ns typically means the simulator is stuck in an infinite loop where something is coded such that it can't determine a stable state (i.e. the scheduler has to keep scheduling new delta time events).

I don't think this code is the problem unless you've put this into a testcase and it fails to advance the scheduler past 0 ns. If so, you should give us the testcase showing this instead of an out of context code snippet.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Similar to what @ads-ee said, a freeze at time 0 is most commonly from a process running without either a wait statement or a sensitivity list, however, there is an issue in this process.

Your else branch in your process does not have a wait statement, and hence, once your process selects this branch, your simulation will hang.
Code:
. . .
    else
        data_out <= ( others => 'Z' ) ;	
        read_or_write <= '0' ;	
        cs <= '1' ;	
    end if ;	
end process cpu_transactions ;

If the CPU you are modeling uses a clock, it might be handy to use that as a reference internally to your model.

I know some books suggest that waveform assignments are suitable to setup elements of a test. Once the test has any complexity this approach becomes painful (both to write and review). What I might suggest as a structure is:

CpuTestProc: process
begin
-- wait for system to come out of reset and start time
wait for 100 ns ;
-- Do Write Cycle with address=X"000114", data=X"000020E7"
wait for 300 ns - NOW ; -- NOW is a function in std.standard
-- Do Write Cycle with address=X"000054", data=X"...."
wait for 700000 ns - NOW ;
-- Do Read Cycle with address=X"000034"
. . .

Use procedures to implement a CpuWriteCycle and CpuReadCycle.

If this is for work, see our website (https://www.synthworks.com) for VHDL classes that will help you progress quickly.
 
Your else branch in your process does not have a wait statement, and hence, once your process selects this branch, your simulation will hang.
Great catch, didn't even see that!
Of course I never write testbenches like this so I don't have to deal with making sure I have delays in every branch.

...Instead I do this
If the CPU you are modeling uses a clock, it might be handy to use that as a reference internally to your model.

and...I absolutely do this for every interface to my DUT.
Use procedures to implement a CpuWriteCycle and CpuReadCycle.

My testbenches typically look more like a software program than RTL.
CpuWrite (addr, wdata);
CpuRead (addr, rdata);
SendADCData;
ReadStatus;
...etc.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Your else branch in your process does not have a wait statement, and hence, once your process selects this branch, your simulation will hang.
Why does the "else" branch need a wait statement? Why won't it simply exit after execution?
 

Because the process has no sensitivity list hence it continuously executes, as the else branch is the first and only branch that ever gets executed at 0 ns it stays there forever.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Thanks. that's very clear.

Can you post an example of how to write a procedure that does the same?
 

Can you post an example of how to write a procedure that does the same?
Unfortunately that's not something I can do, I primarily write in Verilog, I only write in VHDL when I'm forced to (basically when they tell me they are going to cut some appendage off that I want to keep if I don't, mere threats of torture don't work on me, as I consider using VHDL is torture ;-))

When I get stuck with a VHDL DUT I usually write my testbench in Verilog anyway.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top