2
\$\begingroup\$

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

enter image description here

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:

enter image description here

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

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

1 Answer 1

1
\$\begingroup\$

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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.