diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ce383cb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.vcd
+*.out
diff --git a/WRITEUP.md b/WRITEUP.md
new file mode 100644
index 0000000..c6807d5
--- /dev/null
+++ b/WRITEUP.md
@@ -0,0 +1,74 @@
+
+# Lab 2 Writeup
+### William Derksen, Alexander Hoppe, Sam Myers, Taylor Sheneman
+
+## Input Conditioner
+
+The input conditioner contains three important elements to test: the synchronizers, debouncer, and edge detectors.
+
+To start, the synchronizers cannot actually correctly be tested. The point of the second synchronizer is to prevent propagation of glitches from the first synchronizer due to violations of setup and hold time. We can't really test this because Verilog doesn't simulate these real world attributes of circuitry.
+
+The debouncers were tested by setting the input pin from 0 to 1 for 1, 2, 3, and 4 clock cycles. The first 3 shouldn't set the conditioned signal correctly, but the last one should.
+
+
+
+Lastly the edge detectors were measured by simply sending in some longer signals and checking for the impulses at the beginning and end of the conditioned signal for the positive edge and negative edge respectively.
+
+
+
+## Shift Register
+
+The test strategy for the shift register was to do a lean, quick validation that it worked the way we expected, and as long as we controlled how it was being used it wouldn't get into any problematic states. There were two main sections to the test: parallel load testing and regular serial shift behavior. We started by shifting in some data and then asserting a parallel load at the same time as one of the shift ins, and verifying that the parallel load took precedence. For the serial tests, we shifted in all ones, then shifted in all zeros. We verified that the parallel readout and the serial output were valid at every step of this process.
+
+## Midpoint FPGA Implementation
+
+We tested the intermediate input conditioner/shift register device by uploading it to an FPGA with LED outputs. Serial and parallel inputs and outputs all worked as expected.
+
+## SPI peripheral components
+
+Data Memory: A two dimensional array of values that behaves according to typical data memory control signals. Takes data input from shift register, address from address latch, and write enable signal DM_WE, outputs to shift register.
+
+Address Latch: A state-holding latch with write enable ADDR_WE, takes shift register parallel out and outputs to data memory.
+
+MISO buffer: D flip-flop with a tri-state buffer. Takes shift register serial out, outputs to MISO pin on negative edges (while enabled with MISO_BUFE).
+
+## Finite State Machine
+
+For all these components to work together properly, we need precisely timed control signals to coordinate their actions. We abstracted out this control signal logic into a finite state machine (FSM) component, intended to track the current state of the SPI transaction and output the necessary control lines. The FSM is able to read two signal lines from the master SPI bus (Chip Select CS and SPI Clock SCLK) and has access to the least significant bit of the shift register.
+
+Functionally, the state machine must:
+ - Recognize the beginning of a transaction
+ - Wait for the appropriate number of clock cycles while address bits are read in
+ - Enable the write to the Address Latch to save address bits
+ - Check the incoming Read/Write bit
+ - (Write operation) Wait for data to be written to the shift register
+ - (Write operation) Write to data memory at the previously saved address
+ - (Read operation) Enable parallel load from data memory to the shift register
+ - (Read operation) Allow bits to be read out of the shift register on the MISO line
+ - Reset to idle state at the end of the transaction
+
+Our design, made to fulfill these requirements:
+
+
+
+This was implemented in code in a switch-case pattern, with each case corresponding to a control state, which defines the state of the four possible control signal outputs.
+
+In testing SPI memory, we realized we wouldn't have access to SCLK after chip select goes high, which necessitated some redesign.
+
+
+
+In addition, we modified the code to always hard reset to idle state on chip select high.
+
+## SPI Memory
+
+Finally, we wrote a top-level SPI module that connected all the appropriate component ports into a complete SPI memory module.
+
+To validate that the SPI memory was actually working, we designed a test bench with two helper tasks for SPI write and SPI read. To do a basic test that it worked, the first six transactions in the test bench are just a write of a byte followed by reading that same byte.
+
+To verify that the addressing scheme worked nicely and also that repeated reads or repeated writes work, we designed a series of six writes to different addresses, and then read them all back and verified that the proper data came out.
+
+In designing the test benches for the SPI and examining the spec, we realized that our FSM did not have proper support for resetting to idle state when the CS line had a positive edge during the middle of a transaction. This prompted some redesign of the FSM.
+
+## Work Plan Reflection
+
+Scheduling turned out to be pretty difficult this time around, so we ended up doing a lot of work in more concentrated periods, rather than spread out as we planned. Almost none of the deadlines we planned for ended up being accurate. We spent significantly longer on the finite state machine than we expected, and as usual, despite our efforts to the contrary, testing took a lot longer than we planned for. On the other hand, we planned for building a lot of components from scratch that were actually already written in the initial code, so that helped to make up for some of our unexpected slowdowns. The most problematic deviation from the plan is probably that we didn't get the complete device working until Thursday night.
diff --git a/buffer.v b/buffer.v
new file mode 100644
index 0000000..26c5c80
--- /dev/null
+++ b/buffer.v
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+// Buffer for ouput of MISO
+//------------------------------------------------------------------------------
+
+module buffer
+#(parameter width = 1)
+(
+input [width-1:0] in,
+input en,
+output [width-1:0] out
+ );
+
+ // Assign out to input or high-z
+ assign out = en ? in : {width{1'bz}};
+
+endmodule
diff --git a/datamemory.v b/datamemory.v
index 0d82131..02225af 100644
--- a/datamemory.v
+++ b/datamemory.v
@@ -17,7 +17,7 @@ module datamemory
input [addresswidth-1:0] address,
input writeEnable,
input [width-1:0] dataIn
-)
+);
reg [width-1:0] memory [depth-1:0];
diff --git a/deliverable_outline.md b/deliverable_outline.md
new file mode 100644
index 0000000..65e8374
--- /dev/null
+++ b/deliverable_outline.md
@@ -0,0 +1,33 @@
+## Project Deliverables
+
+### ~~Midpoint Checkin~~
+- ~~Input Conditioner Edges~~
+- ~~Shift Register~~
+- ~~Midpoint Module~~
+- ~~FPGA Implementation~~
+
+### SPI Memory
+- ~~Shift Register Module~~
+- Data Memory Module
+- Address Latch Module
+- Buffer Module
+- DFF Module
+- Finite State Machine
+ + Paper FSM
+ + Implementation
+
+### SPI Memory Testing
+- Verilog test bench for FSM
+- ~~Verilog tests for Shift Register~~
+- Verilog tests for complete SPI Memory
+
+### Report
+- Input Conditioner
+ + ~~Waveforms~~
+ + Structural Schematic
+ + Debounce glitch time analysis
+- Shift register
+ + Test bench strategy
+- SPI Memory
+ + Testing strategy
+- Work Plan Reflection
diff --git a/dff.v b/dff.v
new file mode 100644
index 0000000..7b7e6e1
--- /dev/null
+++ b/dff.v
@@ -0,0 +1,20 @@
+//------------------------------------------------------------------------
+// General DFF
+// Parameterized width (in bits)
+//------------------------------------------------------------------------
+
+module dff
+#(parameter width = 1)
+(
+input clk, // Global FPGA Clock
+input clockEdge, // Device Clock Edge
+input [width-1:0] D, // Input
+output reg [width-1:0] Q // Output
+ );
+
+ always @(posedge clk) begin
+ if (clockEdge) begin
+ Q <= D;
+ end
+ end
+endmodule
diff --git a/fsm.t.v b/fsm.t.v
new file mode 100644
index 0000000..26c0b32
--- /dev/null
+++ b/fsm.t.v
@@ -0,0 +1,353 @@
+//------------------------------------------------------------------------
+// TestBench
+//------------------------------------------------------------------------
+
+`timescale 1 ns / 1 ps
+`include "fsm.v"
+
+module fsmtestbench();
+ wire clk; // FPGA clock
+ wire sclk; // SPI clock
+ wire cs_pin; // SPI chip select
+ wire shiftReg0; // SPI master out slave in
+ wire addr_WE; //Control signal
+ wire miso_BUFE; //Control signal
+ wire DM_WE; //Control signal
+ wire SR_WE; //Control signal
+ wire[7:0] state;
+
+ reg begintest;
+ wire dutpassed;
+ wire endtest;
+
+ FSM dut(
+ .clk(clk),
+ .sclk(sclk),
+ .cs_pin(cs_pin),
+ .shiftReg0(shiftReg0),
+ .addr_WE(addr_WE),
+ .miso_BUFE(miso_BUFE),
+ .DM_WE(DM_WE),
+ .SR_WE(SR_WE),
+ .state(state)
+ );
+
+ fsmtester tester(
+ .begintest(begintest),
+ .endtest(endtest),
+ .dutpassed(dutpassed),
+ .clk(clk),
+ .sclk(sclk),
+ .cs_pin(cs_pin),
+ .shiftReg0(shiftReg0),
+ .addr_WE(addr_WE),
+ .miso_BUFE(miso_BUFE),
+ .DM_WE(DM_WE),
+ .SR_WE(SR_WE),
+ .state(state)
+ );
+
+ initial begin
+ $dumpfile("fsm.vcd");
+ $dumpvars(0, dut);
+ begintest=0;
+ #10;
+ begintest=1;
+ #100000;
+ end
+
+ always @(posedge endtest) begin
+ $display("DUT passed?: %b", dutpassed);
+ end
+endmodule
+
+module fsmtester(
+ input begintest,
+ output reg endtest,
+ output reg dutpassed,
+
+ output reg clk, // FPGA clock
+ output reg sclk, // SPI clock
+ output reg cs_pin, // SPI chip select
+ output reg shiftReg0, // SPI master out slave in
+ input addr_WE, //Control signal
+ input miso_BUFE, //Control signal
+ input DM_WE, //Control signal
+ input SR_WE, //Control signal
+ input[7:0] state // state of FSM
+);
+ reg[7:0] testnum;
+ reg statecorrect;
+ function statecheck;
+ input[7:0] ourstate, correctstate;
+ begin
+ statecheck = (1 === (ourstate === correctstate));
+ end
+ endfunction
+ function dutcheck;
+ input check, check2, dutpassed;
+ reg inter;
+ begin
+ // Demonstrates driving external Global Reg
+ inter = (check == check2);
+ dutcheck = (inter & dutpassed);
+ end
+ endfunction
+
+ function[7:0] dutprint;
+ input[7:0] state;
+ input integer testnum;
+ input dutpassed;
+ begin
+ if(dutpassed === 1)begin
+ $display("Test %d Passed: State is %b", testnum, state);
+ end else begin
+ $display("Test %d Failed: State is %b", testnum, state);
+ end
+ dutprint = testnum + 1;
+ end
+ endfunction
+ initial begin
+ clk=0;
+ sclk=0;
+ cs_pin=1;
+ shiftReg0=0;
+ testnum = 0;
+ statecorrect = 0;
+ end
+
+ always #10 clk=!clk;
+
+ always #500 sclk=!sclk;
+
+ always @(posedge begintest) begin
+ endtest = 0;
+ dutpassed = 1;
+
+ #1100;
+
+ //** WRITE TEST **//
+
+ // IDLE
+ statecorrect = statecheck(state, 8'b00000001);
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+
+
+ // ADDRESS
+ cs_pin = 0;
+ repeat(6)
+ begin
+ #1000;
+ statecorrect = statecheck(state, 8'b00000010);
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+ end
+
+ // ADDRESS_WRITE
+
+ #1000;
+ statecorrect = statecheck(state, 8'b00000100);
+
+
+ dutpassed = dutcheck(1, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // WRITE_WAIT
+ repeat(8)
+ begin
+ #1000;
+ statecorrect = statecheck(state, 8'b00001000);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+ end
+
+ // WRITE_MEM
+
+ #1000;
+ statecorrect = statecheck(state, 8'b00010000);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(1, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // IDLE
+ #1000;
+ statecorrect = statecheck(state, 8'b00000001);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // IDLE
+ cs_pin = 1;
+ #1000;
+ statecorrect = statecheck(state, 8'b00000001);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ if(dutpassed)begin
+ $display("You must be a scholar, cuz your writing is on point! (Write Command Passed; %d Tests Passed)", testnum);
+ end else begin
+ $display("F-F-F-FAILURE! (Write Command Failed)");
+ end
+
+ //** READ TEST **//
+
+ shiftReg0 = 1;
+ testnum = 0;
+ //IDLE
+ #1000;
+ statecorrect = statecheck(state, 8'b00000001);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // ADDRESS
+ cs_pin = 0;
+ repeat(6)
+ begin
+ #1000;
+ statecorrect = statecheck(state, 8'b00000010);
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+ end
+
+ // ADDRESS_WRITE
+
+ #1000;
+ statecorrect = statecheck(state, 8'b00000100);
+
+
+ dutpassed = dutcheck(1, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // READ_START
+
+ #1000;
+ statecorrect = statecheck(state, 8'b00100000);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(1, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(1, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // READ
+
+ repeat(7)
+ begin
+ #1000;
+ statecorrect = statecheck(state, 8'b01000000);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(1, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+ end
+
+ // IDLE
+
+ #1000;
+ statecorrect = statecheck(state, 8'b00000001);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+ // IDLE
+ cs_pin = 1;
+ #1000;
+ statecorrect = statecheck(state, 8'b00000001);
+
+
+ dutpassed = dutcheck(0, addr_WE, dutpassed);
+ dutpassed = dutcheck(0, miso_BUFE, dutpassed);
+ dutpassed = dutcheck(0, DM_WE, dutpassed);
+ dutpassed = dutcheck(0, SR_WE, dutpassed);
+ dutpassed = dutcheck(1, statecorrect, dutpassed);
+
+ testnum = dutprint(state, testnum, dutpassed);
+
+
+ if(dutpassed)begin
+ $display("Oh Dang Son! Your page turning is on fire!! (Read Command Passed; %d Tests Passed)", testnum);
+ end else begin
+ $display("F-F-F-FAILURE! (Read Command Failed)");
+ end
+ endtest = 1;
+ $finish;
+
+ end
+endmodule
diff --git a/fsm.v b/fsm.v
new file mode 100644
index 0000000..57453ba
--- /dev/null
+++ b/fsm.v
@@ -0,0 +1,177 @@
+//------------------------------------------------------------------------
+// FSM
+//------------------------------------------------------------------------
+
+module FSM
+(
+ input clk, // FPGA clock
+ input sclk, // SPI clock
+ input cs_pin, // SPI chip select
+ input shiftReg0, // SPI master out slave in
+ output reg addr_WE, //Control signal
+ output reg miso_BUFE, //Control signal
+ output reg DM_WE, //Control signal
+ output reg SR_WE, //Control signal
+ output reg[7:0] state
+);
+
+ reg[2:0] counter;
+ //reg[7:0] bitmap;
+
+ //reg [7:0] state;
+
+ localparam
+ IDLE = 8'b00000001,
+ ADDRESS = 8'b00000010,
+ ADDRESS_WRITE = 8'b00000100,
+ WRITE_WAIT = 8'b00001000,
+ WRITE_MEM = 8'b00010000,
+ READ_START = 8'b00100000,
+ READ = 8'b01000000,
+ DONE = 8'b10000000;
+
+ initial state = IDLE;
+
+ always @(posedge clk) begin
+ //if(state == 8'bx) begin
+ // state <= IDLE;
+ //end else begin
+ if (cs_pin == 1) begin
+ state = IDLE;
+ addr_WE <= 0;
+ miso_BUFE <= 0;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+ // forces all write enables to only
+ // occur for one sys clock cycle
+ if (SR_WE == 1)
+ SR_WE <= 0;
+ if (addr_WE == 1)
+ addr_WE <= 0;
+ if (DM_WE == 1)
+ DM_WE <= 0;
+
+ if(sclk) begin
+ case(state)
+ IDLE: begin
+ //currstate <= IDLE;
+ if(cs_pin == 0) begin
+ state = ADDRESS;
+ counter <= 3'b000;
+ end else if (cs_pin == 1) begin
+ state = IDLE;
+ end
+ end
+
+ ADDRESS: begin
+ //currstate <= ADDRESS;
+ if(counter < 5) begin
+ state = ADDRESS;
+ counter <= counter + 3'b001;
+ end else begin
+ state = ADDRESS_WRITE;
+ end
+ end
+
+ ADDRESS_WRITE: begin
+ //currstate <= ADDRESS_WRITE;
+ // addr_WE <= 1;
+ counter <= 3'b000;
+ if(shiftReg0 == 1) begin
+ state = READ_START;
+ end else begin
+ state = WRITE_WAIT;
+ end
+ end
+
+ READ_START: begin
+ //currstate = READ_START;
+ //SR_WE
+ //miso_BUFE
+ state = READ;
+ end
+
+ READ: begin
+ //miso_BUFE
+ //currstate = READ;
+ if(counter < 6) begin
+ state = READ;
+ counter <= counter + 3'b001;
+ end else begin
+ state = IDLE;
+ end
+ end
+
+ WRITE_WAIT: begin
+ //currstate = WRITE_WAIT;
+ if(counter < 7) begin
+ state = WRITE_WAIT;
+ counter <= counter + 3'b001;
+ end else begin
+ state = WRITE_MEM;
+ end
+ end
+
+ WRITE_MEM: begin
+ //currstate = WRITE_MEM;
+ state = IDLE;
+ //DM_WE
+ end
+ endcase
+ case (state)
+ //driving - follow traffic laws
+ IDLE: begin
+ addr_WE <= 0;
+ miso_BUFE <= 0;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+
+
+ ADDRESS: begin
+ addr_WE <= 0;
+ miso_BUFE <= 0;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+
+
+ ADDRESS_WRITE: begin
+ addr_WE <= 1;
+ miso_BUFE <= 0;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+
+ READ_START:begin
+ addr_WE <= 0;
+ miso_BUFE <= 1;
+ DM_WE <= 0;
+ SR_WE <= 1;
+ end
+
+ READ:begin
+ addr_WE <= 0;
+ miso_BUFE <= 1;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+
+ WRITE_WAIT:begin
+ addr_WE <= 0;
+ miso_BUFE <= 0;
+ DM_WE <= 0;
+ SR_WE <= 0;
+ end
+
+ WRITE_MEM:begin
+ addr_WE <= 0;
+ miso_BUFE <= 0;
+ DM_WE <= 1;
+ SR_WE <= 0;
+ end
+ endcase
+ end
+ end
+endmodule
diff --git a/fsm_board.jpg b/fsm_board.jpg
new file mode 100644
index 0000000..25d27c8
Binary files /dev/null and b/fsm_board.jpg differ
diff --git a/fsm_fixed.jpg b/fsm_fixed.jpg
new file mode 100644
index 0000000..a386b94
Binary files /dev/null and b/fsm_fixed.jpg differ
diff --git a/input_conditioner.png b/input_conditioner.png
new file mode 100644
index 0000000..30ec1fa
Binary files /dev/null and b/input_conditioner.png differ
diff --git a/inputconditioner.t.v b/inputconditioner.t.v
index 2814163..1312313 100644
--- a/inputconditioner.t.v
+++ b/inputconditioner.t.v
@@ -1,29 +1,237 @@
//------------------------------------------------------------------------
// Input Conditioner test bench
//------------------------------------------------------------------------
+`timescale 1 ns / 1 ps
+`include "inputconditioner.v"
+
module testConditioner();
- reg clk;
- reg pin;
+ wire clk;
+ wire pin;
wire conditioned;
wire rising;
wire falling;
-
+
+ reg begintest;
+ wire dutpassed;
+ wire endtest;
+
inputconditioner dut(.clk(clk),
.noisysignal(pin),
.conditioned(conditioned),
.positiveedge(rising),
- .negativeedge(falling))
+ .negativeedge(falling));
+
+ inputconditionertester tester
+ (
+ .begintest(begintest),
+ .endtest(endtest),
+ .dutpassed(dutpassed),
+ .pin(pin),
+ .clk(clk),
+ .conditioned(conditioned),
+ .rising(rising),
+ .falling(falling)
+ );
+
+ initial begin
+ $dumpfile("inputconditioner.vcd");
+ $dumpvars(0, dut);
+ begintest=0;
+ #10;
+ begintest=1;
+ #10000;
+
+ end
+
+ // Display test results ('dutpassed' signal) once 'endtest' goes high
+ always @(posedge endtest) begin
+ $display("DUT passed?: %b", dutpassed);
+ end
// Generate clock (50MHz)
- initial clk=0;
- always #10 clk=!clk; // 50MHz Clock
-
- initial begin
+ //initial clk=0;
+ /*always begin
+ if (testrun == 1)
+ #10 clk=!clk; // 50MHz Clock
+ end*/
+ //always #10 clk=!clk;
+
+ /*initial begin
+ $dumpfile("inputconditioner.vcd");
+ $dumpvars(0, dut);
+ pin = 0; #1
+ pin = 1; #1
+ pin = 0; #2
+ pin = 1; #2
+ pin = 0; #5
+ pin = 1; #5
+ pin = 0; #10
+ pin = 1; #10
+ pin = 0; #20
+ pin = 1; #20
+ pin = 0; #40
+ pin = 1; #40
+ pin = 0; #80
+ pin = 1; #80
+ pin = 0; #160
+ pin = 1; #160
+ pin = 0; #320
+ pin = 1; #320
+ $finish;
+ end*/
// Your Test Code
// Be sure to test each of the three conditioner functions:
// Synchronization, Debouncing, Edge Detection
-
+
+endmodule
+
+
+module inputconditionertester
+(
+ input begintest,
+ output reg endtest,
+ output reg dutpassed,
+
+ output reg pin,
+ output reg clk,
+ input conditioned,
+ input rising,
+ input falling
+ );
+ initial begin
+ pin=0;
+ clk=0;
+ end
+
+ always #10 clk=!clk;
+
+ always @(posedge begintest) begin
+ endtest = 0;
+ dutpassed = 1;
+ #100;
+
+ #9 //offset from clock
+ //*** Syncronization Testing Here (???) ***//
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ pin = 1; #2; pin = 0; #2;
+ #200;
+ #11 //offset from clock
+ //If the clock actually had a set and hold time, this signal would cause synchronizer0 to probably have a glitch
+ //which synchronizer1 would then remove.
+
+ if(conditioned==1) begin
+ $display("Your synchronization is looking on point! (Passed Synchronizer Testing)");
+ end
+
+ //*** Debouncing Testing Here ***//
+ #1 //offset from clock
+
+ pin = 1; #20;
+
+ pin = 0; #40;
+
+ if((conditioned == 1)) begin
+ dutpassed = 0; // Set to 'false' on failure
+ $display("Conditioned signal activated at 10 ns of signal. (Test Failed)");
+ end
+
+ #200;
+
+ pin = 1; #40;
+
+ pin = 0; #40;
+
+ if((conditioned == 1)) begin
+ dutpassed = 0; // Set to 'false' on failure
+ $display("Conditioned signal activated at 20 ns of signal. (Test Failed)");
+ end
+
+ #200;
+ pin = 1; #60;
+
+ pin = 0; #40;
+
+ if((conditioned == 1)) begin
+ dutpassed = 0; // Set to 'false' on failure
+ $display("Conditioned signal activated at 30 ns of signal. (Test Failed)");
+ end
+
+ #200;
+ pin = 1; #80;
+ pin = 0; #40;
+
+ if((conditioned == 0)) begin
+ dutpassed = 0; // Set to 'false' on failure
+ $display("Conditioned signal failed to activate at 40 ns of signal. (Test Failed)");
+ end
+
+ #200;
+
+ if(dutpassed == 1) begin
+ $display("Nice going, Your debouncer works hella fine. (Passed Debouncer Testing)");
+ end
+
+ #19; //reset offset back to line up signals with clock
+
+ //*** Edge Detection Testing ***//
+
+ pin = 0; #200
+ pin = 1; #80; #1; //offset so not reading exactly at posedge of clock
+
+ if(rising == 1) begin
+ dutpassed = 0;
+ $display("Rising set too early");
+ end
+ #20
+ if(rising == 0) begin
+ dutpassed = 0;
+ $display("Rising not set correctly");
+ end
+ #20
+ if(rising == 1) begin
+ dutpassed = 0;
+ $display("Rising set too late");
+ end
+
+ #19; //reset offset back to line up signals with clock
+
+ pin = 0; #80 #1;
+
+ if(falling == 1) begin
+ dutpassed = 0;
+ $display("Falling set too early");
+ end
+ #20
+ if(falling == 0) begin
+ dutpassed = 0;
+ $display("Falling not set correctly");
+ end
+ #20
+ if(falling == 1) begin
+ dutpassed = 0;
+ $display("Falling set too late");
+ end
+
+ #19;
+
+ if(dutpassed == 1) begin
+ $display("You really know how to live on the edge! (Passed Edge Detection testing)");
+ end
+
+ endtest = 1;
+
+ $finish;
+ end
+
endmodule
diff --git a/inputconditioner.v b/inputconditioner.v
index 736a866..2acad4d 100644
--- a/inputconditioner.v
+++ b/inputconditioner.v
@@ -4,7 +4,6 @@
// 2) Debounces input
// 3) Creates pulses at edge transitions
//------------------------------------------------------------------------
-
module inputconditioner
(
input clk, // Clock domain to synchronize input to
@@ -16,11 +15,11 @@ output reg negativeedge // 1 clk pulse at falling edge of conditioned
parameter counterwidth = 3; // Counter size, in bits, >= log2(waittime)
parameter waittime = 3; // Debounce delay, in clock cycles
-
+
reg[counterwidth-1:0] counter = 0;
reg synchronizer0 = 0;
reg synchronizer1 = 0;
-
+
always @(posedge clk ) begin
if(conditioned == synchronizer1)
counter <= 0;
@@ -28,10 +27,16 @@ output reg negativeedge // 1 clk pulse at falling edge of conditioned
if( counter == waittime) begin
counter <= 0;
conditioned <= synchronizer1;
+ if (synchronizer1 == 1)
+ positiveedge <= 1;
+ else
+ negativeedge <= 1;
end
- else
+ else
counter <= counter+1;
end
+ if (positiveedge) positiveedge <= 0;
+ if (negativeedge) negativeedge <= 0;
synchronizer0 <= noisysignal;
synchronizer1 <= synchronizer0;
end
diff --git a/inputconditioner_waveform.png b/inputconditioner_waveform.png
new file mode 100644
index 0000000..f9e7f45
Binary files /dev/null and b/inputconditioner_waveform.png differ
diff --git a/midpoint.v b/midpoint.v
new file mode 100644
index 0000000..6b2146a
--- /dev/null
+++ b/midpoint.v
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+// Midpoint checkin 8-bit shift register with input conditioners
+//------------------------------------------------------------------------------
+`include "shiftregister.v"
+`include "inputconditioner.v"
+
+module midpoint(
+input clk,
+input button0,
+input switch0,
+input switch1,
+input [7:0] parallelDataIn,
+output [7:0] parallelDataOut
+ );
+
+ wire serialDataIn;
+ wire peripheralClkEdge;
+ wire parallelLoad;
+
+ // instantiate shift register
+ shiftregister shiftreg (clk, peripheralClkEdge, parallelLoad, parallelDataIn, serialDataIn, parallelDataOut, );
+
+ // instantiate input conditioner on button0
+ inputconditioner but0inputcond (clk, button0, , , parallelLoad);
+
+ // instantiate input conditioner on switch0
+ inputconditioner sw0inputcond (clk, switch0, serialDataIn, , );
+
+ // instantiate input conditioner on switch1
+ inputconditioner sw1inputcond (clk, switch1, , peripheralClkEdge, );
+
+endmodule
diff --git a/shiftregister.t.v b/shiftregister.t.v
index abe5b48..d9434af 100644
--- a/shiftregister.t.v
+++ b/shiftregister.t.v
@@ -1,29 +1,91 @@
//------------------------------------------------------------------------
// Shift Register test bench
//------------------------------------------------------------------------
+`timescale 1 ns / 1 ps
+`include "shiftregister.v"
module testshiftregister();
+ // instantiate test registers
reg clk;
reg peripheralClkEdge;
reg parallelLoad;
wire[7:0] parallelDataOut;
wire serialDataOut;
reg[7:0] parallelDataIn;
- reg serialDataIn;
-
+ reg serialDataIn;
+
// Instantiate with parameter width = 8
- shiftregister #(8) dut(.clk(clk),
+ shiftregister #(8) dut(.clk(clk),
.peripheralClkEdge(peripheralClkEdge),
- .parallelLoad(parallelLoad),
- .parallelDataIn(parallelDataIn),
+ .parallelLoad(parallelLoad),
+ .parallelDataIn(parallelDataIn),
.serialDataIn(serialDataIn),
- .parallelDataOut(parallelDataOut),
+ .parallelDataOut(parallelDataOut),
.serialDataOut(serialDataOut));
-
+
+ // instatiate test helper variables
+ reg testpassed = 1;
+ reg [3:0] index;
+ reg [7:0] expected;
+ reg s_expected;
+
+ // Generate clock (50MHz)
+ initial clk=0;
+ always #10 clk=!clk; // 50MHz Clock
+
initial begin
- // Your Test Code
+ $dumpfile("shiftregister.vcd");
+ $dumpvars(0, dut);
+
+ peripheralClkEdge = 0; #20
+ // Set all data to 0, also do a serial data in and see if it is lower priority
+ serialDataIn = 1; parallelDataIn = 8'd0; parallelLoad = 1; #20
+ peripheralClkEdge = 1; #10 peripheralClkEdge = 0; parallelLoad = 0; #100
+ expected = 8'd0;
+ if (parallelDataOut != expected) begin
+ $display("Test initial parallel set failed, expected pout:%b, got pout:%b", expected, parallelDataOut);
+ testpassed = 0;
end
-endmodule
+ // Shift in ones and make sure it's working
+ for (index = 0; index < 8; index = index + 1) begin
+ serialDataIn = 1; parallelDataIn = 8'd0; parallelLoad = 0; peripheralClkEdge = 1; #20
+ peripheralClkEdge = 0; #100
+ expected = ~(8'b11111110 << index);
+ if (parallelDataOut != expected) begin
+ $display("Test shift in 1s failed, expected pout:%b, got pout:%b", expected, parallelDataOut);
+ testpassed = 0;
+ end
+ s_expected = parallelDataOut[7];
+ if (serialDataOut != s_expected) begin
+ $display("Test shift in 1s failed, expected sout:%b, got sout:%b", s_expected, serialDataOut);
+ testpassed = 0;
+ end
+ end
+ // Shift in zeros and make sure it's working
+ for (index = 0; index < 8; index = index + 1) begin
+ serialDataIn = 0; parallelDataIn = 8'd0; parallelLoad = 0; peripheralClkEdge = 1; #20
+ peripheralClkEdge = 0; #100
+ expected = 8'b11111110 << index;
+ if (parallelDataOut != expected) begin
+ $display("Test shift in 0s failed, expected pout:%b, got pout:%b", expected, parallelDataOut);
+ testpassed = 0;
+ end
+ s_expected = parallelDataOut[7];
+ if (serialDataOut != s_expected) begin
+ $display("Test shift in 0s failed, expected sout:%b, got sout:%b", s_expected, serialDataOut);
+ testpassed = 0;
+ end
+ end
+
+ // Display if we've finished it or not
+ if (testpassed) begin
+ $display("Tests passed");
+ end
+
+ $finish;
+ end
+
+endmodule
diff --git a/shiftregister.v b/shiftregister.v
index b4ec057..8c17e1f 100644
--- a/shiftregister.v
+++ b/shiftregister.v
@@ -18,8 +18,17 @@ output [width-1:0] parallelDataOut, // Shift reg data contents
output serialDataOut // Positive edge synchronized
);
- reg [width-1:0] shiftregistermem;
+ reg [width-1:0] shiftRegisterMem;
+
+ assign parallelDataOut = shiftRegisterMem;
+ assign serialDataOut = shiftRegisterMem[width-1];
+
always @(posedge clk) begin
- // Your Code Here
+ if (parallelLoad) begin
+ shiftRegisterMem <= parallelDataIn;
+ end
+ else if (peripheralClkEdge) begin
+ shiftRegisterMem <= { shiftRegisterMem[width-2:0], serialDataIn };
+ end
end
endmodule
diff --git a/spimemory.t.v b/spimemory.t.v
new file mode 100644
index 0000000..391d0b3
--- /dev/null
+++ b/spimemory.t.v
@@ -0,0 +1,238 @@
+//-------------------------------------------------------------------------------------------
+// Testbench for complete SPI memory module
+//-------------------------------------------------------------------------------------------
+
+`timescale 1 ns / 1 ps
+`include "spimemory.v"
+
+module testSpiMemory();
+
+ wire clk; // FPGA clock
+ wire sclk_pin; // SPI clock
+ wire cs_pin; // SPI chip select
+ wire miso_pin; // SPI master in slave out
+ wire mosi_pin; // SPI master out slave in
+ wire [3:0] leds; // LEDs for debugging
+ wire [7:0] state;
+
+ reg begintest;
+ wire dutpassed;
+ wire endtest;
+
+ spiMemory dut(.clk(clk),
+ .sclk_pin(sclk_pin),
+ .cs_pin(cs_pin),
+ .miso_pin(miso_pin),
+ .mosi_pin(mosi_pin),
+ .leds(leds),
+ .state(state));
+
+ spiMemoryTester tester(.begintest(begintest),
+ .endtest(endtest),
+ .dutpassed(dutpassed),
+ .clk(clk),
+ .sclk_pin(sclk_pin),
+ .cs_pin(cs_pin),
+ .mosi_pin(mosi_pin),
+ .miso_pin(miso_pin));
+
+ initial begin
+ $dumpfile("spimemory.vcd");
+ $dumpvars(0, dut);
+ begintest=0;
+ #10;
+ begintest=1;
+ #10000;
+
+ end
+
+ // Display test results ('dutpassed' signal) once 'endtest' goes high
+ always @(posedge endtest) begin
+ $display("DUT passed?: %b", dutpassed);
+ end
+
+endmodule
+
+module spiMemoryTester (
+ input begintest,
+ output reg endtest,
+ output reg dutpassed,
+
+ output reg clk,
+ output reg sclk_pin,
+ output reg cs_pin,
+ output reg mosi_pin,
+ input miso_pin
+ );
+
+ // Global registers
+ reg [6:0] address;
+ reg [7:0] rx_data;
+ reg [7:0] tx_data;
+ reg [7:0] expected;
+
+ // Define clock
+ initial clk = 0;
+ always #10 clk=!clk;
+
+ // Run test sequence
+ always @(posedge begintest) begin
+ cs_pin = 1;
+ sclk_pin = 1;
+ mosi_pin = 1;#10000
+
+ // Basic write test
+ address = 7'd10;
+ tx_data = 8'd47;
+ write_spi(address, tx_data); #10000;
+ read_spi(address);
+
+ if (rx_data != tx_data | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI writeback failed, wrote %d to %b, got %d", tx_data, address, rx_data);
+ end
+
+ #100000;
+
+ //Write all zeros, get all zeros, write all ones get all ones
+ address = 7'd56;
+ tx_data = 8'b00000000; #10000
+ write_spi(address, tx_data); #10000;
+ read_spi(address);
+ if (rx_data != tx_data | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI write zeros failed, wrote %d to %b, got %d", tx_data, address, rx_data);
+ end
+
+ #10000;
+
+ //Write all zeros, get all zeros, write all ones get all ones
+ address = 7'd56;
+ tx_data = 8'b11111111;
+ write_spi(address, tx_data); #10000;
+ read_spi(address);
+ if (rx_data != tx_data | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI write ones failed, wrote %d to %b, got %d", tx_data, address, rx_data);
+ end
+
+ #10000;
+
+ //Write various different addresses, then read them back
+ address = 7'd0; tx_data = 8'd0;
+ write_spi(address, tx_data); #10000
+ address = 7'd1; tx_data = 8'd1;
+ write_spi(address, tx_data); #10000
+ address = 7'd2; tx_data = 8'd2;
+ write_spi(address, tx_data); #10000
+ address = 7'd3; tx_data = 8'd4;
+ write_spi(address, tx_data); #10000
+ address = 7'd4; tx_data = 8'd8;
+ write_spi(address, tx_data); #10000
+ address = 7'd5; tx_data = 8'd16;
+ write_spi(address, tx_data); #10000
+
+ address = 7'd0; tx_data = 8'd0;
+ read_spi(7'd0);
+ if (rx_data != 8'd0 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd0, 7'd0, rx_data);
+ end #10000;
+
+ address = 7'd1; tx_data = 8'd1;
+ read_spi(7'd1);
+ if (rx_data != 8'd1 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd1, 7'd1, rx_data);
+ end #10000;
+
+ address = 7'd2; tx_data = 8'd2;
+ read_spi(7'd2);
+ if (rx_data != 8'd2 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd2, 7'd2, rx_data);
+ end #10000;
+
+ address = 7'd3; tx_data = 8'd4;
+ read_spi(7'd3);
+ if (rx_data != 8'd4 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd4, 7'd3, rx_data);
+ end #10000;
+
+ address = 7'd4; tx_data = 8'd8;
+ read_spi(7'd4);
+ if (rx_data != 8'd8 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd8, 7'd4, rx_data);
+ end #10000;
+
+ address = 7'd5; tx_data = 8'd16;
+ read_spi(7'd5);
+ if (rx_data != 8'd16 | rx_data === 8'bx) begin
+ dutpassed = 0;
+ $display("Test SPI multiple write failed, wrote %d to %b, got %d", 8'd16, 7'd5, rx_data);
+ end #10000;
+
+ $finish;
+ end
+
+
+ // Define helper tasks to do SPI transactions
+ task read_spi;
+ input [6:0] address;
+ integer idx;
+ begin
+ // Begin transaction and clock in address
+ cs_pin = 0; #1000;
+ for (idx = 0; idx < 7; idx = idx+1) begin
+ sclk_pin = 0;
+ mosi_pin = address[6 - idx];#1000; // Present data on negative edge
+ sclk_pin = 1;#1000; // Return clock high
+ end
+ // Read-Write bit
+ sclk_pin = 0;
+ mosi_pin = 1;#1000 // Read
+ sclk_pin = 1;#1000
+ // Read Back Data
+ for (idx = 0; idx < 8; idx = idx + 1) begin
+ sclk_pin = 0;#1000 // Negative edge to prompt data
+ sclk_pin = 1;
+ rx_data[7-idx] = miso_pin;#1000; // Read at positive edge
+ end
+ #1000;
+ // Release CS
+ cs_pin = 1;
+
+ end
+ endtask
+
+ task write_spi;
+ input [6:0] address;
+ input [7:0] tx_data;
+ integer idx;
+ begin
+ // Begin transaction and clock in address
+ cs_pin = 0; #1000;
+ for (idx = 0; idx < 7; idx = idx+1) begin
+ sclk_pin = 0;
+ mosi_pin = address[6 - idx];#1000; // Present data on negative edge
+ sclk_pin = 1;#1000; // Return clock high
+ end
+ // Read-Write bit
+ sclk_pin = 0;
+ mosi_pin = 0;#1000 // Write
+ sclk_pin = 1;#1000
+ //Clock in data
+ for (idx = 0; idx < 8; idx = idx+1) begin
+ sclk_pin = 0;
+ mosi_pin = tx_data[7 - idx];#1000; // Present data on negative edge
+ sclk_pin = 1;#1000; // Return clock high
+ end
+ #1000;
+ //Release CS
+ cs_pin=1;
+ end
+ endtask
+
+endmodule
diff --git a/spimemory.v b/spimemory.v
index c6ed4f7..723ac3f 100644
--- a/spimemory.v
+++ b/spimemory.v
@@ -2,6 +2,13 @@
// SPI Memory
//------------------------------------------------------------------------
+`include "inputconditioner.v"
+`include "datamemory.v"
+`include "shiftregister.v"
+`include "fsm.v"
+`include "buffer.v"
+`include "dff.v"
+
module spiMemory
(
input clk, // FPGA clock
@@ -9,9 +16,103 @@ module spiMemory
input cs_pin, // SPI chip select
output miso_pin, // SPI master in slave out
input mosi_pin, // SPI master out slave in
- output [3:0] leds // LEDs for debugging
-)
+ output [3:0] leds, // LEDs for debugging
+ output [7:0] state
+);
+
+ wire serial_in;
+ wire sclk_posedge;
+ wire sclk_negedge;
+ wire cs;
+
+ wire miso_bufe;
+ wire dm_we;
+ wire addr_we;
+ wire sr_we;
+
+ wire [7:0] shift_reg_out_P;
+ wire [7:0] data_mem_out;
+ wire serial_out;
+
+ wire [7:0] address_latch_out;
+ wire [6:0] address;
+
+ wire miso;
+
+ assign address = address_latch_out[6:0];
+
+ inputconditioner mosi_ic(
+ .clk(clk),
+ .noisysignal(mosi_pin),
+ .conditioned(serial_in),
+ .positiveedge(),
+ .negativeedge()
+ );
+
+ inputconditioner sclk_ic(
+ .clk(clk),
+ .noisysignal(sclk_pin),
+ .conditioned(),
+ .positiveedge(sclk_posedge),
+ .negativeedge(sclk_negedge)
+ );
+
+ inputconditioner cs_ic(
+ .clk(clk),
+ .noisysignal(cs_pin),
+ .conditioned(cs),
+ .positiveedge(),
+ .negativeedge()
+ );
+
+ FSM fsm(
+ .clk(clk),
+ .sclk(sclk_posedge),
+ .cs_pin(cs),
+ .shiftReg0(mosi_pin),
+ .addr_WE(addr_we),
+ .miso_BUFE(miso_bufe),
+ .DM_WE(dm_we),
+ .SR_WE(sr_we),
+ .state(state)
+ );
+
+ shiftregister shift_reg(
+ .clk(clk),
+ .peripheralClkEdge(sclk_posedge),
+ .parallelLoad(sr_we),
+ .parallelDataIn(data_mem_out),
+ .serialDataIn(serial_in),
+ .parallelDataOut(shift_reg_out_P),
+ .serialDataOut(serial_out)
+ );
+
+ datamemory data_mem(
+ .clk(clk),
+ .dataOut(data_mem_out),
+ .address(address),
+ .writeEnable(dm_we),
+ .dataIn(shift_reg_out_P)
+ );
+
+ dff #(.width(8)) address_latch(
+ .clk(clk),
+ .clockEdge(addr_we),
+ .D(shift_reg_out_P),
+ .Q(address_latch_out)
+ );
+
+ dff serial_out_dff(
+ .clk(clk),
+ .clockEdge(sclk_negedge),
+ .D(serial_out),
+ .Q(miso)
+ );
+ buffer miso_buffer(
+ .in(miso),
+ .en(miso_bufe),
+ .out(miso_pin)
+ );
endmodule
-
diff --git a/work_plan.txt b/work_plan.txt
new file mode 100644
index 0000000..df6a951
--- /dev/null
+++ b/work_plan.txt
@@ -0,0 +1,17 @@
+# Work Plan
+Alex Hoppe and Taylor Sheneman
+
+1. Read about the lab and figure out how to structure our approach (1.5 hr) Sunday, 10/22
+2. Make work plan (.5 hr) Sunday, 10/22
+3. Make input conditioner circuitry (0.5 hr) Sunday, 10/22
+4. Make input conditioner tests (1 hr) Sunday, 10/22
+5. Make shift register circuitry (1hr) Monday, 10/23
+6. Make shift register tests (1hr) Monday, 10/23
+7. Midpoint Checkin synthesis/FPGA testing (1.5 hr) Wednesday, 10/25
+8. SPI memory drawing/layout (0.5 hr) Wednesday, 10/25
+9. Make data memory and test (1.5 hr) Saturday, 10/28
+10. Make FSM and test (1.5 hr) Saturday, 10/28
+11. Make supporting circuitry (1hr) Sunday, 10/29
+12. Implement full SPI memory design (1.5 hr) Sunday, 10/29
+13. Tests. (3hr) Monday, 10/30
+14. Compile report (1.5 hr) Tuesday/Wednesday, 10/31 - 11/1