Skip to content

emulator: select the HBM generation and channel count from settings - #119

Open
Shreyas8612 wants to merge 1 commit into
mainfrom
feat/hbm-generation-and-channel-settings
Open

Shreyas8612 wants to merge 1 commit into
mainfrom
feat/hbm-generation-and-channel-settings

Conversation

@Shreyas8612

Copy link
Copy Markdown
Collaborator

The Ramulator model was hard-coded to hbm2_preset(8) in runner.rs, so
neither the HBM generation nor the channel count could be changed
without rebuilding, and the ramulator crate had no HBM3 device model.

Add TRANSACTIONAL.CONFIG.HBM_GEN ("hbm2" | "hbm3") and HBM_CHANNELS to
plena_settings.toml with --hbm-gen / --hbm-channels CLI overrides, and
have the runner pick the preset from them. Both keys are optional and
default to hbm2 / 8, so existing settings files and runs are unchanged.

Add Ramulator::hbm3_preset, backed by a new config/hbm3.rs that
reproduces ramulator 2.1's data-driven HBM3 spec (JESD238 HBM3_8Gb_8hi
organisation at the 6.4 Gb/s speed bin, half-CK ticks, dual command
bus) exactly as upstream's Python generator serialises it, on the HBM34
controller. Expose the channel count on the model wrapper so presets
can be checked, and document the settings in the emulator readme.

Verified with cargo fmt, cargo clippy --workspace --all-targets
-D warnings and cargo test --workspace: the HBM3 config matches the
upstream generator's output for the same presets, hbm3_preset(16)
builds with 16 channels at a 312 ps tick and 32-byte transfers,
hbm2_preset(8) keeps its shape, and the settings default/override
resolution is pinned. The ATen linear testbench passes on the default
path and produces identical results with --hbm-gen hbm3.

The Ramulator model was hard-coded to `hbm2_preset(8)` in runner.rs, so
neither the HBM generation nor the channel count could be changed
without rebuilding, and the ramulator crate had no HBM3 device model.

Add TRANSACTIONAL.CONFIG.HBM_GEN ("hbm2" | "hbm3") and HBM_CHANNELS to
plena_settings.toml with --hbm-gen / --hbm-channels CLI overrides, and
have the runner pick the preset from them. Both keys are optional and
default to hbm2 / 8, so existing settings files and runs are unchanged.

Add `Ramulator::hbm3_preset`, backed by a new config/hbm3.rs that
reproduces ramulator 2.1's data-driven HBM3 spec (JESD238 HBM3_8Gb_8hi
organisation at the 6.4 Gb/s speed bin, half-CK ticks, dual command
bus) exactly as upstream's Python generator serialises it, on the HBM34
controller. Expose the channel count on the model wrapper so presets
can be checked, and document the settings in the emulator readme.

Verified with cargo fmt, cargo clippy --workspace --all-targets
-D warnings and cargo test --workspace: the HBM3 config matches the
upstream generator's output for the same presets, hbm3_preset(16)
builds with 16 channels at a 312 ps tick and 32-byte transfers,
hbm2_preset(8) keeps its shape, and the settings default/override
resolution is pinned. The ATen linear testbench passes on the default
path and produces identical results with --hbm-gen hbm3.
Copilot AI lite review requested due to automatic review settings September 17, 2026 01:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

CLI overrides use eager unwrap_or fallbacks, so invalid settings can still panic before the override is applied.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds configurable HBM generation and channel count selection, including a new Ramulator HBM3 model and CLI/settings integration.

Changes:

  • Adds HBM_GEN and HBM_CHANNELS settings with CLI overrides.
  • Implements and tests the HBM3 Ramulator preset.
  • Documents the new configuration options.
File summaries
File Description
transactional_emulator/src/runtime_config.rs Exposes HBM settings at runtime.
transactional_emulator/src/runner.rs Resolves settings and selects the Ramulator preset.
transactional_emulator/src/load_config.rs Parses, defaults, and validates HBM settings.
transactional_emulator/src/cli.rs Adds HBM CLI overrides.
transactional_emulator/readme.md Documents HBM configuration.
transactional_emulator/lib/ramulator/src/raw.rs Adds HBM3 controller and transfer metadata.
transactional_emulator/lib/ramulator/src/preset.rs Adds HBM3 and preserves HBM2 presets.
transactional_emulator/lib/ramulator/src/model.rs Exposes channel count.
transactional_emulator/lib/ramulator/src/config/hbm3.rs Defines the HBM3 device specification.
transactional_emulator/lib/ramulator/src/config.rs Registers HBM3 configuration types.
README.md Updates configuration overview.
plena_settings.toml Adds default HBM settings.
Review details

