Added a simple flash interface controller.
diff --git a/verilog/rtl/Flash/FlashBuffer.v b/verilog/rtl/Flash/FlashBuffer.v index acaae31..29c2171 100644 --- a/verilog/rtl/Flash/FlashBuffer.v +++ b/verilog/rtl/Flash/FlashBuffer.v
@@ -4,18 +4,22 @@ input wire clk, input wire rst, - // Flash cache interface - input wire flashCache_readEnable, - input wire[23:0] flashCache_address, - input wire[3:0] flashCache_byteSelect, - output wire[31:0] flashCache_dataRead, - output wire flashCache_busy, + // Peripheral Bus + input wire peripheralBus_we, + input wire peripheralBus_oe, + input wire[23:0] peripheralBus_address, + input wire[3:0] peripheralBus_byteSelect, + input wire[31:0] peripheralBus_dataWrite, + output reg[31:0] peripheralBus_dataRead, + output wire peripheralBus_busy, // QSPI device - output wire[23:0] dataRequest_address, - output wire dataRequest_enable, - input wire[31:0] dataRequest_data, - input wire dataRequest_dataValid, + output wire qspi_enable, + output wire[23:0] qspi_address, + output wire qspi_changeAddress, + output reg qspi_requestData, + input wire[31:0] qspi_readData, + input wire qspi_readDataValid, // Flash controller SRAM rw port output wire sram_clk0, @@ -32,39 +36,149 @@ output wire[SRAM_ADDRESS_SIZE-1:0] sram_addr1, input wire[31:0] sram_dout1 ); - - //TODO: Flash cache control - assign dataRequest_address = flashCache_address; - assign dataRequest_enable = 1'b0; + + reg[23:0] cachedAddress; + reg[SRAM_ADDRESS_SIZE:0] cachedCount; + wire[SRAM_ADDRESS_SIZE:0] nextCachedCount = cachedCount + 1; + wire[SRAM_ADDRESS_SIZE:0] cachedCountFinal = { 1'b1, {(SRAM_ADDRESS_SIZE){1'b0}} }; + + // Select + wire sramEnable = peripheralBus_address[23:SRAM_ADDRESS_SIZE+2] == {(22-SRAM_ADDRESS_SIZE){1'b0}}; + wire registersEnable = peripheralBus_address[23:12] == 12'h001; + wire[11:0] localAddress = peripheralBus_address[11:0]; + + // Register + // Configuration register Default 0x0 + // b00: enable Default 0x0 + wire[31:0] configurationRegisterOutputData; + wire configurationRegisterOutputRequest; + wire configuration; + ConfigurationRegister #(.WIDTH(1), .ADDRESS(12'h000), .DEFAULT(1'b0)) configurationRegister( + .clk(clk), + .rst(rst), + .enable(registersEnable), + .peripheralBus_we(peripheralBus_we), + .peripheralBus_oe(peripheralBus_oe), + .peripheralBus_address(localAddress), + .peripheralBus_byteSelect(peripheralBus_byteSelect), + .peripheralBus_dataWrite(peripheralBus_dataWrite), + .peripheralBus_dataRead(configurationRegisterOutputData), + .requestOutput(configurationRegisterOutputRequest), + .currentValue(configuration)); + + assign qspi_enable = configuration; + + // Base address register Default 0x0 + reg[23:0] baseAddress; + wire[31:0] baseAddressRegisterOutputData; + wire baseAddressRegisterOutputRequest; + wire baseAddressRegisterBusBusy_nc; + wire[23:0] baseAddressRegisterWriteData; + wire baseAddressRegisterWriteDataEnable; + wire baseAddressRegisterReadDataEnable_nc; + DataRegister #(.WIDTH(24), .ADDRESS(12'h004)) baseAddressRegister( + .clk(clk), + .rst(rst), + .enable(registersEnable), + .peripheralBus_we(peripheralBus_we), + .peripheralBus_oe(peripheralBus_oe), + .peripheralBus_busy(baseAddressRegisterBusBusy_nc), + .peripheralBus_address(localAddress), + .peripheralBus_byteSelect(peripheralBus_byteSelect), + .peripheralBus_dataWrite(peripheralBus_dataWrite), + .peripheralBus_dataRead(baseAddressRegisterOutputData), + .requestOutput(baseAddressRegisterOutputRequest), + .writeData(baseAddressRegisterWriteData), + .writeData_en(baseAddressRegisterWriteDataEnable), + .writeData_busy(1'b0), + .readData(baseAddress), + .readData_en(baseAddressRegisterReadDataEnable_nc), + .readData_busy(1'b0)); + + always @(posedge clk) begin + if (rst) baseAddress <= 24'b0; + else if (baseAddressRegisterWriteDataEnable) baseAddress <= baseAddressRegisterWriteData; + end + + // Cached address register + wire[31:0] cachedAddressRegisterOutputData; + wire cachedAddressRegisterOutputRequest; + wire cachedAddressRegisterBusBusy_nc; + wire[23:0] cachedAddressRegisterWriteData_nc; + wire cachedAddressRegisterWriteDataEnable_nc; + wire cachedAddressRegisterReadDataEnable_nc; + DataRegister #(.WIDTH(24), .ADDRESS(12'h008)) cachedAddressRegister( + .clk(clk), + .rst(rst), + .enable(registersEnable), + .peripheralBus_we(peripheralBus_we), + .peripheralBus_oe(peripheralBus_oe), + .peripheralBus_busy(cachedAddressRegisterBusBusy_nc), + .peripheralBus_address(localAddress), + .peripheralBus_byteSelect(peripheralBus_byteSelect), + .peripheralBus_dataWrite(peripheralBus_dataWrite), + .peripheralBus_dataRead(cachedAddressRegisterOutputData), + .requestOutput(cachedAddressRegisterOutputRequest), + .writeData(cachedAddressRegisterWriteData_nc), + .writeData_en(cachedAddressRegisterWriteDataEnable_nc), + .writeData_busy(1'b0), + .readData(cachedAddress), + .readData_en(cachedAddressRegisterReadDataEnable_nc), + .readData_busy(1'b0)); // Remember that the read data is only valid on the next clock cycle reg flashCacheReadReady = 1'b0; always @(posedge clk) begin if (rst) flashCacheReadReady <= 1'b0; - else if (flashCache_readEnable) flashCacheReadReady <= 1'b1; + else if (peripheralBus_oe && sramEnable) flashCacheReadReady <= 1'b1; else flashCacheReadReady <= 1'b0; end - assign flashCache_dataRead = { - flashCache_byteSelect[3] && flashCacheReadReady ? sram_dout1[31:24] : 8'h00, - flashCache_byteSelect[2] && flashCacheReadReady ? sram_dout1[23:16] : 8'h00, - flashCache_byteSelect[1] && flashCacheReadReady ? sram_dout1[15:8] : 8'h00, - flashCache_byteSelect[0] && flashCacheReadReady ? sram_dout1[7:0] : 8'h00 - }; + // Assign peripheral read + always @(*) begin + case (1'b1) + configurationRegisterOutputRequest: peripheralBus_dataRead <= configurationRegisterOutputData; + baseAddressRegisterOutputRequest: peripheralBus_dataRead <= baseAddressRegisterOutputData; + cachedAddressRegisterOutputRequest: peripheralBus_dataRead <= cachedAddressRegisterOutputData; + flashCacheReadReady: peripheralBus_dataRead <= sram_dout1; + default: peripheralBus_dataRead <= 32'b0; + endcase + end - assign flashCache_busy = flashCache_readEnable && !flashCacheReadReady; + assign peripheralBus_busy = peripheralBus_oe && sramEnable && !flashCacheReadReady; + // QSPI interface + always @(posedge clk) begin + if (rst) begin + cachedAddress <= 32'b0; + cachedCount <= {SRAM_ADDRESS_SIZE{1'b0}}; + qspi_requestData <= 1'b0; + end else if (baseAddressRegisterWriteDataEnable) begin + cachedAddress <= baseAddressRegisterWriteData[23:2]; + cachedCount <= {SRAM_ADDRESS_SIZE{1'b0}}; + qspi_requestData <= 1'b1; + end else if (qspi_requestData && qspi_readDataValid) begin + cachedAddress <= cachedAddress + 4; + cachedCount <= nextCachedCount; + qspi_requestData <= nextCachedCount != cachedCountFinal; + end + end + + assign qspi_address = baseAddressRegisterWriteData; + assign qspi_changeAddress = baseAddressRegisterWriteDataEnable; + + // Assign sram port + // Read/write port assign sram_clk0 = clk; - assign sram_csb0 = 1'b1; // Active low chip enable - assign sram_web0 = 1'b1; // Active low write enable (probably keep as always write) + assign sram_csb0 = !(qspi_requestData && qspi_readDataValid); // Active low chip enable + assign sram_web0 = 1'b0; // Active low write enable (probably keep as always write) assign sram_wmask0 = 4'b1111; - assign sram_addr0 = {SRAM_ADDRESS_SIZE{1'b0}}; - assign sram_din0 = 32'b0; + assign sram_addr0 = cachedAddress[SRAM_ADDRESS_SIZE+1:2]; + assign sram_din0 = qspi_readData; // Read port - wire validAddress = flashCache_address[23:SRAM_ADDRESS_SIZE+1] == 'b0; assign sram_clk1 = clk; - assign sram_csb1 = !(validAddress && flashCache_readEnable); - assign sram_addr1 = flashCache_address[SRAM_ADDRESS_SIZE+1:2]; + assign sram_csb1 = !(sramEnable && peripheralBus_oe); + assign sram_addr1 = peripheralBus_address[SRAM_ADDRESS_SIZE+1:2]; endmodule \ No newline at end of file
diff --git a/verilog/rtl/Flash/Flash_top.v b/verilog/rtl/Flash/Flash_top.v index 16370a2..d5f31a2 100644 --- a/verilog/rtl/Flash/Flash_top.v +++ b/verilog/rtl/Flash/Flash_top.v
@@ -52,13 +52,18 @@ localparam STATE_READ_CONTINUOUS = 2'b11; // Wishbone interface - wire flashCache_readEnable; - wire[23:0] flashCache_address; - wire[3:0] flashCache_byteSelect; - wire[31:0] flashCache_dataRead; - wire flashCache_busy; - - WBFlashInterface wbFlashInterface( + wire peripheralBus_we; + wire peripheralBus_oe; + wire peripheralBus_busy; + wire[23:0] peripheralBus_address; + wire[3:0] peripheralBus_byteSelect; + wire[31:0] peripheralBus_dataRead; + wire[31:0] peripheralBus_dataWrite; + WBPeripheralBusInterface wbPeripheralBusInterface( + `ifdef USE_POWER_PINS + .vccd1(vccd1), // User area 1 1.8V power + .vssd1(vssd1), // User area 1 digital ground + `endif .wb_clk_i(wb_clk_i), .wb_rst_i(wb_rst_i), .wb_stb_i(wb_stb_i), @@ -71,30 +76,38 @@ .wb_stall_o(wb_stall_o), .wb_error_o(wb_error_o), .wb_data_o(wb_data_o), - .flashCache_readEnable(flashCache_readEnable), - .flashCache_address(flashCache_address), - .flashCache_byteSelect(flashCache_byteSelect), - .flashCache_dataRead(flashCache_dataRead), - .flashCache_busy(flashCache_busy)); + .peripheralBus_we(peripheralBus_we), + .peripheralBus_oe(peripheralBus_oe), + .peripheralBus_address(peripheralBus_address), + .peripheralBus_byteSelect(peripheralBus_byteSelect), + .peripheralBus_dataWrite(peripheralBus_dataWrite), + .peripheralBus_dataRead(peripheralBus_dataRead), + .peripheralBus_busy(peripheralBus_busy)); // Flash cache - wire[23:0] dataRequest_address; - wire dataRequest_enable; - wire[31:0] dataRequest_data; - wire dataRequest_dataValid; + wire qspi_enable; + wire[23:0] qspi_address; + wire qspi_changeAddress; + wire qspi_requestData; + wire[31:0] qspi_readData; + wire qspi_readDataValid; - FlashBuffer flashBuffer( + FlashBuffer #(.SRAM_ADDRESS_SIZE(SRAM_ADDRESS_SIZE)) flashBuffer( .clk(wb_clk_i), .rst(wb_rst_i), - .flashCache_readEnable(flashCache_readEnable), - .flashCache_address(flashCache_address), - .flashCache_byteSelect(flashCache_byteSelect), - .flashCache_dataRead(flashCache_dataRead), - .flashCache_busy(flashCache_busy), - .dataRequest_address(dataRequest_address), - .dataRequest_enable(dataRequest_enable), - .dataRequest_data(dataRequest_data), - .dataRequest_dataValid(dataRequest_dataValid), + .peripheralBus_we(peripheralBus_we), + .peripheralBus_oe(peripheralBus_oe), + .peripheralBus_address(peripheralBus_address), + .peripheralBus_byteSelect(peripheralBus_byteSelect), + .peripheralBus_dataWrite(peripheralBus_dataWrite), + .peripheralBus_dataRead(peripheralBus_dataRead), + .peripheralBus_busy(peripheralBus_busy), + .qspi_enable(qspi_enable), + .qspi_address(qspi_address), + .qspi_changeAddress(qspi_changeAddress), + .qspi_requestData(qspi_requestData), + .qspi_readData(qspi_readData), + .qspi_readDataValid(qspi_readDataValid), .sram_clk0(sram_clk0), .sram_csb0(sram_csb0), .sram_web0(sram_web0), @@ -108,13 +121,15 @@ .sram_dout1(sram_dout1)); // QSPI controller - QSPIDevice #(.CLOCK_WIDTH(8)) qspiDevice ( + QSPIDevice qspiDevice ( .clk(wb_clk_i), .rst(wb_rst_i), - .dataRequest_address(dataRequest_address), - .dataRequest_enable(dataRequest_enable), - .dataRequest_data(dataRequest_data), - .dataRequest_dataValid(dataRequest_dataValid), + .qspi_enable(qspi_enable), + .qspi_address(qspi_address), + .qspi_changeAddress(qspi_changeAddress), + .qspi_requestData(qspi_requestData), + .qspi_readData(qspi_readData), + .qspi_readDataValid(qspi_readDataValid), .flash_csb(flash_csb), .flash_sck(flash_sck), .flash_io0_we(flash_io0_we), @@ -124,101 +139,4 @@ .flash_io1_write(flash_io1_write), .flash_io1_read(flash_io1_read)); - // Flash controller - // wire doneTransferByte = 1'b0; - // reg[1:0] state = STATE_STARTUP; - - // reg[7:0] dataBuffer [0:3]; - // reg[1:0] bufferPointer = 2'h0; - // wire[2:0] nextBufferPointer = bufferPointer + 1; - - // reg[31:0] currentAddress = 32'b0; - // wire[31:0] nextAddress = currentAddress + 1; - - // reg[31:0] outputData; - - // always @(*) begin - // case (bufferPointer) - // 2'h0: outputData <= { dataBuffer[3], dataBuffer[2], dataBuffer[1], dataBuffer[0] }; - // 2'h1: outputData <= { dataBuffer[2], dataBuffer[1], dataBuffer[0], dataBuffer[3] }; - // 2'h2: outputData <= { dataBuffer[1], dataBuffer[0], dataBuffer[3], dataBuffer[2] }; - // 2'h3: outputData <= { dataBuffer[0], dataBuffer[3], dataBuffer[2], dataBuffer[1] }; - // endcase - // end - - // // Parallel interface - // wire writeEnable; - // wire readEnable; - // wire[7:0] writeData; - // wire[7:0] readData; - // wire busy; - - - - // always @(posedge clk) begin - // if (rst) begin - // state <= STATE_STARTUP; - // bufferPointer <= 3'h0; - // dataBuffer[0] <= 8'hFF; - // dataBuffer[1] <= 8'hAB; - // dataBuffer[2] <= 8'h03; - // dataBuffer[3] <= 8'h00; - // end else begin - // case (state) - // STATE_STARTUP: begin - // if (doneTransferByte) begin - // if (bufferPointer == 3'h1) begin - // state <= STATE_CHANGE_ADDRESS; - // dataBuffer[0] <= 8'h03; - // dataBuffer[1] <= 8'h00; - // dataBuffer[2] <= 8'h00; - // dataBuffer[3] <= 8'h00; - // bufferPointer <= 3'h0; - // end else begin - // bufferPointer <= nextBufferPointer; - // end - // end - // end - - // STATE_WRITE_COMMAND: begin - // if (doneTransferByte) begin - // dataBuffer[bufferPointer] <= readData; - // bufferPointer <= nextBufferPointer; - // currentAddress <= nextAddress; - // end - // end - - // STATE_CHANGE_ADDRESS: begin - // if (doneTransferByte) begin - // if (bufferPointer == 3'h1) begin - // state <= STATE_READ_CONTINUOUS; - // dataBuffer[0] <= 8'h00; - // dataBuffer[1] <= 8'h00; - // dataBuffer[2] <= 8'h00; - // dataBuffer[3] <= 8'h00; - // bufferPointer <= 3'h0; - // end else begin - // bufferPointer <= nextBufferPointer; - // end - // end - // end - - // STATE_READ_CONTINUOUS: begin - - // end - - // default: begin - // state <= STATE_STARTUP; - // bufferPointer <= 3'h0; - // dataBuffer[0] <= 8'hFF; - // dataBuffer[1] <= 8'hAB; - // dataBuffer[2] <= 8'h03; - // dataBuffer[3] <= 8'h00; - // end - // endcase - // end - // end - - // assign writeData = dataBuffer[bufferPointer]; - endmodule \ No newline at end of file
diff --git a/verilog/rtl/Flash/QSPIDevice.v b/verilog/rtl/Flash/QSPIDevice.v index f1e3d7f..c59e366 100644 --- a/verilog/rtl/Flash/QSPIDevice.v +++ b/verilog/rtl/Flash/QSPIDevice.v
@@ -1,18 +1,18 @@ -module QSPIDevice #( - parameter CLOCK_WIDTH = 8 - )( +module QSPIDevice ( input wire clk, input wire rst, // Cache interface - input wire[23:0] dataRequest_address, - input wire dataRequest_enable, - output wire[31:0] dataRequest_data, - output wire dataRequest_dataValid, + input wire qspi_enable, + input wire[23:0] qspi_address, + input wire qspi_changeAddress, + input wire qspi_requestData, + output wire[31:0] qspi_readData, + output reg qspi_readDataValid, // QSPI interface output wire flash_csb, - output wire flash_sck, + output reg flash_sck, output wire flash_io0_we, output wire flash_io0_write, input wire flash_io0_read, // Unused @@ -21,218 +21,129 @@ input wire flash_io1_read ); - // Have this running at the system clock rate - // This will probably be 40MHz - assign flash_sck = clk; + localparam STATE_IDLE = 2'h0; + localparam STATE_SETUP = 2'h1; + localparam STATE_SHIFT = 2'h2; + localparam STATE_END = 2'h3; - assign flash_csb = 1'b0; + localparam RESET_NONE = 2'h0; + localparam RESET_START = 2'h1; + localparam RESET_WAKE = 2'h2; + + // Assign these as constants to be in a default spi mode assign flash_io0_we = 1'b1; - assign flash_io0_write = 1'b0; assign flash_io1_we = 1'b0; assign flash_io1_write = 1'b0; - //assign in = flash_io1_read; - assign dataRequest_data = 32'b0; - assign dataRequest_dataValid = 1'b1; + // State control + reg[1:0] state = STATE_IDLE; + wire deviceBusy = state != STATE_IDLE; + reg[1:0] resetState = RESET_NONE; + wire resetDevice = resetState != RESET_NONE; - // localparam CLOCK_BITS = $clog2(CLOCK_WIDTH); - - // localparam STATE_IDLE = 2'b00; - // localparam STATE_SETUP = 2'b01; - // localparam STATE_SHIFT = 2'b10; - // localparam STATE_END = 2'b11; - - // // Device select - // wire[11:0] localAddress; - // wire deviceEnable; - // DeviceSelect #(.ID(ID)) select( - // .peripheralEnable(peripheralEnable), - // .peripheralBus_address(peripheralBus_address), - // .localAddress(localAddress), - // .deviceEnable(deviceEnable)); - - // // Register - // // Configuration register Default 0x064 - // // b00-b02: clockScale Default 0x4 - // // b03-04: spiMode Default 0x0 - // // b05: msbFirst Default 0x1 - // // b06: useCS Default 0x1 - // // b07: activeHighCS Default 0x0 - // // b08: enable Default 0x0 - // wire[31:0] configurationRegisterOutputData; - // wire configurationRegisterOutputRequest; - // wire[8:0] configuration; - // ConfigurationRegister #(.WIDTH(9), .ADDRESS(12'h000), .DEFAULT(9'h064)) configurationRegister( - // .clk(clk), - // .rst(rst), - // .enable(deviceEnable), - // .peripheralBus_we(peripheralBus_we), - // .peripheralBus_oe(peripheralBus_oe), - // .peripheralBus_address(localAddress), - // .peripheralBus_byteSelect(peripheralBus_byteSelect), - // .peripheralBus_dataWrite(peripheralBus_dataWrite), - // .peripheralBus_dataRead(configurationRegisterOutputData), - // .requestOutput(configurationRegisterOutputRequest), - // .currentValue(configuration)); - - // wire[2:0] clockScale = configuration[2:0]; - // wire[1:0] spiMode = configuration[4:3]; - // wire msbFirst = configuration[5]; - // wire useCS = configuration[6]; - // wire activeHighCS = configuration[7]; - // assign spi_en = configuration[8]; - // 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( - // .clk(clk), - // .rst(rst), - // .enable(deviceEnable), - // .peripheralBus_we(peripheralBus_we), - // .peripheralBus_oe(peripheralBus_oe), - // .peripheralBus_busy(dataRegisterBusBusy_nc), - // .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), - // .readData_en(dataRegisterReadDataEnable_nc), - // .readData_busy(1'b0)); - - // // State control - // reg[1:0] state = STATE_IDLE; - // wire busy = state != STATE_IDLE; + reg outputClock = 1'b0; + reg[4:0] bitCounter = 5'b0; + wire[4:0] nextBitCounter = bitCounter + 1; - // reg[2:0] bitCounter = 3'b0; - // wire[2:0] nextBitCounter = bitCounter + 1; + wire shiftInEnable = outputClock && deviceBusy; + wire shiftOutEnable = !outputClock && deviceBusy; - // reg[CLOCK_WIDTH-1:0] clockCounter = {CLOCK_WIDTH{1'b0}}; - // wire nextClockCounter = clockCounter + 1; - // wire[CLOCK_WIDTH-1:0] clockScaleHalfMask = {(CLOCK_WIDTH-1){1'b0}, 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); + reg[31:0] registerLoadData; + wire serialOut; + wire[31:0] flashData; + ShiftRegister #(.WIDTH(32)) register ( + .clk(clk), + .rst(rst), + .loadEnable((!deviceBusy && qspi_changeAddress) || ((state == STATE_SETUP) && resetDevice)), + .shiftInEnable(shiftInEnable), + .shiftOutEnable(shiftOutEnable), + .msbFirst(1'b1), + .parallelIn(registerLoadData), + .parallelOut(flashData), + .serialIn(flash_io1_read), + .serialOut(serialOut)); - // reg spiClockRise = 1'b0; - // reg spiClockFall = 1'b0; + // Reorder bytes + assign qspi_readData = { flashData[7:0], flashData[15:8], flashData[23:16], flashData[31:24] }; - // wire shiftInEnable = spiSampleMode ? spiClockFall : spiClockRise; - // wire shiftOutEnable = spiSampleMode ? spiClockRise : spiClockFall; + always @(*) begin + case (1'b1) + resetState == RESET_START: registerLoadData <= { 8'hFF, 8'h00, 8'h00, 8'h00 }; + resetState == RESET_WAKE: registerLoadData <= { 8'hAB, 8'h00, 8'h00, 8'h00 }; + qspi_changeAddress: registerLoadData <= { 8'h03, qspi_address }; + default: registerLoadData <= 32'b0; + endcase + end - // reg loadEnable; - // ShiftRegister #(.WIDTH(8)) register ( - // .clk(clk), - // .rst(rst), - // .loadEnable(loadEnable), - // .shiftInEnable(shiftInEnable), - // .shiftOutEnable(shiftOutEnable), - // .msbFirst(msbFirst), - // .parallelIn(writeData), - // .parallelOut(readData), - // .serialIn(spi_miso), - // .serialOut(spi_mosi)); + always @(posedge clk) begin + if (rst) begin + state <= STATE_IDLE; + outputClock <= 1'b0; + bitCounter <= 5'b0; + resetState <= RESET_START; + qspi_readDataValid <= 1'b0; + end else begin + case (state) + STATE_IDLE: begin + outputClock <= 1'b0; + bitCounter <= 5'b0; - // 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; - // end else begin - // case (state) - // STATE_IDLE: begin - // bitCounter <= 3'b0; - // clockCounter <= {CLOCK_WIDTH{1'b0}}; - // loadEnable <= 1'b0; + if (qspi_enable) begin + if (resetDevice || qspi_changeAddress) state <= STATE_SETUP; + end + end - // if (writeData_en && peripheralBus_byteSelect[0]) begin - // state <= STATE_SETUP; - // loadEnable <= 1'b1; - // end - // end + STATE_SETUP: begin + state <= STATE_SHIFT; + bitCounter <= 5'b0; + outputClock <= 1'b1; + qspi_readDataValid <= 1'b0; + end - // STATE_SETUP: begin - // loadEnable <= 1'b0; + STATE_SHIFT: begin + if (!outputClock) begin + if ((resetDevice && bitCounter == 5'h07) || (bitCounter == 5'h1F)) begin + state <= STATE_END; + qspi_readDataValid <= 1'b1; + end else begin + bitCounter <= nextBitCounter; + end + end - // if (spiHalfClock) begin - // clockCounter <= {CLOCK_WIDTH{1'b0}}; - // bitCounter <= 1'b0; - // state <= STATE_SHIFT; - // end else begin - // clockCounter <= nextClockCounter; - // end - // end + outputClock <= !outputClock; - // STATE_SHIFT: begin - // if (spiClock) begin - // if (spiClockPolarity) begin - // spiClockRise <= 1'b0; - // spiClockFall <= 1'b1; - // end else begin - // spiClockRise <= 1'b1; - // spiClockFall <= 1'b0; - // end + if (qspi_changeAddress) state <= STATE_IDLE; + end - // clockCounter <= {CLOCK_WIDTH{1'b0}}; - // if (bitCounter == 3'h7) state <= STATE_END; - // else bitCounter <= nextBitCounter; - // end else if (spiHalfClock) 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'b0; - // spiClockFall <= 1'b0; - // clockCounter <= nextClockCounter; - // end - // end + STATE_END: begin + if (qspi_requestData) state <= STATE_SETUP; + else state <= STATE_IDLE; - // STATE_END: begin - // spiClockRise <= 1'b0; - // spiClockFall <= 1'b0; + outputClock <= 1'b0; + qspi_readDataValid <= 1'b0; - // if (spiClock) state <= STATE_IDLE; - // else clockCounter <= nextClockCounter; - // end + if (resetState == RESET_START) resetState <= RESET_WAKE; + else resetState <= RESET_NONE; + end - // default: begin - // state <= STATE_IDLE; - // bitCounter <= 3'b0; - // clockCounter <= {CLOCK_WIDTH{1'b0}}; - // loadEnable <= 1'b0; - // spiClockRise <= 1'b0; - // spiClockFall <= 1'b0; - // end - // endcase - // end - // end + default: begin + state <= STATE_IDLE; + bitCounter <= 5'b0; + outputClock <= 1'b0; + qspi_readDataValid <= 1'b0; + resetState <= RESET_START; + 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) flash_sck <= 1'b0; + else flash_sck <= outputClock; + end - // assign spi_clk = spiClockPolarity ? !(spiClock && busy) : spiClock && busy; - // assign spi_cs = useCS ? (activeHighCS ? busy : !busy) : 1'b0; + assign flash_io0_write = serialOut & deviceBusy; + assign flash_csb = !deviceBusy; endmodule \ No newline at end of file
diff --git a/verilog/rtl/Flash/WBFlashInterface.v b/verilog/rtl/Flash/WBFlashInterface.v deleted file mode 100644 index 60ea02d..0000000 --- a/verilog/rtl/Flash/WBFlashInterface.v +++ /dev/null
@@ -1,110 +0,0 @@ -module WBFlashInterface ( - // Wishbone Slave ports - input wire wb_clk_i, - input wire wb_rst_i, - input wire wb_stb_i, - input wire wb_cyc_i, - input wire wb_we_i, - input wire[3:0] wb_sel_i, - input wire[31:0] wb_data_i, - input wire[23:0] wb_adr_i, - output wire wb_ack_o, - output wire wb_stall_o, - output wire wb_error_o, - output wire[31:0] wb_data_o, - - // Flash cache interface - output wire flashCache_readEnable, - output wire[23:0] flashCache_address, - output wire[3:0] flashCache_byteSelect, - input wire[31:0] flashCache_dataRead, - input wire flashCache_busy - ); - - localparam STATE_IDLE = 2'h0; - localparam STATE_WRITE_SINGLE = 2'h1; - localparam STATE_READ_SINGLE = 2'h2; - localparam STATE_FINISH = 2'h3; - - reg[1:0] state = STATE_IDLE; - reg[23:0] currentAddress; - reg[3:0] currentByteSelect; - reg[31:0] currentDataIn; - - reg stall = 1'b0; - reg acknowledge = 1'b0; - reg[31:0] dataRead_buffered; - - always @(posedge wb_clk_i) begin - if (wb_rst_i) begin - state <= STATE_IDLE; - stall <= 1'b0; - acknowledge <= 1'b0; - dataRead_buffered <= ~32'b0; - end else begin - case (state) - STATE_IDLE: begin - stall <= 1'b0; - acknowledge <= 1'b0; - dataRead_buffered <= ~32'b0; - - if (wb_cyc_i) begin - if (wb_stb_i) begin - currentAddress <= wb_adr_i; - currentByteSelect <= wb_sel_i; - currentDataIn <= wb_data_i; - stall <= 1'b1; - - if (wb_we_i) begin - state <= STATE_WRITE_SINGLE; - end else begin - state <= STATE_READ_SINGLE; - end - end - end - end - - STATE_WRITE_SINGLE: begin - // Not allowed to write, so just acknowledge so the bus doesn't hang - state <= STATE_FINISH; - acknowledge <= 1'b1; - end - - STATE_READ_SINGLE: begin - if (!flashCache_busy) begin - state <= STATE_FINISH; - acknowledge <= 1'b1; - dataRead_buffered <= flashCache_dataRead; - end - end - - STATE_FINISH: begin - state <= STATE_IDLE; - stall <= 1'b0; - acknowledge <= 1'b0; - dataRead_buffered <= ~32'b0; - end - - default: begin - state <= STATE_IDLE; - stall <= 1'b0; - acknowledge <= 1'b0; - end - endcase - end - end - - // Connect wishbone bus signals - assign wb_ack_o = acknowledge; - assign wb_stall_o = stall; - assign wb_error_o = 1'b0; - - // Connect peripheral bus signals - assign flashCache_readEnable = state == STATE_READ_SINGLE; - - assign flashCache_address = state != STATE_IDLE ? currentAddress : 24'b0; - assign flashCache_byteSelect = state != STATE_IDLE ? currentByteSelect : 4'b0; - - assign wb_data_o = dataRead_buffered; - -endmodule \ No newline at end of file