Merge pull request #922 from JacobPease/main

SPI Clock Polarity and Phase fixes
This commit is contained in:
Rose Thompson 2024-08-20 14:54:53 -07:00 committed by GitHub
commit 4b7a498ada
7 changed files with 125 additions and 94 deletions

View File

@ -136,8 +136,8 @@ set_property -dict {PACKAGE_PIN H2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCWP}] set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33 PULLUP true} [get_ports {SDCWP}]
set_input_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCCS}] set_output_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCCS}]
set_input_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCCS}] set_output_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCCS}]
set_input_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCIn}] set_input_delay -clock [get_clocks SPISDCClock] -min -add_delay 2.500 [get_ports {SDCIn}]
set_input_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCIn}] set_input_delay -clock [get_clocks SPISDCClock] -max -add_delay 10.000 [get_ports {SDCIn}]
@ -158,54 +158,54 @@ set_max_delay -datapath_only -from [get_pins xlnx_ddr3_c0/u_xlnx_ddr3_mig/u_memc
# ddr3 # ddr3
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[1] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[1]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[2] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[2]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[3] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[3]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[4] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[4]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[5] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[5]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[6] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[6]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[7] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[7]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[8] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[8]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[9] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[9]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[10] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[10]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[11] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[11]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[12] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[12]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[13] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[13]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[14] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[14]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[15] set_property IOSTANDARD SSTL135 [get_ports ddr3_dq[15]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[1] set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[1]]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[0] set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[0]]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[0] set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[0]]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[1] set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[1]]
set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[1] set_property IOSTANDARD DIFF [get_ports ddr3_dqs_n[1]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[13] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[13]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[12] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[12]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[11] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[11]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[10] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[10]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[9] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[9]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[8] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[8]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[7] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[7]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[6] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[6]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[5] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[5]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[4] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[4]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[3] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[3]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[2] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[2]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[1] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[1]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_addr[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[2] set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[2]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[1] set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[1]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_ba[0]]
set_property IOSTANDARD DIFF [get_ports ddr3_ck_p[0] set_property IOSTANDARD DIFF [get_ports ddr3_ck_p[0]]
set_property IOSTANDARD DIFF [get_ports ddr3_ck_n[0] set_property IOSTANDARD DIFF [get_ports ddr3_ck_n[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_ras_n set_property IOSTANDARD SSTL135 [get_ports ddr3_ras_n]
set_property IOSTANDARD SSTL135 [get_ports ddr3_cas_n set_property IOSTANDARD SSTL135 [get_ports ddr3_cas_n]
set_property IOSTANDARD SSTL135 [get_ports ddr3_we_n set_property IOSTANDARD SSTL135 [get_ports ddr3_we_n]
set_property IOSTANDARD SSTL135 [get_ports ddr3_reset_n set_property IOSTANDARD SSTL135 [get_ports ddr3_reset_n]
set_property IOSTANDARD SSTL135 [get_ports ddr3_cke[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_cke[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_odt[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_odt[0]]
set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n[0] set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n[0]]
set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]] set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]]

View File

@ -91,29 +91,29 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count) {
while((r = spi_dummy()) != SD_DATA_TOKEN); while((r = spi_dummy()) != SD_DATA_TOKEN);
crc = 0; crc = 0;
n = 512; /* n = 512; */
do {
uint8_t x = spi_dummy();
*p++ = x;
crc = crc16(crc, x);
} while (--n > 0);
/* n = 512/8; */
/* do { */ /* do { */
/* // Send 8 dummy bytes (fifo should be empty) */ /* uint8_t x = spi_dummy(); */
/* for (j = 0; j < 8; j++) { */
/* spi_sendbyte(0xff); */
/* } */
/* // Reset counter. Process bytes AS THEY COME IN. */
/* for (j = 0; j < 8; j++) { */
/* while (!(read_reg(SPI_IP) & 2)) {} */
/* uint8_t x = spi_readbyte(); */
/* *p++ = x; */ /* *p++ = x; */
/* crc = crc16(crc, x); */ /* crc = crc16(crc, x); */
/* } */
/* } while (--n > 0); */ /* } while (--n > 0); */
n = 512/8;
do {
// Send 8 dummy bytes (fifo should be empty)
for (j = 0; j < 8; j++) {
spi_sendbyte(0xff);
}
// Reset counter. Process bytes AS THEY COME IN.
for (j = 0; j < 8; j++) {
while (!(read_reg(SPI_IP) & 2)) {}
uint8_t x = spi_readbyte();
*p++ = x;
crc = crc16(crc, x);
}
} while(--n > 0);
// Read CRC16 and check // Read CRC16 and check
crc_exp = ((uint16_t)spi_dummy() << 8); crc_exp = ((uint16_t)spi_dummy() << 8);
crc_exp |= spi_dummy(); crc_exp |= spi_dummy();

View File

@ -148,8 +148,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
// APB access // APB access
assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase
// JACOB: This shouldn't behave this way assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | TransmitInactive; // Tie PREADY to transmission for hardware interlock
assign PREADY = TransmitInactive; // Tie PREADY to transmission for hardware interlock
// Account for subword read/write circuitry // Account for subword read/write circuitry
// -- Note SPI registers are 32 bits no matter what; access them with LW SW. // -- Note SPI registers are 32 bits no matter what; access them with LW SW.
@ -188,11 +187,15 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]}; SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]};
SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]}; SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]};
SPI_FMT: Format <= {Din[19:16], Din[2]}; SPI_FMT: Format <= {Din[19:16], Din[2]};
SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0];
SPI_TXMARK: TransmitWatermark <= Din[2:0]; SPI_TXMARK: TransmitWatermark <= Din[2:0];
SPI_RXMARK: ReceiveWatermark <= Din[2:0]; SPI_RXMARK: ReceiveWatermark <= Din[2:0];
SPI_IE: InterruptEnable <= Din[1:0]; SPI_IE: InterruptEnable <= Din[1:0];
endcase endcase
if (Memwrite)
case(Entry)
SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0];
endcase
/* verilator lint_off CASEINCOMPLETE */ /* verilator lint_off CASEINCOMPLETE */
// According to FU540 spec: Once interrupt is pending, it will remain set until number // According to FU540 spec: Once interrupt is pending, it will remain set until number
@ -268,11 +271,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
always_ff @(posedge PCLK) always_ff @(posedge PCLK)
if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0; if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0;
else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive); else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull);
always_ff @(posedge PCLK) always_ff @(posedge PCLK)
if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0; if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0;
else ReceiveFIFOReadIncrement <= ((Entry == 8'h4C) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); else ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement);
// Tx/Rx FIFOs // Tx/Rx FIFOs
spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0], spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0],
@ -301,6 +304,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
if (~PRESETn) begin if (~PRESETn) begin
state <= CS_INACTIVE; state <= CS_INACTIVE;
FrameCount <= 4'b0; FrameCount <= 4'b0;
SPICLK <= SckMode[1];
end else if (SCLKenable) begin end else if (SCLKenable) begin
/* verilator lint_off CASEINCOMPLETE */ /* verilator lint_off CASEINCOMPLETE */
case (state) case (state)
@ -311,21 +315,32 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
InterCSCount <= 9'b10; InterCSCount <= 9'b10;
InterXFRCount <= 9'b1; InterXFRCount <= 9'b1;
if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty) & ((|(Delay0[7:0])) | ~SckMode[0])) state <= DELAY_0; if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty) & ((|(Delay0[7:0])) | ~SckMode[0])) state <= DELAY_0;
else if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty)) state <= ACTIVE_0; else if ((~TransmitFIFOReadEmpty | ~TransmitShiftEmpty)) begin
state <= ACTIVE_0;
SPICLK <= ~SckMode[1];
end else SPICLK <= SckMode[1];
end end
DELAY_0: begin DELAY_0: begin
CS_SCKCount <= CS_SCKCount + 9'b1; CS_SCKCount <= CS_SCKCount + 9'b1;
if (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1)) state <= ACTIVE_0; if (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1)) begin
state <= ACTIVE_0;
SPICLK <= ~SckMode[1];
end
end end
ACTIVE_0: begin ACTIVE_0: begin
FrameCount <= FrameCount + 4'b1; FrameCount <= FrameCount + 4'b1;
SPICLK <= SckMode[1];
state <= ACTIVE_1; state <= ACTIVE_1;
end end
ACTIVE_1: begin ACTIVE_1: begin
InterXFRCount <= 9'b1; InterXFRCount <= 9'b1;
if (FrameCount < Format[4:1]) state <= ACTIVE_0; if (FrameCount < Format[4:1]) begin
state <= ACTIVE_0;
SPICLK <= ~SckMode[1];
end
else if ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty)) begin else if ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty)) begin
state <= ACTIVE_0; state <= ACTIVE_0;
SPICLK <= ~SckMode[1];
CS_SCKCount <= 9'b1; CS_SCKCount <= 9'b1;
SCK_CSCount <= 9'b10; SCK_CSCount <= 9'b10;
FrameCount <= 4'b0; FrameCount <= 4'b0;
@ -341,6 +356,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
end end
INTER_CS: begin INTER_CS: begin
InterCSCount <= InterCSCount + 9'b1; InterCSCount <= InterCSCount + 9'b1;
SPICLK <= SckMode[1];
if (InterCSCount >= ({Delay1[7:0],1'b0})) state <= CS_INACTIVE; if (InterCSCount >= ({Delay1[7:0],1'b0})) state <= CS_INACTIVE;
end end
INTER_XFR: begin INTER_XFR: begin
@ -349,8 +365,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
FrameCount <= 4'b0; FrameCount <= 4'b0;
InterCSCount <= 9'b10; InterCSCount <= 9'b10;
InterXFRCount <= InterXFRCount + 9'b1; InterXFRCount <= InterXFRCount + 9'b1;
if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) state <= ACTIVE_0; if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) begin
else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE; state <= ACTIVE_0;
SPICLK <= ~SckMode[1];
end else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE;
else SPICLK <= SckMode[1];
end end
endcase endcase
/* verilator lint_off CASEINCOMPLETE */ /* verilator lint_off CASEINCOMPLETE */
@ -360,32 +379,28 @@ module spi_apb import cvw::*; #(parameter cvw_t P) (
assign DelayMode = SckMode[0] ? (state == DELAY_1) : (state == ACTIVE_1 & ReceiveShiftFull); assign DelayMode = SckMode[0] ? (state == DELAY_1) : (state == ACTIVE_1 & ReceiveShiftFull);
assign ChipSelectInternal = (state == CS_INACTIVE | state == INTER_CS | DelayMode & ~|(Delay0[15:8])) ? ChipSelectDef : ~ChipSelectDef; assign ChipSelectInternal = (state == CS_INACTIVE | state == INTER_CS | DelayMode & ~|(Delay0[15:8])) ? ChipSelectDef : ~ChipSelectDef;
assign SPICLK = (state == ACTIVE_0) ? ~SckMode[1] : SckMode[1];
assign Active = (state == ACTIVE_0 | state == ACTIVE_1); assign Active = (state == ACTIVE_0 | state == ACTIVE_1);
assign SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0); assign SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0);
assign ZeroDelayHoldMode = ((ChipSelectMode == 2'b10) & (~|(Delay1[7:4]))); assign ZeroDelayHoldMode = ((ChipSelectMode == 2'b10) & (~|(Delay1[7:4])));
assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode)); assign TransmitInactive = ((state == INTER_CS) | (state == CS_INACTIVE) | (state == INTER_XFR) | (ReceiveShiftFullDelayPCLK & ZeroDelayHoldMode) | ((state == ACTIVE_1) & ((ChipSelectMode[1:0] == 2'b10) & ~|(Delay1[15:8]) & (~TransmitFIFOReadEmpty) & (FrameCount == Format[4:1]))));
assign Active0 = (state == ACTIVE_0); assign Active0 = (state == ACTIVE_0);
// Signal tracks which edge of sck to shift data // Signal tracks which edge of sck to shift data
// Jacob: We need to confirm that this represents the actual polarity and phase options for sampling.
// The first option now samples on the leading edge and shifts on the falling edge like it's supposed to.
// We need to confirm the validity of the other options.
always_comb always_comb
case(SckMode[1:0]) case(SckMode[1:0])
2'b00: ShiftEdge = SPICLK & SCLKenable; 2'b00: ShiftEdge = SPICLK & SCLKenable;
2'b01: ShiftEdge = (SPICLK & |(FrameCount) & SCLKenable); // Probably wrong 2'b01: ShiftEdge = (~SPICLK & (|(FrameCount) | (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1))) & SCLKenable & (FrameCount != Format[4:1]) & ~TransmitInactive);
2'b10: ShiftEdge = ~SPICLK & SCLKenable; // Probably wrong 2'b10: ShiftEdge = ~SPICLK & SCLKenable;
2'b11: ShiftEdge = (~SPICLK & |(FrameCount) & SCLKenable); // Probably wrong 2'b11: ShiftEdge = (SPICLK & (|(FrameCount) | (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1))) & SCLKenable & (FrameCount != Format[4:1]) & ~TransmitInactive);
default: ShiftEdge = SPICLK & SCLKenable; default: ShiftEdge = SPICLK & SCLKenable;
endcase endcase
// Transmit shift register // Transmit shift register
assign TransmitDataEndian = Format[0] ? {TransmitFIFOReadData[0], TransmitFIFOReadData[1], TransmitFIFOReadData[2], TransmitFIFOReadData[3], TransmitFIFOReadData[4], TransmitFIFOReadData[5], TransmitFIFOReadData[6], TransmitFIFOReadData[7]} : TransmitFIFOReadData[7:0]; assign TransmitDataEndian = Format[0] ? {TransmitFIFOReadData[0], TransmitFIFOReadData[1], TransmitFIFOReadData[2], TransmitFIFOReadData[3], TransmitFIFOReadData[4], TransmitFIFOReadData[5], TransmitFIFOReadData[6], TransmitFIFOReadData[7]} : TransmitFIFOReadData[7:0];
always_ff @(posedge PCLK) always_ff @(posedge PCLK)
if(~PRESETn) TransmitShiftReg <= 8'b0; // Temporarily changing to 1s if(~PRESETn) TransmitShiftReg <= 8'b0;
else if (TransmitShiftRegLoad) TransmitShiftReg <= TransmitDataEndian; else if (TransmitShiftRegLoad) TransmitShiftReg <= TransmitDataEndian;
else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], TransmitShiftReg[0]}; // Temporarily changing to 1s else if (ShiftEdge & Active) TransmitShiftReg <= {TransmitShiftReg[6:0], TransmitShiftReg[0]};
assign SPIOut = TransmitShiftReg[7]; assign SPIOut = TransmitShiftReg[7];

