ยง 3.1.5. NOR Flash¶
Digital NOR-style flash following the common device architecture. Programming clears selected bits; block erase restores ones. It is not SRAM with a longer write delay, and it is not a NAND page/block controller.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
NORFlashCell |
Nonvolatile digital bit, program 1โ0, erase to 1 | Yes | No |
NORFlashRow<C> |
Shared row selection/erase and per-column programming | Yes | Yes |
NORFlashStorageBank<W> |
Cell rows and selected-row column sensing | Yes | Yes |
NORFlashCommandControl<W> |
Write-enable latch and timed command phases | Yes | No |
NORFlash<W> |
Complete word-read/program, block-erase device | Yes | Yes |
The write-enable latch, busy interval, one-way programming, and block erase are recognizable NOR-flash behaviors. The Winbond W25Q80BV data sheet is a real-device reference, not this component's pin/command specification: this simulator uses a parallel educational command port, not SPI opcodes or the data sheet's page-program protocol.
Configuration¶
Width W, capacity N, and words-per-row K follow 3.1.
| Parameter | Default | Meaning / constraints |
|---|---|---|
block_words (B) |
2 | Erase granularity; whole rows, divides N, BโคN |
phase_ticks (P) |
32 | Phase spacing, 32โฆ10,000 |
program_ticks |
128 | Delay before program pulse; Pโฆ1,000,000 |
erase_ticks |
256 | Delay before erase pulse; at least program_ticks, at most 10,000,000 |
The default simulation starts with every bit erased to one. This is an explicit initial-image assumption; it is not a claim that an arbitrary physical flash chip always contains ones when powered up. No per-cell refresh is required. Persistence across simulator recreation/file storage, wear, disturb, power-loss behavior, and erase/program voltage generation are outside this model.
The references below follow the FF/SRAM pattern. Compile the C++ examples in page order: larger references compose the earlier ones. They cover binary controls, state, outputs, and operation deadlines without gate propagation or analog behavior; they are not registered simulator implementations. Construction parameters must satisfy the documented geometry/timing constraints. Every recorded test checkpoint is included with its number and absolute time.
The configuration type is NORFlashConfig. Catalog contracts are memory.nor-flash.cell, row, bank.W, command-control.W, and device.W under the memory.nor-flash. prefix. A standalone row takes columns; banks, controllers, and devices take the geometry/timing configuration. The cell has no parameters. Only public bank/device wrappers are C++ width templates; the command controller is catalog-created.
3.1.5.1. NORFlashCell¶
One digital nonvolatile bit with separate program and erase operations.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
WL |
Input | 1 | Row selection for programming |
PROGRAM |
Input | 1 | Program excitation, qualified by WL |
ERASE |
Input | 1 | Erase independently of WL |
D |
Input | 1 | Program value: 0 clears, 1 preserves |
Q |
Output | 1 | Stored bit |
Behavior¶
Initially erased (Q=1). Programming performs Q AND D; it cannot turn zero back to one. ERASE restores one independently of WL, unless programming is simultaneously enabled, which makes Q unknown. The cell has no command port, write-enable latch, block policy, or timer.
C++ example¶
Binary controls with an optional stored bit (empty means X). Startup wiring qualification is handled separately by the simulator.
#include <optional>
struct NORFlashCellReference {
std::optional<bool> q = true;
void update(bool wl, bool program, bool erase, std::optional<bool> data) {
const bool enabled = wl && program;
if (erase) q = enabled ? std::nullopt : std::optional(true);
else if (enabled) {
if (q == false || data == false) q = false;
else if (q == true && data == true) q = true;
else q.reset();
}
}
};
Unknown inputs and timing¶
Unknown program data cannot undo Q=0; it makes Q=1 unknown. An unknown erase loses certainty. Unknown WL/PROGRAM conservatively make a possible write unknown unless a known zero enable excludes it or Q is already zero. Z is treated as unknown, not retained charge. At startup, the erased value is held until the first fully binary WL/PROGRAM/ERASE tuple; later unknown controls are not ignored. Output delay is one primitive tick.
Implementation¶
Structural implementation¶
Terminal digital nonvolatile-charge primitive. Program and erase transitions represent storage rules, not floating-gate voltage, tunneling, wear, or disturb. A second behavioral-fidelity copy is not registered.
The visualizer shows the recorded stored bit Q and WL/PROGRAM/ERASE indicators. These are cell signals, not the device controller's busy state, and update when scrubbing backward or forward.
Examples¶
All 7 recorded rows of NORFlashCellTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: canonical-default-preview / structural (3f3be5125c460b70). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | DInput ยท 1 bit |
ERASEInput ยท 1 bit |
PROGRAMInput ยท 1 bit |
WLInput ยท 1 bit |
QExpected output ยท 1 bit |
|---|---|---|---|---|---|---|
#0erased | 1 | 1 |
0 |
0 |
0 |
1 |
#1program-zero | 3 | 0 |
0 |
1 |
1 |
0 |
#2one-cannot-undo-program | 4 | 1 |
0 |
1 |
1 |
0 |
#3release | 5 | 1 |
0 |
0 |
0 |
0 |
#4erase | 7 | 1 |
1 |
0 |
0 |
1 |
#5hold-erased | 8 | 1 |
0 |
0 |
0 |
1 |
#6unknown-program-data | 10 | X |
0 |
1 |
1 |
X |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
Checks erased one, programming zero, the inability to program that zero back to one, release, erase, and programming with unknown data.
Embedded simulation¶
The standalone NORFlashCellTest opens this component as MEMORY_ROOT. This component has one registered structural implementation.
Open NORFlashCell in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
NORFlashCellTest |
The complete standalone sequence shown above |
MemoryDeviceContractTest |
Integration in the new structural devices and comparison with their compact implementations |
3.1.5.2. NORFlashRow<C>¶
C flash cells sharing row selection and row erase.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
WL |
Input | 1 | Shared program selection |
ERASE |
Input | 1 | Erase all cells in this row |
PROGRAM_c, D_c |
Input | 1 each | Column program enable/value |
Q_c |
Output | 1 each | Stored bits, 0 โค c < C |
Behavior¶
columns=C accepts 1โ512 (default 4). Each cell follows the NORFlashCell transition rule. Programming can affect columns independently. ERASE reaches all cells; device-level control selects all rows of an erase block. This row alone does not enforce block granularity.
C++ example¶
Composition of the cell reference above. Each column retains its own state.
#include <array>
#include <cstddef>
#include <optional>
template<class Cell, std::size_t C>
void flash_row_update(std::array<Cell, C>& cells, bool wl, bool erase,
const std::array<bool, C>& program,
const std::array<std::optional<bool>, C>& data) {
for (std::size_t c = 0; c < C; ++c)
cells[c].update(wl, program[c], erase, data[c]);
}
Unknown inputs and timing¶
Initial state, startup qualification, conflicts, and X/Z handling are per-cell. Unknown shared erase can affect the whole row. Outputs settle after each cell update; there is no row-level program-latency timer.
Implementation¶
Structural implementation¶
CELL_0 through CELL_(Cโ1) share WL and ERASE. Program/data are per-column. Cells are arranged horizontally in numeric column order.
Behavioral implementation¶
Stores C four-state values and per-cell startup-qualification flags. It applies the same charge transition rule directly; it is not freely writable RAM.
Examples¶
All 4 recorded rows of NORFlashRowTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: canonical-default-preview / structural (3f3be5125c460b70). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | D_0Input ยท 1 bit |
D_1Input ยท 1 bit |
ERASEInput ยท 1 bit |
PROGRAM_0Input ยท 1 bit |
PROGRAM_1Input ยท 1 bit |
WLInput ยท 1 bit |
Q_0Expected output ยท 1 bit |
Q_1Expected output ยท 1 bit |
|---|---|---|---|---|---|---|---|---|---|
#0erased | 1 | 0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
#1program-one-column | 3 | 0 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
#2release | 4 | 0 |
0 |
0 |
0 |
0 |
0 |
0 |
not checked |
#3erase-row | 6 | 0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
The two-column row starts erased, programs only column zero while preserving column one, releases programming, then erases both.
Embedded simulation¶
The standalone NORFlashRowTest opens this component as MEMORY_ROOT. Use the explorer to compare structural and behavioral implementations.
Open NORFlashRow<C> in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
NORFlashRowTest |
The complete standalone sequence shown above |
MemoryDeviceContractTest |
Structural/behavioral agreement at settled checkpoints, including mixed hierarchy selection |
3.1.5.3. NORFlashStorageBank<W>¶
Flash rows with shared read sensing and independent row erase lines.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
WL_r |
Input | 1 each | Read/program row selection, 0 โค r < N/K |
ERASE_r |
Input | 1 each | Erase every cell in row r |
DRIVE_c, DATA_c |
Input | 1 each | Column program controls/data |
COL_c |
Output | 1 each | Selected stored bits, 0 โค c < WรK |
Behavior¶
Exactly one binary WL selects a row for reading. Each cell programs only when its WL and column DRIVE are high. ERASE_r is independent of WL_r. Multiple selected rows invalidate sensed outputs but can still expose those rows to programming; the caller must supply legal controls. Block policy belongs to the device, not this bank.
C++ example¶
The whole bank composes the cell reference and the static read-column rule. It updates every program/erase input and publishes every column, including invalid row selection.
#include <vector>
#include <cstddef>
#include <optional>
struct FlashBankReference {
std::vector<std::vector<NORFlashCellReference>> rows;
std::vector<std::optional<bool>> columns;
FlashBankReference(std::size_t r, std::size_t c)
: rows(r, std::vector<NORFlashCellReference>(c)), columns(c) {}
void update(const std::vector<bool>& wl, const std::vector<bool>& erase,
const std::vector<bool>& drive,
const std::vector<std::optional<bool>>& data) {
for (std::size_t c = 0; c < columns.size(); ++c) {
unsigned count = 0;
columns[c].reset();
for (std::size_t r = 0; r < rows.size(); ++r) {
rows[r][c].update(wl.at(r), drive.at(c), erase.at(r), data.at(c));
if (wl[r]) { ++count; columns[c] = rows[r][c].q; }
}
if (count != 1) columns[c].reset();
}
}
};
Unknown inputs and timing¶
No selected row, conflicting selections, or unknown WL yields X on COL. Cell writes/erase retain their own conservative X/Z rules. Both bank fidelities retain scalar row/column pins and the 4,096-cell limit; large-capacity use belongs at device level.
Implementation¶
Structural implementation¶
ROW_r contains WรK flash cells. COLUMN_c is a StaticReadColumn shared across rows. Columns align under the same numbered cell in every row. Device control asserts ERASE_r for all rows in one block.
Behavioral implementation¶
Uses a bounded bit vector and startup flags, applying cell transitions before selecting the read columns. Read selection and storage mutation remain separate, matching the expanded bank.
Examples¶
All 7 recorded rows of NORFlashStorageBankTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: canonical-default-preview / structural (3f3be5125c460b70). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | DATA_0Input ยท 1 bit |
DATA_1Input ยท 1 bit |
DATA_10Input ยท 1 bit |
DATA_11Input ยท 1 bit |
DATA_12Input ยท 1 bit |
DATA_13Input ยท 1 bit |
DATA_14Input ยท 1 bit |
DATA_15Input ยท 1 bit |
DATA_2Input ยท 1 bit |
DATA_3Input ยท 1 bit |
DATA_4Input ยท 1 bit |
DATA_5Input ยท 1 bit |
DATA_6Input ยท 1 bit |
DATA_7Input ยท 1 bit |
DATA_8Input ยท 1 bit |
DATA_9Input ยท 1 bit |
DRIVE_0Input ยท 1 bit |
DRIVE_1Input ยท 1 bit |
DRIVE_10Input ยท 1 bit |
DRIVE_11Input ยท 1 bit |
DRIVE_12Input ยท 1 bit |
DRIVE_13Input ยท 1 bit |
DRIVE_14Input ยท 1 bit |
DRIVE_15Input ยท 1 bit |
DRIVE_2Input ยท 1 bit |
DRIVE_3Input ยท 1 bit |
DRIVE_4Input ยท 1 bit |
DRIVE_5Input ยท 1 bit |
DRIVE_6Input ยท 1 bit |
DRIVE_7Input ยท 1 bit |
DRIVE_8Input ยท 1 bit |
DRIVE_9Input ยท 1 bit |
ERASE_0Input ยท 1 bit |
ERASE_1Input ยท 1 bit |
WL_0Input ยท 1 bit |
WL_1Input ยท 1 bit |
COL_0Expected output ยท 1 bit |
COL_1Expected output ยท 1 bit |
COL_10Expected output ยท 1 bit |
COL_11Expected output ยท 1 bit |
COL_12Expected output ยท 1 bit |
COL_13Expected output ยท 1 bit |
COL_14Expected output ยท 1 bit |
COL_15Expected output ยท 1 bit |
COL_2Expected output ยท 1 bit |
COL_3Expected output ยท 1 bit |
COL_4Expected output ยท 1 bit |
COL_5Expected output ยท 1 bit |
COL_6Expected output ยท 1 bit |
COL_7Expected output ยท 1 bit |
COL_8Expected output ยท 1 bit |
COL_9Expected output ยท 1 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
#0deselected | 1 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
X |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#1read-erased-row | 3 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#2program-column-zero | 6 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#3release-driver | 7 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#4other-row-unmodified | 9 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#5erase-first-row | 11 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#6read-first-row-again | 12 | 0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
Reads an erased row, programs column zero, checks another row remains erased, erases the first row, and reads it again.
Embedded simulation¶
The standalone NORFlashStorageBankTest opens this component as MEMORY_ROOT. Use the explorer to compare structural and behavioral implementations.
Open NORFlashStorageBank<W> in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
NORFlashStorageBankTest |
The complete standalone sequence shown above |
MemoryDeviceContractTest |
Structural/behavioral agreement at settled checkpoints, including mixed hierarchy selection |
3.1.5.4. NORFlashCommandControl<W>¶
Write-enable latch, request capture, and program/erase sequencing.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
CLK |
Input | 1 | Strict 0โ1 command edge |
CMD |
Input | 3 | Device command code |
WORD_ADDR |
Input | 32 | Word address or address within erase block |
WRITE_DATA |
Input | W | Program payload |
WRITE_MASK |
Input | W/8 | Program byte enables |
BUSY, ERROR, READ_VALID, WRITE_ENABLED |
Output | 1 each | Device status |
ROW_ADDR, COLUMN_ADDR |
Output | 32 each | Latched address decomposed into row/slot |
DATA |
Output | W | Latched program data |
MASK |
Output | W/8 | Latched byte enables |
ROW_ENABLE, PROGRAM_ENABLE, OUTPUT_ENABLE |
Output | 1 each | Selection, program pulse, read publication |
ERASE_r |
Output | 1 each | Pulse for every row in the selected block |
Behavior¶
Implements the command table in NORFlash
C++ example¶
All binary commands and control outputs are represented. Geometry and positive timing parameters are prevalidated. Call on input changes and every due; valid drives both READ_VALID and OUTPUT_ENABLE, wel drives WRITE_ENABLED, and select drives ROW_ENABLE. There is no reset pin.
#include <cstdint>
#include <vector>
#include <optional>
template<std::size_t W> struct FlashControlReference {
struct Inputs {
bool clock = false;
unsigned cmd = 0;
std::uint32_t address = 0, data = 0;
unsigned mask = 0;
};
std::size_t depth, slots, block, ticks, program_ticks, erase_ticks, due = 0;
unsigned command = 0, stage = 0;
std::uint32_t address = 0;
bool busy = false, error = false, wel = false, valid = false;
bool program = false, erase = false, select = false;
std::optional<bool> previous_clock; // First observed high is not a 0->1 edge.
unsigned mask = 0;
std::vector<std::optional<bool>> data = std::vector<std::optional<bool>>(W);
FlashControlReference(std::size_t n, std::size_t k, std::size_t block_words,
std::size_t phase, std::size_t prog, std::size_t er)
: depth(n), slots(k), block(block_words), ticks(phase), program_ticks(prog), erase_ticks(er) {}
std::size_t row() const { return address / slots; }
std::size_t col() const { return address % slots; }
bool erase_row(std::size_t r) const {
return erase && (r * slots) / block == address / block;
}
void update(std::size_t now, const Inputs& in) {
if (due && now >= due) {
due = 0; ++stage;
if (command == 1) { valid = true; busy = false; }
else if (stage == 1) {
program = command == 2; erase = command == 3; due = now + ticks;
} else if (stage == 2) {
program = erase = select = false; due = now + ticks;
} else busy = false;
}
const bool edge = previous_clock == false && in.clock;
previous_clock = in.clock;
if (!edge || in.cmd == 0) return; // NOP holds WEL, error and read-valid.
if (busy) { error = true; return; } // Existing command still completes.
if (in.cmd > 5 || (in.cmd <= 3 && in.address >= depth) ||
((in.cmd == 2 || in.cmd == 3) && !wel)) {
error = true; valid = false; return;
}
error = valid = select = false;
if (in.cmd == 4 || in.cmd == 5) { wel = in.cmd == 4; return; }
command = in.cmd; stage = 0; address = in.address;
busy = true; select = command != 3;
if (command == 1) due = now + ticks;
else {
wel = false;
for (unsigned b = 0; b < W; ++b) data[b] = bool((in.data >> b) & 1u);
mask = in.mask;
due = now + (command == 2 ? program_ticks : erase_ticks);
}
}
};
Unknown inputs and timing¶
Only 0โ1 CLK is an edge. Unknown CMD is rejected; address must be binary for READ/PROGRAM/ERASE and mask must be binary for PROGRAM. Unknown data is permitted. NOP/WREN/WRDI ignore address/data/mask; ERASE ignores data/mask. Idle rejection invalidates old read data. Busy rejection sets ERROR without replacing the scheduled operation. Completion is processed before an edge at the same internal deadline.
Implementation¶
Structural implementation¶
Terminal digital FSM with write-enable state and timed pulses, not a gate-expanded sequencer. ERASE_r covers the rows whose words belong to WORD_ADDR / block_words. Because it exposes one erase pin per row, this standalone controller retains the expanded geometry limit. Compact complete devices use internal state without those pins.
Examples¶
All 41 recorded rows of NORFlashCommandControlTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: canonical-default-preview / structural (3f3be5125c460b70). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | CLKInput ยท 1 bit |
CMDInput ยท 3 bit |
WORD_ADDRInput ยท 32 bit |
WRITE_DATAInput ยท 8 bit |
WRITE_MASKInput ยท 1 bit |
BUSYExpected output ยท 1 bit |
COLUMN_ADDRExpected output ยท 32 bit |
DATAExpected output ยท 8 bit |
ERASE_0Expected output ยท 1 bit |
ERASE_1Expected output ยท 1 bit |
ERRORExpected output ยท 1 bit |
MASKExpected output ยท 1 bit |
OUTPUT_ENABLEExpected output ยท 1 bit |
PROGRAM_ENABLEExpected output ยท 1 bit |
READ_VALIDExpected output ยท 1 bit |
ROW_ADDRExpected output ยท 32 bit |
ROW_ENABLEExpected output ยท 1 bit |
WRITE_ENABLEDExpected output ยท 1 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
#0ready-erased | 1 | 0 |
0x0 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#1read-erased-setup | 2 | 0 |
0x1 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#2read-erased | 36 | 1 |
0x1 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked |
#3program-without-enable-setup | 37 | 0 |
0x2 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#4program-without-enable | 39 | 1 |
0x2 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#5write-enable-setup | 40 | 0 |
0x4 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#6write-enable | 42 | 1 |
0x4 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | 0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
#7program-word-setup | 43 | 0 |
0x2 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#8program-word | 237 | 1 |
0x2 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | 0 |
not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#9read-programmed-setup | 238 | 0 |
0x1 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#10read-programmed | 272 | 1 |
0x1 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked |
#11enable-again-setup | 273 | 0 |
0x4 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#12enable-again | 275 | 1 |
0x4 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#13cannot-program-zero-to-one-setup | 276 | 0 |
0x2 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#14cannot-program-zero-to-one | 470 | 1 |
0x2 |
0x00000000 |
0xFF |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#15read-unchanged-setup | 471 | 0 |
0x1 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#16read-unchanged | 505 | 1 |
0x1 |
0x00000000 |
0xFF |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked |
#17enable-other-block-setup | 506 | 0 |
0x4 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#18enable-other-block | 508 | 1 |
0x4 |
0x00000000 |
0xFF |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#19program-other-block-setup | 509 | 0 |
0x2 |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#20program-other-block | 703 | 1 |
0x2 |
0x00000002 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#21enable-erase-setup | 704 | 0 |
0x4 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#22enable-erase | 706 | 1 |
0x4 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#23erase-block-zero-setup | 707 | 0 |
0x3 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#24erase-block-zero | 1029 | 1 |
0x3 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#25read-erased-again-setup | 1030 | 0 |
0x1 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#26read-erased-again | 1064 | 1 |
0x1 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked |
#27other-block-survives-setup | 1065 | 0 |
0x1 |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#28other-block-survives | 1099 | 1 |
0x1 |
0x00000002 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked |
#29unknown-command-setup | 1100 | 0 |
0bXXX |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked |
#30unknown-command-rejected | 1102 | 1 |
0bXXX |
0x00000002 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | 1 |
not checked | 0 |
not checked | 0 |
not checked | not checked | not checked |
#31nop-preserves-error-setup | 1103 | 0 |
0x0 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#32nop-preserves-error | 1104 | 1 |
0x0 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | 0 |
not checked | not checked | not checked |
#33invalid-address-setup | 1105 | 0 |
0x1 |
0x00000004 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#34invalid-address | 1106 | 1 |
0x1 |
0x00000004 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#35reserved-command-setup | 1107 | 0 |
0x7 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#36reserved-command | 1108 | 1 |
0x7 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | 1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#37enable-then-disable-setup | 1109 | 0 |
0x4 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#38enable-then-disable | 1111 | 1 |
0x4 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#39write-disable-setup | 1112 | 0 |
0x5 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#40write-disable | 1114 | 1 |
0x5 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0 |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
The control example follows the full device command stream, checking write-enable, errors, read qualification, and completion. It includes unknown-command rejection and NOP error preservation.
Embedded simulation¶
The standalone NORFlashCommandControlTest opens this component as MEMORY_ROOT. This component has one registered structural implementation.
Open NORFlashCommandControl<W> in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
NORFlashCommandControlTest |
The complete standalone sequence shown above |
MemoryDeviceTimingTest |
Intermediate BUSY, busy-command rejection, and latched program payload in both complete-device fidelities |
3.1.5.5. NORFlash<W>¶
Complete word-read/program, block-erase NOR-style device.
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
CLK |
Input | 1 | Strict 0โ1 command edge |
CMD |
Input | 3 | Command code below |
WORD_ADDR |
Input | 32 | Word address or word inside an erase block |
WRITE_DATA |
Input | W | Program payload |
WRITE_MASK |
Input | W/8 | Enabled program bytes |
BUSY |
Output | 1 | Read/program/erase in progress |
ERROR |
Output | 1 | Rejected request; next accepted non-NOP clears it |
WRITE_ENABLED |
Output | 1 | Current write-enable latch |
READ_VALID |
Output | 1 | Completed read available |
READ_DATA |
Output | W | Valid word, otherwise Z |
Behavior¶
Reads are word-addressed. Programming only clears bits within enabled bytes. Erase resets every word in the containing B-word block; an aligned block-base address is not required.
Commands and timing¶
| CMD | Operation | Preconditions / effect | Sequencer completion |
|---|---|---|---|
| 0 | NOP | Ignore other inputs; preserve status | None |
| 1 | READ | Valid word address | P ticks |
| 2 | PROGRAM | Valid address, WEL=1, binary mask; consume WEL | program_ticks + 2P |
| 3 | ERASE | Valid address, WEL=1; consume WEL; erase containing B-word block | erase_ticks + 2P |
| 4 | WREN | Set WEL; address/data/mask ignored | Accepted edge |
| 5 | WRDI | Clear WEL; address/data/mask ignored | Accepted edge |
| 6โ7 | Reserved | Reject | ERROR |
Program/erase wait their configured delay, assert the corresponding pulse for P ticks, then release it and wait P more ticks before clearing BUSY. Read waits P. Output wire propagation and structural gate settling add to sequencer deadlines. These are model ticks, not chip performance claims.
Requests are latched at acceptance. Non-NOP commands while BUSY are rejected; they neither cancel nor replace the active operation. WREN is required again after every accepted PROGRAM or ERASE, including a zero-mask program. A rejected command does not consume WEL. NOP preserves status; an accepted non-NOP clears the previous ERROR and read-valid state. A read remains valid until superseded or invalidated. Initial unknown clock followed by high does not count as a rising edge.
C++ example¶
The native device composes the bank and command control above. W is 8/16/32; capacity, row width, erase-block size, and timing are construction parameters. This includes reads, WREN/WRDI, errors, zero masks, delayed program/erase, and stable state while busyโnot merely the final array mutation.
#include <cstdint>
#include <vector>
template<std::size_t W> struct FlashReference {
static_assert(W == 8 || W == 16 || W == 32);
FlashControlReference<W> control;
FlashBankReference bank;
bool high_z = true;
std::vector<std::optional<bool>> read_data = std::vector<std::optional<bool>>(W);
FlashReference(std::size_t words, std::size_t slots, std::size_t block,
std::size_t ticks, std::size_t program, std::size_t erase)
: control(words, slots, block, ticks, program, erase), bank(words / slots, W * slots) {}
void update(std::size_t now, const typename FlashControlReference<W>::Inputs& in) {
control.update(now, in);
std::vector<bool> wl(bank.rows.size(), false), erase(bank.rows.size());
std::vector<bool> drive(bank.columns.size());
std::vector<std::optional<bool>> data(bank.columns.size());
if (control.select) wl[control.row()] = true;
for (std::size_t r = 0; r < erase.size(); ++r) erase[r] = control.erase_row(r);
for (std::size_t c = 0; c < drive.size(); ++c) {
data[c] = control.data[c % W];
drive[c] = control.program && c / W == control.col() &&
(control.mask & (1u << ((c % W) / 8)));
}
bank.update(wl, erase, drive, data);
high_z = !control.valid;
for (std::size_t b = 0; b < W; ++b)
read_data[b] = high_z ? std::nullopt : bank.columns[control.col() * W + b];
}
// BUSY / ERROR / READ_VALID / WRITE_ENABLED = control.busy / error / valid / wel.
// Next scheduled phase: control.due (0 means none).
};
Unknown inputs and timing¶
Command validation follows NORFlashCommandControl. Enabled program data bits may become X; an already-zero bit remains zero. Masked-off bytes ignore data, including X/Z. NOP preserves status; unknown idle commands invalidate previous read-valid like reserved codes. Wait for BUSY and propagation to settle. Timing parameters are abstract simulator units, not manufacturer performance figures.
Implementation¶
Structural implementation¶
COMMAND_CONTROL drives ROW_DECODE, write pulses, and per-row erase. STORAGE exposes the cell matrix and shared read columns. COLUMN_SELECT reads one word; WRITE_DRIVERS qualifies program bits; OUTPUT releases READ_DATA when invalid. All rows of the selected erase block receive the erase pulse.
Behavioral implementation¶
Uses initially erased packed MemoryStorage and the same command sequencer, with a separately implemented storage data path. Program applies four-state AND within enabled bytes; erase writes ones one word at a time to bound temporary allocation. Read-only inspector history can be disabled for scale; debug loading cannot bypass WREN/PROGRAM/ERASE.
Examples¶
All 41 recorded rows of NORFlashTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.
Default scenario profile: canonical-default-preview / structural (3f3be5125c460b70). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | CLKInput ยท 1 bit |
CMDInput ยท 3 bit |
WORD_ADDRInput ยท 32 bit |
WRITE_DATAInput ยท 8 bit |
WRITE_MASKInput ยท 1 bit |
BUSYExpected output ยท 1 bit |
ERRORExpected output ยท 1 bit |
READ_DATAExpected output ยท 8 bit |
READ_VALIDExpected output ยท 1 bit |
WRITE_ENABLEDExpected output ยท 1 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|
#0ready-erased | 11 | 0 |
0x0 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | 0 |
#1read-erased-setup | 12 | 0 |
0x1 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#2read-erased | 47 | 1 |
0x1 |
0x00000000 |
0x81 |
1 |
0 |
not checked | 0xFF |
1 |
not checked |
#3program-without-enable-setup | 48 | 0 |
0x2 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#4program-without-enable | 51 | 1 |
0x2 |
0x00000000 |
0x81 |
1 |
0 |
1 |
not checked | not checked | not checked |
#5write-enable-setup | 52 | 0 |
0x4 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#6write-enable | 59 | 1 |
0x4 |
0x00000000 |
0x81 |
1 |
0 |
0 |
not checked | not checked | 1 |
#7program-word-setup | 60 | 0 |
0x2 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#8program-word | 254 | 1 |
0x2 |
0x00000000 |
0x81 |
1 |
0 |
0 |
not checked | not checked | 0 |
#9read-programmed-setup | 255 | 0 |
0x1 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#10read-programmed | 290 | 1 |
0x1 |
0x00000000 |
0x81 |
1 |
0 |
not checked | 0x81 |
1 |
not checked |
#11enable-again-setup | 291 | 0 |
0x4 |
0x00000000 |
0x81 |
1 |
not checked | not checked | not checked | not checked | not checked |
#12enable-again | 298 | 1 |
0x4 |
0x00000000 |
0x81 |
1 |
0 |
not checked | not checked | not checked | not checked |
#13cannot-program-zero-to-one-setup | 299 | 0 |
0x2 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked |
#14cannot-program-zero-to-one | 493 | 1 |
0x2 |
0x00000000 |
0xFF |
1 |
0 |
not checked | not checked | not checked | not checked |
#15read-unchanged-setup | 494 | 0 |
0x1 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked |
#16read-unchanged | 529 | 1 |
0x1 |
0x00000000 |
0xFF |
1 |
0 |
not checked | 0x81 |
1 |
not checked |
#17enable-other-block-setup | 530 | 0 |
0x4 |
0x00000000 |
0xFF |
1 |
not checked | not checked | not checked | not checked | not checked |
#18enable-other-block | 537 | 1 |
0x4 |
0x00000000 |
0xFF |
1 |
0 |
not checked | not checked | not checked | not checked |
#19program-other-block-setup | 538 | 0 |
0x2 |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#20program-other-block | 732 | 1 |
0x2 |
0x00000002 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked |
#21enable-erase-setup | 733 | 0 |
0x4 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#22enable-erase | 735 | 1 |
0x4 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked |
#23erase-block-zero-setup | 736 | 0 |
0x3 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#24erase-block-zero | 1058 | 1 |
0x3 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | 0 |
#25read-erased-again-setup | 1059 | 0 |
0x1 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#26read-erased-again | 1094 | 1 |
0x1 |
0x00000000 |
0x78 |
1 |
0 |
not checked | 0xFF |
1 |
not checked |
#27other-block-survives-setup | 1095 | 0 |
0x1 |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#28other-block-survives | 1130 | 1 |
0x1 |
0x00000002 |
0x78 |
1 |
0 |
not checked | 0x78 |
1 |
not checked |
#29unknown-command-setup | 1131 | 0 |
0bXXX |
0x00000002 |
0x78 |
1 |
not checked | not checked | not checked | 1 |
not checked |
#30unknown-command-rejected | 1134 | 1 |
0bXXX |
0x00000002 |
0x78 |
1 |
0 |
1 |
0bZZZZZZZZ |
0 |
not checked |
#31nop-preserves-error-setup | 1135 | 0 |
0x0 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#32nop-preserves-error | 1136 | 1 |
0x0 |
0x00000000 |
0x78 |
1 |
0 |
1 |
not checked | 0 |
not checked |
#33invalid-address-setup | 1137 | 0 |
0x1 |
0x00000004 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#34invalid-address | 1138 | 1 |
0x1 |
0x00000004 |
0x78 |
1 |
0 |
1 |
not checked | not checked | not checked |
#35reserved-command-setup | 1139 | 0 |
0x7 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#36reserved-command | 1140 | 1 |
0x7 |
0x00000000 |
0x78 |
1 |
0 |
1 |
not checked | not checked | not checked |
#37enable-then-disable-setup | 1141 | 0 |
0x4 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#38enable-then-disable | 1148 | 1 |
0x4 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | not checked |
#39write-disable-setup | 1149 | 0 |
0x5 |
0x00000000 |
0x78 |
1 |
not checked | not checked | not checked | not checked | not checked |
#40write-disable | 1151 | 1 |
0x5 |
0x00000000 |
0x78 |
1 |
0 |
not checked | not checked | not checked | 0 |
Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.
Rejects programming without WREN, programs 0x81, confirms programming 0xFF cannot restore cleared bits, programs 0x78 in another block, then erases the first block while preserving the second. Also checks invalid/unknown/reserved commands, NOP status preservation, and WRDI.
Embedded simulation¶
The standalone NORFlashTest opens this component as MEMORY_ROOT. Use the explorer to compare structural and behavioral implementations.
Open NORFlash<W> in the simulator
Source and tests¶
| Test | Coverage |
|---|---|
NORFlashTest |
The complete standalone sequence shown above |
MemoryDeviceContractTest |
Width/geometry and mixed-fidelity checks, seeded byte-mask/program oracle, readonly history, allocation limits |
MemoryDeviceTimingTest |
Early BUSY, in-flight command rejection, latched data, and finite event queues |
MemoryDeviceDocumentationTest |
Compile the exact references; test W=8/16/32, masks, WREN/WRDI, delayed program/erase, block isolation, conflicts and completion edges; replay native command/device binary-input prefixes |