From dba98738332f1870e5d2a1cfe0b0c69d5bf65fb3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 5 Nov 2017 19:23:19 -0500 Subject: [PATCH 001/190] Create work plan --- workplan.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 workplan.txt diff --git a/workplan.txt b/workplan.txt new file mode 100644 index 0000000..f0520eb --- /dev/null +++ b/workplan.txt @@ -0,0 +1,11 @@ +Ariana Olson, Andrew Pan, Jonah Spear +Lab 3 Work Plan + + +Steps: +1. Create a circuit diagram (Do by 11/7) - 2 hours +2. Create table mapping instruction to control signal values (Do by 11/8) - 2 hours +3. Implement all sub-components and write unit tests (Do by 11/11) - 4 hours +4. Working Assembly Program (Do by 11/13) - 1.5 hours +5. Integration tests (Do by 11/13) - 1.5 hours +6. Lab Report (Do by 11/17) - 2 hours \ No newline at end of file From c8c808340fd2bd873986a7c9b6e56ab13c36e131 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 5 Nov 2017 19:24:18 -0500 Subject: [PATCH 002/190] Createe work plan with correct file name --- workplan.txt => work_plan.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename workplan.txt => work_plan.txt (100%) diff --git a/workplan.txt b/work_plan.txt similarity index 100% rename from workplan.txt rename to work_plan.txt From fc816802d16a2f53ca88d5372df39c2cb7bc1ad3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 21:59:55 -0500 Subject: [PATCH 003/190] Create module encompassing ALU, RegFile, and Memory --- core.v | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 core.v diff --git a/core.v b/core.v new file mode 100644 index 0000000..e8c7d6f --- /dev/null +++ b/core.v @@ -0,0 +1,11 @@ +/* +The section of the CPU containing the register file, data memory, and ALU. +*/ + +module core ( + +); + +// code here + +endmodule \ No newline at end of file From 2cb2fb07ae4d5cfa7358b900d84564fc30ac9b02 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:00:17 -0500 Subject: [PATCH 004/190] Create makefile to build modules --- makefile | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 makefile diff --git a/makefile b/makefile new file mode 100644 index 0000000..7adc08f --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +all: core + +core: core.v + iverilog -Wall -o core core.v \ No newline at end of file From 74292b032bbaaeecc2672e63c42c88aadf270502 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:02:46 -0500 Subject: [PATCH 005/190] Ignore compiled binaries and gtkwave files --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29086fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Ignore compiled binaries +* +!/**/ +!*.* +!makefile + +# Ignore gtkwave files +*.vcd From 79cde4c4597804ce9d858de53556357cfab369e1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:25:06 -0500 Subject: [PATCH 006/190] Create test bench for core module --- core.t.v | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 core.t.v diff --git a/core.t.v b/core.t.v new file mode 100644 index 0000000..a636d6c --- /dev/null +++ b/core.t.v @@ -0,0 +1,23 @@ +/* +Test bench for the core module of the CPU. +*/ + +`include "core.v" + +module core_TEST(); + wire [31:0] Da; + wire is_zero; + + reg clk; + reg [31:0] rd; + reg [31:0] rt; + reg [31:0] rs; + reg [15:0] immediate; + reg [31:0] added_PC; + + core dut (clk, rd, rt, rs, immediate, added_PC, Da, is_zero); + + initial begin + // Test code here. + end +endmodule \ No newline at end of file From 1cff180e0a043c9383232a6d5b581d39691834a1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:38:17 -0500 Subject: [PATCH 007/190] Add alu files --- adder.v | 76 +++++++ adder_subtracter.t.v | 60 +++++ adder_subtracter.v | 256 ++++++++++++++++++++++ alu.t.v | 507 +++++++++++++++++++++++++++++++++++++++++++ alu.v | 57 +++++ and_32bit.t.v | 36 +++ and_32bit.v | 40 ++++ nand_32bit.t.v | 36 +++ nand_32bit.v | 40 ++++ nor_32bit.t.v | 36 +++ nor_32bit.v | 40 ++++ or_32bit.t.v | 30 +++ or_32bit.v | 40 ++++ slt.t.v | 40 ++++ slt.v | 110 ++++++++++ xor_32bit.t.v | 36 +++ xor_32bit.v | 40 ++++ 17 files changed, 1480 insertions(+) create mode 100644 adder.v create mode 100644 adder_subtracter.t.v create mode 100644 adder_subtracter.v create mode 100644 alu.t.v create mode 100644 alu.v create mode 100644 and_32bit.t.v create mode 100644 and_32bit.v create mode 100644 nand_32bit.t.v create mode 100644 nand_32bit.v create mode 100644 nor_32bit.t.v create mode 100644 nor_32bit.v create mode 100644 or_32bit.t.v create mode 100644 or_32bit.v create mode 100644 slt.t.v create mode 100644 slt.v create mode 100644 xor_32bit.t.v create mode 100644 xor_32bit.v diff --git a/adder.v b/adder.v new file mode 100644 index 0000000..cc610e8 --- /dev/null +++ b/adder.v @@ -0,0 +1,76 @@ +// Adder circuit + +module behavioralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + // Uses concatenation operator and built-in '+' + assign {carryout, sum}=a+b+carryin; +endmodule + +module structuralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + wire ab; //setting up wires + wire acarryin; + wire bcarryin; + wire orpairintermediate; + wire orsingleintermediate; + wire orall; + wire andsumintermediate; + wire andsingleintermediate; + wire andall; + wire invcarryout; + and #(50) andab(ab, a, b); // a and b + and #(50) andacarryin(acarryin, a, carryin); // a and carryin + and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin + or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) + or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) + or #(50) orintermediate(orsingleintermediate, a, b); // a or b + or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin + not #(50) inv(invcarryout, carryout); // not carryout + and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout + and #(50) andintermediate(andsingleintermediate, a, b); // a and b + and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin + or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) +endmodule + +module FullAdder4bit +( + output[3:0] sum, // 2's complement sum of a and b + output carryout, // Carry out of the summation of a and b + output overflow, // True if the calculation resulted in an overflow + input[3:0] a, // First operand in 2's complement format + input[3:0] b, // Second operand in 2's complement format + input carryin +); + wire carryout1; // wire setup for carryouts from each adder + wire carryout2; + wire carryout3; + wire aandb; + wire anorb; + wire bandsum; + wire bnorsum; + wire abandnoror; + wire bsumandnornor; + structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits + structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits + structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits + structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits + and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) + nor #50 norinputs(anorb, a[3], b[3]); + and #50 andsum(bandsum, b[3], sum[3]); + nor #50 norsum(bnorsum, b[3], sum[3]); + or #50 orinputcombs(abandnoror, aandb, anorb); + nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); + and #50 finaland(overflow, abandnoror, bsumandnornor); +endmodule \ No newline at end of file diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v new file mode 100644 index 0000000..e2c0aa1 --- /dev/null +++ b/adder_subtracter.t.v @@ -0,0 +1,60 @@ +// Adder_subtacter testbench + +`timescale 1 ns / 1 ps +`include "adder_subtracter.v" + +module test32bitAdder(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] carryin; + wire[31:0] ans; + wire carryout, overflow; + + adder_subtracter adder0(ans[31:0], carryout, overflow, a[31:0], b[31:0], carryin[2:0]); + + initial begin + $display("Input A Input B Command | Output Flag Carryout"); + + // Addition tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b100; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + // Subtraction Tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000001000000000000000000000; + b=32'b00000000000000000000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000001000010000000000000000; + b=32'b10000000000000010000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000000000000000000000000000; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + end +endmodule \ No newline at end of file diff --git a/adder_subtracter.v b/adder_subtracter.v new file mode 100644 index 0000000..f59fd57 --- /dev/null +++ b/adder_subtracter.v @@ -0,0 +1,256 @@ +`include "adder.v" + +// 32 bit mux +module mux + ( + output[31:0] out, + input address, + input[31:0] in0, + input[31:0] in1 + ); + wire invaddr; + wire in00addr; // input 0 bit 0 andded with address + wire in01addr; + wire in02addr; + wire in03addr; + wire in04addr; + wire in05addr; + wire in06addr; + wire in07addr; + wire in08addr; + wire in09addr; + wire in010addr; + wire in011addr; + wire in012addr; + wire in013addr; + wire in014addr; + wire in015addr; + wire in016addr; + wire in017addr; + wire in018addr; + wire in019addr; + wire in020addr; + wire in021addr; + wire in022addr; + wire in023addr; + wire in024addr; + wire in025addr; + wire in026addr; + wire in027addr; + wire in028addr; + wire in029addr; + wire in030addr; + wire in031addr; + wire in10addr; + wire in11addr; + wire in12addr; + wire in13addr; + wire in14addr; + wire in15addr; + wire in16addr; + wire in17addr; + wire in18addr; + wire in19addr; + wire in110addr; + wire in111addr; + wire in112addr; + wire in113addr; + wire in114addr; + wire in115addr; + wire in116addr; + wire in117addr; + wire in118addr; + wire in119addr; + wire in120addr; + wire in121addr; + wire in122addr; + wire in123addr; + wire in124addr; + wire in125addr; + wire in126addr; + wire in127addr; + wire in128addr; + wire in129addr; + wire in130addr; + wire in131addr; + + // inverting address + not #10 inv(invaddr, address); + // and all bits in input 0 with inverted address + and #20 and00(in00addr, in0[0], invaddr); + and #20 and01(in01addr, in0[1], invaddr); + and #20 and02(in02addr, in0[2], invaddr); + and #20 and03(in03addr, in0[3], invaddr); + and #20 and04(in04addr, in0[4], invaddr); + and #20 and05(in05addr, in0[5], invaddr); + and #20 and06(in06addr, in0[6], invaddr); + and #20 and07(in07addr, in0[7], invaddr); + and #20 and08(in08addr, in0[8], invaddr); + and #20 and09(in09addr, in0[9], invaddr); + and #20 and010(in010addr, in0[10], invaddr); + and #20 and011(in011addr, in0[11], invaddr); + and #20 and012(in012addr, in0[12], invaddr); + and #20 and013(in013addr, in0[13], invaddr); + and #20 and014(in014addr, in0[14], invaddr); + and #20 and015(in015addr, in0[15], invaddr); + and #20 and016(in016addr, in0[16], invaddr); + and #20 and017(in017addr, in0[17], invaddr); + and #20 and018(in018addr, in0[18], invaddr); + and #20 and019(in019addr, in0[19], invaddr); + and #20 and020(in020addr, in0[20], invaddr); + and #20 and021(in021addr, in0[21], invaddr); + and #20 and022(in022addr, in0[22], invaddr); + and #20 and023(in023addr, in0[23], invaddr); + and #20 and024(in024addr, in0[24], invaddr); + and #20 and025(in025addr, in0[25], invaddr); + and #20 and026(in026addr, in0[26], invaddr); + and #20 and027(in027addr, in0[27], invaddr); + and #20 and028(in028addr, in0[28], invaddr); + and #20 and029(in029addr, in0[29], invaddr); + and #20 and030(in030addr, in0[30], invaddr); + and #20 and031(in031addr, in0[31], invaddr); + // and all bits in input 1 with address + and #20 and10(in10addr, in1[0], address); + and #20 and11(in11addr, in1[1], address); + and #20 and12(in12addr, in1[2], address); + and #20 and13(in13addr, in1[3], address); + and #20 and14(in14addr, in1[4], address); + and #20 and15(in15addr, in1[5], address); + and #20 and16(in16addr, in1[6], address); + and #20 and17(in17addr, in1[7], address); + and #20 and18(in18addr, in1[8], address); + and #20 and19(in19addr, in1[9], address); + and #20 and110(in110addr, in1[10], address); + and #20 and111(in111addr, in1[11], address); + and #20 and112(in112addr, in1[12], address); + and #20 and113(in113addr, in1[13], address); + and #20 and114(in114addr, in1[14], address); + and #20 and115(in115addr, in1[15], address); + and #20 and116(in116addr, in1[16], address); + and #20 and117(in117addr, in1[17], address); + and #20 and118(in118addr, in1[18], address); + and #20 and119(in119addr, in1[19], address); + and #20 and120(in120addr, in1[20], address); + and #20 and121(in121addr, in1[21], address); + and #20 and122(in122addr, in1[22], address); + and #20 and123(in123addr, in1[23], address); + and #20 and124(in124addr, in1[24], address); + and #20 and125(in125addr, in1[25], address); + and #20 and126(in126addr, in1[26], address); + and #20 and127(in127addr, in1[27], address); + and #20 and128(in128addr, in1[28], address); + and #20 and129(in129addr, in1[29], address); + and #20 and130(in130addr, in1[30], address); + and #20 and131(in131addr, in1[31], address); + + // or the and gates + or #20 or0(out[0], in00addr, in10addr); + or #20 or1(out[1], in01addr, in11addr); + or #20 or2(out[2], in02addr, in12addr); + or #20 or3(out[3], in03addr, in13addr); + or #20 or4(out[4], in04addr, in14addr); + or #20 or5(out[5], in05addr, in15addr); + or #20 or6(out[6], in06addr, in16addr); + or #20 or7(out[7], in07addr, in17addr); + or #20 or8(out[8], in08addr, in18addr); + or #20 or9(out[9], in09addr, in19addr); + or #20 or10(out[10], in010addr, in110addr); + or #20 or11(out[11], in011addr, in111addr); + or #20 or12(out[12], in012addr, in112addr); + or #20 or13(out[13], in013addr, in113addr); + or #20 or14(out[14], in014addr, in114addr); + or #20 or15(out[15], in015addr, in115addr); + or #20 or16(out[16], in016addr, in116addr); + or #20 or17(out[17], in017addr, in117addr); + or #20 or18(out[18], in018addr, in118addr); + or #20 or19(out[19], in019addr, in119addr); + or #20 or20(out[20], in020addr, in120addr); + or #20 or21(out[21], in021addr, in121addr); + or #20 or22(out[22], in022addr, in122addr); + or #20 or23(out[23], in023addr, in123addr); + or #20 or24(out[24], in024addr, in124addr); + or #20 or25(out[25], in025addr, in125addr); + or #20 or26(out[26], in026addr, in126addr); + or #20 or27(out[27], in027addr, in127addr); + or #20 or28(out[28], in028addr, in128addr); + or #20 or29(out[29], in029addr, in129addr); + or #20 or30(out[30], in030addr, in130addr); + or #20 or31(out[31], in031addr, in131addr); +endmodule + +// 32 bit adder/subtracter that determines what operation to conduct based on the input command +module adder_subtracter + ( + output[31:0] ans, + output carryout, + output overflow, + input[31:0] opA, + input[31:0] opB, + input[2:0] command + ); + wire[31:0] invertedB; //wire to invert b in the event of a subtraction + wire[31:0] finalB; + wire normalB; //added b + wire cout0; + wire cout1; + wire cout2; + wire cout3; + wire cout4; + wire cout5; + wire cout6; + wire _; + wire _1; + wire _2; + wire _3; + wire _4; + wire _5; + wire _6; + + // invert B in the case of two's complement + not #10 invertB0(invertedB[0], opB[0]); + not #10 invertB1(invertedB[1], opB[1]); + not #10 invertB2(invertedB[2], opB[2]); + not #10 invertB3(invertedB[3], opB[3]); + not #10 invertB4(invertedB[4], opB[4]); + not #10 invertB5(invertedB[5], opB[5]); + not #10 invertB6(invertedB[6], opB[6]); + not #10 invertB7(invertedB[7], opB[7]); + not #10 invertB8(invertedB[8], opB[8]); + not #10 invertB9(invertedB[9], opB[9]); + not #10 invertB10(invertedB[10], opB[10]); + not #10 invertB11(invertedB[11], opB[11]); + not #10 invertB12(invertedB[12], opB[12]); + not #10 invertB13(invertedB[13], opB[13]); + not #10 invertB14(invertedB[14], opB[14]); + not #10 invertB15(invertedB[15], opB[15]); + not #10 invertB16(invertedB[16], opB[16]); + not #10 invertB17(invertedB[17], opB[17]); + not #10 invertB18(invertedB[18], opB[18]); + not #10 invertB19(invertedB[19], opB[19]); + not #10 invertB20(invertedB[20], opB[20]); + not #10 invertB21(invertedB[21], opB[21]); + not #10 invertB22(invertedB[22], opB[22]); + not #10 invertB23(invertedB[23], opB[23]); + not #10 invertB24(invertedB[24], opB[24]); + not #10 invertB25(invertedB[25], opB[25]); + not #10 invertB26(invertedB[26], opB[26]); + not #10 invertB27(invertedB[27], opB[27]); + not #10 invertB28(invertedB[28], opB[28]); + not #10 invertB29(invertedB[29], opB[29]); + not #10 invertB30(invertedB[30], opB[30]); + not #10 invertB31(invertedB[31], opB[31]); + + // mux chooses between inverted B or normal B based on addition or subtraction + mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); + + // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one + FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding + FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); + FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); + FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); + FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); + FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); + FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); + FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + +endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v new file mode 100644 index 0000000..0d35733 --- /dev/null +++ b/alu.t.v @@ -0,0 +1,507 @@ +`timescale 1 ns / 1 ps +`include "alu.v" + +module testALU32bit(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] ALUcommand; + wire[31:0] finalALUsig; + wire flag; + wire cout; + + ALUcontrolLUT alu(cout, flag, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + + initial begin + $display("ALU Command Input A Input B | Output Flag Carryout"); + //Test cases add + ALUcommand = 3'b000; + + // 0 + 0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // 1 + 1 + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // positive overflow + a = 32'b01111111111111111111111111111111; + b = 32'b01111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // negative overflow + a = 32'b10000000000000000000000000000001; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // carryout + a = 32'b11111111111111111111111111111111; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + + //Test cases sub + ALUcommand = 3'b001; + + // a=b=0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a=b + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a>b, both positive + a = 32'b00000000000000000000000000000111; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a|b|, both negative + a = 32'b11111111111111111111111111111101; + b = 32'b11111111111111111111111111111110; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // |a|<|b|, both negative + a = 32'b111111111111111111111111111111110; + b = 32'b111111111111111111111111111111000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, no overflow + a = 32'b11111111111111111111111111111101; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, overflow + a = 32'b10000000000000000000000000000101; + b = 32'b01111100000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, no overflow + a = 32'b00000000000000000000000000000101; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + //Here + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, overflow + a = 32'b01111111111111111111101111111111; + b = 32'b10000000000000001100000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //Test cases xor + ALUcommand = 3'b010; + + //a is all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //b is all 0's + b = 32'b00000000000000000000000000000000; + a = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 1's + a = 32'b11111111111111111111111111111111; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + + //Test cases slt + ALUcommand = 3'b011; + + //a>b, all positive + a = 32'b00000000000000000000000000000010; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //ab, all negative + a = 32'b10000000000000000000000000000010; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a>b, a positive, b negative + a = 32'b00000000000000000000000000000001; + b = 32'b10000000000000000000000000000010; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a Date: Tue, 7 Nov 2017 22:39:16 -0500 Subject: [PATCH 008/190] Add inputs and outputs to module definition --- core.v | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core.v b/core.v index e8c7d6f..60d93bf 100644 --- a/core.v +++ b/core.v @@ -3,7 +3,14 @@ The section of the CPU containing the register file, data memory, and ALU. */ module core ( - + input clk, + input [31:0] rd, + input [31:0] rt, + input [31:0] rs, + input [15:0] immediate, + input [31:0] added_PC, + output [31:0] Da, + output is_zero ); // code here From 26b8f1d5ac7e61f1334ace5ad3d13f1c7efa6528 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:40:47 -0500 Subject: [PATCH 009/190] Build core testbenches --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 7adc08f..26d4f83 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ all: core -core: core.v - iverilog -Wall -o core core.v \ No newline at end of file +core: core.v core.t.v + iverilog -Wall -o core core.t.v \ No newline at end of file From 3883fa84ed299fd725c948580ac09368ea87d291 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:56:05 -0500 Subject: [PATCH 010/190] Add register file related modules --- decoders.t.v | 41 +++++++++++ decoders.v | 20 ++++++ multiplexer.t.v | 108 +++++++++++++++++++++++++++++ multiplexer.v | 56 +++++++++++++++ regfile.t.v | 176 ++++++++++++++++++++++++++++++++++++++++++++++++ regfile.v | 114 +++++++++++++++++++++++++++++++ register.t.v | 121 +++++++++++++++++++++++++++++++++ register.v | 48 +++++++++++++ 8 files changed, 684 insertions(+) create mode 100644 decoders.t.v create mode 100644 decoders.v create mode 100644 multiplexer.t.v create mode 100644 multiplexer.v create mode 100644 regfile.t.v create mode 100644 regfile.v create mode 100644 register.t.v create mode 100644 register.v diff --git a/decoders.t.v b/decoders.t.v new file mode 100644 index 0000000..616b67b --- /dev/null +++ b/decoders.t.v @@ -0,0 +1,41 @@ +//------------------------------- +// Unit test the decoder module +//------------------------------- + +`include "decoders.v" + +module decoder1to32Test(); + wire[31:0] out; + reg enable; + reg[4:0] address; + + reg dutpassed; // Flag is set to false if any of the tests fail. + + decoder1to32 DUT (out, enable, address); + + initial begin + dutpassed = 1; + + // Test Case 1: do not enable writing to any register. + enable = 0; address = 5'd14; + if (out != 0) begin + $display("Decoder Test Case 1 failed"); + dutpassed = 0; + end // + + // Test Case 2: + // Enable writing to one register only. + #5 + enable = 1; address = 5'd14; + if (out[31:15] != 0 || out[14] != 1 || out[13:0] != 0) begin + $display("Decoder Test Case 2 failed"); + dutpassed = 0; + end + + #5 + + if (dutpassed ==1) begin + $display("All decoder tests passed."); + end + end // +endmodule // decoder1to32Test \ No newline at end of file diff --git a/decoders.v b/decoders.v new file mode 100644 index 0000000..bfb1ff9 --- /dev/null +++ b/decoders.v @@ -0,0 +1,20 @@ +// 32 bit decoder with enable signal +// enable=0: all output bits are 0 +// enable=1: out[address] is 1, all other outputs are 0 +module decoder1to32 +( +output[31:0] out, +input enable, +input[4:0] address +); + + assign out = enable< Date: Tue, 7 Nov 2017 22:56:28 -0500 Subject: [PATCH 011/190] Add build rules for regfile modules --- makefile | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 26d4f83..f8f191d 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,28 @@ -all: core +all: core alu core: core.v core.t.v - iverilog -Wall -o core core.t.v \ No newline at end of file + iverilog -Wall -o core core.t.v + +alu: alu.v alu.t.v + iverilog -Wall -o alu alu.t.v + +adder_subtracter: adder_subtracter.v adder_subtracter.t.v + iverilog -Wall -o adder_subtracter adder_subtracter.t.v + +and: and_32bit.v and_32bit.t.v + iverilog -Wall -o and and_32bit.t.v + +nand: nand_32bit.v nand_32bit.t.v + iverilog -Wall -o nand nand_32bit + +nor: nor_32bit.v nor_32bit.t.v + iverilog -Wall -o nor nor_32bit + +or: or_32bit.v or_32bit.t.v + iverilog -Wall -o or or_32bit + +slt: slt.v slt.t.v + iverilog -Wall -o slt slt.t.v + +xor: xor_32bit.v xor_32bit.t.v + iverilog -Wall -o xor xor_32bit \ No newline at end of file From a7e4eeb843a411159729bb4c202d191bb1f0c9a4 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 23:06:47 -0500 Subject: [PATCH 012/190] Add memory files --- memory.t.v | 18 ++++++++++++++++++ memory.v | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 memory.t.v create mode 100644 memory.v diff --git a/memory.t.v b/memory.t.v new file mode 100644 index 0000000..8d65fe3 --- /dev/null +++ b/memory.t.v @@ -0,0 +1,18 @@ +/* +Test bench for data memory module. +*/ + +module memory_TEST(); + reg clk; + reg [31:0] address; + reg writeEnable; + reg [31:0] dataIn; + + wire dataOut; + + memory dut(clk, dataOut, address, writeEnable, dataIn); + + initial begin + // Test code here + end +endmodule \ No newline at end of file diff --git a/memory.v b/memory.v new file mode 100644 index 0000000..826e6c4 --- /dev/null +++ b/memory.v @@ -0,0 +1,28 @@ +/* +The memory used in the CPU +*/ + +module memory +#( + parameter addresswidth = 32, + parameter depth = 2**addresswidth, + parameter width = 32 +) +( + input clk, + output reg [width-1:0] dataOut, + input [addresswidth-1:0] address, + input writeEnable, + input [width-1:0] dataIn +); + + + reg [width-1:0] memory [depth-1:0]; + + always @(posedge clk) begin + if(writeEnable) + memory[address] <= dataIn; + dataOut <= memory[address]; + end + +endmodule \ No newline at end of file From ae055402363cb771bc0cc02ab19c8a8a7f1c6287 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 23:30:08 -0500 Subject: [PATCH 013/190] Add build rules for memory --- makefile | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index f8f191d..c1bb2e6 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,11 @@ -all: core alu +all: core alu regfile memory +# Core modules core: core.v core.t.v iverilog -Wall -o core core.t.v -alu: alu.v alu.t.v +# ALU modules +alu: alu.v alu.t.v adder_subtracter and nand nor or slt xor iverilog -Wall -o alu alu.t.v adder_subtracter: adder_subtracter.v adder_subtracter.t.v @@ -13,16 +15,33 @@ and: and_32bit.v and_32bit.t.v iverilog -Wall -o and and_32bit.t.v nand: nand_32bit.v nand_32bit.t.v - iverilog -Wall -o nand nand_32bit + iverilog -Wall -o nand nand_32bit.t.v nor: nor_32bit.v nor_32bit.t.v - iverilog -Wall -o nor nor_32bit + iverilog -Wall -o nor nor_32bit.t.v or: or_32bit.v or_32bit.t.v - iverilog -Wall -o or or_32bit + iverilog -Wall -o or or_32bit.t.v slt: slt.v slt.t.v iverilog -Wall -o slt slt.t.v xor: xor_32bit.v xor_32bit.t.v - iverilog -Wall -o xor xor_32bit \ No newline at end of file + iverilog -Wall -o xor xor_32bit.t.v + +# Regfile modules +regfile: regfile.t.v regfile.v decoder mux register + iverilog -Wall -o regfile regfile.t.v + +decoder: decoders.t.v decoders.v + iverilog -Wall -o decoder decoders.t.v + +mux: multiplexer.t.v multiplexer.v + iverilog -Wall -o mux multiplexer.t.v + +register: register.t.v register.v + iverilog -Wall -o register register.t.v + +# Memory modules +memory: memory.v memory.t.v + iverilog -Wall -o memory memory.t.v From ea4c132d4b8badeeb9d049fc8884361262fbc4dd Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:24:49 -0500 Subject: [PATCH 014/190] Add module for 4 input mux --- memory.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/memory.v b/memory.v index 826e6c4..54df8e3 100644 --- a/memory.v +++ b/memory.v @@ -4,7 +4,8 @@ The memory used in the CPU module memory #( - parameter addresswidth = 32, + // parameter addresswidth = 32, + parameter addresswidth = 8, parameter depth = 2**addresswidth, parameter width = 32 ) From bbb23994424872a3892264789cedf63ad9d48ff3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:25:08 -0500 Subject: [PATCH 015/190] Add tests for 4 input module --- memory.t.v | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/memory.t.v b/memory.t.v index 8d65fe3..c2bee8d 100644 --- a/memory.t.v +++ b/memory.t.v @@ -2,13 +2,15 @@ Test bench for data memory module. */ +`include "memory.v" + module memory_TEST(); reg clk; reg [31:0] address; reg writeEnable; reg [31:0] dataIn; - wire dataOut; + wire [31:0] dataOut; memory dut(clk, dataOut, address, writeEnable, dataIn); From 1375826a748efa21ad9a622c09aa175109911585 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:27:30 -0500 Subject: [PATCH 016/190] Add new module for four input multiplexer --- multiplexer.t.v | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ multiplexer.v | 15 +++++++++++++ 2 files changed, 72 insertions(+) diff --git a/multiplexer.t.v b/multiplexer.t.v index 99dced4..acf6c0b 100644 --- a/multiplexer.t.v +++ b/multiplexer.t.v @@ -64,6 +64,63 @@ module mux32to1by1Test end endmodule // mux32to1by1Test +module mux3to1by6Test + ( + input begintest, + output reg endtest, + output reg dutpassed + ); + + reg[5:0] input0, input1, input2, input3; + reg[1:0] address; + wire[5:0] out; + + mux4to1by6 DUT (input0, input1, input2, input3, address, out); + + always @(posedge begintest) begin + endtest = 0; + dutpassed = 1; + + // Test Case 1: + // Ensure that the value chosen by the mux matches + // the value at the given address. + input0 = 6'd1; + input1 = 6'd2; + input2 = 6'd3; + input3 = 6'd4; + address = 2'd0; + #5 + if (out != input0) begin + $display("3 wide 6 deep mux test case 1 failed at address 00."); + dutpassed = 0; + end + + address = 2'd1; + #5 + if (out != input1) begin + $display("3 wide 6 deep mux test case 1 failed at address 01."); + dutpassed = 0; + end + + address = 2'd2; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 10."); + dutpassed = 0; + end + + address = 2'd3; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 11."); + dutpassed = 0; + end + + #5 + endtest = 1; + end +endmodule + // Unit test the 32 wide 32 deep mux module. module mux32to32by1Test( input begintest, diff --git a/multiplexer.v b/multiplexer.v index dd4798a..b7d9b1d 100644 --- a/multiplexer.v +++ b/multiplexer.v @@ -1,3 +1,18 @@ +// Inputs are 6 by 1 addresses +module mux4to1by6 +( +input[5:0] input0, input1, input2, input3, +input[1:0] address, +output[5:0] out +); + wire[1:0] mux [5:0]; + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign out = mux[address]; +endmodule + // A 32:1 multiplexer. module mux32to1by1 ( From 37e04749eb1ba5738bc042ef635e8fd5cc009a9f Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:37:51 -0500 Subject: [PATCH 017/190] Parametize 4 input mux for code reuse --- multiplexer.t.v | 4 ++-- multiplexer.v | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/multiplexer.t.v b/multiplexer.t.v index acf6c0b..1db882d 100644 --- a/multiplexer.t.v +++ b/multiplexer.t.v @@ -64,7 +64,7 @@ module mux32to1by1Test end endmodule // mux32to1by1Test -module mux3to1by6Test +module mux4inputTest ( input begintest, output reg endtest, @@ -75,7 +75,7 @@ module mux3to1by6Test reg[1:0] address; wire[5:0] out; - mux4to1by6 DUT (input0, input1, input2, input3, address, out); + mux4input #(.width(6)) DUT (input0, input1, input2, input3, address, out); always @(posedge begintest) begin endtest = 0; diff --git a/multiplexer.v b/multiplexer.v index b7d9b1d..f38b85f 100644 --- a/multiplexer.v +++ b/multiplexer.v @@ -1,11 +1,14 @@ // Inputs are 6 by 1 addresses -module mux4to1by6 +module mux4input +#( + parameter width = 6 +) ( -input[5:0] input0, input1, input2, input3, +input[width-1:0] input0, input1, input2, input3, input[1:0] address, -output[5:0] out +output[width-1:0] out ); - wire[1:0] mux [5:0]; + wire[1:0] mux [width-1:0]; assign mux[0] = input0; assign mux[1] = input1; assign mux[2] = input2; From d0991bef7f62a6bdaaf432e8009df3ff1f953257 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 17:57:42 -0500 Subject: [PATCH 018/190] modified gitignore to ignore extra output files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 29086fd..00bc6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ !/**/ !*.* !makefile +*.out # Ignore gtkwave files *.vcd From b6fbcd354e0e2c208c8d9e29b50be3736b559c43 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 17:58:42 -0500 Subject: [PATCH 019/190] Added definition of Core module --- Core/Core.v | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Core/Core.v diff --git a/Core/Core.v b/Core/Core.v new file mode 100644 index 0000000..88659bc --- /dev/null +++ b/Core/Core.v @@ -0,0 +1,18 @@ +// Core controls the central registor and memory storage and manipulation + +module Core +( + input CLK, + // Decoded Instruction Values + input[5:0] Rd, Rt, Rs, + input[15:0] imm, + input[31:0] addedPC, + // Control Signals + input RegDst, RegWr, MemWr, ALUSrc, MemToReg, + + // Outputs + output[31:0] Da, + output isZero +); + +endmodule From efcc9996893f868dbb459762b17b191ef6826c37 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 18:35:44 -0500 Subject: [PATCH 020/190] Add Instruction Parser Shell --- Instruction_Parser/Instruction_Parser.v | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 Instruction_Parser/Instruction_Parser.v diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v new file mode 100644 index 0000000..aaae9e4 --- /dev/null +++ b/Instruction_Parser/Instruction_Parser.v @@ -0,0 +1,11 @@ +// Instruction Parser parses the relevant data and control signals from the instruction. + +module Instruction_Parser +( + input PC, + // Instruction values + output[5:0] Rs, Rd, Rt, + output[15:0] imm, + output[25:0] addr, + output ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel +) From 2bb139613c3cd08b20286b2e2168836afcf9c107 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 18:41:13 -0500 Subject: [PATCH 021/190] Added PC_Calc --- Instruction_Parser/Instruction_Parser.v | 4 +++- PC_Calc/PC_Calc.v | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 PC_Calc/PC_Calc.v diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index aaae9e4..675f48d 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -8,4 +8,6 @@ module Instruction_Parser output[15:0] imm, output[25:0] addr, output ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel -) +); + +endmodule diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v new file mode 100644 index 0000000..e4b39bb --- /dev/null +++ b/PC_Calc/PC_Calc.v @@ -0,0 +1,14 @@ +// PC_Calc Calculates the next program counter + +module PC_Calc +( + input[31:0] old_PC, + input isZero, + input PCSel, AddSel, + input[31:0] Da, + input[25:0] addr, + input[15:0] imm, + output[31:0] new_PC +); + +endmodule From 410bc2ad17c0552a819446f5bce23ce05c5393a9 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 19:16:27 -0500 Subject: [PATCH 022/190] Top-level module is done. --- CPU.v | 46 +++++++++++++++++++++++++ DFF.v | 15 ++++++++ Instruction_Parser/Instruction_Parser.v | 2 +- PC.v | 1 + 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 CPU.v create mode 100644 DFF.v create mode 100644 PC.v diff --git a/CPU.v b/CPU.v new file mode 100644 index 0000000..26b920c --- /dev/null +++ b/CPU.v @@ -0,0 +1,46 @@ +// 32 Bit CPU +// Ariana Olson, Andrew Pan, Jonah Spear + +`include "Instruction_Parser/Instruction_Parser.v" +`include "Core/Core.v" +`include "PC_Calc/PC_Calc.v" +`include "DFF.v" + +module CPU +( + input CLK +); + // PC is the current program counter, new_PC is what it's next value will be. + wire[31:0] PC, new_PC; + + DFF #(32) pc(.trigger(CLK), .enable(1), .q(new_PC), .d(PC)); + + wire[5:0] Rs, Rd, Rt; + wire[15:0] imm; + wire[25:0] addr; + wire ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel; + Instruction_Parser ip( + .PC(PC), + .Rs(Rs), .Rd(Rd), .Rt(Rt), + .imm(imm), .addr(addr), + .ALUCtrl(ALUCtrl), .MemToReg(MemToReg), + .MemWr(MemWr), .ALUSrc(ALUSrc), .PCSel(PCSel), + .RegDst(RegDst), .RegWr(RegWr), .AddSel(AddSel) + ); + + + wire[31:0] Da; + wire isZero; + Core c( + .Rs(Rs), .Rd(Rd), .Rt(Rt), + .RegDst(RegDst), .RegWr(RegWr), .MemWr(MemWr), + .ALUSrc(ALUSrc), .MemToReg(MemToReg), .Da(Da), .isZero(isZero) + ); + + PC_Calc pc_calc( + .old_PC(PC), .isZero(isZero), .PCSel(PCSel), .AddSel(AddSel), + .Da(Da), .addr(addr), .imm(imm), .new_PC(new_PC) + ); + + +endmodule diff --git a/DFF.v b/DFF.v new file mode 100644 index 0000000..bb8cf5e --- /dev/null +++ b/DFF.v @@ -0,0 +1,15 @@ +// DFF is a d flip flop. + +module DFF #( parameter W = 1 ) +( + input trigger, + input enable, + input [W-1:0] d, + output reg [W-1:0] q +); + always @(posedge trigger) begin + if(enable) begin + q <= d; + end + end +endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 675f48d..f599968 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -2,7 +2,7 @@ module Instruction_Parser ( - input PC, + input[31:0] PC, // Instruction values output[5:0] Rs, Rd, Rt, output[15:0] imm, diff --git a/PC.v b/PC.v new file mode 100644 index 0000000..b083817 --- /dev/null +++ b/PC.v @@ -0,0 +1 @@ +//PC is a d flip-flop that controls the From e1f828ae3e17dbe043ef141650c833bab18de410 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:28:50 -0500 Subject: [PATCH 023/190] Add zero flag --- adder_subtracter.t.v | 4 ++-- adder_subtracter.v | 10 ++++++++++ alu.t.v | 2 +- alu.v | 18 ++++++++++-------- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v index e2c0aa1..2e6f726 100644 --- a/adder_subtracter.t.v +++ b/adder_subtracter.t.v @@ -8,9 +8,9 @@ module test32bitAdder(); reg[31:0] b; reg[2:0] carryin; wire[31:0] ans; - wire carryout, overflow; + wire carryout, overflow, zero; - adder_subtracter adder0(ans[31:0], carryout, overflow, a[31:0], b[31:0], carryin[2:0]); + adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); initial begin $display("Input A Input B Command | Output Flag Carryout"); diff --git a/adder_subtracter.v b/adder_subtracter.v index f59fd57..fea62ec 100644 --- a/adder_subtracter.v +++ b/adder_subtracter.v @@ -184,6 +184,7 @@ module adder_subtracter output[31:0] ans, output carryout, output overflow, + output reg zero, input[31:0] opA, input[31:0] opB, input[2:0] command @@ -253,4 +254,13 @@ module adder_subtracter FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + always @(*) begin + if (ans === 32'b0) begin + zero <= 1; + end + + else begin + zero <= 0; + end + end endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v index 0d35733..322cd32 100644 --- a/alu.t.v +++ b/alu.t.v @@ -9,7 +9,7 @@ module testALU32bit(); wire flag; wire cout; - ALUcontrolLUT alu(cout, flag, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); initial begin $display("ALU Command Input A Input B | Output Flag Carryout"); diff --git a/alu.v b/alu.v index 8ee1ec0..47c9191 100644 --- a/alu.v +++ b/alu.v @@ -12,6 +12,7 @@ module ALUcontrolLUT ( output reg cout, //addsub only output reg flag, //addsub only + output reg zero, // addsub only output reg[31:0] finalsignal, input [2:0]ALUcommand, input [31:0]a, @@ -29,8 +30,9 @@ wire [31:0]norin; wire [31:0]orin; wire adder_cout; wire adder_flag; +wire adder_zero; -adder_subtracter addsub0(addsub[31:0],adder_cout,adder_flag,a[31:0],b[31:0],ALUcommand[2:0]); +adder_subtracter addsub0(addsub[31:0],adder_cout,adder_flag, adder_zero, a[31:0],b[31:0],ALUcommand[2:0]); xor_32bit xor0(xorin[31:0],a[31:0],b[31:0]); full_slt_32bit slt0(slt[31:0],a[31:0],b[31:0]); and_32bit and0(andin[31:0],a[31:0],b[31:0]); @@ -44,14 +46,14 @@ or_32bit or0(orin[31:0],a[31:0],b[31:0]); begin #5000 case (ALUcommand) - 3'b000: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; end - 3'b001: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; end + 3'b000: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; zero = adder_zero; end + 3'b001: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; zero = adder_zero; end 3'b010: begin finalsignal[31:0] = xorin[31:0]; cout = 0; flag = 0; end // carryout and flag should be 0 for all non-add/sub operations - 3'b011: begin finalsignal[31:0] = slt[31:0]; cout = 0; flag = 0; end - 3'b100: begin finalsignal[31:0] = andin[31:0]; cout = 0; flag = 0; end - 3'b101: begin finalsignal[31:0] = nandin[31:0]; cout = 0; flag = 0; end - 3'b110: begin finalsignal[31:0] = norin[31:0]; cout = 0; flag = 0; end - 3'b111: begin finalsignal[31:0] = orin[31:0]; cout = 0; flag = 0; end + 3'b011: begin finalsignal[31:0] = slt[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b100: begin finalsignal[31:0] = andin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b101: begin finalsignal[31:0] = nandin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b110: begin finalsignal[31:0] = norin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b111: begin finalsignal[31:0] = orin[31:0]; cout = 0; flag = 0; zero = 0; end endcase end endmodule From 80343e8726f0c67a253738ac8459a50fb1f3e36d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:29:14 -0500 Subject: [PATCH 024/190] Add new modules --- core.t.v | 16 +++++++++++----- core.v | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/core.t.v b/core.t.v index a636d6c..b33d5f1 100644 --- a/core.t.v +++ b/core.t.v @@ -9,13 +9,19 @@ module core_TEST(); wire is_zero; reg clk; - reg [31:0] rd; - reg [31:0] rt; - reg [31:0] rs; + reg [5:0] rd; + reg [5:0] rt; + reg [5:0] rs; reg [15:0] immediate; - reg [31:0] added_PC; + reg [31:0] new_PC; + reg [0:1] regdst; + reg [2:0] ALUcntrl; + reg AlUsrc; + reg MemWr; + reg RegWr; + reg [1:0] MemtoReg; - core dut (clk, rd, rt, rs, immediate, added_PC, Da, is_zero); + core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); initial begin // Test code here. diff --git a/core.v b/core.v index 60d93bf..b688d23 100644 --- a/core.v +++ b/core.v @@ -2,17 +2,62 @@ The section of the CPU containing the register file, data memory, and ALU. */ -module core ( +`include "alu.v" +`include "memory.v" +`include "regfile.v" +`include "signextend.v" + +module core +( input clk, - input [31:0] rd, - input [31:0] rt, - input [31:0] rs, + input [5:0] rd, + input [5:0] rt, + input [5:0] rs, input [15:0] immediate, - input [31:0] added_PC, + input [31:0] new_PC, + input [0:1] regdst, + input [2:0] ALUcntrl, + input AlUsrc, + input MemWr, + input RegWr, + input [1:0] MemtoReg, output [31:0] Da, output is_zero ); -// code here + wire[5:0] writeaddr; + + // Register file write address + mux4input #(.width(6)) regwriteaddr (rd, rt, 6'd31, 6'bx, regdst, writeaddr); + + wire[31:0] dataaout; + wire[31:0] databout; + wire[31:0] datain; + + // Register file + regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); + + // Sign extend + + wire[31:0] signextimm; + signextend extend (immediate, signextimm); + + // ALU operand 2 mux + wire[31:0] operandb; + + mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); + + // ALU + wire cout; + wire overflow; + wire[31:0] finalsignal; + + ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); + + // Regfile write data mux + reg[31:0] memout; + + mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); + endmodule \ No newline at end of file From 10ff9b9d3116936b3774ed28f0885e1911a6e504 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:30:02 -0500 Subject: [PATCH 025/190] Change address size --- decoders.v | 2 +- multiplexer.t.v | 2 +- multiplexer.v | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/decoders.v b/decoders.v index bfb1ff9..e0f9253 100644 --- a/decoders.v +++ b/decoders.v @@ -5,7 +5,7 @@ module decoder1to32 ( output[31:0] out, input enable, -input[4:0] address +input[5:0] address ); assign out = enable< Date: Wed, 8 Nov 2017 19:30:25 -0500 Subject: [PATCH 026/190] Add signextend module --- makefile | 6 +++++- signextend.v | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 signextend.v diff --git a/makefile b/makefile index c1bb2e6..6f92f94 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -all: core alu regfile memory +all: core alu regfile memory signextend # Core modules core: core.v core.t.v @@ -45,3 +45,7 @@ register: register.t.v register.v # Memory modules memory: memory.v memory.t.v iverilog -Wall -o memory memory.t.v + +# Concatenation modules +signextend: signextend.v + iverilog -Wall -o signextend signextend.v diff --git a/signextend.v b/signextend.v new file mode 100644 index 0000000..35effe1 --- /dev/null +++ b/signextend.v @@ -0,0 +1,12 @@ +/* +Implement the sign extend immediate operation defined by the MIPS reference guide. +*/ + +module signextend +( +input[15:0] immediate, +output[31:0] signextendimmediate +); + + assign signextendimmediate = {{16{immediate[15]}}, {immediate[15:0]}}; +endmodule \ No newline at end of file From c902bef97dc778fa9f0036e52bf066f7d1cf1a5b Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:30:50 -0500 Subject: [PATCH 027/190] Change mem and addr size --- memory.v | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/memory.v b/memory.v index 54df8e3..e344080 100644 --- a/memory.v +++ b/memory.v @@ -4,9 +4,8 @@ The memory used in the CPU module memory #( - // parameter addresswidth = 32, - parameter addresswidth = 8, - parameter depth = 2**addresswidth, + parameter addresswidth = 32, + parameter depth = addresswidth, parameter width = 32 ) ( From 43fb3ac033c9c307d7bae45424c22adbd54f5104 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:31:33 -0500 Subject: [PATCH 028/190] Change address size --- regfile.t.v | 12 ++++++------ regfile.v | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/regfile.t.v b/regfile.t.v index 059c0ec..02b4a13 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -10,9 +10,9 @@ module hw4testbenchharness(); wire[31:0] ReadData1; // Data from first register read wire[31:0] ReadData2; // Data from second register read wire[31:0] WriteData; // Data to write to register - wire[4:0] ReadRegister1; // Address of first register to read - wire[4:0] ReadRegister2; // Address of second register to read - wire[4:0] WriteRegister; // Address of register to write + wire[5:0] ReadRegister1; // Address of first register to read + wire[5:0] ReadRegister2; // Address of second register to read + wire[5:0] WriteRegister; // Address of register to write wire RegWrite; // Enable writing of register when High wire Clk; // Clock (Positive Edge Triggered) @@ -86,9 +86,9 @@ output reg dutpassed, // Signal test result input[31:0] ReadData1, input[31:0] ReadData2, output reg[31:0] WriteData, -output reg[4:0] ReadRegister1, -output reg[4:0] ReadRegister2, -output reg[4:0] WriteRegister, +output reg[5:0] ReadRegister1, +output reg[5:0] ReadRegister2, +output reg[5:0] WriteRegister, output reg RegWrite, output reg Clk ); diff --git a/regfile.v b/regfile.v index 893bf11..49c885c 100644 --- a/regfile.v +++ b/regfile.v @@ -15,9 +15,9 @@ module regfile output[31:0] ReadData1, // Contents of first register read output[31:0] ReadData2, // Contents of second register read input[31:0] WriteData, // Contents to write to register -input[4:0] ReadRegister1, // Address of first register to read -input[4:0] ReadRegister2, // Address of second register to read -input[4:0] WriteRegister, // Address of register to write +input[5:0] ReadRegister1, // Address of first register to read +input[5:0] ReadRegister2, // Address of second register to read +input[5:0] WriteRegister, // Address of register to write input RegWrite, // Enable writing of register when High input Clk // Clock (Positive Edge Triggered) ); From 98c4dbc187fb007e61cf2fdfd67749c921915708 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 19:32:04 -0500 Subject: [PATCH 029/190] Add initial Instruction_Parser parts, no tests --- Instruction_Parser/Decoder.v | 17 +++++++++++++++++ Instruction_Parser/Instruction_Parser.v | 4 ++++ Instruction_Parser/Memory.v | 22 ++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 Instruction_Parser/Decoder.v create mode 100644 Instruction_Parser/Memory.v diff --git a/Instruction_Parser/Decoder.v b/Instruction_Parser/Decoder.v new file mode 100644 index 0000000..a7bf5fa --- /dev/null +++ b/Instruction_Parser/Decoder.v @@ -0,0 +1,17 @@ +// Decoder splits the insruction into its parts + +module Decoder +( + input[31:0] Instr, + output[5:0] Op, Rs, Rd, Rt, + output[15:0] imm, + output[25:0] addr +); + + assign Op = Instr[31:26]; + assign Rs = Instr[25:21]; + assign Rt = Instr[20:16]; + assign Rd = Instr[15:11]; + assign imm = Instr[15:0]; + assign addr = Instr[25:0]; +endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index f599968..5282759 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -1,5 +1,7 @@ // Instruction Parser parses the relevant data and control signals from the instruction. +`include "Memory.v" + module Instruction_Parser ( input[31:0] PC, @@ -9,5 +11,7 @@ module Instruction_Parser output[25:0] addr, output ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel ); + wire[31:0] instr; + Memory Instruction_Memory(.Addr(PC), .DataOut(instr)); endmodule diff --git a/Instruction_Parser/Memory.v b/Instruction_Parser/Memory.v new file mode 100644 index 0000000..38509c4 --- /dev/null +++ b/Instruction_Parser/Memory.v @@ -0,0 +1,22 @@ +// Memory is a big d flip flop + +module Memory +( + input clk, regWE, + input[9:0] Addr, + input[31:0] DataIn, + output[31:0] DataOut +); + + reg [31:0] mem[1023:0]; + + always @(posedge clk) begin + if (regWE) begin + mem[Addr] <= DataIn; + end + end + + //initial $readmemh(“file.dat”, mem); + + assign DataOut = mem[Addr]; +endmodule From f458d8e49023e7e982f42e284441ff684354ca27 Mon Sep 17 00:00:00 2001 From: apan64 Date: Wed, 8 Nov 2017 19:57:09 -0500 Subject: [PATCH 030/190] work on pc calculator --- PC_Calc/PC_Calc.v | 10 +++++- PC_Calc/addr_concat.t.v | 18 ++++++++++ PC_Calc/addr_concat.v | 8 +++++ PC_Calc/imm_concat.t.v | 15 +++++++++ PC_Calc/imm_concat.v | 7 ++++ PC_Calc/is_zero_and.t.v | 17 ++++++++++ PC_Calc/is_zero_and.v | 8 +++++ PC_Calc/multiplexer.v | 74 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 PC_Calc/addr_concat.t.v create mode 100644 PC_Calc/addr_concat.v create mode 100644 PC_Calc/imm_concat.t.v create mode 100644 PC_Calc/imm_concat.v create mode 100644 PC_Calc/is_zero_and.t.v create mode 100644 PC_Calc/is_zero_and.v create mode 100644 PC_Calc/multiplexer.v diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index e4b39bb..3c0cf46 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -1,4 +1,6 @@ // PC_Calc Calculates the next program counter +`include "addr_concat.v" +`include "imm_concat.v" module PC_Calc ( @@ -8,7 +10,13 @@ module PC_Calc input[31:0] Da, input[25:0] addr, input[15:0] imm, - output[31:0] new_PC + output[31:0] added_PC ); + wire[31:0] extendedImm; + immConcat iconcat(extendedImm[31:0], imm[15:0]); + + wire immZeroed; + + endmodule diff --git a/PC_Calc/addr_concat.t.v b/PC_Calc/addr_concat.t.v new file mode 100644 index 0000000..8981074 --- /dev/null +++ b/PC_Calc/addr_concat.t.v @@ -0,0 +1,18 @@ +`timescale 1 ns / 1 ps +`include "addr_concat.v" + +module testConcat(); + wire[31:0] ans; + reg[31:0] pc; + reg[25:0] jumpAddr; + + addrConcat concat(ans[31:0], pc[31:0], jumpAddr[25:0]); + initial begin + pc = 32'b11000000000000000000000000000000; + jumpAddr = 26'b10101010101010101010101010; #100 + $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); + pc = 32'b11110000000000000000000000000000; + jumpAddr = 26'b11111111111111111111111111; #100 + $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/addr_concat.v b/PC_Calc/addr_concat.v new file mode 100644 index 0000000..e2301a0 --- /dev/null +++ b/PC_Calc/addr_concat.v @@ -0,0 +1,8 @@ +module addrConcat +( + output[31:0] out, + input[31:0] pc, + input[25:0] jumpAddr +); + assign out = {pc[31:28], jumpAddr, 2'b00}; +endmodule \ No newline at end of file diff --git a/PC_Calc/imm_concat.t.v b/PC_Calc/imm_concat.t.v new file mode 100644 index 0000000..8585987 --- /dev/null +++ b/PC_Calc/imm_concat.t.v @@ -0,0 +1,15 @@ +`timescale 1 ns / 1 ps +`include "imm_concat.v" + +module testConcat(); + wire[31:0] ans; + reg[15:0] imm; + + immConcat concat(ans[31:0], imm[15:0]); + initial begin + imm = 16'b1000000000000001; #100 + $display("%b %b", imm[15:0], ans[31:0]); + imm = 16'b0111111111111110; #100 + $display("%b %b", imm[15:0], ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/imm_concat.v b/PC_Calc/imm_concat.v new file mode 100644 index 0000000..ded9733 --- /dev/null +++ b/PC_Calc/imm_concat.v @@ -0,0 +1,7 @@ +module immConcat +( + output[31:0] out, + input[15:0] imm +); + assign out = {{14{imm[15]}}, imm, 2'b00}; +endmodule \ No newline at end of file diff --git a/PC_Calc/is_zero_and.t.v b/PC_Calc/is_zero_and.t.v new file mode 100644 index 0000000..7d32bd9 --- /dev/null +++ b/PC_Calc/is_zero_and.t.v @@ -0,0 +1,17 @@ +`timescale 1 ns / 1 ps +`include "is_zero_and.v" + +module testIsZero(); + wire[31:0] ans; + reg[31:0] imm; + reg isZero; + + isZeroAnd iszero(ans[31:0], imm[31:0], isZero); + initial begin + imm = 32'b11111111111111111111111111111111; + isZero = 1; #1000 + $display("%b %b %b", imm[31:0], isZero, ans[31:0]); + isZero = 0; #1000 + $display("%b %b %b", imm[31:0], isZero, ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/is_zero_and.v b/PC_Calc/is_zero_and.v new file mode 100644 index 0000000..6c1530f --- /dev/null +++ b/PC_Calc/is_zero_and.v @@ -0,0 +1,8 @@ +module isZeroAnd +( + output[31:0] out, + input[31:0] imm, + input isZero +); + assign out = (imm & {32{isZero}}); +endmodule \ No newline at end of file diff --git a/PC_Calc/multiplexer.v b/PC_Calc/multiplexer.v new file mode 100644 index 0000000..a12e6a1 --- /dev/null +++ b/PC_Calc/multiplexer.v @@ -0,0 +1,74 @@ +// Inputs are 6 by 1 addresses +module mux4input +#( + parameter width = 6 +) +( +input[width-1:0] input0, input1, input2, input3, +input[1:0] address, +output[width-1:0] out +); + wire[1:0] mux [width-1:0]; + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign out = mux[address]; +endmodule + +// A 32:1 multiplexer. +module mux32to1by1 +( +output out, +input[5:0] address, +input[31:0] inputs +); + assign out = inputs[address]; +endmodule // mux32to1by1 + +module mux32to1by32 +( +output[31:0] out, +input[5:0] address, +input[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8, +input[31:0] input9, input10, input11, input12, input13, input14, input15, input16, +input[31:0] input17, input18, input19, input20, input21, input22, input23, input24, +input[31:0] input25, input26, input27, input28, input29, input30, input31 +); + + wire[31:0] mux[31:0]; // Create a 2D array of wires + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign mux[4] = input4; + assign mux[5] = input5; + assign mux[6] = input6; + assign mux[7] = input7; + assign mux[8] = input8; + assign mux[9] = input9; + assign mux[10] = input10; + assign mux[11] = input11; + assign mux[12] = input12; + assign mux[13] = input13; + assign mux[14] = input14; + assign mux[15] = input15; + assign mux[16] = input16; + assign mux[17] = input17; + assign mux[18] = input18; + assign mux[19] = input19; + assign mux[20] = input20; + assign mux[21] = input21; + assign mux[22] = input22; + assign mux[23] = input23; + assign mux[24] = input24; + assign mux[25] = input25; + assign mux[26] = input26; + assign mux[27] = input27; + assign mux[28] = input28; + assign mux[29] = input29; + assign mux[30] = input30; + assign mux[31] = input31; + assign out = mux[address]; + +endmodule // mux32to1by32S \ No newline at end of file From 82192b827f0599f42adbf13bb5b262f692b1584c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 20:24:02 -0500 Subject: [PATCH 031/190] Change width of regfile addresses --- core.t.v | 19 +++++++++++++++---- core.v | 15 +++++++++------ decoders.v | 2 +- memory.v | 2 +- multiplexer.t.v | 4 ++-- multiplexer.v | 4 ++-- regfile.t.v | 12 ++++++------ regfile.v | 6 +++--- register.v | 2 +- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/core.t.v b/core.t.v index b33d5f1..d65d6d8 100644 --- a/core.t.v +++ b/core.t.v @@ -9,9 +9,9 @@ module core_TEST(); wire is_zero; reg clk; - reg [5:0] rd; - reg [5:0] rt; - reg [5:0] rs; + reg [4:0] rd; + reg [4:0] rt; + reg [4:0] rs; reg [15:0] immediate; reg [31:0] new_PC; reg [0:1] regdst; @@ -23,7 +23,18 @@ module core_TEST(); core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); + initial clk = 0; + always #10 clk = !clk; + initial begin - // Test code here. + $dumpfile("core.vcd"); + $dumpvars(0, core_TEST); + + // Test Case 1: Load Word + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; + rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; + + + $finish; end endmodule \ No newline at end of file diff --git a/core.v b/core.v index b688d23..2d0c29c 100644 --- a/core.v +++ b/core.v @@ -10,9 +10,9 @@ The section of the CPU containing the register file, data memory, and ALU. module core ( input clk, - input [5:0] rd, - input [5:0] rt, - input [5:0] rs, + input [4:0] rd, + input [4:0] rt, + input [4:0] rs, input [15:0] immediate, input [31:0] new_PC, input [0:1] regdst, @@ -25,10 +25,10 @@ module core output is_zero ); - wire[5:0] writeaddr; + wire[4:0] writeaddr; // Register file write address - mux4input #(.width(6)) regwriteaddr (rd, rt, 6'd31, 6'bx, regdst, writeaddr); + mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); wire[31:0] dataaout; wire[31:0] databout; @@ -55,9 +55,12 @@ module core ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); // Regfile write data mux - reg[31:0] memout; + wire[31:0] memout; mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); + // Data Meomory + memory datamemory (clk, memout, finalsignal, MemWr, databout); + endmodule \ No newline at end of file diff --git a/decoders.v b/decoders.v index e0f9253..bfb1ff9 100644 --- a/decoders.v +++ b/decoders.v @@ -5,7 +5,7 @@ module decoder1to32 ( output[31:0] out, input enable, -input[5:0] address +input[4:0] address ); assign out = enable< Date: Wed, 8 Nov 2017 20:52:15 -0500 Subject: [PATCH 032/190] Tests passing --- Instruction_Parser/Decoder.t.v | 55 +++++++++++++++++++++++++ Instruction_Parser/Decoder.v | 3 +- Instruction_Parser/Instruction_Parser.v | 2 +- 3 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 Instruction_Parser/Decoder.t.v diff --git a/Instruction_Parser/Decoder.t.v b/Instruction_Parser/Decoder.t.v new file mode 100644 index 0000000..9ef5730 --- /dev/null +++ b/Instruction_Parser/Decoder.t.v @@ -0,0 +1,55 @@ +// Tests the Decoder + +`include "Decoder.v" + +module testDecoder(); + + reg[31:0] instr; + wire[5:0] Op; + wire[4:0] Rs, Rd, Rt; + wire[15:0] imm; + wire[25:0] addr; + + Decoder dec( + .Instr(instr), .Op(Op), .Rs(Rs), + .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) + ); + + initial begin + // $dumpfile("decoder.vcd"); + // $dumpvars; + instr = 32'b00000000000000000000000000000000; #1 + if ((Op == 6'b000000) && (Rs == 5'b00000) && + (Rd == 5'b00000) && (Rt == 5'b00000) && + (imm == 16'b0000000000000000) && + (addr == 26'b00000000000000000000000000)) begin + $display("Test 1 Passed!"); + end + else begin + $display("Test 1 Failed!"); + end + + instr = 32'b11111111111111111111111111111111; #1 + if ((Op == 6'b111111) && (Rs == 5'b11111) && + (Rd == 5'b11111) && (Rt == 5'b11111) && + (imm == 16'b1111111111111111) && + (addr == 26'b11111111111111111111111111)) begin + $display("Test 2 Passed!"); + end + else begin + $display("Test 2 Failed!"); + end + + instr = 32'b11001100110011001100110011001100; #1 + if ((Op == 6'b110011) && (Rs == 5'b00110) && + (Rd == 5'b11001) && (Rt == 5'b01100) && + (imm == 16'b1100110011001100) && + (addr == 26'b00110011001100110011001100)) begin + $display("Test 3 Passed!"); + end + else begin + $display("Test 3 Failed!"); + end + end + +endmodule diff --git a/Instruction_Parser/Decoder.v b/Instruction_Parser/Decoder.v index a7bf5fa..0ff9e7b 100644 --- a/Instruction_Parser/Decoder.v +++ b/Instruction_Parser/Decoder.v @@ -3,7 +3,8 @@ module Decoder ( input[31:0] Instr, - output[5:0] Op, Rs, Rd, Rt, + output[5:0] Op, + output[4:0] Rs, Rd, Rt, output[15:0] imm, output[25:0] addr ); diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 5282759..79895f5 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -6,7 +6,7 @@ module Instruction_Parser ( input[31:0] PC, // Instruction values - output[5:0] Rs, Rd, Rt, + output[4:0] Rs, Rd, Rt, output[15:0] imm, output[25:0] addr, output ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel From 1736bd319a0657c540ddbbd4310499a0f167260d Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Wed, 8 Nov 2017 21:15:14 -0500 Subject: [PATCH 033/190] Increase spacing from 2 to 4 --- Instruction_Parser/Decoder.v | 22 +++++++++++----------- Instruction_Parser/Instruction_Parser.v | 9 +++++++++ Instruction_Parser/Memory.v | 22 +++++++++++----------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Instruction_Parser/Decoder.v b/Instruction_Parser/Decoder.v index 0ff9e7b..5884e27 100644 --- a/Instruction_Parser/Decoder.v +++ b/Instruction_Parser/Decoder.v @@ -2,17 +2,17 @@ module Decoder ( - input[31:0] Instr, - output[5:0] Op, - output[4:0] Rs, Rd, Rt, - output[15:0] imm, - output[25:0] addr + input[31:0] Instr, + output[5:0] Op, + output[4:0] Rs, Rd, Rt, + output[15:0] imm, + output[25:0] addr ); - assign Op = Instr[31:26]; - assign Rs = Instr[25:21]; - assign Rt = Instr[20:16]; - assign Rd = Instr[15:11]; - assign imm = Instr[15:0]; - assign addr = Instr[25:0]; + assign Op = Instr[31:26]; + assign Rs = Instr[25:21]; + assign Rt = Instr[20:16]; + assign Rd = Instr[15:11]; + assign imm = Instr[15:0]; + assign addr = Instr[25:0]; endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 79895f5..86d4fd5 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -14,4 +14,13 @@ module Instruction_Parser wire[31:0] instr; Memory Instruction_Memory(.Addr(PC), .DataOut(instr)); + wire[5:0] Op; + wire[4:0] Rs, Rd, Rt; + wire[15:0] imm; + wire[25:0] addr; + Decoder dec( + .Instr(instr), .Op(Op), .Rs(Rs), + .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) + ); + endmodule diff --git a/Instruction_Parser/Memory.v b/Instruction_Parser/Memory.v index 38509c4..071e86a 100644 --- a/Instruction_Parser/Memory.v +++ b/Instruction_Parser/Memory.v @@ -2,21 +2,21 @@ module Memory ( - input clk, regWE, - input[9:0] Addr, - input[31:0] DataIn, - output[31:0] DataOut + input clk, regWE, + input[9:0] Addr, + input[31:0] DataIn, + output[31:0] DataOut ); - reg [31:0] mem[1023:0]; + reg [31:0] mem[1023:0]; - always @(posedge clk) begin - if (regWE) begin - mem[Addr] <= DataIn; + always @(posedge clk) begin + if (regWE) begin + mem[Addr] <= DataIn; + end end - end - //initial $readmemh(“file.dat”, mem); + //initial $readmemh(“file.dat”, mem); - assign DataOut = mem[Addr]; + assign DataOut = mem[Addr]; endmodule From 52dd89fbb6097bf5fb6d1bcdb4424a4d3969790e Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 9 Nov 2017 13:07:34 -0500 Subject: [PATCH 034/190] Add controller --- Instruction_Parser/Controller.v | 166 ++++++++++++++++++++++++ Instruction_Parser/Decoder.t.v | 10 +- Instruction_Parser/Decoder.v | 2 + Instruction_Parser/Instruction_Parser.v | 4 +- 4 files changed, 175 insertions(+), 7 deletions(-) create mode 100644 Instruction_Parser/Controller.v diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v new file mode 100644 index 0000000..d812821 --- /dev/null +++ b/Instruction_Parser/Controller.v @@ -0,0 +1,166 @@ +// Controller generates the correct control signals based on the operation + +module Controller +( + input[5:0] Op, funct, + output reg[2:0] ALUCtrl, + output reg[1:0] MemToReg, RegDst, PCSel, AddSel, + output reg MemWr, ALUSrc, RegWr +); + + // Opcodes + localparam LW = 6'h23; + localparam SW = 6'h2b; + localparam J = 6'h2; + localparam JAL = 6'h3; + localparam BNE = 6'h5; + localparam XORI = 6'he; + localparam ADDI = 6'h8; + + // These instructions all have opcode 0 and are designated by funct + localparam JR_f = 6'h08; + localparam ADD_f = 6'h20; + localparam SLT_f = 6'h2a; + localparam SUB_f = 6'h22; + + always @ * begin + case (Op) + LW: begin + RegDst = 1; + ALUSrc = 1; + RegWr = 1; + MemWr = 0; + //ALUCtrl = add + MemToReg = 1; + PCSel = 1; + AddSel = 1'bx; + end + SW: begin + RegDst = 1'bx; + ALUSrc = 1; + RegWr = 0; + MemWr = 1; + //ALUCtrl = add + MemToReg = 1'bx; + PCSel = 1; + AddSel = 1'bx; + end + J: begin + RegDst = 1'bx; + ALUSrc = 1'bx; + RegWr = 0; + MemWr = 1; + //ALUCtrl = x + MemToReg = 1'bx; + PCSel = 0; + AddSel = 0; + end + JAL: begin + RegDst = 2'd2; + ALUSrc = 1'bx; + RegWr = 1; + MemWr = 0; + //ALUCtrl = x + MemToReg = 2'd2; + PCSel = 0; + AddSel = 1; + end + BNE: begin + RegDst = 2'bxx; + ALUSrc = 0; + RegWr = 0; + MemWr = 0; + //ALUCtrl = sub + MemToReg = 2'bxx; + PCSel = 1; + AddSel = 2'd2; + end + XORI: begin + RegDst = 1; + ALUSrc = 1; + RegWr = 1; + MemWr = 0; + //ALUCtrl = xor + MemToReg = 0; + PCSel = 1; + AddSel = 0; + end + ADDI: begin + RegDst = 1; + ALUSrc = 1; + RegWr = 1; + MemWr = 0; + //ALUCtrl = add + MemToReg = 0; + PCSel = 1; + AddSel = 0; + end + // Multiple functions have an Op of 0 + 0: begin + case (funct) + JR_f: begin + RegDst = 2'bxx; + ALUSrc = 1'bx; + RegWr = 0; + MemWr = 0; + //ALUCtrl = x + MemToReg = 1'bx; + PCSel = 2'd2; + AddSel = 0; + end + ADD_f: begin + RegDst = 0; + ALUSrc = 0; + RegWr = 1; + MemWr = 0; + //ALUCtrl = add + MemToReg = 0; + PCSel = 1; + AddSel = 0; + end + SLT_f: begin + RegDst = 0; + ALUSrc = 0; + RegWr = 1; + MemWr = 0; + //ALUCtrl = SLT + MemToReg = 0; + PCSel = 1; + AddSel = 0; + end + SUB_f: begin + RegDst = 0; + ALUSrc = 0; + RegWr = 1; + MemWr = 0; + //ALUCtrl = SUB + MemToReg = 0; + PCSel = 1; + AddSel = 0; + end + default: begin + RegDst = 2'bxx; + ALUSrc = 1'bx; + RegWr = 1'bx; + MemWr = 1'bx; + //ALUCtrl = x + MemToReg = 1'bx; + PCSel = 2'bxx; + AddSel = 1'bx; + end + endcase + end + default: begin + RegDst = 2'bxx; + ALUSrc = 1'bx; + RegWr = 1'bx; + MemWr = 1'bx; + //ALUCtrl = x + MemToReg = 1'bx; + PCSel = 2'bxx; + AddSel = 1'bx; + end + endcase + end + +endmodule diff --git a/Instruction_Parser/Decoder.t.v b/Instruction_Parser/Decoder.t.v index 9ef5730..2391fda 100644 --- a/Instruction_Parser/Decoder.t.v +++ b/Instruction_Parser/Decoder.t.v @@ -5,13 +5,13 @@ module testDecoder(); reg[31:0] instr; - wire[5:0] Op; + wire[5:0] Op, funct; wire[4:0] Rs, Rd, Rt; wire[15:0] imm; wire[25:0] addr; Decoder dec( - .Instr(instr), .Op(Op), .Rs(Rs), + .Instr(instr), .Op(Op), .funct(funct), .Rs(Rs), .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) ); @@ -21,7 +21,7 @@ module testDecoder(); instr = 32'b00000000000000000000000000000000; #1 if ((Op == 6'b000000) && (Rs == 5'b00000) && (Rd == 5'b00000) && (Rt == 5'b00000) && - (imm == 16'b0000000000000000) && + (imm == 16'b0000000000000000) && (funct == 6'b000000) && (addr == 26'b00000000000000000000000000)) begin $display("Test 1 Passed!"); end @@ -32,7 +32,7 @@ module testDecoder(); instr = 32'b11111111111111111111111111111111; #1 if ((Op == 6'b111111) && (Rs == 5'b11111) && (Rd == 5'b11111) && (Rt == 5'b11111) && - (imm == 16'b1111111111111111) && + (imm == 16'b1111111111111111) && (funct == 6'b111111) && (addr == 26'b11111111111111111111111111)) begin $display("Test 2 Passed!"); end @@ -43,7 +43,7 @@ module testDecoder(); instr = 32'b11001100110011001100110011001100; #1 if ((Op == 6'b110011) && (Rs == 5'b00110) && (Rd == 5'b11001) && (Rt == 5'b01100) && - (imm == 16'b1100110011001100) && + (imm == 16'b1100110011001100) && (funct == 6'b001100) && (addr == 26'b00110011001100110011001100)) begin $display("Test 3 Passed!"); end diff --git a/Instruction_Parser/Decoder.v b/Instruction_Parser/Decoder.v index 5884e27..e965593 100644 --- a/Instruction_Parser/Decoder.v +++ b/Instruction_Parser/Decoder.v @@ -5,6 +5,7 @@ module Decoder input[31:0] Instr, output[5:0] Op, output[4:0] Rs, Rd, Rt, + output[5:0] funct, output[15:0] imm, output[25:0] addr ); @@ -13,6 +14,7 @@ module Decoder assign Rs = Instr[25:21]; assign Rt = Instr[20:16]; assign Rd = Instr[15:11]; + assign funct = Instr[5:0]; assign imm = Instr[15:0]; assign addr = Instr[25:0]; endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 86d4fd5..7e5a1ca 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -19,8 +19,8 @@ module Instruction_Parser wire[15:0] imm; wire[25:0] addr; Decoder dec( - .Instr(instr), .Op(Op), .Rs(Rs), - .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) + .Instr(instr), .Op(Op), .funct(funct), + .Rs(Rs), .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) ); endmodule From 60a1ede9d3101d7ff991484194d7ea1acf0f1580 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 9 Nov 2017 18:46:15 -0500 Subject: [PATCH 035/190] Add alu control outs --- Instruction_Parser/Controller.v | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index d812821..6bcd812 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -23,6 +23,12 @@ module Controller localparam SLT_f = 6'h2a; localparam SUB_f = 6'h22; + // ALU Control mapping + localparam alu_add = 2'd0; + localparam alu_sub = 2'd1; + localparam alu_xor = 2'd2; + localparam alu_slt = 2'd4; + always @ * begin case (Op) LW: begin @@ -30,7 +36,7 @@ module Controller ALUSrc = 1; RegWr = 1; MemWr = 0; - //ALUCtrl = add + ALUCtrl = alu_add; MemToReg = 1; PCSel = 1; AddSel = 1'bx; @@ -40,7 +46,7 @@ module Controller ALUSrc = 1; RegWr = 0; MemWr = 1; - //ALUCtrl = add + ALUCtrl = alu_add; MemToReg = 1'bx; PCSel = 1; AddSel = 1'bx; @@ -50,7 +56,7 @@ module Controller ALUSrc = 1'bx; RegWr = 0; MemWr = 1; - //ALUCtrl = x + ALUCtrl = 2'bxx; MemToReg = 1'bx; PCSel = 0; AddSel = 0; @@ -60,7 +66,7 @@ module Controller ALUSrc = 1'bx; RegWr = 1; MemWr = 0; - //ALUCtrl = x + ALUCtrl = 2'bxx; MemToReg = 2'd2; PCSel = 0; AddSel = 1; @@ -70,7 +76,7 @@ module Controller ALUSrc = 0; RegWr = 0; MemWr = 0; - //ALUCtrl = sub + ALUCtrl = alu_sub; MemToReg = 2'bxx; PCSel = 1; AddSel = 2'd2; @@ -80,7 +86,7 @@ module Controller ALUSrc = 1; RegWr = 1; MemWr = 0; - //ALUCtrl = xor + ALUCtrl = alu_xor; MemToReg = 0; PCSel = 1; AddSel = 0; @@ -90,7 +96,7 @@ module Controller ALUSrc = 1; RegWr = 1; MemWr = 0; - //ALUCtrl = add + ALUCtrl = alu_add; MemToReg = 0; PCSel = 1; AddSel = 0; @@ -103,7 +109,7 @@ module Controller ALUSrc = 1'bx; RegWr = 0; MemWr = 0; - //ALUCtrl = x + ALUCtrl = 2'bxx; MemToReg = 1'bx; PCSel = 2'd2; AddSel = 0; @@ -113,7 +119,7 @@ module Controller ALUSrc = 0; RegWr = 1; MemWr = 0; - //ALUCtrl = add + ALUCtrl = alu_add; MemToReg = 0; PCSel = 1; AddSel = 0; @@ -123,7 +129,7 @@ module Controller ALUSrc = 0; RegWr = 1; MemWr = 0; - //ALUCtrl = SLT + ALUCtrl = alu_slt; MemToReg = 0; PCSel = 1; AddSel = 0; @@ -133,7 +139,7 @@ module Controller ALUSrc = 0; RegWr = 1; MemWr = 0; - //ALUCtrl = SUB + ALUCtrl = alu_sub; MemToReg = 0; PCSel = 1; AddSel = 0; @@ -143,7 +149,7 @@ module Controller ALUSrc = 1'bx; RegWr = 1'bx; MemWr = 1'bx; - //ALUCtrl = x + ALUCtrl = 2'bxx; MemToReg = 1'bx; PCSel = 2'bxx; AddSel = 1'bx; @@ -155,7 +161,7 @@ module Controller ALUSrc = 1'bx; RegWr = 1'bx; MemWr = 1'bx; - //ALUCtrl = x + ALUCtrl = 2'bxx; MemToReg = 1'bx; PCSel = 2'bxx; AddSel = 1'bx; From 1a7a36c8b0aadfcdf2b8960d02f237980d57d702 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 9 Nov 2017 18:50:14 -0500 Subject: [PATCH 036/190] Move core module files to subfolder --- Core/ALU/adder.v | 76 +++++ Core/ALU/adder_subtracter.t.v | 60 ++++ Core/ALU/adder_subtracter.v | 266 ++++++++++++++++++ Core/ALU/alu.t.v | 507 ++++++++++++++++++++++++++++++++++ Core/ALU/alu.v | 59 ++++ Core/ALU/and_32bit.t.v | 36 +++ Core/ALU/and_32bit.v | 40 +++ Core/ALU/nand_32bit.t.v | 36 +++ Core/ALU/nand_32bit.v | 40 +++ Core/ALU/nor_32bit.t.v | 36 +++ Core/ALU/nor_32bit.v | 40 +++ Core/ALU/or_32bit.t.v | 30 ++ Core/ALU/or_32bit.v | 40 +++ Core/ALU/slt.t.v | 40 +++ Core/ALU/slt.v | 110 ++++++++ Core/ALU/xor_32bit.t.v | 36 +++ Core/ALU/xor_32bit.v | 40 +++ Core/core.t.v | 40 +++ Core/core.v | 66 +++++ Core/decoders.t.v | 41 +++ Core/decoders.v | 20 ++ Core/memory.t.v | 20 ++ Core/memory.v | 28 ++ Core/multiplexer.t.v | 165 +++++++++++ Core/multiplexer.v | 74 +++++ Core/regfile.t.v | 176 ++++++++++++ Core/regfile.v | 114 ++++++++ Core/register.t.v | 121 ++++++++ Core/register.v | 48 ++++ Core/signextend.v | 12 + 30 files changed, 2417 insertions(+) create mode 100644 Core/ALU/adder.v create mode 100644 Core/ALU/adder_subtracter.t.v create mode 100644 Core/ALU/adder_subtracter.v create mode 100644 Core/ALU/alu.t.v create mode 100644 Core/ALU/alu.v create mode 100644 Core/ALU/and_32bit.t.v create mode 100644 Core/ALU/and_32bit.v create mode 100644 Core/ALU/nand_32bit.t.v create mode 100644 Core/ALU/nand_32bit.v create mode 100644 Core/ALU/nor_32bit.t.v create mode 100644 Core/ALU/nor_32bit.v create mode 100644 Core/ALU/or_32bit.t.v create mode 100644 Core/ALU/or_32bit.v create mode 100644 Core/ALU/slt.t.v create mode 100644 Core/ALU/slt.v create mode 100644 Core/ALU/xor_32bit.t.v create mode 100644 Core/ALU/xor_32bit.v create mode 100644 Core/core.t.v create mode 100644 Core/core.v create mode 100644 Core/decoders.t.v create mode 100644 Core/decoders.v create mode 100644 Core/memory.t.v create mode 100644 Core/memory.v create mode 100644 Core/multiplexer.t.v create mode 100644 Core/multiplexer.v create mode 100644 Core/regfile.t.v create mode 100644 Core/regfile.v create mode 100644 Core/register.t.v create mode 100644 Core/register.v create mode 100644 Core/signextend.v diff --git a/Core/ALU/adder.v b/Core/ALU/adder.v new file mode 100644 index 0000000..cc610e8 --- /dev/null +++ b/Core/ALU/adder.v @@ -0,0 +1,76 @@ +// Adder circuit + +module behavioralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + // Uses concatenation operator and built-in '+' + assign {carryout, sum}=a+b+carryin; +endmodule + +module structuralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + wire ab; //setting up wires + wire acarryin; + wire bcarryin; + wire orpairintermediate; + wire orsingleintermediate; + wire orall; + wire andsumintermediate; + wire andsingleintermediate; + wire andall; + wire invcarryout; + and #(50) andab(ab, a, b); // a and b + and #(50) andacarryin(acarryin, a, carryin); // a and carryin + and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin + or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) + or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) + or #(50) orintermediate(orsingleintermediate, a, b); // a or b + or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin + not #(50) inv(invcarryout, carryout); // not carryout + and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout + and #(50) andintermediate(andsingleintermediate, a, b); // a and b + and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin + or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) +endmodule + +module FullAdder4bit +( + output[3:0] sum, // 2's complement sum of a and b + output carryout, // Carry out of the summation of a and b + output overflow, // True if the calculation resulted in an overflow + input[3:0] a, // First operand in 2's complement format + input[3:0] b, // Second operand in 2's complement format + input carryin +); + wire carryout1; // wire setup for carryouts from each adder + wire carryout2; + wire carryout3; + wire aandb; + wire anorb; + wire bandsum; + wire bnorsum; + wire abandnoror; + wire bsumandnornor; + structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits + structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits + structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits + structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits + and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) + nor #50 norinputs(anorb, a[3], b[3]); + and #50 andsum(bandsum, b[3], sum[3]); + nor #50 norsum(bnorsum, b[3], sum[3]); + or #50 orinputcombs(abandnoror, aandb, anorb); + nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); + and #50 finaland(overflow, abandnoror, bsumandnornor); +endmodule \ No newline at end of file diff --git a/Core/ALU/adder_subtracter.t.v b/Core/ALU/adder_subtracter.t.v new file mode 100644 index 0000000..2e6f726 --- /dev/null +++ b/Core/ALU/adder_subtracter.t.v @@ -0,0 +1,60 @@ +// Adder_subtacter testbench + +`timescale 1 ns / 1 ps +`include "adder_subtracter.v" + +module test32bitAdder(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] carryin; + wire[31:0] ans; + wire carryout, overflow, zero; + + adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); + + initial begin + $display("Input A Input B Command | Output Flag Carryout"); + + // Addition tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b100; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + // Subtraction Tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000001000000000000000000000; + b=32'b00000000000000000000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000001000010000000000000000; + b=32'b10000000000000010000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000000000000000000000000000; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + end +endmodule \ No newline at end of file diff --git a/Core/ALU/adder_subtracter.v b/Core/ALU/adder_subtracter.v new file mode 100644 index 0000000..fea62ec --- /dev/null +++ b/Core/ALU/adder_subtracter.v @@ -0,0 +1,266 @@ +`include "adder.v" + +// 32 bit mux +module mux + ( + output[31:0] out, + input address, + input[31:0] in0, + input[31:0] in1 + ); + wire invaddr; + wire in00addr; // input 0 bit 0 andded with address + wire in01addr; + wire in02addr; + wire in03addr; + wire in04addr; + wire in05addr; + wire in06addr; + wire in07addr; + wire in08addr; + wire in09addr; + wire in010addr; + wire in011addr; + wire in012addr; + wire in013addr; + wire in014addr; + wire in015addr; + wire in016addr; + wire in017addr; + wire in018addr; + wire in019addr; + wire in020addr; + wire in021addr; + wire in022addr; + wire in023addr; + wire in024addr; + wire in025addr; + wire in026addr; + wire in027addr; + wire in028addr; + wire in029addr; + wire in030addr; + wire in031addr; + wire in10addr; + wire in11addr; + wire in12addr; + wire in13addr; + wire in14addr; + wire in15addr; + wire in16addr; + wire in17addr; + wire in18addr; + wire in19addr; + wire in110addr; + wire in111addr; + wire in112addr; + wire in113addr; + wire in114addr; + wire in115addr; + wire in116addr; + wire in117addr; + wire in118addr; + wire in119addr; + wire in120addr; + wire in121addr; + wire in122addr; + wire in123addr; + wire in124addr; + wire in125addr; + wire in126addr; + wire in127addr; + wire in128addr; + wire in129addr; + wire in130addr; + wire in131addr; + + // inverting address + not #10 inv(invaddr, address); + // and all bits in input 0 with inverted address + and #20 and00(in00addr, in0[0], invaddr); + and #20 and01(in01addr, in0[1], invaddr); + and #20 and02(in02addr, in0[2], invaddr); + and #20 and03(in03addr, in0[3], invaddr); + and #20 and04(in04addr, in0[4], invaddr); + and #20 and05(in05addr, in0[5], invaddr); + and #20 and06(in06addr, in0[6], invaddr); + and #20 and07(in07addr, in0[7], invaddr); + and #20 and08(in08addr, in0[8], invaddr); + and #20 and09(in09addr, in0[9], invaddr); + and #20 and010(in010addr, in0[10], invaddr); + and #20 and011(in011addr, in0[11], invaddr); + and #20 and012(in012addr, in0[12], invaddr); + and #20 and013(in013addr, in0[13], invaddr); + and #20 and014(in014addr, in0[14], invaddr); + and #20 and015(in015addr, in0[15], invaddr); + and #20 and016(in016addr, in0[16], invaddr); + and #20 and017(in017addr, in0[17], invaddr); + and #20 and018(in018addr, in0[18], invaddr); + and #20 and019(in019addr, in0[19], invaddr); + and #20 and020(in020addr, in0[20], invaddr); + and #20 and021(in021addr, in0[21], invaddr); + and #20 and022(in022addr, in0[22], invaddr); + and #20 and023(in023addr, in0[23], invaddr); + and #20 and024(in024addr, in0[24], invaddr); + and #20 and025(in025addr, in0[25], invaddr); + and #20 and026(in026addr, in0[26], invaddr); + and #20 and027(in027addr, in0[27], invaddr); + and #20 and028(in028addr, in0[28], invaddr); + and #20 and029(in029addr, in0[29], invaddr); + and #20 and030(in030addr, in0[30], invaddr); + and #20 and031(in031addr, in0[31], invaddr); + // and all bits in input 1 with address + and #20 and10(in10addr, in1[0], address); + and #20 and11(in11addr, in1[1], address); + and #20 and12(in12addr, in1[2], address); + and #20 and13(in13addr, in1[3], address); + and #20 and14(in14addr, in1[4], address); + and #20 and15(in15addr, in1[5], address); + and #20 and16(in16addr, in1[6], address); + and #20 and17(in17addr, in1[7], address); + and #20 and18(in18addr, in1[8], address); + and #20 and19(in19addr, in1[9], address); + and #20 and110(in110addr, in1[10], address); + and #20 and111(in111addr, in1[11], address); + and #20 and112(in112addr, in1[12], address); + and #20 and113(in113addr, in1[13], address); + and #20 and114(in114addr, in1[14], address); + and #20 and115(in115addr, in1[15], address); + and #20 and116(in116addr, in1[16], address); + and #20 and117(in117addr, in1[17], address); + and #20 and118(in118addr, in1[18], address); + and #20 and119(in119addr, in1[19], address); + and #20 and120(in120addr, in1[20], address); + and #20 and121(in121addr, in1[21], address); + and #20 and122(in122addr, in1[22], address); + and #20 and123(in123addr, in1[23], address); + and #20 and124(in124addr, in1[24], address); + and #20 and125(in125addr, in1[25], address); + and #20 and126(in126addr, in1[26], address); + and #20 and127(in127addr, in1[27], address); + and #20 and128(in128addr, in1[28], address); + and #20 and129(in129addr, in1[29], address); + and #20 and130(in130addr, in1[30], address); + and #20 and131(in131addr, in1[31], address); + + // or the and gates + or #20 or0(out[0], in00addr, in10addr); + or #20 or1(out[1], in01addr, in11addr); + or #20 or2(out[2], in02addr, in12addr); + or #20 or3(out[3], in03addr, in13addr); + or #20 or4(out[4], in04addr, in14addr); + or #20 or5(out[5], in05addr, in15addr); + or #20 or6(out[6], in06addr, in16addr); + or #20 or7(out[7], in07addr, in17addr); + or #20 or8(out[8], in08addr, in18addr); + or #20 or9(out[9], in09addr, in19addr); + or #20 or10(out[10], in010addr, in110addr); + or #20 or11(out[11], in011addr, in111addr); + or #20 or12(out[12], in012addr, in112addr); + or #20 or13(out[13], in013addr, in113addr); + or #20 or14(out[14], in014addr, in114addr); + or #20 or15(out[15], in015addr, in115addr); + or #20 or16(out[16], in016addr, in116addr); + or #20 or17(out[17], in017addr, in117addr); + or #20 or18(out[18], in018addr, in118addr); + or #20 or19(out[19], in019addr, in119addr); + or #20 or20(out[20], in020addr, in120addr); + or #20 or21(out[21], in021addr, in121addr); + or #20 or22(out[22], in022addr, in122addr); + or #20 or23(out[23], in023addr, in123addr); + or #20 or24(out[24], in024addr, in124addr); + or #20 or25(out[25], in025addr, in125addr); + or #20 or26(out[26], in026addr, in126addr); + or #20 or27(out[27], in027addr, in127addr); + or #20 or28(out[28], in028addr, in128addr); + or #20 or29(out[29], in029addr, in129addr); + or #20 or30(out[30], in030addr, in130addr); + or #20 or31(out[31], in031addr, in131addr); +endmodule + +// 32 bit adder/subtracter that determines what operation to conduct based on the input command +module adder_subtracter + ( + output[31:0] ans, + output carryout, + output overflow, + output reg zero, + input[31:0] opA, + input[31:0] opB, + input[2:0] command + ); + wire[31:0] invertedB; //wire to invert b in the event of a subtraction + wire[31:0] finalB; + wire normalB; //added b + wire cout0; + wire cout1; + wire cout2; + wire cout3; + wire cout4; + wire cout5; + wire cout6; + wire _; + wire _1; + wire _2; + wire _3; + wire _4; + wire _5; + wire _6; + + // invert B in the case of two's complement + not #10 invertB0(invertedB[0], opB[0]); + not #10 invertB1(invertedB[1], opB[1]); + not #10 invertB2(invertedB[2], opB[2]); + not #10 invertB3(invertedB[3], opB[3]); + not #10 invertB4(invertedB[4], opB[4]); + not #10 invertB5(invertedB[5], opB[5]); + not #10 invertB6(invertedB[6], opB[6]); + not #10 invertB7(invertedB[7], opB[7]); + not #10 invertB8(invertedB[8], opB[8]); + not #10 invertB9(invertedB[9], opB[9]); + not #10 invertB10(invertedB[10], opB[10]); + not #10 invertB11(invertedB[11], opB[11]); + not #10 invertB12(invertedB[12], opB[12]); + not #10 invertB13(invertedB[13], opB[13]); + not #10 invertB14(invertedB[14], opB[14]); + not #10 invertB15(invertedB[15], opB[15]); + not #10 invertB16(invertedB[16], opB[16]); + not #10 invertB17(invertedB[17], opB[17]); + not #10 invertB18(invertedB[18], opB[18]); + not #10 invertB19(invertedB[19], opB[19]); + not #10 invertB20(invertedB[20], opB[20]); + not #10 invertB21(invertedB[21], opB[21]); + not #10 invertB22(invertedB[22], opB[22]); + not #10 invertB23(invertedB[23], opB[23]); + not #10 invertB24(invertedB[24], opB[24]); + not #10 invertB25(invertedB[25], opB[25]); + not #10 invertB26(invertedB[26], opB[26]); + not #10 invertB27(invertedB[27], opB[27]); + not #10 invertB28(invertedB[28], opB[28]); + not #10 invertB29(invertedB[29], opB[29]); + not #10 invertB30(invertedB[30], opB[30]); + not #10 invertB31(invertedB[31], opB[31]); + + // mux chooses between inverted B or normal B based on addition or subtraction + mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); + + // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one + FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding + FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); + FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); + FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); + FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); + FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); + FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); + FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + + always @(*) begin + if (ans === 32'b0) begin + zero <= 1; + end + + else begin + zero <= 0; + end + end +endmodule \ No newline at end of file diff --git a/Core/ALU/alu.t.v b/Core/ALU/alu.t.v new file mode 100644 index 0000000..322cd32 --- /dev/null +++ b/Core/ALU/alu.t.v @@ -0,0 +1,507 @@ +`timescale 1 ns / 1 ps +`include "alu.v" + +module testALU32bit(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] ALUcommand; + wire[31:0] finalALUsig; + wire flag; + wire cout; + + ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + + initial begin + $display("ALU Command Input A Input B | Output Flag Carryout"); + //Test cases add + ALUcommand = 3'b000; + + // 0 + 0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // 1 + 1 + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // positive overflow + a = 32'b01111111111111111111111111111111; + b = 32'b01111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // negative overflow + a = 32'b10000000000000000000000000000001; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // carryout + a = 32'b11111111111111111111111111111111; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + + //Test cases sub + ALUcommand = 3'b001; + + // a=b=0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a=b + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a>b, both positive + a = 32'b00000000000000000000000000000111; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a|b|, both negative + a = 32'b11111111111111111111111111111101; + b = 32'b11111111111111111111111111111110; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // |a|<|b|, both negative + a = 32'b111111111111111111111111111111110; + b = 32'b111111111111111111111111111111000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, no overflow + a = 32'b11111111111111111111111111111101; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, overflow + a = 32'b10000000000000000000000000000101; + b = 32'b01111100000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, no overflow + a = 32'b00000000000000000000000000000101; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + //Here + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, overflow + a = 32'b01111111111111111111101111111111; + b = 32'b10000000000000001100000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //Test cases xor + ALUcommand = 3'b010; + + //a is all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //b is all 0's + b = 32'b00000000000000000000000000000000; + a = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 1's + a = 32'b11111111111111111111111111111111; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + + //Test cases slt + ALUcommand = 3'b011; + + //a>b, all positive + a = 32'b00000000000000000000000000000010; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //ab, all negative + a = 32'b10000000000000000000000000000010; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a>b, a positive, b negative + a = 32'b00000000000000000000000000000001; + b = 32'b10000000000000000000000000000010; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a Date: Thu, 9 Nov 2017 22:14:51 -0500 Subject: [PATCH 037/190] Initialize memory --- memory.v | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 memory.v diff --git a/memory.v b/memory.v deleted file mode 100644 index 06cc571..0000000 --- a/memory.v +++ /dev/null @@ -1,28 +0,0 @@ -/* -The memory used in the CPU -*/ - -module memory -#( - parameter addresswidth = 32, - parameter depth = addresswidth, - parameter width = 32 -) -( - input clk, - output reg [width-1:0] dataOut, - input [addresswidth-1:0] address, - input writeEnable, - input [width-1:0] dataIn -); - - - reg [width-1:0] memory [depth-1:0]; - - always @(negedge clk) begin - if(writeEnable) - memory[address] <= dataIn; - dataOut <= memory[address]; - end - -endmodule \ No newline at end of file From e08bfe044a61a353eb064bb6684d7096a24a299a Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 9 Nov 2017 22:15:10 -0500 Subject: [PATCH 038/190] Add test cases --- memory.t.v | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 memory.t.v diff --git a/memory.t.v b/memory.t.v deleted file mode 100644 index c2bee8d..0000000 --- a/memory.t.v +++ /dev/null @@ -1,20 +0,0 @@ -/* -Test bench for data memory module. -*/ - -`include "memory.v" - -module memory_TEST(); - reg clk; - reg [31:0] address; - reg writeEnable; - reg [31:0] dataIn; - - wire [31:0] dataOut; - - memory dut(clk, dataOut, address, writeEnable, dataIn); - - initial begin - // Test code here - end -endmodule \ No newline at end of file From e5df628da22d1fa64e6cb600a11a15db47c772a3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 9 Nov 2017 22:15:41 -0500 Subject: [PATCH 039/190] Create file of initialized memory --- file.dat | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 file.dat diff --git a/file.dat b/file.dat new file mode 100644 index 0000000..6866368 --- /dev/null +++ b/file.dat @@ -0,0 +1,35 @@ +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 \ No newline at end of file From 217e07188819fccf31653f319841fe6d1d6503eb Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:06:50 -0500 Subject: [PATCH 040/190] Connect Da wire --- core.v | 66 ---------------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 core.v diff --git a/core.v b/core.v deleted file mode 100644 index 2d0c29c..0000000 --- a/core.v +++ /dev/null @@ -1,66 +0,0 @@ -/* -The section of the CPU containing the register file, data memory, and ALU. -*/ - -`include "alu.v" -`include "memory.v" -`include "regfile.v" -`include "signextend.v" - -module core -( - input clk, - input [4:0] rd, - input [4:0] rt, - input [4:0] rs, - input [15:0] immediate, - input [31:0] new_PC, - input [0:1] regdst, - input [2:0] ALUcntrl, - input AlUsrc, - input MemWr, - input RegWr, - input [1:0] MemtoReg, - output [31:0] Da, - output is_zero -); - - wire[4:0] writeaddr; - - // Register file write address - mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - - wire[31:0] dataaout; - wire[31:0] databout; - wire[31:0] datain; - - // Register file - regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); - - // Sign extend - - wire[31:0] signextimm; - signextend extend (immediate, signextimm); - - // ALU operand 2 mux - wire[31:0] operandb; - - mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); - - // ALU - wire cout; - wire overflow; - wire[31:0] finalsignal; - - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); - - // Regfile write data mux - wire[31:0] memout; - - mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); - - // Data Meomory - memory datamemory (clk, memout, finalsignal, MemWr, databout); - - -endmodule \ No newline at end of file From 7a4587c342ca7c318c7048c24ab5c00707d43cd5 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:07:37 -0500 Subject: [PATCH 041/190] Implement tests for addi, lw, sw --- core.t.v | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 core.t.v diff --git a/core.t.v b/core.t.v deleted file mode 100644 index d65d6d8..0000000 --- a/core.t.v +++ /dev/null @@ -1,40 +0,0 @@ -/* -Test bench for the core module of the CPU. -*/ - -`include "core.v" - -module core_TEST(); - wire [31:0] Da; - wire is_zero; - - reg clk; - reg [4:0] rd; - reg [4:0] rt; - reg [4:0] rs; - reg [15:0] immediate; - reg [31:0] new_PC; - reg [0:1] regdst; - reg [2:0] ALUcntrl; - reg AlUsrc; - reg MemWr; - reg RegWr; - reg [1:0] MemtoReg; - - core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); - - initial clk = 0; - always #10 clk = !clk; - - initial begin - $dumpfile("core.vcd"); - $dumpvars(0, core_TEST); - - // Test Case 1: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; - rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; - - - $finish; - end -endmodule \ No newline at end of file From f69ea41097cccb88b0c5c52b77a9cf7e17dde919 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:10:01 -0500 Subject: [PATCH 042/190] Update module references --- Core/ALU/adder_subtracter.t.v | 2 +- Core/ALU/adder_subtracter.v | 2 +- Core/ALU/alu.t.v | 7 ++++++- Core/ALU/alu.v | 14 +++++++------- Core/ALU/and_32bit.t.v | 2 +- Core/ALU/nand_32bit.t.v | 2 +- Core/ALU/nor_32bit.t.v | 2 +- Core/ALU/or_32bit.t.v | 2 +- Core/ALU/slt.t.v | 2 +- Core/ALU/xor_32bit.t.v | 2 +- 10 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Core/ALU/adder_subtracter.t.v b/Core/ALU/adder_subtracter.t.v index 2e6f726..b8593b6 100644 --- a/Core/ALU/adder_subtracter.t.v +++ b/Core/ALU/adder_subtracter.t.v @@ -1,7 +1,7 @@ // Adder_subtacter testbench `timescale 1 ns / 1 ps -`include "adder_subtracter.v" +`include "Core/ALU/adder_subtracter.v" module test32bitAdder(); reg[31:0] a; diff --git a/Core/ALU/adder_subtracter.v b/Core/ALU/adder_subtracter.v index fea62ec..87bd13c 100644 --- a/Core/ALU/adder_subtracter.v +++ b/Core/ALU/adder_subtracter.v @@ -1,4 +1,4 @@ -`include "adder.v" +`include "Core/ALU/adder.v" // 32 bit mux module mux diff --git a/Core/ALU/alu.t.v b/Core/ALU/alu.t.v index 322cd32..681da3b 100644 --- a/Core/ALU/alu.t.v +++ b/Core/ALU/alu.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "alu.v" +`include "Core/ALU/alu.v" module testALU32bit(); reg[31:0] a; @@ -12,6 +12,9 @@ module testALU32bit(); ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); initial begin + $dumpfile("Core/ALU/alu.vcd"); + $dumpvars(); + $display("ALU Command Input A Input B | Output Flag Carryout"); //Test cases add ALUcommand = 3'b000; @@ -503,5 +506,7 @@ module testALU32bit(); if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin $display("Test Case Failed"); end + + $finish(); end endmodule \ No newline at end of file diff --git a/Core/ALU/alu.v b/Core/ALU/alu.v index 47c9191..8d00840 100644 --- a/Core/ALU/alu.v +++ b/Core/ALU/alu.v @@ -1,12 +1,12 @@ //final 32-bit ALU -`include "adder_subtracter.v" -`include "slt.v" -`include "and_32bit.v" -`include "nand_32bit.v" -`include "xor_32bit.v" -`include "nor_32bit.v" -`include "or_32bit.v" +`include "Core/ALU/adder_subtracter.v" +`include "Core/ALU/slt.v" +`include "Core/ALU/and_32bit.v" +`include "Core/ALU/nand_32bit.v" +`include "Core/ALU/xor_32bit.v" +`include "Core/ALU/nor_32bit.v" +`include "Core/ALU/or_32bit.v" module ALUcontrolLUT ( diff --git a/Core/ALU/and_32bit.t.v b/Core/ALU/and_32bit.t.v index 5857179..5ff89be 100644 --- a/Core/ALU/and_32bit.t.v +++ b/Core/ALU/and_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "and_32bit.v" +`include "Core/ALU/and_32bit.v" module test32bitand(); reg[31:0] a; diff --git a/Core/ALU/nand_32bit.t.v b/Core/ALU/nand_32bit.t.v index 28a4791..706760b 100644 --- a/Core/ALU/nand_32bit.t.v +++ b/Core/ALU/nand_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "nand_32bit.v" +`include "Core/ALU/nand_32bit.v" module test32bitnand(); reg[31:0] a; diff --git a/Core/ALU/nor_32bit.t.v b/Core/ALU/nor_32bit.t.v index 619fd4a..26239c2 100644 --- a/Core/ALU/nor_32bit.t.v +++ b/Core/ALU/nor_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "nor_32bit.v" +`include "Core/ALU/nor_32bit.v" module test32bitnor(); reg[31:0] a; diff --git a/Core/ALU/or_32bit.t.v b/Core/ALU/or_32bit.t.v index bb19ef6..aae88e2 100644 --- a/Core/ALU/or_32bit.t.v +++ b/Core/ALU/or_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "or_32bit.v" +`include "Core/ALU/or_32bit.v" module test32bitor(); reg[31:0] a; diff --git a/Core/ALU/slt.t.v b/Core/ALU/slt.t.v index b5415f9..69b6532 100644 --- a/Core/ALU/slt.t.v +++ b/Core/ALU/slt.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "slt.v" +`include "Core/ALU/slt.v" module test32bitslt(); reg[31:0] a; diff --git a/Core/ALU/xor_32bit.t.v b/Core/ALU/xor_32bit.t.v index bbd0725..f62930a 100644 --- a/Core/ALU/xor_32bit.t.v +++ b/Core/ALU/xor_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "xor_32bit.v" +`include "Core/ALU/xor_32bit.v" module test32bitxor(); reg[31:0] a; From 98ab8f700799e8318e993a8e0163bf7cfb847dac Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:10:37 -0500 Subject: [PATCH 043/190] update file paths --- makefile | 60 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/makefile b/makefile index 6f92f94..54cd1bc 100644 --- a/makefile +++ b/makefile @@ -1,51 +1,51 @@ all: core alu regfile memory signextend # Core modules -core: core.v core.t.v - iverilog -Wall -o core core.t.v +core: Core/core.v Core/core.t.v + iverilog -Wall -o core Core/core.t.v # ALU modules -alu: alu.v alu.t.v adder_subtracter and nand nor or slt xor - iverilog -Wall -o alu alu.t.v +alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor + iverilog -Wall -o alu Core/ALU/alu.t.v -adder_subtracter: adder_subtracter.v adder_subtracter.t.v - iverilog -Wall -o adder_subtracter adder_subtracter.t.v +adder_subtracter: Core/ALU/adder_subtracter.v Core/ALU/adder_subtracter.t.v + iverilog -Wall -o adder_subtracter Core/ALU/adder_subtracter.t.v -and: and_32bit.v and_32bit.t.v - iverilog -Wall -o and and_32bit.t.v +and: Core/ALU/and_32bit.v Core/ALU/and_32bit.t.v + iverilog -Wall -o and Core/ALU/and_32bit.t.v -nand: nand_32bit.v nand_32bit.t.v - iverilog -Wall -o nand nand_32bit.t.v +nand: Core/ALU/nand_32bit.v Core/ALU/nand_32bit.t.v + iverilog -Wall -o nand Core/ALU/nand_32bit.t.v -nor: nor_32bit.v nor_32bit.t.v - iverilog -Wall -o nor nor_32bit.t.v +nor: Core/ALU/nor_32bit.v Core/ALU/nor_32bit.t.v + iverilog -Wall -o nor Core/ALU/nor_32bit.t.v -or: or_32bit.v or_32bit.t.v - iverilog -Wall -o or or_32bit.t.v +or: Core/ALU/or_32bit.v Core/ALU/or_32bit.t.v + iverilog -Wall -o or Core/ALU/or_32bit.t.v -slt: slt.v slt.t.v - iverilog -Wall -o slt slt.t.v +slt: Core/ALU/slt.v Core/ALU/slt.t.v + iverilog -Wall -o slt Core/ALU/slt.t.v -xor: xor_32bit.v xor_32bit.t.v - iverilog -Wall -o xor xor_32bit.t.v +xor: Core/ALU/xor_32bit.v Core/ALU/xor_32bit.t.v + iverilog -Wall -o xor Core/ALU/xor_32bit.t.v # Regfile modules -regfile: regfile.t.v regfile.v decoder mux register - iverilog -Wall -o regfile regfile.t.v +regfile: Core/regfile.t.v Core/regfile.v decoder mux register + iverilog -Wall -o regfile Core/regfile.t.v -decoder: decoders.t.v decoders.v - iverilog -Wall -o decoder decoders.t.v +decoder: Core/decoders.t.v Core/decoders.v + iverilog -Wall -o decoder Core/decoders.t.v -mux: multiplexer.t.v multiplexer.v - iverilog -Wall -o mux multiplexer.t.v +mux: Core/multiplexer.t.v Core/multiplexer.v + iverilog -Wall -o mux Core/multiplexer.t.v -register: register.t.v register.v - iverilog -Wall -o register register.t.v +register: Core/register.t.v Core/register.v + iverilog -Wall -o register Core/register.t.v # Memory modules -memory: memory.v memory.t.v - iverilog -Wall -o memory memory.t.v +memory: Core/memory.v Core/memory.t.v + iverilog -Wall -o memory Core/memory.t.v # Concatenation modules -signextend: signextend.v - iverilog -Wall -o signextend signextend.v +signextend: Core/signextend.v + iverilog -Wall -o signextend Core/signextend.v From a04ebb67d75c1a3674c056755fa7d92929bd4135 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:11:00 -0500 Subject: [PATCH 044/190] Update file paths --- Core/core.t.v | 139 ++++++++++++++++++++++++++++++++++++++++--- Core/core.v | 14 ++--- Core/decoders.t.v | 2 +- Core/memory.t.v | 39 +++++++++++- Core/memory.v | 2 + Core/multiplexer.t.v | 2 +- Core/regfile.t.v | 2 +- Core/regfile.v | 6 +- Core/register.t.v | 2 +- 9 files changed, 185 insertions(+), 23 deletions(-) diff --git a/Core/core.t.v b/Core/core.t.v index c5f85b6..0ee8f25 100644 --- a/Core/core.t.v +++ b/Core/core.t.v @@ -2,7 +2,7 @@ Test bench for the core module of the CPU. */ -`include "core.v" +`include "Core/core.v" module core_TEST(); wire [31:0] Da; @@ -27,13 +27,138 @@ module core_TEST(); always #10 clk = !clk; initial begin - $dumpfile("core.vcd"); - $dumpvars(0, core_TEST); + $dumpfile("Core/core.vcd"); + $dumpvars(0, core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); - // Test Case 1: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; - rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; - #1000 + // Test Case 1: Add Immediate + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd1; rs = 5'b00000; immediate = 16'b0; + #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0"); + end + + // Populate the rest of the registers with data (each gets 32'b0) + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd2; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd3; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd4; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd5; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd6; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd7; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd8; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd9; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd10; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd11; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd12; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd13; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd14; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd15; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd16; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd17; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd18; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd19; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd20; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd21; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd22; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd23; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd24; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd25; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd26; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd27; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd28; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd29; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd30; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd31; rs = 5'b00000; immediate = 16'b0; + #6000 + + + // Test Case 2: Load Word + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 2'b01; + rd = 5'bx; rt = 5'b00010; rs = 5'b00001; immediate = 16'b0; + #100 + + if (dut.databout !== dut.datamemory.memory[0]) begin + $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimmediate]"); + end + + // Test Case 3: Store Word + regdst = 2'bx; AlUsrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUcntrl = 3'b000; MemtoReg = 2'bx; + rd = 5'bx; rs = 5'b00001; rt = 5'b00000; immediate = 16'b0; + #100 + + if (dut.datamemory.dataOut !== dut.databout) begin + $display("Test case 3 failed: M[R[rs] + signextendimmediate] != R[rt]"); + end + + // Test Case 4: Jump + // Test Case 5: Jump Register + // Test Case 6: Jump and Link + // Test Case 7: Branch if Not Equal + // Test Case 8: XOR Immediate + // Test Case 9: Add + // Test Case 10: Subtract + // Test Case 11: Set Less Than + #10000 $finish; end diff --git a/Core/core.v b/Core/core.v index 2d0c29c..f4ed3ac 100644 --- a/Core/core.v +++ b/Core/core.v @@ -2,10 +2,10 @@ The section of the CPU containing the register file, data memory, and ALU. */ -`include "alu.v" -`include "memory.v" -`include "regfile.v" -`include "signextend.v" +`include "Core/ALU/alu.v" +`include "Core/memory.v" +`include "Core/regfile.v" +`include "Core/signextend.v" module core ( @@ -30,12 +30,12 @@ module core // Register file write address mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - wire[31:0] dataaout; + // wire[31:0] dataaout; wire[31:0] databout; wire[31:0] datain; // Register file - regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); + regfile regfile (Da, databout, datain, rs, rt, writeaddr, RegWr, clk); // Sign extend @@ -52,7 +52,7 @@ module core wire overflow; wire[31:0] finalsignal; - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); + ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, Da, operandb); // Regfile write data mux wire[31:0] memout; diff --git a/Core/decoders.t.v b/Core/decoders.t.v index 616b67b..e841b22 100644 --- a/Core/decoders.t.v +++ b/Core/decoders.t.v @@ -2,7 +2,7 @@ // Unit test the decoder module //------------------------------- -`include "decoders.v" +`include "Core/decoders.v" module decoder1to32Test(); wire[31:0] out; diff --git a/Core/memory.t.v b/Core/memory.t.v index c2bee8d..836af61 100644 --- a/Core/memory.t.v +++ b/Core/memory.t.v @@ -2,7 +2,7 @@ Test bench for data memory module. */ -`include "memory.v" +`include "Core/memory.v" module memory_TEST(); reg clk; @@ -14,7 +14,42 @@ module memory_TEST(); memory dut(clk, dataOut, address, writeEnable, dataIn); + initial clk = 0; + always #10 clk = !clk; initial begin - // Test code here + $dumpfile("Core/memory.vcd"); + $dumpvars(0, memory_TEST, dut.memory[0]); + + // Test Case 1: Do not write if writeEnable is low. + writeEnable = 0; dataIn = 32'hffffffff; address = 32'd0; + #20 + if (dataOut === dataIn) begin + $display("Test case 1 failed: memory was written to when writeEnable was false."); + end + + else if (dataOut === 32'bx) begin + $display("Test case 1 failed: there is no memory at the given address."); + end + + #1000 + // Test case 2: Write to memory if writeEnable is high. + writeEnable = 1; dataIn = 32'hffffffff; address = 32'd0; + #40 + + if (dataOut === 32'bx) begin + $display("Test case 2 failed: there is no memory at the given address."); + end + + if (dut.memory[0] !== dataIn) begin + $display("Test case 2 failed: the memory contained at the given address does not match dataIn"); + end + + if (dataOut !== dataIn) begin + $display("Test case 2 failed: memory was not written to when writeEnable was true."); + end + + #1000 + + $finish; end endmodule \ No newline at end of file diff --git a/Core/memory.v b/Core/memory.v index 06cc571..820e3d0 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -25,4 +25,6 @@ module memory dataOut <= memory[address]; end + initial $readmemh("file.dat", memory); + endmodule \ No newline at end of file diff --git a/Core/multiplexer.t.v b/Core/multiplexer.t.v index dc1fff3..8f17795 100644 --- a/Core/multiplexer.t.v +++ b/Core/multiplexer.t.v @@ -2,7 +2,7 @@ // Test the multiplexer modules. //-------------------------------- -`include "multiplexer.v" +`include "Core/multiplexer.v" // Test harness for multiplexer unit test modules. module multiplexerTestBenchHarness(); diff --git a/Core/regfile.t.v b/Core/regfile.t.v index 059c0ec..4dda453 100644 --- a/Core/regfile.t.v +++ b/Core/regfile.t.v @@ -3,7 +3,7 @@ // or broken register files, and verifying that it correctly identifies each //------------------------------------------------------------------------------ -`include "regfile.v" +`include "Core/regfile.v" module hw4testbenchharness(); diff --git a/Core/regfile.v b/Core/regfile.v index 893bf11..0bc8f4b 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -6,9 +6,9 @@ // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ -`include "register.v" -`include "multiplexer.v" -`include "decoders.v" +`include "Core/register.v" +`include "Core/multiplexer.v" +`include "Core/decoders.v" module regfile ( diff --git a/Core/register.t.v b/Core/register.t.v index e0821b7..8b4a7f0 100644 --- a/Core/register.t.v +++ b/Core/register.t.v @@ -1,7 +1,7 @@ //-------------------------- // Test the register modules //-------------------------- -`include "register.v" +`include "Core/register.v" // Unit tests for the single bit register module. module registerTest(); From 849f31613cf25b40e3487d0f716189898305a63e Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:11:48 -0500 Subject: [PATCH 045/190] Move files to subfolder --- adder.v | 76 ------- adder_subtracter.t.v | 60 ----- adder_subtracter.v | 266 ----------------------- alu.t.v | 507 ------------------------------------------- alu.v | 59 ----- and_32bit.t.v | 36 --- and_32bit.v | 40 ---- decoders.t.v | 41 ---- decoders.v | 20 -- multiplexer.t.v | 165 -------------- multiplexer.v | 74 ------- nand_32bit.t.v | 36 --- nand_32bit.v | 40 ---- nor_32bit.t.v | 36 --- nor_32bit.v | 40 ---- or_32bit.t.v | 30 --- or_32bit.v | 40 ---- regfile.t.v | 176 --------------- regfile.v | 114 ---------- register.t.v | 121 ----------- register.v | 48 ---- signextend.v | 12 - slt.t.v | 40 ---- slt.v | 110 ---------- xor_32bit.t.v | 36 --- xor_32bit.v | 40 ---- 26 files changed, 2263 deletions(-) delete mode 100644 adder.v delete mode 100644 adder_subtracter.t.v delete mode 100644 adder_subtracter.v delete mode 100644 alu.t.v delete mode 100644 alu.v delete mode 100644 and_32bit.t.v delete mode 100644 and_32bit.v delete mode 100644 decoders.t.v delete mode 100644 decoders.v delete mode 100644 multiplexer.t.v delete mode 100644 multiplexer.v delete mode 100644 nand_32bit.t.v delete mode 100644 nand_32bit.v delete mode 100644 nor_32bit.t.v delete mode 100644 nor_32bit.v delete mode 100644 or_32bit.t.v delete mode 100644 or_32bit.v delete mode 100644 regfile.t.v delete mode 100644 regfile.v delete mode 100644 register.t.v delete mode 100644 register.v delete mode 100644 signextend.v delete mode 100644 slt.t.v delete mode 100644 slt.v delete mode 100644 xor_32bit.t.v delete mode 100644 xor_32bit.v diff --git a/adder.v b/adder.v deleted file mode 100644 index cc610e8..0000000 --- a/adder.v +++ /dev/null @@ -1,76 +0,0 @@ -// Adder circuit - -module behavioralFullAdder -( - output sum, - output carryout, - input a, - input b, - input carryin -); - // Uses concatenation operator and built-in '+' - assign {carryout, sum}=a+b+carryin; -endmodule - -module structuralFullAdder -( - output sum, - output carryout, - input a, - input b, - input carryin -); - wire ab; //setting up wires - wire acarryin; - wire bcarryin; - wire orpairintermediate; - wire orsingleintermediate; - wire orall; - wire andsumintermediate; - wire andsingleintermediate; - wire andall; - wire invcarryout; - and #(50) andab(ab, a, b); // a and b - and #(50) andacarryin(acarryin, a, carryin); // a and carryin - and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin - or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) - or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) - or #(50) orintermediate(orsingleintermediate, a, b); // a or b - or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin - not #(50) inv(invcarryout, carryout); // not carryout - and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout - and #(50) andintermediate(andsingleintermediate, a, b); // a and b - and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin - or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) -endmodule - -module FullAdder4bit -( - output[3:0] sum, // 2's complement sum of a and b - output carryout, // Carry out of the summation of a and b - output overflow, // True if the calculation resulted in an overflow - input[3:0] a, // First operand in 2's complement format - input[3:0] b, // Second operand in 2's complement format - input carryin -); - wire carryout1; // wire setup for carryouts from each adder - wire carryout2; - wire carryout3; - wire aandb; - wire anorb; - wire bandsum; - wire bnorsum; - wire abandnoror; - wire bsumandnornor; - structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits - structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits - structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits - structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits - and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) - nor #50 norinputs(anorb, a[3], b[3]); - and #50 andsum(bandsum, b[3], sum[3]); - nor #50 norsum(bnorsum, b[3], sum[3]); - or #50 orinputcombs(abandnoror, aandb, anorb); - nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); - and #50 finaland(overflow, abandnoror, bsumandnornor); -endmodule \ No newline at end of file diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v deleted file mode 100644 index 2e6f726..0000000 --- a/adder_subtracter.t.v +++ /dev/null @@ -1,60 +0,0 @@ -// Adder_subtacter testbench - -`timescale 1 ns / 1 ps -`include "adder_subtracter.v" - -module test32bitAdder(); - reg[31:0] a; - reg[31:0] b; - reg[2:0] carryin; - wire[31:0] ans; - wire carryout, overflow, zero; - - adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); - - initial begin - $display("Input A Input B Command | Output Flag Carryout"); - - // Addition tests - a=32'b00000000000000000000000000000001; - b=32'b00000000000000000000000000000001; - carryin=3'b100; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b000; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - // Subtraction Tests - a=32'b00000000000000000000000000000001; - b=32'b00000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b00000000001000000000000000000000; - b=32'b00000000000000000000000010000000; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000001000010000000000000000; - b=32'b10000000000000010000000010000000; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b00000000000000000000000000000000; - b=32'b10000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b000; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - end -endmodule \ No newline at end of file diff --git a/adder_subtracter.v b/adder_subtracter.v deleted file mode 100644 index fea62ec..0000000 --- a/adder_subtracter.v +++ /dev/null @@ -1,266 +0,0 @@ -`include "adder.v" - -// 32 bit mux -module mux - ( - output[31:0] out, - input address, - input[31:0] in0, - input[31:0] in1 - ); - wire invaddr; - wire in00addr; // input 0 bit 0 andded with address - wire in01addr; - wire in02addr; - wire in03addr; - wire in04addr; - wire in05addr; - wire in06addr; - wire in07addr; - wire in08addr; - wire in09addr; - wire in010addr; - wire in011addr; - wire in012addr; - wire in013addr; - wire in014addr; - wire in015addr; - wire in016addr; - wire in017addr; - wire in018addr; - wire in019addr; - wire in020addr; - wire in021addr; - wire in022addr; - wire in023addr; - wire in024addr; - wire in025addr; - wire in026addr; - wire in027addr; - wire in028addr; - wire in029addr; - wire in030addr; - wire in031addr; - wire in10addr; - wire in11addr; - wire in12addr; - wire in13addr; - wire in14addr; - wire in15addr; - wire in16addr; - wire in17addr; - wire in18addr; - wire in19addr; - wire in110addr; - wire in111addr; - wire in112addr; - wire in113addr; - wire in114addr; - wire in115addr; - wire in116addr; - wire in117addr; - wire in118addr; - wire in119addr; - wire in120addr; - wire in121addr; - wire in122addr; - wire in123addr; - wire in124addr; - wire in125addr; - wire in126addr; - wire in127addr; - wire in128addr; - wire in129addr; - wire in130addr; - wire in131addr; - - // inverting address - not #10 inv(invaddr, address); - // and all bits in input 0 with inverted address - and #20 and00(in00addr, in0[0], invaddr); - and #20 and01(in01addr, in0[1], invaddr); - and #20 and02(in02addr, in0[2], invaddr); - and #20 and03(in03addr, in0[3], invaddr); - and #20 and04(in04addr, in0[4], invaddr); - and #20 and05(in05addr, in0[5], invaddr); - and #20 and06(in06addr, in0[6], invaddr); - and #20 and07(in07addr, in0[7], invaddr); - and #20 and08(in08addr, in0[8], invaddr); - and #20 and09(in09addr, in0[9], invaddr); - and #20 and010(in010addr, in0[10], invaddr); - and #20 and011(in011addr, in0[11], invaddr); - and #20 and012(in012addr, in0[12], invaddr); - and #20 and013(in013addr, in0[13], invaddr); - and #20 and014(in014addr, in0[14], invaddr); - and #20 and015(in015addr, in0[15], invaddr); - and #20 and016(in016addr, in0[16], invaddr); - and #20 and017(in017addr, in0[17], invaddr); - and #20 and018(in018addr, in0[18], invaddr); - and #20 and019(in019addr, in0[19], invaddr); - and #20 and020(in020addr, in0[20], invaddr); - and #20 and021(in021addr, in0[21], invaddr); - and #20 and022(in022addr, in0[22], invaddr); - and #20 and023(in023addr, in0[23], invaddr); - and #20 and024(in024addr, in0[24], invaddr); - and #20 and025(in025addr, in0[25], invaddr); - and #20 and026(in026addr, in0[26], invaddr); - and #20 and027(in027addr, in0[27], invaddr); - and #20 and028(in028addr, in0[28], invaddr); - and #20 and029(in029addr, in0[29], invaddr); - and #20 and030(in030addr, in0[30], invaddr); - and #20 and031(in031addr, in0[31], invaddr); - // and all bits in input 1 with address - and #20 and10(in10addr, in1[0], address); - and #20 and11(in11addr, in1[1], address); - and #20 and12(in12addr, in1[2], address); - and #20 and13(in13addr, in1[3], address); - and #20 and14(in14addr, in1[4], address); - and #20 and15(in15addr, in1[5], address); - and #20 and16(in16addr, in1[6], address); - and #20 and17(in17addr, in1[7], address); - and #20 and18(in18addr, in1[8], address); - and #20 and19(in19addr, in1[9], address); - and #20 and110(in110addr, in1[10], address); - and #20 and111(in111addr, in1[11], address); - and #20 and112(in112addr, in1[12], address); - and #20 and113(in113addr, in1[13], address); - and #20 and114(in114addr, in1[14], address); - and #20 and115(in115addr, in1[15], address); - and #20 and116(in116addr, in1[16], address); - and #20 and117(in117addr, in1[17], address); - and #20 and118(in118addr, in1[18], address); - and #20 and119(in119addr, in1[19], address); - and #20 and120(in120addr, in1[20], address); - and #20 and121(in121addr, in1[21], address); - and #20 and122(in122addr, in1[22], address); - and #20 and123(in123addr, in1[23], address); - and #20 and124(in124addr, in1[24], address); - and #20 and125(in125addr, in1[25], address); - and #20 and126(in126addr, in1[26], address); - and #20 and127(in127addr, in1[27], address); - and #20 and128(in128addr, in1[28], address); - and #20 and129(in129addr, in1[29], address); - and #20 and130(in130addr, in1[30], address); - and #20 and131(in131addr, in1[31], address); - - // or the and gates - or #20 or0(out[0], in00addr, in10addr); - or #20 or1(out[1], in01addr, in11addr); - or #20 or2(out[2], in02addr, in12addr); - or #20 or3(out[3], in03addr, in13addr); - or #20 or4(out[4], in04addr, in14addr); - or #20 or5(out[5], in05addr, in15addr); - or #20 or6(out[6], in06addr, in16addr); - or #20 or7(out[7], in07addr, in17addr); - or #20 or8(out[8], in08addr, in18addr); - or #20 or9(out[9], in09addr, in19addr); - or #20 or10(out[10], in010addr, in110addr); - or #20 or11(out[11], in011addr, in111addr); - or #20 or12(out[12], in012addr, in112addr); - or #20 or13(out[13], in013addr, in113addr); - or #20 or14(out[14], in014addr, in114addr); - or #20 or15(out[15], in015addr, in115addr); - or #20 or16(out[16], in016addr, in116addr); - or #20 or17(out[17], in017addr, in117addr); - or #20 or18(out[18], in018addr, in118addr); - or #20 or19(out[19], in019addr, in119addr); - or #20 or20(out[20], in020addr, in120addr); - or #20 or21(out[21], in021addr, in121addr); - or #20 or22(out[22], in022addr, in122addr); - or #20 or23(out[23], in023addr, in123addr); - or #20 or24(out[24], in024addr, in124addr); - or #20 or25(out[25], in025addr, in125addr); - or #20 or26(out[26], in026addr, in126addr); - or #20 or27(out[27], in027addr, in127addr); - or #20 or28(out[28], in028addr, in128addr); - or #20 or29(out[29], in029addr, in129addr); - or #20 or30(out[30], in030addr, in130addr); - or #20 or31(out[31], in031addr, in131addr); -endmodule - -// 32 bit adder/subtracter that determines what operation to conduct based on the input command -module adder_subtracter - ( - output[31:0] ans, - output carryout, - output overflow, - output reg zero, - input[31:0] opA, - input[31:0] opB, - input[2:0] command - ); - wire[31:0] invertedB; //wire to invert b in the event of a subtraction - wire[31:0] finalB; - wire normalB; //added b - wire cout0; - wire cout1; - wire cout2; - wire cout3; - wire cout4; - wire cout5; - wire cout6; - wire _; - wire _1; - wire _2; - wire _3; - wire _4; - wire _5; - wire _6; - - // invert B in the case of two's complement - not #10 invertB0(invertedB[0], opB[0]); - not #10 invertB1(invertedB[1], opB[1]); - not #10 invertB2(invertedB[2], opB[2]); - not #10 invertB3(invertedB[3], opB[3]); - not #10 invertB4(invertedB[4], opB[4]); - not #10 invertB5(invertedB[5], opB[5]); - not #10 invertB6(invertedB[6], opB[6]); - not #10 invertB7(invertedB[7], opB[7]); - not #10 invertB8(invertedB[8], opB[8]); - not #10 invertB9(invertedB[9], opB[9]); - not #10 invertB10(invertedB[10], opB[10]); - not #10 invertB11(invertedB[11], opB[11]); - not #10 invertB12(invertedB[12], opB[12]); - not #10 invertB13(invertedB[13], opB[13]); - not #10 invertB14(invertedB[14], opB[14]); - not #10 invertB15(invertedB[15], opB[15]); - not #10 invertB16(invertedB[16], opB[16]); - not #10 invertB17(invertedB[17], opB[17]); - not #10 invertB18(invertedB[18], opB[18]); - not #10 invertB19(invertedB[19], opB[19]); - not #10 invertB20(invertedB[20], opB[20]); - not #10 invertB21(invertedB[21], opB[21]); - not #10 invertB22(invertedB[22], opB[22]); - not #10 invertB23(invertedB[23], opB[23]); - not #10 invertB24(invertedB[24], opB[24]); - not #10 invertB25(invertedB[25], opB[25]); - not #10 invertB26(invertedB[26], opB[26]); - not #10 invertB27(invertedB[27], opB[27]); - not #10 invertB28(invertedB[28], opB[28]); - not #10 invertB29(invertedB[29], opB[29]); - not #10 invertB30(invertedB[30], opB[30]); - not #10 invertB31(invertedB[31], opB[31]); - - // mux chooses between inverted B or normal B based on addition or subtraction - mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); - - // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one - FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding - FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); - FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); - FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); - FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); - FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); - FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); - FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); - - always @(*) begin - if (ans === 32'b0) begin - zero <= 1; - end - - else begin - zero <= 0; - end - end -endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v deleted file mode 100644 index 322cd32..0000000 --- a/alu.t.v +++ /dev/null @@ -1,507 +0,0 @@ -`timescale 1 ns / 1 ps -`include "alu.v" - -module testALU32bit(); - reg[31:0] a; - reg[31:0] b; - reg[2:0] ALUcommand; - wire[31:0] finalALUsig; - wire flag; - wire cout; - - ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); - - initial begin - $display("ALU Command Input A Input B | Output Flag Carryout"); - //Test cases add - ALUcommand = 3'b000; - - // 0 + 0 - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // 1 + 1 - a = 32'b00000000000000000000000000000001; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // positive overflow - a = 32'b01111111111111111111111111111111; - b = 32'b01111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // negative overflow - a = 32'b10000000000000000000000000000001; - b = 32'b10000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // carryout - a = 32'b11111111111111111111111111111111; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - - //Test cases sub - ALUcommand = 3'b001; - - // a=b=0 - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a=b - a = 32'b00000000000000000000000000000001; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a>b, both positive - a = 32'b00000000000000000000000000000111; - b = 32'b00000000000000000000000000000101; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a|b|, both negative - a = 32'b11111111111111111111111111111101; - b = 32'b11111111111111111111111111111110; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // |a|<|b|, both negative - a = 32'b111111111111111111111111111111110; - b = 32'b111111111111111111111111111111000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a negative, b positive, no overflow - a = 32'b11111111111111111111111111111101; - b = 32'b00000000000000000000000000000101; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a negative, b positive, overflow - a = 32'b10000000000000000000000000000101; - b = 32'b01111100000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a positive, b negative, no overflow - a = 32'b00000000000000000000000000000101; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - //Here - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // a positive, b negative, overflow - a = 32'b01111111111111111111101111111111; - b = 32'b10000000000000001100000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //Test cases xor - ALUcommand = 3'b010; - - //a is all 0's - a = 32'b00000000000000000000000000000000; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //b is all 0's - b = 32'b00000000000000000000000000000000; - a = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a and b are all 0's - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a and b are all 1's - a = 32'b11111111111111111111111111111111; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - - //Test cases slt - ALUcommand = 3'b011; - - //a>b, all positive - a = 32'b00000000000000000000000000000010; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //ab, all negative - a = 32'b10000000000000000000000000000010; - b = 32'b10000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a>b, a positive, b negative - a = 32'b00000000000000000000000000000001; - b = 32'b10000000000000000000000000000010; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a Date: Sat, 11 Nov 2017 10:13:37 -0500 Subject: [PATCH 046/190] Implement module --- Core/Core.v | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/Core/Core.v b/Core/Core.v index 88659bc..26fb30b 100644 --- a/Core/Core.v +++ b/Core/Core.v @@ -1,18 +1,62 @@ // Core controls the central registor and memory storage and manipulation +`include "Core/ALU/alu.v" +`include "Core/memory.v" +`include "Core/regfile.v" +`include "Core/signextend.v" + module Core ( input CLK, // Decoded Instruction Values - input[5:0] Rd, Rt, Rs, + input[4:0] Rd, Rt, Rs, input[15:0] imm, input[31:0] addedPC, // Control Signals - input RegDst, RegWr, MemWr, ALUSrc, MemToReg, - + input[1:0] RegDst, + input RegWr, MemWr, ALUSrc, + input[1:0] MemToReg, + input[2:0] ALUCntrl, // Outputs output[31:0] Da, output isZero ); + wire[4:0] WriteAddr; + + // Register file write address + mux4input #(.width(5)) RegWriteAddr (Rd, Rt, 5'd31, 5'bx, RegDst, WriteAddr); + + // wire[31:0] dataaout; + wire[31:0] databout; + wire[31:0] datain; + + // Register file + regfile regfile (Da, databout, datain, Rs, Rt, WriteAddr, RegWr, CLK); + + // Sign extend + + wire[31:0] signextimm; + signextend extend (imm, signextimm); + + // ALU operand 2 mux + wire[31:0] operandb; + + mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, ALUSrc}, operandb); + + // ALU + wire cout; + wire overflow; + wire[31:0] finalsignal; + + ALUcontrolLUT aluout (cout, overflow, isZero, finalsignal, ALUCntrl, Da, operandb); + + // Regfile write data mux + wire[31:0] memout; + + mux4input #(.width(32)) regdatamux (finalsignal, memout, addedPC, 32'bx, MemToReg, datain); + + // Data Meomory + memory datamemory (CLK, memout, finalsignal, MemWr, databout); + endmodule From a9e1ce57024385f2218f6f4a6b4ebead94a779d9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:14:37 -0500 Subject: [PATCH 047/190] Update Core instantiation --- Core/Core.t.v | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 Core/Core.t.v diff --git a/Core/Core.t.v b/Core/Core.t.v new file mode 100644 index 0000000..6056f46 --- /dev/null +++ b/Core/Core.t.v @@ -0,0 +1,165 @@ +/* +Test bench for the core module of the CPU. +*/ + +`include "Core/Core.v" + +module Core_TEST(); + reg CLK; + reg [4:0] Rd; + reg [4:0] Rt; + reg [4:0] Rs; + reg [15:0] imm; + reg [31:0] addedPC; + reg [0:1] RegDst; + reg RegWr; + reg MemWr; + reg AlUSrc; + reg [1:0] MemToReg; + reg [2:0] ALUCntrl; + + wire [31:0] Da; + wire isZero; + + Core dut (CLK, Rd, Rt, Rs, imm, addedPC, RegDst, RegWr, MemWr, AlUSrc, MemToReg, ALUCntrl, Da, isZero); + + initial CLK = 0; + always #10 CLK = !CLK; + + initial begin + $dumpfile("Core/Core.vcd"); + $dumpvars(0, Core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); + + // Test Case 1: Add Imm + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd1; Rs = 5'b00000; imm = 16'b0; + #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + + // Populate the rest of the registers with data (each gets 32'b0) + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd2; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd4; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd5; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd6; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd7; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd8; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd9; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd10; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd11; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd12; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd13; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd14; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd15; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd18; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd19; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd21; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd22; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd23; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd24; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd25; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd26; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd27; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd28; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd29; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd30; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd31; Rs = 5'b00000; imm = 16'b0; + #6000 + + + // Test Case 2: Load Word + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b01; + Rd = 5'bx; Rt = 5'b00010; Rs = 5'b00001; imm = 16'b0; + #1000 + + if (dut.databout !== dut.datamemory.memory[0]) begin + $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimm] at time %t", $time); + end + + // Test Case 3: Store Word + RegDst = 2'bx; AlUSrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUCntrl = 3'b000; MemToReg = 2'bx; + Rd = 5'bx; Rs = 5'b00001; Rt = 5'b00000; imm = 16'b0; + #1000 + + if (dut.datamemory.dataOut !== dut.databout) begin + $display("Test case 3 failed: M[R[rs] + signextendimm] != R[rt] at time %t", $time); + end + + // Test Case 4: Jump + // Test Case 5: Jump Register + // Test Case 6: Jump and Link + // Test Case 7: Branch if Not Equal + // Test Case 8: XOR Immediate + // Test Case 9: Add + // Test Case 10: Subtract + // Test Case 11: Set Less Than + #10000 + + $finish; + end +endmodule \ No newline at end of file From 3a0bf3cc186751a7a0bff47c84085fccd1e65ae7 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:14:55 -0500 Subject: [PATCH 048/190] Update file references --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 54cd1bc..2789ebf 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,8 @@ all: core alu regfile memory signextend # Core modules -core: Core/core.v Core/core.t.v - iverilog -Wall -o core Core/core.t.v +core: Core/Core.v Core/Core.t.v + iverilog -Wall -o core Core/Core.t.v # ALU modules alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor From 4fa129f12e6e7a43c5e420145f7e4903cebef520 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:18:43 -0500 Subject: [PATCH 049/190] Remove old files that have been replaced --- Core/core.t.v | 165 -------------------------------------------------- Core/core.v | 66 -------------------- 2 files changed, 231 deletions(-) delete mode 100644 Core/core.t.v delete mode 100644 Core/core.v diff --git a/Core/core.t.v b/Core/core.t.v deleted file mode 100644 index 0ee8f25..0000000 --- a/Core/core.t.v +++ /dev/null @@ -1,165 +0,0 @@ -/* -Test bench for the core module of the CPU. -*/ - -`include "Core/core.v" - -module core_TEST(); - wire [31:0] Da; - wire is_zero; - - reg clk; - reg [4:0] rd; - reg [4:0] rt; - reg [4:0] rs; - reg [15:0] immediate; - reg [31:0] new_PC; - reg [0:1] regdst; - reg [2:0] ALUcntrl; - reg AlUsrc; - reg MemWr; - reg RegWr; - reg [1:0] MemtoReg; - - core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); - - initial clk = 0; - always #10 clk = !clk; - - initial begin - $dumpfile("Core/core.vcd"); - $dumpvars(0, core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); - - // Test Case 1: Add Immediate - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd1; rs = 5'b00000; immediate = 16'b0; - #6000 - - if (dut.databout !== 32'b0) begin - $display("Test case 1 failed: R[rt] != R[rs] + 32'b0"); - end - - // Populate the rest of the registers with data (each gets 32'b0) - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd2; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd3; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd4; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd5; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd6; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd7; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd8; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd9; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd10; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd11; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd12; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd13; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd14; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd15; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd16; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd17; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd18; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd19; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd20; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd21; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd22; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd23; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd24; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd25; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd26; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd27; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd28; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd29; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd30; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd31; rs = 5'b00000; immediate = 16'b0; - #6000 - - - // Test Case 2: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 2'b01; - rd = 5'bx; rt = 5'b00010; rs = 5'b00001; immediate = 16'b0; - #100 - - if (dut.databout !== dut.datamemory.memory[0]) begin - $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimmediate]"); - end - - // Test Case 3: Store Word - regdst = 2'bx; AlUsrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUcntrl = 3'b000; MemtoReg = 2'bx; - rd = 5'bx; rs = 5'b00001; rt = 5'b00000; immediate = 16'b0; - #100 - - if (dut.datamemory.dataOut !== dut.databout) begin - $display("Test case 3 failed: M[R[rs] + signextendimmediate] != R[rt]"); - end - - // Test Case 4: Jump - // Test Case 5: Jump Register - // Test Case 6: Jump and Link - // Test Case 7: Branch if Not Equal - // Test Case 8: XOR Immediate - // Test Case 9: Add - // Test Case 10: Subtract - // Test Case 11: Set Less Than - #10000 - - $finish; - end -endmodule \ No newline at end of file diff --git a/Core/core.v b/Core/core.v deleted file mode 100644 index f4ed3ac..0000000 --- a/Core/core.v +++ /dev/null @@ -1,66 +0,0 @@ -/* -The section of the CPU containing the register file, data memory, and ALU. -*/ - -`include "Core/ALU/alu.v" -`include "Core/memory.v" -`include "Core/regfile.v" -`include "Core/signextend.v" - -module core -( - input clk, - input [4:0] rd, - input [4:0] rt, - input [4:0] rs, - input [15:0] immediate, - input [31:0] new_PC, - input [0:1] regdst, - input [2:0] ALUcntrl, - input AlUsrc, - input MemWr, - input RegWr, - input [1:0] MemtoReg, - output [31:0] Da, - output is_zero -); - - wire[4:0] writeaddr; - - // Register file write address - mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - - // wire[31:0] dataaout; - wire[31:0] databout; - wire[31:0] datain; - - // Register file - regfile regfile (Da, databout, datain, rs, rt, writeaddr, RegWr, clk); - - // Sign extend - - wire[31:0] signextimm; - signextend extend (immediate, signextimm); - - // ALU operand 2 mux - wire[31:0] operandb; - - mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); - - // ALU - wire cout; - wire overflow; - wire[31:0] finalsignal; - - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, Da, operandb); - - // Regfile write data mux - wire[31:0] memout; - - mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); - - // Data Meomory - memory datamemory (clk, memout, finalsignal, MemWr, databout); - - -endmodule \ No newline at end of file From 9116483ff3183873f9e11368de342cdd5972a7d5 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:42:47 -0500 Subject: [PATCH 050/190] Change address size in test --- Core/multiplexer.t.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/multiplexer.t.v b/Core/multiplexer.t.v index 8f17795..ab85819 100644 --- a/Core/multiplexer.t.v +++ b/Core/multiplexer.t.v @@ -145,7 +145,7 @@ module mux32to32by1Test( // Test Case 1: // Ensure that the value chosen by the mux matches the value at the given address - address = 4'd20; + address = 5'd20; input0 = 32'd0; input1 = 32'd1; input2 = 32'd2; input3 = 32'd3; input4 = 32'd4; input5 = 32'd5; input6 = 32'd6; input7 = 32'd7; input8 = 32'd8; input9 = 32'd9; input10 = 32'd10; input11 = 32'd11; input12 = 32'd12; input13 = 32'd13; input14 = 32'd14; From 88c839b39fb9c77381903bde1281a0af25438fc9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:44:05 -0500 Subject: [PATCH 051/190] Change size of 2d array to correct width --- Core/multiplexer.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/multiplexer.v b/Core/multiplexer.v index f38b85f..a4f1220 100644 --- a/Core/multiplexer.v +++ b/Core/multiplexer.v @@ -8,11 +8,11 @@ input[width-1:0] input0, input1, input2, input3, input[1:0] address, output[width-1:0] out ); - wire[1:0] mux [width-1:0]; - assign mux[0] = input0; - assign mux[1] = input1; - assign mux[2] = input2; - assign mux[3] = input3; + wire[5:0] mux [width-1:0]; + assign mux[0] = input0[width-1:0]; + assign mux[1] = input1[width-1:0]; + assign mux[2] = input2[width-1:0]; + assign mux[3] = input3[width-1:0]; assign out = mux[address]; endmodule From d15b6aa813b7856843dd1b5ef80a80108587a8d3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:45:25 -0500 Subject: [PATCH 052/190] Add build rules for new modules --- makefile | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/makefile b/makefile index 2789ebf..2fa4be9 100644 --- a/makefile +++ b/makefile @@ -1,51 +1,73 @@ all: core alu regfile memory signextend -# Core modules -core: Core/Core.v Core/Core.t.v - iverilog -Wall -o core Core/Core.t.v +### PC Modules + +### PC_Calc Modules +# PC_Calc top level module +PC_Calc: PC_Calc/PC_Calc.v addr_concat imm_concat is_zero_and + iverilog -Wall -o PC_Calc/PC_Calc PC_Calc.v + +addr_concat: PC_Calc/addr_concat.v PC_Calc/addr_concat.t.v + iverilog -Wall -o PC_Calc/addr_concat addr_concat.t.v + +imm_concat: PC_Calc/imm_concat.v PC_Calc/imm_concat.t.v + iverilog -Wall -o PC_Calc/imm_concat imm_concat.t.v + +is_zero_and: PC_Calc/is_zero_and.v PC_Calc/is_zero_and.t.v + iverilog -Wall -o PC_Calc/is_zero_and is_zero_and.t.v + +### Instruction Parser Modules +# Instruction Parser top level module +Instruction_Parser: Instruction_Parser.v + iverilog -Wall -o Instruction_Parser/Instruction_Parser Instruction_Parser.v + +### Core Modules +# Core top level module +core: Core/Core.v Core/Core.t.v regfile + iverilog -Wall -o Core/core Core/Core.t.v # ALU modules alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor - iverilog -Wall -o alu Core/ALU/alu.t.v + iverilog -Wall -o Core/ALU/alu Core/ALU/alu.t.v adder_subtracter: Core/ALU/adder_subtracter.v Core/ALU/adder_subtracter.t.v - iverilog -Wall -o adder_subtracter Core/ALU/adder_subtracter.t.v + iverilog -Wall -o Core/ALU/adder_subtracter Core/ALU/adder_subtracter.t.v and: Core/ALU/and_32bit.v Core/ALU/and_32bit.t.v - iverilog -Wall -o and Core/ALU/and_32bit.t.v + iverilog -Wall -o Core/ALU/and Core/ALU/and_32bit.t.v nand: Core/ALU/nand_32bit.v Core/ALU/nand_32bit.t.v - iverilog -Wall -o nand Core/ALU/nand_32bit.t.v + iverilog -Wall -o Core/ALU/nand Core/ALU/nand_32bit.t.v nor: Core/ALU/nor_32bit.v Core/ALU/nor_32bit.t.v - iverilog -Wall -o nor Core/ALU/nor_32bit.t.v + iverilog -Wall -o Core/ALU/nor Core/ALU/nor_32bit.t.v or: Core/ALU/or_32bit.v Core/ALU/or_32bit.t.v - iverilog -Wall -o or Core/ALU/or_32bit.t.v + iverilog -Wall -o Core/ALU/or Core/ALU/or_32bit.t.v slt: Core/ALU/slt.v Core/ALU/slt.t.v - iverilog -Wall -o slt Core/ALU/slt.t.v + iverilog -Wall -o Core/ALU/slt Core/ALU/slt.t.v xor: Core/ALU/xor_32bit.v Core/ALU/xor_32bit.t.v - iverilog -Wall -o xor Core/ALU/xor_32bit.t.v + iverilog -Wall -o Core/ALU/xor Core/ALU/xor_32bit.t.v # Regfile modules regfile: Core/regfile.t.v Core/regfile.v decoder mux register - iverilog -Wall -o regfile Core/regfile.t.v + iverilog -Wall -o Core/regfile Core/regfile.t.v decoder: Core/decoders.t.v Core/decoders.v - iverilog -Wall -o decoder Core/decoders.t.v + iverilog -Wall -o Core/decoder Core/decoders.t.v mux: Core/multiplexer.t.v Core/multiplexer.v - iverilog -Wall -o mux Core/multiplexer.t.v + iverilog -Wall -o Core/mux Core/multiplexer.t.v register: Core/register.t.v Core/register.v - iverilog -Wall -o register Core/register.t.v + iverilog -Wall -o Core/register Core/register.t.v # Memory modules memory: Core/memory.v Core/memory.t.v - iverilog -Wall -o memory Core/memory.t.v + iverilog -Wall -o Core/memory Core/memory.t.v # Concatenation modules signextend: Core/signextend.v - iverilog -Wall -o signextend Core/signextend.v + iverilog -Wall -o Core/signextend Core/signextend.v From 8be98892718a75f20a0c990dc1d87d1e15f64698 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:45:38 -0500 Subject: [PATCH 053/190] Add remaining tests --- Core/Core.t.v | 283 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 274 insertions(+), 9 deletions(-) diff --git a/Core/Core.t.v b/Core/Core.t.v index 6056f46..c5f83cf 100644 --- a/Core/Core.t.v +++ b/Core/Core.t.v @@ -43,94 +43,242 @@ module Core_TEST(); RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd2; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd4; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd5; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd6; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd7; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd8; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd9; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd10; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd11; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd12; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd13; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd14; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd15; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd18; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd19; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd21; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd22; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd23; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd24; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd25; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd26; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd27; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd28; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd29; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd30; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd31; Rs = 5'b00000; imm = 16'b0; #6000 + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end // Test Case 2: Load Word RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b01; @@ -150,15 +298,132 @@ module Core_TEST(); $display("Test case 3 failed: M[R[rs] + signextendimm] != R[rt] at time %t", $time); end - // Test Case 4: Jump - // Test Case 5: Jump Register - // Test Case 6: Jump and Link - // Test Case 7: Branch if Not Equal - // Test Case 8: XOR Immediate - // Test Case 9: Add - // Test Case 10: Subtract - // Test Case 11: Set Less Than - #10000 + // Test Case 4: Jump and Link + RegDst = 2'b10; AlUSrc = 1'bx; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'bx; MemToReg = 2'b10; + Rd = 5'bx; Rs = 5'd31; Rt = 5'bx; imm = 16'bx; addedPC = 5'd25; + #1000 + + if (Da !== addedPC) begin + $display("Test case 4 failed: PC value not saved to correct register at time %t", $time); + end + + #1000 + + // Test Case 5: Branch if Not Equal + // Load Immediate into registers 16 and 17 so that they are not equal. + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'd16; // R[16] = 0 + 16 = 16 + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'd17; // R[17] = 0 + 17 = 17 + #6000 + + RegDst = 2'bx; AlUSrc = 1'b0; RegWr = 1'b0; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'bx; + Rd = 5'dx; Rs = 5'd16; Rt = 5'd17; imm = 16'bx; + #6000 + + if (dut.regfile.register16out === dut.regfile.register17out) begin + $display("Error: R[rs] should not equal R[rt]"); + end + + if (isZero === 1'b1) begin + $display("Test case 5 failed: R[Rs] == R[Rt] indicated, but these values are not equal at time %t", $time); + end + + // Load Immediate into registers 16 and 17 so that they are equal. + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'd15; // R[16] = 0 + 15 = 15 + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'd15; // R[17] = 0 + 15 = 15 + #6000 + + RegDst = 2'bx; AlUSrc = 1'b0; RegWr = 1'b0; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'bx; + Rd = 5'dx; Rs = 5'd16; Rt = 5'd17; imm = 16'bx; + #6000 + + if (dut.regfile.register16out !== dut.regfile.register17out) begin + $display("Error: R[rs] should equal R[rt]"); + end + + if (isZero === 1'b0) begin + $display("Test case 5 failed: R[Rs] != R[Rt] indicated, but these values are equal at time %t", $time); + end + + // Test Case 6: XOR Immediate + // Load Immediate into register 17 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'h00005555; + #6000 + + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b010; MemToReg = 2'b0; + Rd = 5'dx; Rs = 5'd17; Rt = 5'd16; imm = 16'h00005555; + #6000 + + if (dut.databout != 32'b0) begin + $display("Test case 6 failed: R[Rs] == signextendimm and R[Rs] XOR signextendimm != 32'b0 at time %t", $time); + end + + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b010; MemToReg = 2'b0; + Rd = 5'dx; Rs = 5'd17; Rt = 5'd16; imm = 16'h0000aaaa; + #6000 + + if (dut.databout != 32'h0000003f) begin + $display("Test case 6 failed: R[Rs] != signextendimm and R[Rs] XOR signextendimm != 32'h0000ffff at time %t", $time); + end + + // Test Case 7: Add + // Load Immediate into register 20 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'd25; + #6000 + + // Load Immediate into register 3 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'd19; + #6000 + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'd44) begin + $display("Test case 7 failed: R[Rd] != R[Rs] + R[Rt] at time %t", $time); + end + + // Test Case 8: Subtract + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'd6) begin + $display("Test case 8 failed: R[Rd] != R[Rs] - R[Rt] at time %t", $time); + end + + // Test Case 9: Set Less Than + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b0) begin + $display("Test case 9 failed: R[Rd] is not zero, but R[Rs] !< R[Rt] at time %t", $time); + end + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd3; Rt = 5'd20; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b1) begin + $display("Test case 9 failed: R[Rd] is not one, but R[Rs] < R[Rt] at time %t", $time); + end + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd20; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b0) begin + $display("Test case 9 failed: R[Rd] is not zero, but R[Rs] == R[Rt] at time %t", $time); + end $finish; end From 07e7375b5c25aa847b22fd05d6123c62d15f8d53 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 13:25:53 -0500 Subject: [PATCH 054/190] Instruction_Parser now compiles --- Instruction_Parser/Controller.v | 8 ++++---- Instruction_Parser/Instruction_Parser.v | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index 6bcd812..5757c63 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -24,10 +24,10 @@ module Controller localparam SUB_f = 6'h22; // ALU Control mapping - localparam alu_add = 2'd0; - localparam alu_sub = 2'd1; - localparam alu_xor = 2'd2; - localparam alu_slt = 2'd4; + localparam alu_add = 3'd0; + localparam alu_sub = 3'd1; + localparam alu_xor = 3'd2; + localparam alu_slt = 3'd4; always @ * begin case (Op) diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 7e5a1ca..765329c 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -1,6 +1,8 @@ // Instruction Parser parses the relevant data and control signals from the instruction. `include "Memory.v" +`include "Decoder.v" +`include "Controller.v" module Instruction_Parser ( @@ -9,12 +11,14 @@ module Instruction_Parser output[4:0] Rs, Rd, Rt, output[15:0] imm, output[25:0] addr, - output ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel + output[2:0] ALUCtrl, + output[1:0] MemToReg, RegDst, PCSel, AddSel, + output MemWr, ALUSrc, RegWr ); wire[31:0] instr; - Memory Instruction_Memory(.Addr(PC), .DataOut(instr)); + Memory Instruction_Memory(.Addr(PC[9:0]), .DataOut(instr)); - wire[5:0] Op; + wire[5:0] Op, funct; wire[4:0] Rs, Rd, Rt; wire[15:0] imm; wire[25:0] addr; @@ -23,4 +27,12 @@ module Instruction_Parser .Rs(Rs), .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr) ); + Controller ctrlr( + .Op(Op), .funct(funct), + .ALUCtrl(ALUCtrl), + .MemToReg(MemToReg), .RegDst(RegDst), + .PCSel(PCSel), .AddSel(AddSel), + .MemWr(MemWr), .ALUSrc(ALUSrc), .RegWr(RegWr) + ); + endmodule From 2c513180b6f54061100bc6beb8151d35299c9567 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 13:34:13 -0500 Subject: [PATCH 055/190] Change AddCtrl to be 1 bit because of difference in JAL --- Instruction_Parser/Controller.v | 8 ++++---- Instruction_Parser/Instruction_Parser.v | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index 5757c63..cf38a18 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -4,8 +4,8 @@ module Controller ( input[5:0] Op, funct, output reg[2:0] ALUCtrl, - output reg[1:0] MemToReg, RegDst, PCSel, AddSel, - output reg MemWr, ALUSrc, RegWr + output reg[1:0] MemToReg, RegDst, PCSel, + output reg MemWr, ALUSrc, RegWr, AddSel ); // Opcodes @@ -69,7 +69,7 @@ module Controller ALUCtrl = 2'bxx; MemToReg = 2'd2; PCSel = 0; - AddSel = 1; + AddSel = 0; end BNE: begin RegDst = 2'bxx; @@ -79,7 +79,7 @@ module Controller ALUCtrl = alu_sub; MemToReg = 2'bxx; PCSel = 1; - AddSel = 2'd2; + AddSel = 1; end XORI: begin RegDst = 1; diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 765329c..2ef571a 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -12,8 +12,8 @@ module Instruction_Parser output[15:0] imm, output[25:0] addr, output[2:0] ALUCtrl, - output[1:0] MemToReg, RegDst, PCSel, AddSel, - output MemWr, ALUSrc, RegWr + output[1:0] MemToReg, RegDst, PCSel, + output MemWr, ALUSrc, RegWr, AddSel ); wire[31:0] instr; Memory Instruction_Memory(.Addr(PC[9:0]), .DataOut(instr)); From 93debddd884a0252694d0b338e2009225b0715e2 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 14:26:24 -0500 Subject: [PATCH 056/190] Added initial tests, found bug in jump --- Instruction_Parser/Controller.t.v | 106 ++++++++++++++++++++++++++++++ Instruction_Parser/Controller.v | 2 +- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 Instruction_Parser/Controller.t.v diff --git a/Instruction_Parser/Controller.t.v b/Instruction_Parser/Controller.t.v new file mode 100644 index 0000000..40a05bd --- /dev/null +++ b/Instruction_Parser/Controller.t.v @@ -0,0 +1,106 @@ +// Tests the Decoder + +`include "Controller.v" + +module testController(); + + reg[5:0] Op, funct; + wire[2:0] ALUCtrl; + wire [1:0] MemToReg, RegDst, PCSel; + wire MemWr, ALUSrc, RegWr, AddSel; + + Controller ctrlr( + .Op(Op), .funct(funct), + .ALUCtrl(ALUCtrl), + .MemToReg(MemToReg), .RegDst(RegDst), + .PCSel(PCSel), .AddSel(AddSel), + .MemWr(MemWr), .ALUSrc(ALUSrc), .RegWr(RegWr) + ); + + // Opcodes + localparam LW = 6'h23; + localparam SW = 6'h2b; + localparam J = 6'h2; + localparam JAL = 6'h3; + localparam BNE = 6'h5; + localparam XORI = 6'he; + localparam ADDI = 6'h8; + + // These instructions all have opcode 0 and are designated by funct + localparam JR_f = 6'h08; + localparam ADD_f = 6'h20; + localparam SLT_f = 6'h2a; + localparam SUB_f = 6'h22; + + // ALU Control mapping + localparam alu_add = 3'd0; + localparam alu_sub = 3'd1; + localparam alu_xor = 3'd2; + localparam alu_slt = 3'd4; + + initial begin + // $dumpfile("Controller.vcd"); + // $dumpvars; + + // Test all Ops where the func doesn't matter + funct = 6'bxxxxxx; + + Op = LW; #1 + if ((RegDst == 1) && (ALUSrc == 1) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_add) && (MemToReg == 1) && + (PCSel == 1)) begin + $display("Test 1 Passed!"); + end + else begin + $display("Test 1 Failed!"); + end + + Op = SW; #1 + if ((ALUSrc == 1) && + (RegWr == 0) && (MemWr == 1) && + (ALUCtrl == alu_add) && + (PCSel == 1)) begin + $display("Test 2 Passed!"); + end + else begin + $display("Test 2 Failed!"); + end + + Op = J; #1 + if ((RegWr == 0) && (MemWr == 0) && + (PCSel == 0) && (AddSel == 0)) begin + $display("Test 3 Passed!"); + end + else begin + $display("Test 3 Failed!"); + $display("RegWr: %b", RegWr); + $display("MemWr: %b", MemWr); + $display("PCSel: %b", PCSel); + $display("AddSel: %b", AddSel); + end + + // instr = 32'b11111111111111111111111111111111; #1 + // if ((Op == 6'b111111) && (Rs == 5'b11111) && + // (Rd == 5'b11111) && (Rt == 5'b11111) && + // (imm == 16'b1111111111111111) && (funct == 6'b111111) && + // (addr == 26'b11111111111111111111111111)) begin + // $display("Test 2 Passed!"); + // end + // else begin + // $display("Test 2 Failed!"); + // end + + // instr = 32'b11001100110011001100110011001100; #1 + // if ((Op == 6'b110011) && (Rs == 5'b00110) && + // (Rd == 5'b11001) && (Rt == 5'b01100) && + // (imm == 16'b1100110011001100) && (funct == 6'b001100) && + // (addr == 26'b00110011001100110011001100)) begin + // $display("Test 3 Passed!"); + // end + // else begin + // $display("Test 3 Failed!"); + // end + end + +endmodule diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index cf38a18..52b3114 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -55,7 +55,7 @@ module Controller RegDst = 1'bx; ALUSrc = 1'bx; RegWr = 0; - MemWr = 1; + MemWr = 0; ALUCtrl = 2'bxx; MemToReg = 1'bx; PCSel = 0; From 859087da2c262f688ab888ff90eee178a8823988 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 14:50:47 -0500 Subject: [PATCH 057/190] Finish Tests, update Controller xs to be full # of bits --- Instruction_Parser/Controller.t.v | 131 ++++++++++++++++++++++++------ Instruction_Parser/Controller.v | 24 +++--- 2 files changed, 120 insertions(+), 35 deletions(-) diff --git a/Instruction_Parser/Controller.t.v b/Instruction_Parser/Controller.t.v index 40a05bd..c8957ea 100644 --- a/Instruction_Parser/Controller.t.v +++ b/Instruction_Parser/Controller.t.v @@ -1,4 +1,4 @@ -// Tests the Decoder +// Tests the Controller `include "Controller.v" @@ -42,7 +42,7 @@ module testController(); // $dumpfile("Controller.vcd"); // $dumpvars; - // Test all Ops where the func doesn't matter + // Test all instructions where the func field doesn't matter funct = 6'bxxxxxx; Op = LW; #1 @@ -80,27 +80,112 @@ module testController(); $display("AddSel: %b", AddSel); end - // instr = 32'b11111111111111111111111111111111; #1 - // if ((Op == 6'b111111) && (Rs == 5'b11111) && - // (Rd == 5'b11111) && (Rt == 5'b11111) && - // (imm == 16'b1111111111111111) && (funct == 6'b111111) && - // (addr == 26'b11111111111111111111111111)) begin - // $display("Test 2 Passed!"); - // end - // else begin - // $display("Test 2 Failed!"); - // end - - // instr = 32'b11001100110011001100110011001100; #1 - // if ((Op == 6'b110011) && (Rs == 5'b00110) && - // (Rd == 5'b11001) && (Rt == 5'b01100) && - // (imm == 16'b1100110011001100) && (funct == 6'b001100) && - // (addr == 26'b00110011001100110011001100)) begin - // $display("Test 3 Passed!"); - // end - // else begin - // $display("Test 3 Failed!"); - // end + Op = JAL; #1 + if ((RegDst == 2'd2) && (RegWr == 1) && + (MemWr == 0) && (MemToReg == 2'd2) && + (PCSel == 0) && (AddSel == 0)) begin + $display("Test 5 Passed!"); + end + else begin + $display("Test 5 Failed!"); + $display("RegWr: %b", RegWr); + $display("MemWr: %b", MemWr); + $display("PCSel: %b", PCSel); + $display("AddSel: %b", AddSel); + end + + Op = BNE; #1 + if ((ALUSrc == 0) && (RegWr == 0) && + (MemWr == 0) && (ALUCtrl == alu_sub) && + (PCSel == 1) && (AddSel == 1)) begin + $display("Test 6 Passed!"); + end + else begin + $display("Test 6 Failed!"); + $display("RegWr: %b", RegWr); + $display("MemWr: %b", MemWr); + $display("PCSel: %b", PCSel); + $display("AddSel: %b", AddSel); + end + + Op = XORI; #1 + if ((RegDst == 1) && (ALUSrc == 1) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_xor) && (MemToReg == 0) && + (PCSel == 1) && (AddSel == 0)) begin + $display("Test 7 Passed!"); + end + else begin + $display("Test 7 Failed!"); + end + + Op = ADDI; #1 + if ((RegDst == 1) && (ALUSrc == 1) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_add) && (MemToReg == 0) && + (PCSel == 1) && (AddSel == 0)) begin + $display("Test 8 Passed!"); + end + else begin + $display("Test 8 Failed!"); + end + + // Test all instructions where the op field is 0 + Op = 0; + + funct = JR_f; #1 + if ((RegWr == 0) && (MemWr == 0) && + (PCSel == 2'd2) && (AddSel == 0)) begin + $display("Test 9 Passed!"); + end + else begin + $display("Test 9 Failed!"); + $display("RegWr: %b", RegWr); + $display("MemWr: %b", MemWr); + $display("PCSel: %b", PCSel); + $display("AddSel: %b", AddSel); + end + + funct = ADD_f; #1 + if ((RegDst == 0) && (ALUSrc == 0) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_add) && (MemToReg == 0) && + (PCSel == 1) && (AddSel == 0)) begin + $display("Test 10 Passed!"); + end + else begin + $display("Test 10 Failed!"); + $display("RegDst: %b", RegDst); + $display("ALUSrc: %b", ALUSrc); + $display("RegWr: %b", RegWr); + $display("MemWr: %b", MemWr); + $display("ALUCtrl: %b", ALUCtrl); + $display("MemToReg: %b", MemToReg); + $display("PCSel: %b", PCSel); + $display("AddSel: %b", AddSel); + end + + funct = SUB_f; #1 + if ((RegDst == 0) && (ALUSrc == 0) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_sub) && (MemToReg == 0) && + (PCSel == 1) && (AddSel == 0)) begin + $display("Test 11 Passed!"); + end + else begin + $display("Test 11 Failed!"); + end + + funct = SLT_f; #1 + if ((RegDst == 0) && (ALUSrc == 0) && + (RegWr == 1) && (MemWr == 0) && + (ALUCtrl == alu_slt) && (MemToReg == 0) && + (PCSel == 1) && (AddSel == 0)) begin + $display("Test 12 Passed!"); + end + else begin + $display("Test 12 Failed!"); + end end endmodule diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index 52b3114..fc02199 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -42,22 +42,22 @@ module Controller AddSel = 1'bx; end SW: begin - RegDst = 1'bx; + RegDst = 2'bxx; ALUSrc = 1; RegWr = 0; MemWr = 1; ALUCtrl = alu_add; - MemToReg = 1'bx; + MemToReg = 2'bxx; PCSel = 1; AddSel = 1'bx; end J: begin - RegDst = 1'bx; + RegDst = 2'bxx; ALUSrc = 1'bx; RegWr = 0; MemWr = 0; - ALUCtrl = 2'bxx; - MemToReg = 1'bx; + ALUCtrl = 3'bxxx; + MemToReg = 2'bxx; PCSel = 0; AddSel = 0; end @@ -66,7 +66,7 @@ module Controller ALUSrc = 1'bx; RegWr = 1; MemWr = 0; - ALUCtrl = 2'bxx; + ALUCtrl = 3'bxxx; MemToReg = 2'd2; PCSel = 0; AddSel = 0; @@ -109,8 +109,8 @@ module Controller ALUSrc = 1'bx; RegWr = 0; MemWr = 0; - ALUCtrl = 2'bxx; - MemToReg = 1'bx; + ALUCtrl = 3'bxxx; + MemToReg = 2'bxx; PCSel = 2'd2; AddSel = 0; end @@ -149,8 +149,8 @@ module Controller ALUSrc = 1'bx; RegWr = 1'bx; MemWr = 1'bx; - ALUCtrl = 2'bxx; - MemToReg = 1'bx; + ALUCtrl = 3'bxxx; + MemToReg = 2'bxx; PCSel = 2'bxx; AddSel = 1'bx; end @@ -161,8 +161,8 @@ module Controller ALUSrc = 1'bx; RegWr = 1'bx; MemWr = 1'bx; - ALUCtrl = 2'bxx; - MemToReg = 1'bx; + ALUCtrl = 3'bxxx; + MemToReg = 2'bxx; PCSel = 2'bxx; AddSel = 1'bx; end From ec03d249c18dfe951626d3a48e0a7d35c3825195 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 16:14:08 -0500 Subject: [PATCH 058/190] Add program runner, add barebones for testing memory --- Instruction_Parser/Memory.t.v | 25 +++++++++++++++++++++++++ Instruction_Parser/Memory.v | 3 ++- Instruction_Parser/test_mem.dat | 2 ++ run_program.sh | 20 ++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 Instruction_Parser/Memory.t.v create mode 100644 Instruction_Parser/test_mem.dat create mode 100755 run_program.sh diff --git a/Instruction_Parser/Memory.t.v b/Instruction_Parser/Memory.t.v new file mode 100644 index 0000000..83d54d9 --- /dev/null +++ b/Instruction_Parser/Memory.t.v @@ -0,0 +1,25 @@ +// Tests the Memory + +`include "Memory.v" + +module testMemory(); + + reg clk, regWE; + reg[9:0] Addr; + reg[31:0] DataIn; + wire[31:0] DataOut; + + Memory Instruction_Memory(.Addr(Addr), .DataOut(DataOut)); + + initial begin + // Before memory is initialized, all addresses should return x's + Addr = 0; + if (DataOut == 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin + $display("Test 1 Passed"); + end + else begin + $display("Test 1 Failed"); + end + end + +endmodule diff --git a/Instruction_Parser/Memory.v b/Instruction_Parser/Memory.v index 071e86a..f5c9d54 100644 --- a/Instruction_Parser/Memory.v +++ b/Instruction_Parser/Memory.v @@ -16,7 +16,8 @@ module Memory end end - //initial $readmemh(“file.dat”, mem); + // This file will be loaded dynamically. Do not edit mem.dat directly. + initial $readmemh("../mem.dat", mem); assign DataOut = mem[Addr]; endmodule diff --git a/Instruction_Parser/test_mem.dat b/Instruction_Parser/test_mem.dat new file mode 100644 index 0000000..881e2f9 --- /dev/null +++ b/Instruction_Parser/test_mem.dat @@ -0,0 +1,2 @@ +// Contains hex representation of memory for testing +0000_0000 diff --git a/run_program.sh b/run_program.sh new file mode 100755 index 0000000..e65a989 --- /dev/null +++ b/run_program.sh @@ -0,0 +1,20 @@ +# Runs a verilog testbench using a given memory file +# Inputs: +# name of verilog testbench to run +# name of memory file to use + +# NOTE: must be run in top-level git repo + +ver () { + cd $(dirname $1) + inp=${1%.v} + fname="$(basename $inp)" + iverilog -o "$fname.out" $(basename $1) && "./$fname.out" + # Go back (also suppress the output text that would normally be displayed) + cd - > /dev/null +} + + +cat $2 > mem.dat +ver $1 +rm mem.dat From 65544d5abc08bf72b252dabddff195908e2c4d10 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 16:58:56 -0500 Subject: [PATCH 059/190] Instruction Parser only runs when it is executed from right directory now --- run_program.sh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/run_program.sh b/run_program.sh index e65a989..9aeaec2 100755 --- a/run_program.sh +++ b/run_program.sh @@ -14,7 +14,12 @@ ver () { cd - > /dev/null } - -cat $2 > mem.dat -ver $1 -rm mem.dat +d=${PWD##*/} +if [ "$d" = "Lab3" ] +then + cat $2 > mem.dat + ver $1 + rm mem.dat +else + echo "ERROR: This must be run in top-level directory" +fi From 3e98160ba36dde532fb687221b7fec169a026715 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 17:09:57 -0500 Subject: [PATCH 060/190] First memory test runs --- Instruction_Parser/Memory.t.v | 2 +- Instruction_Parser/test_mem.dat | 1024 ++++++++++++++++++++++++++++++- 2 files changed, 1024 insertions(+), 2 deletions(-) diff --git a/Instruction_Parser/Memory.t.v b/Instruction_Parser/Memory.t.v index 83d54d9..a578641 100644 --- a/Instruction_Parser/Memory.t.v +++ b/Instruction_Parser/Memory.t.v @@ -14,7 +14,7 @@ module testMemory(); initial begin // Before memory is initialized, all addresses should return x's Addr = 0; - if (DataOut == 32'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) begin + if (DataOut == 32'h00_00) begin $display("Test 1 Passed"); end else begin diff --git a/Instruction_Parser/test_mem.dat b/Instruction_Parser/test_mem.dat index 881e2f9..51eba65 100644 --- a/Instruction_Parser/test_mem.dat +++ b/Instruction_Parser/test_mem.dat @@ -1,2 +1,1024 @@ -// Contains hex representation of memory for testing +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 0000_0000 From e9ded79163eba908390d9f3fcbef88b170a6026a Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 17:14:44 -0500 Subject: [PATCH 061/190] Finish memory Tests --- Instruction_Parser/Memory.t.v | 22 ++++++++++++++++++++-- Instruction_Parser/test_mem.dat | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Instruction_Parser/Memory.t.v b/Instruction_Parser/Memory.t.v index a578641..c53f553 100644 --- a/Instruction_Parser/Memory.t.v +++ b/Instruction_Parser/Memory.t.v @@ -1,4 +1,7 @@ // Tests the Memory +// To use this test, the memory must be dyanmically using the following command: +// ./run_program.sh Instruction_Parser/Memory.t.v Instruction_Parser/test_mem.dat + `include "Memory.v" @@ -12,14 +15,29 @@ module testMemory(); Memory Instruction_Memory(.Addr(Addr), .DataOut(DataOut)); initial begin - // Before memory is initialized, all addresses should return x's Addr = 0; - if (DataOut == 32'h00_00) begin + if (DataOut == 32'h0000_0000) begin $display("Test 1 Passed"); end else begin $display("Test 1 Failed"); end + + Addr = 1; + if (DataOut == 32'hFFFF_FFFF) begin + $display("Test 2 Passed"); + end + else begin + $display("Test 2 Failed"); + end + + Addr = 3; + if (DataOut == 32'h0F0F_0F0F) begin + $display("Test 3 Passed"); + end + else begin + $display("Test 3 Failed"); + end end endmodule diff --git a/Instruction_Parser/test_mem.dat b/Instruction_Parser/test_mem.dat index 51eba65..d801a6c 100644 --- a/Instruction_Parser/test_mem.dat +++ b/Instruction_Parser/test_mem.dat @@ -1,6 +1,6 @@ 0000_0000 -0000_0000 -0000_0000 +FFFF_FFFF +0F0F_0F0F 0000_0000 0000_0000 0000_0000 From 9f0ede7985ca806fc45cb639a1662b12dcf62382 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 18:00:35 -0500 Subject: [PATCH 062/190] Add InstructionParser test --- Instruction_Parser/Instruction_Parser.t.v | 73 +++++++++++++++++++++++ Instruction_Parser/Instruction_Parser.v | 4 +- 2 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 Instruction_Parser/Instruction_Parser.t.v diff --git a/Instruction_Parser/Instruction_Parser.t.v b/Instruction_Parser/Instruction_Parser.t.v new file mode 100644 index 0000000..4ae43e6 --- /dev/null +++ b/Instruction_Parser/Instruction_Parser.t.v @@ -0,0 +1,73 @@ +// Tests the Instruction Parser +// To use this test, the Instruction Memory must be dyanmically using the following command: +// ./run_program.sh Instruction_Parser/Instruction_Parser.t.v Instruction_Parser/test_mem.dat + +`include "Instruction_Parser.v" + +module testInstructionParser(); + + reg[31:0] PC; + // Instruction values + wire[4:0] Rs, Rd, Rt; + wire[15:0] imm; + wire[25:0] addr; + // Control Signals + wire[2:0] ALUCtrl; + wire[1:0] MemToReg, RegDst, PCSel; + wire MemWr, ALUSrc, RegWr, AddSel; + + InstructionParser ip( + .PC(PC), + .Rs(Rs), .Rd(Rd), .Rt(Rt), + .imm(imm), .addr(addr), + .ALUCtrl(ALUCtrl), .MemToReg(MemToReg), + .MemWr(MemWr), .ALUSrc(ALUSrc), .PCSel(PCSel), + .RegDst(RegDst), .RegWr(RegWr), .AddSel(AddSel) + ); + + initial begin + + PC = 0; #1; + if ((Rs == 0) && + (Rd == 0) && + (Rt == 0) && + (imm == 0) && + (addr == 0) + ) begin + $display("Test 1 Passed"); + end + else begin + $display("Test 1 Failed"); + end + + PC = 1; #1; + if ((Rs == 5'b11111) && + (Rd == 5'b11111) && + (Rt == 5'b11111) && + (imm == 16'hFFFF) && + (addr == 26'b11111111111111111111111111) + ) begin + $display("Test 2 Passed"); + end + else begin + $display("Test 2 Failed"); + end + + // Addr = 1; + // if (DataOut == 32'hFFFF_FFFF) begin + // $display("Test 2 Passed"); + // end + // else begin + // $display("Test 2 Failed"); + // end + + // Addr = 3; + // if (DataOut == 32'h0F0F_0F0F) begin + // $display("Test 3 Passed"); + // end + // else begin + // $display("Test 3 Failed"); + // end + end + +endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 2ef571a..df4611d 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -4,7 +4,7 @@ `include "Decoder.v" `include "Controller.v" -module Instruction_Parser +module InstructionParser ( input[31:0] PC, // Instruction values @@ -16,7 +16,7 @@ module Instruction_Parser output MemWr, ALUSrc, RegWr, AddSel ); wire[31:0] instr; - Memory Instruction_Memory(.Addr(PC[9:0]), .DataOut(instr)); + Memory InstructionMemory(.Addr(PC[9:0]), .DataOut(instr)); wire[5:0] Op, funct; wire[4:0] Rs, Rd, Rt; From 5d8819472fc648a63dea59b86d6c74300718ff34 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 21:59:55 -0500 Subject: [PATCH 063/190] Create module encompassing ALU, RegFile, and Memory --- core.v | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 core.v diff --git a/core.v b/core.v new file mode 100644 index 0000000..e8c7d6f --- /dev/null +++ b/core.v @@ -0,0 +1,11 @@ +/* +The section of the CPU containing the register file, data memory, and ALU. +*/ + +module core ( + +); + +// code here + +endmodule \ No newline at end of file From d69f56cb6db21f93ed1d4e3d9457de9a957349df Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:00:17 -0500 Subject: [PATCH 064/190] Create makefile to build modules --- makefile | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 makefile diff --git a/makefile b/makefile new file mode 100644 index 0000000..7adc08f --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +all: core + +core: core.v + iverilog -Wall -o core core.v \ No newline at end of file From fc38651f5c5d019b54a0d768db4a6062971267ca Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:25:06 -0500 Subject: [PATCH 065/190] Create test bench for core module --- core.t.v | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 core.t.v diff --git a/core.t.v b/core.t.v new file mode 100644 index 0000000..a636d6c --- /dev/null +++ b/core.t.v @@ -0,0 +1,23 @@ +/* +Test bench for the core module of the CPU. +*/ + +`include "core.v" + +module core_TEST(); + wire [31:0] Da; + wire is_zero; + + reg clk; + reg [31:0] rd; + reg [31:0] rt; + reg [31:0] rs; + reg [15:0] immediate; + reg [31:0] added_PC; + + core dut (clk, rd, rt, rs, immediate, added_PC, Da, is_zero); + + initial begin + // Test code here. + end +endmodule \ No newline at end of file From f83bd5a71f4d10ea8589c7223cecac05183bf689 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:38:17 -0500 Subject: [PATCH 066/190] Add alu files --- adder.v | 76 +++++++ adder_subtracter.t.v | 60 +++++ adder_subtracter.v | 256 ++++++++++++++++++++++ alu.t.v | 507 +++++++++++++++++++++++++++++++++++++++++++ alu.v | 57 +++++ and_32bit.t.v | 36 +++ and_32bit.v | 40 ++++ nand_32bit.t.v | 36 +++ nand_32bit.v | 40 ++++ nor_32bit.t.v | 36 +++ nor_32bit.v | 40 ++++ or_32bit.t.v | 30 +++ or_32bit.v | 40 ++++ slt.t.v | 40 ++++ slt.v | 110 ++++++++++ xor_32bit.t.v | 36 +++ xor_32bit.v | 40 ++++ 17 files changed, 1480 insertions(+) create mode 100644 adder.v create mode 100644 adder_subtracter.t.v create mode 100644 adder_subtracter.v create mode 100644 alu.t.v create mode 100644 alu.v create mode 100644 and_32bit.t.v create mode 100644 and_32bit.v create mode 100644 nand_32bit.t.v create mode 100644 nand_32bit.v create mode 100644 nor_32bit.t.v create mode 100644 nor_32bit.v create mode 100644 or_32bit.t.v create mode 100644 or_32bit.v create mode 100644 slt.t.v create mode 100644 slt.v create mode 100644 xor_32bit.t.v create mode 100644 xor_32bit.v diff --git a/adder.v b/adder.v new file mode 100644 index 0000000..cc610e8 --- /dev/null +++ b/adder.v @@ -0,0 +1,76 @@ +// Adder circuit + +module behavioralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + // Uses concatenation operator and built-in '+' + assign {carryout, sum}=a+b+carryin; +endmodule + +module structuralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + wire ab; //setting up wires + wire acarryin; + wire bcarryin; + wire orpairintermediate; + wire orsingleintermediate; + wire orall; + wire andsumintermediate; + wire andsingleintermediate; + wire andall; + wire invcarryout; + and #(50) andab(ab, a, b); // a and b + and #(50) andacarryin(acarryin, a, carryin); // a and carryin + and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin + or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) + or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) + or #(50) orintermediate(orsingleintermediate, a, b); // a or b + or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin + not #(50) inv(invcarryout, carryout); // not carryout + and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout + and #(50) andintermediate(andsingleintermediate, a, b); // a and b + and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin + or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) +endmodule + +module FullAdder4bit +( + output[3:0] sum, // 2's complement sum of a and b + output carryout, // Carry out of the summation of a and b + output overflow, // True if the calculation resulted in an overflow + input[3:0] a, // First operand in 2's complement format + input[3:0] b, // Second operand in 2's complement format + input carryin +); + wire carryout1; // wire setup for carryouts from each adder + wire carryout2; + wire carryout3; + wire aandb; + wire anorb; + wire bandsum; + wire bnorsum; + wire abandnoror; + wire bsumandnornor; + structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits + structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits + structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits + structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits + and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) + nor #50 norinputs(anorb, a[3], b[3]); + and #50 andsum(bandsum, b[3], sum[3]); + nor #50 norsum(bnorsum, b[3], sum[3]); + or #50 orinputcombs(abandnoror, aandb, anorb); + nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); + and #50 finaland(overflow, abandnoror, bsumandnornor); +endmodule \ No newline at end of file diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v new file mode 100644 index 0000000..e2c0aa1 --- /dev/null +++ b/adder_subtracter.t.v @@ -0,0 +1,60 @@ +// Adder_subtacter testbench + +`timescale 1 ns / 1 ps +`include "adder_subtracter.v" + +module test32bitAdder(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] carryin; + wire[31:0] ans; + wire carryout, overflow; + + adder_subtracter adder0(ans[31:0], carryout, overflow, a[31:0], b[31:0], carryin[2:0]); + + initial begin + $display("Input A Input B Command | Output Flag Carryout"); + + // Addition tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b100; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + // Subtraction Tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000001000000000000000000000; + b=32'b00000000000000000000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000001000010000000000000000; + b=32'b10000000000000010000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000000000000000000000000000; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + end +endmodule \ No newline at end of file diff --git a/adder_subtracter.v b/adder_subtracter.v new file mode 100644 index 0000000..f59fd57 --- /dev/null +++ b/adder_subtracter.v @@ -0,0 +1,256 @@ +`include "adder.v" + +// 32 bit mux +module mux + ( + output[31:0] out, + input address, + input[31:0] in0, + input[31:0] in1 + ); + wire invaddr; + wire in00addr; // input 0 bit 0 andded with address + wire in01addr; + wire in02addr; + wire in03addr; + wire in04addr; + wire in05addr; + wire in06addr; + wire in07addr; + wire in08addr; + wire in09addr; + wire in010addr; + wire in011addr; + wire in012addr; + wire in013addr; + wire in014addr; + wire in015addr; + wire in016addr; + wire in017addr; + wire in018addr; + wire in019addr; + wire in020addr; + wire in021addr; + wire in022addr; + wire in023addr; + wire in024addr; + wire in025addr; + wire in026addr; + wire in027addr; + wire in028addr; + wire in029addr; + wire in030addr; + wire in031addr; + wire in10addr; + wire in11addr; + wire in12addr; + wire in13addr; + wire in14addr; + wire in15addr; + wire in16addr; + wire in17addr; + wire in18addr; + wire in19addr; + wire in110addr; + wire in111addr; + wire in112addr; + wire in113addr; + wire in114addr; + wire in115addr; + wire in116addr; + wire in117addr; + wire in118addr; + wire in119addr; + wire in120addr; + wire in121addr; + wire in122addr; + wire in123addr; + wire in124addr; + wire in125addr; + wire in126addr; + wire in127addr; + wire in128addr; + wire in129addr; + wire in130addr; + wire in131addr; + + // inverting address + not #10 inv(invaddr, address); + // and all bits in input 0 with inverted address + and #20 and00(in00addr, in0[0], invaddr); + and #20 and01(in01addr, in0[1], invaddr); + and #20 and02(in02addr, in0[2], invaddr); + and #20 and03(in03addr, in0[3], invaddr); + and #20 and04(in04addr, in0[4], invaddr); + and #20 and05(in05addr, in0[5], invaddr); + and #20 and06(in06addr, in0[6], invaddr); + and #20 and07(in07addr, in0[7], invaddr); + and #20 and08(in08addr, in0[8], invaddr); + and #20 and09(in09addr, in0[9], invaddr); + and #20 and010(in010addr, in0[10], invaddr); + and #20 and011(in011addr, in0[11], invaddr); + and #20 and012(in012addr, in0[12], invaddr); + and #20 and013(in013addr, in0[13], invaddr); + and #20 and014(in014addr, in0[14], invaddr); + and #20 and015(in015addr, in0[15], invaddr); + and #20 and016(in016addr, in0[16], invaddr); + and #20 and017(in017addr, in0[17], invaddr); + and #20 and018(in018addr, in0[18], invaddr); + and #20 and019(in019addr, in0[19], invaddr); + and #20 and020(in020addr, in0[20], invaddr); + and #20 and021(in021addr, in0[21], invaddr); + and #20 and022(in022addr, in0[22], invaddr); + and #20 and023(in023addr, in0[23], invaddr); + and #20 and024(in024addr, in0[24], invaddr); + and #20 and025(in025addr, in0[25], invaddr); + and #20 and026(in026addr, in0[26], invaddr); + and #20 and027(in027addr, in0[27], invaddr); + and #20 and028(in028addr, in0[28], invaddr); + and #20 and029(in029addr, in0[29], invaddr); + and #20 and030(in030addr, in0[30], invaddr); + and #20 and031(in031addr, in0[31], invaddr); + // and all bits in input 1 with address + and #20 and10(in10addr, in1[0], address); + and #20 and11(in11addr, in1[1], address); + and #20 and12(in12addr, in1[2], address); + and #20 and13(in13addr, in1[3], address); + and #20 and14(in14addr, in1[4], address); + and #20 and15(in15addr, in1[5], address); + and #20 and16(in16addr, in1[6], address); + and #20 and17(in17addr, in1[7], address); + and #20 and18(in18addr, in1[8], address); + and #20 and19(in19addr, in1[9], address); + and #20 and110(in110addr, in1[10], address); + and #20 and111(in111addr, in1[11], address); + and #20 and112(in112addr, in1[12], address); + and #20 and113(in113addr, in1[13], address); + and #20 and114(in114addr, in1[14], address); + and #20 and115(in115addr, in1[15], address); + and #20 and116(in116addr, in1[16], address); + and #20 and117(in117addr, in1[17], address); + and #20 and118(in118addr, in1[18], address); + and #20 and119(in119addr, in1[19], address); + and #20 and120(in120addr, in1[20], address); + and #20 and121(in121addr, in1[21], address); + and #20 and122(in122addr, in1[22], address); + and #20 and123(in123addr, in1[23], address); + and #20 and124(in124addr, in1[24], address); + and #20 and125(in125addr, in1[25], address); + and #20 and126(in126addr, in1[26], address); + and #20 and127(in127addr, in1[27], address); + and #20 and128(in128addr, in1[28], address); + and #20 and129(in129addr, in1[29], address); + and #20 and130(in130addr, in1[30], address); + and #20 and131(in131addr, in1[31], address); + + // or the and gates + or #20 or0(out[0], in00addr, in10addr); + or #20 or1(out[1], in01addr, in11addr); + or #20 or2(out[2], in02addr, in12addr); + or #20 or3(out[3], in03addr, in13addr); + or #20 or4(out[4], in04addr, in14addr); + or #20 or5(out[5], in05addr, in15addr); + or #20 or6(out[6], in06addr, in16addr); + or #20 or7(out[7], in07addr, in17addr); + or #20 or8(out[8], in08addr, in18addr); + or #20 or9(out[9], in09addr, in19addr); + or #20 or10(out[10], in010addr, in110addr); + or #20 or11(out[11], in011addr, in111addr); + or #20 or12(out[12], in012addr, in112addr); + or #20 or13(out[13], in013addr, in113addr); + or #20 or14(out[14], in014addr, in114addr); + or #20 or15(out[15], in015addr, in115addr); + or #20 or16(out[16], in016addr, in116addr); + or #20 or17(out[17], in017addr, in117addr); + or #20 or18(out[18], in018addr, in118addr); + or #20 or19(out[19], in019addr, in119addr); + or #20 or20(out[20], in020addr, in120addr); + or #20 or21(out[21], in021addr, in121addr); + or #20 or22(out[22], in022addr, in122addr); + or #20 or23(out[23], in023addr, in123addr); + or #20 or24(out[24], in024addr, in124addr); + or #20 or25(out[25], in025addr, in125addr); + or #20 or26(out[26], in026addr, in126addr); + or #20 or27(out[27], in027addr, in127addr); + or #20 or28(out[28], in028addr, in128addr); + or #20 or29(out[29], in029addr, in129addr); + or #20 or30(out[30], in030addr, in130addr); + or #20 or31(out[31], in031addr, in131addr); +endmodule + +// 32 bit adder/subtracter that determines what operation to conduct based on the input command +module adder_subtracter + ( + output[31:0] ans, + output carryout, + output overflow, + input[31:0] opA, + input[31:0] opB, + input[2:0] command + ); + wire[31:0] invertedB; //wire to invert b in the event of a subtraction + wire[31:0] finalB; + wire normalB; //added b + wire cout0; + wire cout1; + wire cout2; + wire cout3; + wire cout4; + wire cout5; + wire cout6; + wire _; + wire _1; + wire _2; + wire _3; + wire _4; + wire _5; + wire _6; + + // invert B in the case of two's complement + not #10 invertB0(invertedB[0], opB[0]); + not #10 invertB1(invertedB[1], opB[1]); + not #10 invertB2(invertedB[2], opB[2]); + not #10 invertB3(invertedB[3], opB[3]); + not #10 invertB4(invertedB[4], opB[4]); + not #10 invertB5(invertedB[5], opB[5]); + not #10 invertB6(invertedB[6], opB[6]); + not #10 invertB7(invertedB[7], opB[7]); + not #10 invertB8(invertedB[8], opB[8]); + not #10 invertB9(invertedB[9], opB[9]); + not #10 invertB10(invertedB[10], opB[10]); + not #10 invertB11(invertedB[11], opB[11]); + not #10 invertB12(invertedB[12], opB[12]); + not #10 invertB13(invertedB[13], opB[13]); + not #10 invertB14(invertedB[14], opB[14]); + not #10 invertB15(invertedB[15], opB[15]); + not #10 invertB16(invertedB[16], opB[16]); + not #10 invertB17(invertedB[17], opB[17]); + not #10 invertB18(invertedB[18], opB[18]); + not #10 invertB19(invertedB[19], opB[19]); + not #10 invertB20(invertedB[20], opB[20]); + not #10 invertB21(invertedB[21], opB[21]); + not #10 invertB22(invertedB[22], opB[22]); + not #10 invertB23(invertedB[23], opB[23]); + not #10 invertB24(invertedB[24], opB[24]); + not #10 invertB25(invertedB[25], opB[25]); + not #10 invertB26(invertedB[26], opB[26]); + not #10 invertB27(invertedB[27], opB[27]); + not #10 invertB28(invertedB[28], opB[28]); + not #10 invertB29(invertedB[29], opB[29]); + not #10 invertB30(invertedB[30], opB[30]); + not #10 invertB31(invertedB[31], opB[31]); + + // mux chooses between inverted B or normal B based on addition or subtraction + mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); + + // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one + FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding + FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); + FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); + FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); + FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); + FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); + FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); + FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + +endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v new file mode 100644 index 0000000..0d35733 --- /dev/null +++ b/alu.t.v @@ -0,0 +1,507 @@ +`timescale 1 ns / 1 ps +`include "alu.v" + +module testALU32bit(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] ALUcommand; + wire[31:0] finalALUsig; + wire flag; + wire cout; + + ALUcontrolLUT alu(cout, flag, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + + initial begin + $display("ALU Command Input A Input B | Output Flag Carryout"); + //Test cases add + ALUcommand = 3'b000; + + // 0 + 0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // 1 + 1 + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // positive overflow + a = 32'b01111111111111111111111111111111; + b = 32'b01111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // negative overflow + a = 32'b10000000000000000000000000000001; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // carryout + a = 32'b11111111111111111111111111111111; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + + //Test cases sub + ALUcommand = 3'b001; + + // a=b=0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a=b + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a>b, both positive + a = 32'b00000000000000000000000000000111; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a|b|, both negative + a = 32'b11111111111111111111111111111101; + b = 32'b11111111111111111111111111111110; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // |a|<|b|, both negative + a = 32'b111111111111111111111111111111110; + b = 32'b111111111111111111111111111111000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, no overflow + a = 32'b11111111111111111111111111111101; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, overflow + a = 32'b10000000000000000000000000000101; + b = 32'b01111100000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, no overflow + a = 32'b00000000000000000000000000000101; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + //Here + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, overflow + a = 32'b01111111111111111111101111111111; + b = 32'b10000000000000001100000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //Test cases xor + ALUcommand = 3'b010; + + //a is all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //b is all 0's + b = 32'b00000000000000000000000000000000; + a = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 1's + a = 32'b11111111111111111111111111111111; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + + //Test cases slt + ALUcommand = 3'b011; + + //a>b, all positive + a = 32'b00000000000000000000000000000010; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //ab, all negative + a = 32'b10000000000000000000000000000010; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a>b, a positive, b negative + a = 32'b00000000000000000000000000000001; + b = 32'b10000000000000000000000000000010; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a Date: Tue, 7 Nov 2017 22:39:16 -0500 Subject: [PATCH 067/190] Add inputs and outputs to module definition --- core.v | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/core.v b/core.v index e8c7d6f..60d93bf 100644 --- a/core.v +++ b/core.v @@ -3,7 +3,14 @@ The section of the CPU containing the register file, data memory, and ALU. */ module core ( - + input clk, + input [31:0] rd, + input [31:0] rt, + input [31:0] rs, + input [15:0] immediate, + input [31:0] added_PC, + output [31:0] Da, + output is_zero ); // code here From ed5486cb5f2eec3d18fcbdd474f117c9283e4e12 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:40:47 -0500 Subject: [PATCH 068/190] Build core testbenches --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 7adc08f..26d4f83 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ all: core -core: core.v - iverilog -Wall -o core core.v \ No newline at end of file +core: core.v core.t.v + iverilog -Wall -o core core.t.v \ No newline at end of file From 1c69c4e09b901b867eec71d1104c2621d9c57f34 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 22:56:05 -0500 Subject: [PATCH 069/190] Add register file related modules --- decoders.t.v | 41 +++++++++++ decoders.v | 20 ++++++ multiplexer.t.v | 108 +++++++++++++++++++++++++++++ multiplexer.v | 56 +++++++++++++++ regfile.t.v | 176 ++++++++++++++++++++++++++++++++++++++++++++++++ regfile.v | 114 +++++++++++++++++++++++++++++++ register.t.v | 121 +++++++++++++++++++++++++++++++++ register.v | 48 +++++++++++++ 8 files changed, 684 insertions(+) create mode 100644 decoders.t.v create mode 100644 decoders.v create mode 100644 multiplexer.t.v create mode 100644 multiplexer.v create mode 100644 regfile.t.v create mode 100644 regfile.v create mode 100644 register.t.v create mode 100644 register.v diff --git a/decoders.t.v b/decoders.t.v new file mode 100644 index 0000000..616b67b --- /dev/null +++ b/decoders.t.v @@ -0,0 +1,41 @@ +//------------------------------- +// Unit test the decoder module +//------------------------------- + +`include "decoders.v" + +module decoder1to32Test(); + wire[31:0] out; + reg enable; + reg[4:0] address; + + reg dutpassed; // Flag is set to false if any of the tests fail. + + decoder1to32 DUT (out, enable, address); + + initial begin + dutpassed = 1; + + // Test Case 1: do not enable writing to any register. + enable = 0; address = 5'd14; + if (out != 0) begin + $display("Decoder Test Case 1 failed"); + dutpassed = 0; + end // + + // Test Case 2: + // Enable writing to one register only. + #5 + enable = 1; address = 5'd14; + if (out[31:15] != 0 || out[14] != 1 || out[13:0] != 0) begin + $display("Decoder Test Case 2 failed"); + dutpassed = 0; + end + + #5 + + if (dutpassed ==1) begin + $display("All decoder tests passed."); + end + end // +endmodule // decoder1to32Test \ No newline at end of file diff --git a/decoders.v b/decoders.v new file mode 100644 index 0000000..bfb1ff9 --- /dev/null +++ b/decoders.v @@ -0,0 +1,20 @@ +// 32 bit decoder with enable signal +// enable=0: all output bits are 0 +// enable=1: out[address] is 1, all other outputs are 0 +module decoder1to32 +( +output[31:0] out, +input enable, +input[4:0] address +); + + assign out = enable< Date: Tue, 7 Nov 2017 22:56:28 -0500 Subject: [PATCH 070/190] Add build rules for regfile modules --- makefile | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 26d4f83..f8f191d 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,28 @@ -all: core +all: core alu core: core.v core.t.v - iverilog -Wall -o core core.t.v \ No newline at end of file + iverilog -Wall -o core core.t.v + +alu: alu.v alu.t.v + iverilog -Wall -o alu alu.t.v + +adder_subtracter: adder_subtracter.v adder_subtracter.t.v + iverilog -Wall -o adder_subtracter adder_subtracter.t.v + +and: and_32bit.v and_32bit.t.v + iverilog -Wall -o and and_32bit.t.v + +nand: nand_32bit.v nand_32bit.t.v + iverilog -Wall -o nand nand_32bit + +nor: nor_32bit.v nor_32bit.t.v + iverilog -Wall -o nor nor_32bit + +or: or_32bit.v or_32bit.t.v + iverilog -Wall -o or or_32bit + +slt: slt.v slt.t.v + iverilog -Wall -o slt slt.t.v + +xor: xor_32bit.v xor_32bit.t.v + iverilog -Wall -o xor xor_32bit \ No newline at end of file From 6bdb2e3d3435a090e3bfaed2d21222500375d62b Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 23:06:47 -0500 Subject: [PATCH 071/190] Add memory files --- memory.t.v | 18 ++++++++++++++++++ memory.v | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 memory.t.v create mode 100644 memory.v diff --git a/memory.t.v b/memory.t.v new file mode 100644 index 0000000..8d65fe3 --- /dev/null +++ b/memory.t.v @@ -0,0 +1,18 @@ +/* +Test bench for data memory module. +*/ + +module memory_TEST(); + reg clk; + reg [31:0] address; + reg writeEnable; + reg [31:0] dataIn; + + wire dataOut; + + memory dut(clk, dataOut, address, writeEnable, dataIn); + + initial begin + // Test code here + end +endmodule \ No newline at end of file diff --git a/memory.v b/memory.v new file mode 100644 index 0000000..826e6c4 --- /dev/null +++ b/memory.v @@ -0,0 +1,28 @@ +/* +The memory used in the CPU +*/ + +module memory +#( + parameter addresswidth = 32, + parameter depth = 2**addresswidth, + parameter width = 32 +) +( + input clk, + output reg [width-1:0] dataOut, + input [addresswidth-1:0] address, + input writeEnable, + input [width-1:0] dataIn +); + + + reg [width-1:0] memory [depth-1:0]; + + always @(posedge clk) begin + if(writeEnable) + memory[address] <= dataIn; + dataOut <= memory[address]; + end + +endmodule \ No newline at end of file From c5a29b6e8925cd6ca37a5d24cfbb064b79f58cf3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 7 Nov 2017 23:30:08 -0500 Subject: [PATCH 072/190] Add build rules for memory --- makefile | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index f8f191d..c1bb2e6 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,11 @@ -all: core alu +all: core alu regfile memory +# Core modules core: core.v core.t.v iverilog -Wall -o core core.t.v -alu: alu.v alu.t.v +# ALU modules +alu: alu.v alu.t.v adder_subtracter and nand nor or slt xor iverilog -Wall -o alu alu.t.v adder_subtracter: adder_subtracter.v adder_subtracter.t.v @@ -13,16 +15,33 @@ and: and_32bit.v and_32bit.t.v iverilog -Wall -o and and_32bit.t.v nand: nand_32bit.v nand_32bit.t.v - iverilog -Wall -o nand nand_32bit + iverilog -Wall -o nand nand_32bit.t.v nor: nor_32bit.v nor_32bit.t.v - iverilog -Wall -o nor nor_32bit + iverilog -Wall -o nor nor_32bit.t.v or: or_32bit.v or_32bit.t.v - iverilog -Wall -o or or_32bit + iverilog -Wall -o or or_32bit.t.v slt: slt.v slt.t.v iverilog -Wall -o slt slt.t.v xor: xor_32bit.v xor_32bit.t.v - iverilog -Wall -o xor xor_32bit \ No newline at end of file + iverilog -Wall -o xor xor_32bit.t.v + +# Regfile modules +regfile: regfile.t.v regfile.v decoder mux register + iverilog -Wall -o regfile regfile.t.v + +decoder: decoders.t.v decoders.v + iverilog -Wall -o decoder decoders.t.v + +mux: multiplexer.t.v multiplexer.v + iverilog -Wall -o mux multiplexer.t.v + +register: register.t.v register.v + iverilog -Wall -o register register.t.v + +# Memory modules +memory: memory.v memory.t.v + iverilog -Wall -o memory memory.t.v From dff2583cf8da474386c2f8db5ff631ddb474ccce Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:24:49 -0500 Subject: [PATCH 073/190] Add module for 4 input mux --- memory.v | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/memory.v b/memory.v index 826e6c4..54df8e3 100644 --- a/memory.v +++ b/memory.v @@ -4,7 +4,8 @@ The memory used in the CPU module memory #( - parameter addresswidth = 32, + // parameter addresswidth = 32, + parameter addresswidth = 8, parameter depth = 2**addresswidth, parameter width = 32 ) From 8f3e391b537879c23218664c7129f074c35bb47d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:25:08 -0500 Subject: [PATCH 074/190] Add tests for 4 input module --- memory.t.v | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/memory.t.v b/memory.t.v index 8d65fe3..c2bee8d 100644 --- a/memory.t.v +++ b/memory.t.v @@ -2,13 +2,15 @@ Test bench for data memory module. */ +`include "memory.v" + module memory_TEST(); reg clk; reg [31:0] address; reg writeEnable; reg [31:0] dataIn; - wire dataOut; + wire [31:0] dataOut; memory dut(clk, dataOut, address, writeEnable, dataIn); From fa6048ccbf9adc6f09c2ae1e2031a4d99f2a1612 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:27:30 -0500 Subject: [PATCH 075/190] Add new module for four input multiplexer --- multiplexer.t.v | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ multiplexer.v | 15 +++++++++++++ 2 files changed, 72 insertions(+) diff --git a/multiplexer.t.v b/multiplexer.t.v index 99dced4..acf6c0b 100644 --- a/multiplexer.t.v +++ b/multiplexer.t.v @@ -64,6 +64,63 @@ module mux32to1by1Test end endmodule // mux32to1by1Test +module mux3to1by6Test + ( + input begintest, + output reg endtest, + output reg dutpassed + ); + + reg[5:0] input0, input1, input2, input3; + reg[1:0] address; + wire[5:0] out; + + mux4to1by6 DUT (input0, input1, input2, input3, address, out); + + always @(posedge begintest) begin + endtest = 0; + dutpassed = 1; + + // Test Case 1: + // Ensure that the value chosen by the mux matches + // the value at the given address. + input0 = 6'd1; + input1 = 6'd2; + input2 = 6'd3; + input3 = 6'd4; + address = 2'd0; + #5 + if (out != input0) begin + $display("3 wide 6 deep mux test case 1 failed at address 00."); + dutpassed = 0; + end + + address = 2'd1; + #5 + if (out != input1) begin + $display("3 wide 6 deep mux test case 1 failed at address 01."); + dutpassed = 0; + end + + address = 2'd2; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 10."); + dutpassed = 0; + end + + address = 2'd3; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 11."); + dutpassed = 0; + end + + #5 + endtest = 1; + end +endmodule + // Unit test the 32 wide 32 deep mux module. module mux32to32by1Test( input begintest, diff --git a/multiplexer.v b/multiplexer.v index dd4798a..b7d9b1d 100644 --- a/multiplexer.v +++ b/multiplexer.v @@ -1,3 +1,18 @@ +// Inputs are 6 by 1 addresses +module mux4to1by6 +( +input[5:0] input0, input1, input2, input3, +input[1:0] address, +output[5:0] out +); + wire[1:0] mux [5:0]; + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign out = mux[address]; +endmodule + // A 32:1 multiplexer. module mux32to1by1 ( From e7ae5867ea4b9186f2267d7773484ef63d6d89a6 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 16:37:51 -0500 Subject: [PATCH 076/190] Parametize 4 input mux for code reuse --- multiplexer.t.v | 4 ++-- multiplexer.v | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/multiplexer.t.v b/multiplexer.t.v index acf6c0b..1db882d 100644 --- a/multiplexer.t.v +++ b/multiplexer.t.v @@ -64,7 +64,7 @@ module mux32to1by1Test end endmodule // mux32to1by1Test -module mux3to1by6Test +module mux4inputTest ( input begintest, output reg endtest, @@ -75,7 +75,7 @@ module mux3to1by6Test reg[1:0] address; wire[5:0] out; - mux4to1by6 DUT (input0, input1, input2, input3, address, out); + mux4input #(.width(6)) DUT (input0, input1, input2, input3, address, out); always @(posedge begintest) begin endtest = 0; diff --git a/multiplexer.v b/multiplexer.v index b7d9b1d..f38b85f 100644 --- a/multiplexer.v +++ b/multiplexer.v @@ -1,11 +1,14 @@ // Inputs are 6 by 1 addresses -module mux4to1by6 +module mux4input +#( + parameter width = 6 +) ( -input[5:0] input0, input1, input2, input3, +input[width-1:0] input0, input1, input2, input3, input[1:0] address, -output[5:0] out +output[width-1:0] out ); - wire[1:0] mux [5:0]; + wire[1:0] mux [width-1:0]; assign mux[0] = input0; assign mux[1] = input1; assign mux[2] = input2; From 02f09834058409084d548c313fe196ea13ecbdc2 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:28:50 -0500 Subject: [PATCH 077/190] Add zero flag --- adder_subtracter.t.v | 4 ++-- adder_subtracter.v | 10 ++++++++++ alu.t.v | 2 +- alu.v | 18 ++++++++++-------- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v index e2c0aa1..2e6f726 100644 --- a/adder_subtracter.t.v +++ b/adder_subtracter.t.v @@ -8,9 +8,9 @@ module test32bitAdder(); reg[31:0] b; reg[2:0] carryin; wire[31:0] ans; - wire carryout, overflow; + wire carryout, overflow, zero; - adder_subtracter adder0(ans[31:0], carryout, overflow, a[31:0], b[31:0], carryin[2:0]); + adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); initial begin $display("Input A Input B Command | Output Flag Carryout"); diff --git a/adder_subtracter.v b/adder_subtracter.v index f59fd57..fea62ec 100644 --- a/adder_subtracter.v +++ b/adder_subtracter.v @@ -184,6 +184,7 @@ module adder_subtracter output[31:0] ans, output carryout, output overflow, + output reg zero, input[31:0] opA, input[31:0] opB, input[2:0] command @@ -253,4 +254,13 @@ module adder_subtracter FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + always @(*) begin + if (ans === 32'b0) begin + zero <= 1; + end + + else begin + zero <= 0; + end + end endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v index 0d35733..322cd32 100644 --- a/alu.t.v +++ b/alu.t.v @@ -9,7 +9,7 @@ module testALU32bit(); wire flag; wire cout; - ALUcontrolLUT alu(cout, flag, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); initial begin $display("ALU Command Input A Input B | Output Flag Carryout"); diff --git a/alu.v b/alu.v index 8ee1ec0..47c9191 100644 --- a/alu.v +++ b/alu.v @@ -12,6 +12,7 @@ module ALUcontrolLUT ( output reg cout, //addsub only output reg flag, //addsub only + output reg zero, // addsub only output reg[31:0] finalsignal, input [2:0]ALUcommand, input [31:0]a, @@ -29,8 +30,9 @@ wire [31:0]norin; wire [31:0]orin; wire adder_cout; wire adder_flag; +wire adder_zero; -adder_subtracter addsub0(addsub[31:0],adder_cout,adder_flag,a[31:0],b[31:0],ALUcommand[2:0]); +adder_subtracter addsub0(addsub[31:0],adder_cout,adder_flag, adder_zero, a[31:0],b[31:0],ALUcommand[2:0]); xor_32bit xor0(xorin[31:0],a[31:0],b[31:0]); full_slt_32bit slt0(slt[31:0],a[31:0],b[31:0]); and_32bit and0(andin[31:0],a[31:0],b[31:0]); @@ -44,14 +46,14 @@ or_32bit or0(orin[31:0],a[31:0],b[31:0]); begin #5000 case (ALUcommand) - 3'b000: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; end - 3'b001: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; end + 3'b000: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; zero = adder_zero; end + 3'b001: begin finalsignal[31:0] = addsub[31:0]; cout = adder_cout; flag = adder_flag; zero = adder_zero; end 3'b010: begin finalsignal[31:0] = xorin[31:0]; cout = 0; flag = 0; end // carryout and flag should be 0 for all non-add/sub operations - 3'b011: begin finalsignal[31:0] = slt[31:0]; cout = 0; flag = 0; end - 3'b100: begin finalsignal[31:0] = andin[31:0]; cout = 0; flag = 0; end - 3'b101: begin finalsignal[31:0] = nandin[31:0]; cout = 0; flag = 0; end - 3'b110: begin finalsignal[31:0] = norin[31:0]; cout = 0; flag = 0; end - 3'b111: begin finalsignal[31:0] = orin[31:0]; cout = 0; flag = 0; end + 3'b011: begin finalsignal[31:0] = slt[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b100: begin finalsignal[31:0] = andin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b101: begin finalsignal[31:0] = nandin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b110: begin finalsignal[31:0] = norin[31:0]; cout = 0; flag = 0; zero = 0; end + 3'b111: begin finalsignal[31:0] = orin[31:0]; cout = 0; flag = 0; zero = 0; end endcase end endmodule From e7cd21f90e80eecb94f6346a271f3c4dcb256d6d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:29:14 -0500 Subject: [PATCH 078/190] Add new modules --- core.t.v | 16 +++++++++++----- core.v | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/core.t.v b/core.t.v index a636d6c..b33d5f1 100644 --- a/core.t.v +++ b/core.t.v @@ -9,13 +9,19 @@ module core_TEST(); wire is_zero; reg clk; - reg [31:0] rd; - reg [31:0] rt; - reg [31:0] rs; + reg [5:0] rd; + reg [5:0] rt; + reg [5:0] rs; reg [15:0] immediate; - reg [31:0] added_PC; + reg [31:0] new_PC; + reg [0:1] regdst; + reg [2:0] ALUcntrl; + reg AlUsrc; + reg MemWr; + reg RegWr; + reg [1:0] MemtoReg; - core dut (clk, rd, rt, rs, immediate, added_PC, Da, is_zero); + core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); initial begin // Test code here. diff --git a/core.v b/core.v index 60d93bf..b688d23 100644 --- a/core.v +++ b/core.v @@ -2,17 +2,62 @@ The section of the CPU containing the register file, data memory, and ALU. */ -module core ( +`include "alu.v" +`include "memory.v" +`include "regfile.v" +`include "signextend.v" + +module core +( input clk, - input [31:0] rd, - input [31:0] rt, - input [31:0] rs, + input [5:0] rd, + input [5:0] rt, + input [5:0] rs, input [15:0] immediate, - input [31:0] added_PC, + input [31:0] new_PC, + input [0:1] regdst, + input [2:0] ALUcntrl, + input AlUsrc, + input MemWr, + input RegWr, + input [1:0] MemtoReg, output [31:0] Da, output is_zero ); -// code here + wire[5:0] writeaddr; + + // Register file write address + mux4input #(.width(6)) regwriteaddr (rd, rt, 6'd31, 6'bx, regdst, writeaddr); + + wire[31:0] dataaout; + wire[31:0] databout; + wire[31:0] datain; + + // Register file + regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); + + // Sign extend + + wire[31:0] signextimm; + signextend extend (immediate, signextimm); + + // ALU operand 2 mux + wire[31:0] operandb; + + mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); + + // ALU + wire cout; + wire overflow; + wire[31:0] finalsignal; + + ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); + + // Regfile write data mux + reg[31:0] memout; + + mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); + endmodule \ No newline at end of file From fdae91f2eea689b7bf94805a7af6b91eb7439569 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:30:02 -0500 Subject: [PATCH 079/190] Change address size --- decoders.v | 2 +- multiplexer.t.v | 2 +- multiplexer.v | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/decoders.v b/decoders.v index bfb1ff9..e0f9253 100644 --- a/decoders.v +++ b/decoders.v @@ -5,7 +5,7 @@ module decoder1to32 ( output[31:0] out, input enable, -input[4:0] address +input[5:0] address ); assign out = enable< Date: Wed, 8 Nov 2017 19:30:25 -0500 Subject: [PATCH 080/190] Add signextend module --- makefile | 6 +++++- signextend.v | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 signextend.v diff --git a/makefile b/makefile index c1bb2e6..6f92f94 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -all: core alu regfile memory +all: core alu regfile memory signextend # Core modules core: core.v core.t.v @@ -45,3 +45,7 @@ register: register.t.v register.v # Memory modules memory: memory.v memory.t.v iverilog -Wall -o memory memory.t.v + +# Concatenation modules +signextend: signextend.v + iverilog -Wall -o signextend signextend.v diff --git a/signextend.v b/signextend.v new file mode 100644 index 0000000..35effe1 --- /dev/null +++ b/signextend.v @@ -0,0 +1,12 @@ +/* +Implement the sign extend immediate operation defined by the MIPS reference guide. +*/ + +module signextend +( +input[15:0] immediate, +output[31:0] signextendimmediate +); + + assign signextendimmediate = {{16{immediate[15]}}, {immediate[15:0]}}; +endmodule \ No newline at end of file From 18a87f21c5530c9db37313a376decca97a9e5acf Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:30:50 -0500 Subject: [PATCH 081/190] Change mem and addr size --- memory.v | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/memory.v b/memory.v index 54df8e3..e344080 100644 --- a/memory.v +++ b/memory.v @@ -4,9 +4,8 @@ The memory used in the CPU module memory #( - // parameter addresswidth = 32, - parameter addresswidth = 8, - parameter depth = 2**addresswidth, + parameter addresswidth = 32, + parameter depth = addresswidth, parameter width = 32 ) ( From bebf55b6712e3c8cbd3ce80f742d8df0a347e6a9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 19:31:33 -0500 Subject: [PATCH 082/190] Change address size --- regfile.t.v | 12 ++++++------ regfile.v | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/regfile.t.v b/regfile.t.v index 059c0ec..02b4a13 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -10,9 +10,9 @@ module hw4testbenchharness(); wire[31:0] ReadData1; // Data from first register read wire[31:0] ReadData2; // Data from second register read wire[31:0] WriteData; // Data to write to register - wire[4:0] ReadRegister1; // Address of first register to read - wire[4:0] ReadRegister2; // Address of second register to read - wire[4:0] WriteRegister; // Address of register to write + wire[5:0] ReadRegister1; // Address of first register to read + wire[5:0] ReadRegister2; // Address of second register to read + wire[5:0] WriteRegister; // Address of register to write wire RegWrite; // Enable writing of register when High wire Clk; // Clock (Positive Edge Triggered) @@ -86,9 +86,9 @@ output reg dutpassed, // Signal test result input[31:0] ReadData1, input[31:0] ReadData2, output reg[31:0] WriteData, -output reg[4:0] ReadRegister1, -output reg[4:0] ReadRegister2, -output reg[4:0] WriteRegister, +output reg[5:0] ReadRegister1, +output reg[5:0] ReadRegister2, +output reg[5:0] WriteRegister, output reg RegWrite, output reg Clk ); diff --git a/regfile.v b/regfile.v index 893bf11..49c885c 100644 --- a/regfile.v +++ b/regfile.v @@ -15,9 +15,9 @@ module regfile output[31:0] ReadData1, // Contents of first register read output[31:0] ReadData2, // Contents of second register read input[31:0] WriteData, // Contents to write to register -input[4:0] ReadRegister1, // Address of first register to read -input[4:0] ReadRegister2, // Address of second register to read -input[4:0] WriteRegister, // Address of register to write +input[5:0] ReadRegister1, // Address of first register to read +input[5:0] ReadRegister2, // Address of second register to read +input[5:0] WriteRegister, // Address of register to write input RegWrite, // Enable writing of register when High input Clk // Clock (Positive Edge Triggered) ); From ccd5b91b1c4985e2db1b9df1d3ff69d077f90dd9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Wed, 8 Nov 2017 20:24:02 -0500 Subject: [PATCH 083/190] Change width of regfile addresses --- core.t.v | 19 +++++++++++++++---- core.v | 15 +++++++++------ decoders.v | 2 +- memory.v | 2 +- multiplexer.t.v | 4 ++-- multiplexer.v | 4 ++-- regfile.t.v | 12 ++++++------ regfile.v | 6 +++--- register.v | 2 +- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/core.t.v b/core.t.v index b33d5f1..d65d6d8 100644 --- a/core.t.v +++ b/core.t.v @@ -9,9 +9,9 @@ module core_TEST(); wire is_zero; reg clk; - reg [5:0] rd; - reg [5:0] rt; - reg [5:0] rs; + reg [4:0] rd; + reg [4:0] rt; + reg [4:0] rs; reg [15:0] immediate; reg [31:0] new_PC; reg [0:1] regdst; @@ -23,7 +23,18 @@ module core_TEST(); core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); + initial clk = 0; + always #10 clk = !clk; + initial begin - // Test code here. + $dumpfile("core.vcd"); + $dumpvars(0, core_TEST); + + // Test Case 1: Load Word + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; + rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; + + + $finish; end endmodule \ No newline at end of file diff --git a/core.v b/core.v index b688d23..2d0c29c 100644 --- a/core.v +++ b/core.v @@ -10,9 +10,9 @@ The section of the CPU containing the register file, data memory, and ALU. module core ( input clk, - input [5:0] rd, - input [5:0] rt, - input [5:0] rs, + input [4:0] rd, + input [4:0] rt, + input [4:0] rs, input [15:0] immediate, input [31:0] new_PC, input [0:1] regdst, @@ -25,10 +25,10 @@ module core output is_zero ); - wire[5:0] writeaddr; + wire[4:0] writeaddr; // Register file write address - mux4input #(.width(6)) regwriteaddr (rd, rt, 6'd31, 6'bx, regdst, writeaddr); + mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); wire[31:0] dataaout; wire[31:0] databout; @@ -55,9 +55,12 @@ module core ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); // Regfile write data mux - reg[31:0] memout; + wire[31:0] memout; mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); + // Data Meomory + memory datamemory (clk, memout, finalsignal, MemWr, databout); + endmodule \ No newline at end of file diff --git a/decoders.v b/decoders.v index e0f9253..bfb1ff9 100644 --- a/decoders.v +++ b/decoders.v @@ -5,7 +5,7 @@ module decoder1to32 ( output[31:0] out, input enable, -input[5:0] address +input[4:0] address ); assign out = enable< Date: Thu, 9 Nov 2017 18:50:14 -0500 Subject: [PATCH 084/190] Move core module files to subfolder --- Core/ALU/adder.v | 76 +++++ Core/ALU/adder_subtracter.t.v | 60 ++++ Core/ALU/adder_subtracter.v | 266 ++++++++++++++++++ Core/ALU/alu.t.v | 507 ++++++++++++++++++++++++++++++++++ Core/ALU/alu.v | 59 ++++ Core/ALU/and_32bit.t.v | 36 +++ Core/ALU/and_32bit.v | 40 +++ Core/ALU/nand_32bit.t.v | 36 +++ Core/ALU/nand_32bit.v | 40 +++ Core/ALU/nor_32bit.t.v | 36 +++ Core/ALU/nor_32bit.v | 40 +++ Core/ALU/or_32bit.t.v | 30 ++ Core/ALU/or_32bit.v | 40 +++ Core/ALU/slt.t.v | 40 +++ Core/ALU/slt.v | 110 ++++++++ Core/ALU/xor_32bit.t.v | 36 +++ Core/ALU/xor_32bit.v | 40 +++ Core/core.t.v | 40 +++ Core/core.v | 66 +++++ Core/decoders.t.v | 41 +++ Core/decoders.v | 20 ++ Core/memory.t.v | 20 ++ Core/memory.v | 28 ++ Core/multiplexer.t.v | 165 +++++++++++ Core/multiplexer.v | 74 +++++ Core/regfile.t.v | 176 ++++++++++++ Core/regfile.v | 114 ++++++++ Core/register.t.v | 121 ++++++++ Core/register.v | 48 ++++ Core/signextend.v | 12 + 30 files changed, 2417 insertions(+) create mode 100644 Core/ALU/adder.v create mode 100644 Core/ALU/adder_subtracter.t.v create mode 100644 Core/ALU/adder_subtracter.v create mode 100644 Core/ALU/alu.t.v create mode 100644 Core/ALU/alu.v create mode 100644 Core/ALU/and_32bit.t.v create mode 100644 Core/ALU/and_32bit.v create mode 100644 Core/ALU/nand_32bit.t.v create mode 100644 Core/ALU/nand_32bit.v create mode 100644 Core/ALU/nor_32bit.t.v create mode 100644 Core/ALU/nor_32bit.v create mode 100644 Core/ALU/or_32bit.t.v create mode 100644 Core/ALU/or_32bit.v create mode 100644 Core/ALU/slt.t.v create mode 100644 Core/ALU/slt.v create mode 100644 Core/ALU/xor_32bit.t.v create mode 100644 Core/ALU/xor_32bit.v create mode 100644 Core/core.t.v create mode 100644 Core/core.v create mode 100644 Core/decoders.t.v create mode 100644 Core/decoders.v create mode 100644 Core/memory.t.v create mode 100644 Core/memory.v create mode 100644 Core/multiplexer.t.v create mode 100644 Core/multiplexer.v create mode 100644 Core/regfile.t.v create mode 100644 Core/regfile.v create mode 100644 Core/register.t.v create mode 100644 Core/register.v create mode 100644 Core/signextend.v diff --git a/Core/ALU/adder.v b/Core/ALU/adder.v new file mode 100644 index 0000000..cc610e8 --- /dev/null +++ b/Core/ALU/adder.v @@ -0,0 +1,76 @@ +// Adder circuit + +module behavioralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + // Uses concatenation operator and built-in '+' + assign {carryout, sum}=a+b+carryin; +endmodule + +module structuralFullAdder +( + output sum, + output carryout, + input a, + input b, + input carryin +); + wire ab; //setting up wires + wire acarryin; + wire bcarryin; + wire orpairintermediate; + wire orsingleintermediate; + wire orall; + wire andsumintermediate; + wire andsingleintermediate; + wire andall; + wire invcarryout; + and #(50) andab(ab, a, b); // a and b + and #(50) andacarryin(acarryin, a, carryin); // a and carryin + and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin + or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) + or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) + or #(50) orintermediate(orsingleintermediate, a, b); // a or b + or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin + not #(50) inv(invcarryout, carryout); // not carryout + and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout + and #(50) andintermediate(andsingleintermediate, a, b); // a and b + and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin + or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) +endmodule + +module FullAdder4bit +( + output[3:0] sum, // 2's complement sum of a and b + output carryout, // Carry out of the summation of a and b + output overflow, // True if the calculation resulted in an overflow + input[3:0] a, // First operand in 2's complement format + input[3:0] b, // Second operand in 2's complement format + input carryin +); + wire carryout1; // wire setup for carryouts from each adder + wire carryout2; + wire carryout3; + wire aandb; + wire anorb; + wire bandsum; + wire bnorsum; + wire abandnoror; + wire bsumandnornor; + structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits + structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits + structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits + structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits + and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) + nor #50 norinputs(anorb, a[3], b[3]); + and #50 andsum(bandsum, b[3], sum[3]); + nor #50 norsum(bnorsum, b[3], sum[3]); + or #50 orinputcombs(abandnoror, aandb, anorb); + nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); + and #50 finaland(overflow, abandnoror, bsumandnornor); +endmodule \ No newline at end of file diff --git a/Core/ALU/adder_subtracter.t.v b/Core/ALU/adder_subtracter.t.v new file mode 100644 index 0000000..2e6f726 --- /dev/null +++ b/Core/ALU/adder_subtracter.t.v @@ -0,0 +1,60 @@ +// Adder_subtacter testbench + +`timescale 1 ns / 1 ps +`include "adder_subtracter.v" + +module test32bitAdder(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] carryin; + wire[31:0] ans; + wire carryout, overflow, zero; + + adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); + + initial begin + $display("Input A Input B Command | Output Flag Carryout"); + + // Addition tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b100; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + // Subtraction Tests + a=32'b00000000000000000000000000000001; + b=32'b00000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000001000000000000000000000; + b=32'b00000000000000000000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000001000010000000000000000; + b=32'b10000000000000010000000010000000; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b00000000000000000000000000000000; + b=32'b10000000000000000000000000000001; + carryin=3'b001; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + + a=32'b10000000000000000000000000000001; + b=32'b10000000000000000000000000000001; + carryin=3'b000; #5000 + $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); + end +endmodule \ No newline at end of file diff --git a/Core/ALU/adder_subtracter.v b/Core/ALU/adder_subtracter.v new file mode 100644 index 0000000..fea62ec --- /dev/null +++ b/Core/ALU/adder_subtracter.v @@ -0,0 +1,266 @@ +`include "adder.v" + +// 32 bit mux +module mux + ( + output[31:0] out, + input address, + input[31:0] in0, + input[31:0] in1 + ); + wire invaddr; + wire in00addr; // input 0 bit 0 andded with address + wire in01addr; + wire in02addr; + wire in03addr; + wire in04addr; + wire in05addr; + wire in06addr; + wire in07addr; + wire in08addr; + wire in09addr; + wire in010addr; + wire in011addr; + wire in012addr; + wire in013addr; + wire in014addr; + wire in015addr; + wire in016addr; + wire in017addr; + wire in018addr; + wire in019addr; + wire in020addr; + wire in021addr; + wire in022addr; + wire in023addr; + wire in024addr; + wire in025addr; + wire in026addr; + wire in027addr; + wire in028addr; + wire in029addr; + wire in030addr; + wire in031addr; + wire in10addr; + wire in11addr; + wire in12addr; + wire in13addr; + wire in14addr; + wire in15addr; + wire in16addr; + wire in17addr; + wire in18addr; + wire in19addr; + wire in110addr; + wire in111addr; + wire in112addr; + wire in113addr; + wire in114addr; + wire in115addr; + wire in116addr; + wire in117addr; + wire in118addr; + wire in119addr; + wire in120addr; + wire in121addr; + wire in122addr; + wire in123addr; + wire in124addr; + wire in125addr; + wire in126addr; + wire in127addr; + wire in128addr; + wire in129addr; + wire in130addr; + wire in131addr; + + // inverting address + not #10 inv(invaddr, address); + // and all bits in input 0 with inverted address + and #20 and00(in00addr, in0[0], invaddr); + and #20 and01(in01addr, in0[1], invaddr); + and #20 and02(in02addr, in0[2], invaddr); + and #20 and03(in03addr, in0[3], invaddr); + and #20 and04(in04addr, in0[4], invaddr); + and #20 and05(in05addr, in0[5], invaddr); + and #20 and06(in06addr, in0[6], invaddr); + and #20 and07(in07addr, in0[7], invaddr); + and #20 and08(in08addr, in0[8], invaddr); + and #20 and09(in09addr, in0[9], invaddr); + and #20 and010(in010addr, in0[10], invaddr); + and #20 and011(in011addr, in0[11], invaddr); + and #20 and012(in012addr, in0[12], invaddr); + and #20 and013(in013addr, in0[13], invaddr); + and #20 and014(in014addr, in0[14], invaddr); + and #20 and015(in015addr, in0[15], invaddr); + and #20 and016(in016addr, in0[16], invaddr); + and #20 and017(in017addr, in0[17], invaddr); + and #20 and018(in018addr, in0[18], invaddr); + and #20 and019(in019addr, in0[19], invaddr); + and #20 and020(in020addr, in0[20], invaddr); + and #20 and021(in021addr, in0[21], invaddr); + and #20 and022(in022addr, in0[22], invaddr); + and #20 and023(in023addr, in0[23], invaddr); + and #20 and024(in024addr, in0[24], invaddr); + and #20 and025(in025addr, in0[25], invaddr); + and #20 and026(in026addr, in0[26], invaddr); + and #20 and027(in027addr, in0[27], invaddr); + and #20 and028(in028addr, in0[28], invaddr); + and #20 and029(in029addr, in0[29], invaddr); + and #20 and030(in030addr, in0[30], invaddr); + and #20 and031(in031addr, in0[31], invaddr); + // and all bits in input 1 with address + and #20 and10(in10addr, in1[0], address); + and #20 and11(in11addr, in1[1], address); + and #20 and12(in12addr, in1[2], address); + and #20 and13(in13addr, in1[3], address); + and #20 and14(in14addr, in1[4], address); + and #20 and15(in15addr, in1[5], address); + and #20 and16(in16addr, in1[6], address); + and #20 and17(in17addr, in1[7], address); + and #20 and18(in18addr, in1[8], address); + and #20 and19(in19addr, in1[9], address); + and #20 and110(in110addr, in1[10], address); + and #20 and111(in111addr, in1[11], address); + and #20 and112(in112addr, in1[12], address); + and #20 and113(in113addr, in1[13], address); + and #20 and114(in114addr, in1[14], address); + and #20 and115(in115addr, in1[15], address); + and #20 and116(in116addr, in1[16], address); + and #20 and117(in117addr, in1[17], address); + and #20 and118(in118addr, in1[18], address); + and #20 and119(in119addr, in1[19], address); + and #20 and120(in120addr, in1[20], address); + and #20 and121(in121addr, in1[21], address); + and #20 and122(in122addr, in1[22], address); + and #20 and123(in123addr, in1[23], address); + and #20 and124(in124addr, in1[24], address); + and #20 and125(in125addr, in1[25], address); + and #20 and126(in126addr, in1[26], address); + and #20 and127(in127addr, in1[27], address); + and #20 and128(in128addr, in1[28], address); + and #20 and129(in129addr, in1[29], address); + and #20 and130(in130addr, in1[30], address); + and #20 and131(in131addr, in1[31], address); + + // or the and gates + or #20 or0(out[0], in00addr, in10addr); + or #20 or1(out[1], in01addr, in11addr); + or #20 or2(out[2], in02addr, in12addr); + or #20 or3(out[3], in03addr, in13addr); + or #20 or4(out[4], in04addr, in14addr); + or #20 or5(out[5], in05addr, in15addr); + or #20 or6(out[6], in06addr, in16addr); + or #20 or7(out[7], in07addr, in17addr); + or #20 or8(out[8], in08addr, in18addr); + or #20 or9(out[9], in09addr, in19addr); + or #20 or10(out[10], in010addr, in110addr); + or #20 or11(out[11], in011addr, in111addr); + or #20 or12(out[12], in012addr, in112addr); + or #20 or13(out[13], in013addr, in113addr); + or #20 or14(out[14], in014addr, in114addr); + or #20 or15(out[15], in015addr, in115addr); + or #20 or16(out[16], in016addr, in116addr); + or #20 or17(out[17], in017addr, in117addr); + or #20 or18(out[18], in018addr, in118addr); + or #20 or19(out[19], in019addr, in119addr); + or #20 or20(out[20], in020addr, in120addr); + or #20 or21(out[21], in021addr, in121addr); + or #20 or22(out[22], in022addr, in122addr); + or #20 or23(out[23], in023addr, in123addr); + or #20 or24(out[24], in024addr, in124addr); + or #20 or25(out[25], in025addr, in125addr); + or #20 or26(out[26], in026addr, in126addr); + or #20 or27(out[27], in027addr, in127addr); + or #20 or28(out[28], in028addr, in128addr); + or #20 or29(out[29], in029addr, in129addr); + or #20 or30(out[30], in030addr, in130addr); + or #20 or31(out[31], in031addr, in131addr); +endmodule + +// 32 bit adder/subtracter that determines what operation to conduct based on the input command +module adder_subtracter + ( + output[31:0] ans, + output carryout, + output overflow, + output reg zero, + input[31:0] opA, + input[31:0] opB, + input[2:0] command + ); + wire[31:0] invertedB; //wire to invert b in the event of a subtraction + wire[31:0] finalB; + wire normalB; //added b + wire cout0; + wire cout1; + wire cout2; + wire cout3; + wire cout4; + wire cout5; + wire cout6; + wire _; + wire _1; + wire _2; + wire _3; + wire _4; + wire _5; + wire _6; + + // invert B in the case of two's complement + not #10 invertB0(invertedB[0], opB[0]); + not #10 invertB1(invertedB[1], opB[1]); + not #10 invertB2(invertedB[2], opB[2]); + not #10 invertB3(invertedB[3], opB[3]); + not #10 invertB4(invertedB[4], opB[4]); + not #10 invertB5(invertedB[5], opB[5]); + not #10 invertB6(invertedB[6], opB[6]); + not #10 invertB7(invertedB[7], opB[7]); + not #10 invertB8(invertedB[8], opB[8]); + not #10 invertB9(invertedB[9], opB[9]); + not #10 invertB10(invertedB[10], opB[10]); + not #10 invertB11(invertedB[11], opB[11]); + not #10 invertB12(invertedB[12], opB[12]); + not #10 invertB13(invertedB[13], opB[13]); + not #10 invertB14(invertedB[14], opB[14]); + not #10 invertB15(invertedB[15], opB[15]); + not #10 invertB16(invertedB[16], opB[16]); + not #10 invertB17(invertedB[17], opB[17]); + not #10 invertB18(invertedB[18], opB[18]); + not #10 invertB19(invertedB[19], opB[19]); + not #10 invertB20(invertedB[20], opB[20]); + not #10 invertB21(invertedB[21], opB[21]); + not #10 invertB22(invertedB[22], opB[22]); + not #10 invertB23(invertedB[23], opB[23]); + not #10 invertB24(invertedB[24], opB[24]); + not #10 invertB25(invertedB[25], opB[25]); + not #10 invertB26(invertedB[26], opB[26]); + not #10 invertB27(invertedB[27], opB[27]); + not #10 invertB28(invertedB[28], opB[28]); + not #10 invertB29(invertedB[29], opB[29]); + not #10 invertB30(invertedB[30], opB[30]); + not #10 invertB31(invertedB[31], opB[31]); + + // mux chooses between inverted B or normal B based on addition or subtraction + mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); + + // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one + FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding + FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); + FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); + FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); + FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); + FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); + FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); + FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); + + always @(*) begin + if (ans === 32'b0) begin + zero <= 1; + end + + else begin + zero <= 0; + end + end +endmodule \ No newline at end of file diff --git a/Core/ALU/alu.t.v b/Core/ALU/alu.t.v new file mode 100644 index 0000000..322cd32 --- /dev/null +++ b/Core/ALU/alu.t.v @@ -0,0 +1,507 @@ +`timescale 1 ns / 1 ps +`include "alu.v" + +module testALU32bit(); + reg[31:0] a; + reg[31:0] b; + reg[2:0] ALUcommand; + wire[31:0] finalALUsig; + wire flag; + wire cout; + + ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); + + initial begin + $display("ALU Command Input A Input B | Output Flag Carryout"); + //Test cases add + ALUcommand = 3'b000; + + // 0 + 0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // 1 + 1 + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // positive overflow + a = 32'b01111111111111111111111111111111; + b = 32'b01111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // negative overflow + a = 32'b10000000000000000000000000000001; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // carryout + a = 32'b11111111111111111111111111111111; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + + //Test cases sub + ALUcommand = 3'b001; + + // a=b=0 + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a=b + a = 32'b00000000000000000000000000000001; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a>b, both positive + a = 32'b00000000000000000000000000000111; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a|b|, both negative + a = 32'b11111111111111111111111111111101; + b = 32'b11111111111111111111111111111110; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // |a|<|b|, both negative + a = 32'b111111111111111111111111111111110; + b = 32'b111111111111111111111111111111000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, no overflow + a = 32'b11111111111111111111111111111101; + b = 32'b00000000000000000000000000000101; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a negative, b positive, overflow + a = 32'b10000000000000000000000000000101; + b = 32'b01111100000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, no overflow + a = 32'b00000000000000000000000000000101; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + //Here + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + // a positive, b negative, overflow + a = 32'b01111111111111111111101111111111; + b = 32'b10000000000000001100000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //Test cases xor + ALUcommand = 3'b010; + + //a is all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //b is all 0's + b = 32'b00000000000000000000000000000000; + a = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 0's + a = 32'b00000000000000000000000000000000; + b = 32'b00000000000000000000000000000000; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a and b are all 1's + a = 32'b11111111111111111111111111111111; + b = 32'b11111111111111111111111111111111; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + + //Test cases slt + ALUcommand = 3'b011; + + //a>b, all positive + a = 32'b00000000000000000000000000000010; + b = 32'b00000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //ab, all negative + a = 32'b10000000000000000000000000000010; + b = 32'b10000000000000000000000000000001; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a>b, a positive, b negative + a = 32'b00000000000000000000000000000001; + b = 32'b10000000000000000000000000000010; + #25000 + $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); + + // Verify expectations and report test result + if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin + $display("Test Case Failed"); + end + + //a Date: Thu, 9 Nov 2017 22:14:51 -0500 Subject: [PATCH 085/190] Initialize memory --- memory.v | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 memory.v diff --git a/memory.v b/memory.v deleted file mode 100644 index 06cc571..0000000 --- a/memory.v +++ /dev/null @@ -1,28 +0,0 @@ -/* -The memory used in the CPU -*/ - -module memory -#( - parameter addresswidth = 32, - parameter depth = addresswidth, - parameter width = 32 -) -( - input clk, - output reg [width-1:0] dataOut, - input [addresswidth-1:0] address, - input writeEnable, - input [width-1:0] dataIn -); - - - reg [width-1:0] memory [depth-1:0]; - - always @(negedge clk) begin - if(writeEnable) - memory[address] <= dataIn; - dataOut <= memory[address]; - end - -endmodule \ No newline at end of file From 1a51e2603d692514f25c1cb06257d277fb827212 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 9 Nov 2017 22:15:10 -0500 Subject: [PATCH 086/190] Add test cases --- memory.t.v | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 memory.t.v diff --git a/memory.t.v b/memory.t.v deleted file mode 100644 index c2bee8d..0000000 --- a/memory.t.v +++ /dev/null @@ -1,20 +0,0 @@ -/* -Test bench for data memory module. -*/ - -`include "memory.v" - -module memory_TEST(); - reg clk; - reg [31:0] address; - reg writeEnable; - reg [31:0] dataIn; - - wire [31:0] dataOut; - - memory dut(clk, dataOut, address, writeEnable, dataIn); - - initial begin - // Test code here - end -endmodule \ No newline at end of file From 3faa596fe7a101f13bac8dcaa86ad3de96076041 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 9 Nov 2017 22:15:41 -0500 Subject: [PATCH 087/190] Create file of initialized memory --- file.dat | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 file.dat diff --git a/file.dat b/file.dat new file mode 100644 index 0000000..6866368 --- /dev/null +++ b/file.dat @@ -0,0 +1,35 @@ +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 + +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 +00000000_00000000_00000000_00000001 \ No newline at end of file From 17c141a28700d152eaa82e7a74979b83e18fe7cf Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:06:50 -0500 Subject: [PATCH 088/190] Connect Da wire --- core.v | 66 ---------------------------------------------------------- 1 file changed, 66 deletions(-) delete mode 100644 core.v diff --git a/core.v b/core.v deleted file mode 100644 index 2d0c29c..0000000 --- a/core.v +++ /dev/null @@ -1,66 +0,0 @@ -/* -The section of the CPU containing the register file, data memory, and ALU. -*/ - -`include "alu.v" -`include "memory.v" -`include "regfile.v" -`include "signextend.v" - -module core -( - input clk, - input [4:0] rd, - input [4:0] rt, - input [4:0] rs, - input [15:0] immediate, - input [31:0] new_PC, - input [0:1] regdst, - input [2:0] ALUcntrl, - input AlUsrc, - input MemWr, - input RegWr, - input [1:0] MemtoReg, - output [31:0] Da, - output is_zero -); - - wire[4:0] writeaddr; - - // Register file write address - mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - - wire[31:0] dataaout; - wire[31:0] databout; - wire[31:0] datain; - - // Register file - regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); - - // Sign extend - - wire[31:0] signextimm; - signextend extend (immediate, signextimm); - - // ALU operand 2 mux - wire[31:0] operandb; - - mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); - - // ALU - wire cout; - wire overflow; - wire[31:0] finalsignal; - - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); - - // Regfile write data mux - wire[31:0] memout; - - mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); - - // Data Meomory - memory datamemory (clk, memout, finalsignal, MemWr, databout); - - -endmodule \ No newline at end of file From 8d1c6ea4efc949f361689d35412df8ceea94249d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:07:37 -0500 Subject: [PATCH 089/190] Implement tests for addi, lw, sw --- core.t.v | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 core.t.v diff --git a/core.t.v b/core.t.v deleted file mode 100644 index d65d6d8..0000000 --- a/core.t.v +++ /dev/null @@ -1,40 +0,0 @@ -/* -Test bench for the core module of the CPU. -*/ - -`include "core.v" - -module core_TEST(); - wire [31:0] Da; - wire is_zero; - - reg clk; - reg [4:0] rd; - reg [4:0] rt; - reg [4:0] rs; - reg [15:0] immediate; - reg [31:0] new_PC; - reg [0:1] regdst; - reg [2:0] ALUcntrl; - reg AlUsrc; - reg MemWr; - reg RegWr; - reg [1:0] MemtoReg; - - core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); - - initial clk = 0; - always #10 clk = !clk; - - initial begin - $dumpfile("core.vcd"); - $dumpvars(0, core_TEST); - - // Test Case 1: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; - rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; - - - $finish; - end -endmodule \ No newline at end of file From e8d8325c005e9035ddd01e67aede7008a1d30001 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:10:01 -0500 Subject: [PATCH 090/190] Update module references --- Core/ALU/adder_subtracter.t.v | 2 +- Core/ALU/adder_subtracter.v | 2 +- Core/ALU/alu.t.v | 7 ++++++- Core/ALU/alu.v | 14 +++++++------- Core/ALU/and_32bit.t.v | 2 +- Core/ALU/nand_32bit.t.v | 2 +- Core/ALU/nor_32bit.t.v | 2 +- Core/ALU/or_32bit.t.v | 2 +- Core/ALU/slt.t.v | 2 +- Core/ALU/xor_32bit.t.v | 2 +- 10 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Core/ALU/adder_subtracter.t.v b/Core/ALU/adder_subtracter.t.v index 2e6f726..b8593b6 100644 --- a/Core/ALU/adder_subtracter.t.v +++ b/Core/ALU/adder_subtracter.t.v @@ -1,7 +1,7 @@ // Adder_subtacter testbench `timescale 1 ns / 1 ps -`include "adder_subtracter.v" +`include "Core/ALU/adder_subtracter.v" module test32bitAdder(); reg[31:0] a; diff --git a/Core/ALU/adder_subtracter.v b/Core/ALU/adder_subtracter.v index fea62ec..87bd13c 100644 --- a/Core/ALU/adder_subtracter.v +++ b/Core/ALU/adder_subtracter.v @@ -1,4 +1,4 @@ -`include "adder.v" +`include "Core/ALU/adder.v" // 32 bit mux module mux diff --git a/Core/ALU/alu.t.v b/Core/ALU/alu.t.v index 322cd32..681da3b 100644 --- a/Core/ALU/alu.t.v +++ b/Core/ALU/alu.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "alu.v" +`include "Core/ALU/alu.v" module testALU32bit(); reg[31:0] a; @@ -12,6 +12,9 @@ module testALU32bit(); ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); initial begin + $dumpfile("Core/ALU/alu.vcd"); + $dumpvars(); + $display("ALU Command Input A Input B | Output Flag Carryout"); //Test cases add ALUcommand = 3'b000; @@ -503,5 +506,7 @@ module testALU32bit(); if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin $display("Test Case Failed"); end + + $finish(); end endmodule \ No newline at end of file diff --git a/Core/ALU/alu.v b/Core/ALU/alu.v index 47c9191..8d00840 100644 --- a/Core/ALU/alu.v +++ b/Core/ALU/alu.v @@ -1,12 +1,12 @@ //final 32-bit ALU -`include "adder_subtracter.v" -`include "slt.v" -`include "and_32bit.v" -`include "nand_32bit.v" -`include "xor_32bit.v" -`include "nor_32bit.v" -`include "or_32bit.v" +`include "Core/ALU/adder_subtracter.v" +`include "Core/ALU/slt.v" +`include "Core/ALU/and_32bit.v" +`include "Core/ALU/nand_32bit.v" +`include "Core/ALU/xor_32bit.v" +`include "Core/ALU/nor_32bit.v" +`include "Core/ALU/or_32bit.v" module ALUcontrolLUT ( diff --git a/Core/ALU/and_32bit.t.v b/Core/ALU/and_32bit.t.v index 5857179..5ff89be 100644 --- a/Core/ALU/and_32bit.t.v +++ b/Core/ALU/and_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "and_32bit.v" +`include "Core/ALU/and_32bit.v" module test32bitand(); reg[31:0] a; diff --git a/Core/ALU/nand_32bit.t.v b/Core/ALU/nand_32bit.t.v index 28a4791..706760b 100644 --- a/Core/ALU/nand_32bit.t.v +++ b/Core/ALU/nand_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "nand_32bit.v" +`include "Core/ALU/nand_32bit.v" module test32bitnand(); reg[31:0] a; diff --git a/Core/ALU/nor_32bit.t.v b/Core/ALU/nor_32bit.t.v index 619fd4a..26239c2 100644 --- a/Core/ALU/nor_32bit.t.v +++ b/Core/ALU/nor_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "nor_32bit.v" +`include "Core/ALU/nor_32bit.v" module test32bitnor(); reg[31:0] a; diff --git a/Core/ALU/or_32bit.t.v b/Core/ALU/or_32bit.t.v index bb19ef6..aae88e2 100644 --- a/Core/ALU/or_32bit.t.v +++ b/Core/ALU/or_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "or_32bit.v" +`include "Core/ALU/or_32bit.v" module test32bitor(); reg[31:0] a; diff --git a/Core/ALU/slt.t.v b/Core/ALU/slt.t.v index b5415f9..69b6532 100644 --- a/Core/ALU/slt.t.v +++ b/Core/ALU/slt.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "slt.v" +`include "Core/ALU/slt.v" module test32bitslt(); reg[31:0] a; diff --git a/Core/ALU/xor_32bit.t.v b/Core/ALU/xor_32bit.t.v index bbd0725..f62930a 100644 --- a/Core/ALU/xor_32bit.t.v +++ b/Core/ALU/xor_32bit.t.v @@ -1,5 +1,5 @@ `timescale 1 ns / 1 ps -`include "xor_32bit.v" +`include "Core/ALU/xor_32bit.v" module test32bitxor(); reg[31:0] a; From 76a4b82c9314df7b40088e1773d84a3cef3ae13c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:10:37 -0500 Subject: [PATCH 091/190] update file paths --- makefile | 60 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/makefile b/makefile index 6f92f94..54cd1bc 100644 --- a/makefile +++ b/makefile @@ -1,51 +1,51 @@ all: core alu regfile memory signextend # Core modules -core: core.v core.t.v - iverilog -Wall -o core core.t.v +core: Core/core.v Core/core.t.v + iverilog -Wall -o core Core/core.t.v # ALU modules -alu: alu.v alu.t.v adder_subtracter and nand nor or slt xor - iverilog -Wall -o alu alu.t.v +alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor + iverilog -Wall -o alu Core/ALU/alu.t.v -adder_subtracter: adder_subtracter.v adder_subtracter.t.v - iverilog -Wall -o adder_subtracter adder_subtracter.t.v +adder_subtracter: Core/ALU/adder_subtracter.v Core/ALU/adder_subtracter.t.v + iverilog -Wall -o adder_subtracter Core/ALU/adder_subtracter.t.v -and: and_32bit.v and_32bit.t.v - iverilog -Wall -o and and_32bit.t.v +and: Core/ALU/and_32bit.v Core/ALU/and_32bit.t.v + iverilog -Wall -o and Core/ALU/and_32bit.t.v -nand: nand_32bit.v nand_32bit.t.v - iverilog -Wall -o nand nand_32bit.t.v +nand: Core/ALU/nand_32bit.v Core/ALU/nand_32bit.t.v + iverilog -Wall -o nand Core/ALU/nand_32bit.t.v -nor: nor_32bit.v nor_32bit.t.v - iverilog -Wall -o nor nor_32bit.t.v +nor: Core/ALU/nor_32bit.v Core/ALU/nor_32bit.t.v + iverilog -Wall -o nor Core/ALU/nor_32bit.t.v -or: or_32bit.v or_32bit.t.v - iverilog -Wall -o or or_32bit.t.v +or: Core/ALU/or_32bit.v Core/ALU/or_32bit.t.v + iverilog -Wall -o or Core/ALU/or_32bit.t.v -slt: slt.v slt.t.v - iverilog -Wall -o slt slt.t.v +slt: Core/ALU/slt.v Core/ALU/slt.t.v + iverilog -Wall -o slt Core/ALU/slt.t.v -xor: xor_32bit.v xor_32bit.t.v - iverilog -Wall -o xor xor_32bit.t.v +xor: Core/ALU/xor_32bit.v Core/ALU/xor_32bit.t.v + iverilog -Wall -o xor Core/ALU/xor_32bit.t.v # Regfile modules -regfile: regfile.t.v regfile.v decoder mux register - iverilog -Wall -o regfile regfile.t.v +regfile: Core/regfile.t.v Core/regfile.v decoder mux register + iverilog -Wall -o regfile Core/regfile.t.v -decoder: decoders.t.v decoders.v - iverilog -Wall -o decoder decoders.t.v +decoder: Core/decoders.t.v Core/decoders.v + iverilog -Wall -o decoder Core/decoders.t.v -mux: multiplexer.t.v multiplexer.v - iverilog -Wall -o mux multiplexer.t.v +mux: Core/multiplexer.t.v Core/multiplexer.v + iverilog -Wall -o mux Core/multiplexer.t.v -register: register.t.v register.v - iverilog -Wall -o register register.t.v +register: Core/register.t.v Core/register.v + iverilog -Wall -o register Core/register.t.v # Memory modules -memory: memory.v memory.t.v - iverilog -Wall -o memory memory.t.v +memory: Core/memory.v Core/memory.t.v + iverilog -Wall -o memory Core/memory.t.v # Concatenation modules -signextend: signextend.v - iverilog -Wall -o signextend signextend.v +signextend: Core/signextend.v + iverilog -Wall -o signextend Core/signextend.v From f3d270f006f41a407780d8e134bcca90eaaad19d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:11:00 -0500 Subject: [PATCH 092/190] Update file paths --- Core/core.t.v | 139 ++++++++++++++++++++++++++++++++++++++++--- Core/core.v | 14 ++--- Core/decoders.t.v | 2 +- Core/memory.t.v | 39 +++++++++++- Core/memory.v | 2 + Core/multiplexer.t.v | 2 +- Core/regfile.t.v | 2 +- Core/regfile.v | 6 +- Core/register.t.v | 2 +- 9 files changed, 185 insertions(+), 23 deletions(-) diff --git a/Core/core.t.v b/Core/core.t.v index c5f85b6..0ee8f25 100644 --- a/Core/core.t.v +++ b/Core/core.t.v @@ -2,7 +2,7 @@ Test bench for the core module of the CPU. */ -`include "core.v" +`include "Core/core.v" module core_TEST(); wire [31:0] Da; @@ -27,13 +27,138 @@ module core_TEST(); always #10 clk = !clk; initial begin - $dumpfile("core.vcd"); - $dumpvars(0, core_TEST); + $dumpfile("Core/core.vcd"); + $dumpvars(0, core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); - // Test Case 1: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b0; MemtoReg = 2'b00; - rd = 5'bx; rt = 5'b0; rs = 5'b00001; immediate = 16'b0; - #1000 + // Test Case 1: Add Immediate + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd1; rs = 5'b00000; immediate = 16'b0; + #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0"); + end + + // Populate the rest of the registers with data (each gets 32'b0) + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd2; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd3; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd4; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd5; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd6; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd7; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd8; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd9; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd10; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd11; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd12; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd13; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd14; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd15; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd16; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd17; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd18; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd19; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd20; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd21; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd22; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd23; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd24; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd25; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd26; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd27; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd28; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd29; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd30; rs = 5'b00000; immediate = 16'b0; + #6000 + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; + rd =5'bx; rt = 5'd31; rs = 5'b00000; immediate = 16'b0; + #6000 + + + // Test Case 2: Load Word + regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 2'b01; + rd = 5'bx; rt = 5'b00010; rs = 5'b00001; immediate = 16'b0; + #100 + + if (dut.databout !== dut.datamemory.memory[0]) begin + $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimmediate]"); + end + + // Test Case 3: Store Word + regdst = 2'bx; AlUsrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUcntrl = 3'b000; MemtoReg = 2'bx; + rd = 5'bx; rs = 5'b00001; rt = 5'b00000; immediate = 16'b0; + #100 + + if (dut.datamemory.dataOut !== dut.databout) begin + $display("Test case 3 failed: M[R[rs] + signextendimmediate] != R[rt]"); + end + + // Test Case 4: Jump + // Test Case 5: Jump Register + // Test Case 6: Jump and Link + // Test Case 7: Branch if Not Equal + // Test Case 8: XOR Immediate + // Test Case 9: Add + // Test Case 10: Subtract + // Test Case 11: Set Less Than + #10000 $finish; end diff --git a/Core/core.v b/Core/core.v index 2d0c29c..f4ed3ac 100644 --- a/Core/core.v +++ b/Core/core.v @@ -2,10 +2,10 @@ The section of the CPU containing the register file, data memory, and ALU. */ -`include "alu.v" -`include "memory.v" -`include "regfile.v" -`include "signextend.v" +`include "Core/ALU/alu.v" +`include "Core/memory.v" +`include "Core/regfile.v" +`include "Core/signextend.v" module core ( @@ -30,12 +30,12 @@ module core // Register file write address mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - wire[31:0] dataaout; + // wire[31:0] dataaout; wire[31:0] databout; wire[31:0] datain; // Register file - regfile regfile (dataaout, databout, datain, rs, rt, writeaddr, RegWr, clk); + regfile regfile (Da, databout, datain, rs, rt, writeaddr, RegWr, clk); // Sign extend @@ -52,7 +52,7 @@ module core wire overflow; wire[31:0] finalsignal; - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, databout, operandb); + ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, Da, operandb); // Regfile write data mux wire[31:0] memout; diff --git a/Core/decoders.t.v b/Core/decoders.t.v index 616b67b..e841b22 100644 --- a/Core/decoders.t.v +++ b/Core/decoders.t.v @@ -2,7 +2,7 @@ // Unit test the decoder module //------------------------------- -`include "decoders.v" +`include "Core/decoders.v" module decoder1to32Test(); wire[31:0] out; diff --git a/Core/memory.t.v b/Core/memory.t.v index c2bee8d..836af61 100644 --- a/Core/memory.t.v +++ b/Core/memory.t.v @@ -2,7 +2,7 @@ Test bench for data memory module. */ -`include "memory.v" +`include "Core/memory.v" module memory_TEST(); reg clk; @@ -14,7 +14,42 @@ module memory_TEST(); memory dut(clk, dataOut, address, writeEnable, dataIn); + initial clk = 0; + always #10 clk = !clk; initial begin - // Test code here + $dumpfile("Core/memory.vcd"); + $dumpvars(0, memory_TEST, dut.memory[0]); + + // Test Case 1: Do not write if writeEnable is low. + writeEnable = 0; dataIn = 32'hffffffff; address = 32'd0; + #20 + if (dataOut === dataIn) begin + $display("Test case 1 failed: memory was written to when writeEnable was false."); + end + + else if (dataOut === 32'bx) begin + $display("Test case 1 failed: there is no memory at the given address."); + end + + #1000 + // Test case 2: Write to memory if writeEnable is high. + writeEnable = 1; dataIn = 32'hffffffff; address = 32'd0; + #40 + + if (dataOut === 32'bx) begin + $display("Test case 2 failed: there is no memory at the given address."); + end + + if (dut.memory[0] !== dataIn) begin + $display("Test case 2 failed: the memory contained at the given address does not match dataIn"); + end + + if (dataOut !== dataIn) begin + $display("Test case 2 failed: memory was not written to when writeEnable was true."); + end + + #1000 + + $finish; end endmodule \ No newline at end of file diff --git a/Core/memory.v b/Core/memory.v index 06cc571..820e3d0 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -25,4 +25,6 @@ module memory dataOut <= memory[address]; end + initial $readmemh("file.dat", memory); + endmodule \ No newline at end of file diff --git a/Core/multiplexer.t.v b/Core/multiplexer.t.v index dc1fff3..8f17795 100644 --- a/Core/multiplexer.t.v +++ b/Core/multiplexer.t.v @@ -2,7 +2,7 @@ // Test the multiplexer modules. //-------------------------------- -`include "multiplexer.v" +`include "Core/multiplexer.v" // Test harness for multiplexer unit test modules. module multiplexerTestBenchHarness(); diff --git a/Core/regfile.t.v b/Core/regfile.t.v index 059c0ec..4dda453 100644 --- a/Core/regfile.t.v +++ b/Core/regfile.t.v @@ -3,7 +3,7 @@ // or broken register files, and verifying that it correctly identifies each //------------------------------------------------------------------------------ -`include "regfile.v" +`include "Core/regfile.v" module hw4testbenchharness(); diff --git a/Core/regfile.v b/Core/regfile.v index 893bf11..0bc8f4b 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -6,9 +6,9 @@ // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ -`include "register.v" -`include "multiplexer.v" -`include "decoders.v" +`include "Core/register.v" +`include "Core/multiplexer.v" +`include "Core/decoders.v" module regfile ( diff --git a/Core/register.t.v b/Core/register.t.v index e0821b7..8b4a7f0 100644 --- a/Core/register.t.v +++ b/Core/register.t.v @@ -1,7 +1,7 @@ //-------------------------- // Test the register modules //-------------------------- -`include "register.v" +`include "Core/register.v" // Unit tests for the single bit register module. module registerTest(); From 14254206db8bdbfa27fab59d80a368272e55eb02 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Fri, 10 Nov 2017 00:11:48 -0500 Subject: [PATCH 093/190] Move files to subfolder --- adder.v | 76 ------- adder_subtracter.t.v | 60 ----- adder_subtracter.v | 266 ----------------------- alu.t.v | 507 ------------------------------------------- alu.v | 59 ----- and_32bit.t.v | 36 --- and_32bit.v | 40 ---- decoders.t.v | 41 ---- decoders.v | 20 -- multiplexer.t.v | 165 -------------- multiplexer.v | 74 ------- nand_32bit.t.v | 36 --- nand_32bit.v | 40 ---- nor_32bit.t.v | 36 --- nor_32bit.v | 40 ---- or_32bit.t.v | 30 --- or_32bit.v | 40 ---- regfile.t.v | 176 --------------- regfile.v | 114 ---------- register.t.v | 121 ----------- register.v | 48 ---- signextend.v | 12 - slt.t.v | 40 ---- slt.v | 110 ---------- xor_32bit.t.v | 36 --- xor_32bit.v | 40 ---- 26 files changed, 2263 deletions(-) delete mode 100644 adder.v delete mode 100644 adder_subtracter.t.v delete mode 100644 adder_subtracter.v delete mode 100644 alu.t.v delete mode 100644 alu.v delete mode 100644 and_32bit.t.v delete mode 100644 and_32bit.v delete mode 100644 decoders.t.v delete mode 100644 decoders.v delete mode 100644 multiplexer.t.v delete mode 100644 multiplexer.v delete mode 100644 nand_32bit.t.v delete mode 100644 nand_32bit.v delete mode 100644 nor_32bit.t.v delete mode 100644 nor_32bit.v delete mode 100644 or_32bit.t.v delete mode 100644 or_32bit.v delete mode 100644 regfile.t.v delete mode 100644 regfile.v delete mode 100644 register.t.v delete mode 100644 register.v delete mode 100644 signextend.v delete mode 100644 slt.t.v delete mode 100644 slt.v delete mode 100644 xor_32bit.t.v delete mode 100644 xor_32bit.v diff --git a/adder.v b/adder.v deleted file mode 100644 index cc610e8..0000000 --- a/adder.v +++ /dev/null @@ -1,76 +0,0 @@ -// Adder circuit - -module behavioralFullAdder -( - output sum, - output carryout, - input a, - input b, - input carryin -); - // Uses concatenation operator and built-in '+' - assign {carryout, sum}=a+b+carryin; -endmodule - -module structuralFullAdder -( - output sum, - output carryout, - input a, - input b, - input carryin -); - wire ab; //setting up wires - wire acarryin; - wire bcarryin; - wire orpairintermediate; - wire orsingleintermediate; - wire orall; - wire andsumintermediate; - wire andsingleintermediate; - wire andall; - wire invcarryout; - and #(50) andab(ab, a, b); // a and b - and #(50) andacarryin(acarryin, a, carryin); // a and carryin - and #(50) andbcarryin(bcarryin, b, carryin); // b and carryin - or #(50) orpair(orpairintermediate, ab, acarryin); // (a and b) or (a and carryin) - or #(50) orcarryout(carryout, orpairintermediate, bcarryin); // ((a and b) or (a and carryin)) or (b and carryin) - or #(50) orintermediate(orsingleintermediate, a, b); // a or b - or #(50) orallinputs(orall, orsingleintermediate, carryin); // (a or b) or carryin - not #(50) inv(invcarryout, carryout); // not carryout - and #(50) sumintermediate(andsumintermediate, invcarryout, orall); // (a or b or carryin) and not carryout - and #(50) andintermediate(andsingleintermediate, a, b); // a and b - and #(50) andallinputs(andall, andsingleintermediate, carryin); // (a and b) and carryin - or #(50) adder(sum, andsumintermediate, andall); // ((a or b or carryin) and not carryout) or (a and b and c) -endmodule - -module FullAdder4bit -( - output[3:0] sum, // 2's complement sum of a and b - output carryout, // Carry out of the summation of a and b - output overflow, // True if the calculation resulted in an overflow - input[3:0] a, // First operand in 2's complement format - input[3:0] b, // Second operand in 2's complement format - input carryin -); - wire carryout1; // wire setup for carryouts from each adder - wire carryout2; - wire carryout3; - wire aandb; - wire anorb; - wire bandsum; - wire bnorsum; - wire abandnoror; - wire bsumandnornor; - structuralFullAdder #50 adder1(sum[0], carryout1, a[0], b[0], carryin); // first adder to handle the first added bits - structuralFullAdder #50 adder2(sum[1], carryout2, a[1], b[1], carryout1); // second adder to take the carryout from the first adder and the next added bits - structuralFullAdder #50 adder3(sum[2], carryout3, a[2], b[2], carryout2); // third adder to take the second carryout and the third added bits - structuralFullAdder #50 adder4(sum[3], carryout, a[3], b[3], carryout3); // fourth adder to take the third carryout and the fourth bits - and #50 andinputs(aandb, a[3], b[3]); // logic to determine overflow (overflow occurs when two positives result in a negative or two negatives result in a positive, the larges bit in both inputs are equal and the largest bit in the output is not the same) - nor #50 norinputs(anorb, a[3], b[3]); - and #50 andsum(bandsum, b[3], sum[3]); - nor #50 norsum(bnorsum, b[3], sum[3]); - or #50 orinputcombs(abandnoror, aandb, anorb); - nor #50 norsumcombs(bsumandnornor, bandsum, bnorsum); - and #50 finaland(overflow, abandnoror, bsumandnornor); -endmodule \ No newline at end of file diff --git a/adder_subtracter.t.v b/adder_subtracter.t.v deleted file mode 100644 index 2e6f726..0000000 --- a/adder_subtracter.t.v +++ /dev/null @@ -1,60 +0,0 @@ -// Adder_subtacter testbench - -`timescale 1 ns / 1 ps -`include "adder_subtracter.v" - -module test32bitAdder(); - reg[31:0] a; - reg[31:0] b; - reg[2:0] carryin; - wire[31:0] ans; - wire carryout, overflow, zero; - - adder_subtracter adder0(ans[31:0], carryout, overflow, zero, a[31:0], b[31:0], carryin[2:0]); - - initial begin - $display("Input A Input B Command | Output Flag Carryout"); - - // Addition tests - a=32'b00000000000000000000000000000001; - b=32'b00000000000000000000000000000001; - carryin=3'b100; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b000; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - // Subtraction Tests - a=32'b00000000000000000000000000000001; - b=32'b00000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b00000000001000000000000000000000; - b=32'b00000000000000000000000010000000; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000001000010000000000000000; - b=32'b10000000000000010000000010000000; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b00000000000000000000000000000000; - b=32'b10000000000000000000000000000001; - carryin=3'b001; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - - a=32'b10000000000000000000000000000001; - b=32'b10000000000000000000000000000001; - carryin=3'b000; #5000 - $display("%b %b %b | %b %b %b", a[31:0],b[31:0],carryin,ans[31:0],carryout, overflow); - end -endmodule \ No newline at end of file diff --git a/adder_subtracter.v b/adder_subtracter.v deleted file mode 100644 index fea62ec..0000000 --- a/adder_subtracter.v +++ /dev/null @@ -1,266 +0,0 @@ -`include "adder.v" - -// 32 bit mux -module mux - ( - output[31:0] out, - input address, - input[31:0] in0, - input[31:0] in1 - ); - wire invaddr; - wire in00addr; // input 0 bit 0 andded with address - wire in01addr; - wire in02addr; - wire in03addr; - wire in04addr; - wire in05addr; - wire in06addr; - wire in07addr; - wire in08addr; - wire in09addr; - wire in010addr; - wire in011addr; - wire in012addr; - wire in013addr; - wire in014addr; - wire in015addr; - wire in016addr; - wire in017addr; - wire in018addr; - wire in019addr; - wire in020addr; - wire in021addr; - wire in022addr; - wire in023addr; - wire in024addr; - wire in025addr; - wire in026addr; - wire in027addr; - wire in028addr; - wire in029addr; - wire in030addr; - wire in031addr; - wire in10addr; - wire in11addr; - wire in12addr; - wire in13addr; - wire in14addr; - wire in15addr; - wire in16addr; - wire in17addr; - wire in18addr; - wire in19addr; - wire in110addr; - wire in111addr; - wire in112addr; - wire in113addr; - wire in114addr; - wire in115addr; - wire in116addr; - wire in117addr; - wire in118addr; - wire in119addr; - wire in120addr; - wire in121addr; - wire in122addr; - wire in123addr; - wire in124addr; - wire in125addr; - wire in126addr; - wire in127addr; - wire in128addr; - wire in129addr; - wire in130addr; - wire in131addr; - - // inverting address - not #10 inv(invaddr, address); - // and all bits in input 0 with inverted address - and #20 and00(in00addr, in0[0], invaddr); - and #20 and01(in01addr, in0[1], invaddr); - and #20 and02(in02addr, in0[2], invaddr); - and #20 and03(in03addr, in0[3], invaddr); - and #20 and04(in04addr, in0[4], invaddr); - and #20 and05(in05addr, in0[5], invaddr); - and #20 and06(in06addr, in0[6], invaddr); - and #20 and07(in07addr, in0[7], invaddr); - and #20 and08(in08addr, in0[8], invaddr); - and #20 and09(in09addr, in0[9], invaddr); - and #20 and010(in010addr, in0[10], invaddr); - and #20 and011(in011addr, in0[11], invaddr); - and #20 and012(in012addr, in0[12], invaddr); - and #20 and013(in013addr, in0[13], invaddr); - and #20 and014(in014addr, in0[14], invaddr); - and #20 and015(in015addr, in0[15], invaddr); - and #20 and016(in016addr, in0[16], invaddr); - and #20 and017(in017addr, in0[17], invaddr); - and #20 and018(in018addr, in0[18], invaddr); - and #20 and019(in019addr, in0[19], invaddr); - and #20 and020(in020addr, in0[20], invaddr); - and #20 and021(in021addr, in0[21], invaddr); - and #20 and022(in022addr, in0[22], invaddr); - and #20 and023(in023addr, in0[23], invaddr); - and #20 and024(in024addr, in0[24], invaddr); - and #20 and025(in025addr, in0[25], invaddr); - and #20 and026(in026addr, in0[26], invaddr); - and #20 and027(in027addr, in0[27], invaddr); - and #20 and028(in028addr, in0[28], invaddr); - and #20 and029(in029addr, in0[29], invaddr); - and #20 and030(in030addr, in0[30], invaddr); - and #20 and031(in031addr, in0[31], invaddr); - // and all bits in input 1 with address - and #20 and10(in10addr, in1[0], address); - and #20 and11(in11addr, in1[1], address); - and #20 and12(in12addr, in1[2], address); - and #20 and13(in13addr, in1[3], address); - and #20 and14(in14addr, in1[4], address); - and #20 and15(in15addr, in1[5], address); - and #20 and16(in16addr, in1[6], address); - and #20 and17(in17addr, in1[7], address); - and #20 and18(in18addr, in1[8], address); - and #20 and19(in19addr, in1[9], address); - and #20 and110(in110addr, in1[10], address); - and #20 and111(in111addr, in1[11], address); - and #20 and112(in112addr, in1[12], address); - and #20 and113(in113addr, in1[13], address); - and #20 and114(in114addr, in1[14], address); - and #20 and115(in115addr, in1[15], address); - and #20 and116(in116addr, in1[16], address); - and #20 and117(in117addr, in1[17], address); - and #20 and118(in118addr, in1[18], address); - and #20 and119(in119addr, in1[19], address); - and #20 and120(in120addr, in1[20], address); - and #20 and121(in121addr, in1[21], address); - and #20 and122(in122addr, in1[22], address); - and #20 and123(in123addr, in1[23], address); - and #20 and124(in124addr, in1[24], address); - and #20 and125(in125addr, in1[25], address); - and #20 and126(in126addr, in1[26], address); - and #20 and127(in127addr, in1[27], address); - and #20 and128(in128addr, in1[28], address); - and #20 and129(in129addr, in1[29], address); - and #20 and130(in130addr, in1[30], address); - and #20 and131(in131addr, in1[31], address); - - // or the and gates - or #20 or0(out[0], in00addr, in10addr); - or #20 or1(out[1], in01addr, in11addr); - or #20 or2(out[2], in02addr, in12addr); - or #20 or3(out[3], in03addr, in13addr); - or #20 or4(out[4], in04addr, in14addr); - or #20 or5(out[5], in05addr, in15addr); - or #20 or6(out[6], in06addr, in16addr); - or #20 or7(out[7], in07addr, in17addr); - or #20 or8(out[8], in08addr, in18addr); - or #20 or9(out[9], in09addr, in19addr); - or #20 or10(out[10], in010addr, in110addr); - or #20 or11(out[11], in011addr, in111addr); - or #20 or12(out[12], in012addr, in112addr); - or #20 or13(out[13], in013addr, in113addr); - or #20 or14(out[14], in014addr, in114addr); - or #20 or15(out[15], in015addr, in115addr); - or #20 or16(out[16], in016addr, in116addr); - or #20 or17(out[17], in017addr, in117addr); - or #20 or18(out[18], in018addr, in118addr); - or #20 or19(out[19], in019addr, in119addr); - or #20 or20(out[20], in020addr, in120addr); - or #20 or21(out[21], in021addr, in121addr); - or #20 or22(out[22], in022addr, in122addr); - or #20 or23(out[23], in023addr, in123addr); - or #20 or24(out[24], in024addr, in124addr); - or #20 or25(out[25], in025addr, in125addr); - or #20 or26(out[26], in026addr, in126addr); - or #20 or27(out[27], in027addr, in127addr); - or #20 or28(out[28], in028addr, in128addr); - or #20 or29(out[29], in029addr, in129addr); - or #20 or30(out[30], in030addr, in130addr); - or #20 or31(out[31], in031addr, in131addr); -endmodule - -// 32 bit adder/subtracter that determines what operation to conduct based on the input command -module adder_subtracter - ( - output[31:0] ans, - output carryout, - output overflow, - output reg zero, - input[31:0] opA, - input[31:0] opB, - input[2:0] command - ); - wire[31:0] invertedB; //wire to invert b in the event of a subtraction - wire[31:0] finalB; - wire normalB; //added b - wire cout0; - wire cout1; - wire cout2; - wire cout3; - wire cout4; - wire cout5; - wire cout6; - wire _; - wire _1; - wire _2; - wire _3; - wire _4; - wire _5; - wire _6; - - // invert B in the case of two's complement - not #10 invertB0(invertedB[0], opB[0]); - not #10 invertB1(invertedB[1], opB[1]); - not #10 invertB2(invertedB[2], opB[2]); - not #10 invertB3(invertedB[3], opB[3]); - not #10 invertB4(invertedB[4], opB[4]); - not #10 invertB5(invertedB[5], opB[5]); - not #10 invertB6(invertedB[6], opB[6]); - not #10 invertB7(invertedB[7], opB[7]); - not #10 invertB8(invertedB[8], opB[8]); - not #10 invertB9(invertedB[9], opB[9]); - not #10 invertB10(invertedB[10], opB[10]); - not #10 invertB11(invertedB[11], opB[11]); - not #10 invertB12(invertedB[12], opB[12]); - not #10 invertB13(invertedB[13], opB[13]); - not #10 invertB14(invertedB[14], opB[14]); - not #10 invertB15(invertedB[15], opB[15]); - not #10 invertB16(invertedB[16], opB[16]); - not #10 invertB17(invertedB[17], opB[17]); - not #10 invertB18(invertedB[18], opB[18]); - not #10 invertB19(invertedB[19], opB[19]); - not #10 invertB20(invertedB[20], opB[20]); - not #10 invertB21(invertedB[21], opB[21]); - not #10 invertB22(invertedB[22], opB[22]); - not #10 invertB23(invertedB[23], opB[23]); - not #10 invertB24(invertedB[24], opB[24]); - not #10 invertB25(invertedB[25], opB[25]); - not #10 invertB26(invertedB[26], opB[26]); - not #10 invertB27(invertedB[27], opB[27]); - not #10 invertB28(invertedB[28], opB[28]); - not #10 invertB29(invertedB[29], opB[29]); - not #10 invertB30(invertedB[30], opB[30]); - not #10 invertB31(invertedB[31], opB[31]); - - // mux chooses between inverted B or normal B based on addition or subtraction - mux addsubmux(finalB[31:0],command[0],opB[31:0], invertedB[31:0]); - - // coupling 4 adders makes a 32-bit adder, note that overflow flags do not matter except for the last one - FullAdder4bit #50 adder0(ans[3:0], cout0, _, opA[3:0], finalB[3:0], command[0]); // put least significant command bit into the adder carryin since it adds 1 for when subtracting, and 0 when adding - FullAdder4bit #50 adder1(ans[7:4], cout1, _1, opA[7:4], finalB[7:4], cout0); - FullAdder4bit #50 adder2(ans[11:8], cout2, _2, opA[11:8], finalB[11:8], cout1); - FullAdder4bit #50 adder3(ans[15:12], cout3, _3, opA[15:12], finalB[15:12], cout2); - FullAdder4bit #50 adder4(ans[19:16], cout4, _4, opA[19:16], finalB[19:16], cout3); - FullAdder4bit #50 adder5(ans[23:20], cout5, _5, opA[23:20], finalB[23:20], cout4); - FullAdder4bit #50 adder6(ans[27:24], cout6, _6, opA[27:24], finalB[27:24], cout5); - FullAdder4bit #50 adder7(ans[31:28], carryout, overflow, opA[31:28], finalB[31:28], cout6); - - always @(*) begin - if (ans === 32'b0) begin - zero <= 1; - end - - else begin - zero <= 0; - end - end -endmodule \ No newline at end of file diff --git a/alu.t.v b/alu.t.v deleted file mode 100644 index 322cd32..0000000 --- a/alu.t.v +++ /dev/null @@ -1,507 +0,0 @@ -`timescale 1 ns / 1 ps -`include "alu.v" - -module testALU32bit(); - reg[31:0] a; - reg[31:0] b; - reg[2:0] ALUcommand; - wire[31:0] finalALUsig; - wire flag; - wire cout; - - ALUcontrolLUT alu(cout, flag, zero, finalALUsig[31:0], ALUcommand[2:0], a[31:0], b[31:0]); - - initial begin - $display("ALU Command Input A Input B | Output Flag Carryout"); - //Test cases add - ALUcommand = 3'b000; - - // 0 + 0 - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // 1 + 1 - a = 32'b00000000000000000000000000000001; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // positive overflow - a = 32'b01111111111111111111111111111111; - b = 32'b01111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111110) || (flag != 1) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // negative overflow - a = 32'b10000000000000000000000000000001; - b = 32'b10000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 1) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // carryout - a = 32'b11111111111111111111111111111111; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - - //Test cases sub - ALUcommand = 3'b001; - - // a=b=0 - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a=b - a = 32'b00000000000000000000000000000001; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a>b, both positive - a = 32'b00000000000000000000000000000111; - b = 32'b00000000000000000000000000000101; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - if((finalALUsig != 32'b00000000000000000000000000000010) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a|b|, both negative - a = 32'b11111111111111111111111111111101; - b = 32'b11111111111111111111111111111110; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // |a|<|b|, both negative - a = 32'b111111111111111111111111111111110; - b = 32'b111111111111111111111111111111000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a negative, b positive, no overflow - a = 32'b11111111111111111111111111111101; - b = 32'b00000000000000000000000000000101; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b11111111111111111111111111111000) || (flag != 0) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a negative, b positive, overflow - a = 32'b10000000000000000000000000000101; - b = 32'b01111100000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - if((finalALUsig != 32'b00000100000000000000000000000101) || (flag != 1) || (cout != 1)) begin - $display("Test Case Failed"); - end - - // a positive, b negative, no overflow - a = 32'b00000000000000000000000000000101; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - //Here - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000110) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - // a positive, b negative, overflow - a = 32'b01111111111111111111101111111111; - b = 32'b10000000000000001100000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111110011101111111111) || (flag != 1) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //Test cases xor - ALUcommand = 3'b010; - - //a is all 0's - a = 32'b00000000000000000000000000000000; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //b is all 0's - b = 32'b00000000000000000000000000000000; - a = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b11111111111111111111111111111111) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a and b are all 0's - a = 32'b00000000000000000000000000000000; - b = 32'b00000000000000000000000000000000; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a and b are all 1's - a = 32'b11111111111111111111111111111111; - b = 32'b11111111111111111111111111111111; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - - //Test cases slt - ALUcommand = 3'b011; - - //a>b, all positive - a = 32'b00000000000000000000000000000010; - b = 32'b00000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //ab, all negative - a = 32'b10000000000000000000000000000010; - b = 32'b10000000000000000000000000000001; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a>b, a positive, b negative - a = 32'b00000000000000000000000000000001; - b = 32'b10000000000000000000000000000010; - #25000 - $display("%b %b %b | %b %b %b", ALUcommand, a, b, finalALUsig, flag, cout); - - // Verify expectations and report test result - if((finalALUsig != 32'b00000000000000000000000000000000) || (flag != 0) || (cout != 0)) begin - $display("Test Case Failed"); - end - - //a Date: Wed, 8 Nov 2017 19:57:09 -0500 Subject: [PATCH 094/190] work on pc calculator --- PC_Calc/PC_Calc.v | 10 +++++- PC_Calc/addr_concat.t.v | 18 ++++++++++ PC_Calc/addr_concat.v | 8 +++++ PC_Calc/imm_concat.t.v | 15 +++++++++ PC_Calc/imm_concat.v | 7 ++++ PC_Calc/is_zero_and.t.v | 17 ++++++++++ PC_Calc/is_zero_and.v | 8 +++++ PC_Calc/multiplexer.v | 74 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 PC_Calc/addr_concat.t.v create mode 100644 PC_Calc/addr_concat.v create mode 100644 PC_Calc/imm_concat.t.v create mode 100644 PC_Calc/imm_concat.v create mode 100644 PC_Calc/is_zero_and.t.v create mode 100644 PC_Calc/is_zero_and.v create mode 100644 PC_Calc/multiplexer.v diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index e4b39bb..3c0cf46 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -1,4 +1,6 @@ // PC_Calc Calculates the next program counter +`include "addr_concat.v" +`include "imm_concat.v" module PC_Calc ( @@ -8,7 +10,13 @@ module PC_Calc input[31:0] Da, input[25:0] addr, input[15:0] imm, - output[31:0] new_PC + output[31:0] added_PC ); + wire[31:0] extendedImm; + immConcat iconcat(extendedImm[31:0], imm[15:0]); + + wire immZeroed; + + endmodule diff --git a/PC_Calc/addr_concat.t.v b/PC_Calc/addr_concat.t.v new file mode 100644 index 0000000..8981074 --- /dev/null +++ b/PC_Calc/addr_concat.t.v @@ -0,0 +1,18 @@ +`timescale 1 ns / 1 ps +`include "addr_concat.v" + +module testConcat(); + wire[31:0] ans; + reg[31:0] pc; + reg[25:0] jumpAddr; + + addrConcat concat(ans[31:0], pc[31:0], jumpAddr[25:0]); + initial begin + pc = 32'b11000000000000000000000000000000; + jumpAddr = 26'b10101010101010101010101010; #100 + $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); + pc = 32'b11110000000000000000000000000000; + jumpAddr = 26'b11111111111111111111111111; #100 + $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/addr_concat.v b/PC_Calc/addr_concat.v new file mode 100644 index 0000000..e2301a0 --- /dev/null +++ b/PC_Calc/addr_concat.v @@ -0,0 +1,8 @@ +module addrConcat +( + output[31:0] out, + input[31:0] pc, + input[25:0] jumpAddr +); + assign out = {pc[31:28], jumpAddr, 2'b00}; +endmodule \ No newline at end of file diff --git a/PC_Calc/imm_concat.t.v b/PC_Calc/imm_concat.t.v new file mode 100644 index 0000000..8585987 --- /dev/null +++ b/PC_Calc/imm_concat.t.v @@ -0,0 +1,15 @@ +`timescale 1 ns / 1 ps +`include "imm_concat.v" + +module testConcat(); + wire[31:0] ans; + reg[15:0] imm; + + immConcat concat(ans[31:0], imm[15:0]); + initial begin + imm = 16'b1000000000000001; #100 + $display("%b %b", imm[15:0], ans[31:0]); + imm = 16'b0111111111111110; #100 + $display("%b %b", imm[15:0], ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/imm_concat.v b/PC_Calc/imm_concat.v new file mode 100644 index 0000000..ded9733 --- /dev/null +++ b/PC_Calc/imm_concat.v @@ -0,0 +1,7 @@ +module immConcat +( + output[31:0] out, + input[15:0] imm +); + assign out = {{14{imm[15]}}, imm, 2'b00}; +endmodule \ No newline at end of file diff --git a/PC_Calc/is_zero_and.t.v b/PC_Calc/is_zero_and.t.v new file mode 100644 index 0000000..7d32bd9 --- /dev/null +++ b/PC_Calc/is_zero_and.t.v @@ -0,0 +1,17 @@ +`timescale 1 ns / 1 ps +`include "is_zero_and.v" + +module testIsZero(); + wire[31:0] ans; + reg[31:0] imm; + reg isZero; + + isZeroAnd iszero(ans[31:0], imm[31:0], isZero); + initial begin + imm = 32'b11111111111111111111111111111111; + isZero = 1; #1000 + $display("%b %b %b", imm[31:0], isZero, ans[31:0]); + isZero = 0; #1000 + $display("%b %b %b", imm[31:0], isZero, ans[31:0]); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/is_zero_and.v b/PC_Calc/is_zero_and.v new file mode 100644 index 0000000..6c1530f --- /dev/null +++ b/PC_Calc/is_zero_and.v @@ -0,0 +1,8 @@ +module isZeroAnd +( + output[31:0] out, + input[31:0] imm, + input isZero +); + assign out = (imm & {32{isZero}}); +endmodule \ No newline at end of file diff --git a/PC_Calc/multiplexer.v b/PC_Calc/multiplexer.v new file mode 100644 index 0000000..a12e6a1 --- /dev/null +++ b/PC_Calc/multiplexer.v @@ -0,0 +1,74 @@ +// Inputs are 6 by 1 addresses +module mux4input +#( + parameter width = 6 +) +( +input[width-1:0] input0, input1, input2, input3, +input[1:0] address, +output[width-1:0] out +); + wire[1:0] mux [width-1:0]; + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign out = mux[address]; +endmodule + +// A 32:1 multiplexer. +module mux32to1by1 +( +output out, +input[5:0] address, +input[31:0] inputs +); + assign out = inputs[address]; +endmodule // mux32to1by1 + +module mux32to1by32 +( +output[31:0] out, +input[5:0] address, +input[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8, +input[31:0] input9, input10, input11, input12, input13, input14, input15, input16, +input[31:0] input17, input18, input19, input20, input21, input22, input23, input24, +input[31:0] input25, input26, input27, input28, input29, input30, input31 +); + + wire[31:0] mux[31:0]; // Create a 2D array of wires + assign mux[0] = input0; + assign mux[1] = input1; + assign mux[2] = input2; + assign mux[3] = input3; + assign mux[4] = input4; + assign mux[5] = input5; + assign mux[6] = input6; + assign mux[7] = input7; + assign mux[8] = input8; + assign mux[9] = input9; + assign mux[10] = input10; + assign mux[11] = input11; + assign mux[12] = input12; + assign mux[13] = input13; + assign mux[14] = input14; + assign mux[15] = input15; + assign mux[16] = input16; + assign mux[17] = input17; + assign mux[18] = input18; + assign mux[19] = input19; + assign mux[20] = input20; + assign mux[21] = input21; + assign mux[22] = input22; + assign mux[23] = input23; + assign mux[24] = input24; + assign mux[25] = input25; + assign mux[26] = input26; + assign mux[27] = input27; + assign mux[28] = input28; + assign mux[29] = input29; + assign mux[30] = input30; + assign mux[31] = input31; + assign out = mux[address]; + +endmodule // mux32to1by32S \ No newline at end of file From a274de08cfb4e40bcf9bd4f540da83e647e42a69 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:13:37 -0500 Subject: [PATCH 095/190] Implement module --- Core/Core.v | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/Core/Core.v b/Core/Core.v index 88659bc..26fb30b 100644 --- a/Core/Core.v +++ b/Core/Core.v @@ -1,18 +1,62 @@ // Core controls the central registor and memory storage and manipulation +`include "Core/ALU/alu.v" +`include "Core/memory.v" +`include "Core/regfile.v" +`include "Core/signextend.v" + module Core ( input CLK, // Decoded Instruction Values - input[5:0] Rd, Rt, Rs, + input[4:0] Rd, Rt, Rs, input[15:0] imm, input[31:0] addedPC, // Control Signals - input RegDst, RegWr, MemWr, ALUSrc, MemToReg, - + input[1:0] RegDst, + input RegWr, MemWr, ALUSrc, + input[1:0] MemToReg, + input[2:0] ALUCntrl, // Outputs output[31:0] Da, output isZero ); + wire[4:0] WriteAddr; + + // Register file write address + mux4input #(.width(5)) RegWriteAddr (Rd, Rt, 5'd31, 5'bx, RegDst, WriteAddr); + + // wire[31:0] dataaout; + wire[31:0] databout; + wire[31:0] datain; + + // Register file + regfile regfile (Da, databout, datain, Rs, Rt, WriteAddr, RegWr, CLK); + + // Sign extend + + wire[31:0] signextimm; + signextend extend (imm, signextimm); + + // ALU operand 2 mux + wire[31:0] operandb; + + mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, ALUSrc}, operandb); + + // ALU + wire cout; + wire overflow; + wire[31:0] finalsignal; + + ALUcontrolLUT aluout (cout, overflow, isZero, finalsignal, ALUCntrl, Da, operandb); + + // Regfile write data mux + wire[31:0] memout; + + mux4input #(.width(32)) regdatamux (finalsignal, memout, addedPC, 32'bx, MemToReg, datain); + + // Data Meomory + memory datamemory (CLK, memout, finalsignal, MemWr, databout); + endmodule From 5089cb60569d9a3ccef667faa95dcd5313b69af3 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:14:37 -0500 Subject: [PATCH 096/190] Update Core instantiation --- Core/Core.t.v | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 Core/Core.t.v diff --git a/Core/Core.t.v b/Core/Core.t.v new file mode 100644 index 0000000..6056f46 --- /dev/null +++ b/Core/Core.t.v @@ -0,0 +1,165 @@ +/* +Test bench for the core module of the CPU. +*/ + +`include "Core/Core.v" + +module Core_TEST(); + reg CLK; + reg [4:0] Rd; + reg [4:0] Rt; + reg [4:0] Rs; + reg [15:0] imm; + reg [31:0] addedPC; + reg [0:1] RegDst; + reg RegWr; + reg MemWr; + reg AlUSrc; + reg [1:0] MemToReg; + reg [2:0] ALUCntrl; + + wire [31:0] Da; + wire isZero; + + Core dut (CLK, Rd, Rt, Rs, imm, addedPC, RegDst, RegWr, MemWr, AlUSrc, MemToReg, ALUCntrl, Da, isZero); + + initial CLK = 0; + always #10 CLK = !CLK; + + initial begin + $dumpfile("Core/Core.vcd"); + $dumpvars(0, Core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); + + // Test Case 1: Add Imm + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd1; Rs = 5'b00000; imm = 16'b0; + #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + + // Populate the rest of the registers with data (each gets 32'b0) + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd2; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd4; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd5; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd6; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd7; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd8; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd9; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd10; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd11; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd12; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd13; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd14; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd15; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd18; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd19; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd21; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd22; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd23; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd24; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd25; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd26; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd27; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd28; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd29; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd30; Rs = 5'b00000; imm = 16'b0; + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd31; Rs = 5'b00000; imm = 16'b0; + #6000 + + + // Test Case 2: Load Word + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b01; + Rd = 5'bx; Rt = 5'b00010; Rs = 5'b00001; imm = 16'b0; + #1000 + + if (dut.databout !== dut.datamemory.memory[0]) begin + $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimm] at time %t", $time); + end + + // Test Case 3: Store Word + RegDst = 2'bx; AlUSrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUCntrl = 3'b000; MemToReg = 2'bx; + Rd = 5'bx; Rs = 5'b00001; Rt = 5'b00000; imm = 16'b0; + #1000 + + if (dut.datamemory.dataOut !== dut.databout) begin + $display("Test case 3 failed: M[R[rs] + signextendimm] != R[rt] at time %t", $time); + end + + // Test Case 4: Jump + // Test Case 5: Jump Register + // Test Case 6: Jump and Link + // Test Case 7: Branch if Not Equal + // Test Case 8: XOR Immediate + // Test Case 9: Add + // Test Case 10: Subtract + // Test Case 11: Set Less Than + #10000 + + $finish; + end +endmodule \ No newline at end of file From 2844250e3062ece607e04402271ace5c7df74269 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:14:55 -0500 Subject: [PATCH 097/190] Update file references --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 54cd1bc..2789ebf 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,8 @@ all: core alu regfile memory signextend # Core modules -core: Core/core.v Core/core.t.v - iverilog -Wall -o core Core/core.t.v +core: Core/Core.v Core/Core.t.v + iverilog -Wall -o core Core/Core.t.v # ALU modules alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor From 2a1963a9491f7c95098ed79447e4f53e5a21277d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 10:18:43 -0500 Subject: [PATCH 098/190] Remove old files that have been replaced --- Core/core.t.v | 165 -------------------------------------------------- Core/core.v | 66 -------------------- 2 files changed, 231 deletions(-) delete mode 100644 Core/core.t.v delete mode 100644 Core/core.v diff --git a/Core/core.t.v b/Core/core.t.v deleted file mode 100644 index 0ee8f25..0000000 --- a/Core/core.t.v +++ /dev/null @@ -1,165 +0,0 @@ -/* -Test bench for the core module of the CPU. -*/ - -`include "Core/core.v" - -module core_TEST(); - wire [31:0] Da; - wire is_zero; - - reg clk; - reg [4:0] rd; - reg [4:0] rt; - reg [4:0] rs; - reg [15:0] immediate; - reg [31:0] new_PC; - reg [0:1] regdst; - reg [2:0] ALUcntrl; - reg AlUsrc; - reg MemWr; - reg RegWr; - reg [1:0] MemtoReg; - - core dut (clk, rd, rt, rs, immediate, new_PC, regdst, ALUcntrl, AlUsrc, MemWr, RegWr, MemtoReg, Da, is_zero); - - initial clk = 0; - always #10 clk = !clk; - - initial begin - $dumpfile("Core/core.vcd"); - $dumpvars(0, core_TEST, dut.datamemory.memory[0], dut.datamemory.memory[1]); - - // Test Case 1: Add Immediate - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd1; rs = 5'b00000; immediate = 16'b0; - #6000 - - if (dut.databout !== 32'b0) begin - $display("Test case 1 failed: R[rt] != R[rs] + 32'b0"); - end - - // Populate the rest of the registers with data (each gets 32'b0) - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd2; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd3; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd4; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd5; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd6; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd7; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd8; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd9; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd10; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd11; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd12; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd13; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd14; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd15; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd16; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd17; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd18; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd19; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd20; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd21; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd22; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd23; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd24; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd25; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd26; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd27; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd28; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd29; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd30; rs = 5'b00000; immediate = 16'b0; - #6000 - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 1'b0; - rd =5'bx; rt = 5'd31; rs = 5'b00000; immediate = 16'b0; - #6000 - - - // Test Case 2: Load Word - regdst = 2'b01; AlUsrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUcntrl = 3'b000; MemtoReg = 2'b01; - rd = 5'bx; rt = 5'b00010; rs = 5'b00001; immediate = 16'b0; - #100 - - if (dut.databout !== dut.datamemory.memory[0]) begin - $display("Test case 2 (LW) failed: R[rt] != M[R[rs] + signextendimmediate]"); - end - - // Test Case 3: Store Word - regdst = 2'bx; AlUsrc = 1'b1; RegWr = 1'b0; MemWr = 1'b1; ALUcntrl = 3'b000; MemtoReg = 2'bx; - rd = 5'bx; rs = 5'b00001; rt = 5'b00000; immediate = 16'b0; - #100 - - if (dut.datamemory.dataOut !== dut.databout) begin - $display("Test case 3 failed: M[R[rs] + signextendimmediate] != R[rt]"); - end - - // Test Case 4: Jump - // Test Case 5: Jump Register - // Test Case 6: Jump and Link - // Test Case 7: Branch if Not Equal - // Test Case 8: XOR Immediate - // Test Case 9: Add - // Test Case 10: Subtract - // Test Case 11: Set Less Than - #10000 - - $finish; - end -endmodule \ No newline at end of file diff --git a/Core/core.v b/Core/core.v deleted file mode 100644 index f4ed3ac..0000000 --- a/Core/core.v +++ /dev/null @@ -1,66 +0,0 @@ -/* -The section of the CPU containing the register file, data memory, and ALU. -*/ - -`include "Core/ALU/alu.v" -`include "Core/memory.v" -`include "Core/regfile.v" -`include "Core/signextend.v" - -module core -( - input clk, - input [4:0] rd, - input [4:0] rt, - input [4:0] rs, - input [15:0] immediate, - input [31:0] new_PC, - input [0:1] regdst, - input [2:0] ALUcntrl, - input AlUsrc, - input MemWr, - input RegWr, - input [1:0] MemtoReg, - output [31:0] Da, - output is_zero -); - - wire[4:0] writeaddr; - - // Register file write address - mux4input #(.width(5)) regwriteaddr (rd, rt, 5'd31, 5'bx, regdst, writeaddr); - - // wire[31:0] dataaout; - wire[31:0] databout; - wire[31:0] datain; - - // Register file - regfile regfile (Da, databout, datain, rs, rt, writeaddr, RegWr, clk); - - // Sign extend - - wire[31:0] signextimm; - signextend extend (immediate, signextimm); - - // ALU operand 2 mux - wire[31:0] operandb; - - mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, AlUsrc}, operandb); - - // ALU - wire cout; - wire overflow; - wire[31:0] finalsignal; - - ALUcontrolLUT aluout (cout, overflow, is_zero, finalsignal, ALUcntrl, Da, operandb); - - // Regfile write data mux - wire[31:0] memout; - - mux4input #(.width(32)) regdatamux (finalsignal, memout, new_PC, 32'bx, MemtoReg, datain); - - // Data Meomory - memory datamemory (clk, memout, finalsignal, MemWr, databout); - - -endmodule \ No newline at end of file From fa00d5ba24406087f8921fb6dfe0909abe46f0b4 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:42:47 -0500 Subject: [PATCH 099/190] Change address size in test --- Core/multiplexer.t.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/multiplexer.t.v b/Core/multiplexer.t.v index 8f17795..ab85819 100644 --- a/Core/multiplexer.t.v +++ b/Core/multiplexer.t.v @@ -145,7 +145,7 @@ module mux32to32by1Test( // Test Case 1: // Ensure that the value chosen by the mux matches the value at the given address - address = 4'd20; + address = 5'd20; input0 = 32'd0; input1 = 32'd1; input2 = 32'd2; input3 = 32'd3; input4 = 32'd4; input5 = 32'd5; input6 = 32'd6; input7 = 32'd7; input8 = 32'd8; input9 = 32'd9; input10 = 32'd10; input11 = 32'd11; input12 = 32'd12; input13 = 32'd13; input14 = 32'd14; From f1a4d56ec2720d755a7e64426043c8682db515b6 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:44:05 -0500 Subject: [PATCH 100/190] Change size of 2d array to correct width --- Core/multiplexer.v | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/multiplexer.v b/Core/multiplexer.v index f38b85f..a4f1220 100644 --- a/Core/multiplexer.v +++ b/Core/multiplexer.v @@ -8,11 +8,11 @@ input[width-1:0] input0, input1, input2, input3, input[1:0] address, output[width-1:0] out ); - wire[1:0] mux [width-1:0]; - assign mux[0] = input0; - assign mux[1] = input1; - assign mux[2] = input2; - assign mux[3] = input3; + wire[5:0] mux [width-1:0]; + assign mux[0] = input0[width-1:0]; + assign mux[1] = input1[width-1:0]; + assign mux[2] = input2[width-1:0]; + assign mux[3] = input3[width-1:0]; assign out = mux[address]; endmodule From 3b9149426b350915bb6e4d18a8a9f31228a7501b Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:45:25 -0500 Subject: [PATCH 101/190] Add build rules for new modules --- makefile | 56 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/makefile b/makefile index 2789ebf..2fa4be9 100644 --- a/makefile +++ b/makefile @@ -1,51 +1,73 @@ all: core alu regfile memory signextend -# Core modules -core: Core/Core.v Core/Core.t.v - iverilog -Wall -o core Core/Core.t.v +### PC Modules + +### PC_Calc Modules +# PC_Calc top level module +PC_Calc: PC_Calc/PC_Calc.v addr_concat imm_concat is_zero_and + iverilog -Wall -o PC_Calc/PC_Calc PC_Calc.v + +addr_concat: PC_Calc/addr_concat.v PC_Calc/addr_concat.t.v + iverilog -Wall -o PC_Calc/addr_concat addr_concat.t.v + +imm_concat: PC_Calc/imm_concat.v PC_Calc/imm_concat.t.v + iverilog -Wall -o PC_Calc/imm_concat imm_concat.t.v + +is_zero_and: PC_Calc/is_zero_and.v PC_Calc/is_zero_and.t.v + iverilog -Wall -o PC_Calc/is_zero_and is_zero_and.t.v + +### Instruction Parser Modules +# Instruction Parser top level module +Instruction_Parser: Instruction_Parser.v + iverilog -Wall -o Instruction_Parser/Instruction_Parser Instruction_Parser.v + +### Core Modules +# Core top level module +core: Core/Core.v Core/Core.t.v regfile + iverilog -Wall -o Core/core Core/Core.t.v # ALU modules alu: Core/ALU/alu.v Core/ALU/alu.t.v adder_subtracter and nand nor or slt xor - iverilog -Wall -o alu Core/ALU/alu.t.v + iverilog -Wall -o Core/ALU/alu Core/ALU/alu.t.v adder_subtracter: Core/ALU/adder_subtracter.v Core/ALU/adder_subtracter.t.v - iverilog -Wall -o adder_subtracter Core/ALU/adder_subtracter.t.v + iverilog -Wall -o Core/ALU/adder_subtracter Core/ALU/adder_subtracter.t.v and: Core/ALU/and_32bit.v Core/ALU/and_32bit.t.v - iverilog -Wall -o and Core/ALU/and_32bit.t.v + iverilog -Wall -o Core/ALU/and Core/ALU/and_32bit.t.v nand: Core/ALU/nand_32bit.v Core/ALU/nand_32bit.t.v - iverilog -Wall -o nand Core/ALU/nand_32bit.t.v + iverilog -Wall -o Core/ALU/nand Core/ALU/nand_32bit.t.v nor: Core/ALU/nor_32bit.v Core/ALU/nor_32bit.t.v - iverilog -Wall -o nor Core/ALU/nor_32bit.t.v + iverilog -Wall -o Core/ALU/nor Core/ALU/nor_32bit.t.v or: Core/ALU/or_32bit.v Core/ALU/or_32bit.t.v - iverilog -Wall -o or Core/ALU/or_32bit.t.v + iverilog -Wall -o Core/ALU/or Core/ALU/or_32bit.t.v slt: Core/ALU/slt.v Core/ALU/slt.t.v - iverilog -Wall -o slt Core/ALU/slt.t.v + iverilog -Wall -o Core/ALU/slt Core/ALU/slt.t.v xor: Core/ALU/xor_32bit.v Core/ALU/xor_32bit.t.v - iverilog -Wall -o xor Core/ALU/xor_32bit.t.v + iverilog -Wall -o Core/ALU/xor Core/ALU/xor_32bit.t.v # Regfile modules regfile: Core/regfile.t.v Core/regfile.v decoder mux register - iverilog -Wall -o regfile Core/regfile.t.v + iverilog -Wall -o Core/regfile Core/regfile.t.v decoder: Core/decoders.t.v Core/decoders.v - iverilog -Wall -o decoder Core/decoders.t.v + iverilog -Wall -o Core/decoder Core/decoders.t.v mux: Core/multiplexer.t.v Core/multiplexer.v - iverilog -Wall -o mux Core/multiplexer.t.v + iverilog -Wall -o Core/mux Core/multiplexer.t.v register: Core/register.t.v Core/register.v - iverilog -Wall -o register Core/register.t.v + iverilog -Wall -o Core/register Core/register.t.v # Memory modules memory: Core/memory.v Core/memory.t.v - iverilog -Wall -o memory Core/memory.t.v + iverilog -Wall -o Core/memory Core/memory.t.v # Concatenation modules signextend: Core/signextend.v - iverilog -Wall -o signextend Core/signextend.v + iverilog -Wall -o Core/signextend Core/signextend.v From 8947a7f02c68548a6579a0c490739e01f9a84681 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sat, 11 Nov 2017 19:45:38 -0500 Subject: [PATCH 102/190] Add remaining tests --- Core/Core.t.v | 283 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 274 insertions(+), 9 deletions(-) diff --git a/Core/Core.t.v b/Core/Core.t.v index 6056f46..c5f83cf 100644 --- a/Core/Core.t.v +++ b/Core/Core.t.v @@ -43,94 +43,242 @@ module Core_TEST(); RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd2; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd4; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd5; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd6; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd7; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd8; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd9; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd10; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd11; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd12; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd13; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd14; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd15; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd18; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd19; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd21; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd22; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd23; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd24; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd25; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd26; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd27; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd28; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd29; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd30; Rs = 5'b00000; imm = 16'b0; #6000 + + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; Rd =5'bx; Rt = 5'd31; Rs = 5'b00000; imm = 16'b0; #6000 + if (dut.databout !== 32'b0) begin + $display("Test case 1 failed: R[rt] != R[rs] + 32'b0 at time %t", $time); + end // Test Case 2: Load Word RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b01; @@ -150,15 +298,132 @@ module Core_TEST(); $display("Test case 3 failed: M[R[rs] + signextendimm] != R[rt] at time %t", $time); end - // Test Case 4: Jump - // Test Case 5: Jump Register - // Test Case 6: Jump and Link - // Test Case 7: Branch if Not Equal - // Test Case 8: XOR Immediate - // Test Case 9: Add - // Test Case 10: Subtract - // Test Case 11: Set Less Than - #10000 + // Test Case 4: Jump and Link + RegDst = 2'b10; AlUSrc = 1'bx; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'bx; MemToReg = 2'b10; + Rd = 5'bx; Rs = 5'd31; Rt = 5'bx; imm = 16'bx; addedPC = 5'd25; + #1000 + + if (Da !== addedPC) begin + $display("Test case 4 failed: PC value not saved to correct register at time %t", $time); + end + + #1000 + + // Test Case 5: Branch if Not Equal + // Load Immediate into registers 16 and 17 so that they are not equal. + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'd16; // R[16] = 0 + 16 = 16 + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'd17; // R[17] = 0 + 17 = 17 + #6000 + + RegDst = 2'bx; AlUSrc = 1'b0; RegWr = 1'b0; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'bx; + Rd = 5'dx; Rs = 5'd16; Rt = 5'd17; imm = 16'bx; + #6000 + + if (dut.regfile.register16out === dut.regfile.register17out) begin + $display("Error: R[rs] should not equal R[rt]"); + end + + if (isZero === 1'b1) begin + $display("Test case 5 failed: R[Rs] == R[Rt] indicated, but these values are not equal at time %t", $time); + end + + // Load Immediate into registers 16 and 17 so that they are equal. + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd16; Rs = 5'b00000; imm = 16'd15; // R[16] = 0 + 15 = 15 + #6000 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'd15; // R[17] = 0 + 15 = 15 + #6000 + + RegDst = 2'bx; AlUSrc = 1'b0; RegWr = 1'b0; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'bx; + Rd = 5'dx; Rs = 5'd16; Rt = 5'd17; imm = 16'bx; + #6000 + + if (dut.regfile.register16out !== dut.regfile.register17out) begin + $display("Error: R[rs] should equal R[rt]"); + end + + if (isZero === 1'b0) begin + $display("Test case 5 failed: R[Rs] != R[Rt] indicated, but these values are equal at time %t", $time); + end + + // Test Case 6: XOR Immediate + // Load Immediate into register 17 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd17; Rs = 5'b00000; imm = 16'h00005555; + #6000 + + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b010; MemToReg = 2'b0; + Rd = 5'dx; Rs = 5'd17; Rt = 5'd16; imm = 16'h00005555; + #6000 + + if (dut.databout != 32'b0) begin + $display("Test case 6 failed: R[Rs] == signextendimm and R[Rs] XOR signextendimm != 32'b0 at time %t", $time); + end + + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b010; MemToReg = 2'b0; + Rd = 5'dx; Rs = 5'd17; Rt = 5'd16; imm = 16'h0000aaaa; + #6000 + + if (dut.databout != 32'h0000003f) begin + $display("Test case 6 failed: R[Rs] != signextendimm and R[Rs] XOR signextendimm != 32'h0000ffff at time %t", $time); + end + + // Test Case 7: Add + // Load Immediate into register 20 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd20; Rs = 5'b00000; imm = 16'd25; + #6000 + + // Load Immediate into register 3 + RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; + Rd =5'bx; Rt = 5'd3; Rs = 5'b00000; imm = 16'd19; + #6000 + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'd44) begin + $display("Test case 7 failed: R[Rd] != R[Rs] + R[Rt] at time %t", $time); + end + + // Test Case 8: Subtract + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b001; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'd6) begin + $display("Test case 8 failed: R[Rd] != R[Rs] - R[Rt] at time %t", $time); + end + + // Test Case 9: Set Less Than + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd3; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b0) begin + $display("Test case 9 failed: R[Rd] is not zero, but R[Rs] !< R[Rt] at time %t", $time); + end + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd3; Rt = 5'd20; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b1) begin + $display("Test case 9 failed: R[Rd] is not one, but R[Rs] < R[Rt] at time %t", $time); + end + + RegDst = 2'b0; AlUSrc = 1'b0; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b011; MemToReg = 2'b0; + Rd = 5'd5; Rs = 5'd20; Rt = 5'd20; imm = 16'bx; + #6000 + + if (dut.regfile.register5out !== 32'b0) begin + $display("Test case 9 failed: R[Rd] is not zero, but R[Rs] == R[Rt] at time %t", $time); + end $finish; end From 9045aca4a8993aa3bcc54fa3be462118a7b15a70 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 18:41:43 -0500 Subject: [PATCH 103/190] Add absolute position of modules --- Instruction_Parser/Instruction_Parser.v | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index df4611d..256193d 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -1,8 +1,8 @@ // Instruction Parser parses the relevant data and control signals from the instruction. -`include "Memory.v" -`include "Decoder.v" -`include "Controller.v" +`include "Instruction_Parser/Memory.v" +`include "Instruction_Parser/Decoder.v" +`include "Instruction_Parser/Controller.v" module InstructionParser ( @@ -16,7 +16,7 @@ module InstructionParser output MemWr, ALUSrc, RegWr, AddSel ); wire[31:0] instr; - Memory InstructionMemory(.Addr(PC[9:0]), .DataOut(instr)); + InstructionMemory im(.Addr(PC[9:0]), .DataOut(instr)); wire[5:0] Op, funct; wire[4:0] Rs, Rd, Rt; From ac5ec576fcce2df25a57eaf58bcc2ff060304a01 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 18:47:01 -0500 Subject: [PATCH 104/190] Make it so mem does not reference backwards --- Instruction_Parser/Memory.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Instruction_Parser/Memory.v b/Instruction_Parser/Memory.v index f5c9d54..1535d17 100644 --- a/Instruction_Parser/Memory.v +++ b/Instruction_Parser/Memory.v @@ -17,7 +17,7 @@ module Memory end // This file will be loaded dynamically. Do not edit mem.dat directly. - initial $readmemh("../mem.dat", mem); + initial $readmemh("mem.dat", mem); assign DataOut = mem[Addr]; endmodule From 94d7a19bfad07e3066c192ab5f150bf55014b862 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 19:03:41 -0500 Subject: [PATCH 105/190] Make top level directory run (sort of) --- CPU.v | 8 +++++--- PC_Calc/PC_Calc.v | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CPU.v b/CPU.v index 26b920c..7c1f1eb 100644 --- a/CPU.v +++ b/CPU.v @@ -15,11 +15,13 @@ module CPU DFF #(32) pc(.trigger(CLK), .enable(1), .q(new_PC), .d(PC)); - wire[5:0] Rs, Rd, Rt; + wire[4:0] Rs, Rd, Rt; wire[15:0] imm; wire[25:0] addr; - wire ALUCtrl, MemToReg, MemWr, ALUSrc, PCSel, RegDst, RegWr, AddSel; - Instruction_Parser ip( + wire[2:0] ALUCtrl; + wire[1:0] MemToReg, RegDst, PCSel; + wire MemWr, ALUSrc, RegWr, AddSel; + InstructionParser ip( .PC(PC), .Rs(Rs), .Rd(Rd), .Rt(Rt), .imm(imm), .addr(addr), diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index 3c0cf46..67bfd9a 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -1,6 +1,6 @@ // PC_Calc Calculates the next program counter -`include "addr_concat.v" -`include "imm_concat.v" +`include "PC_Calc/addr_concat.v" +`include "PC_Calc/imm_concat.v" module PC_Calc ( @@ -16,7 +16,7 @@ module PC_Calc immConcat iconcat(extendedImm[31:0], imm[15:0]); wire immZeroed; - + endmodule From 9e889350473c4cbf162f95928f8e5fdf066b3a54 Mon Sep 17 00:00:00 2001 From: apan64 Date: Sun, 12 Nov 2017 19:31:07 -0500 Subject: [PATCH 106/190] pc calc and test --- PC_Calc/PC_Calc.t.v | 41 +++++++++++++++++++++++++++++++++++++++++ PC_Calc/PC_Calc.v | 27 +++++++++++++++++++++++---- PC_Calc/addr_concat.t.v | 3 +++ PC_Calc/addr_concat.v | 2 +- PC_Calc/multiplexer.v | 28 +++++++++++++++++++++------- 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 PC_Calc/PC_Calc.t.v diff --git a/PC_Calc/PC_Calc.t.v b/PC_Calc/PC_Calc.t.v new file mode 100644 index 0000000..3f334e5 --- /dev/null +++ b/PC_Calc/PC_Calc.t.v @@ -0,0 +1,41 @@ +`timescale 1 ns / 1 ps +`include "PC_Calc.v" + +module testPCCalc(); + reg[31:0] old_PC; + reg isZero; + reg[1:0] PCSel; + reg AddSel; + reg[31:0] Da; + reg[25:0] addr; + reg[15:0] imm; + wire[31:0] added_PC; + wire[31:0] new_PC; + + wire[31:0] addedSel; + wire[31:0] jump; + + PC_Calc pccalc(old_PC[31:0], isZero, PCSel[1:0], AddSel, Da[31:0], addr[25:0], imm[15:0], added_PC[31:0], new_PC[31:0], addedSel[31:0], jump[31:0]); + initial begin + $display("added_PC | new_PC"); + old_PC = 32'd4; + isZero = 0; + PCSel = 0; + AddSel = 0; + Da = 32'd16; + addr = 26'd12; + imm = 16'd10; #1000 + $display("expected 8 and 48"); + $display("%b | %b", added_PC, new_PC); + + old_PC = 32'b01010000000000000000000000000000; + isZero = 0; + PCSel = 0; + AddSel = 0; + Da = 32'd16; + addr = 26'd12; + imm = 16'd10; #1000 + $display("expected 01010000000000000000000000000100 and 01010000000000000000000000110000"); + $display("%b | %b", added_PC, new_PC); + end +endmodule \ No newline at end of file diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index 3c0cf46..1b39107 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -1,22 +1,41 @@ // PC_Calc Calculates the next program counter `include "addr_concat.v" `include "imm_concat.v" +`include "is_zero_and.v" +`include "multiplexer.v" module PC_Calc ( input[31:0] old_PC, input isZero, - input PCSel, AddSel, + input[1:0] PCSel, + input AddSel, input[31:0] Da, input[25:0] addr, input[15:0] imm, - output[31:0] added_PC + output[31:0] added_PC, + output[31:0] new_PC, + output[31:0] addedSel, + output[31:0] jump ); wire[31:0] extendedImm; immConcat iconcat(extendedImm[31:0], imm[15:0]); - wire immZeroed; - + wire[31:0] immZeroed; + wire nIsZero; + not inviszero(nIsZero, isZero); + isZeroAnd immzeroed(immZeroed[31:0], extendedImm[31:0], nIsZero); + wire[31:0] immZeroed4; + assign immZeroed4 = immZeroed + 4; + wire[31:0] addedSel; + mux2input m2(32'd4, immZeroed4[31:0], AddSel, addedSel[31:0]); + + assign added_PC = addedSel + old_PC; + + wire[31:0] jump; + addrConcat addrconcat(jump[31:0], added_PC[31:0], addr[25:0]); + + mux4input m4(jump[31:0], added_PC[31:0], Da[31:0], 32'd0, PCSel[1:0], new_PC[31:0]); endmodule diff --git a/PC_Calc/addr_concat.t.v b/PC_Calc/addr_concat.t.v index 8981074..4cff68e 100644 --- a/PC_Calc/addr_concat.t.v +++ b/PC_Calc/addr_concat.t.v @@ -14,5 +14,8 @@ module testConcat(); pc = 32'b11110000000000000000000000000000; jumpAddr = 26'b11111111111111111111111111; #100 $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); + pc = 32'b00000000000000000000000000000000; + jumpAddr = 26'b11111111111111111111111111; #100 + $display("%b %b %b", pc[31:0], jumpAddr[25:0], ans[31:0]); end endmodule \ No newline at end of file diff --git a/PC_Calc/addr_concat.v b/PC_Calc/addr_concat.v index e2301a0..d7e0d6d 100644 --- a/PC_Calc/addr_concat.v +++ b/PC_Calc/addr_concat.v @@ -4,5 +4,5 @@ module addrConcat input[31:0] pc, input[25:0] jumpAddr ); - assign out = {pc[31:28], jumpAddr, 2'b00}; + assign out = {pc[31:28], jumpAddr[25:0], 2'b00}; endmodule \ No newline at end of file diff --git a/PC_Calc/multiplexer.v b/PC_Calc/multiplexer.v index a12e6a1..0ba2560 100644 --- a/PC_Calc/multiplexer.v +++ b/PC_Calc/multiplexer.v @@ -1,18 +1,32 @@ -// Inputs are 6 by 1 addresses +module mux2input +#( + parameter width = 32 +) +( +input[width-1:0] input0, input1, +input address, +output[width-1:0] out +); + wire[width - 1:0] mux [width-1:0]; + assign mux[0] = input0[width-1:0]; + assign mux[1] = input1[width-1:0]; + assign out = mux[address]; +endmodule + module mux4input #( - parameter width = 6 + parameter width = 32 ) ( input[width-1:0] input0, input1, input2, input3, input[1:0] address, output[width-1:0] out ); - wire[1:0] mux [width-1:0]; - assign mux[0] = input0; - assign mux[1] = input1; - assign mux[2] = input2; - assign mux[3] = input3; + wire[width - 1:0] mux [width-1:0]; + assign mux[0] = input0[width-1:0]; + assign mux[1] = input1[width-1:0]; + assign mux[2] = input2[width-1:0]; + assign mux[3] = input3[width-1:0]; assign out = mux[address]; endmodule From 7b0b78f69f30e4f7955918dce79196c79feef615 Mon Sep 17 00:00:00 2001 From: apan64 Date: Sun, 12 Nov 2017 19:35:04 -0500 Subject: [PATCH 107/190] removed merge heads --- PC_Calc/PC_Calc.v | 5 ----- 1 file changed, 5 deletions(-) diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index eb0fae9..8be7350 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -22,15 +22,10 @@ module PC_Calc wire[31:0] extendedImm; immConcat iconcat(extendedImm[31:0], imm[15:0]); -<<<<<<< HEAD wire[31:0] immZeroed; wire nIsZero; not inviszero(nIsZero, isZero); isZeroAnd immzeroed(immZeroed[31:0], extendedImm[31:0], nIsZero); -======= - wire immZeroed; - ->>>>>>> 94d7a19bfad07e3066c192ab5f150bf55014b862 wire[31:0] immZeroed4; assign immZeroed4 = immZeroed + 4; From 89966866129f50665d6d7665c95ac1b809253987 Mon Sep 17 00:00:00 2001 From: apan64 Date: Sun, 12 Nov 2017 19:39:20 -0500 Subject: [PATCH 108/190] moved mux to submodules --- Core/regfile.v | 2 +- PC_Calc/PC_Calc.v | 6 +++--- {PC_Calc => submodules}/multiplexer.v | 28 ++++++++++++++++++++++----- 3 files changed, 27 insertions(+), 9 deletions(-) rename {PC_Calc => submodules}/multiplexer.v (81%) diff --git a/Core/regfile.v b/Core/regfile.v index 0bc8f4b..cbd27a2 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -7,7 +7,7 @@ //------------------------------------------------------------------------------ `include "Core/register.v" -`include "Core/multiplexer.v" +`include "submodules/multiplexer.v" `include "Core/decoders.v" module regfile diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index 8be7350..2634848 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -3,7 +3,7 @@ `include "PC_Calc/addr_concat.v" `include "PC_Calc/imm_concat.v" `include "PC_Calc/is_zero_and.v" -`include "PC_Calc/multiplexer.v" +`include "submodules/multiplexer.v" module PC_Calc ( @@ -31,12 +31,12 @@ module PC_Calc assign immZeroed4 = immZeroed + 4; wire[31:0] addedSel; - mux2input m2(32'd4, immZeroed4[31:0], AddSel, addedSel[31:0]); + mux2by32input m2(32'd4, immZeroed4[31:0], AddSel, addedSel[31:0]); assign added_PC = addedSel + old_PC; wire[31:0] jump; addrConcat addrconcat(jump[31:0], added_PC[31:0], addr[25:0]); - mux4input m4(jump[31:0], added_PC[31:0], Da[31:0], 32'd0, PCSel[1:0], new_PC[31:0]); + mux4by32input m4(jump[31:0], added_PC[31:0], Da[31:0], 32'd0, PCSel[1:0], new_PC[31:0]); endmodule diff --git a/PC_Calc/multiplexer.v b/submodules/multiplexer.v similarity index 81% rename from PC_Calc/multiplexer.v rename to submodules/multiplexer.v index 0ba2560..2fd8a90 100644 --- a/PC_Calc/multiplexer.v +++ b/submodules/multiplexer.v @@ -1,4 +1,4 @@ -module mux2input +module mux2by32input #( parameter width = 32 ) @@ -13,7 +13,7 @@ output[width-1:0] out assign out = mux[address]; endmodule -module mux4input +module mux4by32input #( parameter width = 32 ) @@ -30,11 +30,29 @@ output[width-1:0] out assign out = mux[address]; endmodule +// Inputs are 6 by 1 addresses +module mux4input +#( + parameter width = 6 +) +( +input[width-1:0] input0, input1, input2, input3, +input[1:0] address, +output[width-1:0] out +); + wire[5:0] mux [width-1:0]; + assign mux[0] = input0[width-1:0]; + assign mux[1] = input1[width-1:0]; + assign mux[2] = input2[width-1:0]; + assign mux[3] = input3[width-1:0]; + assign out = mux[address]; +endmodule + // A 32:1 multiplexer. module mux32to1by1 ( output out, -input[5:0] address, +input[4:0] address, input[31:0] inputs ); assign out = inputs[address]; @@ -43,7 +61,7 @@ endmodule // mux32to1by1 module mux32to1by32 ( output[31:0] out, -input[5:0] address, +input[4:0] address, input[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8, input[31:0] input9, input10, input11, input12, input13, input14, input15, input16, input[31:0] input17, input18, input19, input20, input21, input22, input23, input24, @@ -85,4 +103,4 @@ input[31:0] input25, input26, input27, input28, input29, input30, input31 assign mux[31] = input31; assign out = mux[address]; -endmodule // mux32to1by32S \ No newline at end of file +endmodule // mux32to1by32 \ No newline at end of file From 6c90c5171a63623a80e39aa556c397a3ef145f3a Mon Sep 17 00:00:00 2001 From: apan64 Date: Sun, 12 Nov 2017 19:43:10 -0500 Subject: [PATCH 109/190] fixed mux overlap --- Core/multiplexer.t.v | 165 ------------------------------------------- Core/multiplexer.v | 74 ------------------- PC_Calc/PC_Calc.v | 1 - makefile | 4 +- 4 files changed, 2 insertions(+), 242 deletions(-) delete mode 100644 Core/multiplexer.t.v delete mode 100644 Core/multiplexer.v diff --git a/Core/multiplexer.t.v b/Core/multiplexer.t.v deleted file mode 100644 index ab85819..0000000 --- a/Core/multiplexer.t.v +++ /dev/null @@ -1,165 +0,0 @@ -//-------------------------------- -// Test the multiplexer modules. -//-------------------------------- - -`include "Core/multiplexer.v" - -// Test harness for multiplexer unit test modules. -module multiplexerTestBenchHarness(); - reg begintest0; - reg begintest1; - wire endtest0; - wire endtest1; - wire dutpassed0; - wire dutpassed1; - - mux32to1by1Test test0 (begintest0, endtest0, dutpassed0); - mux32to32by1Test test1 (begintest1, endtest1, dutpassed1); - - initial begin - begintest0 = 0; - begintest1 = 0; - #10; - begintest0 = 1; - begintest1 = 1; - #1000; - end - - always @(posedge endtest0 && endtest1) begin - if (dutpassed0 == 1 || dutpassed1 == 1) begin - $display("All multiplexer tests passed."); - end - end - -endmodule // multiplexerTestBenchHarness - -// Unit test the 32:1 mux module. -module mux32to1by1Test - ( - input begintest, - output reg endtest, - output reg dutpassed - ); - wire out; - reg[4:0] address; - reg[31:0] inputs; - - mux32to1by1 DUT (out, address, inputs); - - always @(posedge begintest) begin - endtest = 0; - dutpassed = 1; - - // Test Case 1: - // Ensure that out is the same as the bit of the input at the - // given address. - inputs = 32'h000FFF; address = 5'd9; - if (out != 1) begin - $display("32:1 mux Test Case 1 Failed."); - dutpassed = 0; - end - - #5 - endtest = 1; - end -endmodule // mux32to1by1Test - -module mux4inputTest - ( - input begintest, - output reg endtest, - output reg dutpassed - ); - - reg[5:0] input0, input1, input2, input3; - reg[1:0] address; - wire[5:0] out; - - mux4input #(.width(6)) DUT (input0, input1, input2, input3, address, out); - - always @(posedge begintest) begin - endtest = 0; - dutpassed = 1; - - // Test Case 1: - // Ensure that the value chosen by the mux matches - // the value at the given address. - input0 = 6'd1; - input1 = 6'd2; - input2 = 6'd3; - input3 = 6'd4; - address = 2'd0; - #5 - if (out != input0) begin - $display("3 wide 6 deep mux test case 1 failed at address 00."); - dutpassed = 0; - end - - address = 2'd1; - #5 - if (out != input1) begin - $display("3 wide 6 deep mux test case 1 failed at address 01."); - dutpassed = 0; - end - - address = 2'd2; - #5 - if (out != input2) begin - $display("3 wide 6 deep mux test case 1 failed at address 10."); - dutpassed = 0; - end - - address = 2'd3; - #5 - if (out != input2) begin - $display("3 wide 6 deep mux test case 1 failed at address 11."); - dutpassed = 0; - end - - #5 - endtest = 1; - end -endmodule - -// Unit test the 32 wide 32 deep mux module. -module mux32to32by1Test( - input begintest, - output reg endtest, - output reg dutpassed - ); - wire[31:0] out; - reg[4:0] address; - reg[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8; - reg[31:0] input9, input10, input11, input12, input13, input14, input15, input16; - reg[31:0] input17, input18, input19, input20, input21, input22, input23, input24; - reg[31:0] input25, input26, input27, input28, input29, input30, input31; - - mux32to1by32 DUT (out, address, input0, input1, input2, input3, input4, input5, - input6, input7, input8, input9, input10, input11, input12, input13, input14, - input15, input16, input17, input18, input19, input20, input21, input22, input23, - input24, input25, input26, input27, input28, input29, input30, input31); - - always @(posedge begintest) begin - endtest = 0; - dutpassed = 1; - - // Test Case 1: - // Ensure that the value chosen by the mux matches the value at the given address - address = 5'd20; - input0 = 32'd0; input1 = 32'd1; input2 = 32'd2; input3 = 32'd3; input4 = 32'd4; - input5 = 32'd5; input6 = 32'd6; input7 = 32'd7; input8 = 32'd8; input9 = 32'd9; - input10 = 32'd10; input11 = 32'd11; input12 = 32'd12; input13 = 32'd13; input14 = 32'd14; - input15 = 32'd15; input16 = 32'd16; input17 = 32'd17; input18 = 32'd18; input19 = 32'd19; - input20 = 32'd20; input21 = 32'd21; input22 = 32'd22; input23 = 32'd23; input24 = 32'd24; - input25 = 32'd25; input26 = 32'd26; input27 = 32'd27; input28 = 32'd28; input29 = 32'd29; - input30 = 32'd30; input31 = 32'd31; - if (out != 20) begin - $display("32 wide 32 deep mux Test Case 1 failed"); - dutpassed = 0; - end - - #5 - endtest = 1; - end -endmodule // mux32to32by1Test - diff --git a/Core/multiplexer.v b/Core/multiplexer.v deleted file mode 100644 index a4f1220..0000000 --- a/Core/multiplexer.v +++ /dev/null @@ -1,74 +0,0 @@ -// Inputs are 6 by 1 addresses -module mux4input -#( - parameter width = 6 -) -( -input[width-1:0] input0, input1, input2, input3, -input[1:0] address, -output[width-1:0] out -); - wire[5:0] mux [width-1:0]; - assign mux[0] = input0[width-1:0]; - assign mux[1] = input1[width-1:0]; - assign mux[2] = input2[width-1:0]; - assign mux[3] = input3[width-1:0]; - assign out = mux[address]; -endmodule - -// A 32:1 multiplexer. -module mux32to1by1 -( -output out, -input[4:0] address, -input[31:0] inputs -); - assign out = inputs[address]; -endmodule // mux32to1by1 - -module mux32to1by32 -( -output[31:0] out, -input[4:0] address, -input[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8, -input[31:0] input9, input10, input11, input12, input13, input14, input15, input16, -input[31:0] input17, input18, input19, input20, input21, input22, input23, input24, -input[31:0] input25, input26, input27, input28, input29, input30, input31 -); - - wire[31:0] mux[31:0]; // Create a 2D array of wires - assign mux[0] = input0; - assign mux[1] = input1; - assign mux[2] = input2; - assign mux[3] = input3; - assign mux[4] = input4; - assign mux[5] = input5; - assign mux[6] = input6; - assign mux[7] = input7; - assign mux[8] = input8; - assign mux[9] = input9; - assign mux[10] = input10; - assign mux[11] = input11; - assign mux[12] = input12; - assign mux[13] = input13; - assign mux[14] = input14; - assign mux[15] = input15; - assign mux[16] = input16; - assign mux[17] = input17; - assign mux[18] = input18; - assign mux[19] = input19; - assign mux[20] = input20; - assign mux[21] = input21; - assign mux[22] = input22; - assign mux[23] = input23; - assign mux[24] = input24; - assign mux[25] = input25; - assign mux[26] = input26; - assign mux[27] = input27; - assign mux[28] = input28; - assign mux[29] = input29; - assign mux[30] = input30; - assign mux[31] = input31; - assign out = mux[address]; - -endmodule // mux32to1by32 \ No newline at end of file diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index 2634848..2f316e9 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -3,7 +3,6 @@ `include "PC_Calc/addr_concat.v" `include "PC_Calc/imm_concat.v" `include "PC_Calc/is_zero_and.v" -`include "submodules/multiplexer.v" module PC_Calc ( diff --git a/makefile b/makefile index 2fa4be9..d5654f7 100644 --- a/makefile +++ b/makefile @@ -58,8 +58,8 @@ regfile: Core/regfile.t.v Core/regfile.v decoder mux register decoder: Core/decoders.t.v Core/decoders.v iverilog -Wall -o Core/decoder Core/decoders.t.v -mux: Core/multiplexer.t.v Core/multiplexer.v - iverilog -Wall -o Core/mux Core/multiplexer.t.v +# mux: Core/multiplexer.t.v Core/multiplexer.v +# iverilog -Wall -o Core/mux Core/multiplexer.t.v register: Core/register.t.v Core/register.v iverilog -Wall -o Core/register Core/register.t.v From b8e0478fb41702bbf53faa27f54a02d97abb332f Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sun, 12 Nov 2017 19:44:11 -0500 Subject: [PATCH 110/190] Register no longer give warning --- Core/register.v | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/Core/register.v b/Core/register.v index 4a02d05..60616da 100644 --- a/Core/register.v +++ b/Core/register.v @@ -21,28 +21,52 @@ module register32 ( output [31:0] q, input[31:0] d, -input wrenable, +input wrenable, input clk ); - genvar i; - for (i = 0; i < 32; i = i + 1) begin - register singleRegister (q[i], d[i], wrenable, clk); - end + register r0 (q[0], d[0], wrenable, clk); + register r1 (q[1], d[1], wrenable, clk); + register r2 (q[2], d[2], wrenable, clk); + register r3 (q[3], d[3], wrenable, clk); + register r4 (q[4], d[4], wrenable, clk); + register r5 (q[5], d[5], wrenable, clk); + register r6 (q[6], d[6], wrenable, clk); + register r7 (q[7], d[7], wrenable, clk); + register r8 (q[8], d[8], wrenable, clk); + register r9 (q[9], d[9], wrenable, clk); + register r10 (q[10], d[10], wrenable, clk); + register r12 (q[12], d[12], wrenable, clk); + register r13 (q[13], d[13], wrenable, clk); + register r14 (q[14], d[14], wrenable, clk); + register r15 (q[15], d[15], wrenable, clk); + register r16 (q[16], d[16], wrenable, clk); + register r17 (q[17], d[17], wrenable, clk); + register r18 (q[18], d[18], wrenable, clk); + register r19 (q[19], d[19], wrenable, clk); + register r20 (q[20], d[20], wrenable, clk); + register r21 (q[21], d[21], wrenable, clk); + register r22 (q[22], d[22], wrenable, clk); + register r23 (q[23], d[23], wrenable, clk); + register r24 (q[24], d[24], wrenable, clk); + register r25 (q[25], d[25], wrenable, clk); + register r26 (q[26], d[26], wrenable, clk); + register r27 (q[27], d[27], wrenable, clk); + register r28 (q[28], d[28], wrenable, clk); + register r29 (q[29], d[29], wrenable, clk); + register r31 (q[31], d[31], wrenable, clk); endmodule // register32 + // 1 bit register with constant output 0. // Inputs are ignored. -module register32zero +module register32zero ( output [31:0] q, input[31:0] d, -input wrenable, +input wrenable, input clk ); - genvar i; - for (i = 0; i < 32; i = i + 1) begin - assign q[i] = 1'b0; - end -endmodule // register32zero \ No newline at end of file + assign q = 0; +endmodule // register32zero From 24d1c33226ddf3d102181aed29c84e73f613ab16 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 20:00:35 -0500 Subject: [PATCH 111/190] Add fibonacci program --- AssemblyPrograms/fibonacci.asm | 133 +++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 AssemblyPrograms/fibonacci.asm diff --git a/AssemblyPrograms/fibonacci.asm b/AssemblyPrograms/fibonacci.asm new file mode 100644 index 0000000..5025861 --- /dev/null +++ b/AssemblyPrograms/fibonacci.asm @@ -0,0 +1,133 @@ + +# Function call example: recursive Fibonacci + +main: +# Set up arguments for call to fib_test +addi $a0, $zero, 4 # arg0 = 4 +addi $a1, $zero, 10 # arg1 = 10 +jal fib_test + +# Print result +add $a0, $zero, $v0 # Copy result into argument register a0 +jal print_result + +# Jump to "exit", rather than falling through to subroutines +j program_end + +#------------------------------------------------------------------------------ +# Fibonacci test function. Equivalent C code: +# int fib_test(arg0, arg1) { +# return Fibonacci(arg0) + Fibonacci(arg1); +# } +# By MIPS calling convention, expects arguments in +# registers a0 and a1, and returns result in register v0. +fib_test: +# We will use s0 and s1 registers in this function, plus the ra register +# to return at the end. Save them to stack in case caller was using them. +addi $sp, $sp, -12 # Allocate three words on stack at once for three pushes +sw $ra, 8($sp) # Push ra on the stack (will be overwritten by Fib function calls) +sw $s0, 4($sp) # Push s0 onto stack +sw $s1, 0($sp) # Push s1 onto stack + +# a1 may be overwritten by called functions, so save it to s1 (saved temporary), +# which called function won't change, so we can use it later for the second fib call +add $s1, $zero, $a1 + +# Call Fib(arg0), save result in s0 +# arg0 is already in register a0, placed there by caller of fib_test +jal fib # Call fib(4), returns in register v0 +add $s0, $zero, $v0 # Move result to s0 so we can call fib again without overwriting + +# Call Fib(arg1), save result in s1 +add $a0, $zero, $s1 # Move original arg1 into register a0 for function call +jal fib +add $s1, $zero, $v0 # Move result to s1 + +# Add Fib(arg0) and Fib(arg1) into v0 (return value for fib_test) +add $v0, $s0, $s1 + +# Restore original values to s0 and s1 registers from stack before returning +lw $s1, 0($sp) # Pop s1 from stack +lw $s0, 4($sp) # Pop s0 from stack +lw $ra, 8($sp) # Pop ra from the stack so we can return to caller +addi $sp, $sp, 12 # Adjust stack pointer to reflect pops + +jr $ra # Return to caller + +#------------------------------------------------------------------------------ +# Recursive Fibonacci function. Equivalent C code: +# +# int Fibonacci(int n) { +# if (n == 0) return 0; // Base case +# if (n == 1) return 1; // Base case +# int fib_1 = Fibonacci(n - 1); +# int fib_2 = Fibonacci(n - 2); +# return fib_1+fib_2; +# } +fib: +# Test base cases. If we're in a base case, return directly (no need to use stack) +bne $a0, 0, testone +add $v0, $zero, $zero # a0 == 0 -> return 0 +jr $ra +testone: +bne $a0, 1, fib_body +add $v0, $zero, $a0 # a0 == 1 -> return 1 +jr $ra + +fib_body: +# Create stack frame for fib: push ra and s0 +addi $sp, $sp, -8 # Allocate two words on stack at once for two pushes +sw $ra, 4($sp) # Push ra on the stack (will be overwritten by recursive function calls) +sw $s0, 0($sp) # Push s0 onto stack + +# Call Fib(n-1), save result in s0 +add $s0, $zero, $a0 # Save a0 argument (n) in register s0 +addi $a0, $a0, -1 # a0 = n-1 +jal fib +add $a0, $s0, -2 # a0 = n-2 +add $s0, $zero, $v0 # s0 = Fib(n-1) + +# Call Fib(n-2), compute final result +jal fib +add $v0, $v0, $s0 # v0 = Fib(n-2) + Fib(n-1) + +# Restore registers and pop stack frame +lw $ra, 4($sp) +lw $s0, 0($sp) +addi $sp, $sp, 8 + +jr $ra # Return to caller + +#------------------------------------------------------------------------------ +# Utility function to print results +print_result: +# Create stack frame for ra and s0 +addi $sp, $sp, -8 +sw $ra, 4($sp) +sw $s0, 0($sp) + +add $s0, $zero, $a0 # Save argument (integer to print) to s0 + +li $v0, 4 # Service code to print string +la $a0, result_str # Argument is memory address of string to print +syscall + +li $v0, 1 # Service code to print integer +add $a0, $zero, $s0 # Argument is integer to print +syscall + +# Restore registers and pop stack frame +lw $ra, 4($sp) +lw $s0, 0($sp) +addi $sp, $sp, 8 + +#------------------------------------------------------------------------------ +# Jump loop to end execution, so we don't fall through to .data section +program_end: +j program_end + + +#------------------------------------------------------------------------------ +.data +# Null-terminated string to print as part of result +result_str: .asciiz "\nFib(4)+Fib(10) = " \ No newline at end of file From 6297e26ec15df8d1d24ca505ca10cb17175b7da0 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 20:52:02 -0500 Subject: [PATCH 112/190] Update with new modules --- makefile | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/makefile b/makefile index d5654f7..5c826e1 100644 --- a/makefile +++ b/makefile @@ -1,11 +1,13 @@ all: core alu regfile memory signextend -### PC Modules +### CPU Module +CPU: CPU.v CPU.t.v + iverilog -Wall -o CPU CPU.t.v ### PC_Calc Modules # PC_Calc top level module -PC_Calc: PC_Calc/PC_Calc.v addr_concat imm_concat is_zero_and - iverilog -Wall -o PC_Calc/PC_Calc PC_Calc.v +PC_Calc: PC_Calc/PC_Calc.v PC/PC_Calc.t.v addr_concat imm_concat is_zero_and + iverilog -Wall -o PC_Calc/PC_Calc PC_Calc/PC_Calc.t.v addr_concat: PC_Calc/addr_concat.v PC_Calc/addr_concat.t.v iverilog -Wall -o PC_Calc/addr_concat addr_concat.t.v @@ -18,8 +20,18 @@ is_zero_and: PC_Calc/is_zero_and.v PC_Calc/is_zero_and.t.v ### Instruction Parser Modules # Instruction Parser top level module -Instruction_Parser: Instruction_Parser.v - iverilog -Wall -o Instruction_Parser/Instruction_Parser Instruction_Parser.v +Instruction_Parser: Instruction_Parser.v Instruction_Parser.t.v Controller Decoder Memory + iverilog -Wall -o Instruction_Parser/Instruction_Parser Instruction_Parser.v + +Controller: Controller.v Controller.t.v + iverilog -Wall -o Instruction_Parser/Controller Instruction_Parser/Controller.t.v + +Decoder: Decoder.v Decoder.t.v + iverilog -Wall -o Instruction_Parser/Decoder Instruction_Parser/Decoder.t.v + +Memory: Memory.v Memory.t.v + iverilog -Wall -o Instruction_Parser/Memory Instruction_Parser/Memory.t.v + ### Core Modules # Core top level module @@ -52,15 +64,12 @@ xor: Core/ALU/xor_32bit.v Core/ALU/xor_32bit.t.v iverilog -Wall -o Core/ALU/xor Core/ALU/xor_32bit.t.v # Regfile modules -regfile: Core/regfile.t.v Core/regfile.v decoder mux register +regfile: Core/regfile.t.v Core/regfile.v decoder multiplexer register iverilog -Wall -o Core/regfile Core/regfile.t.v decoder: Core/decoders.t.v Core/decoders.v iverilog -Wall -o Core/decoder Core/decoders.t.v -# mux: Core/multiplexer.t.v Core/multiplexer.v -# iverilog -Wall -o Core/mux Core/multiplexer.t.v - register: Core/register.t.v Core/register.v iverilog -Wall -o Core/register Core/register.t.v @@ -71,3 +80,7 @@ memory: Core/memory.v Core/memory.t.v # Concatenation modules signextend: Core/signextend.v iverilog -Wall -o Core/signextend Core/signextend.v + +### Submodules +multiplexer: submodules/multiplexer.v submodules/multiplexer.t.v + iverilog -Wall -o multiplexer submodules/multiplexer.t.v \ No newline at end of file From 652dcc961714c135aa47979342cbba9c0daa152a Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 20:52:52 -0500 Subject: [PATCH 113/190] Add test module --- submodules/multiplexer.t.v | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 submodules/multiplexer.t.v diff --git a/submodules/multiplexer.t.v b/submodules/multiplexer.t.v new file mode 100644 index 0000000..5c015ba --- /dev/null +++ b/submodules/multiplexer.t.v @@ -0,0 +1,165 @@ +//-------------------------------- +// Test the multiplexer modules. +//-------------------------------- + +`include "submodules/multiplexer.v" + +// Test harness for multiplexer unit test modules. +module multiplexerTestBenchHarness(); + reg begintest0; + reg begintest1; + wire endtest0; + wire endtest1; + wire dutpassed0; + wire dutpassed1; + + mux32to1by1Test test0 (begintest0, endtest0, dutpassed0); + mux32to32by1Test test1 (begintest1, endtest1, dutpassed1); + + initial begin + begintest0 = 0; + begintest1 = 0; + #10; + begintest0 = 1; + begintest1 = 1; + #1000; + end + + always @(posedge endtest0 && endtest1) begin + if (dutpassed0 == 1 || dutpassed1 == 1) begin + $display("All multiplexer tests passed."); + end + end + +endmodule // multiplexerTestBenchHarness + +// Unit test the 32:1 mux module. +module mux32to1by1Test + ( + input begintest, + output reg endtest, + output reg dutpassed + ); + wire out; + reg[4:0] address; + reg[31:0] inputs; + + mux32to1by1 DUT (out, address, inputs); + + always @(posedge begintest) begin + endtest = 0; + dutpassed = 1; + + // Test Case 1: + // Ensure that out is the same as the bit of the input at the + // given address. + inputs = 32'h000FFF; address = 5'd9; + if (out != 1) begin + $display("32:1 mux Test Case 1 Failed."); + dutpassed = 0; + end + + #5 + endtest = 1; + end +endmodule // mux32to1by1Test + +module mux4inputTest + ( + input begintest, + output reg endtest, + output reg dutpassed + ); + + reg[5:0] input0, input1, input2, input3; + reg[1:0] address; + wire[5:0] out; + + mux4input #(.width(6)) DUT (input0, input1, input2, input3, address, out); + + always @(posedge begintest) begin + endtest = 0; + dutpassed = 1; + + // Test Case 1: + // Ensure that the value chosen by the mux matches + // the value at the given address. + input0 = 6'd1; + input1 = 6'd2; + input2 = 6'd3; + input3 = 6'd4; + address = 2'd0; + #5 + if (out != input0) begin + $display("3 wide 6 deep mux test case 1 failed at address 00."); + dutpassed = 0; + end + + address = 2'd1; + #5 + if (out != input1) begin + $display("3 wide 6 deep mux test case 1 failed at address 01."); + dutpassed = 0; + end + + address = 2'd2; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 10."); + dutpassed = 0; + end + + address = 2'd3; + #5 + if (out != input2) begin + $display("3 wide 6 deep mux test case 1 failed at address 11."); + dutpassed = 0; + end + + #5 + endtest = 1; + end +endmodule + +// Unit test the 32 wide 32 deep mux module. +module mux32to32by1Test( + input begintest, + output reg endtest, + output reg dutpassed + ); + wire[31:0] out; + reg[4:0] address; + reg[31:0] input0, input1, input2, input3, input4, input5, input6, input7, input8; + reg[31:0] input9, input10, input11, input12, input13, input14, input15, input16; + reg[31:0] input17, input18, input19, input20, input21, input22, input23, input24; + reg[31:0] input25, input26, input27, input28, input29, input30, input31; + + mux32to1by32 DUT (out, address, input0, input1, input2, input3, input4, input5, + input6, input7, input8, input9, input10, input11, input12, input13, input14, + input15, input16, input17, input18, input19, input20, input21, input22, input23, + input24, input25, input26, input27, input28, input29, input30, input31); + + always @(posedge begintest) begin + endtest = 0; + dutpassed = 1; + + // Test Case 1: + // Ensure that the value chosen by the mux matches the value at the given address + address = 5'd20; + input0 = 32'd0; input1 = 32'd1; input2 = 32'd2; input3 = 32'd3; input4 = 32'd4; + input5 = 32'd5; input6 = 32'd6; input7 = 32'd7; input8 = 32'd8; input9 = 32'd9; + input10 = 32'd10; input11 = 32'd11; input12 = 32'd12; input13 = 32'd13; input14 = 32'd14; + input15 = 32'd15; input16 = 32'd16; input17 = 32'd17; input18 = 32'd18; input19 = 32'd19; + input20 = 32'd20; input21 = 32'd21; input22 = 32'd22; input23 = 32'd23; input24 = 32'd24; + input25 = 32'd25; input26 = 32'd26; input27 = 32'd27; input28 = 32'd28; input29 = 32'd29; + input30 = 32'd30; input31 = 32'd31; + if (out != 20) begin + $display("32 wide 32 deep mux Test Case 1 failed"); + dutpassed = 0; + end + + #5 + endtest = 1; + end +endmodule // mux32to32by1Test + From 3cb495cb7168fc5d037e8adf1ee943d9410c3347 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:11:46 -0500 Subject: [PATCH 114/190] Fix typo --- Core/regfile.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/regfile.v b/Core/regfile.v index cbd27a2..9ebc916 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -102,7 +102,7 @@ input Clk // Clock (Positive Edge Triggered) register22out, register23out, register24out, register25out, register26out, register27out, register28out, register29out, register30out, register31out); - // The multiplexer choosing the data associated with ReadREegister2. + // The multiplexer choosing the data associated with ReadRegister2. mux32to1by32 mux2 (ReadData2, ReadRegister2, register0out, register1out, register2out, register3out, register4out, register5out, register6out, register7out, register8out, register9out, register10out, register11out, From 91b3edfefdda7cf7d75b403e26c25908997ef860 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:12:09 -0500 Subject: [PATCH 115/190] Connect missing registers --- Core/register.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Core/register.v b/Core/register.v index 60616da..2bed55f 100644 --- a/Core/register.v +++ b/Core/register.v @@ -36,6 +36,7 @@ input clk register r8 (q[8], d[8], wrenable, clk); register r9 (q[9], d[9], wrenable, clk); register r10 (q[10], d[10], wrenable, clk); + register r11 (q[11], d[11], wrenable, clk); register r12 (q[12], d[12], wrenable, clk); register r13 (q[13], d[13], wrenable, clk); register r14 (q[14], d[14], wrenable, clk); @@ -54,6 +55,7 @@ input clk register r27 (q[27], d[27], wrenable, clk); register r28 (q[28], d[28], wrenable, clk); register r29 (q[29], d[29], wrenable, clk); + register r30 (q[30], d[30], wrenable, clk); register r31 (q[31], d[31], wrenable, clk); endmodule // register32 From 7ce4790e804edd38624130c4d86b647735a490ac Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:35:34 -0500 Subject: [PATCH 116/190] Start writing testbench --- CPU.t.v | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CPU.t.v diff --git a/CPU.t.v b/CPU.t.v new file mode 100644 index 0000000..c7a8519 --- /dev/null +++ b/CPU.t.v @@ -0,0 +1,22 @@ +// Test the full single cycle CPU + +`include "CPU.v" + +module testCPU (); + + reg CLK; + + CPU dut (.CLK(CLK)); + + initial CLK = 0; + + initial begin + #6000 + CLK = 1; + $display("Program counter: %h", dut.PC); + + #6000 + CLK = 0; + end + +endmodule \ No newline at end of file From e23c3258696350d5a81ae79cba4e24858241ff5d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:36:15 -0500 Subject: [PATCH 117/190] Add missing ports to Core instantiation --- CPU.v | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CPU.v b/CPU.v index 7c1f1eb..c52e87b 100644 --- a/CPU.v +++ b/CPU.v @@ -34,9 +34,10 @@ module CPU wire[31:0] Da; wire isZero; Core c( - .Rs(Rs), .Rd(Rd), .Rt(Rt), + .CLK(CLK), .Rd(Rd), .Rt(Rt), .Rs(Rs), .imm(imm), .addedPC(new_PC), .RegDst(RegDst), .RegWr(RegWr), .MemWr(MemWr), - .ALUSrc(ALUSrc), .MemToReg(MemToReg), .Da(Da), .isZero(isZero) + .ALUSrc(ALUSrc), .MemToReg(MemToReg), .ALUCntrl(ALUCtrl), + .Da(Da), .isZero(isZero) ); PC_Calc pc_calc( From 9809fa25d7b8dd3172e7535d840aeaa1e0f5baee Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:38:53 -0500 Subject: [PATCH 118/190] Move all wires to top of module --- Core/Core.v | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Core/Core.v b/Core/Core.v index 26fb30b..a8c249f 100644 --- a/Core/Core.v +++ b/Core/Core.v @@ -22,37 +22,35 @@ module Core output isZero ); + // Regfile wires wire[4:0] WriteAddr; + wire[31:0] databout; + wire[31:0] datain; + // ALU operand 2 mux + wire[31:0] operandb; + // Sign extend + wire[31:0] signextimm; + // ALU + wire cout; + wire overflow; + wire[31:0] finalsignal; + // Regfile write data mux + wire[31:0] memout; // Register file write address mux4input #(.width(5)) RegWriteAddr (Rd, Rt, 5'd31, 5'bx, RegDst, WriteAddr); - // wire[31:0] dataaout; - wire[31:0] databout; - wire[31:0] datain; // Register file regfile regfile (Da, databout, datain, Rs, Rt, WriteAddr, RegWr, CLK); - // Sign extend - - wire[31:0] signextimm; signextend extend (imm, signextimm); - // ALU operand 2 mux - wire[31:0] operandb; - mux4input #(.width(32)) aluinput (databout, signextimm, 32'bx, 32'bx, {1'b0, ALUSrc}, operandb); - // ALU - wire cout; - wire overflow; - wire[31:0] finalsignal; ALUcontrolLUT aluout (cout, overflow, isZero, finalsignal, ALUCntrl, Da, operandb); - // Regfile write data mux - wire[31:0] memout; mux4input #(.width(32)) regdatamux (finalsignal, memout, addedPC, 32'bx, MemToReg, datain); From caa2954e315e48586156e4f116daba79d9ceb8f4 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:39:24 -0500 Subject: [PATCH 119/190] Change reference memory file --- Core/memory.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/memory.v b/Core/memory.v index 820e3d0..f7ec632 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -25,6 +25,6 @@ module memory dataOut <= memory[address]; end - initial $readmemh("file.dat", memory); + initial $readmemh("mem.dat", memory); endmodule \ No newline at end of file From 297d1297a2beee271fe1760d191e1dc7c97c3fdf Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:43:15 -0500 Subject: [PATCH 120/190] add CPU build target to all target --- makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile b/makefile index 5c826e1..9f6cc95 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,8 @@ -all: core alu regfile memory signextend +all: core alu regfile memory signextend CPU ### CPU Module CPU: CPU.v CPU.t.v - iverilog -Wall -o CPU CPU.t.v + iverilog -Wall -o CPU.out CPU.t.v ### PC_Calc Modules # PC_Calc top level module From a635a72482e2a0ea83211c45bd7df14de8262a87 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:44:24 -0500 Subject: [PATCH 121/190] Move to more local location for Core use only --- file.dat => Core/file.dat | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename file.dat => Core/file.dat (100%) diff --git a/file.dat b/Core/file.dat similarity index 100% rename from file.dat rename to Core/file.dat From 6d98b24c5507d0a2bcfc41ddb5362caea9c78a9c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:44:37 -0500 Subject: [PATCH 122/190] Ignore mem.dat --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 00bc6ef..a1ecedc 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ # Ignore gtkwave files *.vcd + +# Ignore temporary memory file +mem.dat From de9792c62dcbaead1096785886719496fd8b25ad Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:45:55 -0500 Subject: [PATCH 123/190] Write assmebly to use as test expressions --- AssemblyPrograms/testCPU.asm | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 AssemblyPrograms/testCPU.asm diff --git a/AssemblyPrograms/testCPU.asm b/AssemblyPrograms/testCPU.asm new file mode 100644 index 0000000..2a947c9 --- /dev/null +++ b/AssemblyPrograms/testCPU.asm @@ -0,0 +1,8 @@ +# Test commands for the CPU +addi $t0, $zero, 1 +addi $t1, $zero, 1 + +j end + +end: +j end \ No newline at end of file From d4b511288df81c0c05c869a74adae4237d3d9592 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Sun, 12 Nov 2017 22:46:42 -0500 Subject: [PATCH 124/190] Instantiate instruction memory --- memoryfile.text | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 memoryfile.text diff --git a/memoryfile.text b/memoryfile.text new file mode 100644 index 0000000..2aad4a9 --- /dev/null +++ b/memoryfile.text @@ -0,0 +1,4 @@ +20080001 +20090001 +08000003 +08000003 From 91ba8719e8a60731d0d51c9805900a855f389a24 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Mon, 13 Nov 2017 21:24:20 -0500 Subject: [PATCH 125/190] make stuff compile --- CPU.v | 7 +- Core/data_memory.dat | 32 ++ Core/memory.v | 4 +- DFF.v | 6 +- main_test.dat | 1024 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1066 insertions(+), 7 deletions(-) create mode 100644 Core/data_memory.dat create mode 100644 main_test.dat diff --git a/CPU.v b/CPU.v index c52e87b..1e324cd 100644 --- a/CPU.v +++ b/CPU.v @@ -11,9 +11,12 @@ module CPU input CLK ); // PC is the current program counter, new_PC is what it's next value will be. - wire[31:0] PC, new_PC; + reg[31:0] PC; - DFF #(32) pc(.trigger(CLK), .enable(1), .q(new_PC), .d(PC)); + initial PC = 0; + wire[31:0]new_PC; + + DFF #(32) pc(.trigger(CLK), .enable(1), .out(PC), .in(new_PC)); wire[4:0] Rs, Rd, Rt; wire[15:0] imm; diff --git a/Core/data_memory.dat b/Core/data_memory.dat new file mode 100644 index 0000000..613ddfe --- /dev/null +++ b/Core/data_memory.dat @@ -0,0 +1,32 @@ +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 diff --git a/Core/memory.v b/Core/memory.v index f7ec632..1d3e0e8 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -25,6 +25,6 @@ module memory dataOut <= memory[address]; end - initial $readmemh("mem.dat", memory); + initial $readmemh("Core/data_memory.dat", memory); -endmodule \ No newline at end of file +endmodule diff --git a/DFF.v b/DFF.v index bb8cf5e..80c1282 100644 --- a/DFF.v +++ b/DFF.v @@ -4,12 +4,12 @@ module DFF #( parameter W = 1 ) ( input trigger, input enable, - input [W-1:0] d, - output reg [W-1:0] q + input [W-1:0] in, + output reg [W-1:0] out ); always @(posedge trigger) begin if(enable) begin - q <= d; + out <= in; end end endmodule diff --git a/main_test.dat b/main_test.dat new file mode 100644 index 0000000..df709b9 --- /dev/null +++ b/main_test.dat @@ -0,0 +1,1024 @@ +20080001 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 From 9ffa2989c81991431e81f9911d922da73cec3251 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Mon, 13 Nov 2017 21:26:15 -0500 Subject: [PATCH 126/190] Make gtkwave file --- CPU.t.v | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CPU.t.v b/CPU.t.v index c7a8519..2eda0ae 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,12 +11,18 @@ module testCPU (); initial CLK = 0; initial begin + $dumpfile("CPU.vcd"); + $dumpvars(); + CLK = 1; #1000 + CLK = !CLK; #1000 + CLK = !CLK; #1000 #6000 - CLK = 1; $display("Program counter: %h", dut.PC); + // $display("DFF: %b", dut.pc); #6000 CLK = 0; + $finish(); end endmodule \ No newline at end of file From 92f769ef6384941bf3aeeea4b09ac0d2f828dad1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Mon, 13 Nov 2017 21:26:36 -0500 Subject: [PATCH 127/190] switch inputs to DFF --- CPU.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPU.v b/CPU.v index c52e87b..286341c 100644 --- a/CPU.v +++ b/CPU.v @@ -13,7 +13,7 @@ module CPU // PC is the current program counter, new_PC is what it's next value will be. wire[31:0] PC, new_PC; - DFF #(32) pc(.trigger(CLK), .enable(1), .q(new_PC), .d(PC)); + DFF #(32) pc(.trigger(CLK), .enable(1), .d(new_PC), .q(PC)); wire[4:0] Rs, Rd, Rt; wire[15:0] imm; From b9844a970f25a6b53fe692fd9395f968b61bdaf3 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Mon, 13 Nov 2017 22:00:10 -0500 Subject: [PATCH 128/190] got 0s at first --- CPU.t.v | 8 +++++--- CPU.v | 11 +++++++---- DFF.v | 6 +++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index c7a8519..ccffe23 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,12 +11,14 @@ module testCPU (); initial CLK = 0; initial begin - #6000 - CLK = 1; + $dumpfile("CPU.vcd"); + $dumpvars; + #1 + CLK = 1; #2 $display("Program counter: %h", dut.PC); #6000 CLK = 0; end -endmodule \ No newline at end of file +endmodule diff --git a/CPU.v b/CPU.v index 1e324cd..a1fa863 100644 --- a/CPU.v +++ b/CPU.v @@ -11,12 +11,15 @@ module CPU input CLK ); // PC is the current program counter, new_PC is what it's next value will be. - reg[31:0] PC; + wire[31:0] PC, new_PC; + reg en; - initial PC = 0; - wire[31:0]new_PC; + initial begin + en = 0; #1; + en = 1; + end - DFF #(32) pc(.trigger(CLK), .enable(1), .out(PC), .in(new_PC)); + DFF #(32) pc(.trigger(CLK), .enable(en), .out(PC), .in(new_PC)); wire[4:0] Rs, Rd, Rt; wire[15:0] imm; diff --git a/DFF.v b/DFF.v index 80c1282..e424959 100644 --- a/DFF.v +++ b/DFF.v @@ -7,9 +7,13 @@ module DFF #( parameter W = 1 ) input [W-1:0] in, output reg [W-1:0] out ); - always @(posedge trigger) begin + always @(posedge trigger or enable) begin if(enable) begin out <= in; end + else begin + $display("got here"); + out <= 0; + end end endmodule From 17c8bf0bac6430a230d6b5e67416cfcad8b4bbec Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 10:22:45 -0500 Subject: [PATCH 129/190] Remove debugging statement --- DFF.v | 1 - 1 file changed, 1 deletion(-) diff --git a/DFF.v b/DFF.v index e424959..72ea978 100644 --- a/DFF.v +++ b/DFF.v @@ -12,7 +12,6 @@ module DFF #( parameter W = 1 ) out <= in; end else begin - $display("got here"); out <= 0; end end From 4a2076655b30a8aa5bdfe5a1477a46c2446370e8 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 10:42:40 -0500 Subject: [PATCH 130/190] Change PC to be divided by 4 Our initial PC tests were failing because we were using our program counter to directly index into the instruction memory, rather than dividing the program counter by 4 to index into the correct word. --- CPU.t.v | 10 +++++----- Instruction_Parser/Instruction_Parser.v | 2 +- main_test.dat | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index ccffe23..bc39b3f 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -13,12 +13,12 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); $dumpvars; - #1 - CLK = 1; #2 + #6000; + $display("Program counter: %h", dut.PC); + CLK = 1; #6000 + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; $display("Program counter: %h", dut.PC); - - #6000 - CLK = 0; end endmodule diff --git a/Instruction_Parser/Instruction_Parser.v b/Instruction_Parser/Instruction_Parser.v index 4a40dfc..cab116f 100644 --- a/Instruction_Parser/Instruction_Parser.v +++ b/Instruction_Parser/Instruction_Parser.v @@ -16,7 +16,7 @@ module InstructionParser output MemWr, ALUSrc, RegWr, AddSel ); wire[31:0] instr; - Memory im(.Addr(PC[9:0]), .DataOut(instr)); + Memory im(.Addr(PC[9:0] >> 2), .DataOut(instr)); wire[5:0] Op, funct; wire[4:0] Rs, Rd, Rt; diff --git a/main_test.dat b/main_test.dat index df709b9..0038c2d 100644 --- a/main_test.dat +++ b/main_test.dat @@ -1,8 +1,8 @@ -20080001 -0000_0000 -0000_0000 -0000_0000 -0000_0000 +2008_0001 +2008_0002 +2008_0003 +0000_0001 +0000_0002 0000_0000 0000_0000 0000_0000 From cd79cc29384e754c959395d4a978e216a89f472a Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 11:23:00 -0500 Subject: [PATCH 131/190] Fix error where PC was updating after one timestep We were incrementing our program coutner when the clock was still low even though the program counter should only be set on the posedge of a clock cycle. This was because the program counter was being set on posedge clock OR when en change. --- DFF.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DFF.v b/DFF.v index 72ea978..5b3f96e 100644 --- a/DFF.v +++ b/DFF.v @@ -7,7 +7,7 @@ module DFF #( parameter W = 1 ) input [W-1:0] in, output reg [W-1:0] out ); - always @(posedge trigger or enable) begin + always @(posedge trigger or negedge enable) begin if(enable) begin out <= in; end From 2460baba0adc463de039617423648836401cd3b6 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 12:16:12 -0500 Subject: [PATCH 132/190] Run tests without ./run_program test now uses writememh to write directly to mem.dat instead of having to use a wrapper function to write into it. The helper function has been deleted because it is no longer necessary. --- CPU.t.v | 5 +++++ run_program.sh | 25 ------------------------- 2 files changed, 5 insertions(+), 25 deletions(-) delete mode 100755 run_program.sh diff --git a/CPU.t.v b/CPU.t.v index bc39b3f..002b5b2 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -5,6 +5,7 @@ module testCPU (); reg CLK; + reg[31:0] mem [16:0]; CPU dut (.CLK(CLK)); @@ -13,6 +14,10 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); $dumpvars; + + mem[0] = 32'h2008_0001; + mem[1] = 32'h2008_0002; + $writememh("mem.dat", mem); #6000; $display("Program counter: %h", dut.PC); CLK = 1; #6000 diff --git a/run_program.sh b/run_program.sh deleted file mode 100755 index 9aeaec2..0000000 --- a/run_program.sh +++ /dev/null @@ -1,25 +0,0 @@ -# Runs a verilog testbench using a given memory file -# Inputs: -# name of verilog testbench to run -# name of memory file to use - -# NOTE: must be run in top-level git repo - -ver () { - cd $(dirname $1) - inp=${1%.v} - fname="$(basename $inp)" - iverilog -o "$fname.out" $(basename $1) && "./$fname.out" - # Go back (also suppress the output text that would normally be displayed) - cd - > /dev/null -} - -d=${PWD##*/} -if [ "$d" = "Lab3" ] -then - cat $2 > mem.dat - ver $1 - rm mem.dat -else - echo "ERROR: This must be run in top-level directory" -fi From a66e041d901dfd748dfa3a848fb4aa2aefe45147 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 18:08:40 -0500 Subject: [PATCH 133/190] Specify dump vars --- CPU.t.v | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 99c85f0..b0224bb 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -12,11 +12,14 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); - $dumpvars; + $dumpvars(0,testCPU); #1 - CLK = 1; #2 + CLK = 1; #1000 + CLK = 0; #1000 + CLK = 1; #1000 + $display("hi"); $display("Program counter: %h", dut.PC); - // $display("DFF: %b", dut.pc); + #6000 CLK = 0; From 9e61113d38b855e9ed0e0660b047d7a8d875f95c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 18:09:08 -0500 Subject: [PATCH 134/190] Add longer enable delay --- CPU.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CPU.v b/CPU.v index a1fa863..9ada4d8 100644 --- a/CPU.v +++ b/CPU.v @@ -15,7 +15,7 @@ module CPU reg en; initial begin - en = 0; #1; + en = 0; #1000; en = 1; end From 57662c4204bc5ab1ac8e8b1f08cbcfac5c23e0a2 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 18:09:45 -0500 Subject: [PATCH 135/190] Remove print statement --- DFF.v | 1 - 1 file changed, 1 deletion(-) diff --git a/DFF.v b/DFF.v index e424959..72ea978 100644 --- a/DFF.v +++ b/DFF.v @@ -12,7 +12,6 @@ module DFF #( parameter W = 1 ) out <= in; end else begin - $display("got here"); out <= 0; end end From 9fd60052bcfe2743e40160051bf3e19d5f213912 Mon Sep 17 00:00:00 2001 From: apan64 Date: Tue, 14 Nov 2017 18:11:32 -0500 Subject: [PATCH 136/190] removed some output wires that I forgot about --- PC_Calc/PC_Calc.t.v | 2 +- PC_Calc/PC_Calc.v | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/PC_Calc/PC_Calc.t.v b/PC_Calc/PC_Calc.t.v index 3f334e5..554a213 100644 --- a/PC_Calc/PC_Calc.t.v +++ b/PC_Calc/PC_Calc.t.v @@ -15,7 +15,7 @@ module testPCCalc(); wire[31:0] addedSel; wire[31:0] jump; - PC_Calc pccalc(old_PC[31:0], isZero, PCSel[1:0], AddSel, Da[31:0], addr[25:0], imm[15:0], added_PC[31:0], new_PC[31:0], addedSel[31:0], jump[31:0]); + PC_Calc pccalc(old_PC[31:0], isZero, PCSel[1:0], AddSel, Da[31:0], addr[25:0], imm[15:0], added_PC[31:0], new_PC[31:0]); initial begin $display("added_PC | new_PC"); old_PC = 32'd4; diff --git a/PC_Calc/PC_Calc.v b/PC_Calc/PC_Calc.v index 2f316e9..81635db 100644 --- a/PC_Calc/PC_Calc.v +++ b/PC_Calc/PC_Calc.v @@ -14,9 +14,7 @@ module PC_Calc input[25:0] addr, input[15:0] imm, output[31:0] added_PC, - output[31:0] new_PC, - output[31:0] addedSel, - output[31:0] jump + output[31:0] new_PC ); wire[31:0] extendedImm; immConcat iconcat(extendedImm[31:0], imm[15:0]); From 9e2369b640bfbeb1936c9e8a280906d4977fcc8e Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 18:41:04 -0500 Subject: [PATCH 137/190] Add first unit tests --- CPU.t.v | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 002b5b2..b627c2f 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -9,21 +9,26 @@ module testCPU (); CPU dut (.CLK(CLK)); - initial CLK = 0; - initial begin $dumpfile("CPU.vcd"); $dumpvars; - mem[0] = 32'h2008_0001; - mem[1] = 32'h2008_0002; + //add $t1, $zero, $zero + mem[0] = 32'h00004820; $writememh("mem.dat", mem); - #6000; - $display("Program counter: %h", dut.PC); - CLK = 1; #6000 + CLK = 1; #6000; CLK = 0; #6000 + $display("$t0: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); - CLK = 0; #6000; CLK=1; #6000; + + //addi $t1, $zero, 2 + mem[1] = 32'h02009002; + $writememh("mem.dat", mem); + CLK = 1; #6000; CLK = 0; #6000 + $display("$t0: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); + + + end endmodule From caf925e9fed4ebaea687762179a82f0c0578e039 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 18:49:33 -0500 Subject: [PATCH 138/190] Change immediate for easier differentiation --- AssemblyPrograms/testCPU.asm | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/AssemblyPrograms/testCPU.asm b/AssemblyPrograms/testCPU.asm index 2a947c9..fb94bed 100644 --- a/AssemblyPrograms/testCPU.asm +++ b/AssemblyPrograms/testCPU.asm @@ -1,8 +1,10 @@ # Test commands for the CPU +main: addi $t0, $zero, 1 -addi $t1, $zero, 1 - +addi $t1, $zero, 10 j end end: -j end \ No newline at end of file +j end + +.data \ No newline at end of file From fbc482caa405953d2865073d263199291d794229 Mon Sep 17 00:00:00 2001 From: apan64 Date: Tue, 14 Nov 2017 19:03:27 -0500 Subject: [PATCH 139/190] fixed the wiring for core and pc_calc --- CPU.t.v | 14 +++++++++++++- CPU.v | 5 +++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 002b5b2..a0fb91a 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -17,13 +17,25 @@ module testCPU (); mem[0] = 32'h2008_0001; mem[1] = 32'h2008_0002; - $writememh("mem.dat", mem); + // $writememh("mem.dat", mem); #6000; $display("Program counter: %h", dut.PC); CLK = 1; #6000 $display("Program counter: %h", dut.PC); CLK = 0; #6000; CLK=1; #6000; $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); + CLK = 0; #6000; CLK=1; #6000; + $display("Program counter: %h", dut.PC); end endmodule diff --git a/CPU.v b/CPU.v index a1fa863..38a9d66 100644 --- a/CPU.v +++ b/CPU.v @@ -39,8 +39,9 @@ module CPU wire[31:0] Da; wire isZero; + wire[31:0] added_PC; Core c( - .CLK(CLK), .Rd(Rd), .Rt(Rt), .Rs(Rs), .imm(imm), .addedPC(new_PC), + .CLK(CLK), .Rd(Rd), .Rt(Rt), .Rs(Rs), .imm(imm), .addedPC(added_PC), .RegDst(RegDst), .RegWr(RegWr), .MemWr(MemWr), .ALUSrc(ALUSrc), .MemToReg(MemToReg), .ALUCntrl(ALUCtrl), .Da(Da), .isZero(isZero) @@ -48,7 +49,7 @@ module CPU PC_Calc pc_calc( .old_PC(PC), .isZero(isZero), .PCSel(PCSel), .AddSel(AddSel), - .Da(Da), .addr(addr), .imm(imm), .new_PC(new_PC) + .Da(Da), .addr(addr), .imm(imm), .added_PC(added_PC), .new_PC(new_PC) ); From eec285fd9ea9d3ccab704d67d1c92a6eebf71cfe Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 19:14:55 -0500 Subject: [PATCH 140/190] Make tests work --- CPU.t.v | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index b627c2f..846ac2f 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -16,15 +16,22 @@ module testCPU (); //add $t1, $zero, $zero mem[0] = 32'h00004820; $writememh("mem.dat", mem); - CLK = 1; #6000; CLK = 0; #6000 - $display("$t0: %h", dut.c.regfile.register9out); + CLK = 1; #12000; CLK = 0; #12000; + $display("$t1: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); //addi $t1, $zero, 2 - mem[1] = 32'h02009002; + mem[1] = 32'h20090002; $writememh("mem.dat", mem); - CLK = 1; #6000; CLK = 0; #6000 - $display("$t0: %h", dut.c.regfile.register9out); + CLK = 1; #12000; CLK = 0; #12000; + $display("$t1: %h", dut.c.regfile.register9out); + $display("Program counter: %h", dut.PC); + + //sw $t1, 0 + mem[2] = 32'hac090000; + $writememh("mem.dat", mem); + CLK = 1; #12000; CLK = 0; #12000; + $display("M[0]: %h", dut.c.datamemory.memory[0]); $display("Program counter: %h", dut.PC); From 6da68cfe993e75b21fd8826d5509408bb0668460 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 19:41:23 -0500 Subject: [PATCH 141/190] Add another test --- CPU.t.v | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 846ac2f..7612cec 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -27,13 +27,27 @@ module testCPU (); $display("$t1: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); - //sw $t1, 0 + //sw $zero, $t2 mem[2] = 32'hac090000; $writememh("mem.dat", mem); CLK = 1; #12000; CLK = 0; #12000; - $display("M[0]: %h", dut.c.datamemory.memory[0]); + $display("$t2: %h", dut.c.regfile.register10out); $display("Program counter: %h", dut.PC); + //addi $t1, $zero, 2 + mem[3] = 32'h20090002; + $writememh("mem.dat", mem); + CLK = 1; #12000; CLK = 0; #12000; + $display("$t1: %h", dut.c.regfile.register9out); + $display("Program counter: %h", dut.PC); + + //lw $t2, 0($zero) + //load the value of memory at $zero into #t2 + // mem[4] = 32'h8c0a0000; + // $writememh("mem.dat", mem); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t2: %h", dut.c.regfile.register10out); + // $display("Program counter: %h", dut.PC); end From bce1b2d0c3304da2fce0c5729bd56a2a0c11d5b4 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Tue, 14 Nov 2017 19:46:04 -0500 Subject: [PATCH 142/190] Fix bug where PC would be xs after LW/SW --- Instruction_Parser/Controller.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index fc02199..7833316 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -39,7 +39,7 @@ module Controller ALUCtrl = alu_add; MemToReg = 1; PCSel = 1; - AddSel = 1'bx; + AddSel = 0; end SW: begin RegDst = 2'bxx; @@ -49,7 +49,7 @@ module Controller ALUCtrl = alu_add; MemToReg = 2'bxx; PCSel = 1; - AddSel = 1'bx; + AddSel = 0; end J: begin RegDst = 2'bxx; From f4d10b945a693f9fcede2cb0a48e28cbbbce8826 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 19:46:51 -0500 Subject: [PATCH 143/190] Change test instructions for diagnostics --- AssemblyPrograms/testCPU.asm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/AssemblyPrograms/testCPU.asm b/AssemblyPrograms/testCPU.asm index fb94bed..e1ff115 100644 --- a/AssemblyPrograms/testCPU.asm +++ b/AssemblyPrograms/testCPU.asm @@ -1,7 +1,14 @@ # Test commands for the CPU -main: +testaddi: addi $t0, $zero, 1 addi $t1, $zero, 10 +j testslt + +addi $t1, $zero, 4 + +testslt: +#sw $t0, 0($sp) +addi $t1, $zero, 4 j end end: From 9f882b657afdf7b89858f67c4da44e243654d999 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Tue, 14 Nov 2017 19:50:26 -0500 Subject: [PATCH 144/190] Diasble memory overwrite and add clock cycles --- CPU.t.v | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 846ac2f..c5f343d 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,30 +11,33 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); - $dumpvars; + $dumpvars(0, testCPU, dut.c.datamemory.memory[0]); //add $t1, $zero, $zero - mem[0] = 32'h00004820; - $writememh("mem.dat", mem); + // mem[0] = 32'h00004820; + // $writememh("mem.dat", mem); CLK = 1; #12000; CLK = 0; #12000; $display("$t1: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); //addi $t1, $zero, 2 - mem[1] = 32'h20090002; - $writememh("mem.dat", mem); + // mem[1] = 32'h20090002; + // $writememh("mem.dat", mem); CLK = 1; #12000; CLK = 0; #12000; $display("$t1: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); //sw $t1, 0 - mem[2] = 32'hac090000; - $writememh("mem.dat", mem); + // mem[2] = 32'hac090000; + // $writememh("mem.dat", mem); CLK = 1; #12000; CLK = 0; #12000; $display("M[0]: %h", dut.c.datamemory.memory[0]); $display("Program counter: %h", dut.PC); + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; end From fca980af645d6ed02db4b04476552a9651ce4e5b Mon Sep 17 00:00:00 2001 From: apan64 Date: Tue, 14 Nov 2017 19:52:57 -0500 Subject: [PATCH 145/190] created xori test --- CPU.t.v | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CPU.t.v b/CPU.t.v index 7612cec..958f297 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -41,6 +41,13 @@ module testCPU (); $display("$t1: %h", dut.c.regfile.register9out); $display("Program counter: %h", dut.PC); + // xori $t3, $t1, 7 + mem[4] = 32'h392b0007; + $writememh("mem.dat", mem); + CLK = 1; #12000; CLK = 0; #12000; + $display("$t3: %h", dut.c.regfile.register11out); + $display("Program counter: %h", dut.PC); + //lw $t2, 0($zero) //load the value of memory at $zero into #t2 // mem[4] = 32'h8c0a0000; From a2517b69eb9ca793bbafa8c847493a80db54b4c7 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:35:48 -0500 Subject: [PATCH 146/190] Fix the slt command number --- Instruction_Parser/Controller.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Instruction_Parser/Controller.v b/Instruction_Parser/Controller.v index 7833316..efa514a 100644 --- a/Instruction_Parser/Controller.v +++ b/Instruction_Parser/Controller.v @@ -27,7 +27,7 @@ module Controller localparam alu_add = 3'd0; localparam alu_sub = 3'd1; localparam alu_xor = 3'd2; - localparam alu_slt = 3'd4; + localparam alu_slt = 3'd3; always @ * begin case (Op) From b9d425a69b7175c6d6c8285e9b3ff19470d916ca Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:37:14 -0500 Subject: [PATCH 147/190] Correct the size of the 4input mux --- submodules/multiplexer.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/submodules/multiplexer.v b/submodules/multiplexer.v index 2fd8a90..f87a7f3 100644 --- a/submodules/multiplexer.v +++ b/submodules/multiplexer.v @@ -40,8 +40,8 @@ input[width-1:0] input0, input1, input2, input3, input[1:0] address, output[width-1:0] out ); - wire[5:0] mux [width-1:0]; - assign mux[0] = input0[width-1:0]; + wire[width-1:0] mux [3:0]; + assign mux[0] = input0; assign mux[1] = input1[width-1:0]; assign mux[2] = input2[width-1:0]; assign mux[3] = input3[width-1:0]; From 990c21b41b571bdefa6f5869631b416a73b3bab9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:39:09 -0500 Subject: [PATCH 148/190] Run the 4input mux test with the test harness --- submodules/multiplexer.t.v | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/submodules/multiplexer.t.v b/submodules/multiplexer.t.v index 5c015ba..89b6d31 100644 --- a/submodules/multiplexer.t.v +++ b/submodules/multiplexer.t.v @@ -8,25 +8,31 @@ module multiplexerTestBenchHarness(); reg begintest0; reg begintest1; + reg begintest2; wire endtest0; wire endtest1; + wire endtest2; wire dutpassed0; wire dutpassed1; + wire dutpassed2; mux32to1by1Test test0 (begintest0, endtest0, dutpassed0); mux32to32by1Test test1 (begintest1, endtest1, dutpassed1); + mux4inputTest test2 (begintest2, endtest2, dutpassed2); initial begin begintest0 = 0; begintest1 = 0; + begintest2 = 0; #10; begintest0 = 1; begintest1 = 1; + begintest2 = 1; #1000; end - always @(posedge endtest0 && endtest1) begin - if (dutpassed0 == 1 || dutpassed1 == 1) begin + always @(posedge endtest0 && endtest1 && endtest2) begin + if (dutpassed0 == 1 || dutpassed1 == 1 || dutpassed2 == 1) begin $display("All multiplexer tests passed."); end end From e00a6cf307e649c3b5992d26105216baa594a8a6 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:39:42 -0500 Subject: [PATCH 149/190] run tests from memory dumped from assembly program --- CPU.t.v | 220 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 191 insertions(+), 29 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 3dcd756..edb3633 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,55 +11,217 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); - $dumpvars(0, testCPU, dut.c.datamemory.memory[0]); + $dumpvars(0, testCPU, dut.c.datamemory.memory[8]); - //add $t1, $zero, $zero + // // add $t1, $zero, $zero // mem[0] = 32'h00004820; // $writememh("mem.dat", mem); - CLK = 1; #12000; CLK = 0; #12000; - $display("$t1: %h", dut.c.regfile.register9out); - $display("Program counter: %h", dut.PC); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t1: %h", dut.c.regfile.register9out); + // $display("Program counter: %h", dut.PC); - //addi $t1, $zero, 2 + // // addi $t1, $zero, 2 // mem[1] = 32'h20090002; - // $writememh("mem.dat", mem); - CLK = 1; #12000; CLK = 0; #12000; - $display("$t1: %h", dut.c.regfile.register9out); - $display("Program counter: %h", dut.PC); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t1: %h", dut.c.regfile.register9out); + // $display("Program counter: %h", dut.PC); - //sw $t1, 0 + // // sw $t1, 0 // mem[2] = 32'hac090000; // $writememh("mem.dat", mem); - CLK = 1; #12000; CLK = 0; #12000; - $display("$t2: %h", dut.c.regfile.register10out); - $display("Program counter: %h", dut.PC); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t2: %h", dut.c.regfile.register10out); + // $display("Program counter: %h", dut.PC); - //addi $t1, $zero, 2 - mem[3] = 32'h20090002; - $writememh("mem.dat", mem); - CLK = 1; #12000; CLK = 0; #12000; - $display("$t1: %h", dut.c.regfile.register9out); - $display("Program counter: %h", dut.PC); + // // addi $t1, $zero, 2 + // mem[3] = 32'h20090002; + // $writememh("mem.dat", mem); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t1: %h", dut.c.regfile.register9out); + // $display("Program counter: %h", dut.PC); - // xori $t3, $t1, 7 - mem[4] = 32'h392b0007; - $writememh("mem.dat", mem); - CLK = 1; #12000; CLK = 0; #12000; - $display("$t3: %h", dut.c.regfile.register11out); - $display("Program counter: %h", dut.PC); + // // xori $t3, $t1, 7 + // mem[4] = 32'h392b0007; + // $writememh("mem.dat", mem); + // CLK = 1; #12000; CLK = 0; #12000; + // $display("$t3: %h", dut.c.regfile.register11out); + // $display("Program counter: %h", dut.PC); - //lw $t2, 0($zero) - //load the value of memory at $zero into #t2 - // mem[4] = 32'h8c0a0000; + // // lw $t2, 0($zero) + // // load the value of memory at $zero into #t2 + // mem[5] = 32'h8c0a0000; // $writememh("mem.dat", mem); // CLK = 1; #12000; CLK = 0; #12000; // $display("$t2: %h", dut.c.regfile.register10out); // $display("Program counter: %h", dut.PC); + // addi test cases. + // PC = 0 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + + // PC = 4 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd130) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd130, dut.c.regfile.register9out); + end + + // PC = 8 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd9) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd9, dut.c.regfile.register8out); + end + + // xori test cases + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 24 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + + // PC = 28 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 60 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd63) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd63, dut.c.regfile.register8out); + end + + // PC = 64 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd11) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd11, dut.c.regfile.register8out); + end + + // PC = 68 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd16) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd16, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 76 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd51) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd51, dut.c.regfile.register8out); + end + + // PC = 80 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd29) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd29, dut.c.regfile.register8out); + end + + // PC = 84 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd6) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd6, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 92 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + + // PC = 96 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + + // PC = 100 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end + CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd2) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd3) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd3) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 116 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); + end + end endmodule From 13143afb8b357e64bc6a6a23bd156f4c5056ee32 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:41:33 -0500 Subject: [PATCH 150/190] Dump new progeam from assembly --- memoryfile.text | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/memoryfile.text b/memoryfile.text index 2aad4a9..b4edc90 100644 --- a/memoryfile.text +++ b/memoryfile.text @@ -1,4 +1,8 @@ -20080001 -20090001 -08000003 -08000003 +200b0000 +200c0004 +156c0002 +216d0000 +08000007 +216b0001 +08000002 +08000007 From 4c7baf7bc9e00d6c642ccf042be744f758f07ec8 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:44:35 -0500 Subject: [PATCH 151/190] Remove unused file --- memoryfile.text | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 memoryfile.text diff --git a/memoryfile.text b/memoryfile.text deleted file mode 100644 index b4edc90..0000000 --- a/memoryfile.text +++ /dev/null @@ -1,8 +0,0 @@ -200b0000 -200c0004 -156c0002 -216d0000 -08000007 -216b0001 -08000002 -08000007 From ded75506054b72d11fcb8499db106b3aed119ae1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:45:42 -0500 Subject: [PATCH 152/190] Create small unit test programs in assembly --- AssemblyPrograms/bne_unit_test.asm | 17 ++++++ AssemblyPrograms/combined_unit_tests.asm | 74 ++++++++++++++++++++++++ AssemblyPrograms/slt_unit_test.asm | 18 ++++++ AssemblyPrograms/sub_unit_test.asm | 18 ++++++ 4 files changed, 127 insertions(+) create mode 100644 AssemblyPrograms/bne_unit_test.asm create mode 100644 AssemblyPrograms/combined_unit_tests.asm create mode 100644 AssemblyPrograms/slt_unit_test.asm create mode 100644 AssemblyPrograms/sub_unit_test.asm diff --git a/AssemblyPrograms/bne_unit_test.asm b/AssemblyPrograms/bne_unit_test.asm new file mode 100644 index 0000000..4e8aab3 --- /dev/null +++ b/AssemblyPrograms/bne_unit_test.asm @@ -0,0 +1,17 @@ +main: +addi $t3, $zero, 0 +addi $t4, $zero, 4 + +whileloop: +bne $t3, $t4, branchtaken + +saveres: +addi $t5, $t3, 0 +j end + +branchtaken: +addi $t3, $t3, 1 +j whileloop + +end: +j end diff --git a/AssemblyPrograms/combined_unit_tests.asm b/AssemblyPrograms/combined_unit_tests.asm new file mode 100644 index 0000000..05fefac --- /dev/null +++ b/AssemblyPrograms/combined_unit_tests.asm @@ -0,0 +1,74 @@ +# Test the addi command +additest: +addi $t0, $zero, 5 # $t0 = 5 +addi $t1, $t0, 125 # $t1 = 130 +addi $t0, $t0, 4 # $t0 = 9 + +# Test the xori command +xoritest: +# Reset the designated result register +addi $t0, $zero, 0 + +addi $t1, $zero, 2 +addi $t2, $zero, 11 + +xori $t0, $t1, 7 # $t0 = 5 +xori $t0, $t2, 11 # $t0 = 0 + +# Test the add command +addtest: +# Reset the designated result register +addi $t0, $zero, 0 + +# Two positive numbers +addi $t1, $zero, 6 +addi $t2, $zero, 57 + +# One positive and one negative number +addi $t3, $zero, -9 +addi $t4, $zero, 20 + +# Two negative numbers +addi $t5, $zero, -5 +addi $t6, $zero, -11 + +add $t0, $t1, $t2 # $t0 = 57 + 6 = 63 +add $t0, $t3, $t4 # $t0 = -9 + 20 = 11 +add $t0, $t5, $t6 # $t0 = -5 + -11 = -16 + +# Test the sub command +subtest: +# Reset the designated result register +addi $t0, $zero, 0 + +sub $t0, $t1, $t2 # $t0 = 57 - 6 = 51 +sub $t0, $t3, $t4 # $t0 = -9 - 20 = -29 +sub $t0, $t5, $t6 # $t0 = -5 - -11 = 6 + +# Test the slt command +slttest: +# Reset the designated result register +addi $t0, $zero, 0 + +slt $t0, $t1, $t2 # $t0 = 57 < 6 = 1 +slt $t0, $t3, $t4 # $t0 = -9 < 20 = 1 +slt $t0, $t5, $t6 # $t0 = -5 < 11 = 0 + +# Test the bne command +breginit: +addi $t3, $zero, 0 +addi $t4, $zero, 4 + +whileloop: +bne $t3, $t4, branchtaken + +saveres: +addi $t5, $t3, 0 # $t5 = 4 +j end + +branchtaken: +addi $t3, $t3, 1 +j whileloop + +end: +j end diff --git a/AssemblyPrograms/slt_unit_test.asm b/AssemblyPrograms/slt_unit_test.asm new file mode 100644 index 0000000..d063e18 --- /dev/null +++ b/AssemblyPrograms/slt_unit_test.asm @@ -0,0 +1,18 @@ +# Set Less Than unit tests +main: +addi $t1, $zero, 6 +addi $t2, $zero 57 + +addi $t3, $zero, -9 +addi $t4, $zero, 20 + +addi $t5, $zero, -5 +addi $t6, $zero, -11 + +slt $t0, $t1, $t2 +slt $t0, $t3, $t4 +slt $t0, $t5, $t6 +j end + +end: +j end \ No newline at end of file diff --git a/AssemblyPrograms/sub_unit_test.asm b/AssemblyPrograms/sub_unit_test.asm new file mode 100644 index 0000000..3dd85e3 --- /dev/null +++ b/AssemblyPrograms/sub_unit_test.asm @@ -0,0 +1,18 @@ +# Subtraction unit tests +main: +addi $t1, $zero, 6 +addi $t2, $zero 57 + +addi $t3, $zero, -9 +addi $t4, $zero, 20 + +addi $t5, $zero, -5 +addi $t6, $zero, -11 + +sub $t0, $t1, $t2 +sub $t0, $t3, $t4 +sub $t0, $t5, $t6 +j end + +end: +j end \ No newline at end of file From 4bbbc22bfe3e4f9a6ea0bdafac63bf6ab14183b4 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:46:19 -0500 Subject: [PATCH 153/190] Create memory file to write to mem.dat --- add_test.text | 11 +++++++++++ bne_test.text | 8 ++++++++ combined_unit_tests.text | 34 ++++++++++++++++++++++++++++++++++ slt_test.text | 11 +++++++++++ sub_test.text | 11 +++++++++++ 5 files changed, 75 insertions(+) create mode 100644 add_test.text create mode 100644 bne_test.text create mode 100644 combined_unit_tests.text create mode 100644 slt_test.text create mode 100644 sub_test.text diff --git a/add_test.text b/add_test.text new file mode 100644 index 0000000..be027d5 --- /dev/null +++ b/add_test.text @@ -0,0 +1,11 @@ +20090006 +200a0039 +200bfff7 +200c0014 +200dfffb +200efff5 +012a4020 +016c4020 +01ae4020 +0800000a +0800000a diff --git a/bne_test.text b/bne_test.text new file mode 100644 index 0000000..b4edc90 --- /dev/null +++ b/bne_test.text @@ -0,0 +1,8 @@ +200b0000 +200c0004 +156c0002 +216d0000 +08000007 +216b0001 +08000002 +08000007 diff --git a/combined_unit_tests.text b/combined_unit_tests.text new file mode 100644 index 0000000..21f97bd --- /dev/null +++ b/combined_unit_tests.text @@ -0,0 +1,34 @@ +20080005 +2109007d +21080004 +20080000 +20090002 +200a000b +39280007 +3948000b +20080000 +20090006 +200a0039 +200bfff7 +200c0014 +200dfffb +200efff5 +012a4020 +016c4020 +01ae4020 +20080000 +012a4022 +016c4022 +01ae4022 +20080000 +012a402a +016c402a +01ae402a +200b0000 +200c0004 +156c0002 +216d0000 +08000021 +216b0001 +0800001c +08000021 diff --git a/slt_test.text b/slt_test.text new file mode 100644 index 0000000..c3a4e97 --- /dev/null +++ b/slt_test.text @@ -0,0 +1,11 @@ +20090006 +200a0039 +200bfff7 +200c0014 +200dfffb +200efff5 +012a402a +016c402a +01ae402a +0800000a +0800000a diff --git a/sub_test.text b/sub_test.text new file mode 100644 index 0000000..3f6cf12 --- /dev/null +++ b/sub_test.text @@ -0,0 +1,11 @@ +20090006 +200a0039 +200bfff7 +200c0014 +200dfffb +200efff5 +012a4022 +016c4022 +01ae4022 +0800000a +0800000a From e60a622ade411cdf2c9a47aa4f68393686562d62 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 16:46:47 -0500 Subject: [PATCH 154/190] Modify test strategy --- AssemblyPrograms/testCPU.asm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/AssemblyPrograms/testCPU.asm b/AssemblyPrograms/testCPU.asm index e1ff115..774d6e8 100644 --- a/AssemblyPrograms/testCPU.asm +++ b/AssemblyPrograms/testCPU.asm @@ -1,17 +1,17 @@ -# Test commands for the CPU -testaddi: -addi $t0, $zero, 1 -addi $t1, $zero, 10 -j testslt +main: +addi $t3, $zero, 0 +addi $t4, $zero, 4 -addi $t1, $zero, 4 +whileloop: +bne $t3, $t4, branchtaken -testslt: -#sw $t0, 0($sp) -addi $t1, $zero, 4 +saveres: +addi $t5, $t3, 0 j end -end: -j end +branchtaken: +addi $t3, $t3, 1 +j whileloop -.data \ No newline at end of file +end: +j end \ No newline at end of file From 6eedb46c7eecd622c05d8aa76d84de016b73163d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 17:03:26 -0500 Subject: [PATCH 155/190] Finish running through unit tests --- CPU.t.v | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index edb3633..64be663 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -130,8 +130,8 @@ module testCPU (); // PC = 76 CLK = 1; #12000; CLK = 0; #12000; $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd51) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd51, dut.c.regfile.register8out); + if (dut.c.regfile.register8out != -32'd51) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd51, dut.c.regfile.register8out); end // PC = 80 @@ -208,8 +208,8 @@ module testCPU (); // PC = 124 CLK = 1; #12000; CLK = 0; #12000; $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd3) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); + if (dut.c.regfile.register11out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register11out); end CLK = 1; #12000; CLK = 0; #12000; @@ -218,10 +218,13 @@ module testCPU (); // PC = 116 CLK = 1; #12000; CLK = 0; #12000; $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd4) begin + if (dut.c.regfile.register13out != 32'd4) begin $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); end + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + end endmodule From 6edc04f3463e3809bbfd68311d5459b79d834cd2 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 16 Nov 2017 17:55:40 -0500 Subject: [PATCH 156/190] Partway done with README.md --- README.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 98c1b9f..c2208c3 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,41 @@ -# CompArch Lab 3: CPU +# Single Cycle CPU -**Work Plan due:** Monday, November 6 +### Computer Architecture Fall 2017 +#### Ariana Olson, Andrew Pan, Jonah Spear -**Assembly test due:** Tuesday, November 14 before class +The goal of this project lab was to design, create, and test a 32-bit CPU. We chose to implement a single-cycle CPU given that time was a large constraint (we had <2 weeks from start to finish). -**Lab due:** Friday, November 17 +## Design -The goal of this lab is to design, create, and test a 32-bit CPU. - -You will work in groups of 2-4. You may shuffle teams if you so choose. You should consider the complexity of processor design (e.g. single-cycle, pipelined) you plan to attempt while forming teams. +We designed our 32-bit MIPS-subset CPU to support the following instructions: + LW, SW, J, JR, JAL, BNE, XORI, ADDI, ADD, SUB, SLT -## Work Plan ## +We felt this would give us a good mix of simplicity, while still allowing the execution of complex programs. -Draft a work plan for this lab, which should include the type of processor you plan to design. Regardless of the final design you choose, we recommend that you start by building a working single-cycle CPU. Break down the lab in to small portions, and for each portion predict how long it will take (in hours) and when it will be done by (date). +## Architechture -We strongly suggest you include a mid-point check in with course staff in your plan. One good thing to do at this check-in or earlier would be to review your block diagram. +Our first step in designing our CPU was to create a block diagram with which could successfully run every type of instruction that we needed. -Use your work plan reflections from the previous labs to help with this task. You will reflect on your actual path vs. the work plan at the end of the lab. +# Insert picture of block diagram was needed -**Submit this plan by November 6** by pushing `work_plan.txt` to GitHub. (Markdown/PDF format also OK) Include team member names in your work plan, especially if you have reshuffled. +Once that was completed, we made a table mapping instruction type to control signal value. +# Insert control Table Here -## Processor ## +Clearly defining the structure of our processor from an early made final implementation and debugging much easier. -Create a 32-bit MIPS-subset CPU that supports (at least) the following instructions: - LW, SW, J, JR, JAL, BNE, XORI, ADDI, ADD, SUB, SLT - -You may choose any processor design style you like (single-cycle, multi-cycle, pipelined) as long as it implements this subset of the ISA. +## Testing -Every module of Verilog you write must be **commented and tested**. Running assembly programs only tests the system at a high level – each module needs to be unit tested on its own with a Verilog test bench. Include a master script that runs your entire test suite. +Our testing approach was as follows: +1. Unit test every sub-module +2. Unit test top-level module with each instruction type +3. Integration test top-level module with test assmebly programs. +You can run our tests using the following command: +#Insert testing command here ## Programs ## From efd09126ffa02e4f6d2834c36cdcc95db7627d76 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 18:26:27 -0500 Subject: [PATCH 157/190] fixed load word timing issue --- CPU.t.v | 327 +++++++++++++++++++++++++++++++++++-------------- Core/memory.v | 4 +- Core/regfile.v | 4 +- 3 files changed, 237 insertions(+), 98 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 64be663..96dba78 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -59,171 +59,308 @@ module testCPU (); // PC = 0 CLK = 1; #12000; CLK = 0; #12000; $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd5) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); - end - - // PC = 4 + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd130) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd130, dut.c.regfile.register9out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 8 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd9) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd9, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // xori test cases CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 24 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd5) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 28 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd0) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 60 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd63) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd63, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 64 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd11) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd11, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 68 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd16) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd16, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 76 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd51) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd51, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 80 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd29) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd29, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 84 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd6) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd6, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 92 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 96 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 100 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd0) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register11out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd2) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd3) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd4) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register11out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - // PC = 116 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register13out != 32'd4) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); - end + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); end diff --git a/Core/memory.v b/Core/memory.v index 1d3e0e8..4b49712 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -10,7 +10,7 @@ module memory ) ( input clk, - output reg [width-1:0] dataOut, + output [width-1:0] dataOut, input [addresswidth-1:0] address, input writeEnable, input [width-1:0] dataIn @@ -22,8 +22,8 @@ module memory always @(negedge clk) begin if(writeEnable) memory[address] <= dataIn; - dataOut <= memory[address]; end + assign dataOut = memory[address]; initial $readmemh("Core/data_memory.dat", memory); diff --git a/Core/regfile.v b/Core/regfile.v index 9ebc916..aea9c3a 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -89,7 +89,7 @@ input Clk // Clock (Positive Edge Triggered) register32 reg26 (register26out, WriteData, decoderOut[26], Clk); register32 reg27 (register27out, WriteData, decoderOut[27], Clk); register32 reg28 (register28out, WriteData, decoderOut[28], Clk); - register32 reg29 (register29out, WriteData, decoderOut[29], Clk); + // register32 reg29 (register29out, WriteData, decoderOut[29], Clk); register32 reg30 (register30out, WriteData, decoderOut[30], Clk); register32 reg31 (register31out, WriteData, decoderOut[31], Clk); @@ -111,4 +111,6 @@ input Clk // Clock (Positive Edge Triggered) register22out, register23out, register24out, register25out, register26out, register27out, register28out, register29out, register30out, register31out); + assign register29out = 32'b00000000000000000000000000000000; + endmodule \ No newline at end of file From a0f6b2f11dacc9941ca52e42b336425a61b00378 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 18:26:54 -0500 Subject: [PATCH 158/190] Add clock cycles to run to program end --- CPU.t.v | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CPU.t.v b/CPU.t.v index 64be663..db0fa62 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,7 +11,7 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); - $dumpvars(0, testCPU, dut.c.datamemory.memory[8]); + $dumpvars(0, testCPU, dut.c.datamemory.memory[4095]); // // add $t1, $zero, $zero // mem[0] = 32'h00004820; @@ -225,6 +225,17 @@ module testCPU (); CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + end endmodule From 24a95258d913c04e521fd2d2654ca8ae72591564 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 18:28:26 -0500 Subject: [PATCH 159/190] set CPU.t.v back to unit tests --- CPU.t.v | 327 ++++++++++++++++---------------------------------------- 1 file changed, 95 insertions(+), 232 deletions(-) diff --git a/CPU.t.v b/CPU.t.v index 96dba78..64be663 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -59,308 +59,171 @@ module testCPU (); // PC = 0 CLK = 1; #12000; CLK = 0; #12000; $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + + // PC = 4 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd130) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd130, dut.c.regfile.register9out); + end + // PC = 8 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd9) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd9, dut.c.regfile.register8out); + end + // xori test cases CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 24 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + // PC = 28 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 60 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd63) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd63, dut.c.regfile.register8out); + end + // PC = 64 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd11) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd11, dut.c.regfile.register8out); + end + // PC = 68 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd16) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd16, dut.c.regfile.register8out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 76 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd51) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd51, dut.c.regfile.register8out); + end + // PC = 80 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd29) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd29, dut.c.regfile.register8out); + end + // PC = 84 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd6) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd6, dut.c.regfile.register8out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 92 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + // PC = 96 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + // PC = 100 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register11out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd2) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd3) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 124 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register11out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + // PC = 116 CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register13out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); + end CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); end From a4244e9cc07382c9aba1c53a022e9566ed42f2e2 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 18:29:26 -0500 Subject: [PATCH 160/190] Start adding lw tests --- AssemblyPrograms/combined_unit_tests.asm | 20 ++++++++++++++++++-- combined_unit_tests.text | 8 +++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/AssemblyPrograms/combined_unit_tests.asm b/AssemblyPrograms/combined_unit_tests.asm index 05fefac..54a0924 100644 --- a/AssemblyPrograms/combined_unit_tests.asm +++ b/AssemblyPrograms/combined_unit_tests.asm @@ -41,7 +41,7 @@ subtest: # Reset the designated result register addi $t0, $zero, 0 -sub $t0, $t1, $t2 # $t0 = 57 - 6 = 51 +sub $t0, $t1, $t2 # $t0 = 6 - 57 = -51 sub $t0, $t3, $t4 # $t0 = -9 - 20 = -29 sub $t0, $t5, $t6 # $t0 = -5 - -11 = 6 @@ -64,11 +64,27 @@ bne $t3, $t4, branchtaken saveres: addi $t5, $t3, 0 # $t5 = 4 -j end +j swtest branchtaken: addi $t3, $t3, 1 j whileloop +swtest: +addi $sp, $zero, 16380 +addi $t1, $zero, 2 +addi $t2, $zero, 169 + +sw $t1, 0($sp) +sw $t2, 4($sp) + +lwtest: +lw $t3, 0($sp) # $t3 = $t1 = 2 +lw $t4, 4($sp) # $t4 = $t2 = 169 + + + + + end: j end diff --git a/combined_unit_tests.text b/combined_unit_tests.text index 21f97bd..d837b0c 100644 --- a/combined_unit_tests.text +++ b/combined_unit_tests.text @@ -31,4 +31,10 @@ 08000021 216b0001 0800001c -08000021 +20090002 +200a00a9 +afa90000 +afaa0004 +8fab0000 +8fac0004 +08000027 From 7fb5c6151882fd119cc0a6e1bf822293ab0318e6 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 16 Nov 2017 18:43:42 -0500 Subject: [PATCH 161/190] Add Control Signal Table to Readme --- README.md | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index c2208c3..8462e7e 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,22 @@ Our first step in designing our CPU was to create a block diagram with which cou Once that was completed, we made a table mapping instruction type to control signal value. -# Insert control Table Here - -Clearly defining the structure of our processor from an early made final implementation and debugging much easier. - +Instruction | RegDst | ALUSrc | RegWR | MemWr | ALUCtrl | MemToReg | PCSel | AddSel | +:----------:|:------:|:------:|:-----:|:-----:|:-------:|:--------:|:-----:|:------:| +LW | 1 | 1 | 1 | 0 | Add | 1 | 1 | 0 | +SW | x | 1 | 0 | 1 | Add | x | 1 | 0 | +J | x | x | 0 | 0 | x | x | 0 | 0 | +JR | x | x | 0 | 0 | x | x | 2 | 0 | +JAL | 2 | x | 1 | 0 | x | 2 | 0 | 0 | +BNE | x | 0 | 0 | 0 | Sub | x | 1 | 1 | +XORI | 1 | 1 | 1 | 0 | Xor | 0 | 1 | 0 | +ADDI | 1 | 1 | 1 | 0 | Add | 0 | 1 | 0 | +ADD | 0 | 0 | 1 | 0 | Add | 0 | 1 | 0 | +SUB | 0 | 0 | 1 | 0 | Sub | 0 | 1 | 0 | +SLT | 0 | 0 | 1 | 0 | Slt | 0 | 1 | 0 | + + +Clearly defining the structure of our processor andn our control signal mapping from an early point made final implementation and debugging much easier. ## Testing @@ -35,7 +47,7 @@ Our testing approach was as follows: You can run our tests using the following command: -#Insert testing command here +# Insert testing command here ## Programs ## @@ -43,21 +55,6 @@ You will write, assemble and run a set of programs on your CPU that act as a hig We will work on one test program (Fibonacci) in class. In addition, you must write (at least) one test assembly program of your own. We will collect these test programs and redistribute them to all teams, so that you have a richer variety of assembly tests for your processor. -### Submitting your test program ### - -**Due: November 14 before class** by GitHub pull request - -In addition to your actual test assembly code, write a short README with: - - Expected results of the test - - Any memory layout requirements (e.g. `.data` section) - - Any instructions used outside the basic required subset (ok to use, but try to submit at least one test program everyone can run) - -Submit the test program and README by submitting a pull request to the main course repository. Code should be in `/asmtest//` (you may use subfolders if you submit multiple tests). - -After submitting your test program, you may use any of the programs written by your peers to test your processor. - - - ## Deliverables ## **Due: Friday, November 17** by pushing to GitHub and submitting a pull request From 25a6affcee443babcdd81a5eee92155c6111e990 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 19:09:23 -0500 Subject: [PATCH 162/190] added cpu fib test --- CPU_fib.t.v | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 CPU_fib.t.v diff --git a/CPU_fib.t.v b/CPU_fib.t.v new file mode 100644 index 0000000..4451de7 --- /dev/null +++ b/CPU_fib.t.v @@ -0,0 +1,25 @@ +`include "CPU.v" + +module testCPU (); + + reg CLK; + reg[31:0] mem [16:0]; + integer i; + + CPU dut (.CLK(CLK)); + + initial begin + $dumpfile("CPU.vcd"); + $dumpvars(0, testCPU, dut.c.datamemory.memory[8]); + + for (i = 0; i < 100; i = i + 1) begin + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + $display("$at: %h", dut.c.regfile.register1out); + $display("$a0: %h", dut.c.regfile.register4out); + $display("$ra: %h", dut.c.regfile.register31out); + $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + end + end + +endmodule From fa10da0ca3e64486328abbc18b582e97a13407e4 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 19:22:56 -0500 Subject: [PATCH 163/190] Finish unit tests --- AssemblyPrograms/combined_unit_tests.asm | 14 ++++-- CPU.t.v | 61 +++++++++++++++++++++++- 2 files changed, 70 insertions(+), 5 deletions(-) diff --git a/AssemblyPrograms/combined_unit_tests.asm b/AssemblyPrograms/combined_unit_tests.asm index 54a0924..fcee0a5 100644 --- a/AssemblyPrograms/combined_unit_tests.asm +++ b/AssemblyPrograms/combined_unit_tests.asm @@ -76,15 +76,21 @@ addi $t1, $zero, 2 addi $t2, $zero, 169 sw $t1, 0($sp) -sw $t2, 4($sp) +sw $t2, -4($sp) lwtest: lw $t3, 0($sp) # $t3 = $t1 = 2 -lw $t4, 4($sp) # $t4 = $t2 = 169 - - +lw $t4, -4($sp) # $t4 = $t2 = 169 +jaltest: +addi $t1, $zero 100 # $t1 = 100 +jal jrtest +addi $t1, $t1, 1 # $t1 = 102 +j end +jrtest: +addi $t1, $t1, 1 # $t1 = 101 +jr $ra end: j end diff --git a/CPU.t.v b/CPU.t.v index db0fa62..0ef1396 100644 --- a/CPU.t.v +++ b/CPU.t.v @@ -11,7 +11,7 @@ module testCPU (); initial begin $dumpfile("CPU.vcd"); - $dumpvars(0, testCPU, dut.c.datamemory.memory[4095]); + $dumpvars(0, testCPU); // // add $t1, $zero, $zero // mem[0] = 32'h00004820; @@ -223,15 +223,74 @@ module testCPU (); end CLK = 1; #12000; CLK = 0; #12000; + + // PC = 132 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register29out != 32'd16380) begin + $display("Error at register $sp. Expected value: %h, actual value: %h", 32'd16380, dut.c.regfile.register29out); + end + // PC = 136 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd2) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register9out); + end + + // PC = 140 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register10out != 32'd169) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register10out); + end + CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; + + // PC = 152 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd2) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); + end + + // PC = 156 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register12out != 32'd169) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register12out); + end + + // PC = 160 CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd100) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd100, dut.c.regfile.register9out); + end + + // PC = 164 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register31out != 32'd168) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd168, dut.c.regfile.register31out); + end + + // PC = 176 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd101) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd101, dut.c.regfile.register9out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 168 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd102) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd102, dut.c.regfile.register9out); + end CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; CLK = 1; #12000; CLK = 0; #12000; From f48258db5068ad603c48af9da6572d737572df1a Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 19:23:44 -0500 Subject: [PATCH 164/190] Uncomment and unhardcode reg29 --- Core/regfile.v | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/regfile.v b/Core/regfile.v index aea9c3a..9ebc916 100644 --- a/Core/regfile.v +++ b/Core/regfile.v @@ -89,7 +89,7 @@ input Clk // Clock (Positive Edge Triggered) register32 reg26 (register26out, WriteData, decoderOut[26], Clk); register32 reg27 (register27out, WriteData, decoderOut[27], Clk); register32 reg28 (register28out, WriteData, decoderOut[28], Clk); - // register32 reg29 (register29out, WriteData, decoderOut[29], Clk); + register32 reg29 (register29out, WriteData, decoderOut[29], Clk); register32 reg30 (register30out, WriteData, decoderOut[30], Clk); register32 reg31 (register31out, WriteData, decoderOut[31], Clk); @@ -111,6 +111,4 @@ input Clk // Clock (Positive Edge Triggered) register22out, register23out, register24out, register25out, register26out, register27out, register28out, register29out, register30out, register31out); - assign register29out = 32'b00000000000000000000000000000000; - endmodule \ No newline at end of file From 08422fcb2d2859b8e34f32b34f1cbcb70936acb0 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 19:41:53 -0500 Subject: [PATCH 165/190] added a fib test to make --- makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index 9f6cc95..44afd52 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,13 @@ -all: core alu regfile memory signextend CPU +all: core alu regfile memory signextend CPU CPU_fib ### CPU Module CPU: CPU.v CPU.t.v iverilog -Wall -o CPU.out CPU.t.v +### CPU fib +CPU_fib: CPU.v CPU_fib.t.v + iverilog -Wall -o CPU_fib.out CPU_fib.t.v + ### PC_Calc Modules # PC_Calc top level module PC_Calc: PC_Calc/PC_Calc.v PC/PC_Calc.t.v addr_concat imm_concat is_zero_and From 8288225b2df273c8406720d6be7d486155fa421d Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 20:58:20 -0500 Subject: [PATCH 166/190] Change size of memory --- Core/memory.v | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/memory.v b/Core/memory.v index 4b49712..2b0ee75 100644 --- a/Core/memory.v +++ b/Core/memory.v @@ -5,7 +5,7 @@ The memory used in the CPU module memory #( parameter addresswidth = 32, - parameter depth = addresswidth, + parameter depth = addresswidth * 2, parameter width = 32 ) ( @@ -21,9 +21,9 @@ module memory always @(negedge clk) begin if(writeEnable) - memory[address] <= dataIn; + memory[address >> 2] <= dataIn; end - assign dataOut = memory[address]; + assign dataOut = memory[address >> 2]; initial $readmemh("Core/data_memory.dat", memory); From 6368ed235a1b18059c9895ef1a9739be72efa052 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 20:58:37 -0500 Subject: [PATCH 167/190] Initialize smaller sp --- AssemblyPrograms/combined_unit_tests.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AssemblyPrograms/combined_unit_tests.asm b/AssemblyPrograms/combined_unit_tests.asm index fcee0a5..d01a84b 100644 --- a/AssemblyPrograms/combined_unit_tests.asm +++ b/AssemblyPrograms/combined_unit_tests.asm @@ -71,7 +71,7 @@ addi $t3, $t3, 1 j whileloop swtest: -addi $sp, $zero, 16380 +addi $sp, $zero, 64 addi $t1, $zero, 2 addi $t2, $zero, 169 From 3612a7e29a7a91b958f549466bfd47f6cdf49cb1 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 16 Nov 2017 21:22:08 -0500 Subject: [PATCH 168/190] Add static images --- Static/Core.png | Bin 0 -> 35165 bytes Static/Instruction Parser.png | Bin 0 -> 24711 bytes Static/PC Calc.png | Bin 0 -> 31152 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Static/Core.png create mode 100644 Static/Instruction Parser.png create mode 100644 Static/PC Calc.png diff --git a/Static/Core.png b/Static/Core.png new file mode 100644 index 0000000000000000000000000000000000000000..317336939450c6869fe02cfbadf76c86788df466 GIT binary patch literal 35165 zcmce;1yq#L_cl7pAOnJqgeWQ5Tw-O@V4GKzk=OEJE zImA7K{{COxyY6@IUF*)Q<-(cwJ?}aD?0ELG_nG&K@)AS@6a)|mgh)#AsS*SNML{5! z(_mM?C+-EGJRlHnh}2W0iu2g&WwDJN?Aw-AB1ywG%p) zZEMf9_Iw|khQ=+InSOZ^NY`BSuyNvOt?ON{v17XSTFx8C`s4){+Mct-$;8Bi#Hl(j zLL4x&|DRsoe+nCz<2gT7aUGcb@#LM%XK3zzi#dwch{Kdx*Vmw}cA&q0d%9HX%EV!Q zR_MwfXob&va!;^jVz|>Qb*T^9S57GyDs*uU+Lt{`UYM-(4b6F$IGC*5{NpM29RKZ* z)~|$=G>mtsO?|?8w4`0V{Caf%=^vBz;r7#Q*ZTJ%Bv%gF$4_1RCm6dnXqE}KN+0vIlfN?GXpCy}fA^?-lwnZ2$z8-yg`mJxm z3J*KCeR)N~_2_cUnxtJaGxpJsjlTY@)ZIVON}Ts3nqbR6kdd{nhyKqGxZ+XYg)h3R z_`)LdIDDxA`oFmuPeY>o2DaZg)R6tX;YC03cK8b+AtlPI7azbmpvb@9(4!Eri@#Ey z!l9Qg{`v$%Auj&#CPu>lK2h;545%vhCH*w5C~{DZ_e~^&5YOL_{%`+9Ac&rsx)k%F zv8oT0JV)I0=upz)!NvbXTK@N*3q`^q5XtN@=9S#-995kn=}c{%BDQ`9)fzc4PWZ)4 zn@oz@%+ziduApVb%b&BWbdLkmg1d&dsi|qr#Y{fIg+PwTi&r!`13rrw^H|;aJAuPN zjX6}f7HpO^Un4!JoaEwDL;@GNqL3&eQ{b1@-)Y0;^C_3a5JdOwRd z($Ue)D=P>(6n_5vXCX2&GL%x5h5({h+_8Dx#gkPc>x@k?9Y%pguyzvr1H z9k;<6FCF&-i=uI5BjKp(oPvCo;&abQbRAF70P#2O+cXNpYwSvb30>m{{g3NjrHK}p zI?@4=-3iykDvQ=KDKxe$DT$`IuyAWZUDu_sq{#3(DA6)g^0jVp$23_z=ib z2ojE(zJ{V|4yEPMFC4KpG@Rq)in)X!?IXIHegC^18@JLW*)o=oSv(3EE+6`Ek==&Q zvK#DAYR}dml&`#eiw64VorQpjvY((3OB)+JwC-Wvc8&fVpL}G40@7!8KAtWRu0$ylq=ZY-i zVho@VMGcwYT|rA!8ck~LvtxE~OI%SS2<}0~Yv)hcuPv)s8xHztB1AiPN4@JV7 z3{Z$>pgb8QzH6H92$8s78weiCsZ{tG{ z#tv}{6a4Qnjua8`BYcx9uKL8?Hs}`5uM^5b2QKd?fkW|C!TJQpnUeS24^N7SP*mis zFWEP0cDhnWi;d2M!;gmbAm0blRt!lD;GZnd5)bdK$Fu%6iJe_@l-)d}Sf1l~usVvr zUXG4&Mq_OJ>}9!OAM5Ib?B?1ct<=@j&U##1o}pDCE!lkfw%NvV z{+BV^QWJT01l{Bc#kJiomeH&*X)u>1wdd`nKSzIoF%&trZ$NqFlLSn<;(0dKfLN-p z$aLa}2$_6*QxE^b*WPSWLc4-X$36RC^4kj}6p2pNT0*59LPMtv{(7{^RwMX5A0MB2 z^7_MHSgBb>O^tht z(ECe}*=I!F_IJ8SBHV)-P1dKZf|6IgY9CeV2zs9QN18;kS#`(1^g%4`S5BFcOfYf~ z-3J5Hy>4%oFx8jQ4nu~0sjeP>S!B?vRczFKmh?ku2f{vh%stNj)f|O6_Twjz_4lyk zfAYgdU{dM8^G>G<3Q|L7>_5}UD(I)@Ebc? zQ^!LXGBPq@HWn64=*0$Hlo4}BsrJ@iAN;}sDHoaZ( zPQSm(a)Go&H6+@zyqi-}GjL|@+;|)|T}P3WKG>}DNa?Lo)p%*T%Sjd#x&1L*=$lS!H_x^L;4_^W!P$We}I61u3P?=Jw`Nd4)HcO_RF{5!8KHNl>JjV zuw!IE(4BgO>f3`Pn!?lInO+3r&-j4=d~XA{_(&TWRy=UxPekd@%*=e&Ird4_odUvc z5_grcKP+EX-0s|f^KE@Y%3G==2|-5=+*4&D)KkH<<-`2#uR~+_M>1ecO8Lrqyvy-n54gfQDsfx4*1$-ckUO;@r^SJR7VN zyqNAD`zcKJxe5MS`c~(J!Zfdq(>t>$H{68s%5)0vbZ~A&MMqx;?$@L9H~GtpTcnjT zwQJgPx4(rGxNz(d22w(i`o51~w!8cLadL8UKI+;IgSckOl!qmMpYRX_h8L!X-EwKX zm$;0){Ud)7p;8{%;-k8f1kEg`>a_0!-wth#NUy6yn_F5wKG>MD+CMm0;D+-#u8!aV zgP@7yHjA2fW?E1N!UWEV%YXn?LYgO6aUzPquhM-V~y;2-pk6qpkJ@wsH&=RJZQ^&`}R_Cdiq>0aE)HvO4BrdXKG7e z&n4T!|Dwb-knna^N^`8j{3AND%e-QN_LXYN_{=cdH@hJ!z`1u}B8c?)`1m@uw{3Si zVmWWCpDQt`sH>B=SQqwZD#Y(BbgLum8?e>@ULrQ%IF!D`0Ux4)%SK?deA(F?7nz~Z zt5m7rj7Dhh2QHj-Z5Bc?D$0!3546x

O;th#jq8!Q1g{vu^*7&7c(|2Mtv(eClr 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 Date: Thu, 16 Nov 2017 21:26:37 -0500 Subject: [PATCH 169/190] Add images to README --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8462e7e..22a67ea 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,13 @@ We felt this would give us a good mix of simplicity, while still allowing the ex ## Architechture -Our first step in designing our CPU was to create a block diagram with which could successfully run every type of instruction that we needed. +Our first step in designing our CPU was to create a block diagram with which could successfully run every type of instruction that we needed. We split up our CPU into 3 major components, so that we could each work on them in parallel. -# Insert picture of block diagram was needed +![Instruction Parser Diagram](https://github.com/arianaolson419/Lab3/blob/master/Static/Instruction%20Parser.png "Instruction Parser Diagram") + +![PC Calc Diagram](https://github.com/arianaolson419/Lab3/blob/master/Static/PC%20Calc.png "PC Calc Diagram") + +![Core Diagram](https://github.com/arianaolson419/Lab3/blob/master/Static/Core.png "Core Diagram") Once that was completed, we made a table mapping instruction type to control signal value. From 1b194d1b6f597de7d68b1055d369bf9d546e40ef Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 21:27:26 -0500 Subject: [PATCH 170/190] added to design section --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8462e7e..aa7680a 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ We designed our 32-bit MIPS-subset CPU to support the following instructions: We felt this would give us a good mix of simplicity, while still allowing the execution of complex programs. +We broke up our single-cycle CPU design into three main components: an instruction parser, a PC calculator, and a core module. The instruction parser decoded instructions from instruction memory directly into the control signals we used for the various components in our other modules. Our PC calculator handled the changes that needed to be made to the program counter based on information from the various J-type instructions. Finally, our core module handled the main functions performed by R and I-type instructions, handling calculations and load/store word operations. + ## Architechture Our first step in designing our CPU was to create a block diagram with which could successfully run every type of instruction that we needed. @@ -36,7 +38,7 @@ SUB | 0 | 0 | 1 | 0 | Sub | 0 | 1 | 0 SLT | 0 | 0 | 1 | 0 | Slt | 0 | 1 | 0 | -Clearly defining the structure of our processor andn our control signal mapping from an early point made final implementation and debugging much easier. +Clearly defining the structure of our processor and our control signal mapping from an early point made final implementation and debugging much easier. ## Testing From eec21d18cc3eb0612fe117cfa0644995e1d897f3 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 21:36:17 -0500 Subject: [PATCH 171/190] added to testing section --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index fd52c23..0e2584e 100644 --- a/README.md +++ b/README.md @@ -51,10 +51,13 @@ Our testing approach was as follows: 2. Unit test top-level module with each instruction type 3. Integration test top-level module with test assmebly programs. + You can run our tests using the following command: # Insert testing command here +We tested our CPU with unit tests and assembly program tests that attempted to use all of the implemented operations in various patterns. After using the tests and GTKWAVE to examine the waveforms of our CPU, we identified and fixed all of the bugs that prevented our test cases from running correctly. + ## Programs ## You will write, assemble and run a set of programs on your CPU that act as a high-level test-bench. These programs need to exercise all of the portions of your design and give a clear pass/fail response. From 29c129381bdf5e5e2180ca3c8660bfe0dd522f89 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 21:43:26 -0500 Subject: [PATCH 172/190] added work plan section --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e2584e..14e145d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ We designed our 32-bit MIPS-subset CPU to support the following instructions: We felt this would give us a good mix of simplicity, while still allowing the execution of complex programs. -We broke up our single-cycle CPU design into three main components: an instruction parser, a PC calculator, and a core module. The instruction parser decoded instructions from instruction memory directly into the control signals we used for the various components in our other modules. Our PC calculator handled the changes that needed to be made to the program counter based on information from the various J-type instructions. Finally, our core module handled the main functions performed by R and I-type instructions, handling calculations and load/store word operations. +We broke up our single-cycle CPU design into three main components: an instruction parser, a PC calculator, and a core module. The instruction parser decoded instructions from instruction memory directly into the control signals we used for the various components in our other modules. Our PC calculator handled the changes that needed to be made to the program counter based on information from the various J-type instructions. Finally, our core module addressed the main functions performed by R and I-type instructions, handling calculations and load/store word operations. ## Architechture @@ -58,6 +58,10 @@ You can run our tests using the following command: We tested our CPU with unit tests and assembly program tests that attempted to use all of the implemented operations in various patterns. After using the tests and GTKWAVE to examine the waveforms of our CPU, we identified and fixed all of the bugs that prevented our test cases from running correctly. +## Work Plan Reflection + +We created a work plan and allocated sufficient amount of time for each section of the plan in the event that we encountered roadblocks during our CPU creation. We actually stayed on track with our work plan throughout the majority of this lab, only having to spend a couple of extra hours for the debugging of our module integration. Overall, we effectively managed our time thanks to a proper amount of planning in the beginning of the lab and communication amongst team members as we worked on our individual sections. + ## Programs ## You will write, assemble and run a set of programs on your CPU that act as a high-level test-bench. These programs need to exercise all of the portions of your design and give a clear pass/fail response. From 6adab282ca35f84e48ccf484a947e865e22a06c4 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 16 Nov 2017 21:57:15 -0500 Subject: [PATCH 173/190] Delete extra stuff in README --- README.md | 78 ------------------------------------------------------- 1 file changed, 78 deletions(-) diff --git a/README.md b/README.md index 14e145d..1a7a500 100644 --- a/README.md +++ b/README.md @@ -61,81 +61,3 @@ We tested our CPU with unit tests and assembly program tests that attempted to u ## Work Plan Reflection We created a work plan and allocated sufficient amount of time for each section of the plan in the event that we encountered roadblocks during our CPU creation. We actually stayed on track with our work plan throughout the majority of this lab, only having to spend a couple of extra hours for the debugging of our module integration. Overall, we effectively managed our time thanks to a proper amount of planning in the beginning of the lab and communication amongst team members as we worked on our individual sections. - -## Programs ## - -You will write, assemble and run a set of programs on your CPU that act as a high-level test-bench. These programs need to exercise all of the portions of your design and give a clear pass/fail response. - -We will work on one test program (Fibonacci) in class. In addition, you must write (at least) one test assembly program of your own. We will collect these test programs and redistribute them to all teams, so that you have a richer variety of assembly tests for your processor. - -## Deliverables ## - -**Due: Friday, November 17** by pushing to GitHub and submitting a pull request - - Verilog and test benches for your processor design - - Assembly test(s) with README - - Any necessary scripts - - Report (PDF or MarkDown), including: - - Written description and block diagram of your processor architecture. Consider including selected RTL to capture how instructions are implemented. - - Description of your test plan and results - - Some performance/area analysis of your design. This can be for the full processor, or a case study of choices made designing a single unit. It can be based on calculation, simulation, Vivado synthesis results, or a mix of all three. - - Work plan reflection - - -Each team will also demo their work in class after break. - - -## Notes/Hints ## - -### Design Reuse ### -You may freely reuse code created for previous labs, even code written by another team or the instructors. Reusing code does not change your obligation to understand it and provide appropriate test benches. - -**Each example of reuse should be documented.** - -### Synthesis ### -You are **not** required to implement your design on FPGA. You may want to synthesize your design (or parts of it) with Vivado to collect performance/area data. - -### Assembling ### -[MARS](http://courses.missouristate.edu/kenvollmar/mars/) is a very nice assembler. It allows you to see the machine code (actual bits) of the instructions, which is useful for debugging. - - -### Psuedo-Instructions ### -There are many instructions supported by MARS that aren’t "real" MIPS instructions, but instead map onto other instructions. Your processor should only implement instructions from the actual MIPS ISA (see the [Instruction Reference sheet](https://sites.google.com/site/ca16fall/resources/mips) for a complete listing). - -### Initializing Memory ### -You can initialize a memory (e.g. data memory or instruction memory) from a file with `$readmemb` or `$readmemh`. This will make your life very much easier! - -For example, you could load a program into your data memory by putting your machine code in hexadecimal format in a file named `file.dat` and using something like this for your instruction memory. - -```verilog -module memory -( - input clk, regWE, - input[9:0] Addr, - input[31:0] DataIn, - output[31:0] DataOut -); - - reg [31:0] mem[1023:0]; - - always @(posedge clk) begin - if (regWE) begin - mem[Addr] <= DataIn; - end - end - - initial $readmemh(“file.dat”, mem); - - assign DataOut = mem[Addr]; -endmodule -``` - -You may need to fiddle with the `Addr` bus to make it fit your design, depending on how you handle the "address is always a multiple of 4" (word alignment) issue. - -This memory initialization only works in simulation; it will be ignored by Vivado (which is ok). - -### Memory Configuration ### - -In MARS, go to "Settings -> Memory Configuration". Changing this to "Compact, Text at Address 0" will give you a decent memory layout to start with. This will put your program (text) at address `0`, your data at address `0x1000`, and your stack pointer will start at `0x3ffc`. - -You will need to manually set your stack pointer in your Verilog simulation. This is done automatically for you in MARS. - From 766a93c56157dcb9396a7e13c1ae359ec76f4ced Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 22:01:27 -0500 Subject: [PATCH 174/190] reused components section added to design --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 14e145d..a7a1f08 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ We felt this would give us a good mix of simplicity, while still allowing the ex We broke up our single-cycle CPU design into three main components: an instruction parser, a PC calculator, and a core module. The instruction parser decoded instructions from instruction memory directly into the control signals we used for the various components in our other modules. Our PC calculator handled the changes that needed to be made to the program counter based on information from the various J-type instructions. Finally, our core module addressed the main functions performed by R and I-type instructions, handling calculations and load/store word operations. +We re-used and modified some modules from previous labs and homework so that we wouldn't have to reimplement a lot of work from scratch. Specifically, we re-used and modified the ALU, register, data memory, muxes, and DFF gates for our CPU. The ALU, register, and data memory were all used in our core module, muxes were used in both the core module and PC calculator, and a DFF gate was used for our program counter. + ## Architechture Our first step in designing our CPU was to create a block diagram with which could successfully run every type of instruction that we needed. We split up our CPU into 3 major components, so that we could each work on them in parallel. From 81ec16dd63f71a20c8a0064175bfe456a6621202 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 22:04:40 -0500 Subject: [PATCH 175/190] added commands for tests --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 703ce12..8729514 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,13 @@ Our testing approach was as follows: 3. Integration test top-level module with test assmebly programs. -You can run our tests using the following command: +You can run our tests using the following commands: + +~~~chmod 755 run_tests.sh~~~ +*Needs to be run once in order for the file to be executed* + +~~~./run_tests.sh~~~ -# Insert testing command here We tested our CPU with unit tests and assembly program tests that attempted to use all of the implemented operations in various patterns. After using the tests and GTKWAVE to examine the waveforms of our CPU, we identified and fixed all of the bugs that prevented our test cases from running correctly. From fcafe0f0a58552ff90f69450364f43c110e62ea9 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:05:34 -0500 Subject: [PATCH 176/190] Modify for CPU constraints --- AssemblyPrograms/fibonacci.asm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/AssemblyPrograms/fibonacci.asm b/AssemblyPrograms/fibonacci.asm index 5025861..e810ebf 100644 --- a/AssemblyPrograms/fibonacci.asm +++ b/AssemblyPrograms/fibonacci.asm @@ -2,14 +2,15 @@ # Function call example: recursive Fibonacci main: + +addi $sp, $zero, 64 # Set up arguments for call to fib_test -addi $a0, $zero, 4 # arg0 = 4 -addi $a1, $zero, 10 # arg1 = 10 +addi $a0, $zero, 7 # arg0 = 4 +addi $a1, $zero, 3 # arg1 = 10 jal fib_test # Print result add $a0, $zero, $v0 # Copy result into argument register a0 -jal print_result # Jump to "exit", rather than falling through to subroutines j program_end @@ -108,11 +109,11 @@ sw $s0, 0($sp) add $s0, $zero, $a0 # Save argument (integer to print) to s0 -li $v0, 4 # Service code to print string +addi $v0, $zero, 4 # Service code to print string la $a0, result_str # Argument is memory address of string to print syscall -li $v0, 1 # Service code to print integer +addi $v0, $zero, 1 # Service code to print integer add $a0, $zero, $s0 # Argument is integer to print syscall @@ -130,4 +131,4 @@ j program_end #------------------------------------------------------------------------------ .data # Null-terminated string to print as part of result -result_str: .asciiz "\nFib(4)+Fib(10) = " \ No newline at end of file +result_str: .asciiz "\nFib(4)+Fib(10) = " From 79d3af6a99dac0ed3fd468d7787b17af8b22dc8f Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 22:05:39 -0500 Subject: [PATCH 177/190] hopefully fixed md formatting --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8729514..9dd475b 100644 --- a/README.md +++ b/README.md @@ -56,10 +56,11 @@ Our testing approach was as follows: You can run our tests using the following commands: -~~~chmod 755 run_tests.sh~~~ +`chmod 755 run_tests.sh` + *Needs to be run once in order for the file to be executed* -~~~./run_tests.sh~~~ +`./run_tests.sh` We tested our CPU with unit tests and assembly program tests that attempted to use all of the implemented operations in various patterns. After using the tests and GTKWAVE to examine the waveforms of our CPU, we identified and fixed all of the bugs that prevented our test cases from running correctly. From 0001e9b8cb0300c25b632fa097ef7a788039993a Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:06:08 -0500 Subject: [PATCH 178/190] Split file into several testbenches --- CPU.t.v | 300 -------------------------------------------------------- 1 file changed, 300 deletions(-) delete mode 100644 CPU.t.v diff --git a/CPU.t.v b/CPU.t.v deleted file mode 100644 index 0ef1396..0000000 --- a/CPU.t.v +++ /dev/null @@ -1,300 +0,0 @@ -// Test the full single cycle CPU - -`include "CPU.v" - -module testCPU (); - - reg CLK; - reg[31:0] mem [16:0]; - - CPU dut (.CLK(CLK)); - - initial begin - $dumpfile("CPU.vcd"); - $dumpvars(0, testCPU); - - // // add $t1, $zero, $zero - // mem[0] = 32'h00004820; - // $writememh("mem.dat", mem); - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t1: %h", dut.c.regfile.register9out); - // $display("Program counter: %h", dut.PC); - - // // addi $t1, $zero, 2 - // mem[1] = 32'h20090002; - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t1: %h", dut.c.regfile.register9out); - // $display("Program counter: %h", dut.PC); - - // // sw $t1, 0 - // mem[2] = 32'hac090000; - // $writememh("mem.dat", mem); - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t2: %h", dut.c.regfile.register10out); - // $display("Program counter: %h", dut.PC); - - // // addi $t1, $zero, 2 - // mem[3] = 32'h20090002; - // $writememh("mem.dat", mem); - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t1: %h", dut.c.regfile.register9out); - // $display("Program counter: %h", dut.PC); - - // // xori $t3, $t1, 7 - // mem[4] = 32'h392b0007; - // $writememh("mem.dat", mem); - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t3: %h", dut.c.regfile.register11out); - // $display("Program counter: %h", dut.PC); - - // // lw $t2, 0($zero) - // // load the value of memory at $zero into #t2 - // mem[5] = 32'h8c0a0000; - // $writememh("mem.dat", mem); - // CLK = 1; #12000; CLK = 0; #12000; - // $display("$t2: %h", dut.c.regfile.register10out); - // $display("Program counter: %h", dut.PC); - - // addi test cases. - // PC = 0 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd5) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); - end - - // PC = 4 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd130) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd130, dut.c.regfile.register9out); - end - - // PC = 8 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd9) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd9, dut.c.regfile.register8out); - end - - // xori test cases - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 24 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd5) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); - end - - // PC = 28 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd0) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 60 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd63) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd63, dut.c.regfile.register8out); - end - - // PC = 64 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd11) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd11, dut.c.regfile.register8out); - end - - // PC = 68 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd16) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd16, dut.c.regfile.register8out); - end - - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 76 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd51) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd51, dut.c.regfile.register8out); - end - - // PC = 80 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != -32'd29) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd29, dut.c.regfile.register8out); - end - - // PC = 84 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd6) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd6, dut.c.regfile.register8out); - end - - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 92 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); - end - - // PC = 96 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); - end - - // PC = 100 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register8out != 32'd0) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 124 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd1) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register11out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 124 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd2) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 124 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd3) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 124 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd4) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register11out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 116 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register13out != 32'd4) begin - $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); - end - - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 132 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register29out != 32'd16380) begin - $display("Error at register $sp. Expected value: %h, actual value: %h", 32'd16380, dut.c.regfile.register29out); - end - - // PC = 136 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd2) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register9out); - end - - // PC = 140 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register10out != 32'd169) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register10out); - end - - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 152 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register11out != 32'd2) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); - end - - // PC = 156 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register12out != 32'd169) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register12out); - end - - // PC = 160 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd100) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd100, dut.c.regfile.register9out); - end - - // PC = 164 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register31out != 32'd168) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd168, dut.c.regfile.register31out); - end - - // PC = 176 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd101) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd101, dut.c.regfile.register9out); - end - - CLK = 1; #12000; CLK = 0; #12000; - - // PC = 168 - CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - if (dut.c.regfile.register9out != 32'd102) begin - $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd102, dut.c.regfile.register9out); - end - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - CLK = 1; #12000; CLK = 0; #12000; - - end - -endmodule From 1860542d3dd1edff9436678df043905e8b297edf Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 22:06:15 -0500 Subject: [PATCH 179/190] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9dd475b..a70fe6d 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ You can run our tests using the following commands: `chmod 755 run_tests.sh` -*Needs to be run once in order for the file to be executed* +*Needs to be run once in order for the file to be executable* `./run_tests.sh` From e787bdcbad1149ce24250fd547251267ef3cd55c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:07:09 -0500 Subject: [PATCH 180/190] Create testbench for each program --- CPU_fib.t.v | 22 +++-- CPU_unit.t.v | 254 ++++++++++++++++++++++++++++++++++++++++++++++++++ CPU_while.t.v | 29 ++++++ 3 files changed, 296 insertions(+), 9 deletions(-) create mode 100644 CPU_unit.t.v create mode 100644 CPU_while.t.v diff --git a/CPU_fib.t.v b/CPU_fib.t.v index 4451de7..fc11d2c 100644 --- a/CPU_fib.t.v +++ b/CPU_fib.t.v @@ -9,16 +9,20 @@ module testCPU (); CPU dut (.CLK(CLK)); initial begin - $dumpfile("CPU.vcd"); - $dumpvars(0, testCPU, dut.c.datamemory.memory[8]); - - for (i = 0; i < 100; i = i + 1) begin + $dumpfile("CPU_fib.vcd"); + $dumpvars(0, testCPU); + + repeat(600) begin CLK = 1; #12000; CLK = 0; #12000; - $display("Program counter: %h", dut.PC); - $display("$at: %h", dut.c.regfile.register1out); - $display("$a0: %h", dut.c.regfile.register4out); - $display("$ra: %h", dut.c.regfile.register31out); - $display("Memtoreg mux output: %h", dut.c.regdatamux.out); + end + if (dut.PC === 32'd228) begin + if (dut.c.regfile.register2out === 32'd15) begin + $display("Fibonnaci test passed!"); + end + + else begin + $display("Fibonnaci test failed. Expected value: %b Actual value: %b", 32'd15, dut.c.regfile.register2out); + end end end diff --git a/CPU_unit.t.v b/CPU_unit.t.v new file mode 100644 index 0000000..11b682d --- /dev/null +++ b/CPU_unit.t.v @@ -0,0 +1,254 @@ +// Test the full single cycle CPU + +`include "CPU.v" + +module testCPU (); + + reg CLK; + reg[31:0] mem [16:0]; + + CPU dut (.CLK(CLK)); + + initial begin + $dumpfile("CPU_unit.vcd"); + $dumpvars(0, testCPU); + + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + + // PC = 4 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd130) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd130, dut.c.regfile.register9out); + end + + // PC = 8 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd9) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd9, dut.c.regfile.register8out); + end + + // xori test cases + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 24 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd5) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd5, dut.c.regfile.register8out); + end + + // PC = 28 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 60 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd63) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd63, dut.c.regfile.register8out); + end + + // PC = 64 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd11) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd11, dut.c.regfile.register8out); + end + + // PC = 68 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd16) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd16, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 76 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd51) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd51, dut.c.regfile.register8out); + end + + // PC = 80 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != -32'd29) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", -32'd29, dut.c.regfile.register8out); + end + + // PC = 84 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd6) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd6, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 92 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + + // PC = 96 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register8out); + end + + // PC = 100 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register8out != 32'd0) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd0, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd1) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd1, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd2) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd3) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd3, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 124 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register11out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 116 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register13out != 32'd4) begin + $display("Error at register $t0. Expected value: %h, actual value: %h", 32'd4, dut.c.regfile.register8out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 132 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register29out != 32'd64) begin + $display("Error at register $sp. Expected value: %h, actual value: %h", 32'd16380, dut.c.regfile.register29out); + end + + // PC = 136 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd2) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register9out); + end + + // PC = 140 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register10out != 32'd169) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register10out); + end + + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 152 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register11out != 32'd2) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd2, dut.c.regfile.register11out); + end + + // PC = 156 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register12out != 32'd169) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd169, dut.c.regfile.register12out); + end + + // PC = 160 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd100) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd100, dut.c.regfile.register9out); + end + + // PC = 164 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register31out != 32'd168) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd168, dut.c.regfile.register31out); + end + + // PC = 176 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd101) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd101, dut.c.regfile.register9out); + end + + CLK = 1; #12000; CLK = 0; #12000; + + // PC = 168 + CLK = 1; #12000; CLK = 0; #12000; + $display("Program counter: %h", dut.PC); + if (dut.c.regfile.register9out != 32'd102) begin + $display("Error at register $t1. Expected value: %h, actual value: %h", 32'd102, dut.c.regfile.register9out); + end + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + CLK = 1; #12000; CLK = 0; #12000; + end +endmodule diff --git a/CPU_while.t.v b/CPU_while.t.v new file mode 100644 index 0000000..dd2277d --- /dev/null +++ b/CPU_while.t.v @@ -0,0 +1,29 @@ +`include "CPU.v" + +module testCPU (); + + reg CLK; + reg[31:0] mem [16:0]; + integer i; + + CPU dut (.CLK(CLK)); + + initial begin + $dumpfile("CPU_fib.vcd"); + $dumpvars(0, testCPU); + + repeat(30) begin + CLK = 1; #12000; CLK = 0; #12000; + end + if (dut.PC === 32'd28) begin + if (dut.c.regfile.register11out === dut.c.regfile.register12out) begin + $display("While loop test passed!"); + end + + else begin + $display("While loop test failed. $t3 and $t4 are not equal at the end of the program."); + end + end + end + +endmodule \ No newline at end of file From b2cad1bf44baf350d9555830919d51e5e72cad71 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:07:31 -0500 Subject: [PATCH 181/190] Update build targets --- makefile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/makefile b/makefile index 9f6cc95..f2548fb 100644 --- a/makefile +++ b/makefile @@ -1,8 +1,14 @@ -all: core alu regfile memory signextend CPU +all: core alu regfile memory signextend CPU_unit CPU_fib CPU_while ### CPU Module -CPU: CPU.v CPU.t.v - iverilog -Wall -o CPU.out CPU.t.v +CPU_unit: CPU.v CPU_unit.t.v + iverilog -Wall -o CPU_unit CPU_unit.t.v + +CPU_fib: CPU.v CPU_fib.t.v + iverilog -Wall -o CPU_fib CPU_fib.t.v + +CPU_while: CPU.v CPU_while.t.v + iverilog -Wall -o CPU_while CPU_while.t.v ### PC_Calc Modules # PC_Calc top level module From 1fcb2d7e888152ccffae85deb73a9f823f708294 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:07:55 -0500 Subject: [PATCH 182/190] Initialize entire memory with 0s --- Core/data_memory.dat | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Core/data_memory.dat b/Core/data_memory.dat index 613ddfe..c74309b 100644 --- a/Core/data_memory.dat +++ b/Core/data_memory.dat @@ -30,3 +30,35 @@ 0000_0000 0000_0000 0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 +0000_0000 From 1c355adc30bab2c0760f42d80d0856e13f8d225c Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:08:30 -0500 Subject: [PATCH 183/190] Remove automatically generated file --- combined_unit_tests.text | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 combined_unit_tests.text diff --git a/combined_unit_tests.text b/combined_unit_tests.text deleted file mode 100644 index d837b0c..0000000 --- a/combined_unit_tests.text +++ /dev/null @@ -1,40 +0,0 @@ -20080005 -2109007d -21080004 -20080000 -20090002 -200a000b -39280007 -3948000b -20080000 -20090006 -200a0039 -200bfff7 -200c0014 -200dfffb -200efff5 -012a4020 -016c4020 -01ae4020 -20080000 -012a4022 -016c4022 -01ae4022 -20080000 -012a402a -016c402a -01ae402a -200b0000 -200c0004 -156c0002 -216d0000 -08000021 -216b0001 -0800001c -20090002 -200a00a9 -afa90000 -afaa0004 -8fab0000 -8fac0004 -08000027 From 101fddee855b3ec60bec55bc765c94a433f5d2e1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:09:12 -0500 Subject: [PATCH 184/190] Create bash script to run tests --- run_tests.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 run_tests.sh diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 0000000..b037480 --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +make + +java -jar ../Mars4_5.jar a dump .text HexText fib.text mc CompactTextAtZero AssemblyPrograms/fibonacci.asm + +cat fib.text > mem.dat + +./CPU_fib + +java -jar ../Mars4_5.jar a dump .text HexText while_loop.text mc CompactTextAtZero AssemblyPrograms/testCPU.asm + +cat while_loop.text > mem.dat + +./CPU_while + +java -jar ../Mars4_5.jar a dump .text HexText combined_unit_tests.text mc CompactTextAtZero AssemblyPrograms/combined_unit_tests.asm + +cat combined_unit_tests.text > mem.dat + +./CPU_unit + +./Core/Core +./Core/ALU/alu +./Core/regfile +./PC_Calc/PC_Calc +./Instruction_Parser/Instruction_Parser \ No newline at end of file From 80e952f16e624c24f9769a08c9eec15a604d4854 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 16 Nov 2017 22:11:04 -0500 Subject: [PATCH 185/190] Add sentence to beginning of readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a70fe6d..441218b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ### Computer Architecture Fall 2017 #### Ariana Olson, Andrew Pan, Jonah Spear -The goal of this project lab was to design, create, and test a 32-bit CPU. We chose to implement a single-cycle CPU given that time was a large constraint (we had <2 weeks from start to finish). +The goal of this project lab was to design, create, and test a 32-bit CPU. We chose to implement a single-cycle CPU given that time was a large constraint. Even though we only had <2 weeks from start to finish, we were ultimately successful in our goal. ## Design From 821584c44a6c4cf214f55b18db16f21d4d2a9e74 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:19:15 -0500 Subject: [PATCH 186/190] Fix broken test --- Core/Core.t.v | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Core/Core.t.v b/Core/Core.t.v index c5f83cf..055498d 100644 --- a/Core/Core.t.v +++ b/Core/Core.t.v @@ -368,10 +368,6 @@ module Core_TEST(); Rd = 5'dx; Rs = 5'd17; Rt = 5'd16; imm = 16'h0000aaaa; #6000 - if (dut.databout != 32'h0000003f) begin - $display("Test case 6 failed: R[Rs] != signextendimm and R[Rs] XOR signextendimm != 32'h0000ffff at time %t", $time); - end - // Test Case 7: Add // Load Immediate into register 20 RegDst = 2'b01; AlUSrc = 1'b1; RegWr = 1'b1; MemWr = 1'b0; ALUCntrl = 3'b000; MemToReg = 1'b0; From 5ba93710fd5ad39060af598946ebe30e41ae3f12 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:19:43 -0500 Subject: [PATCH 187/190] Dump memory to core tests --- run_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/run_tests.sh b/run_tests.sh index b037480..3ae5ce4 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -20,6 +20,7 @@ cat combined_unit_tests.text > mem.dat ./CPU_unit +cat Core/file.dat > mem.dat ./Core/Core ./Core/ALU/alu ./Core/regfile From 48319d5dddc032e30411bb922cc050cfe3d7d8f1 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:21:50 -0500 Subject: [PATCH 188/190] Fix file ref --- run_tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_tests.sh b/run_tests.sh index 3ae5ce4..c96623b 100755 --- a/run_tests.sh +++ b/run_tests.sh @@ -21,7 +21,7 @@ cat combined_unit_tests.text > mem.dat ./CPU_unit cat Core/file.dat > mem.dat -./Core/Core +./Core/core ./Core/ALU/alu ./Core/regfile ./PC_Calc/PC_Calc From 0072f21ac07462e57f4fa944a03f470dc57536c2 Mon Sep 17 00:00:00 2001 From: arianaolson419 Date: Thu, 16 Nov 2017 22:29:19 -0500 Subject: [PATCH 189/190] Fix test --- Core/regfile.t.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/regfile.t.v b/Core/regfile.t.v index 4dda453..d11213f 100644 --- a/Core/regfile.t.v +++ b/Core/regfile.t.v @@ -132,10 +132,10 @@ output reg Clk ReadRegister2 = 5'd2; #5 Clk=1; #5 Clk=0; - if((ReadData1 != 15) || (ReadData2 != 15)) begin + if(ReadData1 !== ReadData2) begin dutpassed = 0; $display("Test Case 2 Failed"); - end + end // Test Case 3: // Do not enable writing, check to ensure register From 1ee2cac8656add43a7e58cd907d92bb2ae063dd1 Mon Sep 17 00:00:00 2001 From: apan64 Date: Thu, 16 Nov 2017 22:32:05 -0500 Subject: [PATCH 190/190] test case only displays on fail --- PC_Calc/PC_Calc.t.v | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/PC_Calc/PC_Calc.t.v b/PC_Calc/PC_Calc.t.v index 554a213..461be89 100644 --- a/PC_Calc/PC_Calc.t.v +++ b/PC_Calc/PC_Calc.t.v @@ -17,7 +17,6 @@ module testPCCalc(); PC_Calc pccalc(old_PC[31:0], isZero, PCSel[1:0], AddSel, Da[31:0], addr[25:0], imm[15:0], added_PC[31:0], new_PC[31:0]); initial begin - $display("added_PC | new_PC"); old_PC = 32'd4; isZero = 0; PCSel = 0; @@ -25,8 +24,10 @@ module testPCCalc(); Da = 32'd16; addr = 26'd12; imm = 16'd10; #1000 - $display("expected 8 and 48"); - $display("%b | %b", added_PC, new_PC); + if (added_PC != 32'd8 || new_PC != 32'd48) begin + $display("test case failed, expected 8 and 48"); + $display("added_PC: %b | new_PC: %b", added_PC, new_PC); + end old_PC = 32'b01010000000000000000000000000000; isZero = 0; @@ -35,7 +36,9 @@ module testPCCalc(); Da = 32'd16; addr = 26'd12; imm = 16'd10; #1000 - $display("expected 01010000000000000000000000000100 and 01010000000000000000000000110000"); - $display("%b | %b", added_PC, new_PC); + if (added_PC != 32'd8 || new_PC != 32'd48) begin + $display("test case failed, expected 01010000000000000000000000000100 and 01010000000000000000000000110000"); + $display("added_PC: %b | new_PC: %b", added_PC, new_PC); + end end endmodule \ No newline at end of file