A cycle-accurate, single-SM SIMT GPU core simulator in C++17. It models warps
executing in lockstep over per-lane registers, an immediate-post-dominator
reconvergence stack for branch divergence, a per-warp scoreboard with
round-robin multi-warp scheduling that hides memory latency by interleaving,
CTA barriers, a global-memory coalescer, and banked shared memory with
conflict replay. The ISA is a small integer-only SIMT instruction set: twelve
fixed-width 32-bit opcodes, 16 registers per lane, and ctaid/ntid/tid
preloaded at launch. Every structural parameter — warp size, resident warps,
banking, coalescing line, latency, memory bandwidth — is a runtime Config
field, so no recompilation is needed to explore the design space.
types.h— fixed-width datapath types, opcode/function enums, and theMasktype that gates every per-lane operation.config.h— theConfigstruct: one field per structural knob, with validation.isa.h— the 32-bit instruction encoding, field layout, and encoders.decoder.h/decoder.cpp— decode of one instruction word into aDecodedstruct (including the branch's reconvergence point), plus a disassembler.alu.h— the per-lane functional model: integer ops and signed compares, free of warp, mask, or timing concerns.memory.h— untimed global-memory storage and the trap type both memories share. Storage says which bytes move; cost lives in the cost models, so a wrong cost can never corrupt a result.shared_memory.h— the CTA-private scratchpad and its bank model: one word per bank per cycle, conflicts serialize into replays, same-word reads broadcast.coalescer.h— folds a warp's per-lane addresses into aligned cache-line transactions; the number of distinct lines is the cost of the access.simt_stack.h— the per-warp immediate-post-dominator reconvergence stack that splits a warp at a divergent branch and reunites it at the join point, with a checked mask-nesting invariant.scoreboard.h— the per-warp scoreboard: one bit per register for writes in flight. No cross-warp state, so independent warps never falsely stall each other.sm.h/sm.cpp— the cycle-accurate core: fetch, decode, issue, execute, and writeback evaluated in reverse pipeline order, round-robin issue over resident warps, CTA barriers, and the memory pipe as a structural hazard at issue.stats.h/stats.cpp— statistics and the report: occupancy, lane utilization, coalescing efficiency, shared-memory replays, and a stall-cause breakdown that accounts for every cycle.main.cpp— the CLI driver: loads a kernel and input, runs a grid, prints the report, and offers--disasm,--trace,--dump, and an occupancy--sweep.
Correctness rests on differential testing. tests/ref.h is a cooperative
scalar reference model — a per-thread interpreter with no warps, no masks,
and no timing, which round-robins threads at barriers so barrier-using
kernels are interpretable. Every kernel in the bundled corpus
(tests/kernels.h) runs on both the reference and the cycle-accurate SM
across a sweep of configurations, and the two are compared on final global
memory, shared memory at each barrier, and retired lane-instruction count.
Kernels are built in-process by the header-only assembler in
tests/gpuasm.h, which computes each branch's reconvergence point from its
structured control-flow helpers. tests/test_main.cpp holds the whole
suite: unit tests of each component, the differential passes, targeted
microarchitectural property assertions (divergence cost, transaction counts,
replay counts, the occupancy roofline), and pinned performance figures.
tools/gen_examples.cpp emits the bundled kernel corpus into examples/:
a .hex of instruction words per kernel, input data where needed, and a
.md recording the launch geometry each kernel expects. The kernels are the
same definitions the test suite runs, so the examples cannot drift from the
tested versions.
make # build build/minigpu
make test # regenerate examples/ and run the test suite
make debug # run the suite under ASan + UBSan
make clean # remove build/ and examples/Run a generated example:
./build/minigpu --prog examples/vecadd.hex --in examples/vecadd.in.hex \
--grid 4 --block 32 --warp-size 8 --warps 4See ./build/minigpu --help for the full CLI: kernel and buffer loading,
launch geometry, output options, and a flag for every Config field.