Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Module not a task or void function

I am trying to create a module for carry select adder in Verilog. Everything works fine except the following portion where it is causing compilation error.

module csa(a,b,s,cout);
input[15:0] a,b;
output [15:0] s;
output cout;
wire zero_c1, zero_c2,zero_c3,zero_c4,zero_c5;
wire one_c1, one_c2,one_c3,one_c4,one_c5;
wire temp_c1,temp_c2,temp_c3,temp_c4,temp_c5;
wire [15:0] s_zero, s_one;

initial
begin
fork
    fa(s[0], temp_c1,a[0],b[0],0);
    fa_one(s_zero[1],s_one[1],zero_c1,one_c1,a[1],b[1]);
    fa_two(s_zero[3:2],s_one[3:2],zero_c2,one_c2,a[3:2],b[3:2]);
    fa_three(s_zero[6:4],s_one[6:4],zero_c3,one_c3,a[6:4],b[6:4]);
    fa_four(s_zero[10:7],s_one[10:7],zero_c4,one_c4,a[10:7],b[10:7]);
    fa_five(s_zero[15:11],s_one[15:11],zero_c5,one_c5,a[15:11],b[15:11]);
join
end

When I try to compile that, it says:

the module "fa", "fa_one" are not a task or void function

I deleted the initial statement, and now it says:

Syntax error near "fork", expecting "endmodule"

I just want to run the code between join and fork in parallel. I have also confirmed that the modules fa and fa_one work fine.

like image 309
DataEnthusiastic Avatar asked Jul 19 '26 14:07

DataEnthusiastic


2 Answers

Verilog modules are not run or executed but instantiated, they represent physical blocks of hardware.

Everything is in parallel unless you have made effort to time share pieces of hardware. For example you might write an ALU core, which exists only once but use a program ROM to tell it which instruction to process every clockcycle.

Inside your modules you can have combinatorial code and sequential code.

Combinatorial logic will simulate in 0 time but will actually take some time for values to propagate through when placed on real devices.

If this propagation delay is not thought about and very large blocks of logic are created you will struggle to close timing on synthesis, due to the settling time through the logic being greater than the clock speed either side of the combinatorial logic.

Sequential logic implies that the results are held in flip-flops, which only update on clock edges. This means chains of sequential logic can take many clock cycles for data to propagate.

When pipelining a processor you break individual section up with flip-flops giving each section a full clock cycle for combinatorial propagation, at the expense of taking several clock cycles to calculate a single result.

To correct your example you would just have:

module csa(
  input  [15:0] a,
  input  [15:0] b,
  output [15:0] s,
  output        cout
);
wire zero_c1, zero_c2,zero_c3,zero_c4,zero_c5;
wire one_c1, one_c2,one_c3,one_c4,one_c5;
wire temp_c1,temp_c2,temp_c3,temp_c4,temp_c5;
wire [15:0] s_zero, s_one;

fa       ufa(s[0], temp_c1,a[0],b[0],0);
fa_one   ufa_one(s_zero[1],s_one[1],zero_c1,one_c1,a[1],b[1]);
fa_two   ufa_two(s_zero[3:2],s_one[3:2],zero_c2,one_c2,a[3:2],b[3:2]);
fa_three ufa_three(s_zero[6:4],s_one[6:4],zero_c3,one_c3,a[6:4],b[6:4]);
fa_four  ufa_four(s_zero[10:7],s_one[10:7],zero_c4,one_c4,a[10:7],b[10:7]);
fa_five  ufa_five(s_zero[15:11],s_one[15:11],zero_c5,one_c5,a[15:11],b[15:11]);
endmodule

NB: it is module_name #(parameters) instance_name ( ports );

like image 130
Morgan Avatar answered Jul 22 '26 03:07

Morgan


fork is used to run procedural statements within a module in parallel. Separate module instances always run in parallel.

Child modules are instantiated directly within their parent module, not within an initial, begin, or fork which are used for procedural statements. So you can remove the initial, begin, fork, join, and end, and add an endmodule at the end.

like image 36
mark4o Avatar answered Jul 22 '26 03:07

mark4o



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!