Search code examples
verilogfpgabit-shiftmultiplication

Shift-add multiply function producing syntax errors


I have some code as follows:

module trapverilog(
    input CLK,
     input signed [7:0] SIGNAL,
     input signed [7:0] x,
     input signed [7:0] SUM, // OUT pins are mapped to SUM pins on board
    output reg OUTP,
     output reg OUT1,
     output reg OUT2,
     output reg OUT3,
     output reg OUT4,
     output reg OUT5,
     output reg OUT6,
     output reg OUT7
    );

reg[7:0] yregone;
reg[7:0] yregtwo;
reg[7:0] innerSumOutput;
reg[7:0] innerSignal;
reg[7:0] innerSum;

function [7:0] multiply;
input [7:0] a;
input [7:0] b;
wire [15:0] a1, a2, a3, a4, a5, a6, a7, a8;
assign a1 = (b[0]==1'b1) ? {8'b00000000, a} : 16'b0000000000000000;
assign a2 = (b[1]==1'b1) ? {7'b0000000, a, 1'b0} : 16'b0000000000000000;
assign a3 = (b[2]==1'b1) ? {6'b000000, a, 2'b00} : 16'b0000000000000000;
assign a4 = (b[3]==1'b1) ? {5'b00000, a, 3'b000} : 16'b0000000000000000;
assign a5 = (b[4]==1'b1) ? {4'b0000, a, 4'b0000} : 16'b0000000000000000;
assign a6 = (b[5]==1'b1) ? {3'b000, a, 5'b00000} : 16'b0000000000000000;
assign a7 = (b[6]==1'b1) ? {2'b00, a, 6'b000000} : 16'b0000000000000000;
assign a8 = (b[7]==1'b1) ? {1'b0, a, 7'b0000000} : 16'b0000000000000000;
multiply = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
endfunction

always @(posedge CLK)
begin
    yregtwo <= yregone;
    yregone <= innerSignal;

    if (yregone != 0)
    begin
        innerSum <= multiply((yregone + yregtwo), x); //treats x as plain h, change if treated as h/2 // multiply defined by function shift-adds
        innerSumOutput <= (innerSum <<< 1) + innerSum; // <<< is signed one bit shift which = /2
        if (innerSumOutput[0] == 1)
        begin
            OUTP <= 1;
        end

        OUT1 <= innerSumOutput[1];
        OUT2 <= innerSumOutput[2];
        OUT3 <= innerSumOutput[3];
        OUT4 <= innerSumOutput[4];
        OUT5 <= innerSumOutput[5];
        OUT6 <= innerSumOutput[6];
        OUT7 <= innerSumOutput[7];
    end
end

endmodule

The basic purpose of the code is to perform the trapezoidal integration method. The code compiled until I added the multiply function, which is a shift-add multiply function. I changed this because I was told in chat that * wouldn't work properly on an FPGA. I read a bit and found this method, but it could very well be an X-Y problem there.

I adapted the function from this module I found and then changed it into a function following the examples here. The errors the program is producing look like a selection of syntax errors mixed in with complaints about "procedural continuous assignments":

ERROR:HDLCompiler:806 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 45: Syntax error near "wire".
ERROR:HDLCompiler:1366 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 42: Multiple statement function/task without begin/end not supported in this mode of Verilog
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 46: <a1> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 46: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 47: <a2> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 47: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 48: <a3> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 48: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 49: <a4> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 49: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 50: <a5> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 50: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 51: <a6> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 51: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 52: <a7> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 52: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 53: <a8> is not declared.
ERROR:HDLCompiler:1673 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 53: Automatic variable a is not allowed in procedural continuous assignments
ERROR:HDLCompiler:69 - "/home/ise/FPGA/trapezoid/trapverilog.v" Line 54: <a1> is not declared.

I am fairly new to programming Verilog and am rather unsure what the problem is. I am also unsure as to whether or not this will work with signed numbers. Any help would be appreciated. Thanks!


Solution

  • You cannot declare wires inside a function. Use reg instead.

    Do not use assign inside a function.

    See my blog for more details about the difference between wires and regs.