Skip to content

ifu top ref and env test added#192

Merged
miceforrat merged 1 commit intoXS-MLVP:mainfrom
miceforrat:ifu_top_verify
Feb 25, 2026
Merged

ifu top ref and env test added#192
miceforrat merged 1 commit intoXS-MLVP:mainfrom
miceforrat:ifu_top_verify

Conversation

@miceforrat
Copy link
Contributor

Description

aggregate ref of submodules to a large scale functional ref(without all the structure feats)

set up a more consolidated framework for testing ifu, including mmio state machine transfer and non mmio req pipeline scheduling.

add some test cases and cover points enough to cover the functional points until the rtil of March 2025

Type of change

Please delete options that are not relevant.

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

make rtl
make dut DUTS=ut_frontend_ifu_top
make test target=ut_frontend/ifu/ifu_top

Test Configuration:
requires picker and toffee

Checklist:

  • My code follows the style guidelines of this project
  • I have added the appropriate labels
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a consolidated IFU top functional reference model and expands the unit-test environment to cover both non-MMIO request scheduling and MMIO state-machine transitions, with functional coverage hooks added to track key behaviors.

Changes:

  • Adds IFU receiver/MMIO functional reference models plus supporting datadefs/utilities for stimulus generation.
  • Reworks the IFU top test environment to register multiple functional coverage groups (top/submodules/MMIO) and adds new non-MMIO + MMIO state tests.
  • Updates bundle auto-generation wrappers and internal-signal exposure (YAML) to support richer checking/coverage.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
ut_frontend/ifu/ifu_top/test/top_test_fixture.py Adds reset sequence, coverage group creation, and registration in the IFU top test fixture.
ut_frontend/ifu/ifu_top/test/smoke_test.py Removes the prior smoke example testcase.
ut_frontend/ifu/ifu_top/test/non_mmio_test.py Adds non-MMIO pipeline/flush/validity and random stress tests plus coverage marking.
ut_frontend/ifu/ifu_top/test/mmio_states_test.py Adds MMIO state-machine transition and resend behavior tests plus random stress test.
ut_frontend/ifu/ifu_top/test/ckpt_tops.py Adds top-level functional coverage watchpoints (cut ptr, exception vec, etc.).
ut_frontend/ifu/ifu_top/test/ckpt_subs.py Adds sub-module functional coverage watchpoints (predecode/pred-check related).
ut_frontend/ifu/ifu_top/test/ckpt_mmio.py Adds MMIO coverage watchpoints for state transfer / first-instr / seq-target.
ut_frontend/ifu/ifu_top/instr_utils.py Introduces instruction construction and cacheline rebuild helpers for stimulus generation.
ut_frontend/ifu/ifu_top/env/rvc_expander_ref.py Adds/updates RVC expand reference implementation.
ut_frontend/ifu/ifu_top/env/predecode_ref.py Adds predecode and f3-predecode reference implementations.
ut_frontend/ifu/ifu_top/env/pred_checker_ref.py Adds pred-checker reference implementation (staged + generator-based).
ut_frontend/ifu/ifu_top/env/ifu_top_env.py Attaches IFUReceiverModel into IFUTopEnv for ref-model checking.
ut_frontend/ifu/ifu_top/env/ifu_req_receiver_ref.py Adds IFUReceiverModel integrating predecode/pred-check/MMIO refs to produce expected outputs.
ut_frontend/ifu/ifu_top/env/ifu_mmio_ref.py Adds MMIO controller reference/state machine logic.
ut_frontend/ifu/ifu_top/env/ifu_icache_receiver.py Adds icache exception merging + per-instr exception generation ref.
ut_frontend/ifu/ifu_top/env/init.py Exports IFUReceiverModel from env package.
ut_frontend/ifu/ifu_top/datadef/sub_modules_def.py Adds dataclasses for predecode/f3-predecode/pred-check return structures.
ut_frontend/ifu/ifu_top/datadef/req_datadef.py Adds non-MMIO request/cluster and response data structures + randomization helpers.
ut_frontend/ifu/ifu_top/datadef/mmio_related.py Expands MMIO-related datadefs and adds MMIOState/MMIO request randomization/logging.
ut_frontend/ifu/ifu_top/datadef/icache_datadef.py Adds ICacheResp/ICacheStatusResp constructors and randomized response generation.
ut_frontend/ifu/ifu_top/datadef/ibuffer_datadef.py Reworks ToIbuffer/ToIbufferAllRes structures and equality/debug comparison behavior.
ut_frontend/ifu/ifu_top/datadef/ftq_datadef.py Reworks FTQ datadefs (idx/offset/query/flush/resp) with randomization and equality.
ut_frontend/ifu/ifu_top/datadef/frontend_trigger_datadef.py Converts trigger request/breakpoint setters to explicit __init__ fields.
ut_frontend/ifu/ifu_top/datadef/init.py Updates exports for the expanded datadef surface.
ut_frontend/ifu/ifu_top/commons.py Adds shared constants/helpers (predict width, cut ptr, doubleline, validity checks).
ut_frontend/ifu/ifu_top/bundle/auto_bundle.py Adds SignalList/BundleList wrappers and extends internal bundle mappings.
ut_frontend/ifu/ifu_top/bundle/init.py Updates bundle exports (InternalBundle rename/usage).
ut_frontend/ifu/ifu_top/agent/all_agent.py Major agent expansion: drives non-MMIO clustered scheduling + MMIO state stepping/compare, exposes internal probes.
scripts/ifu_related/ifu_top_internals.yaml Exposes additional internal wires/regs for checking/coverage (fires/readys/pc/cut ptr/exceptions/MMIO state).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +14 to +18
("send_to_uncache", MMIOState.STATE_SEND_REQ, MMIOState.STATE_WAIT_RESP),
("waiting_uncache_resp", MMIOState.STATE_WAIT_RESP, MMIOState.STATE_WAIT_RESP),
("uncache_once_finished", MMIOState.STATE_WAIT_RESP, MMIOState.STATE_WAIT_COMMIT),
("need_resend", MMIOState.STATE_WAIT_RESP, MMIOState.STATE_SEND_TLB),
("waiting_sending_tlb", MMIOState.STATE_SEND_TLB, MMIOState.STATE_SEND_TLB),
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

