Always in a task? - verilog

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.

Related

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 execution during startup

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

what will be the output of the following verilog code..?

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.

Syntax error near "generate" and "endgenerate" in verilog

I am new in Verilog and I am trying to implement single precision floating point addition-subtraction using verilog. I am getting an error which I am unable to correct. Can anyone please help me?
module addModule(Rs,Re,Rm,As,Ae,Am,Bs,Be,Bm);
//Declarations of ports
Rs,Re,Rm;
As,Bs;
input [7:0] Ae,Be;
input [22:0] Am,Bm;
reg [7:0] Re;
reg [22:0] Rm;
reg Rs;
//wire declarations.
wire [23:-1] C;
assign C[-1] = 0;
wire [23:1] sum;
//variable declaration.
genvar count;
always #(*)
begin
//Add two mantissas.
if ((As^Bs)==0)
begin
generate //getting error here "Syntax error near "generate"."
for(count=0;count<24;count=count+1)
begin
add add_1(.c_out(C[count]),.sum(sum[count]),.in1(tempAm[count]),.in2(tempBm[count]),.c_in(C[count-1]));
end
endgenerate //syntax error near "endgenerate"
end
else
begin
generate //Syntax error near "generate".
for(count=0;count<24;count=count+1)
begin
subtract sub_1(.c_out(C[count]),.dif(sum[count]),.in1(tempAm[count]),.in2(tempBm[count]),.c_in(C[count]));
end
endgenerate //Syntax error near "endgenerate".
end
end
endmodule
Thanks in advance. :)
In Verilog, when you are instantiating a module, that means you are adding extra hardware to the board.
This hardware must be added before simulation starts(i.e. at compile time). Here, you can not add/remove hardware at each clock pulse.
Once instantiated, the module is executed/checked for each timestamp of simulation, till the end.
So to execute any module, just instantiate it, providing the clk and other required inputs to it, and add the always block in the sub-module itself.
Once the hardware is instantiated, it shall be executed according to the logic inside it, for entire life time.
Here you are instantiating module at wrong place. The use of generate block must be done outside any procedural blocks.
// generate outside any other blocks
generate
for(count=0;count<24;count=count+1)
begin
add add_1(.c_out(C[count]),.sum(sum[count]),.in1(tempAm[count]),.in2(tempBm[count]),.c_in(C[count-1]));
end
endgenerate
always #(*)
begin
// Other stuff here.
end
If you want to manipulate input signals of the subtract sub_1 module, simply manipulate C,sum and other variables declared in addModule module. Since they are connected, the change shall reflect in subtract sub_1 module too.
For more information on generate block, refer Module Instantiation, Generate block example and a similar question links.

Error while using always block in verilog

I have a module temp1 in verilog say as below,-
module temp1;
---
---
---
endmodule
I want to call this module instance from other module temp2. However, I want to this laways at the positive edge of the clock-
module temp2(clk);
input clk;
always #(posedge clk)
temp1 t1;
endmodule
This gives me syntax error. It seems I should not call any module from within the always block. Is it true that we cannot create instance of a module from within the always block? If yes, how can I do this in some other way as I have to call temp1 only when at the posedge of the clock?
In verilog, when you are instantiating a module, that means you are adding extra hardware to the board.
This hardware must be added before simulation starts(i.e. at compile time). Here, you can not add/remove hardware at each clock pulse.
Once instantiated, the module is executed/checked for each timestamp of simulation, till the end.
So to execute any module, just instantiate it, providing the clk and other required inputs to it, and add the always block in the sub-module itself.
module temp2(clk);
input clk;
temp1 t1(clk); // note the input port clk here
endmodule
module temp(input clk);
always #(posedge clk)
begin
// ...
end
endmodule
Verilog provides a generate block for creating multiple instances of the same module.
genvar i; // note special genvar type, used in generate block
generate
for(i=0;i<5;i++)
temp t1[i]; // create 5 instances of temp module
endgenerate
Side Note:
You may have mixed the understanding about module instantiation and calling of task/function. Module is a static entity while task/function can be dynamic ones. As you showed, if temp is a task, then the above call is valid.
task temp;
// ...
endtask: temp
module temp2(clk);
input clk;
always #(posedge clk)
temp1(); // task/function temp
endmodule
More information on instantiation can be obtained from Verilog Module Instantiation, Instantiating Modules and Primitives, Structural Modelling links.

Resources