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
An assignment in an Always Construct in a Verilog Design File (. v) that places a value on a Verilog HDL register or an integer. A Procedural Assignment can either be blocking or non blocking.
In always blocks, you should only use non-blocking assignment('<=') which are procedural assignments. Using blocking assignment is possible, however, you have to be sure to do what you want.
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
assignanddeassignstatements can be a source of design errors and can be an impediment to tool implementation. The proceduralassignanddeassignstatements do not provide a capability that cannot be done by another method that avoids these problems. Therefore, the proceduralassignanddeassignstatements 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 proceduralassignanddeassignstatements. 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
You are assigning to result inside an always block, which is not allowed, because result is a wire, not a reg.
Declare result as follows to make it work:
output reg [63:0] result;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With