Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions WRITEUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Homework 4
### Alexander Hoppe

## Deliverable 1

The first implementation uses a multiplexer to control whether or not the device is taking new inputs or just using its previous one.

<img src="flipflop_mux.png" style="width:400px">

The second implementation uses an AND gate on the CLK line, which is less robust to glitches in the WREN signal. If WREN glitches high during the high period of the CLK signal, the flipflop will pass through the state of the D pin, which is not the intended behavior.

<img src="flipflop_and.png" style="width:400px">

## Deliverable 6

```verilog
module decoder1to32
(
output[31:0] out,
input enable,
input[4:0] address
);
assign out = enable<<address;
endmodule
```

This module works as a decoder (sets one bit high based on address) by left shifting the enable register. If the device is enabled, enable will be `1'b1`. If it's not enabled, the enable will be `1'b0`. The next step is the left shift. If the address is 12 and the enable bit is high, the decoder will do `1'b1 << 12` which is `12'b100000000000`, a register with the 12th bit high. This is the behavior of a decoder.
8 changes: 8 additions & 0 deletions decoder1to32.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module decoder1to32
(
output[31:0] out,
input enable,
input[4:0] address
);
assign out = enable<<address;
endmodule
Binary file added flipflop_and.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added flipflop_mux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions mux32to1by1.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Behavioral 32 to 1 multiplexer
module mux32to1by1
(
output out,
input[4:0] address,
input[31:0] inputs
);
assign out = inputs[address];
endmodule
43 changes: 43 additions & 0 deletions mux32to1by32.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@


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;
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
1,157 changes: 1,157 additions & 0 deletions regfile.out

Large diffs are not rendered by default.

91 changes: 83 additions & 8 deletions regfile.t.v
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
);

Expand Down Expand Up @@ -91,6 +93,9 @@ output reg RegWrite,
output reg Clk
);

// For looping through cases
reg [5:0] index;

// Initialize register driver signals
initial begin
WriteData=32'd0;
Expand All @@ -107,7 +112,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;
Expand All @@ -123,7 +128,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;
Expand All @@ -138,11 +143,81 @@ output reg Clk
$display("Test Case 2 Failed");
end

// All correct functioning test cases
// Write 145 to given register, verify with read ports 1 and 2

for (index = 1; index < 32; index = index+1) begin

WriteRegister = index[4:0];
WriteData = 32'd145;
RegWrite = 1;
ReadRegister1 = index[4:0];
ReadRegister2 = index[4:0];
#5 Clk=1; #5 Clk=0;

if((ReadData1 != 145) || (ReadData2 != 145)) begin
dutpassed = 0;
$display("Test Case Failed Wrote 145 r:%b Read %d from %b and %d from %b", index[4:0], ReadData1, ReadRegister1, ReadData2, ReadRegister2);
end

end

// Check if Write Enable works
// Write 132 to all registers with RegWrite = 0, verify all ports are still 145

for (index = 1; index < 32; index = index+1) begin

WriteRegister = index[4:0];
WriteData = 32'd132;
RegWrite = 0;
ReadRegister1 = index[4:0];
ReadRegister2 = index[4:0];
#5 Clk=1; #5 Clk=0;

if((ReadData1 != 145) || (ReadData2 != 145)) begin
dutpassed = 0;
$display("Test Case WriteEnable Failed r:%b Read %d from %b and %d from %b", index[4:0], ReadData1, ReadRegister1, ReadData2, ReadRegister2);
end

end

// Test decoder works and only one register is being written
// Write 6983 to address 17, read address 16 and 18 as 145 still

WriteRegister = 5'd17;
WriteData = 32'd299;
RegWrite = 1;
ReadRegister1 = 5'd16;
ReadRegister2 = 5'd18;
#5 Clk=1; #5 Clk=0;

if((ReadData1 != 145) || (ReadData2 != 145)) begin
dutpassed = 0;
$display("Test Case decoder Failed Wrote %d to %b and Read %d from %b and %d from %b", WriteData, WriteRegister, ReadData1, ReadRegister1, ReadData2, ReadRegister2);
end


// Zero register working test cases
// Write 299 to register address zero, read zero from ports 1 and 2

WriteRegister = 5'b0;
WriteData = 32'd299;
RegWrite = 1;
ReadRegister1 = 5'b0;
ReadRegister2 = 5'b0;
#5 Clk=1; #5 Clk=0;

if((ReadData1 != 0) || (ReadData2 != 0)) begin
dutpassed = 0;
$display("Test Case zero reg Failed Read %d from %b and %d from %b", ReadData1, ReadRegister1, ReadData2, ReadRegister2);
end



// All done! Wait a moment and signal test completion.
#5
endtest = 1;

end

endmodule
endmodule
92 changes: 86 additions & 6 deletions regfile.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
// 1 synchronous, positive edge triggered write port
//------------------------------------------------------------------------------

`include "register32.v"
`include "register32zero.v"
`include "decoder1to32.v"
`include "mux32to1by32.v"

module regfile
(
output[31:0] ReadData1, // Contents of first register read
Expand All @@ -17,11 +22,86 @@ input[4:0] WriteRegister, // Address of register to write
input RegWrite, // Enable writing of register when High
input Clk // Clock (Positive Edge Triggered)
);
wire [31:0] enable;
wire [31:0] regout[31:0];
genvar i;

// Instantiate decoder
decoder1to32 en_decoder(enable[31:0], RegWrite, WriteRegister);

// 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;
// First register is always zero
register32zero register0(regout[0], WriteData, enable[0], Clk);
generate
for (i = 1; i < 32; i=i+1) begin : register_generate
register32 register (regout[i], WriteData, enable[i], Clk);
end
endgenerate

endmodule
//Output Muxes
mux32to1by32 mux_d1 (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 mux_d2 (ReadData1, 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
17 changes: 17 additions & 0 deletions register32.v
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions register32zero.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 32 Bit dummy register with enable
// Positive edge triggered
module register32zero
(
output reg[31:0] q,
input[31:0] d,
input wrenable,
input clk
);

always @(posedge clk) begin
if(wrenable) begin
q = 0;
end
end

endmodule
4 changes: 4 additions & 0 deletions run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

iverilog -Wall -o regfile.out regfile.t.v
vvp regfile.out