diff --git a/fpga/constraints/constraints-ArtyA7.xdc b/fpga/constraints/constraints-ArtyA7.xdc index e4774280f..4dadf3987 100644 --- a/fpga/constraints/constraints-ArtyA7.xdc +++ b/fpga/constraints/constraints-ArtyA7.xdc @@ -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_input_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] -min -add_delay 2.500 [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] -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 -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[2] -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[5] -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[8] -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[11] -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[14] -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[1] -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_p[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[12] -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[9] -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[6] -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[3] -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[0] -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[0] -set_property IOSTANDARD DIFF [get_ports ddr3_ck_p[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_cas_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_cke[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_dq[0]] +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[3]] +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[6]] +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[9]] +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[12]] +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[15]] +set_property IOSTANDARD SSTL135 [get_ports ddr3_dm[0]] +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_n[0]] +set_property IOSTANDARD DIFF [get_ports ddr3_dqs_p[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[12]] +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[9]] +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[6]] +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[3]] +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[0]] +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[0]] +set_property IOSTANDARD DIFF [get_ports ddr3_ck_p[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_cas_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_cke[0]] +set_property IOSTANDARD SSTL135 [get_ports ddr3_odt[0]] +set_property IOSTANDARD SSTL135 [get_ports ddr3_cs_n[0]] set_properity PACKAGE_PIN K5 [get_ports ddr3_dq[0]] diff --git a/fpga/zsbl/boot.c b/fpga/zsbl/boot.c index 566393cb6..e98eda2c1 100644 --- a/fpga/zsbl/boot.c +++ b/fpga/zsbl/boot.c @@ -37,12 +37,29 @@ #include "riscv.h" #include "fail.h" + +// Maximum SD card clock frequency is either 20MHz or half of the +// system clock + +/* +PSEUDOCODE: +transmit 8 dummy bytes +wait for receive fifo to get a byte. +- as soon as a byte is in the receive fifo +- process the byte and increment a byte counter. +when 8 bytes are transferred + + + */ + int disk_read(BYTE * buf, LBA_t sector, UINT count) { uint64_t r; - UINT i; + UINT i, j; volatile uint8_t *p = buf; - UINT modulus = count/50; + // Quarter of the Systemclock, divided by the number of bits in a block + // equals the number of blocks per second transferred. + UINT modulus = SDCCLOCK/(8*512); uint8_t crc = 0; crc = crc7(crc, 0x40 | SD_CMD_READ_BLOCK_MULTIPLE); @@ -72,22 +89,30 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count) { // Wait for data token while((r = spi_dummy()) != SD_DATA_TOKEN); - // println_with_byte("Received data token: 0x", r & 0xff); - // println_with_dec("Block ", i); - // Read block into memory. - /* for (int j = 0; j < 64; j++) { */ - /* *buf = sd_read64(&crc); */ - /* println_with_addr("0x", *buf); */ - /* buf = buf + 64; */ - /* } */ 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 { - uint8_t x = spi_dummy(); - *p++ = x; - crc = crc16(crc, x); - } while (--n > 0); + // 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 crc_exp = ((uint16_t)spi_dummy() << 8); @@ -116,8 +141,6 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count) { print_uart_dec(count); print_uart("/"); print_uart_dec(count); - // write_reg(SPI_CSMODE, SIFIVE_SPI_CSMODE_MODE_AUTO); - //spi_txrx(0xff); print_uart("\r\n"); return 0; } @@ -140,7 +163,7 @@ void copyFlash(QWORD address, QWORD * Dst, DWORD numBlocks) { /* print_uart("\r\n"); */ // Intialize the SD card - init_sd(SYSTEMCLOCK, 5000000); + init_sd(SYSTEMCLOCK, SDCCLOCK); ret = gpt_load_partitions(); } diff --git a/fpga/zsbl/boot.h b/fpga/zsbl/boot.h index 0c09a1e52..d86fdd83e 100644 --- a/fpga/zsbl/boot.h +++ b/fpga/zsbl/boot.h @@ -63,5 +63,14 @@ int disk_read(BYTE * buf, LBA_t sector, UINT count); #define SYSTEMCLOCK 20000000 +// TODO: This line needs to change back to 20MHz when we fix the +// timing problems. +#define MAXSDCCLOCK 5000000 + +// Maximum SDC speed is either the system clock divided by 2 (because +// of the SPI peripheral clock division) or the maximum speed an SD +// card can be pushed to. +#define SDCCLOCK (SYSTEMCLOCK/2 > MAXSDCCLOCK ? MAXSDCCLOCK : SYSTEMCLOCK/2) + #endif // WALLYBOOT diff --git a/src/uncore/spi_apb.sv b/src/uncore/spi_apb.sv index cadb49dfb..9bcf8be05 100644 --- a/src/uncore/spi_apb.sv +++ b/src/uncore/spi_apb.sv @@ -148,8 +148,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( // APB access assign Entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses assign Memwrite = PWRITE & PENABLE & PSEL; // Only write in access phase - // JACOB: This shouldn't behave this way - assign PREADY = TransmitInactive; // Tie PREADY to transmission for hardware interlock + assign PREADY = Entry == SPI_TXDATA | Entry == SPI_RXDATA | TransmitInactive; // Tie PREADY to transmission for hardware interlock // Account for subword read/write circuitry // -- Note SPI registers are 32 bits no matter what; access them with LW SW. @@ -187,12 +186,16 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( SPI_CSMODE: ChipSelectMode <= Din[1:0]; SPI_DELAY0: Delay0 <= {Din[23:16], Din[7:0]}; SPI_DELAY1: Delay1 <= {Din[23:16], Din[7:0]}; - SPI_FMT: Format <= {Din[19:16], Din[2]}; - SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; + SPI_FMT: Format <= {Din[19:16], Din[2]}; SPI_TXMARK: TransmitWatermark <= Din[2:0]; SPI_RXMARK: ReceiveWatermark <= Din[2:0]; SPI_IE: InterruptEnable <= Din[1:0]; endcase + + if (Memwrite) + case(Entry) + SPI_TXDATA: if (~TransmitFIFOWriteFull) TransmitData[7:0] <= Din[7:0]; + endcase /* verilator lint_off CASEINCOMPLETE */ // 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) if (~PRESETn) TransmitFIFOWriteIncrement <= 1'b0; - else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == 8'h48) & ~TransmitFIFOWriteFull & TransmitInactive); + else TransmitFIFOWriteIncrement <= (Memwrite & (Entry == SPI_TXDATA) & ~TransmitFIFOWriteFull); always_ff @(posedge PCLK) if (~PRESETn) ReceiveFIFOReadIncrement <= 1'b0; - else ReceiveFIFOReadIncrement <= ((Entry == 8'h4C) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); + else ReceiveFIFOReadIncrement <= ((Entry == SPI_RXDATA) & ~ReceiveFIFOReadEmpty & PSEL & ~ReceiveFIFOReadIncrement); // Tx/Rx FIFOs spi_fifo #(3,8) txFIFO(PCLK, 1'b1, SCLKenable, PRESETn, TransmitFIFOWriteIncrement, TransmitShiftEmpty, TransmitData[7:0], TransmitWriteWatermarkLevel, TransmitWatermark[2:0], @@ -300,7 +303,8 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( always_ff @(posedge PCLK) if (~PRESETn) begin state <= CS_INACTIVE; - FrameCount <= 4'b0; + FrameCount <= 4'b0; + SPICLK <= SckMode[1]; end else if (SCLKenable) begin /* verilator lint_off CASEINCOMPLETE */ case (state) @@ -311,21 +315,32 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( InterCSCount <= 9'b10; InterXFRCount <= 9'b1; 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 DELAY_0: begin 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 ACTIVE_0: begin FrameCount <= FrameCount + 4'b1; + SPICLK <= SckMode[1]; state <= ACTIVE_1; end ACTIVE_1: begin 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 state <= ACTIVE_0; + SPICLK <= ~SckMode[1]; CS_SCKCount <= 9'b1; SCK_CSCount <= 9'b10; FrameCount <= 4'b0; @@ -341,6 +356,7 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( end INTER_CS: begin InterCSCount <= InterCSCount + 9'b1; + SPICLK <= SckMode[1]; if (InterCSCount >= ({Delay1[7:0],1'b0})) state <= CS_INACTIVE; end INTER_XFR: begin @@ -349,8 +365,11 @@ module spi_apb import cvw::*; #(parameter cvw_t P) ( FrameCount <= 4'b0; InterCSCount <= 9'b10; InterXFRCount <= InterXFRCount + 9'b1; - if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) state <= ACTIVE_0; - else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE; + if ((InterXFRCount >= ({Delay1[15:8], 1'b0})) & ~TransmitFIFOReadEmptyDelay) begin + state <= ACTIVE_0; + SPICLK <= ~SckMode[1]; + end else if (~|ChipSelectMode[1:0]) state <= CS_INACTIVE; + else SPICLK <= SckMode[1]; end endcase /* 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 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 SampleEdge = SckMode[0] ? (state == ACTIVE_1) : (state == ACTIVE_0); 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); // 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 case(SckMode[1:0]) 2'b00: ShiftEdge = SPICLK & SCLKenable; - 2'b01: ShiftEdge = (SPICLK & |(FrameCount) & SCLKenable); // Probably wrong - 2'b10: ShiftEdge = ~SPICLK & SCLKenable; // Probably wrong - 2'b11: 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; + 2'b11: ShiftEdge = (SPICLK & (|(FrameCount) | (CS_SCKCount >= (({Delay0[7:0], 1'b0}) + ImplicitDelay1))) & SCLKenable & (FrameCount != Format[4:1]) & ~TransmitInactive); default: ShiftEdge = SPICLK & SCLKenable; endcase // 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]; 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 (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]; diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output index ebc48ae2e..b006e3229 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/references/WALLY-spi-01.reference_output @@ -88,6 +88,8 @@ 0000000B +000000F3 + 00000079 00000000 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S index 3d0abc6a0..68d3785e8 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv32i_m/privilege/src/WALLY-spi-01.S @@ -178,6 +178,12 @@ test_cases: .4byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end .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 .4byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high @@ -658,4 +664,4 @@ SETUP_PLIC -.4byte 0x0, 0x0, terminate_test \ No newline at end of file +.4byte 0x0, 0x0, terminate_test diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output index 83376aab1..673395696 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/references/WALLY-spi-01.reference_output @@ -88,6 +88,8 @@ 00000000 0000000B 00000000 +000000F3 +00000000 00000079 00000000 00000000 diff --git a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S index 11aebe333..21b38f9b8 100644 --- a/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S +++ b/tests/wally-riscv-arch-test/riscv-test-suite/rv64i_m/privilege/src/WALLY-spi-01.S @@ -180,6 +180,12 @@ test_cases: .8byte 0x0, 0x00000000, spi_data_wait # wait for transmission to end .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 .8byte sck_mode, 0x00000000, write32_test # reset sck polarity to active high @@ -660,4 +666,4 @@ SETUP_PLIC -.8byte 0x0, 0x0, terminate_test \ No newline at end of file +.8byte 0x0, 0x0, terminate_test