Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Test bench principle

Altera_Forum
Honored Contributor II
1,093 Views

When I write test bench for design simulation, I confronted some weird problems in GTL simulation. The results are similar, but I want to post here to discuss. For example, I have RAM, in testbench I input address to write or read like; 

 

// example 1 

always @(posedge clock) // posedge is active edge of the clock 

begin 

wren<=1; 

address<=address+1; 

data<=data+1; 

end 

 

// example 2 

always @(posedge clock) // posedge is active edge of the clock 

begin 

rden<=1; 

address<=address+1; 

end 

 

 

Sometimes, the Modelsim will give warning in each clock posedge to warn the setup and hold timing violation. And GTL simulation results are weird like the output data does not follow the sequence of address. 

 

The Altera staff mentioned "Changing the data in a test bench at the exact same time as the active edge of the clock can produce unreliable and inconsistent results" , and he suggests don't use active edge of clock to change data or add delay like: 

 

always @(negedge clock) // posedge is active edge of the clock 

begin 

wren<=1; 

address<=address+1; 

data<=data+1; 

end 

 

or 

 

always @(posedge clock) // posedge is active edge of the clock 

begin 

wren<=1; 

# 5 address<=address+1; 

# 5 data<=data+1; 

end 

 

So I just have questions, when I writed testbench, I always change data using style: 

always @(posedge) 

begin 

data<=f(data); // f(data) means a function of data 

end 

 

should I put timing delay in all these commands? And in testbench, blocking assignment and non-blocking assignment, which I should use? I think both of them work the difference are concurrent and one cycle delay. 

 

Hope anyone can give me some advices. Thanks very much.
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
352 Views

You should use  

 

always @(posedge clock) // posedge is active edge of the clock 

begin 

wren <=# (delay) 1; 

address <=# (delay) address+1; 

data<=# (delay) f(data); 

end 

 

where delay is what is needed to prevent timing violations. You want to put the delay to the right of the <= the delay is non-blocking; it only effects the delay of the assignment and not when the next statement executes.
0 Kudos
Altera_Forum
Honored Contributor II
352 Views

 

--- Quote Start ---  

You should use  

 

always @(posedge clock) // posedge is active edge of the clock 

begin 

wren <=# (delay) 1; 

address <=# (delay) address+1; 

data<=# (delay) f(data); 

end 

 

where delay is what is needed to prevent timing violations. You want to put the delay to the right of the <= the delay is non-blocking; it only effects the delay of the assignment and not when the next statement executes. 

--- Quote End ---  

 

 

Thanks very much for your help. So the# (delay) should be used for all assignments to prevent assignment happen exactly in active edge of clock, right? 

 

Could you explain a little more why put# (delay) in left not in right? Thanks very much.
0 Kudos
Altera_Forum
Honored Contributor II
352 Views

#delay statement

 

The blocks any statement, which includes an assignment statement. The process is blocked until the time the delay specifies. 

 

That statement can be a non-blocking assignment, which can have a delay that postpone the update to the RHS, but does not block the process. The next statement is executed immediately. 

# delay1 LHS <=# delay2 RHS; 

 

delay1 blocks the entire statement, delay2 only blocks the update to the RHS. 

 

See  

 

http://www.sutherland-hdl.com/papers/1996-cug-presentation_nonblocking_assigns.pdf
0 Kudos
Altera_Forum
Honored Contributor II
352 Views

Thanks very much, it is very clear!

0 Kudos
Reply