Updated the SPI test to include a test of the inverted clock mode. Also fixed a number of problems with the SPI implementation and added a status register for determining if data is still being sent.
diff --git a/README.md b/README.md
index e6bae20..defe829 100644
--- a/README.md
+++ b/README.md
@@ -63,10 +63,9 @@
 ### verify-coreArch-gl: Not implemented
 
 # Need to do
-- Write SPI test
 - Fix timing violations
 - Make final version of art
-- Add buffer to interrupt signals input
+- Add buffer to interrupt signals input and data registers
 
 # Could do
 - Misaligned architecture instructions 
diff --git a/verilog/dv/peripheralsSPI/peripheralsSPI.c b/verilog/dv/peripheralsSPI/peripheralsSPI.c
index cf20f1f..a7d38cc 100644
--- a/verilog/dv/peripheralsSPI/peripheralsSPI.c
+++ b/verilog/dv/peripheralsSPI/peripheralsSPI.c
@@ -117,7 +117,7 @@
 	reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT;
 	reg_mprj_io_22 = GPIO_MODE_USER_STD_OUTPUT;
 	reg_mprj_io_23 = GPIO_MODE_USER_STD_OUTPUT;
-	reg_mprj_io_24 = GPIO_MODE_USER_STD_OUTPUT;
+	reg_mprj_io_24 = GPIO_MODE_USER_STD_INPUT_NOPULL;
 	reg_mprj_io_25 = GPIO_MODE_USER_STD_OUTPUT;
 
 	/* Apply configuration */
@@ -155,7 +155,7 @@
 	if (wbRead (SPI0_STATUS_REGISTER) != 0) testPass = false;
 	nextTest (testPass);
 
-	// Check data data was received
+	// Check that data was received
 	if (wbRead (SPI0_DATA) != 0xC5) testPass = false;
 	nextTest (testPass);
 
@@ -165,6 +165,33 @@
 	// Check data received back is correct
 	// This should be the first test byte
 	if (wbRead (SPI0_DATA) != 0x1F) testPass = false;
+	nextTest (testPass);
+
+	// Change to active low clock mode
+	device0Config = (0b1 << 8) | (0b11 << 5) | (0b11 << 3) | 0x04;
+	wbWrite (SPI0_CONFIGURATION_REGISTER, device0Config);
+	if (wbRead (SPI0_CONFIGURATION_REGISTER) != device0Config) testPass = false;
+	nextTest (testPass);
+
+	// Write fist test byte
+	wbWrite (SPI0_DATA, 0x1F);
+
+	// Check data data was received
+	if (wbRead (SPI0_DATA) != 0xA3) testPass = false;
+	nextTest (testPass);
+
+	// Write second test byte
+	wbWrite (SPI0_DATA, 0x83);
+
+	// Check data received back is correct
+	// This should be the first test byte
+	if (wbRead (SPI0_DATA) != 0x1F) testPass = false;
+	nextTest (testPass);
+
+	device0Config = (0b1 << 8) | (0b11 << 5) | 0x04;
+	wbWrite (SPI0_CONFIGURATION_REGISTER, device0Config);
+	if (wbRead (SPI0_CONFIGURATION_REGISTER) != device0Config) testPass = false;
+	nextTest (testPass);
 
 	// Write third test byte for timing test
 	wbWrite (SPI0_DATA, 0x9B);
diff --git a/verilog/dv/peripheralsSPI/peripheralsSPI_tb.v b/verilog/dv/peripheralsSPI/peripheralsSPI_tb.v
index 7ab770f..7420e91 100644
--- a/verilog/dv/peripheralsSPI/peripheralsSPI_tb.v
+++ b/verilog/dv/peripheralsSPI/peripheralsSPI_tb.v
@@ -54,14 +54,18 @@
 	assign mprj_io[21:17] = 5'b0;
 	assign mprj_io[37:26] = 12'b0;
 
