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?
Best Answer
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:
Ok, we have a module. That's all fine. Now what does it do?
That code says "Whenever
a
,b
, orx
changes: Ifx
is high, instantiate a new piece of hardware calledxor21
, otherwise instantiate a different piece of hardware calledand21
".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 anxor21
module. So lets instantiate one of each: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 fromxor21
, and ifx
is low, we need the output fromand21
. 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:Then the always block (see note):
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 awire
type in a procedural block. So we would have to change the module definition tooutput reg c
.