diff options
| author | Jan Tuomi <jan@jantuomi.fi> | 2025-01-02 15:36:57 +0200 |
|---|---|---|
| committer | Jan Tuomi <jan@jantuomi.fi> | 2025-01-02 15:36:57 +0200 |
| commit | 99203fb27559f91ff903690338af76f6f29cf52d (patch) | |
| tree | b774aae3d6b306d87159f5cec80b39b4e18932ee /atk16_fpga/flash.v | |
| parent | ceea6d2fb9c715e70623407674b4fc4a2ec032fc (diff) | |
WIP flash bootload
Diffstat (limited to 'atk16_fpga/flash.v')
| -rw-r--r-- | atk16_fpga/flash.v | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/atk16_fpga/flash.v b/atk16_fpga/flash.v new file mode 100644 index 0000000..908ecf0 --- /dev/null +++ b/atk16_fpga/flash.v @@ -0,0 +1,60 @@ +`timescale 1ns / 1ps + +// This is a memory model of the flash memory chip on the iCE40HX8K-EVB. +// Relevant specs: +// - 2MB space (not implemented entirely in simulation) +// - An SPI interface +module flash( + input wire cs, // Chip select, active low + input wire clk, // SPI clock + input wire mosi, // Master Out Slave In + output reg miso, // Master In Slave Out + input wire rst_n // Active low reset +); + + reg [7:0] memory [0:2047]; // A smaller memory space for simplicity + reg [7:0] command; + reg [10:0] address; + reg [7:0] temp_data; + reg [3:0] bit_count; + reg write_enable; + + always @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + miso <= 1'b0; + command <= 8'b0; + address <= 11'b0; + temp_data <= 8'b0; + bit_count <= 4'b0; + write_enable <= 1'b0; + end else if (!cs) begin + if (bit_count < 8) begin + // First byte is the command + command[7 - bit_count] <= mosi; + end else if (bit_count < 19) begin + // Next 11 bits are the address + address[18 - bit_count] <= mosi; + end else if (command == 8'h02 && write_enable) begin + // Handle write command + if (bit_count < 28) begin + temp_data[27 - bit_count] <= mosi; + if (bit_count == 27) begin + memory[address] <= temp_data; + end + end + end else if (command == 8'h03) begin + // Handle read command + if (bit_count == 19) begin + temp_data <= memory[address]; + end + if (bit_count >= 20) begin + miso <= temp_data[27 - bit_count]; + end + end + bit_count <= bit_count + 1'b1; + end else begin + bit_count <= 0; + miso <= 1'bz; // Tristate when not active + end + end +endmodule |
