0
\$\begingroup\$

I need to implement this code to synthesize and do so that xor21 and and21 will work separately.

module top(
 input a, b, x,
 output c
);

always @(a or b or x)
begin
    if(x)
       xor21 x1 (.a(a), .b(b), .c(c));
   else
      and21 a1 (.a(a), .b(b), .c(c));
end
endmodule

However, I get the following error:

ERROR:HDLCompiler:1575 Instantiation is not allowed in sequential area except checker instantiation

How do I go about designing this?

\$\endgroup\$
4
\$\begingroup\$

You need to go back to basics.

Verilog is a hardware description language, not a programming language. Your code is describing hardware.

Let's see what your code is trying to infer:

module top(
 input a, b, x,
 output c
 );

Ok, we have a module. That's all fine. Now what does it do?

always @(a or b or x)
begin
    if(x)
       xor21 x1 (.a(a), .b(b), .c(c));
   else
      and21 a1 (.a(a), .b(b), .c(c));
end

That code says "Whenever a, b, or x changes: If x is high, instantiate a new piece of hardware called xor21, otherwise instantiate a different piece of hardware called and21".

Hmm, that means that if the value of x changes, bits of your hardware suddenly disappear, and other bits of hardware appear from nowhere. This cannot happen. The whole design needs to be known when the design is synthesized.

In otherwords, you cannot instantiate a module in a procedural block.


Instead, you need to think about what you hardware you need. You decide, well I need an and21 module, and an xor21 module. So lets instantiate one of each:

module top(
 input a, b, x,
 output c
 );

 wire xor21_output;
 wire and21_output;

 xor21 x1 (.a(a), .b(b), .c(xor21_output));
 and21 x1 (.a(a), .b(b), .c(and21_output));

Cool. Now we have a our module, and it contains our two submodules. Now we need to work out the behaviour of the output c.

Well, if x is high, we want the output from xor21, and if x is low, we need the output from and21. So that means we need a multiplexer. Well, we can either do this in continuous assignment using the ternary operator (?), or we can use an always block. Let's look at both. First the ternary:

assign c = x ? xor21_output : and21_output;

Then the always block (see note):

always @ (x) begin
    if (x) begin
        c = xor21_output;
    end else begin
        c = and21_output; 
    end
end

And voila. We now have a module with the required behaviour, in which the required hardware is known when the design is synthesised.


(note) - if you are assigning a value in an procedural block (such as always or initial), the target must be a storage type, such as reg. You cannot assign a wire type in a procedural block. So we would have to change the module definition to output reg c.

\$\endgroup\$
  • \$\begingroup\$ I want that xor21 and and21 will work separately \$\endgroup\$ – Andranik Avetisyan Sep 1 '18 at 20:51
  • \$\begingroup\$ You can't. The best you can have is a logic block with three inputs a,b and x which implement the function. For that you can try assign c = x?a^b:a&b; An FPGA will use a single LUT to make that. \$\endgroup\$ – Oldfart Sep 1 '18 at 20:56
  • \$\begingroup\$ @AndranikAvetisyan you cannot have hardware suddenly change. It would be like having a switch that desoldered an IC from a circuit board and then soldered a different one in. Instead you must have all hardware present already, and can then simply switch between them. \$\endgroup\$ – Tom Carpenter Sep 1 '18 at 20:59
  • \$\begingroup\$ In fact both the design above, and the one-liner @Oldfart suggested, will both end up compiling into a single lookup table in the FPGA anyway. \$\endgroup\$ – Tom Carpenter Sep 1 '18 at 20:59
  • \$\begingroup\$ there is the only example in large design that bad version. can I use `define or (i don't know everything ) for solved that issue because in IC design that possible \$\endgroup\$ – Andranik Avetisyan Sep 1 '18 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.