I'm getting the error
[Synth 8-2576] procedural assignment to a non-register result is not permitted ["lpm_mult.v":29]
What am i doing wrong?
module lpm_mult (
dataa, datab, // multiplicand,multiplier
sum, // partial sum
clock, // pipeline clock
clken, // clock enable
aclr, // asynch clear
result // product
);
input clock;
input clken;
input aclr;
input [31:0] dataa;
input [31:0] datab;
input [63:0] sum;
output [63:0] result;
always @ (clken or posedge clock) begin
if (1==clken) begin
assign result = dataa * datab;
end
end
endmodule
There are more issues then then giving error message. As others have already pointed out result
should be defined as output reg [63:0] result;
The other issues will not generate a compiling error; they are generating incorrect behavior and are unsynthesizable. With the code:
always @ (clken or posedge clock) begin if (1==clken) begin assign result = dataa * datab; end end
clken
is asynchronous trigger; it should not be in the sensitivity list.An assign
statement inside the always block is call a procedural continuous assignment. Once the assignment is triggered, it will be continuously and immediately updated on any change to dataa
or datab
(ignoring the conditions of clken
and clock
).
Note: IEEE is considering depreciating procedural continuous assignment, so in the future it will likely become illegal syntax. IEEE Std 1800-2012 C.4.2 Procedural assign and deassign statements:
The procedural
assign
anddeassign
statements can be a source of design errors and can be an impediment to tool implementation. The proceduralassign
anddeassign
statements do not provide a capability that cannot be done by another method that avoids these problems. Therefore, the proceduralassign
anddeassign
statements are on a deprecation list. In other words, a future revision of IEEE Std 1800 might not require support for these statements. This current standard still requires tools to support the proceduralassign
anddeassign
statements. However, users are strongly encouraged to migrate their code to use one of the alternate methods of procedural or continuous assignments.
Regular continuous assignments (assign
outside of procedural block) will remain as legal legal syntax.
Verilog and SystemVerilog were officially merged by IEEE with IEEE Std 1800-2009.
Synchronous logic should use non-blocking (<=
) assignments. It is legal syntax to blocking (=
) assignments in synchronous logic blocks, but is it not recommenced. Using blocking assignments in synchronous logic blocks may cause race conditions in the simulator resulting in behavioral mismatch between RTL and synthesized circuit.
assign
statements must use blocking assignments (non-blocking is illegal syntax).Your code should look something line the following to compile and behave correctly in simulation:
...
output reg [63:0] result;
always @ (posedge clock) begin
if (clken==1) begin
result <= dataa * datab;
end
end