// This source file is licensed under the BSD Zero-Clause License. // You are free to use, modify, and distribute this file without restriction. // See LICENSE-BSD-0.txt for details. module alu ( input logic [15:0] x, // Operand X input logic [15:0] y, // Operand Y input logic zx, // Zero X? input logic nx, // Invert X? input logic zy, // Zero Y? input logic ny, // Invert Y? input logic fn, // Function: 0 = AND, 1 = ADD input logic no, // Invert output? output logic [15:0] out, // Output output logic zr, // Output zero flag output logic ng, // Output negative flag (two's complement) output logic ov // Output overflow flag (carry out) ); // Declare intermediate logic logic [15:0] zeroed_x; logic [15:0] final_x; logic [15:0] zeroed_y; logic [15:0] final_y; logic [15:0] output_and; logic [15:0] output_add; logic add_overflow; logic [15:0] output_raw; // Set x and/or y to zero if specified by zx/zy control signals assign zeroed_x = zx ? 16'b0 : x; assign zeroed_y = zy ? 16'b0 : y; // Invert x and/or y if specified by nx/ny control signals assign final_x = nx ? ~zeroed_x : zeroed_x; assign final_y = ny ? ~zeroed_y : zeroed_y; // Compute results of AND and addition operations assign output_and = final_x & final_y; assign {add_overflow, output_add} = final_x + final_y; // Select AND or sum depending on fn control signal assign output_raw = fn ? output_add : output_and; // Invert output if specified by no control signal assign out = no ? ~output_raw : output_raw; // Set zr flag if output is exactly zero assign zr = (out == 0); // Set ng flag if output is negative in two's complement (MSB set) assign ng = out[15]; // Set ov flag if addition had carry out, or 0 if operation is AND assign ov = fn ? add_overflow : 1'b0; endmodule