mmio_transfer contains two entries with the same description "waiting_uncache_resp" (WAIT_RESP→WAIT_RESP and WAIT_RESEND_RESP→WAIT_RESEND_RESP). Because add_watch_point builds a dict keyed by desc, the later entry overwrites the earlier one and you silently lose a coverage bin. Use unique descriptions (e.g. waiting_uncache_resp vs waiting_resend_uncache_resp).

Copilot uses AI. Check for mistakes.
Comment on lines +184 to +186
cluster.reqs.append(req1)
res1=ifu_ref.inner_deal_with_non_mmio(req1)
cluster.resps.append(res1)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This test claims to cover cross prediction block behavior, but the generated cluster appends req1 twice and never exercises req2 (the req2 append is commented out). This looks like a copy/paste mistake and will reduce the intended scenario coverage.

Suggested change
cluster.reqs.append(req1)
res1=ifu_ref.inner_deal_with_non_mmio(req1)
cluster.resps.append(res1)
cluster.reqs.append(req2)
res2=ifu_ref.inner_deal_with_non_mmio(req2)
cluster.resps.append(res2)

Copilot uses AI. Check for mistakes.
f"paddr={self.paddr}, "
f"pbmt={self.pbmt}, "
f"gpaddr={self.gpaddr}, "
f"excp={self.excp}")
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

ITLBResp.__repr__ returns a string without closing the formatting/parenthesis (it ends after excp=...). This produces malformed debug output; close the string representation (and the surrounding (...)) consistently.

Suggested change
f"excp={self.excp}")
f"excp={self.excp})")

Copilot uses AI. Check for mistakes.
Comment on lines +199 to +203
res = construct_non_cfis(rvc=is_rvc, rvc_enabled=True)
instrs[i] = res & ((1 << 16) - 1)
if not is_rvc:
i += 1
instrs[i] =(res >> 16) & ((1 << 16)-1)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

i += 1 inside a for i in range(...) loop doesn’t skip the next iteration in Python, so the upper 16 bits you write into instrs[i] can be overwritten on the next loop iteration. Use a while loop with a manual index (or a skip_next flag) so 32-bit instructions consume two 16-bit slots correctly.

Copilot uses AI. Check for mistakes.
if imm == -1:
return (randint(0, (1 << 25) -1 ) << 7) | opcode
replay = concat(imm, [[20], [1, 10], [11], [12, 19]])
instr = (imm << 12) | (randint(0, 31) << 7) | opcode
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

