8f67e34675
If only for consistency with DISK_GEOMETRY. The main reason to keep BENCH_PERBYTE around is to help debug/sanity check the more complex bus+buffer sim. For that purpose it makes sense to be able to easily switch modes. The only downside is if it's more difficult to introduce -DDISK_SIM=1 at runtime vs compile-time, but eh. Consistency wins.
207 lines
9.7 KiB
C
207 lines
9.7 KiB
C
// littlefs bench runner defines
|
|
|
|
|
|
#ifdef BENCH_INCLUDE
|
|
// DISK_GEOMETRY controls which simulation we use
|
|
// 0 => NOR flash (the default)
|
|
// 1 => NAND flash
|
|
#define DISK_MAP(define) \
|
|
((DISK_GEOMETRY == 0) ? NOR_##define \
|
|
: NAND_##define)
|
|
#endif
|
|
|
|
// preconfigured defines that control how benches run
|
|
#ifdef BENCH_DEFINE
|
|
// name value (overridable)
|
|
BENCH_DEFINE(DISK_SIZE, 128*1024*1024 )
|
|
BENCH_DEFINE(DISK_GEOMETRY, 0 )
|
|
// simulation mode
|
|
// 0 => full bus+buffer sim
|
|
// 1 => simple per-byte sim
|
|
BENCH_DEFINE(DISK_SIM, 0 )
|
|
BENCH_DEFINE(READ_SIZE, DISK_MAP(READ_SIZE) )
|
|
BENCH_DEFINE(PROG_SIZE, DISK_MAP(PROG_SIZE) )
|
|
BENCH_DEFINE(ERASE_SIZE, DISK_MAP(ERASE_SIZE) )
|
|
BENCH_DEFINE(BLOCK_SIZE, LFS3_MAX(ERASE_SIZE, 512) )
|
|
BENCH_DEFINE(BLOCK_COUNT, DISK_SIZE/LFS3_MAX(BLOCK_SIZE, 1) )
|
|
BENCH_DEFINE(BLOCK_RECYCLES, 100 )
|
|
BENCH_DEFINE(RCACHE_SIZE, LFS3_MAX(16, READ_SIZE) )
|
|
BENCH_DEFINE(PCACHE_SIZE, LFS3_MAX(16, PROG_SIZE) )
|
|
BENCH_DEFINE(FCACHE_SIZE, 16 )
|
|
BENCH_DEFINE(LOOKAHEAD_SIZE, 16 )
|
|
BENCH_DEFINE(GC_FLAGS, LFS3_GC_GC )
|
|
BENCH_DEFINE(GC_STEPS, 0 )
|
|
BENCH_DEFINE(GC_LOOKAHEAD_THRESH, -1 )
|
|
BENCH_DEFINE(GC_LOOKGBMAP_THRESH, -1 )
|
|
BENCH_DEFINE(GC_PREERASE_COUNT, -1 )
|
|
BENCH_DEFINE(GC_COMPACT_THRESH, 0 )
|
|
BENCH_DEFINE(SHRUB_SIZE, BLOCK_SIZE/4 )
|
|
BENCH_DEFINE(FRAGMENT_SIZE, LFS3_MIN(BLOCK_SIZE/16, 512) )
|
|
BENCH_DEFINE(CRYSTAL_THRESH, BLOCK_SIZE/16 )
|
|
BENCH_DEFINE(LOOKGBMAP_THRESH, BLOCK_COUNT/4 )
|
|
// don't bother simulating erases, this may be less realistic, but
|
|
// it's certainly faster!
|
|
BENCH_DEFINE(ERASE_VALUE, -1 )
|
|
BENCH_DEFINE(READ_WIDTH, DISK_MAP(READ_WIDTH) )
|
|
BENCH_DEFINE(PROG_WIDTH, DISK_MAP(PROG_WIDTH) )
|
|
BENCH_DEFINE(ERASE_WIDTH, DISK_MAP(ERASE_WIDTH) )
|
|
BENCH_DEFINE(READ_TIMING, DISK_MAP(READ_TIMING) )
|
|
BENCH_DEFINE(PROG_TIMING, DISK_MAP(PROG_TIMING) )
|
|
BENCH_DEFINE(ERASE_TIMING, DISK_MAP(ERASE_TIMING) )
|
|
BENCH_DEFINE(READED_TIMING, DISK_MAP(READED_TIMING) )
|
|
BENCH_DEFINE(PROGGED_TIMING, DISK_MAP(PROGGED_TIMING) )
|
|
BENCH_DEFINE(ERASED_TIMING, DISK_MAP(ERASED_TIMING) )
|
|
|
|
// NOR flash (DISK_GEOMETRY=0)
|
|
//
|
|
// based on w25q64jv:
|
|
// https://www.winbond.com/resource-files/
|
|
// W25Q64JV%20RevM%2012242024%20Plus.pdf
|
|
//
|
|
// note one thing unique to NOR flash is the extreme erase cost
|
|
//
|
|
// FR=104 MHz, quad prog (9.6 ns * 8/4)
|
|
// => +~19 ns for bus (not read!)
|
|
//
|
|
// simple per-byte sim:
|
|
// readed=40ns/B fR=50 MHz, quad read (20 ns * 8/4)
|
|
// progged=1582ns/B tPP=0.4 ms, page=256 (0.4 ms / 256 + bus)
|
|
// erased=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096)
|
|
//
|
|
// less-simple bus+buffer sim:
|
|
// read=0ns/B (no transaction cost)
|
|
// prog=1563ns/B tPP=0.4 ms, page=256 (0.4 ms / 256)
|
|
// erase=10986ns/B tSE=45 ms, sector=4096 (45 ms / 4096)
|
|
// readed=40ns/B fR=50 MHz, quad read (20 ns * 8/4)
|
|
// progged=19ns/B (bus)
|
|
// erased=0ns/B (no bus cost)
|
|
//
|
|
BENCH_DEFINE(NOR_READ_SIZE, 1 )
|
|
BENCH_DEFINE(NOR_PROG_SIZE, 1 )
|
|
BENCH_DEFINE(NOR_ERASE_SIZE, 4096 )
|
|
BENCH_DEFINE(NOR_READ_WIDTH, 1 )
|
|
BENCH_DEFINE(NOR_PROG_WIDTH, LFS3_MIN(256, BLOCK_SIZE) )
|
|
BENCH_DEFINE(NOR_ERASE_WIDTH, BLOCK_SIZE )
|
|
BENCH_DEFINE(NOR_READ_TIMING, (DISK_SIM == 0) ? 0 : 0 )
|
|
BENCH_DEFINE(NOR_PROG_TIMING, (DISK_SIM == 0) ? 1563 : 0 )
|
|
BENCH_DEFINE(NOR_ERASE_TIMING, (DISK_SIM == 0) ? 10986 : 0 )
|
|
BENCH_DEFINE(NOR_READED_TIMING, (DISK_SIM == 0) ? 40 : 40 )
|
|
BENCH_DEFINE(NOR_PROGGED_TIMING, (DISK_SIM == 0) ? 19 : 1582 )
|
|
BENCH_DEFINE(NOR_ERASED_TIMING, (DISK_SIM == 0) ? 0 : 10986 )
|
|
|
|
// NAND flash (DISK_GEOMETRY=1)
|
|
//
|
|
// based on w25n01gv:
|
|
// https://www.winbond.com/resource-files/W25N01GV%20Rev%20R%20070323.pdf
|
|
//
|
|
// FR=104 MHz, quad read/prog (9.6 ns * 8/4)
|
|
// => +~19 ns for bus
|
|
//
|
|
// simple per-byte sim:
|
|
// readed=31ns/B tRD1=25 us, p=2048, s=512 (25 us / 2048 + bus)
|
|
// progged=141ns/B tPP=250 us, p=2048, s=512 (250 us / 2048 + bus)
|
|
// erased=15ns/B tBE=2 ms, block=131072 (2 ms / 131072)
|
|
//
|
|
// less-simple bus+buffer sim:
|
|
// read=12ns/B tRD1=25 us, p=2048, s=512 (25 us / 2048)
|
|
// prog=122ns/B tPP=250 us, p=2048, s=512 (250 us / 2048)
|
|
// erase=15ns/B tBE=2 ms, block=131072 (2 ms / 131072)
|
|
// readed=19ns/B (bus)
|
|
// progged=19ns/B (bus)
|
|
// erased=0ns/B (no bus cost)
|
|
//
|
|
BENCH_DEFINE(NAND_READ_SIZE, 1 )
|
|
BENCH_DEFINE(NAND_PROG_SIZE, 512 )
|
|
BENCH_DEFINE(NAND_ERASE_SIZE, 131072 )
|
|
BENCH_DEFINE(NAND_READ_WIDTH, LFS3_MIN(2048, BLOCK_SIZE) )
|
|
BENCH_DEFINE(NAND_PROG_WIDTH, LFS3_MIN(2048, BLOCK_SIZE) )
|
|
BENCH_DEFINE(NAND_ERASE_WIDTH, BLOCK_SIZE )
|
|
BENCH_DEFINE(NAND_READ_TIMING, (DISK_SIM == 0) ? 12 : 0 )
|
|
BENCH_DEFINE(NAND_PROG_TIMING, (DISK_SIM == 0) ? 122 : 0 )
|
|
BENCH_DEFINE(NAND_ERASE_TIMING, (DISK_SIM == 0) ? 15 : 0 )
|
|
BENCH_DEFINE(NAND_READED_TIMING, (DISK_SIM == 0) ? 19 : 31 )
|
|
BENCH_DEFINE(NAND_PROGGED_TIMING, (DISK_SIM == 0) ? 19 : 141 )
|
|
BENCH_DEFINE(NAND_ERASED_TIMING, (DISK_SIM == 0) ? 0 : 15 )
|
|
#endif
|
|
|
|
|
|
// struct lfs3_cfg definition
|
|
#ifdef BENCH_CFG
|
|
struct lfs3_cfg _cfg = {
|
|
#ifdef BENCH_CFG_CFG
|
|
BENCH_CFG_CFG
|
|
#endif
|
|
.read_size = READ_SIZE,
|
|
.prog_size = PROG_SIZE,
|
|
.block_size = BLOCK_SIZE,
|
|
.block_count = BLOCK_COUNT,
|
|
.block_recycles = BLOCK_RECYCLES,
|
|
.rcache_size = RCACHE_SIZE,
|
|
.pcache_size = PCACHE_SIZE,
|
|
.fcache_size = FCACHE_SIZE,
|
|
.lookahead_size = LOOKAHEAD_SIZE,
|
|
#ifdef LFS3_GBMAP
|
|
.gc_lookgbmap_thresh = GC_LOOKGBMAP_THRESH,
|
|
.lookgbmap_thresh = LOOKGBMAP_THRESH,
|
|
#endif
|
|
#ifdef LFS3_PREERASE
|
|
.gc_preerase_count = GC_PREERASE_COUNT,
|
|
#endif
|
|
#ifdef LFS3_GC
|
|
.gc_flags = GC_FLAGS,
|
|
.gc_steps = GC_STEPS,
|
|
#endif
|
|
.gc_lookahead_thresh = GC_LOOKAHEAD_THRESH,
|
|
.gc_compact_thresh = GC_COMPACT_THRESH,
|
|
.shrub_size = SHRUB_SIZE,
|
|
.fragment_size = FRAGMENT_SIZE,
|
|
.crystal_thresh = CRYSTAL_THRESH,
|
|
};
|
|
struct lfs3_cfg *BENCH_CFG = &_cfg;
|
|
#endif
|
|
|
|
|
|
// struct lfs3_*bd_cfg definition
|
|
#ifdef BENCH_BDCFG
|
|
#ifndef BENCH_KIWIBD
|
|
struct lfs3_emubd_cfg _bdcfg = {
|
|
#ifdef BENCH_BDCFG_CFG
|
|
BENCH_BDCFG_CFG
|
|
#endif
|
|
.erase_value = ERASE_VALUE,
|
|
.read_width = READ_WIDTH,
|
|
.prog_width = PROG_WIDTH,
|
|
.erase_width = ERASE_WIDTH,
|
|
.read_timing = READ_TIMING,
|
|
.prog_timing = PROG_TIMING,
|
|
.erase_timing = ERASE_TIMING,
|
|
.readed_timing = READED_TIMING,
|
|
.progged_timing = PROGGED_TIMING,
|
|
.erased_timing = ERASED_TIMING,
|
|
.erase_cycles = ERASE_CYCLES,
|
|
.badblock_behavior = BADBLOCK_BEHAVIOR,
|
|
.powerloss_behavior = POWERLOSS_BEHAVIOR,
|
|
.seed = BD_SEED,
|
|
};
|
|
struct lfs3_emubd_cfg *BENCH_BDCFG = &_bdcfg;
|
|
#else
|
|
struct lfs3_kiwibd_cfg _bdcfg = {
|
|
#ifdef BENCH_BDCFG_CFG
|
|
BENCH_BDCFG_CFG
|
|
#endif
|
|
.erase_value = ERASE_VALUE,
|
|
.read_width = READ_WIDTH,
|
|
.prog_width = PROG_WIDTH,
|
|
.erase_width = ERASE_WIDTH,
|
|
.read_timing = READ_TIMING,
|
|
.prog_timing = PROG_TIMING,
|
|
.erase_timing = ERASE_TIMING,
|
|
.readed_timing = READED_TIMING,
|
|
.progged_timing = PROGGED_TIMING,
|
|
.erased_timing = ERASED_TIMING,
|
|
};
|
|
struct lfs3_kiwibd_cfg *BENCH_BDCFG = &_bdcfg;
|
|
#endif
|
|
#endif
|
|
|