View File

@ -88,6 +88,8 @@
0000000B 0000000B
000000F3
00000079 00000079
00000000 00000000

View File

@ -178,6 +178,12 @@ test_cases:
.4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end .4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.4byte rx_data, 0x0000000B, read32_test # read rx_data .4byte rx_data, 0x0000000B, read32_test # read rx_data
# Test phase polarity
.4byte sck_mode, 0x00000003, write32_test # set sck mode to 11
.4byte tx_data, 0x000000F3, write32_test # place f3 into tx_data
.4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.4byte rx_data, 0x000000F3, read32_test # read rx_data
# Test chip select polarity # Test chip select polarity
.4byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high .4byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high

View File

@ -88,6 +88,8 @@
00000000 00000000
0000000B 0000000B
00000000 00000000
000000F3
00000000
00000079 00000079
00000000 00000000
00000000 00000000

View File

@ -180,6 +180,12 @@ test_cases:
.8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end .8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.8byte rx_data, 0x0000000B, read32_test # read rx_data .8byte rx_data, 0x0000000B, read32_test # read rx_data
# Test phase polarity
.8byte sck_mode, 0x00000003, write32_test # set sck mode to 11
.8byte tx_data, 0x000000F3, write32_test # place f3 into tx_data
.8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end
.8byte rx_data, 0x000000F3, read32_test # read rx_data
# Test chip select polarity # Test chip select polarity
.8byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high .8byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high