always clk <= #5 !clk;
Seems this doesn`t work and get a "out-of-memory" errors with VCS
What's the reason behind this? I have the feeling the VCS can't get out of the event it scheduled for clk. but don't know why?
You are getting an "out-of-memory" error because it is an non-blocking infinite loop adding future events to the scheduler.
always is functionally equivalent to initial while(1) (an infinite loop). <= #5 doesn't consume time, it schedules an update in the future. There is no time blocking delays in the loop.
Without a time blocking delay the simulator keeps executing the same loop in the same time step. The simulate will not move to the next time step until all operations in the current time step are complete or suspended. Eventually the simulator will run out of memory and error out. Some simulators may exit out early if an infinite loop is detected.
Typically, clocks are generated with LHS delays and with blocking statements. Examples:
reg clk = 1'b1; // or 1'b0
always #5 clk = !clk;
or
reg clk;
initial begin
clk = 1'b1; // or 1'b0
forever #5 clk = !clk;
end
I get "out-of-memory" errors with both VCS and Incisive.
It is more conventional to have the delay on the LHS:
reg clk = 0;
always #5 clk <= !clk;
Related
i know high level async reset can be achieved like:
always#(posedge clk or posedge rst)
begin
if (rst==1)
but how to realize posedge async reset, which means the moment reset edge coming up, the logic in always block reset immediately?
i wrote the logic below:
always#(posedge clk or posedge rst)
begin
rst_pre<=rst;
if(!rst_pre && rst) // to test if rst is posedge
//execute reset logic here...
but the question is, the always block was triggered in a unexpected high frequency, i finally figured out that although there was only 1 posedge of rst, the always block was triggered by rst signal much more than 1 time.
(tested using altera cyclone 10LP with quartus 18)
I think the method i used to achieve posedge async reset is not stable, can anyone tell me what can i do to solve this?
What you are trying to achieve is a asynchronous reset. It can be posedge or negedge.
always#(posedge clk or posedge rst)
begin
if (rst)
// do the reset
else begin
// your normal execution logic
end
end
If you want to use negedge reset then you can use:
always#(posedge clk or negedge rst)
begin
if (~rst)
// do the reset
else begin
// your normal execution logic
end
end
Other than that, there is nothing complicated on reset. Both on these occasions, on posedge/negedge of rst, block will get triggered and it will do the reset.
The very first code snippet which you call "high level async reset" logic is "posedge asynchronous reset logic".
The code snippet specified a active high asynchronous reset signal rst. "active high" + "asynchronous" means signals generated by this always block are reset immediately when rst asserts.
As soon as you include "posedge/negedge reset" in the sensitivy list, and the reset condition inside the always block has priority over the rest of the sequential logic, it is asynchronous:
always # (posedge clk_i, posedge arst_i) begin
if(arst_i) begin
...this condition has to be first
end
else begin
...normal sequential logic
end
end
Use "posedge" for active-high reset, and "negedge" for active-low reset.
Extra note: Sometimes it is also useful to have a reset synchronizer. This synchronized "soft reset" should be included in the normal sequential logic and it would help to have everything synchronized with the clock. By doing this you would have a first asynchronous reset condition, and the last synchronized reset would avoid any metastabiliy problems regarding the asynchronous condition.
This is a simple SV program (I know an arbiter is much more complex, pardon me for naming this as one), but I don't know how the line repeat(4) #ar.cb; keeps controlling the entire clock. If I comment out that line, the clock stops even though I have put it in an 'always' block inside the top module. I can't understand how this works.
testbench.sv
interface arb_if(input bit clk);
logic [1:0] request;
logic [1:0] grant;
logic reset;
clocking cb #(posedge clk);
output request;
input grant;
endclocking
modport DUT(input request,clk,reset,output grant);
modport TB(clocking cb,output reset); endinterface
program automatic test(arb_if.TB ar);
initial begin
ar.reset <= 1;
ar.cb.request<=$urandom;
$display("[%0t]Request is sent",$time);
repeat(4) #ar.cb;
$display("[%0t]Grant=%0d",$time,ar.cb.grant);
end endprogram
module top;
bit clk;
always #5 clk=~clk;
arb_if arb(clk);
test tb(arb);
arbit a1(arb,clk); endmodule
design.sv
module arbit(arb_if.DUT arbiter,input bit clk); always #(posedge clk)
if(arbiter.reset==0)
arbiter.grant<=2'bxx;
else
#1 arbiter.grant<=arbiter.request;
endmodule
And in the design, the grant does not get assigned till the next cycle even if I use a blocking assignment (unless I give #1, in which case it does, of course after the delay).
I am struggling with understanding the synchronous circuit timings. It'd be a great help if someone can clear this up for me.
Without #1:
With #1:
The program terminates the simulation.
From IEEE Std 1800-2017, section 24.3 The program construct:
When all initial procedures within a program have reached their end,
that program shall immediately terminate all descendent threads of
initial procedures within that program. If there is at least one
initial procedure within at least one program block, the entire
simulation shall terminate by means of an implicit call to the $finish
system task immediately after all the threads and all their descendent
threads originating from all initial procedures within all programs
have ended.
With the repeat statement, the simulation ends at time 35. It waits for 4 positive edges of clk, then implicitly calls $finish.
Without the repeat statement, the simulation ends at time 0. It doesn't wait for any clk edges, then implicitly calls $finish.
This question already has an answer here:
Clock waveform does not show in EDAplayground
(1 answer)
Closed 11 months ago.
It has some error in my code, but I can't find anything wrong with my code. EDA Playground says:
Execution interrupted or reached maximum runtime.
Here is my code:
forever #5 clk = ~clk;
Your testbench includes these lines:
forever
#5 clk = ~clk;
This code will keep executing forever. (The clue is in the syntax.) Therefore, your simulation will never stop. EDA Playground's maximum run time is 1 minute, so your simulation is killed after that. Hence your error message.
You need to stop this code executing when you are finished with it. You need something like this:
reg clk, clear, go;
...
initial
begin
go = 1'b1;
...
while (go)
#5 clk = ~clk;
end
initial begin
$dumpfile("systolic_array1.vcd");
$dumpvars(1,systolic_array);
#10
...
go = 1'b0;
end
https://www.edaplayground.com/x/4BCg
In the test-bench code shown below, I'm observing that the clock signal clk does not toggle as expected.
The clock changes from low to high at time 5, but doesn't toggle after that.
module tb();
reg clk;
initial begin
clk = 'b0;
#100 $finish;
end
always#* #5 clk = ~clk;
endmodule
However, if I remove #* from the always#* statement, the clock toggles every 5ns as expected. My question is why doesn't the process block always#* get triggered after the first change?
Note: I've tested the code in NCSIM and VCS, I don't think this a simulator issue.
The accepted answer is wrong - the always is initially triggered by the assignment to 0 in the initial block, so you have a perfectly valid question, which is why the always block isn't triggering itself after it ran the first time (and it clearly did run, because clk is set to 1).
Run the code below - you'll see that it works as expected if you change the blocking assignment to a non-blocking one, or if you use an intra-assignment delay instead of your delay control (clk = #5 ~clk). So, this is a scheduling issue. You might intuitively expect that your process would only trigger once, because the eventual blocking assignment and the process evaluation effectively occur in the same delta, so the blocking assignment could potentially be lost. However, I can't see a specific justification in the LRM. The delay control turns into a future inactive event, and the scheduler eventually executes it, creating an update event, which updates clk (you see this happen once). This should then create an evaluation event for the process, because it's sensitive to clk, but it's not doing this. The scheduling section is (very) woolly, and doesn't really cover this. Mentor would probably give you their version of what's going on if you ask them. VHDL avoids this issue by making all signal assignments non-blocking.
module tb();
reg clk1, clk2, clk3;
initial begin
$monitor($time,, "clk1 = %b; clk2 = %b, clk3 = %b", clk1, clk2, clk3);
clk1 = 1'b0;
clk2 = 1'b0;
clk3 = 1'b0;
#100 $finish;
end
always #*
#5 clk1 = ~clk1;
always #*
#5 clk2 <= ~clk2;
always #(clk3)
clk3 <= #5 ~clk3;
endmodule
clock generators are usually implemented in one of 2 ways:
using always with no sensitivity list, as you already tried:
always #5 clk = ~clk;
the always block without sensitivity list will loop forever and would cause your simulation to hang if it has no #delays inside. Though the latter make it perfect for the clock generator.
use forever loops in your initial block:
initial begin
forever
#5 clk = ~clk;
end
the above code works the same way as the previous always.
The problem is always#(*) will not be sensitive to signals written inside it. So in your case, the implicit sensitivity of the always block doesn't have "clk" in it. Rather it is not sensitive to any signal at all.
I am wondering about the behavior of the below code. There are two always blocks, one is combinational to calculate the next_state signal, the other is sequential which will perform some logic and determine whether or not to shutdown the system. It does this by setting the shutdown_now signal high and then calling state <= next_state.
My question is if the conditions become true that the shutdown_now signal is set (during clock cycle n) in a blocking manner before the state <= next_state line, will the state during clock cycle n+1 be SHUTDOWN or RUNNING? In other words, does the shutdown_now = 1'b1 line block across both state machines since the state signal is dependent on it through the next_state determination?
enum {IDLE, RUNNING, SHUTDOWN} state, next_state;
logic shutdown_now;
// State machine (combinational)
always_comb begin
case (state)
IDLE: next_state <= RUNNING;
RUNNING: next_state <= shutdown_now ? SHUTDOWN : RUNNING;
SHUTDOWN: next_state <= SHUTDOWN;
default: next_state <= SHUTDOWN;
endcase
end
// Sequential Behavior
always_ff # (posedge clk) begin
// Some code here
if (/*some condition*/) begin
shutdown_now = 1'b0;
end else begin
shutdown_now = 1'b1;
end
state <= next_state;
end
First off, you are not following property coding. The always_comb should only use blocking (=) assignments, never non-blocking (<=). And always_ff is the reverse, only non-blocking (<=) assignments, never blocking (=).
With the code as is, state will go RUNNING. This is because the assignment to next_state is non-blocking and thereby next_state will not be updated until later in the scheduler.
Hypothetically, if next_state and shutdown_now were both blocking assignments, then the simulator will have a race condition. Both next_state could be evaluated and updated before or after state is evaluated. This is why it is not a good idea to mix blocking and non-blocking in the same always block.
If properly coded, ie next_state = ... and shutdown_now <= ..., then state will also go to RUNNING. This is because shutdown_now update happens after all scheduled evaluations are complete. So next_state will not see the 1'b1 until after state is evaluated.
Miles, you really only have one state machine, that's the code in your always_comb block. The always_ff just creates a register to hold your state.
The way your code is written now, you will perform a shutdown in the following sequence:
cycle n: the logic in your always_ff block will determine if a shutdown should happen, and will SCHEDULE the shutdown_now signal to assert in the next clock tick.
cycle n+1: shutdown_now asserts, and the state machine (currently in RUNNING) will set the next_state to SHUTDOWN.
cycle n+2: now your state machine will be in the SHUTDOWN state.
Not sure that you need to have your shutdown logic in an always_ff block. If you move that code to a always_comb block, you could leave the rest of your code the same and your state machine would move to the SHUTDOWN state in cycle n+1.
Here is how I would expect that code to perform:
You have two registers: a "shutdown_now" register and a "state" register.
On posedge of clk, the state of both of these registers is updated atomically. That is: when a blocking assignment to shutdown_now takes place, the current process isn't interrupted while state_next gets updated. Instead, for the purposes of the always_ff process, state_next is whatever value it held at the beginning of the posedge clk simulation "tick."
So:
on the first posedge clock tick: shutdown_now will switch from 0 to 1.
Once the "posedge clk" process has completed, the "always_comb" block will notice that it has work to do, and will update state_next (ie. a combinational decode from the new state of the 2 registers).
on the second posedge clock tick: state gets latched with the updated state_next.
So, it will take 2 cycles to shut down your system, not 1.