diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5761abc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/HW4 Writeup.pdf b/HW4 Writeup.pdf new file mode 100644 index 0000000..27b1395 Binary files /dev/null and b/HW4 Writeup.pdf differ diff --git a/multiplexer.v b/multiplexer.v new file mode 100644 index 0000000..48ba578 --- /dev/null +++ b/multiplexer.v @@ -0,0 +1,59 @@ +module mux32to1by1 +( +output out, +input[4:0] address, +input[31:0] inputs +); + assign out = inputs[address]; +endmodule + +module mux32to1by32 +( +output[31:0] out, +input[4:0] address, +input[31:0] 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 +); + + wire[31:0] mux[31:0]; // Create a 2D array of wires + assign mux[0] = input0; // Connect the sources of the array + 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]; // Connect the output of the array +endmodule \ No newline at end of file diff --git a/regfile.t.v b/regfile.t.v index f13815a..70baec4 100644 --- a/regfile.t.v +++ b/regfile.t.v @@ -2,6 +2,7 @@ // 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(); @@ -101,47 +102,88 @@ output reg Clk Clk=0; end + integer i, j; // Once 'begintest' is asserted, start running test cases always @(posedge begintest) begin endtest = 0; dutpassed = 1; #10 - // 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; - WriteData = 32'd42; - RegWrite = 1; - ReadRegister1 = 5'd2; - ReadRegister2 = 5'd2; - #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 - - // 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; - WriteData = 32'd15; - RegWrite = 1; - ReadRegister1 = 5'd2; - ReadRegister2 = 5'd2; - #5 Clk=1; #5 Clk=0; - - if((ReadData1 != 15) || (ReadData2 != 15)) begin - dutpassed = 0; - $display("Test Case 2 Failed"); - end - - - // All done! Wait a moment and signal test completion. - #5 - endtest = 1; + // Test Case 1 + // Writing to registers + for (i = 0; i <= 'b11111; i = i + 1) begin + WriteRegister = i; + WriteData = i; + RegWrite = 1; + ReadRegister1 = i; + ReadRegister2 = i; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != i) || (ReadData2 != i)) begin + dutpassed = 0; + $display("Test Case 1 Failed : failed to write to register %d", i); + end + end + + // Test Case 2 + // write to 0 register + // should always return 0 + WriteRegister = 5'd0; + WriteData = 32'hffffffff; + RegWrite = 1; + ReadRegister1 = 5'd0; + ReadRegister2 = 5'd0; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != 0) || (ReadData2 != 0)) begin + dutpassed = 0; + $display("Test Case 2 Failed : wrote to zero port"); + end + + // Test Case 3 + // write enabled + // should return unchanged value from above + for (i = 0; i <= 'b11111; i = i + 1) begin + WriteRegister = i; + WriteData = 32'hffffffff; + RegWrite = 0; + ReadRegister1 = i; + ReadRegister2 = i; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != i) || (ReadData2 != i)) begin + dutpassed = 0; + $display("Test Case 3 Failed : register %d changed when wrenable is false", i); + end + end + + // Test Case 4 + // Broken decoder + // All registers should start with their address in their memory + for (i = 0; i <= 'b11111; i = i + 1) begin + WriteRegister = i; + WriteData = 32'hffffffff; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + + for (j = 0; j <= 'b11111; j = j + 2) begin + if (j != i) begin + RegWrite = 0; + ReadRegister1 = i; + ReadRegister2 = i + 1; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 == i) || (ReadData2 == i)) begin + dutpassed = 0; + $display("Test Case 4 Failed : value for register %d written to multiple registers", i); + end + end + end + end + + // All done! Wait a moment and signal test completion. + #5 + endtest = 1; end diff --git a/regfile.v b/regfile.v index b8a3c74..228f3a4 100644 --- a/regfile.v +++ b/regfile.v @@ -6,22 +6,87 @@ // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ +`include "multiplexer.v" +`include "register.v" +`include "decoders.v" + 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) +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) ); - // 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; +//outputs +wire[31:0] reg0out, reg1out, reg2out, reg3out, reg4out, + reg5out, reg6out, reg7out, reg8out, reg9out, + reg10out, reg11out, reg12out, reg13out, reg14out, + reg15out, reg16out, reg17out, reg18out, re1g9out, + reg20out, reg21out, reg22out, reg23out, reg24out, + reg25out, reg26out, reg27out, reg28out, reg29out, + reg30out, reg31out; + +// enable writes +wire[31:0] regwrenable; +decoder1to32 wrdecoder (regwrenable, RegWrite, WriteRegister); + +// registers +register32zero reg0 (reg0out, WriteData, regwrenable[0], Clk); +register32 reg1 (reg1out, WriteData, regwrenable[1], Clk); +register32 reg2 (reg2out, WriteData, regwrenable[2], Clk); +register32 reg3 (reg3out, WriteData, regwrenable[3], Clk); +register32 reg4 (reg4out, WriteData, regwrenable[4], Clk); +register32 reg5 (reg5out, WriteData, regwrenable[5], Clk); +register32 reg6 (reg6out, WriteData, regwrenable[6], Clk); +register32 reg7 (reg7out, WriteData, regwrenable[7], Clk); +register32 reg8 (reg8out, WriteData, regwrenable[8], Clk); +register32 reg9 (reg9out, WriteData, regwrenable[9], Clk); +register32 reg10 (reg10out, WriteData, regwrenable[10], Clk); +register32 reg11 (reg11out, WriteData, regwrenable[11], Clk); +register32 reg12 (reg12out, WriteData, regwrenable[12], Clk); +register32 reg13 (reg13out, WriteData, regwrenable[13], Clk); +register32 reg14 (reg14out, WriteData, regwrenable[14], Clk); +register32 reg15 (reg15out, WriteData, regwrenable[15], Clk); +register32 reg16 (reg16out, WriteData, regwrenable[16], Clk); +register32 reg17 (reg17out, WriteData, regwrenable[17], Clk); +register32 reg18 (reg18out, WriteData, regwrenable[18], Clk); +register32 reg19 (reg19out, WriteData, regwrenable[19], Clk); +register32 reg20 (reg20out, WriteData, regwrenable[20], Clk); +register32 reg21 (reg21out, WriteData, regwrenable[21], Clk); +register32 reg22 (reg22out, WriteData, regwrenable[22], Clk); +register32 reg23 (reg23out, WriteData, regwrenable[23], Clk); +register32 reg24 (reg24out, WriteData, regwrenable[24], Clk); +register32 reg25 (reg25out, WriteData, regwrenable[25], Clk); +register32 reg26 (reg26out, WriteData, regwrenable[26], Clk); +register32 reg27 (reg27out, WriteData, regwrenable[27], Clk); +register32 reg28 (reg28out, WriteData, regwrenable[28], Clk); +register32 reg29 (reg29out, WriteData, regwrenable[29], Clk); +register32 reg30 (reg30out, WriteData, regwrenable[30], Clk); +register32 reg31 (reg31out, WriteData, regwrenable[31], Clk); + + +// reads +mux32to1by32 read1Mux (ReadData1, ReadRegister1, + reg0out, reg1out, reg2out, reg3out, reg4out, + reg5out, reg6out, reg7out, reg8out, reg9out, + reg10out, reg11out, reg12out, reg13out, reg14out, + reg15out, reg16out, reg17out, reg18out, re1g9out, + reg20out, reg21out, reg22out, reg23out, reg24out, + reg25out, reg26out, reg27out, reg28out, reg29out, + reg30out, reg31out); + +mux32to1by32 read2Mux (ReadData1, ReadRegister2, + reg0out, reg1out, reg2out, reg3out, reg4out, + reg5out, reg6out, reg7out, reg8out, reg9out, + reg10out, reg11out, reg12out, reg13out, reg14out, + reg15out, reg16out, reg17out, reg18out, re1g9out, + reg20out, reg21out, reg22out, reg23out, reg24out, + reg25out, reg26out, reg27out, reg28out, reg29out, + reg30out, reg31out); endmodule \ No newline at end of file diff --git a/register.v b/register.v index dc9b8cb..1f721b2 100644 --- a/register.v +++ b/register.v @@ -2,10 +2,10 @@ // Positive edge triggered module register ( -output reg q, -input d, -input wrenable, -input clk +output reg q, +input d, +input wrenable, +input clk ); always @(posedge clk) begin @@ -14,4 +14,35 @@ input clk end end +endmodule + +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 + +module register32zero +( + output reg[31:0] q, + input[31:0] d, + input wrenable, + input clk +); + + always @(posedge clk) begin + q = 32'b0; + end + endmodule \ No newline at end of file