`default_nettype none module ALU( input wire [2:0] operation, input wire [31:0] left, right, output reg [31:0] result ); // 1. Unsigned should be a no-op so simply remove those function calls // 2. Signed modifiers don't appear to be supported on VTR, so they might need to be expanded with logic for actually doing the signed operation. // 3. Likewise, the triple shift (arithmetic shift) operator doesn't appear to be supported in VTR so it also might need to be expanded manually. always @* begin result = 32'b0; case(operation) 3'd0: begin // Right logical shift // Only need the lowest 5 bits for 32 bit input result = left >> right[4:0]; end 3'd1: begin // Right arithmetic shift result = $signed(left) >>> right[4:0]; end 3'd2: begin // Signed Comparison result = $signed(left) < $signed(right); end 3'd3: begin // Unsigned comparison result = left < right; end endcase end // Extra stuff for example reg [31:0] result2; reg [31:0] __temp; // sameResult: assert property (result == result2); always @* begin result2 = 32'b0; __temp = 32'b0; case(operation) 3'd0: begin // Right logical shift // Only need the lowest 5 bits for 32 bit input result2 = left >> right[4:0]; end 3'd1: begin // Right arithmetic shift // 1. Take the MSB and replicate it to form a mask // 2. Create a mask for the bits that the shift will set correctly and mask them off of the MSB replication (sets 32 - shift bits correctly) // 3. Combine the shift part and the masked part __temp = {32{left[31]}} & ~ ((33'd1 << (6'd32 - right[4:0])) - 33'd1); result2 = __temp | (left >> right[4:0]); end 3'd2: begin // Signed Comparison case({left[31], right[31]}) 2'b00: result2 = left < right; // Both positive 2'b01: result2 = 32'd0; // + < - (always false) 2'b10: result2 = 32'd1; // - < + (always true) 2'b11: result2 = -left > -right; // Both negative endcase end 3'd3: begin // Unsigned comparison result2 = left < right; end endcase end endmodule