Search code examples
verilogalu

Procedural assignment to a non-register shiftedy is not permitted, left-hand side should be reg/integer/time/genvar -- this is the error I am getting


I have almost solved this question and made changes in the code as shown below. I am also not getting any error but the only thing is that the output of 'shiftedy' is not as expected. Also, I use Xilinx to run my projects and I am getting red line across the simulation output for 'shiftedy'. below is the screenshot for the same. If someone could help me with that.

module shifter(shiftedy, x, constamt, constvar, y);
output [31:0] shiftedy;
input [4:0] x, constamt, constvar;
input [31:0] y;
wire [4:0] amount, m, n;
wire shiftdir;

assign m = constamt & constvar; 
assign n = x && constvar;
assign amount = m || n;

assign shiftedy = (shiftdir == 1'b1) ? (shiftedy <= y << amount) : (shiftedy <= y >> amount);
endmodule

module stimulus;
wire [31:0] shiftedy;
reg [4:0] x, constamt, constvar;
reg [31:0] y;

shifter s1(shiftedy, x, constamt, constvar, y);
initial
begin
$monitor($time, "X=%b, constamt=%b, Y=%b, shiftedy=%b", x, constamt, y, shiftedy);
end

initial
begin
x=5'd0; y=32'd0; constamt=5'd0; constvar=5'd0;
#5 x = 5'd3; y = 5'd4;
#5 x = 5'd5; y = 5'd2; constamt = 1'b1;
#5 x = 5'd5; y = 5'd10;
#5 x = 5'd2; y = 5'd10; constamt = 1'b0;  
#5 x = 5'd10; y = 5'd5; constamt = 1'b1;
end
endmodule

ALU

enter image description here


Solution

  • You are not assigning the shiftdir so it is becoming x or z.There are some basic syntax issues too in your code.

    module shifter(
       output [31:0]   shifted_y
      ,input  [4:0]    x, const_amt, const_var
      ,input  [31:0]   y
      ,input           shift_dir
    );
    wire [4:0] amount, m, n;
    
    assign m = const_amt & const_var; 
    assign n = x && const_var;
    assign amount = m || n;
    
    assign shifted_y = (shift_dir == 1'b1) ? y << amount : y >> amount ;
    
    endmodule
    
    module stimulus;
     wire [31:0] shiftedy;
     reg  [4:0]  x, constamt, constvar;
     reg  [31:0] y;
     reg         shift_dir;
    
    shifter s1(shiftedy, x, constamt, constvar, y,shift_dir);
    
    initial begin
    $monitor($time, "X=%b, constamt=%b, Y=%b, shiftedy=%b", x, constamt, y, shiftedy);
    end
    
     initial begin
          x         = 5'd0 ;
          y         = 32'd0;
          constamt  = 5'd0 ;
          constvar  = 5'd0 ;
          shift_dir = 1'b0;
    
        #5 x = 5'd3 ; y = 32'd4 ;
        #5 x = 5'd5 ; y = 32'd2 ; constamt = 5'b1;
        #5 x = 5'd5 ; y = 32'd10;
        #5 x = 5'd2 ; y = 32'd10; constamt = 5'b0;  
        #5 x = 5'd10; y = 32'd5 ; constamt = 5'b1;
     end
    endmodule
    

    based on the diagram you can use the below code too for the design logic even though not completely correct you can modify it .

    module ALU (
        output [31:0] s
       ,input  [31:0] x,y
       ,input  [04:0] const_amount
       ,input         shift_dir,add_sub,const_var
       ,input  [1:0]  function_class,logic_function
    );
    
    // shifter logic
      wire [4:0]  amount    = const_var ? x [4:0]     : const_amount;
      wire [31:0] shifted_y = shift_dir ? y << amount : y >> amount ;
    
    // ALU
      wire [31:0] k       = {32{add_sub}} ^ y ;
      wire [31:0] alu_out = add_sub ? x + k : x - k;
    
    //logic unit
      wire [31:0] logic_out = (logic_function == 2'b00 ) ?  x  & y :             // ADD
                              (logic_function == 2'b01 ) ?  x  | y :             // OR
                              (logic_function == 2'b10 ) ?  x  ^ y :             // XOR
                              (logic_function == 2'b11 ) ?  x ~| y : 32'b0 ;     // NOR
    
    // output mux
      assign s =  (function_class == 2'b00 ) ?  shifted_y :
                  (function_class == 2'b01 ) ?  alu_out   :
                  (function_class == 2'b10 ) ?  alu_out   :
                  (function_class == 2'b11 ) ?  logic_out : 32'b0;
    
    endmodule