diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..287f121 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +make_and_test: + iverilog -o regfile regfile.t.v + ./regfile + diff --git a/multiplexer.t.v b/multiplexer.t.v new file mode 100644 index 0000000..c74f415 --- /dev/null +++ b/multiplexer.t.v @@ -0,0 +1,22 @@ +`timescale 1 ns / 1 ps +`include "multiplexer32.v" + +module multiplexerTest(); + reg[31:0] inputs; + reg[4:0] address; + wire out; + + mux32to1by1 mux(out, address[4:0], inputs[31:0]); + + initial begin + $display("Input Address Output"); + inputs=32'b00000000111111110000000011111111; + address=5'b00000; + #5000 + $display("%b %b %b", inputs[31:0], address[4:0], out); + + address=5'b01001; #5000 + $display("%b %b %b", inputs[31:0], address[4:0], out); + end + +endmodule \ No newline at end of file diff --git a/multiplexer32.v b/multiplexer32.v new file mode 100644 index 0000000..e408036 --- /dev/null +++ b/multiplexer32.v @@ -0,0 +1,8 @@ +module mux32to1by1 +( + output out, + input[4:0] address, + input[31:0] inputs +); + assign out=inputs[address]; +endmodule \ No newline at end of file diff --git a/mux32to1by32.v b/mux32to1by32.v new file mode 100644 index 0000000..1c98f0d --- /dev/null +++ b/mux32to1by32.v @@ -0,0 +1,42 @@ +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..ef3dad9 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(); @@ -16,7 +17,6 @@ module hw4testbenchharness(); reg begintest; // Set High to begin testing register file wire dutpassed; // Indicates whether register file passed tests - // Instantiate the register file being tested. DUT = Device Under Test regfile DUT ( @@ -138,6 +138,67 @@ output reg Clk $display("Test Case 2 Failed"); end + // Test Write Enable for broken or ignored + // Fails if a same action is made regardless of write enable + WriteRegister = 5'd4; + WriteData = 32'd16; + RegWrite = 1; + ReadRegister1 = 5'd4; + ReadRegister2 = 5'd4; + #5 Clk=1; #5 Clk=0; + + WriteRegister = 5'd5; + WriteData = 32'd16; + RegWrite = 0; + ReadRegister1 = 5'd4; + ReadRegister2 = 5'd5; + #5 Clk=1; #5 Clk=0; + + if(ReadData1 == ReadData2) begin + dutpassed = 0; + $display("Performing same action regardless of write enable"); + end + + // Test for decoder broken + WriteRegister = 5'd4; + WriteData = 32'd10; + RegWrite = 1; + ReadRegister1 = 5'd4; + ReadRegister2 = 5'd10; + #5 Clk=1; #5 Clk=0; + + if ((ReadData1 & ReadData2) == ReadData1) begin + dutpassed = 0; + $display("Decoder broken, multiple registers written to"); + end + + // Test value of register zero + WriteRegister = 5'd0; + WriteData = 32'd10; + RegWrite = 1; + ReadRegister1 = 5'd0; + ReadRegister2 = 5'd10; + #5 Clk=1; #5 Clk=0; + + if (ReadData1 != 0) begin + dutpassed = 0; + $display("Constant value register broken, not always outputting 0"); + end + + // Test port 2 + ReadRegister1 = 5'd10; + ReadRegister2 = 5'd10; + #5 Clk=1; #5 Clk=0; + + if (ReadData1 != ReadData1) begin + dutpassed = 0; + $display("A port is reporting an incorrect value"); + end + + // Perfect register file + if(dutpassed == 1) begin + $display("Fully perfect register file"); + end // All done! Wait a moment and signal test completion. #5 diff --git a/regfile.v b/regfile.v index b8a3c74..c2e8517 100644 --- a/regfile.v +++ b/regfile.v @@ -5,6 +5,10 @@ // 2 asynchronous read ports // 1 synchronous, positive edge triggered write port //------------------------------------------------------------------------------ +`include "decoders.v" +`include "register.v" +`include "mux32to1by32.v" +`include "multiplexer32.v" module regfile ( @@ -18,10 +22,44 @@ 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; + wire[31:0] reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23, reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31; + wire[31:0] decodePos; + // Register to write to + decoder1to32 decode(decodePos, RegWrite, WriteRegister); + register32zero reg32_0(reg0, WriteData, decodePos[0], Clk); + register32 reg32_1(reg1, WriteData, decodePos[1], Clk); + register32 reg32_2(reg2, WriteData, decodePos[2], Clk); + register32 reg32_3(reg3, WriteData, decodePos[3], Clk); + register32 reg32_4(reg4, WriteData, decodePos[4], Clk); + register32 reg32_5(reg5, WriteData, decodePos[5], Clk); + register32 reg32_6(reg6, WriteData, decodePos[6], Clk); + register32 reg32_7(reg7, WriteData, decodePos[7], Clk); + register32 reg32_8(reg8, WriteData, decodePos[8], Clk); + register32 reg32_9(reg9, WriteData, decodePos[9], Clk); + register32 reg32_10(reg10, WriteData, decodePos[10], Clk); + register32 reg32_11(reg11, WriteData, decodePos[11], Clk); + register32 reg32_12(reg12, WriteData, decodePos[12], Clk); + register32 reg32_13(reg13, WriteData, decodePos[13], Clk); + register32 reg32_14(reg14, WriteData, decodePos[14], Clk); + register32 reg32_15(reg15, WriteData, decodePos[15], Clk); + register32 reg32_16(reg16, WriteData, decodePos[16], Clk); + register32 reg32_17(reg17, WriteData, decodePos[17], Clk); + register32 reg32_18(reg18, WriteData, decodePos[18], Clk); + register32 reg32_19(reg19, WriteData, decodePos[19], Clk); + register32 reg32_20(reg20, WriteData, decodePos[20], Clk); + register32 reg32_21(reg21, WriteData, decodePos[21], Clk); + register32 reg32_22(reg22, WriteData, decodePos[22], Clk); + register32 reg32_23(reg23, WriteData, decodePos[23], Clk); + register32 reg32_24(reg24, WriteData, decodePos[24], Clk); + register32 reg32_25(reg25, WriteData, decodePos[25], Clk); + register32 reg32_26(reg26, WriteData, decodePos[26], Clk); + register32 reg32_27(reg27, WriteData, decodePos[27], Clk); + register32 reg32_28(reg28, WriteData, decodePos[28], Clk); + register32 reg32_29(reg29, WriteData, decodePos[29], Clk); + register32 reg32_30(reg30, WriteData, decodePos[30], Clk); + register32 reg32_31(reg31, WriteData, decodePos[31], Clk); + + mux32to1by32 rd1(ReadData1, ReadRegister1, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23, reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31); + mux32to1by32 rd2(ReadData2, ReadRegister2, reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg10, reg11, reg12, reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23, reg24, reg25, reg26, reg27, reg28, reg29, reg30, reg31); endmodule \ No newline at end of file diff --git a/register.t.v b/register.t.v new file mode 100644 index 0000000..7bbb78d --- /dev/null +++ b/register.t.v @@ -0,0 +1,42 @@ +`timescale 1 ns / 1 ps +`include "register.v" + +module registerTest(); + reg[31:0] inputs; + reg wrenable; + reg clk; + wire[31:0] out32; + wire[31:0] out0; + + register32 reg32(out32[31:0], inputs[31:0], wrenable, clk); + register32zero reg32zero(out0[31:0], inputs[31:0], wrenable, clk); + + initial begin + $display("register32"); + $display("Input Enable Output"); + inputs=32'b00000000111111110000000011111111; + wrenable=1; + clk=1; + #5000 + $display("%b %b %b", inputs[31:0], wrenable, out32); + + inputs=32'b11111111000000001111111100000000; #5000 + $display("%b %b %b", inputs[31:0], wrenable, out32); + + clk=0; + clk=1; #5000 + $display("%b %b %b", inputs[31:0], wrenable, out32); + + $display("register32zero"); + $display("Input Enable Output Clock"); + wrenable=1; + clk=0; + #5000 + $display("%b %b %b %b", inputs[31:0], wrenable, out0, clk); + + clk=1; + #5000 + $display("%b %b %b %b", inputs[31:0], wrenable, out0, clk); + end + +endmodule \ No newline at end of file diff --git a/register.v b/register.v index dc9b8cb..7ecb3fa 100644 --- a/register.v +++ b/register.v @@ -14,4 +14,32 @@ 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 = 0; + end endmodule \ No newline at end of file diff --git a/report.pdf b/report.pdf new file mode 100644 index 0000000..e1a7e00 Binary files /dev/null and b/report.pdf differ