Drew Royster
Drew Royster

Reputation: 120

Verilog multiplication through repeated addition

I need help with a Verilog design I'm doing.

the idea is to do multiplication through repeated addition every time the M bit is set to 1/true. then I need to output that value. The assignment statement F=P; is throwing the error.

This is the error I'm getting

Error (10044): Verilog HDL error at Design2.v(13): expression cannot reference entire array "P"

It is my understanding that I can assign a register to an output if they are the same size. If I'm wrong then how can I implement this?

module Design2(A, N, M, F);

input A[7:0];
input N[3:0];
input M;
reg P[15:0];
output F[15:0];

always @(M) begin
    repeat(N) begin
    P = P + A;
    end
    F=P;
end

endmodule

Upvotes: 1

Views: 1945

Answers (1)

sharvil111
sharvil111

Reputation: 4381

Keeping apart the logic side, I can see two issues with your design.

  1. As the comments pointed out, you have used unpacked arrays at wrong place.

  2. Declaration of output port F.

For the first issue, the design needs a 16-bit vector for all the ports and variables. Here, the design takes a bunch of 8-bits as input A which must be declared as input [7:0] A, which is a packed array. Also, P needs to be a vector of size 16-bit in order to have contiguous operations.

This is to be done so that, when the statement P=P+A executes, the addition operation is done with all the variables taken with their respective sizes (size if P=16 and A=8). The overall addition is to be done with 16-bits, padding zeros in MSB side of A.

Hence, convert all the variables to packed array as follows:

  input [7:0] A;
  input [3:0] N;
  input M;
  reg [15:0] P;
  output reg [15:0] F;

For the second issue, the design assigns output in a procedural always block.

wire elements must be continuously driven by something, and cannot store a value. Henceforth, they are assigned values using continuous assignment statements.

reg can be used to create registers in procedural blocks. Thus, it can store some value.

When an input port is connected, it has to be driven through continuous assignments from parent module, hence input ports are always wire. While output from a module can be driven continuously through a wire, or can be driven through procedural assignments through reg. Following image shows the port connection rules.

Input/Output Declaration

To accomplish this in current design, the output port must be declared as output reg [15:0] F. This is the cause of compilation error shown.

Either way, you can have output [15:0] F with no reg and make continuous assignment to F as follows. This will synthesize F to wire:

output [15:0] F;
assign F=P;

SystemVerilog adds a logic datatype to remove confusion between usage of wire and reg declaration. A logic can be driven by both continuous assignment or blocking/non blocking assignment.

// Either continuous assignment
output logic [15:0] F;
assign F=P;

// Or procedural assignment
output logic [15:0] F;
// Inside always block
F=P;

For more information on packed and unpacked array, refer SystemVerilog Arrays link. Regarding port declarations, refer Wire and Net pdf. Refer SystemVerilog IEEE 1800-2012 for more information on logic datatype.

Upvotes: 1

Related Questions