mirror of https://github.com/zachjs/sv2v.git
73 lines
2.6 KiB
Verilog
73 lines
2.6 KiB
Verilog
`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 |