Verilog always block execution during startup - verilog

I have an always block in verilog as shown below. All the input signals inside always block are not stable until startup time say 50ns. I don't want to execute the always block until start up time is reached. What is the best to achieve this functionality? Thanks.
always begin
//functional code
#10
end

Use an initial block
initial #50ns forever begin /* functional code */ #10; end
or for combinational logic, use
initial #50ns forever #* begin /* functional code */ end

Related

$fclose placement in testbench

I want to use $fmonitor so that an output value is written to a file every time the value changes.
When I place $fclose inside the initial begin block, there are no errors. However, unsurprisingly, the output file is empty.
When I place $fclose right before the endmodule statement, I get a syntax error. Where should I place it?
`timescale 1ns / 1ps
module fir168_input_ones_tb();
integer fp;
reg clk, rst;
wire tvalid, fir_valid, fir_rdy;
wire [15:0] inputdata;
wire signed [39:0] fir_out;
generateOnes indata(
.clk (clk),
.outData (inputdata),
.tlast (tvalid));
fir168 fir168_i
//(.M_AXIS_DATA_0_tdata(fir_out_trunc),
(.M_AXIS_DATA_0_tdata(fir_out),
.M_AXIS_DATA_0_tvalid(fir_valid),
.S_AXIS_DATA_0_tdata(inputdata),
.S_AXIS_DATA_0_tready(fir_rdy),
.S_AXIS_DATA_0_tvalid(tvalid),
.aclk_0(clk));
always begin
clk = ~clk; #5;
end
initial begin
fp = $fopen("simOutput.txt", "w+");
$fmonitorh(fp, fir_out);
clk = 0;
//$display("%d", fir_out);
//$fclose(fp);
end//initial
$fclose(fp);
endmodule
$fopen/$fmonitor/$fclose are all procedural statements that must be placed inside procedural code.
When you had $fclose in the initial block, you closed it at time 0 before $fmonitor had a chance to produce any output. $fmonitor writes the state of its arguments at then end of current time slot when any of them change value.
You need to let your simulation run for some period of time and then have it execute a $finish. There is no need to explicitly use $fclose unless you have too many files open at one time, or some other process is blocked waiting for the file output.
$fclose must be used inside a procedural block, like an initial block. That is why you get the syntax error when you place it right before endmodule.
If you want the file to be written until the end of the simulation, there is no need to call $fclose. The file will automatically be closed at the end of the sim.
Otherwise, you need to pick a specific time or a signal event and then close the file. But, keep in mind that $fmonitor will be active for the entire simulation. That means that if fir_out changes after you close the file, your simulator might generate error or warning messages.
$fmoniotor statement does not do much, except it schedules monitor events at the end of every simulation tick. As a result, the $fclose will close the file in the same time tick where $fmonitor was issued before the first execution of a scheduled monitor event.
initial begin
$fmonitor(...);
...
$fclose()
end
You can do several things:
Put a certain timing distance between $fmonitor and $fclose, giving a chance for simulation to do something before the file gets closed:
initial begin
$fmoniotor(..);
...
#1000 // add a simulation delay of some value before closing
$fclose(...);
end
you can place $fclose in the final block if you want to close it before exit:
initial begin
$fmonitor(...);
...
end
final begin
...
$fclose(...);
end
Or you can figure out some event scheme which will close your file when a certain event is generated.
initial
$fmonitor
always #* begin
if (condition)
$fclose()
end

How is the program block controlling the clock output in this code?

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.

Verilog: always#* block not getting triggered

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.

Always in a task?

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.

Going back to initial statement on reset in verilog

I'm learning Verilog and I was wondering, is there a mean to go back to an initial statement in case of a reset? Something like the pseudo-code below:
initial begin
do initial stuff
end
always #(posedge clock) begin
if(reset)
go back to initial
else
do stuff
end
end
It will be a lot less typing if it was possible.
One way I can think of is to use a ROM and use the stored values again at reset.
You could use a task:
task init_stuff;
begin
/* do initial stuff */
end
endtask
initial begin
init_stuff;
end
always #(posedge clock) begin
if(reset) begin
init_stuff;
end else begin
/* do stuff */
end
end
However, for synthesizable code you should be very careful with "initial". Depending on your target architecture it can only be used to initialize ROMs (ASIC) or may create a circuit with very sensitive power-on reset behavior and other oddities (FPGA).

Resources