construct_jal() computes replay = concat(imm, ...) for the JAL immediate encoding but then ignores it and uses (imm << 12) instead, producing an incorrectly encoded JAL. Use replay to place the immediate bits in the JAL format so predecode jump-offset calculations can match the intended target.

Suggested change
instr = (imm << 12) | (randint(0, 31) << 7) | opcode
instr = (replay << 12) | (randint(0, 31) << 7) | opcode

Copilot uses AI. Check for mistakes.
Comment on lines +219 to +223
TIMES=20000
import time
seed = time.time_ns()
random.seed(seed)
for i in range(TIMES):
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This testcase runs 20,000 iterations (plus per-iteration stepping) unconditionally, which is likely too slow/flaky for regular CI. Consider lowering TIMES by default and/or gating the long random stress run behind an env var/marker so CI remains fast and deterministic.

Copilot uses AI. Check for mistakes.
Comment on lines +288 to +298
ifu_top_env.top_group.mark_function("gpaddr_fault", test_cross_prediction_block)
ifu_top_env.top_group.mark_function("exception", test_cross_prediction_block)
ifu_top_env.top_group.mark_function("cut_ptr", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_concat", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_rvc", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_jmpoff", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_brtype", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_jal_ret", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("starts", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("check_errs", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("rvc_expand", test_cross_prediction_block)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Coverage group mark_function calls at the end of test_totally_random_res are registering test_cross_prediction_block instead of the current test function. This will misattribute coverage to the wrong testcase; pass test_totally_random_res here instead.

Suggested change
ifu_top_env.top_group.mark_function("gpaddr_fault", test_cross_prediction_block)
ifu_top_env.top_group.mark_function("exception", test_cross_prediction_block)
ifu_top_env.top_group.mark_function("cut_ptr", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_concat", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_rvc", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_jmpoff", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_brtype", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("predecode_jal_ret", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("starts", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("check_errs", test_cross_prediction_block)
ifu_top_env.submodules_group.mark_function("rvc_expand", test_cross_prediction_block)
ifu_top_env.top_group.mark_function("gpaddr_fault", test_totally_random_res)
ifu_top_env.top_group.mark_function("exception", test_totally_random_res)
ifu_top_env.top_group.mark_function("cut_ptr", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("predecode_concat", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("predecode_rvc", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("predecode_jmpoff", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("predecode_brtype", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("predecode_jal_ret", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("starts", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("check_errs", test_totally_random_res)
ifu_top_env.submodules_group.mark_function("rvc_expand", test_totally_random_res)

Copilot uses AI. Check for mistakes.
Comment on lines +265 to +269
print("seed =", seed)
for i in range(20000):
if i % 1000 == 0:
print(f"epoch: {i}")
await random_once_req(top_agent, ifu_ref)
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

This testcase runs 20,000 randomized MMIO cycles unconditionally. In CI this is likely to be extremely slow/flaky; consider reducing the default iteration count and/or gating the long random run behind an environment variable/marker (similar to other long random tests in the repo that are skipped).

Copilot uses AI. Check for mistakes.
# --- 逐字段比对 ---
scalar_fields = [
"valid", "pds", "ftqPtr", "foldpcs",
"backendException", "enqEnable", "instr_valids", "exceptionTypes","instrValids"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

ToIbuffer.__eq__ includes "instrValids" in scalar_fields, but the class defines instr_valids (snake_case) and no instrValids attribute. This extra field makes the comparison logic confusing; remove it or rename to the actual attribute if needed.

Suggested change
"backendException", "enqEnable", "instr_valids", "exceptionTypes","instrValids"
"backendException", "enqEnable", "instr_valids", "exceptionTypes"

Copilot uses AI. Check for mistakes.
Comment on lines +221 to +225
res = construct_instrs(cfi_type, rvc=is_rvc, rvc_enabled=True, target_imm=cur_imm) if 0 <= cfi_type < 4 else construct_ret(rvc=is_rvc)
instrs[i] = res & ((1 << 16) - 1)
if not is_rvc:
i += 1
if i <= PREDICT_WIDTH:
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

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

Same problem here: modifying i inside this for loop won’t affect the loop counter, so 32-bit instructions won’t reliably occupy two slots. Consider rewriting this section with a while loop and explicit index increments when not is_rvc.

Copilot uses AI. Check for mistakes.
@miceforrat miceforrat merged commit 797e6e9 into XS-MLVP:main Feb 25, 2026
5 checks passed
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.

2 participants