Skip to content

Commit

Permalink
Add standard and quad write functionality to flash model (#426)
Browse files Browse the repository at this point in the history
  • Loading branch information
consanii authored Dec 5, 2023
1 parent dd913a9 commit 1282116
Show file tree
Hide file tree
Showing 4 changed files with 587 additions and 22 deletions.
97 changes: 95 additions & 2 deletions hw/vendor/patches/yosyshq_picorv32/0002-spiflash_valueargs.patch
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
diff --git a/picosoc/spiflash.v b/picosoc/spiflash.v
index 22b337b..e0eef9f 100644
index 22b337b..88582b3 100644
--- a/picosoc/spiflash.v
+++ b/picosoc/spiflash.v
@@ -102,8 +102,14 @@ module spiflash (
@@ -26,7 +26,7 @@
// updates output signals 1ns after the SPI clock edge.
//
// Supported commands:
-// AB, B9, FF, 03, BB, EB, ED
+// AB, B9, FF, 03, BB, EB, ED, 06, 02, 32
//
// Well written SPI flash data sheets:
// Cypress S25FL064L http://www.cypress.com/file/316661/download
@@ -61,6 +61,8 @@ module spiflash (
reg spi_io_vld;

reg powered_up = 0;
+ reg write_enable = 0;
+ reg write_enable_reset = 0;

localparam [3:0] mode_spi = 1;
localparam [3:0] mode_dspi_rd = 2;
@@ -102,8 +104,14 @@ module spiflash (
reg [7:0] memory [0:16*1024*1024-1];

reg [1023:0] firmware_file;
Expand All @@ -18,3 +36,78 @@ index 22b337b..e0eef9f 100644
firmware_file = "firmware.hex";
$readmemh(firmware_file, memory);
end
@@ -123,6 +131,9 @@ module spiflash (

if (spi_cmd == 8'h ff)
xip_cmd = 0;
+
+ if (spi_cmd == 8'h 06)
+ write_enable = 1;
end

if (powered_up && spi_cmd == 'h 03) begin
@@ -141,6 +152,25 @@ module spiflash (
end
end

+ if (powered_up && write_enable && spi_cmd == 'h 02) begin
+ if (bytecount == 1)
+ write_enable_reset = 1;
+
+ if (bytecount == 2)
+ spi_addr[23:16] = buffer;
+
+ if (bytecount == 3)
+ spi_addr[15:8] = buffer;
+
+ if (bytecount == 4)
+ spi_addr[7:0] = buffer;
+
+ if (bytecount >= 5 && bytecount <= 260) begin
+ memory[spi_addr] = buffer;
+ spi_addr = spi_addr + 1;
+ end
+ end
+
if (powered_up && spi_cmd == 'h bb) begin
if (bytecount == 1)
mode = mode_dspi_rd;
@@ -191,6 +221,27 @@ module spiflash (
end
end

+ if (powered_up && write_enable && spi_cmd == 'h 32) begin
+ if (bytecount == 1)
+ write_enable_reset = 1;
+
+ if (bytecount == 2)
+ spi_addr[23:16] = buffer;
+
+ if (bytecount == 3)
+ spi_addr[15:8] = buffer;
+
+ if (bytecount == 4) begin
+ spi_addr[7:0] = buffer;
+ mode = mode_qspi_rd;
+ end
+
+ if (bytecount >= 5 && bytecount <= 260) begin
+ memory[spi_addr] = buffer;
+ spi_addr = spi_addr + 1;
+ end
+ end
+
if (powered_up && spi_cmd == 'h ed) begin
if (bytecount == 1)
next_mode = mode_qspi_ddr_rd;
@@ -268,6 +319,10 @@ module spiflash (
$display("");
$fflush;
end
+ if (write_enable_reset) begin
+ write_enable = 0;
+ write_enable_reset = 0;
+ end
buffer = 0;
bitcount = 0;
bytecount = 0;
51 changes: 50 additions & 1 deletion hw/vendor/yosyshq_picorv32/picosoc/spiflash.v
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
// updates output signals 1ns after the SPI clock edge.
//
// Supported commands:
// AB, B9, FF, 03, BB, EB, ED
// AB, B9, FF, 03, BB, EB, ED, 06, 02, 32
//
// Well written SPI flash data sheets:
// Cypress S25FL064L http://www.cypress.com/file/316661/download
Expand Down Expand Up @@ -61,6 +61,8 @@ module spiflash (
reg spi_io_vld;

reg powered_up = 0;
reg write_enable = 0;
reg write_enable_reset = 0;

localparam [3:0] mode_spi = 1;
localparam [3:0] mode_dspi_rd = 2;
Expand Down Expand Up @@ -129,6 +131,9 @@ module spiflash (

if (spi_cmd == 8'h ff)
xip_cmd = 0;

if (spi_cmd == 8'h 06)
write_enable = 1;
end

if (powered_up && spi_cmd == 'h 03) begin
Expand All @@ -147,6 +152,25 @@ module spiflash (
end
end

if (powered_up && write_enable && spi_cmd == 'h 02) begin
if (bytecount == 1)
write_enable_reset = 1;

if (bytecount == 2)
spi_addr[23:16] = buffer;

if (bytecount == 3)
spi_addr[15:8] = buffer;

if (bytecount == 4)
spi_addr[7:0] = buffer;

if (bytecount >= 5 && bytecount <= 260) begin
memory[spi_addr] = buffer;
spi_addr = spi_addr + 1;
end
end

if (powered_up && spi_cmd == 'h bb) begin
if (bytecount == 1)
mode = mode_dspi_rd;
Expand Down Expand Up @@ -197,6 +221,27 @@ module spiflash (
end
end

if (powered_up && write_enable && spi_cmd == 'h 32) begin
if (bytecount == 1)
write_enable_reset = 1;

if (bytecount == 2)
spi_addr[23:16] = buffer;

if (bytecount == 3)
spi_addr[15:8] = buffer;

if (bytecount == 4) begin
spi_addr[7:0] = buffer;
mode = mode_qspi_rd;
end

if (bytecount >= 5 && bytecount <= 260) begin
memory[spi_addr] = buffer;
spi_addr = spi_addr + 1;
end
end

if (powered_up && spi_cmd == 'h ed) begin
if (bytecount == 1)
next_mode = mode_qspi_ddr_rd;
Expand Down Expand Up @@ -274,6 +319,10 @@ module spiflash (
$display("");
$fflush;
end
if (write_enable_reset) begin
write_enable = 0;
write_enable_reset = 0;
end
buffer = 0;
bitcount = 0;
bytecount = 0;
Expand Down
24 changes: 5 additions & 19 deletions sw/applications/example_spi_flash_write/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,7 @@ static inline __attribute__((always_inline)) void spi_config()
spi_set_configopts(&spi_host, 0, chip_cfg);
spi_set_csid(&spi_host, 0);

// Reset
const uint32_t reset_cmd = 0xFFFFFFFF;
spi_write_word(&spi_host, reset_cmd);
const uint32_t cmd_reset = spi_create_command((spi_command_t){
.len = 3,
.csaat = false,
.speed = kSpiSpeedStandard,
.direction = kSpiDirTxOnly
});
spi_set_command(&spi_host, cmd_reset);
spi_wait_for_ready(&spi_host);
// Set read watermark to 1 word
spi_set_rx_watermark(&spi_host,1);

// Power up flash
Expand Down Expand Up @@ -267,13 +257,6 @@ static inline __attribute__((always_inline)) void spi_wait_4_resp()

int main(int argc, char *argv[])
{

#ifdef TARGET_SIM
#pragma message("This app does not allow Flash write operations in simulation!")
PRINTF("Flash writes are not permitted during Simulation, only on FPGA\n");
return EXIT_SUCCESS;
#endif

soc_ctrl_t soc_ctrl;
soc_ctrl.base_addr = mmio_region_from_addr((uintptr_t)SOC_CTRL_START_ADDRESS);

Expand Down Expand Up @@ -367,12 +350,15 @@ int main(int argc, char *argv[])
}
PRINTF("triggered\n\r");

// In simulation there is no need to wait
#ifdef USE_SPI_FLASH
spi_wait_4_resp();
#endif //USE_SPI_FLASH

PRINTF("%d Bytes written in Flash at @ 0x%08x \n\r", COPY_DATA_UNITS*DMA_DATA_TYPE_2_SIZE(TEST_DATA_TYPE), FLASH_ADDR);


#endif //TEST_SPI_2_MEM
#endif // TEST_MEM_2_SPI

#ifdef TEST_SPI_2_MEM

Expand Down
Loading

0 comments on commit 1282116

Please sign in to comment.