Search code examples
verilog

Why do I get an error calling a module in an always block?


I have a module temp1 in Verilog as below:

module temp1;
---
---
---
endmodule

I want to call this module instance from other module temp2. However, I want to this always at the positive edge of the clock-

module temp2(clk);
    input clk;
    always @(posedge clk)
        temp1 t1;
endmodule

This gives me a 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?


Solution

  • 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.