-	always @(posedge sck) begin
-		if (!chipSelect) shiftValue <= { shiftValue[7:1], mosi };
+	reg clockMode;
+	wire spiClock = clockMode ^ sck;
+
+	always @(posedge spiClock) begin
+		if (!chipSelect) shiftValue <= { shiftValue[6:0], mosi };
 	end
 
 	initial begin
 		clock = 0;
 		timingValid = 1'b1;
 		shiftValue = 8'hC5;
+		clockMode = 1'b0;
 	end
 
 	realtime timerStart;
@@ -78,7 +82,7 @@
 `endif
 
 		// Repeat cycles of 1000 clock edges as needed to complete testbench
-		repeat (200) begin
+		repeat (500) begin
 			repeat (1000) @(posedge clock);
 			//$display("+1000 cycles");
 		end
@@ -97,7 +101,7 @@
 		// Wait for clock signal
 		@(posedge chipSelect);
 		@(posedge sck);
-		@(posedge sck);
+		@(negedge sck);
 
 		// Check device 0 config
 		@(posedge nextTestOutput);
@@ -108,25 +112,48 @@
 		// Check device isn't busy
 		@(posedge nextTestOutput);
 
-		// Check data data was received
+		// Check that data was received
 		@(posedge nextTestOutput);
 
 		// Check that CS is asserted 
-		wait(chipSelect == 1'b0);
+		@(negedge chipSelect);
 
 		// Check that the second byte was received correctly
 		wait(shiftValue == 8'hA3);
 
 		// Check that CS is cleared
-		wait(chipSelect == 1'b1);
+		@(posedge chipSelect);
 
 		// Check data received back in
 		@(posedge nextTestOutput);
 
-		// Check that the third byte was received correctly
-		wait(shiftValue == 8'h9B);
+		clockMode = 1'b1;
+
+		// Check device 0 config
+		@(posedge nextTestOutput);
+
+		// Check that the first byte was received correctly
+		wait(shiftValue == 8'h1F);
+
+		// Check that data was received
+		@(posedge nextTestOutput);
+
+		// Check that the second byte was received correctly
+		wait(shiftValue == 8'h83);
+
+		// Check data received back in
+		@(posedge nextTestOutput);
+
+		clockMode = 1'b0;
+
+		// Check device 0 config
+		@(posedge nextTestOutput);
 
 		// Check clock period is correct
+		
+		// Check that CS is asserted 
+		wait(chipSelect == 1'b0);
+
 		// Wait for signal start
 		@(negedge sck);
 		timerStart = $realtime;
@@ -145,6 +172,8 @@
 		if (timerLength < 390 || timerLength > 410) timingValid = 1'b0;
 		else $display("Invalid time, should be between 390 and 410");
 		
+		// Check that the third byte was received correctly
+		wait(shiftValue == 8'h9B);
 
 		// Wait for management core to output the final output test result
 		@(posedge nextTestOutput);
diff --git a/verilog/rtl/Peripherals/SPI/SPIDevice.v b/verilog/rtl/Peripherals/SPI/SPIDevice.v
index 60d078a..69084a0 100644
--- a/verilog/rtl/Peripherals/SPI/SPIDevice.v
+++ b/verilog/rtl/Peripherals/SPI/SPIDevice.v
@@ -12,13 +12,13 @@
 		output wire peripheralBus_busy,
 		input wire[15:0] peripheralBus_address,
 		input wire[3:0] peripheralBus_byteSelect,
-		output wire[31:0] peripheralBus_dataRead,
+		output reg[31:0] peripheralBus_dataRead,
 		input wire[31:0] peripheralBus_dataWrite,
 		output wire requestOutput,
 
 		// SPI interface
 		output wire spi_en,
-		output wire spi_clk,
+		output reg spi_clk,
 		output wire spi_mosi,
 		input  wire spi_miso,
 		output wire spi_cs
@@ -73,121 +73,162 @@
 	wire spiClockPolarity = spiMode[1];
 	wire spiSampleMode = spiMode[0];
 
-	// Input and Output register
-	wire[31:0] dataRegisterOutputData;
-	wire dataRegisterOutputRequest;
-	wire[7:0] readData;
-	wire[7:0] writeData;	
-	wire writeData_en;
-	wire dataRegisterBusBusy_nc;
-	wire dataRegisterReadDataEnable_nc;
-	DataRegister #(.WIDTH(8), .ADDRESS(12'h004)) dataRegister(
+	// Status register
+	wire deviceBusy = state != STATE_IDLE;
+	wire[31:0] statusRegisterOutputData;
+	wire statusRegisterOutputRequest;
+	wire statusRegisterWriteData_nc;
+	wire statusRegisterWriteDataEnable_nc;
+	wire statusRegisterReadDataEnable_nc;
+	wire statusRegisterBusBusy_nc;
+	DataRegister #(.WIDTH(1), .ADDRESS(12'h004)) statusRegister(
 		.clk(clk),
 		.rst(rst),
 		.enable(deviceEnable),
 		.peripheralBus_we(peripheralBus_we),
 		.peripheralBus_oe(peripheralBus_oe),
-		.peripheralBus_busy(dataRegisterBusBusy_nc),
+		.peripheralBus_busy(statusRegisterBusBusy_nc),
+		.peripheralBus_address(localAddress),
+		.peripheralBus_byteSelect(peripheralBus_byteSelect),
+		.peripheralBus_dataWrite(peripheralBus_dataWrite),
+		.peripheralBus_dataRead(statusRegisterOutputData),
+		.requestOutput(statusRegisterOutputRequest),
+		.writeData(statusRegisterWriteData_nc),
+		.writeData_en(statusRegisterWriteDataEnable_nc),
+		.writeData_busy(1'b0),
+		.readData(deviceBusy),
+		.readData_en(statusRegisterReadDataEnable_nc),
+		.readData_busy(1'b0));
+
+	// Input and Output register
+	wire[31:0] dataRegisterOutputData;
+	wire dataRegisterOutputRequest;
+	wire[7:0] dataRegisterReadData;
+	wire[7:0] dataRegisterWriteData;	
+	wire dataRegisterWriteDataEnable;
+	wire dataRegisterBusBusy;
+	wire dataRegisterReadDataEnable_nc;
+	DataRegister #(.WIDTH(8), .ADDRESS(12'h008)) dataRegister(
+		.clk(clk),
+		.rst(rst),
+		.enable(deviceEnable),
+		.peripheralBus_we(peripheralBus_we),
+		.peripheralBus_oe(peripheralBus_oe),
+		.peripheralBus_busy(dataRegisterBusBusy),
 		.peripheralBus_address(localAddress),
 		.peripheralBus_byteSelect(peripheralBus_byteSelect),
 		.peripheralBus_dataWrite(peripheralBus_dataWrite),
 		.peripheralBus_dataRead(dataRegisterOutputData),
 		.requestOutput(dataRegisterOutputRequest),
-		.writeData(writeData),
-		.writeData_en(writeData_en),
-		.writeData_busy(1'b0),
-		.readData(readData),
+		.writeData(dataRegisterWriteData),
+		.writeData_en(dataRegisterWriteDataEnable),
+		.writeData_busy(deviceBusy),
+		.readData(dataRegisterReadData),
 		.readData_en(dataRegisterReadDataEnable_nc),
-		.readData_busy(1'b0));
+		.readData_busy(deviceBusy));
 
 	// State control
 	reg[1:0] state = STATE_IDLE;
-	wire busy = state != STATE_IDLE;
 	
 	reg[2:0] bitCounter = 3'b0;
 	wire[2:0] nextBitCounter = bitCounter + 1;
 
 	reg[CLOCK_WIDTH-1:0] clockCounter = {CLOCK_WIDTH{1'b0}};
-	wire nextClockCounter = clockCounter + 1;
-	wire[CLOCK_WIDTH-1:0] clockScaleHalfMask = {CLOCK_BITS{1'b1}} << clockScale;
-	wire[CLOCK_WIDTH-1:0] clockScaleMask 	 = { clockScaleMask[CLOCK_WIDTH-2:0], 1'b0 };
-	wire spiHalfClock = clockCounter == (clockScaleHalfMask - 1);//|(clockCounter & clockScaleHalfMask);
-	wire spiClock 	  = clockCounter == (clockScaleMask - 1);
+	wire[CLOCK_WIDTH-1:0] nextClockCounter = clockCounter + 1;
+	wire[CLOCK_WIDTH-1:0] clockScaleCompare = { {(CLOCK_WIDTH-1){1'b0}}, 1'b1 } << clockScale;
+	wire[CLOCK_WIDTH-1:0] clockScaleHalfCompare = { 1'b0, clockScaleCompare[CLOCK_WIDTH-1:1] };
+	wire halfClockCounterMatch = nextClockCounter == clockScaleHalfCompare;
+	wire clockCounterMatch     = nextClockCounter == clockScaleCompare;
 
 	reg spiClockRise = 1'b0;
 	reg spiClockFall = 1'b0;
+	reg spiClock;
 
 	wire shiftInEnable  = spiSampleMode ? spiClockFall : spiClockRise;
 	wire shiftOutEnable = spiSampleMode ? spiClockRise : spiClockFall;
-
-	reg loadEnable;
+	
+	wire serialOut;
 	ShiftRegister #(.WIDTH(8)) register (
 		.clk(clk),
 		.rst(rst),
-		.loadEnable(loadEnable),
+		.loadEnable(dataRegisterWriteDataEnable),
 		.shiftInEnable(shiftInEnable),
 		.shiftOutEnable(shiftOutEnable),
 		.msbFirst(msbFirst),
-		.parallelIn(writeData),
-		.parallelOut(readData),
+		.parallelIn(dataRegisterWriteData),
+		.parallelOut(dataRegisterReadData),
 		.serialIn(spi_miso),
-		.serialOut(spi_mosi));
+		.serialOut(serialOut));
 
 	always @(posedge clk) begin
 		if (rst) begin
 			state <= STATE_IDLE;
 			bitCounter <= 3'b0;
 			clockCounter <= {CLOCK_WIDTH{1'b0}};
-			loadEnable <= 1'b0;
 			spiClockRise <= 1'b0;
 			spiClockFall <= 1'b0;
+			spiClock <= 1'b0;
 		end else begin
 			case (state)
 				STATE_IDLE: begin
 					bitCounter <= 3'b0;
 					clockCounter <= {CLOCK_WIDTH{1'b0}};
-					loadEnable <= 1'b0;
+					spiClockRise <= 1'b0;
+					spiClockFall <= 1'b0;
+					spiClock <= 1'b0;
 
-					if (writeData_en && peripheralBus_byteSelect[0]) begin 
+					if (dataRegisterWriteDataEnable && peripheralBus_byteSelect[0]) begin 
 						state <= STATE_SETUP;
-						loadEnable <= 1'b1;
 					end
 				end
 
 				STATE_SETUP: begin
-					loadEnable <= 1'b0;
+					clockCounter <= nextClockCounter;
 
-					if (spiHalfClock) begin
-						clockCounter <= {CLOCK_WIDTH{1'b0}};
+					if (halfClockCounterMatch) begin
 						bitCounter <= 1'b0;
+						spiClock <= 1'b1;
 						state <= STATE_SHIFT;
-					end else begin
-						clockCounter <= nextClockCounter;
-					end
+
+						if (spiClockPolarity) begin
+							spiClockRise <= 1'b0;
+							spiClockFall <= 1'b1;
+						end else begin
+							spiClockRise <= 1'b1;
+							spiClockFall <= 1'b0;
+						end	
+					end					
 				end
 
 				STATE_SHIFT: begin
-					if (spiClock) begin
+					if (clockCounterMatch) begin
+						clockCounter <= {CLOCK_WIDTH{1'b0}};
+						spiClock <= 1'b0;
+
 						if (spiClockPolarity) begin
-							spiClockRise <= 1'b0;
-							spiClockFall <= 1'b1;
-						end else begin
 							spiClockRise <= 1'b1;
 							spiClockFall <= 1'b0;
+						end else begin
+							spiClockRise <= 1'b0;
+							spiClockFall <= 1'b1;
 						end
 
-						clockCounter <= {CLOCK_WIDTH{1'b0}};
-						if (bitCounter == 3'h7) state <= STATE_END;
-						else bitCounter <= nextBitCounter;
-					end else if (spiHalfClock) begin
+						if (bitCounter == 3'h7) begin
+							state <= STATE_END;
+						end	else begin
+							bitCounter <= nextBitCounter;
+						end
+					end else if (halfClockCounterMatch) begin
 						if (spiClockPolarity) begin
-							spiClockRise <= 1'b1;
-							spiClockFall <= 1'b0;
-						end else begin
 							spiClockRise <= 1'b0;
 							spiClockFall <= 1'b1;
-						end
-						
+						end else begin
+							spiClockRise <= 1'b1;
+							spiClockFall <= 1'b0;
+						end	
+
+						spiClock <= 1'b1;
+						clockCounter <= nextClockCounter;
 					end else begin
 						spiClockRise <= 1'b0;
 						spiClockFall <= 1'b0;
@@ -198,8 +239,9 @@
 				STATE_END: begin
 					spiClockRise <= 1'b0;
 					spiClockFall <= 1'b0;
+					spiClock <= 1'b0;
 					
-					if (spiClock) state <= STATE_IDLE;
+					if (clockCounterMatch) state <= STATE_IDLE;
 					else clockCounter <= nextClockCounter;
 				end
 
@@ -207,21 +249,34 @@
 					state <= STATE_IDLE;
 					bitCounter <= 3'b0;
 					clockCounter <= {CLOCK_WIDTH{1'b0}};
-					loadEnable <= 1'b0;
 					spiClockRise <= 1'b0;
 					spiClockFall <= 1'b0;
+					spiClock <= 1'b0;
 				end
 			endcase
 		end
 	end
 
-	assign requestOutput = configurationRegisterOutputRequest || dataRegisterOutputRequest;
-	assign peripheralBus_dataRead = configurationRegisterOutputRequest ? configurationRegisterOutputData :
-								    dataRegisterOutputRequest 		   ? dataRegisterOutputData :
-													   					 ~32'b0;																			
-	assign peripheralBus_busy = busy;
+	// Buffer the spi clock by one cycle so that it lines up with when data is sampled
+	always @(posedge clk) begin
+		if (rst) spi_clk <= 1'b0;
+		else spi_clk <= spiClockPolarity ? !spiClock : spiClock;
+	end
 
-	assign spi_clk = spiClockPolarity ? !(spiClock && busy) : spiClock && busy;
-	assign spi_cs = useCS ? (activeHighCS ? busy : !busy) : 1'b0;
+	assign requestOutput = configurationRegisterOutputRequest || statusRegisterOutputRequest || dataRegisterOutputRequest;
+
+	always @(*) begin
+		case (1'b1)
+			configurationRegisterOutputRequest: peripheralBus_dataRead <= configurationRegisterOutputData;
+			statusRegisterOutputRequest: peripheralBus_dataRead <= statusRegisterOutputData;
+			dataRegisterOutputRequest: peripheralBus_dataRead <= dataRegisterOutputData;
+			default: peripheralBus_dataRead <=  ~32'b0;
+		endcase
+	end
+
+	assign peripheralBus_busy = dataRegisterBusBusy;
+
+	assign spi_mosi = serialOut & deviceBusy;
+	assign spi_cs = useCS ? (activeHighCS ? deviceBusy : !deviceBusy) : 1'b0;
 
 endmodule
\ No newline at end of file