0
\$\begingroup\$

I have to build a circuit of an arithmetic right shift operator in verilog and include it in a verilog code of a simple computer. I've written the code of the circuit with a module and it compiles without an error but when I try to include it in the code of the computer(it has to be in an if-statement) an error occurs: "error: syntax error, unexpected MODULE" is it possible to include a module in an if-statement?

 always @(alu_A or alu_B or aluop)
if      (aluop==0)    alu <= alu_A;
else if (aluop==1)    alu <= alu_A + alu_B;
else if (aluop==2)    alu <= alu_A - alu_B;
else if (aluop==3)    alu <= alu_A & alu_B;
else if (aluop==4)    alu <= alu_A ^ alu_B;
else if (aluop==5)    alu <= alu_A << alu_B[3:0];
//else if (aluop==6)    alu <= right_shift(alu_A, alu_B[3:0]);
else 
 begin
 module right_shift (alu_A,alu_B,alu);
input [15:0] alu_A;
input [3:0] alu_B;
output [15:0] alu;

this is a piece of the code: the comment is the old piece of code where right shift is done everything beneath are the changes i've done. I did not comment the whole code because it is very big

\$\endgroup\$
  • \$\begingroup\$ You are describing hardware, not writing software. Modules are hardware, you can't instantiate them conditionally with if statements (*). \$\endgroup\$ – Tom Carpenter May 9 '17 at 16:25
  • 2
    \$\begingroup\$ Think about what it would describe. If a signal is high, make some hardware appear, otherwise delete the hardware. FPGAs can't work like that. All hardware is described and fixed at synthesis. \$\endgroup\$ – Tom Carpenter May 9 '17 at 16:26
  • \$\begingroup\$ You could make your right shift code a function, in which case you can call it like the commented out line. This would infer the hardware always being there, but it's output feeds an implicit multiplexer. \$\endgroup\$ – Tom Carpenter May 9 '17 at 16:28
  • \$\begingroup\$ Alternatively instantiate your module not in an if statement, connect its output to a wire, and then use that wire in the if statement. This is basically what a function would infer. \$\endgroup\$ – Tom Carpenter May 9 '17 at 16:30
  • \$\begingroup\$ I'll convert all my comments to a proper answer when I get home. On my phone at the moment. \$\endgroup\$ – Tom Carpenter May 9 '17 at 16:31
1
\$\begingroup\$

It is important to remember that with Verilog you are describing hardware, not writing software. Modules are instances of hardware. They can't be called and they don't return a value.

You can't instantiate a module conditionally within an if statements (*), and you definitely can't instantiate them within procedural blocks. If you consider what such a statement would describe it becomes clear as to why not. With a module instantiation within an if statement you are basically saying:

If signal is high, make some hardware appear; otherwise delete the hardware.

FPGAs can't work like that. All hardware is described and fixed at synthesis.

Instead what you need to do is instantiate your hardware (in this case right shift module) not within the if statement or procedural block. Connect the output of that module to a wire. Now your hardware is always present, regardless of the control signals. So how do you make use of it conditionally?

This is quite simple. Within the if statement you can use your wire. If a condition is met assign the wire to whatever signal you are controlling. Otherwise assign some other signal.

wire module_output_wire;
...
always @ (...) begin
    ...
    if (some_condition) begin
        some_signal <= module_output_wire;
    end else begin
        some_signal <= something_else;
    end
end
...
your_module (
    .whatever(module_output_wire)
);

The reason this now works is because rather than trying to infer transient hardware, you are now inferring a simple multiplexer. The inputs to the multiplexer are the module_output_wire and something_else, the select signal is some_condition, and the output of the multiplexer is some_signal. The hardware always exists, but you don't always need to use the output value.

As an alternative, you could make your right shift code a function. A function in Verilog can be called in the way you show on the commented out line in your code. In the case of the function you are inferring hardware that is always there and the output of the hardware is a wire (the return value of the function) which you can then use in an always block.


(*) With the exception of in Verilog 2001 Generate statements, but in that case the condition is known at compile time, it doesn't depend on the value of a signal.

\$\endgroup\$
0
\$\begingroup\$

Use mulitplexers to select different busses (or op codes), all hardware you are using needs to be there when you compile, FPGA's can't change their hardware on the fly (yet).

If you really want to select between different hardware modules then you can use the equivalent of a #define in C to select what hardware gets compiled. But the selection can only happen before compiling.

conditional_compilation_directive ::=
ifdef_directive
| ifndef_directive
ifdef_directive ::=
`ifdef text_macro_identifier
ifdef_group_of_lines
{ `elsif text_macro_identifier elsif_group_of_lines }
[ `else else_group_of_lines ]
`endif


ifndef_directive ::=
`ifndef text_macro_identifier
ifndef_group_of_lines
{ `elsif text_macro_identifier elsif_group_of_lines }
[ `else else_group_of_lines ]
`endif

More info about this from This PDF.

\$\endgroup\$

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.