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.
Related
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.
I have implemented valid/ready handshake signals in verilog. I just wanted to know if my approach is right or something is wrong. I shall be happy to know of any improvement.
A simple counter is used as an input to fifo. So when fifo is almost full which is declared when used word of fifo is 8 (8 stacks of fifo are used out of 16), ready is zero.
Here is the code.
module fifohandshake(
input CLK,
input RST,
input [31:0] INPUT,
output [31:0] OUTDATA,
output [3:0] usedword,
output Writereq,
input RDReq,
output Almost_full,
output EMPty,
output FUlL,
output VALID,
output READY
);
reg valid;
reg ready;
reg WRReq;
assign VALID=valid;
assign READY=ready;
assign Writereq=WRReq;
fifoip u0(
.clock(CLK),
.data(INPUT),
.rdreq(RDReq),
.sclr(RST),
.wrreq(WRReq),
.almost_full(Almost_full),
.empty(EMPty),
.full(FUlL),
.q(OUTDATA),
.usedw(usedword)
);
always #(posedge CLK)
begin
if(INPUT)
begin
valid<=1;
end
else
begin
valid<=0;
end
end
always #(posedge CLK)
begin
if(Almost_full)
begin
ready<=0;
end
else
begin
ready<=1;
end
end
always #(posedge CLK)
begin
if(ready)
begin
WRReq<=1;
end
else
begin
WRReq<=0;
end
end
endmodule
Have I done it in a right way or is there something that I need to correct? Here are the waveform results.
enter image description here
For those who think that I didn't put enough effort in my research. A finite state machine is a good approach to implement ready/valid handshake protocol. Few points have to be kept in mind
The valid signal doesn't depends upon ready signal. In other words there shouldn't be a combinational loop if you trace your logical circuit from valid to ready signal.
Three basic states can be defined for valid/ready protocol. First idol state where there is no valid data even though the slave is ready to accept data. Then, a transfer state where both ready and valid signals are high. And the third state is wait state where we have the valid signal high but ready signal is low.
A buffer (a fifo or a simple register) has to be used in the wait state to buffer the valid data in case the slave is no ready. Hence, data is not lost and is still on the data line whenever slave is again ready.
That's it....
This was the help that I was trying to ask from the community but from the last couple of days whenever I post something someone intentionally mark my question to be -1. I hope not to experience it next time...
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'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 just want to know the difference between this two statement
always #(posedge CLK)
begin
state <= next_state;
end
AND:
always #(CLK)
begin
case(CLK)
1'b1:
state <= next_state;
1'b0:
state <= state;
end
Is there a difference between both ?
Thanks
Not quite. posedge detects these transitions (from the LRM):
Table 43—Detecting posedge and negedge
To 0 1 x z
From
0 No edge posedge posedge posedge
1 negedge No edge negedge negedge
x negedge posedge No edge No edge
z negedge posedge No edge No edge
So, 0->x is a posedge, for example. Your second example only detects cases where CLK ends up as 1, so misses 0->x and 0->z.
The IEEE Std. 1364.1(E):2002 (IEC 624142(E):2005), the Verilog register transfer level synthesis standard, states in Sec. 5.1 that an always block without any posedge/negedge events in the sensitivity list is combinational logic. I.e. the signals in the event list are ignored and the block is synthesized as if an implicit expression list (#(*), #*) was used. The following example is given in the standard ("Example 4" on page 14):
always # (in)
if (ena)
out = in;
else
out = 1’b1;
// Supported, but simulation mismatch might occur.
// To assure the simulation will match the synthesized logic, add ena
// to the event list so the event list reads: always # (in or ena)
(the comment is also copied from the standard document)
I.e. for a synthesis tool your second block is effectively:
always #*
begin
case(CLK)
1'b1:
state <= next_state;
1'b0:
state <= state;
end
which is just a multiplexer with CLK as select input, next_state as active-1 input and the output (state) fed back as active-0 input. A smart synthesis tool might detect that this is identical to a d-type latch with CLK as enable-input and create a d-type latch instead of a combinational loop. Note that the synthesis tool is not required to detect this latch because the code explicitly assigns state in all branches (compare Sec. 5.3. of the standard).
Either way this is different from the d-type flip-flop your first code example would synthesize to. This is one of many cases where Verilog-code has different meaning in simulation and synthesis. Therefore it is important to (1) write synthesizeable Verilog code in a way that avoids this cases and (2) always run post-synthesis simulations of your design (even if you are also using formal verification!) to make sure you have successfully avoided this pitfalls.
Functionally, those two circuits describe the same behavior in verilog, so I think there should be no difference.
However you should generally use the first style, as that is the one that is standard for writing synthesizable code, and most understandable by anyone else reading your code. The latter style, while describing the correct behavior, may confuse some synthesizers that don't expect to see clocks that are both sensitive to positive and negative edge.
The two blocks are VERY different.
The top one gives you a flip-flop while the bottom one gives you a latch with a multiplexer with the CLK as the select signal.
The critical difference between the two blocks is that the top one is a synchronous block i.e. the posedge clk part while the bottom one is asynchronous with the CLK level, not edge.
A verilog simulator could do left-hand sampling of CLK, effectively making the the case(CLK) version the same as a negedge CLK flop. Otherwise the simulator will treat it like a posedge CLK flop. It really depends how it is handled in the scheduler of specific simulator (or how a particular synthesizer will process it).
The most common codding styles all use the first condition. It is explicitly clear to the synthesizer and anyone reading the code that state is intended to be a flip-flop with a positive edge clocking trigger.
There is also a simulation performance differences. The posedge CLK performances 2 CPU operations every clock period, while the case(CLK) will perform 6 CPU operations every clock period. Granted in this example the differences is insignificance, but in large designs the poor coding used everywhere will add up to hours of simulation time wasted.