ALU Design Under Test(DUT)
ALU Tasarım Kodları | Bitirme projesi
Kaynak Kod
module alu (
input logic clk,
input logic rst_n,
input logic in_valid,
input logic [7:0] operand_a,
input logic [7:0] operand_b,
input logic [2:0] opcode,
output logic out_valid,
output logic [15:0] result,
output logic [3:0] flags
);
// Internal signals for combinational logic outputs
logic [15:0] next_result;
logic [3:0] next_flags;
// Opcode definitions for better readability
localparam bit [2:0]
OP_ADD = 3'b000,
OP_SUB = 3'b001,
OP_MUL = 3'b010,
OP_AND = 3'b011,
OP_OR = 3'b100,
OP_XOR = 3'b101,
OP_SHL = 3'b110,
OP_SHR = 3'b111;
// Flag bit positions
localparam int FLAG_Z = 0; // Zero
localparam int FLAG_N = 1; // Negative
localparam int FLAG_C = 2; // Carry (for 8-bit operations)
localparam int FLAG_P = 3; // Parity
// =========================================================================
// Combinational Block: Arithmetic & Logic Operations
// =========================================================================
always_comb begin
// Default initializations to prevent latches
next_result = 16'd0;
next_flags = 4'd0;
// Perform the operation based on opcode
case (opcode)
OP_ADD: next_result = operand_a + operand_b;
OP_SUB: next_result = operand_a - operand_b;
OP_MUL: next_result = operand_a * operand_b; // 8-bit * 8-bit = 16-bit
OP_AND: next_result = {8'h00, operand_a & operand_b};
OP_OR: next_result = {8'h00, operand_a | operand_b};
OP_XOR: next_result = {8'h00, operand_a ^ operand_b};
OP_SHL: next_result = {8'h00, operand_a} << 1;
OP_SHR: next_result = {8'h00, operand_a} >> 1;
default: next_result = 16'd0;
endcase
// Calculate status flags
next_flags[FLAG_Z] = (next_result == 16'd0);
next_flags[FLAG_N] = next_result[15];
// Carry flag makes sense mainly for ADD/SUB out of the 8th bit
if (opcode == OP_ADD || opcode == OP_SUB) begin
next_flags[FLAG_C] = next_result[8];
end else begin
next_flags[FLAG_C] = 1'b0;
end
// Parity flag (XOR reduction of the result)
next_flags[FLAG_P] = ^next_result;
end
// =========================================================================
// Sequential Block: Output Registers
// =========================================================================
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// Reset state
out_valid <= 1'b0;
result <= 16'd0;
flags <= 4'd0;
end else begin
// Pipeline the valid signal
out_valid <= in_valid;
// Only update outputs when input data is valid
if (in_valid) begin
result <= next_result;
flags <= next_flags;
end
end
end
endmodule