Reg Cannot Be Driven by Primitives or Continuous Assignment

Table of Contents

Simple guide to Verilog Wire and Reg types

The aim of this article is to help clear any confusion for beginners when using verilog wire and reg data types between modules. We'll start with the basic rules for both.

The simple wire rules are:

  1. A wire from an outer module can be connected to the input or output of an inner module.

The simple reg rules are:

  1. A reg can be used as input to an inner module.

  2. In an inner module, a reg can be used as an output, but not as an input.

  3. A reg in an outer module cannot be connected to the output reg of an inner module. This rule can seem confusing.

This illustration will help show what connections are possible:

Testing simple wires between modules

The verilog for two simple modules to demonstrate connecting wires are:

`include            "innermodule.v"            module            top;            wire            w_inputForInnerModule;            wire            w_outputFromInnerModule;            InnerModule innermodule            (            .i_inner_input(w_inputForInnerModule)            ,            .o_inner_output(w_outputFromInnerModule)            )            ;            endmodule          
            module            InnerModule            (            input            i_inner_input,            output            o_inner_output            )            ;            assign            o_inner_output            =            i_inner_input;            endmodule          

The InnerModule simply connects its input to the output and the top level module has two internal wires that connect to InnerModule's input and output ports but that is all. The wire values are indeterminate, and the design is of little practical use. But it does demonstrate how wires can be connected between modules.

However, we need more than wires. We need reg variables for our logic and processing so that we can eventually pass this information to wires.

More rules for a wire and reg data types

More rules for wire data types:

  1. Only wires can be assigned to using the assign statement. They are continuously connected.

  2. Wires can't store information. They have no state.

  3. Wires cannot be assigned a value in an always block.

More rules for reg data types:

  1. A reg can store information.

  2. Only a reg can be assigned a value in an always block.

  3. A reg cannot be continually assigned to using the assign statement.

  4. A reg can continually pass to a wire using assign.

  5. Reg can be used to create both combination and sequential logic.

That's a lot to take in. Let's work through them:

Reg In / Wire Out

Let's try the case where we have a reg in the outer module that is initialised to 1 and is connected to the input of the inner module.

`include            "innermodule.v"            module            top;            reg            r_inputForInnerModule            =            1'b1            ;            wire            w_outputFromInnerModule;            InnerModule innermodule            (            .i_inner_input(r_inputForInnerModule)            ,            .o_inner_output(w_outputFromInnerModule)            )            ;            endmodule          
            module            InnerModule            (            input            i_inner_input,            output            o_inner_output            )            ;            assign            o_inner_output            =            i_inner_input;            endmodule          

And I guess I should supply a small testbench to prove that the output from the inner module was collected from the reg in the outer module:

            `timescale            1ns            /            1ns            `include            "top.v"            module            top_tb;            top top_test            (            )            ;            initial            begin            $dumpfile            (            "top_tb.lxt"            )            ;            $dumpvars            (            0            ,top_tb)            ;            end            initial            begin            #            20            $finish            ;            end            endmodule          

See FPGA Verilog simulation using GTKWave if you need help setting up testbenches for use in GTKWave simulations.

You can see above that the reg that contained the value of 1'b1 has set the wire w_outputFromInnerModule to HIGH. Nice.

A module's output reg cannot connect to a reg in the outer module

It is quite possible to pass back an output reg from a module. But it has to connect to a wire. So let's begin with some code attempting to do the wrong thing with the inner module. We can't just use:

            //bad InnerModule            module            InnerModule            (            input            i_inner_input,            output            reg            o_inner_output            =            1'b0            )            ;            assign            o_inner_output            =            i_inner_input;            endmodule          

This will give us an error of: reg o_inner_output; cannot be driven by primitives or continuous assignment.

We cannot use the assign statement to wire two regs together. But we can change the value of the output reg whenever i_inner_input changes using the always block:

            module            InnerModule            (            input            i_inner_input,            output            reg            o_inner_output            =            1'b0            )            ;            always            @            (i_inner_input)            begin            o_inner_output            <=            i_inner_input;            end            endmodule          

Let's come up with an outer module that tries to connect a reg to the output reg of the inner module. Can we do it?:

            //bad top module            `include            "innermodule.v"            module            top;            reg            r_inputForInnerModule            =            1'b1            ;            reg            r_outputFromInnerModule            =            1'b0            ;            InnerModule innermodule            (            .i_inner_input(r_inputForInnerModule)            ,            .o_inner_output(r_outputFromInnerModule)            )            ;            endmodule          

We get an error from iverilog stating: reg r_outputFromInnerModule; cannot be driven by primitives or continuous assignment.

Same deal.

So going back to the original rule we wanted to test: no we can't connect the reg to the output reg of an inner module. We must connect to a wire in the outer module. Therefore, the correct way is to go with this instead:

`include            "innermodule.v"            module            top;            reg            r_inputForInnerModule            =            1'b1            ;            wire            w_outputFromInnerModule;            InnerModule innermodule            (            .i_inner_input(r_inputForInnerModule)            ,            .o_inner_output(w_outputFromInnerModule)            )            ;            endmodule          

And this will be fine. Again, let's test it using the testbench from before:

It actually ends up being the same simulation result. Interesting right?

You can see the reg was initialised to 1 which made the output equal to 1. This output set w_outputFromInnerModule to HIGH. Fantastic stuff.

If you ever find yourself unsure, always refer to the illustration at the start for a reminder of who can go where.

I would love to hear if this helps you out. Feel free to use the contact link at the top to say hi.

Additional references

gregoryalard1959.blogspot.com

Source: https://blog.waynejohnson.net/doku.php/verilog_wire_and_reg

0 Response to "Reg Cannot Be Driven by Primitives or Continuous Assignment"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel