From a10f94697129087fc1e861ed8afb64e0f659bb7e Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 12 Oct 2017 13:47:29 -0400 Subject: [PATCH 01/11] added register32 --- .gitignore | 1 + register32.v | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 .gitignore create mode 100644 register32.v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f47cb20 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.out diff --git a/register32.v b/register32.v new file mode 100644 index 0000000..68a3b7a --- /dev/null +++ b/register32.v @@ -0,0 +1,17 @@ +// 32-bit D Flip-Flop with enable +// Positive edge triggered +module register32 +( +output reg[31:0] q, +input[31:0] d, +input wrenable, +input clk +); + + always @(posedge clk) begin + if(wrenable) begin + q = d; + end + end + +endmodule From bb7362cd9e044b277ff49b6b6a4955c33a37ee6c Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 12 Oct 2017 14:12:02 -0400 Subject: [PATCH 02/11] add bigger registers and muxes --- mux32to1by1.v | 8 ++++++++ mux32to1by32.v | 47 +++++++++++++++++++++++++++++++++++++++++++++++ regfile.t.v | 18 ++++++++++-------- register32zero.v | 15 +++++++++++++++ 4 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 mux32to1by1.v create mode 100644 mux32to1by32.v create mode 100644 register32zero.v diff --git a/mux32to1by1.v b/mux32to1by1.v new file mode 100644 index 0000000..5b77ac2 --- /dev/null +++ b/mux32to1by1.v @@ -0,0 +1,8 @@ +module mux32to1by1 +( +output out, +input[4:0] address, +input[31:0] inputs +); + assign out = inputs[address]; +endmodule diff --git a/mux32to1by32.v b/mux32to1by32.v new file mode 100644 index 0000000..35c91fc --- /dev/null +++ b/mux32to1by32.v @@ -0,0 +1,47 @@ +`include "mux31to1by1.v" + +module mux32to1by32 +( +output[31:0] out, +input[4:0] address, +input[31:0] input0, input1, input2, input3, +input[31:0] input4, input5, input6, input7, +input[31:0] input8, input9, input10, input11, +input[31:0] input12, input13, input14, input15, +input[31:0] input16, input17, input18, input19, +input[31:0] input20, input21, input22, input23, +input[31:0] input24, input25, input26, input27, +input[31:0] input28, input29, input30, input31 +); + mux31to1by1 mux0(out[0], address, input0); + mux31to1by1 mux1(out[1], address, input1); + mux31to1by1 mux2(out[2], address, input2); + mux31to1by1 mux3(out[3], address, input3); + mux31to1by1 mux4(out[4], address, input4); + mux31to1by1 mux5(out[5], address, input5); + mux31to1by1 mux7(out[7], address, input7); + mux31to1by1 mux8(out[8], address, input8); + mux31to1by1 mux9(out[9], address, input9); + mux31to1by1 mux10(out[10], address, input10); + mux31to1by1 mux11(out[11], address, input11); + mux31to1by1 mux12(out[12], address, input12); + mux31to1by1 mux13(out[13], address, input13); + mux31to1by1 mux14(out[14], address, input14); + mux31to1by1 mux15(out[15], address, input15); + mux31to1by1 mux16(out[16], address, input16); + mux31to1by1 mux17(out[17], address, input17); + mux31to1by1 mux18(out[18], address, input18); + mux31to1by1 mux19(out[19], address, input19); + mux31to1by1 mux20(out[20], address, input20); + mux31to1by1 mux21(out[21], address, input21); + mux31to1by1 mux22(out[22], address, input22); + mux31to1by1 mux23(out[23], address, input23); + mux31to1by1 mux24(out[24], address, input24); + mux31to1by1 mux25(out[25], address, input25); + mux31to1by1 mux26(out[26], address, input26); + mux31to1by1 mux27(out[27], address, input27); + mux31to1by1 mux28(out[28], address, input28); + mux31to1by1 mux29(out[29], address, input29); + mux31to1by1 mux30(out[30], address, input30); + mux31to1by1 mux31(out[31], address, input31); +endmodule diff --git a/regfile.t.v b/regfile.t.v index f13815a..faedc47 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -1,8 +1,10 @@ //------------------------------------------------------------------------------ -// Test harness validates hw4testbench by connecting it to various functional +// Test harness validates hw4testbench by connecting it to various functional // or broken register files, and verifying that it correctly identifies each //------------------------------------------------------------------------------ +`include"regfile.v" + module hw4testbenchharness(); wire[31:0] ReadData1; // Data from first register read @@ -34,15 +36,15 @@ module hw4testbenchharness(); hw4testbench tester ( .begintest(begintest), - .endtest(endtest), + .endtest(endtest), .dutpassed(dutpassed), .ReadData1(ReadData1), .ReadData2(ReadData2), - .WriteData(WriteData), - .ReadRegister1(ReadRegister1), + .WriteData(WriteData), + .ReadRegister1(ReadRegister1), .ReadRegister2(ReadRegister2), .WriteRegister(WriteRegister), - .RegWrite(RegWrite), + .RegWrite(RegWrite), .Clk(Clk) ); @@ -107,7 +109,7 @@ output reg Clk dutpassed = 1; #10 - // Test Case 1: + // Test Case 1: // Write '42' to register 2, verify with Read Ports 1 and 2 // (Passes because example register file is hardwired to return 42) WriteRegister = 5'd2; @@ -123,7 +125,7 @@ output reg Clk $display("Test Case 1 Failed"); end - // Test Case 2: + // Test Case 2: // Write '15' to register 2, verify with Read Ports 1 and 2 // (Fails with example register file, but should pass with yours) WriteRegister = 5'd2; @@ -145,4 +147,4 @@ output reg Clk end -endmodule \ No newline at end of file +endmodule diff --git a/register32zero.v b/register32zero.v new file mode 100644 index 0000000..e7c40af --- /dev/null +++ b/register32zero.v @@ -0,0 +1,15 @@ +// 32-bit D Flip-Flop with enable +// Positive edge triggered +module register32zero +( +output reg[31:0] q, +input[31:0] d, +input wrenable, +input clk +); + + always @(posedge clk) begin + q = 0; + end + +endmodule From d6c967fedcaca8c815839ffb6814956e0295d80d Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 12 Oct 2017 15:25:33 -0400 Subject: [PATCH 03/11] initial implementation of register --- mux32to1by32.v | 65 +++++++------- regfile.v | 60 +++++++++++-- register32.t.v | 228 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 316 insertions(+), 37 deletions(-) create mode 100644 register32.t.v diff --git a/mux32to1by32.v b/mux32to1by32.v index 35c91fc..a70244a 100644 --- a/mux32to1by32.v +++ b/mux32to1by32.v @@ -1,4 +1,4 @@ -`include "mux31to1by1.v" +`include "mux32to1by1.v" module mux32to1by32 ( @@ -13,35 +13,36 @@ input[31:0] input20, input21, input22, input23, input[31:0] input24, input25, input26, input27, input[31:0] input28, input29, input30, input31 ); - mux31to1by1 mux0(out[0], address, input0); - mux31to1by1 mux1(out[1], address, input1); - mux31to1by1 mux2(out[2], address, input2); - mux31to1by1 mux3(out[3], address, input3); - mux31to1by1 mux4(out[4], address, input4); - mux31to1by1 mux5(out[5], address, input5); - mux31to1by1 mux7(out[7], address, input7); - mux31to1by1 mux8(out[8], address, input8); - mux31to1by1 mux9(out[9], address, input9); - mux31to1by1 mux10(out[10], address, input10); - mux31to1by1 mux11(out[11], address, input11); - mux31to1by1 mux12(out[12], address, input12); - mux31to1by1 mux13(out[13], address, input13); - mux31to1by1 mux14(out[14], address, input14); - mux31to1by1 mux15(out[15], address, input15); - mux31to1by1 mux16(out[16], address, input16); - mux31to1by1 mux17(out[17], address, input17); - mux31to1by1 mux18(out[18], address, input18); - mux31to1by1 mux19(out[19], address, input19); - mux31to1by1 mux20(out[20], address, input20); - mux31to1by1 mux21(out[21], address, input21); - mux31to1by1 mux22(out[22], address, input22); - mux31to1by1 mux23(out[23], address, input23); - mux31to1by1 mux24(out[24], address, input24); - mux31to1by1 mux25(out[25], address, input25); - mux31to1by1 mux26(out[26], address, input26); - mux31to1by1 mux27(out[27], address, input27); - mux31to1by1 mux28(out[28], address, input28); - mux31to1by1 mux29(out[29], address, input29); - mux31to1by1 mux30(out[30], address, input30); - mux31to1by1 mux31(out[31], address, input31); + mux32to1by1 mux0(out[0], address, input0); + mux32to1by1 mux1(out[1], address, input1); + mux32to1by1 mux2(out[2], address, input2); + mux32to1by1 mux3(out[3], address, input3); + mux32to1by1 mux4(out[4], address, input4); + mux32to1by1 mux5(out[5], address, input5); + mux32to1by1 mux6(out[5], address, input6); + mux32to1by1 mux7(out[7], address, input7); + mux32to1by1 mux8(out[8], address, input8); + mux32to1by1 mux9(out[9], address, input9); + mux32to1by1 mux10(out[10], address, input10); + mux32to1by1 mux11(out[11], address, input11); + mux32to1by1 mux12(out[12], address, input12); + mux32to1by1 mux13(out[13], address, input13); + mux32to1by1 mux14(out[14], address, input14); + mux32to1by1 mux15(out[15], address, input15); + mux32to1by1 mux16(out[16], address, input16); + mux32to1by1 mux17(out[17], address, input17); + mux32to1by1 mux18(out[18], address, input18); + mux32to1by1 mux19(out[19], address, input19); + mux32to1by1 mux20(out[20], address, input20); + mux32to1by1 mux21(out[21], address, input21); + mux32to1by1 mux22(out[22], address, input22); + mux32to1by1 mux23(out[23], address, input23); + mux32to1by1 mux24(out[24], address, input24); + mux32to1by1 mux25(out[25], address, input25); + mux32to1by1 mux26(out[26], address, input26); + mux32to1by1 mux27(out[27], address, input27); + mux32to1by1 mux28(out[28], address, input28); + mux32to1by1 mux29(out[29], address, input29); + mux32to1by1 mux30(out[30], address, input30); + mux32to1by1 mux31(out[31], address, input31); endmodule diff --git a/regfile.v b/regfile.v index b8a3c74..5adc9a9 100644 --- a/regfile.v +++ b/regfile.v @@ -6,6 +6,11 @@ // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ +`include "register32.v" +`include "register32zero.v" +`include "decoders.v" +`include "mux32to1by32.v" + module regfile ( output[31:0] ReadData1, // Contents of first register read @@ -18,10 +23,55 @@ input RegWrite, // Enable writing of register when High input Clk // Clock (Positive Edge Triggered) ); - // These two lines are clearly wrong. They are included to showcase how the - // test harness works. Delete them after you understand the testing process, + // These two lines are clearly wrong. They are included to showcase how the + // test harness works. Delete them after you understand the testing process, // and replace them with your actual code. - assign ReadData1 = 42; - assign ReadData2 = 42; -endmodule \ No newline at end of file + wire[31:0] reg0out, reg1out, reg2out, reg3out; + wire[31:0] reg4out, reg5out, reg6out, reg7out; + wire[31:0] reg8out, reg9out, reg10out, reg11out; + wire[31:0] reg12out, reg13out, reg14out, reg15out; + wire[31:0] reg16out, reg17out, reg18out, reg19out; + wire[31:0] reg20out, reg21out, reg22out, reg23out; + wire[31:0] reg24out, reg25out, reg26out, reg27out; + wire[31:0] reg28out, reg29out, reg30out, reg31out; + wire[31:0] wrenable; + + decoder1to32 dec(wrenable, RegWrite, WriteRegister); + register32zero reg0(reg0out, WriteData, wrenable[0], Clk); + register32 reg1(reg1out, WriteData, wrenable[1], Clk); + register32 reg2(reg2out, WriteData, wrenable[2], Clk); + register32 reg3(reg3out, WriteData, wrenable[3], Clk); + register32 reg4(reg4out, WriteData, wrenable[4], Clk); + register32 reg5(reg5out, WriteData, wrenable[5], Clk); + register32 reg6(reg6out, WriteData, wrenable[6], Clk); + register32 reg7(reg7out, WriteData, wrenable[7], Clk); + register32 reg8(reg8out, WriteData, wrenable[8], Clk); + register32 reg9(reg9out, WriteData, wrenable[9], Clk); + register32 reg10(reg10out, WriteData, wrenable[10], Clk); + register32 reg11(reg11out, WriteData, wrenable[11], Clk); + register32 reg12(reg12out, WriteData, wrenable[12], Clk); + register32 reg13(reg13out, WriteData, wrenable[13], Clk); + register32 reg14(reg14out, WriteData, wrenable[14], Clk); + register32 reg15(reg15out, WriteData, wrenable[15], Clk); + register32 reg16(reg16out, WriteData, wrenable[16], Clk); + register32 reg17(reg17out, WriteData, wrenable[17], Clk); + register32 reg18(reg18out, WriteData, wrenable[18], Clk); + register32 reg19(reg19out, WriteData, wrenable[19], Clk); + register32 reg20(reg20out, WriteData, wrenable[20], Clk); + register32 reg21(reg21out, WriteData, wrenable[21], Clk); + register32 reg22(reg22out, WriteData, wrenable[22], Clk); + register32 reg23(reg23out, WriteData, wrenable[23], Clk); + register32 reg24(reg24out, WriteData, wrenable[24], Clk); + register32 reg25(reg25out, WriteData, wrenable[25], Clk); + register32 reg26(reg26out, WriteData, wrenable[26], Clk); + register32 reg27(reg27out, WriteData, wrenable[27], Clk); + register32 reg28(reg28out, WriteData, wrenable[28], Clk); + register32 reg29(reg29out, WriteData, wrenable[29], Clk); + register32 reg30(reg30out, WriteData, wrenable[30], Clk); + register32 reg31(reg31out, WriteData, wrenable[31], Clk); + + mux32to1by32 mux0(ReadData1, ReadRegister1, reg0out, reg1out, reg2out, reg3out, reg4out, reg5out, reg6out, reg7out, reg8out, reg9out, reg10out, reg11out, reg12out, reg13out, reg14out, reg15out, reg16out, reg17out, reg18out, reg19out, reg20out, reg21out, reg22out, reg23out, reg24out, reg25out, reg26out, reg27out, reg28out, reg29out, reg30out, reg31out); + mux32to1by32 mux1(ReadData2, ReadRegister2, reg0out, reg1out, reg2out, reg3out, reg4out, reg5out, reg6out, reg7out, reg8out, reg9out, reg10out, reg11out, reg12out, reg13out, reg14out, reg15out, reg16out, reg17out, reg18out, reg19out, reg20out, reg21out, reg22out, reg23out, reg24out, reg25out, reg26out, reg27out, reg28out, reg29out, reg30out, reg31out); + +endmodule diff --git a/register32.t.v b/register32.t.v new file mode 100644 index 0000000..3e46aa2 --- /dev/null +++ b/register32.t.v @@ -0,0 +1,228 @@ +// 1 Bit alu test bench +`timescale 1 ns / 1 ps +`include "register32.v" + +module testRegister32 (); + wire[31:0] out; + reg[31:0] in; + reg wrenable, clk; + + register32 register (out,in,wrenable,clk); + + integer tests = 0; + integer passed_tests = 0; + + function integer test; + input test_case; + integer test_case; + begin + tests = tests + 1; + if (test_case) begin + test = 1; + $display("Passed test with: %b %b | %b", in, wrenable, out); + end + else begin + test = 0; + $display("Failed test with: %b %b | %b*", in, wrenable, out); + end + end + endfunction + + initial begin + + in = 4'b0000; + wrenable = 1; + clk = 0; #1000 clk=1; + passed_tests = test(out == in); + // Test ADD + // $display("ADD:"); + // op=3'b000; + // // without cin + // cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a + b) == out) & ((a & b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); end + // end + // end + // // with cin + // cin = 1; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a ~^ b) == out) & ((a | b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // // Test SUB + // $display("SUB:"); + // op=3'b001; + // // without cin + // cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a - b) == out) & ((a < b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + // // with cin + // cin = 1; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a ~^ b) == out) & ((a <= b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + + // // Test XOR + // $display("XOR:"); + // op=3'b010; cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if ((a ^ b) == out) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // //Test SLT + // $display("SLT:"); + // op=3'b001; + // // without cin + // cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a - b) == out) & ((a < b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + // // with cin + // cin = 1; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (((a ~^ b) == out) & ((a <= b) == cout)) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // // Test AND + // $display("AND:"); + // op=3'b100; cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if ((a & b) == out) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // // Test NAND + // $display("NAND:"); + // op=3'b101; cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if (~(a&b) == out) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // // Test NOR + // $display("NOR:"); + // op=3'b110; cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if ((a ~| b) == out) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + + // // Test OR + // $display("OR:"); + // op=3'b111; cin = 0; + // for (i=0; i<2; i=i+1) begin + // for (j=0; j<2; j=j+1) begin + // a=i;b=j;#1000 + // tests = tests + 1; + // if ((a|b) == out) begin + // passed_tests = passed_tests + 1; + // $display("Passed test with: %b %b %b %b | %b %b", op, a, b, cin, out, cout); + // end + // else begin + // $display("Failed test with: %b %b %b %b | %b %b*", op, a, b, cin, out, cout); + // end + // end + // end + // $display(" op a b cin|out cout "); + + $display("%2d/%2d Test Cases Passed", passed_tests, tests); + + end +endmodule From b267db559d212dc1a7d323aea6877924cb11bde9 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Thu, 12 Oct 2017 16:29:57 -0400 Subject: [PATCH 04/11] Got tests passing --- .gitignore | 1 + mux32to1by1.v | 8 ------ mux32to1by32.v | 69 +++++++++++++++++++++++++------------------------- regfile.t.v | 4 +++ register32.t.v | 2 +- 5 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 mux32to1by1.v diff --git a/.gitignore b/.gitignore index f47cb20..72fd5f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.out +*.vcd diff --git a/mux32to1by1.v b/mux32to1by1.v deleted file mode 100644 index 5b77ac2..0000000 --- a/mux32to1by1.v +++ /dev/null @@ -1,8 +0,0 @@ -module mux32to1by1 -( -output out, -input[4:0] address, -input[31:0] inputs -); - assign out = inputs[address]; -endmodule diff --git a/mux32to1by32.v b/mux32to1by32.v index a70244a..090fc7a 100644 --- a/mux32to1by32.v +++ b/mux32to1by32.v @@ -1,5 +1,3 @@ -`include "mux32to1by1.v" - module mux32to1by32 ( output[31:0] out, @@ -13,36 +11,39 @@ input[31:0] input20, input21, input22, input23, input[31:0] input24, input25, input26, input27, input[31:0] input28, input29, input30, input31 ); - mux32to1by1 mux0(out[0], address, input0); - mux32to1by1 mux1(out[1], address, input1); - mux32to1by1 mux2(out[2], address, input2); - mux32to1by1 mux3(out[3], address, input3); - mux32to1by1 mux4(out[4], address, input4); - mux32to1by1 mux5(out[5], address, input5); - mux32to1by1 mux6(out[5], address, input6); - mux32to1by1 mux7(out[7], address, input7); - mux32to1by1 mux8(out[8], address, input8); - mux32to1by1 mux9(out[9], address, input9); - mux32to1by1 mux10(out[10], address, input10); - mux32to1by1 mux11(out[11], address, input11); - mux32to1by1 mux12(out[12], address, input12); - mux32to1by1 mux13(out[13], address, input13); - mux32to1by1 mux14(out[14], address, input14); - mux32to1by1 mux15(out[15], address, input15); - mux32to1by1 mux16(out[16], address, input16); - mux32to1by1 mux17(out[17], address, input17); - mux32to1by1 mux18(out[18], address, input18); - mux32to1by1 mux19(out[19], address, input19); - mux32to1by1 mux20(out[20], address, input20); - mux32to1by1 mux21(out[21], address, input21); - mux32to1by1 mux22(out[22], address, input22); - mux32to1by1 mux23(out[23], address, input23); - mux32to1by1 mux24(out[24], address, input24); - mux32to1by1 mux25(out[25], address, input25); - mux32to1by1 mux26(out[26], address, input26); - mux32to1by1 mux27(out[27], address, input27); - mux32to1by1 mux28(out[28], address, input28); - mux32to1by1 mux29(out[29], address, input29); - mux32to1by1 mux30(out[30], address, input30); - mux32to1by1 mux31(out[31], address, input31); + wire [31:0] mux[31:0]; + 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 diff --git a/regfile.t.v b/regfile.t.v index faedc47..a290ffa 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -50,6 +50,10 @@ module hw4testbenchharness(); // Test harness asserts 'begintest' for 1000 time steps, starting at time 10 initial begin + + $dumpfile("regfile.vcd"); + $dumpvars; + begintest=0; #10; begintest=1; diff --git a/register32.t.v b/register32.t.v index 3e46aa2..a5b9e37 100644 --- a/register32.t.v +++ b/register32.t.v @@ -32,7 +32,7 @@ module testRegister32 (); in = 4'b0000; wrenable = 1; - clk = 0; #1000 clk=1; + #5 clk = 0; #5 clk=1; passed_tests = test(out == in); // Test ADD // $display("ADD:"); From 38f11f3e6a76551d425d2eef77aafb148809f3d6 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Fri, 13 Oct 2017 09:08:21 -0400 Subject: [PATCH 05/11] add more test cases --- regfile.t.v | 69 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/regfile.t.v b/regfile.t.v index a290ffa..074c806 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -51,8 +51,8 @@ module hw4testbenchharness(); // Test harness asserts 'begintest' for 1000 time steps, starting at time 10 initial begin - $dumpfile("regfile.vcd"); - $dumpvars; + //$dumpfile("regfile.vcd"); + //$dumpvars; begintest=0; #10; @@ -62,7 +62,12 @@ module hw4testbenchharness(); // Display test results ('dutpassed' signal) once 'endtest' goes high always @(posedge endtest) begin - $display("DUT passed?: %b", dutpassed); + if (dutpassed) begin + $display("Tests Passed!"); + end + else begin + $display("Tests Failed!"); + end end endmodule @@ -130,13 +135,13 @@ output reg Clk end // Test Case 2: - // Write '15' to register 2, verify with Read Ports 1 and 2 + // Write '15' to register 3, verify with Read Ports 1 and 2 // (Fails with example register file, but should pass with yours) - WriteRegister = 5'd2; + WriteRegister = 5'd3; WriteData = 32'd15; RegWrite = 1; - ReadRegister1 = 5'd2; - ReadRegister2 = 5'd2; + ReadRegister1 = 5'd3; + ReadRegister2 = 5'd3; #5 Clk=1; #5 Clk=0; if((ReadData1 != 15) || (ReadData2 != 15)) begin @@ -144,6 +149,56 @@ output reg Clk $display("Test Case 2 Failed"); end + // Test Case 3: + // Read both registers that we've already set. + ReadRegister1 = 5'd2; + ReadRegister2 = 5'd3; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != 42) || (ReadData2 != 15)) begin + dutpassed = 0; + $display("Test Case 3 Failed"); + end + + // Test Case 3: + // Clear both registers. Confirm that they are cleared. + WriteRegister = 5'd3; + WriteData = 32'd0; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + WriteRegister = 5'd2; + WriteData = 32'd0; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + ReadRegister1 = 5'd2; + ReadRegister2 = 5'd3; + + // Test Case 4: + // Set RegWrite to 0. Register should not be written to. + WriteRegister = 5'd1; + WriteData = 32'd42; + RegWrite = 0; + #5 Clk=1; #5 Clk=0; + ReadRegister1 = 5'd1; + + if(ReadData1 != 42) begin + dutpassed = 0; + $display("Test Case 4 Failed"); + end + + // Test Case 5: + // Write to Register 0. Register 0 should always return 0 + WriteRegister = 5'd0; + WriteData = 32'd42; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + ReadRegister1 = 5'd0; + + if(ReadData1 != 0) begin + dutpassed = 0; + $display("Test Case 5 Failed"); + end + // All done! Wait a moment and signal test completion. #5 From f4ced7c00571dba65270af67cb95000d2f8a8b28 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 12:02:01 -0400 Subject: [PATCH 06/11] Create illustrations for register implementation comparison --- RegComparison.jpg | Bin 0 -> 56431 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 RegComparison.jpg diff --git a/RegComparison.jpg b/RegComparison.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a62d39291a30447db39db4f263a6bede88a92870 GIT binary patch literal 56431 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 literal 0 HcmV?d00001 From ca9ad68fb5a56e1f694c35f55b362fc75fdc2a16 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 12:02:24 -0400 Subject: [PATCH 07/11] Start updating README.md --- README.md | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ddf0003..fea6d31 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,9 @@ # CompArch HW b0100: Register File # -**Due:** Monday, October 16 +### Jonah Spear -This homework is intended to introduce behavioral Verilog and practice test bench design. You will create your first memory, a register file, which will be reused in your CPU design. - -Homework is to be completed individually. If you seek help from another individual, note that per deliverable. - - -## The Register File ## -The register file is an extremely small, extremely fast memory at the heart of your CPU. They vary per architecture, but you will create one with the following specifications: - - - Width: 32 bits - - Depth: 32 words - - Write Port: Synchronous, Positive Edge Triggered - - Read Port 1: Asynchronous - - Read Port 2: Asynchronous +The purpose of this assignment is to build a 32 bit register in verilog. A 32 bit register is a type of memory that can hold 32 values of 32 bits each. The overall design of the register is as follows: -We are mimicking the MIPS architecture, which has one unusual feature in its register file: The first "register" is actually just the constant value zero. We will exploit this oddity later when we write assembly programs for the processor. - -The overall structure of the register file is shown below. The core is the 32-bit registers: 31 normal registers and a constant zero. The read ports are a pair of giant multiplexers connected to the register outputs. The write port connects to the input of all registers, and a decoder optionally enables one register to be written. This homework will build these units incrementally in behavioral Verilog (wrapped in structural shells), and then assemble them to create the full register file. Register File diagram From beaa5c940299bfe74b2b819a0ee1f5a532ad4e87 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 12:09:50 -0400 Subject: [PATCH 08/11] Mid-way through updating README.md --- README.md | 109 ++++-------------------------------------------------- 1 file changed, 8 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index fea6d31..b689a79 100644 --- a/README.md +++ b/README.md @@ -7,95 +7,21 @@ The purpose of this assignment is to build a 32 bit register in verilog. A 32 bi Register File diagram -## Register ## - -It is critically important to write registers in Behavioral Verilog so that the synthesizer can figure out what to do. -Here is the behavioral description of a D Flip Flop with enable, positive edge triggered: - -```verilog -module register -( -output reg q, -input d, -input wrenable, -input clk -); - always @(posedge clk) begin - if(wrenable) begin - q = d; - end - end -endmodule -``` - -Note the enable logic. It may feel more natural to instead “gate the clock” like this: - -```verilog -// Gated clock - avoid this style -always @(posedge (clk & wrenable)) begin - q = d; -end -``` Theoretically this would work – the clock signal would be steady `FALSE` when disabled, and only have positive edges when enabled. However, "gating the clock" is a bad idea in practice – what happens if that enable signal has glitches? Additionally, FPGAs are typically designed to only support a few distinct clocks. ### Deliverable 1 ### -Draw a circuit diagram showing the structural equivalent for each of the two register implementations above. You may use primitives such as the D Flip-Flop, MUX, decoder, and basic logic gates. - -### Deliverable 2 ### -Create a module named `register32`. This module should exactly match the `register` definition above, but with 32 bits worth of D Flip Flops (`d` and `q` ports should increase width accordingly). If you’d like, try parameterizing this width. - -### Deliverable 3 ### - -Create a module named `register32zero`. This module should match the port definition above, but instead of storing data it should ignore its inputs and always output zero. - - -## Behavioral Muxes ## - -Behavioral Verilog makes it very easy to create a multiplexer through its array syntax. This array syntax is very similar to that of the procedural languages (e.g. MATLAB, Python, C, Java, etc) you may already be familiar with: - -```verilog -wire[31:0] inputsofmux; -wire outputofmux; -assign outputofmux=inputsofmux[address]; -``` - -### Deliverable 4 ### -Create a 32:1 multiplexer with the following module definition: - -```verilog -module mux32to1by1 -( -output out, -input[4:0] address, -input[31:0] inputs -); - // Your code -endmodule -``` -### Deliverable 5 ### +Circuit diagram for two register implementations: +Register File diagram -Create a multiplexer that is 32 bits wide and 32 inputs deep. There are many syntaxes available to do so, and each of them have their own little bit of excitement. The version below has more typing involved than other options, but it will allow better flexibility later. Match the following module port definition: +### Deliverables 2-5 ### -```verilog -module mux32to1by32 -( -output[31:0] out, -input[4:0] address, -input[31:0] input0, input1, input2, ..., input31 -); - - wire[31:0] mux[31:0]; // Create a 2D array of wires - assign mux[0] = input0; // Connect the sources of the array - // Repeat 31 times... - assign out = mux[address]; // Connect the output of the array -endmodule -``` +See containing files. -## Decoder ## +### Deliverable 6 ### -The decoder selects which register of the register file is being written to. Here is the full definition: +Given the following definition for a decoder, describe how this decoder works. ```verilog module decoder1to32 @@ -108,27 +34,8 @@ input[4:0] address endmodule ``` -### Deliverable 6 ### - -Provide a brief written description of how the above module works. How does this behavioral Verilog result in a decoder? - -## Stitch it all together ## - -You now have all the components necessary to create your register file. Use the following module definition and structure to create your register file: - -```verilog -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 RegWrite, // Enable writing of register when High -input Clk // Clock (Positive Edge Triggered) -); -``` +This shifts either 1 or 0 to the left by n bits, effectively setting the nth bit high. + ### Deliverable 7 ### Submit Verilog files that containing your register file and all supporting modules. Note that Deliverable 8 will help you with this. From b81e5db1ef42ac458be7fcce023aa5153501152b Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 12:24:26 -0400 Subject: [PATCH 09/11] Finish updating README.md --- README.md | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/README.md b/README.md index b689a79..c037e9c 100644 --- a/README.md +++ b/README.md @@ -37,46 +37,6 @@ endmodule This shifts either 1 or 0 to the left by n bits, effectively setting the nth bit high. -### Deliverable 7 ### -Submit Verilog files that containing your register file and all supporting modules. Note that Deliverable 8 will help you with this. - -### Deliverable 8 ### -Expand the provided test bench to catch register files with the following error types: - -1. A fully perfect register file. Return True when this is detected, false for all others. -1. Write Enable is broken / ignored – Register is always written to. -1. Decoder is broken – All registers are written to. -1. Register Zero is actually a register instead of the constant value zero. -1. Port 2 is broken and always reads register 14 (for example). - -These will be graded by instantiating intentionally broken register files with your tester. Your tester must return true (works!) or false (broken!) as appropriate. - -It is to your advantage to test more than just these cases to better ensure that your good register file is actually good. - ## Submission ## -Push your work to GitHub and submit a pull request to the course repo. You should include: - - Verilog: top-level `regfile.v` and any supporting files - - Test benches: `regfile.t.v` and any other testing files - - Scripts to run your tests - - "Report" with writing/drawing for deliverables 1 and 6 - -You can choose how to organize your Verilog modules (e.g. one module per file matching filename, all sizes of decoder grouped in `decoders.v`, something else) and testbenches, but the top-level of each must be named `regfile.v` and `regfile.t.v` as specified. - -## Rubric ## -Code portions of this assignment will be checked automatically by scripts. It is therefore critical to follow the module definitions exactly – same port definitions, same names. - -| Deliverable | Weight | Grading | -|-------------|--------|---------| -| 1 | 10 | Manual | -| 2 | 5 | Automatic | -| 3 | 5 | Automatic | -| 4 | 10 | Automatic | -| 5 | 10 | Automatic | -| 6 | 10 | Manual | -| 7 | 25 | Automatic | -| 8 | 25 | Automatic | -| Total | 100 | | - -## Notes ## -We are not doing any time delay related analysis for this assignment. Please do not include time delays. +All tests are contained in regfile.t.v From 5269de7e2f3386b938197048505fa0c118a6495b Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 12:40:10 -0400 Subject: [PATCH 10/11] start refactoring tests --- regfile.t.v | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/regfile.t.v b/regfile.t.v index 074c806..dbd3de1 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -101,6 +101,20 @@ output reg[4:0] WriteRegister, output reg RegWrite, output reg Clk ); + function integer test; + input test_case; + integer test_case; + begin + if (test_case) begin + test = 1; + end + else begin + test = 0; + $display("Failed test with: Dw: %h, Rw: %h, Rr1: %h, Rr2: %h, En: %d", WriteData, WriteRegister, ReadRegister1, ReadRegister2, RegWrite); + $display(" Dr1: %h Dr2: %h", ReadData1, ReadData2); + end + end + endfunction // Initialize register driver signals initial begin @@ -129,10 +143,7 @@ output reg Clk #5 Clk=1; #5 Clk=0; // Generate single clock pulse // Verify expectations and report test result - if((ReadData1 != 42) || (ReadData2 != 42)) begin - dutpassed = 0; // Set to 'false' on failure - $display("Test Case 1 Failed"); - end + dutpassed = test((ReadData1 == 42) & (ReadData2 == 42)); // Test Case 2: // Write '15' to register 3, verify with Read Ports 1 and 2 From 89d1adf1ebe71309228444776100d306ba2a6027 Mon Sep 17 00:00:00 2001 From: Jonah Spear Date: Sat, 14 Oct 2017 13:07:48 -0400 Subject: [PATCH 11/11] update tests --- regfile.t.v | 74 +++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/regfile.t.v b/regfile.t.v index dbd3de1..cdb7910 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -116,6 +116,29 @@ output reg Clk end endfunction + task run_test; + input expected_val_1, expected_val_2; + integer expected_val_1, expected_val_2; + integer i; + begin + Clk=0; #5 Clk=1; #5 Clk=0; + dutpassed = test((ReadData1 == expected_val_1) & (ReadData2 == expected_val_2)); + + // Reset all values to their default + #5 Clk=1; #5 Clk=0; + RegWrite=1; + WriteData=0; + for (i=0; i<31; i=i+1) begin + WriteRegister = i; + #5 Clk=1; #5 Clk=0; + end + RegWrite=0; + WriteRegister=0; + ReadRegister1=0; + ReadRegister2=0; + end + endtask + // Initialize register driver signals initial begin WriteData=32'd0; @@ -132,6 +155,10 @@ output reg Clk dutpassed = 1; #10 + // Test Case 0: + // Before anything is set, both read values should be 0 + run_test(0, 0); + // Test Case 1: // Write '42' to register 2, verify with Read Ports 1 and 2 // (Passes because example register file is hardwired to return 42) @@ -140,10 +167,9 @@ output reg Clk RegWrite = 1; ReadRegister1 = 5'd2; ReadRegister2 = 5'd2; - #5 Clk=1; #5 Clk=0; // Generate single clock pulse // Verify expectations and report test result - dutpassed = test((ReadData1 == 42) & (ReadData2 == 42)); + run_test(42, 42); // Test Case 2: // Write '15' to register 3, verify with Read Ports 1 and 2 @@ -153,36 +179,22 @@ output reg Clk RegWrite = 1; ReadRegister1 = 5'd3; ReadRegister2 = 5'd3; - #5 Clk=1; #5 Clk=0; - if((ReadData1 != 15) || (ReadData2 != 15)) begin - dutpassed = 0; - $display("Test Case 2 Failed"); - end + run_test(15, 15); // Test Case 3: - // Read both registers that we've already set. - ReadRegister1 = 5'd2; + // Write to two registers, then clear them. Confirm that they are cleared. + RegWrite = 1; + ReadRegister1 = 5'd3; ReadRegister2 = 5'd3; - #5 Clk=1; #5 Clk=0; - - if((ReadData1 != 42) || (ReadData2 != 15)) begin - dutpassed = 0; - $display("Test Case 3 Failed"); - end - // Test Case 3: - // Clear both registers. Confirm that they are cleared. + // Writing WriteRegister = 5'd3; - WriteData = 32'd0; - RegWrite = 1; - #5 Clk=1; #5 Clk=0; - WriteRegister = 5'd2; - WriteData = 32'd0; - RegWrite = 1; + WriteData = 32'd15; #5 Clk=1; #5 Clk=0; - ReadRegister1 = 5'd2; - ReadRegister2 = 5'd3; + // Clearing + WriteData=0; + run_test(0, 0); // Test Case 4: // Set RegWrite to 0. Register should not be written to. @@ -191,11 +203,9 @@ output reg Clk RegWrite = 0; #5 Clk=1; #5 Clk=0; ReadRegister1 = 5'd1; + ReadRegister2 = 5'd1; - if(ReadData1 != 42) begin - dutpassed = 0; - $display("Test Case 4 Failed"); - end + run_test(0, 0); // Test Case 5: // Write to Register 0. Register 0 should always return 0 @@ -204,11 +214,9 @@ output reg Clk RegWrite = 1; #5 Clk=1; #5 Clk=0; ReadRegister1 = 5'd0; + ReadRegister1 = 5'd0; - if(ReadData1 != 0) begin - dutpassed = 0; - $display("Test Case 5 Failed"); - end + run_test(0, 0); // All done! Wait a moment and signal test completion.