mirror of
https://github.com/supleed2/ELEC40006-P1-CW.git
synced 2024-11-10 02:05:48 +00:00
Aadi Desai
3647e0b15c
Updated to use custom block and decide which step of MUL, MLA and MLS depending on exec2 input
142 lines
5.5 KiB
Coq
142 lines
5.5 KiB
Coq
module alu (enable, Rd, Rs1, Rs2, opcode, carryin, mulresult, carryout, mul1, mul2, Rout, jump);
|
|
|
|
input enable; // active LOW, disables the ALU during load/store operations so that undefined behaviour does not occur
|
|
input signed [15:0] Rd; // input destination register
|
|
input signed [15:0] Rs1; // input source register 1
|
|
input signed [15:0] Rs2; // input source register 2
|
|
input [5:0] opcode; // opcode is fed in from instruction using wires outside ALU
|
|
input carryin; // current status of carry flip-flop
|
|
input signed [31:0] mulresult; // 32-bit result from multiplier
|
|
|
|
output carryout; // resulting carry from operation, updated each cycle
|
|
output reg signed [15:0] mul1; // first number to be multiplied
|
|
output reg signed [15:0] mul2; // second number to be multiplied
|
|
output signed [15:0] Rout; // value to be saved to destination register
|
|
output jump; // tells decoder whether Jump condition is true
|
|
|
|
// load and store are handled outside the ALU so those opcodes can be ignored. All other instructions have a consistent format.
|
|
|
|
reg signed [16:0] alusum; // extra bit to hold carry from operations other than Multiply
|
|
assign Rout = alusum [15:0];
|
|
assign carryout = alusum [16];
|
|
assign jump = (alusum[16] && ((opcode[5:2] == 4'b0000) | (opcode[5:2] == 4'b0001) | (opcode[5:2] == 4'b0010)));
|
|
reg [15:0] mulextra;
|
|
reg signed [31:0] mlaresult;
|
|
|
|
//Jump Conditionals:
|
|
wire JC1, JC2, JC3, JC4, JC5, JC6, JC7, JC8;
|
|
assign JC1 = (Rs1 < Rs2);
|
|
assign JC2 = (Rs1 > Rs2);
|
|
assign JC3 = (Rs1 == Rs2);
|
|
assign JC4 = (Rs1 == 0);
|
|
assign JC5 = (Rs1 >= Rs2);
|
|
assign JC6 = (Rs1 <= Rs2);
|
|
assign JC7 = (Rs1 != Rs2);
|
|
assign JC8 = (Rs1 < 0);
|
|
|
|
always @(*)
|
|
begin
|
|
if(!enable)
|
|
begin
|
|
case (opcode)
|
|
6'b000000: alusum = {1'b1, Rd}; // JMP Unconditional Jump, first bit high to indicate jump and passes through Rd
|
|
|
|
6'b000100: alusum = {JC1, Rd}; // JC1 Conditional Jump A < B
|
|
6'b000101: alusum = {JC2, Rd}; // JC2 Conditional Jump A > B
|
|
6'b000110: alusum = {JC3, Rd}; // JC3 Conditional Jump A = B
|
|
6'b000111: alusum = {JC4, Rd}; // JC4 Conditional Jump A = 0
|
|
|
|
6'b001000: alusum = {JC5, Rd}; // JC5 Conditional Jump A >= B / A !< B
|
|
6'b001001: alusum = {JC6, Rd}; // JC6 Conditional Jump A <= B / A !> B
|
|
6'b001010: alusum = {JC7, Rd}; // JC7 Conditional Jump A != B
|
|
6'b001011: alusum = {JC8, Rd}; // JC8 Conditional Jump A < 0
|
|
|
|
6'b001100: alusum = {1'b0, Rs1 & Rs2}; // AND Bitwise AND
|
|
6'b001101: alusum = {1'b0, Rs1 | Rs2}; // OR Bitwise OR
|
|
6'b001110: alusum = {1'b0, Rs1 ^ Rs2}; // XOR Bitwise XOR
|
|
6'b001111: alusum = {1'b0, ~Rs1}; // NOT Bitwise NOT
|
|
|
|
6'b010000: alusum = {1'b0, ~Rs1 | ~Rs2}; // NND Bitwise NAND
|
|
6'b010001: alusum = {1'b0, ~Rs1 & ~Rs2}; // NOR Bitwise NOR
|
|
6'b010010: alusum = {1'b0, Rs1 ~^ Rs2}; // XNR Bitwise XNOR
|
|
6'b010011: alusum = {1'b0, Rs1}; // MOV Move (Rd = Rs1)
|
|
|
|
6'b010100: alusum = {1'b0, Rs1} + {1'b0, Rs2}; // ADD Add (Rd = Rs1 + Rs2)
|
|
6'b010101: alusum = {1'b0, Rs1} + {1'b0, Rs2} + carryin; // ADC Add w/ Carry (Rd = Rs1 + Rs2 + C)
|
|
6'b010110: alusum = {1'b0, Rs1} + {17'b00000000000000001}; // ADO Add 1 (Rd = Rd + 1)
|
|
6'b010111: ;
|
|
|
|
6'b011000: alusum = {1'b0, Rs1} - {1'b0, Rs2}; // SUB Subtract (Rd = Rs1 - Rs2)
|
|
6'b011001: alusum = {1'b0, Rs1} - {1'b0, Rs2} + carryin - {17'b00000000000000001}; // SBC Subtract w/ Carry (Rd = Rs1 - Rs2 + C - 1)
|
|
6'b011010: alusum = {1'b0, Rs1} - {17'b00000000000000001}; // SBO Subtract 1 (Rd = Rd - 1)
|
|
6'b011011: ;
|
|
|
|
6'b011100: // MUL Multiply (Rd = Rs1 * Rs2)
|
|
begin
|
|
// mul1 = Rs1;
|
|
// mul2 = Rs2;
|
|
alusum[16] = 1'b0;
|
|
{mulextra, alusum[15:0]} = Rs1 * Rs2;
|
|
end
|
|
6'b011101: // MLA Multiply and Add (Rd = Rs2 + (Rd * Rs1))
|
|
begin
|
|
// mul1 = Rs1;
|
|
// mul2 = Rs2;
|
|
alusum[16] = 1'b0;
|
|
{mulextra, alusum[15:0]} = (Rd * Rs1) + Rs2;
|
|
end
|
|
6'b011110: // MLS Multiply and Subtract (Rd = Rs2 - (Rd * Rs1)[15:0])
|
|
begin
|
|
// mul1 = Rs1;
|
|
// mul2 = Rs2;
|
|
alusum = {1'b0, Rs2 - (Rd * Rs1)};
|
|
end
|
|
6'b011111: alusum = mulextra; // MRT Retrieve Multiply MSBs (Rd = MSBs)
|
|
|
|
6'b100000: alusum = {1'b0, Rs1 << Rs2}; // LSL Logical Shift Left (Rd = Rs1 shifted left by value of Rs2)
|
|
6'b100001: alusum = {1'b0, Rs1 >> Rs2}; // LSR Logical Shift Right (Rd = Rs1 shifted right by value of Rs2)
|
|
6'b100010: alusum = {Rs1[15], Rs1 >>> Rs2}; // ASR Arithmetic Shift Right (Rd = Rs1 shifted right by value of Rs2, maintaining sign bit)
|
|
6'b100011: ;
|
|
|
|
6'b100100: alusum = {1'b0, (Rs1 >> Rs2[3:0]) | (Rs1 << (16 - Rs2[3:0]))}; // ROR Shift Right Loop (Rd = Rs1 shifted right by Rs2, but Rs1[0] -> Rs1[15])
|
|
6'b100101: alusum = ({Rs1, carryin} >> (Rs2 % 17)) | ({Rs1, carryin} << (17 - (Rs2 % 17)));// RRC Shift Right Loop w/ Carry (Rd = Rs1 shifted right by Rs2, but Rs1[0] -> Carry & Carry -> Rs1[15])
|
|
6'b100110: ;
|
|
6'b100111: ;
|
|
|
|
6'b111110: ; // NOP No Operation (Do Nothing for a cycle)
|
|
6'b111111: ; // STP Stop (Program Ends)
|
|
|
|
default: ; // During Load & Store as well as undefined opcodes
|
|
endcase;
|
|
end
|
|
else
|
|
begin
|
|
alusum = {1'b0, 16'h0000}; // Bring output low during Load/Store so it does not interfere
|
|
end
|
|
end
|
|
|
|
/*
|
|
always @(*)
|
|
begin
|
|
case (opcode)
|
|
6'b011100:
|
|
begin
|
|
alusum = {1'b0, mulresult[15:0]};
|
|
mulextra = mulresult[31:16];
|
|
end
|
|
6'b011101:
|
|
begin
|
|
mlaresult = mulresult + {16'h0000, Rs2};
|
|
alusum = {1'b0, mlaresult[15:0]};
|
|
mulextra = mlaresult[31:16];
|
|
end
|
|
6'b011110:
|
|
begin
|
|
alusum = {1'b0, Rs2 - mulresult[15:0]};
|
|
end
|
|
default: ;
|
|
endcase
|
|
end
|
|
*/
|
|
|
|
endmodule |