From 3647e0b15c5a525e7a81bd58bda8ddffbc347b79 Mon Sep 17 00:00:00 2001 From: supleed2 <21363892+supleed2@users.noreply.github.com> Date: Wed, 3 Jun 2020 15:15:44 +0100 Subject: [PATCH] ALU now uses multiply block rather than * operator Updated to use custom block and decide which step of MUL, MLA and MLS depending on exec2 input --- CPUProject.qsf | 15 +++--- CPUProject.qws | Bin 48 -> 0 bytes alu.v | 70 +++++++++++------------- alu.v.bak | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 45 deletions(-) delete mode 100644 CPUProject.qws create mode 100644 alu.v.bak diff --git a/CPUProject.qsf b/CPUProject.qsf index 0ad5ce2..3ca0489 100644 --- a/CPUProject.qsf +++ b/CPUProject.qsf @@ -38,13 +38,18 @@ set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE AUTO -set_global_assignment -name TOP_LEVEL_ENTITY DECODE +set_global_assignment -name TOP_LEVEL_ENTITY CPUProject set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.0 set_global_assignment -name PROJECT_CREATION_TIME_DATE "12:38:11 MAY 20, 2020" -set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Standard Edition" +set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top +set_global_assignment -name VERILOG_FILE alu.v set_global_assignment -name MIF_FILE LUTSquares.mif set_global_assignment -name BDF_FILE mul8.bdf set_global_assignment -name BDF_FILE abs.bdf @@ -60,8 +65,4 @@ set_global_assignment -name BDF_FILE mul16.bdf set_global_assignment -name QIP_FILE LUT.qip set_global_assignment -name VERILOG_FILE min.v set_global_assignment -name VERILOG_FILE SM.v -set_global_assignment -name VECTOR_WAVEFORM_FILE Waveform.vwf -set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top -set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top -set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file +set_global_assignment -name VECTOR_WAVEFORM_FILE Waveform.vwf \ No newline at end of file diff --git a/CPUProject.qws b/CPUProject.qws deleted file mode 100644 index 63563b76eda4b19c3f4f321afd3f1b7df67b8d5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48 ocmZ?JV1NM`h8%`OhGK>ihIoc@hJ1!1hHN0O04SEskP1@-0GYrBX8-^I diff --git a/alu.v b/alu.v index 1389477..c38f7fb 100644 --- a/alu.v +++ b/alu.v @@ -1,4 +1,4 @@ -module alu (enable, Rd, Rs1, Rs2, opcode, carryin, mulresult, carryout, mul1, mul2, Rout, jump); +module alu (enable, Rd, Rs1, Rs2, opcode, carryin, mulresult, exec2, 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 @@ -7,6 +7,7 @@ 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 +input exec2; // Input from state machine to indicate when to take in result from multiplication output carryout; // resulting carry from operation, updated each cycle output reg signed [15:0] mul1; // first number to be multiplied @@ -21,7 +22,6 @@ 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; @@ -73,23 +73,41 @@ always @(*) 6'b011100: // MUL Multiply (Rd = Rs1 * Rs2) begin -// mul1 = Rs1; -// mul2 = Rs2; - alusum[16] = 1'b0; - {mulextra, alusum[15:0]} = Rs1 * Rs2; + if(!exec2) + begin + mul1 = Rs1; + mul2 = Rs2; + end + else + begin + alusum[16] = 1'b0; + {mulextra, alusum[15:0]} = mulresult; + end 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; + if(!exec2) + begin + mul1 = Rs1; + mul2 = Rs2; + end + else + begin + alusum[16] = 1'b0; + {mulextra, alusum[15:0]} = mulresult + {16'h0000, Rs2}; + end end 6'b011110: // MLS Multiply and Subtract (Rd = Rs2 - (Rd * Rs1)[15:0]) begin -// mul1 = Rs1; -// mul2 = Rs2; - alusum = {1'b0, Rs2 - (Rd * Rs1)}; + if(!exec2) + begin + mul1 = Rs1; + mul2 = Rs2; + end + else + begin + alusum = {1'b0, Rs2 - mulresult[15:0]}; + end end 6'b011111: alusum = mulextra; // MRT Retrieve Multiply MSBs (Rd = MSBs) @@ -104,7 +122,7 @@ always @(*) 6'b100111: ; 6'b111110: ; // NOP No Operation (Do Nothing for a cycle) - 6'b111111: ; // STP Stop (Program Ends) + 6'b111111: alusum = {1'b0, 16'h0000}; // STP Stop (Program Ends) default: ; // During Load & Store as well as undefined opcodes endcase; @@ -115,28 +133,4 @@ always @(*) 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 \ No newline at end of file diff --git a/alu.v.bak b/alu.v.bak new file mode 100644 index 0000000..27546b7 --- /dev/null +++ b/alu.v.bak @@ -0,0 +1,142 @@ +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 \ No newline at end of file