diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72fd5f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.out +*.vcd diff --git a/README.md b/README.md index ddf0003..c037e9c 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,27 @@ # 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 -## 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 -); +See containing files. - 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 -``` - -## 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 @@ -123,68 +34,9 @@ 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) -); -``` - -### 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 +This shifts either 1 or 0 to the left by n bits, effectively setting the nth bit high. -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 | | +## Submission ## -## 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 diff --git a/RegComparison.jpg b/RegComparison.jpg new file mode 100644 index 0000000..a62d392 Binary files /dev/null and b/RegComparison.jpg differ diff --git a/mux32to1by32.v b/mux32to1by32.v new file mode 100644 index 0000000..090fc7a --- /dev/null +++ b/mux32to1by32.v @@ -0,0 +1,49 @@ +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 +); + 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 f13815a..cdb7910 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,20 +36,24 @@ 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) ); // Test harness asserts 'begintest' for 1000 time steps, starting at time 10 initial begin + + //$dumpfile("regfile.vcd"); + //$dumpvars; + begintest=0; #10; begintest=1; @@ -56,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 @@ -90,6 +101,43 @@ 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 + + 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 @@ -107,7 +155,11 @@ output reg Clk dutpassed = 1; #10 - // Test Case 1: + // 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) WriteRegister = 5'd2; @@ -115,28 +167,56 @@ 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 - if((ReadData1 != 42) || (ReadData2 != 42)) begin - dutpassed = 0; // Set to 'false' on failure - $display("Test Case 1 Failed"); - end + run_test(42, 42); - // Test Case 2: - // Write '15' to register 2, verify with Read Ports 1 and 2 + // Test Case 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; + + run_test(15, 15); + + // Test Case 3: + // Write to two registers, then clear them. Confirm that they are cleared. + RegWrite = 1; + ReadRegister1 = 5'd3; + ReadRegister2 = 5'd3; + + // Writing + WriteRegister = 5'd3; + WriteData = 32'd15; #5 Clk=1; #5 Clk=0; + // Clearing + WriteData=0; + run_test(0, 0); - if((ReadData1 != 15) || (ReadData2 != 15)) begin - dutpassed = 0; - $display("Test Case 2 Failed"); - end + // 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; + ReadRegister2 = 5'd1; + + run_test(0, 0); + + // 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; + ReadRegister1 = 5'd0; + + run_test(0, 0); // All done! Wait a moment and signal test completion. @@ -145,4 +225,4 @@ output reg Clk end -endmodule \ No newline at end of file +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..a5b9e37 --- /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; + #5 clk = 0; #5 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 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 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