diff --git a/decoders.v b/decoders.v index dd467c2..8f67812 100644 --- a/decoders.v +++ b/decoders.v @@ -12,3 +12,9 @@ input[4:0] address endmodule +// Deliveriable 6 +// In the above code, the value of 'out' is assigned to the value of that the enable bit is shifted +// 'address' bits in the left direction. +// If 'enable' is 0(decoder is disabled), 'out' is always 32-bit zero. So all output bit is inactive. +// If 'enable' is 1(decoder is enabled), 'out' is the 32-bit value of which ('address'+1)-th bit is 1 +// and other bits are 0. So only the bit which is selected by 'address' value is active. \ No newline at end of file diff --git a/deliverable.md b/deliverable.md new file mode 100644 index 0000000..5614fd6 --- /dev/null +++ b/deliverable.md @@ -0,0 +1,37 @@ +### Deliverable 1 : + +![Deliverable1](image/deliverable1.jpg "Deliverable 1") + +The first picture is the register circuit that implements the following code. + +~~~ +module register +( +output reg q, +input d, +input wrenable, +input clk +); + always @(posedge clk) begin + if(wrenable) begin + q = d; + end + end +endmodule +~~~ + +The second picture is the register circuit that changes the always block of the above code into the following code. + +~~~ +always @(posedge (clk & wrenable)) begin + q = d; +end +~~~ + +**Deliverable 2 ~ 5** are in 'register.v' + +**Deliverable 6** is in 'decoders.v' as comments + +**Deliverable 7** is in 'regfile.v' + +**Deliverable 8** is in 'regfile.t.v' \ No newline at end of file diff --git a/image/deliverable1.jpg b/image/deliverable1.jpg new file mode 100644 index 0000000..b85d03e Binary files /dev/null and b/image/deliverable1.jpg differ diff --git a/regfile.t.v b/regfile.t.v index f13815a..340bd6b 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(); @@ -91,6 +92,9 @@ output reg RegWrite, output reg Clk ); + // loop index + integer index; + // Initialize register driver signals initial begin WriteData=32'd0; @@ -139,6 +143,142 @@ output reg Clk end + //--------Deliverable 8--------- + + // 1 + + // Test Case 1: + // Write maximum value to all register. Then check the value of them + WriteData = 32'hFFFFFFFF; + RegWrite = 1; + for(index=1;index<32;index=index+1) begin + WriteRegister = index; + ReadRegister1 = index; + ReadRegister2 = index; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != 4294967295) || (ReadData2 != 4294967295)) begin + dutpassed = 0; + $display("Type 1 Test Case 1 Failed"); + end + end + + + // 2. Write Enable is broken / ignored – Register is always written to. + + // Test Case 1: + // After writing '1955103904 - 10*(register number)' to a register, disenable RegWrite. + // Then try to write '3410 + (register number)*(register number)' to the register. Repeat for all register. + + for(index=1;index<32;index=index+1) begin + WriteRegister = index; + WriteData = 32'd1955103904 - 10*index; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + RegWrite = 0; + WriteData = 32'd3410 + index*index; + #5 Clk=1; #5 Clk=0; + ReadRegister1 = index; + ReadRegister2 = index; + if((ReadData1 != 1955103904 - 10*index) || (ReadData2 != 1955103904 - 10*index)) begin + dutpassed = 0; + $display("Type 2 Test Case 1 Failed: A register changes while Write Enable is off"); + end + end + + + // 3. Decoder is broken – All registers are written to. + + // Test Case 1: + // After reset all register to zero, write '795546904 - 34*(register number)' to all register. Then check the value of each register + + // Reset all register to zero + RegWrite = 1; + WriteData = 0; + for(index=1;index<32;index=index+1) begin + WriteRegister = index; + #5 Clk=1; #5 Clk=0; + end + + for(index=1;index<32;index=index+1) begin + WriteRegister = index; + WriteData = 32'd795546904 - 34*index; + #5 Clk=1; #5 Clk=0; + end + + for(index=1;index<32;index=index+1) begin + ReadRegister1 = index; + ReadRegister2 = index; + if((ReadData1 != (795546904 - 34*index)) || (ReadData2 != (795546904 - 34*index))) begin + dutpassed = 0; + $display("Type 3 Test Case 1 Failed: Decoder is broken"); + end + end + + // Test Case 2: + // Write '8193' to register 13, '4294901760' to register 31, and '15793935' to register 16. + // Then Check the value of register 1, 13, 16, 31 + WriteRegister = 5'd13; + WriteData = 32'd8193; + #5 Clk=1; #5 Clk=0; + WriteRegister = 5'd31; + WriteData = 32'd4294901760; + #5 Clk=1; #5 Clk=0; + WriteRegister = 5'd16; + WriteData = 32'd15793935; + #5 Clk=1; #5 Clk=0; + + ReadRegister1 = 5'd1; + ReadRegister2 = 5'd13; + if((ReadData1 != 795546870) || (ReadData2 != 8193)) begin + dutpassed = 0; + $display("Type 3 Test Case 2 Failed: Decoder is broken"); + end + + ReadRegister1 = 5'd16; + ReadRegister2 = 5'd31; + if((ReadData1 != 15793935) || (ReadData2 != 4294901760)) begin + dutpassed = 0; + $display("Type 3 Test Case 2 Failed: Decoder is broken"); + end + + + + + // 4. Register Zero is actually a register instead of the constant value zero. + + // Test Case 1: + ReadRegister1 = 5'd0; + ReadRegister2 = 5'd0; + if((ReadData1 != 0) || (ReadData2 != 0)) begin + dutpassed = 0; + $display("Type 4 Test Case 1 Failed: Zero register has a non-zero value."); + end + + + // Test Case 2: + // Write '3410' to register 0, check its value changes + WriteRegister = 5'd0; + WriteData = 32'd3410; + RegWrite = 1; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != 0) || (ReadData2 != 0)) begin + dutpassed = 0; + $display("Type 4 Test Case 2 Failed: Zero register has a non-zero value"); + end + + // Test Case 3: + // Write '47186640' to register 0, check its value changes + WriteData = 32'd47186640; + #5 Clk=1; #5 Clk=0; + + if((ReadData1 != 0) || (ReadData2 != 0)) begin + dutpassed = 0; + $display("Type 4 Test Case 3 Failed: Zero register has a non-zero value"); + end + + // All done! Wait a moment and signal test completion. #5 endtest = 1; diff --git a/regfile.v b/regfile.v index b8a3c74..ee2d7c3 100644 --- a/regfile.v +++ b/regfile.v @@ -5,6 +5,8 @@ // 2 asynchronous read ports // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ +`include "decoders.v" +`include "register.v" module regfile ( @@ -21,7 +23,42 @@ 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; + + wire[31:0] wrenable; // Enable writing of each register + wire[31:0] regout[31:0]; + + decoder1to32 decoder( + .out(wrenable), + .enable(RegWrite), + .address(WriteRegister) + ); + + register32zero zero_register(regout[0], WriteData, wrenable[0], Clk); + generate + genvar i; + for (i=1; i<32; i=i+1) begin: generate_register + register32 register32bit( + .q(regout[i]), + .d(WriteData), + .wrenable(wrenable[i]), + .clk(Clk) + ); + end + endgenerate + + mux32to1by32 mux1(ReadData1, ReadRegister1, + regout[0], regout[1], regout[2], regout[3], regout[4], regout[5], regout[6], regout[7], regout[8], regout[9], + regout[10], regout[11], regout[12], regout[13], regout[14], regout[15], regout[16], regout[17], regout[18], regout[19], + regout[20], regout[21], regout[22], regout[23], regout[24], regout[25], regout[26], regout[27], regout[28], regout[29], + regout[30], regout[31] + ); + + mux32to1by32 mux2(ReadData2, ReadRegister2, + regout[0], regout[1], regout[2], regout[3], regout[4], regout[5], regout[6], regout[7], regout[8], regout[9], + regout[10], regout[11], regout[12], regout[13], regout[14], regout[15], regout[16], regout[17], regout[18], regout[19], + regout[20], regout[21], regout[22], regout[23], regout[24], regout[25], regout[26], regout[27], regout[28], regout[29], + regout[30], regout[31] + ); + endmodule \ No newline at end of file diff --git a/register.v b/register.v index dc9b8cb..bb1dd61 100644 --- a/register.v +++ b/register.v @@ -2,16 +2,108 @@ // 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 if(wrenable) begin - q = d; + q <= d; end end +endmodule + + +module register32 // Deliverable 2 +( + output reg[31:0] q, + input[31:0] d, + input wrenable, + input clk +); + // generate 32 1-bit registers connecting each bit + always @(posedge clk) begin + if (wrenable) begin + q <= d; + end + end + +endmodule + + +module register32zero //Deliverable 3 +( + output reg[31:0] q, + input[31:0] d, + input wrenable, + input clk +); + + always @(posedge clk) begin + q <= 0; + end + +endmodule + +module mux32to1by1 //Deliverable 4 +( + output out, + input[4:0] address, + input[31:0] inputs +); + assign out = inputs[address]; + +endmodule + + +module mux32to1by32 //Deliverable 5 +( + 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 32 inputs + 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]; // Connect the output of the array + endmodule \ No newline at end of file