# Synthesizing error while designing 4-bit ALU in Verilog

I'm trying to design a 4-bit ALU which does the following functions:

I've written the below Verilog code, and the simulation is working fine without any errors.

timescale 1ns / 1ps

module alu_4_bit(

input M,
input S1,
input S0,
input C0,
input [3:0] A,
input [3:0] B,
output reg [3:0] F,
output reg Cout
);

reg Cout_temp; // Internal Variable //

always @(*)

begin

case({M,S1,S0,C0})

/* Logical Operations */

4'b0000,4'b0001,4'b000x : assign F = A & B;
4'b0010,4'b0011,4'b001x : assign F = A | B;
4'b0100,4'b0101,4'b010x : assign F = A ^ B;
4'b0110,4'b0111,4'b011x : assign F = ~(A ^ B);

/*Arithmetic Operations*/

4'b1000 : assign {Cout,F} = {4'b000,A};
4'b1001 : assign {Cout,F} = A+1;
4'b1010 : assign {Cout,F} = A+B;
4'b1011 : assign {Cout,F} = A+B+1;

/* When there's negation of any one data entry, Cout also gets negated */

4'b1101 :
begin
assign {Cout_temp,F} = A+(~B)+1;
assign Cout = ~ Cout_temp;
end

4'b1111 :
begin
assign {Cout_temp,F} = (~A)+B+1;
assign Cout = ~ Cout_temp;
end

4'b1100 :
begin
assign {Cout_temp,F} = A+(~B);
assign Cout = ~ Cout_temp;
end

4'b1110 :
begin
assign {Cout_temp,F} = (~A)+B;
assign Cout = ~ Cout_temp;
end

default : assign {Cout,F} = 5'b00000;

endcase

end

endmodule


But, when I'm trying to synthesize the project and View the Technology/RTL Schematics, I'm encountering the following errors:

Can anyone point out where the mistake is and help me rectify it?

• In the always @(*) block, you don't need the assign key word, the comb logic is implied. Commented May 21, 2020 at 10:40
• Yes, this helped me in successfully generating the synthesis file. Commented May 21, 2020 at 11:24

## 1 Answer

The error "unsupported procedural assignment for signal" means that your synthesis tool does not allow you to use the assign keyword inside the always block. Assignments inside an always block are known as procedural assignments. The assign keyword is typically used for continuous assignments, which are normally outside procedural blocks, such as always and initial.

The syntax in your code is supported by IEEE Std 1800-2017, section 10.6 Procedural continuous assignments. However, it is not considered good coding style, and obviously all tools do not support it.

As suggested by the comment on your question, you should simply remove all the assign keywords in your code to avoid the errors.

After you fix those errors, there is another issue with your code: it will infer unintended latches. You intend to infer purely combinational logic, but latches are sequential logic which retain state.

Your code retains state because it does not assign a value to Cout in all of the branches of the case statement, specifically those under the /* Logical Operations */ comment. Those branches only make assignments to F.

One simple way to avoid the latches is to make an assignment to Cout just before the case statement:

timescale 1ns / 1ps

module alu_4_bit (
input M,
input S1,
input S0,
input C0,
input [3:0] A,
input [3:0] B,
output reg [3:0] F,
output reg Cout
);

reg Cout_temp; // Internal Variable

always @(*) begin
Cout = 0;
case({M,S1,S0,C0})
/* Logical Operations */

4'b0000, 4'b0001, 4'b000x : F = A & B;
4'b0010, 4'b0011, 4'b001x : F = A | B;
4'b0100, 4'b0101, 4'b010x : F = A ^ B;
4'b0110, 4'b0111, 4'b011x : F = ~(A ^ B);

/*Arithmetic Operations*/

4'b1000 : {Cout,F} = {4'b000,A};
4'b1001 : {Cout,F} = A+1;
4'b1010 : {Cout,F} = A+B;
4'b1011 : {Cout,F} = A+B+1;

/* When there's negation of any one data entry, Cout also gets negated */

4'b1101 :
begin
{Cout_temp,F} = A+(~B)+1;
Cout = ~ Cout_temp;
end

4'b1111 :
begin
{Cout_temp,F} = (~A)+B+1;
Cout = ~ Cout_temp;
end

4'b1100 :
begin
{Cout_temp,F} = A+(~B);
Cout = ~ Cout_temp;
end

4'b1110 :
begin
{Cout_temp,F} = (~A)+B;
Cout = ~ Cout_temp;
end

default : {Cout,F} = 5'b00000;
endcase
end
endmodule