module abc(input clk, output a);
reg a;
always #(posedge clk)
begin
a=0;
$monitor("%d",a);
end
always #(posedge clk)
begin
a=1;
$monitor("%d",a);
end
what will be the first output after first clk pulse? if we don't want any default value of reg(we want a value for a)...?
This is a race condition. Verilog does not guarantee the ordering of execution between processes synchronized to the same event. One simulation tool might pick the first block. another tool might pick the second block. Synthesis tools will not allow multiple assignments to the same variable from different blocks.
Related
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.
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 came to know that we can use assign statements in procedural blocks(like in always), what will be the difference in using "assign" inside always block and outside it(in concern with synthesized circuit). I mean when it is absolutely necessary to use assign in always?
Never, assign keyword is for continuous assignment and it will generate combinatorial logic at synthesis. In fact, you can obtain the assign behaviour with an always block:
wire test;
//At all times, test equals input
assign test = input;
Is equivalent to:
reg test;
//Each time input changes(with the always#*), test takes its value
always#*
test = input;
In always blocks, you should only use non-blocking assignment('<=') which are procedural assignments. Using blocking assignment is possible, however, you have to be sure to do what you want.
From this thread:
Two rules to live by that I know of no exceptions:
Always use blocking assignments for combinatorial or level-sensitive code, as well a clock assignments
Always use non-blocking assignments for variables that are written on a clock edge, and read on the same clock edge in another process.
assign and corresponding deassign (in always blocks) are also called 'procedural continuous assighment' can be used in always blocks for specific purposes. In most cases this is non-synthesizable and I had never ran across its use.
an example:
reg in1, in2, out;
reg [1:0] select;
always #* begin
case (select)
2'b01: assign out = in1;
2'b10: assign out = in2;
2'b11: deassign out;
endcase // case (select)
end
general recommendateion -- do not use it.
I'm using Verilog for programming a FPGA.
I have my top module and I would like to call a Task which contains an always block.
The Task is a routine for serializing a byte in UART. (inputs: baudrate_clk, bytetosend ; output: TxD which is the physical output pin)
module serial();
task serial;
input baudrate;
input [7:0] data;
output TxD;
reg [3:0] state;
begin
always #(posedge baudrate) begin
case(state)
// ...
endcase
end
end
always #(state[2:0]) begin
case(state[2:0])
// ...
endcase
end
assign TxD ...
end
endtask
endmodule
I get a unexpected token: 'always' at the first always, always #(posedge baudrate) begin
I read Task could include wait, posedge etc...
If I cannot use Taks, what can I use for this purpose ?
Thank you.
Either your task should be a module or you should use a loop inside your task. It's difficult to see your design intent, but it looks to me that you needed a module in this case, not a task.
Tasks contain sequential code, just like an always block does. A task is just another place to put the kind of code that can go inside an always block. It makes no sense to put an always block inside a task.
I am trying to make a module that performs the twos complement of a value if the msb is 1. It works in cadence, however when I try to synthesize it I get the following error:
Cannot test variable X_parallel because it was not in the event expression or with wrong polarity.
The code for the module is as follows:
module xTwosComp (X_parallel, Clk, Reset, X_pos);
input [13:0] X_parallel;
input Clk, Reset;
//wire X_msb; //was an attempt at fixing the problem
output [13:0] X_pos;
reg [13:0] X_pos;
//assign X_msb=X_parallel[13];//failled attempt at fixing
always # (posedge Clk or posedge Reset)
begin
if (X_parallel[13]) begin
X_pos = ~(X_parallel) +1;
end else begin
X_pos = X_parallel;
end
end
endmodule
You are missing your reset statement. Not sure if this fixes the exact error, but synthesizers expect code to determine what events are asynchronous when there is more than one edge event.
You need an if (Reset) begin X_pos <= 14'b0; else before the if (X_parallel[13]). Otherwise posedge Reset is treated as another clock and not a asynchronous reset. This will confuse the synthesizer.
FYI: flops should be assigned with non-blocking assignments (<=). It will save you from debugging false race condition and RTL to gates simulation mismatches.
After countless hours I have figured it out. It was because i was not referencing Clk or Reset in my always block.
Thanks to anyone who considered the issue.
Thanks Greg for your answer, although I figured out how to make it work I am very glad for your response since it cleared up why it works now. Thanks!