blob: 088d303d383df09b913ce184be811794ab28bc43 [file] [log] [blame]
module FlashBuffer #(
parameter SRAM_ADDRESS_SIZE = 9
)(
input wire clk,
input wire rst,
// 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 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,
output wire sram_csb0,
output wire sram_web0,
output wire[3:0] sram_wmask0,
output wire[SRAM_ADDRESS_SIZE-1:0] sram_addr0,
output wire[31:0] sram_din0,
input wire[31:0] sram_dout0,
// Wishbone SRAM r port
output wire sram_clk1,
output wire sram_csb1,
output wire[SRAM_ADDRESS_SIZE-1:0] sram_addr1,
input wire[31:0] sram_dout1
);
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 (peripheralBus_oe && sramEnable) flashCacheReadReady <= 1'b1;
else flashCacheReadReady <= 1'b0;
end
// 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 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], 2'b00 };
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 = !(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 = cachedAddress[SRAM_ADDRESS_SIZE+1:2];
assign sram_din0 = qspi_readData;
// Read port
assign sram_clk1 = clk;
assign sram_csb1 = !(sramEnable && peripheralBus_oe);
assign sram_addr1 = peripheralBus_address[SRAM_ADDRESS_SIZE+1:2];
endmodule