Suppressed comments (1)

transactional_emulator/src/runner.rs:43

  • Option::unwrap_or eagerly evaluates *HBM_GEN, so --hbm-gen hbm3 still parses the settings value before using the CLI value. An invalid HBM_GEN in the settings file will panic instead of being overridden, so use a lazy fallback here as well.
    (cli_gen.unwrap_or(*HBM_GEN), channels)
  • Files reviewed: 12/12 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

/// Resolve the Ramulator HBM geometry: `--hbm-gen` / `--hbm-channels` win
/// over `HBM_GEN` / `HBM_CHANNELS` from plena_settings.toml.
fn resolve_hbm_model(cli_gen: Option<HbmGen>, cli_channels: Option<usize>) -> (HbmGen, usize) {
let channels = cli_channels.unwrap_or(*HBM_CHANNELS);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, could you clarify why we need a separate config/hbm3.rs instead of using Ramulator 2.1’s upstream HBM3 model/configuration directly?

Also, have you done any cross-validation experiments on your model? We verified the HBM2E model with our V80 FPGA board.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a separate config/hbm3.rs

It is upstream's HBM3 model: the C++ device (src/ramulator/dram/impl/HBM3.cpp) is used unchanged. What the file supplies is the device configuration. Since ramulator 2.1 the C++ devices are generated from Python (HBM3.cpp is marked auto-generated from python/ramulator/dram/hbm3.py) and no longer carry presets: DRAMSpec::load_config reads the organisation counts, timing values, timing-constraint list, read_latency and command_cycles from the config, which upstream normally produces with its Python package. Our pkgs/ramulator2 builds with the Python bindings off and the emulator passes only a config string through the C API, so, like config/hbm2.rs and config/ddr4.rs from #102, the presets and constraint table have to be rendered on our side.

To check it is a faithful port, I generated the config with upstream's own Python at the commit pkgs/ramulator2 pins (b3efdc5), for the same presets (HBM3_8Gb_8hi, HBM3_6400Mbps), and compared it with what hbm3.rs serialises:

Field Result
organisation (dq, level counts) identical
timing values (29) identical
timing constraints identical, 52 of 52, same order
read_latency, channel_width, command_cycles identical

If you'd rather not maintain Rust ports, the alternative is to generate these tables from upstream's Python inside the nix derivation (or check in the generated JSON). Happy to switch to that.

Side note from the same check: as a control I ran the comparison on main's hbm2.rs, and it does not match the pinned upstream generator. Upstream treats ACT as a 2-cycle command, so it adds a 2-cycle command-bus occupancy after ACT and shifts 16 ACT-adjacent constraints by one cycle (e.g. bank ACT→RD 15 vs 14, PRE→ACT 13 vs 14). Since that's the model you validated on the V80 I haven't touched it; just flagging it in case the V80 match was against an earlier ramulator revision.

Cross-validation

No hardware cross-validation: I don't have an HBM3 platform, so this preset isn't validated the way your HBM2E path is. Beyond the spec-level check above, I ran a same-harness sanity check against the HBM2 preset (lib/ramulator, 64 B reads over 64 MiB):

Preset Idle 64 B read Sequential read, 1024 in flight Of nominal peak
hbm2, 8 channels 34.0 ns 112.2 GB/s 87.6% of 128 GB/s
hbm3, 16 channels 33.7 ns 691.3 GB/s 84.4% of 819.2 GB/s

So it behaves consistently with the validated preset, but these are JEDEC-spec numbers, not measurements. Three options, your call:

  1. Keep it, default stays hbm2, and I label HBM3 "spec-level, not hardware-validated" in the readme, the settings comment and the startup log.
  2. Drop HBM3 from this PR and keep only the HBM_CHANNELS setting.
  3. If your V80 harness is in the repo, point me at it and I'll run the identical access pattern on both presets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants