From c6ff02a058e1b6aac824ce7430ea66cefc95229b Mon Sep 17 00:00:00 2001 From: PurplePower <60787289+PurplePower@users.noreply.github.com> Date: Thu, 14 Aug 2025 18:19:52 +0800 Subject: [PATCH] some updates --- .../labs/lab3/lab3-pipelined-cpu.md | 4 +- .../fivestage_forward/InstructionDecode.scala | 8 +-- misc/autoans.py | 53 ++++++++++++++++++- misc/example_codes.yaml | 1 + 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/docs/docs/better-tut/labs/lab3/lab3-pipelined-cpu.md b/docs/docs/better-tut/labs/lab3/lab3-pipelined-cpu.md index 47238b4..0e3a9c3 100644 --- a/docs/docs/better-tut/labs/lab3/lab3-pipelined-cpu.md +++ b/docs/docs/better-tut/labs/lab3/lab3-pipelined-cpu.md @@ -164,9 +164,7 @@ !!! note "实验任务:缩短分支延迟" - `InstructionDecode`中的实现与五级阻塞流水线CPU基本一致,你可以复制前面填好的内容。 - - 我们已经为你定义好相关模块的接口并移除了 `Execute` 模块中分支和跳转的相关代码,请你修改 `src/main/scala/riscv/core/fivestage_final/InstructionDecode.scala`、`src/main/scala/riscv/core/fivestage_final/Control.scala` 和 `src/main/scala/riscv/core/fivestage_final/Forwarding.scala` 中 `// Lab3(Final)` 处的代码,使其能够通过 `FiveStageCPUFinal` 测试。你可以复制上道题中相应代码并作修改。 + 我们已经为你定义好相关模块的接口并移除了 `Execute` 模块中分支和跳转的相关代码,请你修改 `src/main/scala/riscv/core/fivestage_final` 下的 `InstructionDecode.scala`、`Control.scala` 和 `Forwarding.scala` 中 `// Lab3(Final)` 处的代码,使其能够通过 `FiveStageCPUFinal` 测试。你可以复制上道题中相应代码并作修改。 ### 提示:如何有效 debug diff --git a/lab3/src/main/scala/riscv/core/fivestage_forward/InstructionDecode.scala b/lab3/src/main/scala/riscv/core/fivestage_forward/InstructionDecode.scala index 4be4a03..249eb23 100644 --- a/lab3/src/main/scala/riscv/core/fivestage_forward/InstructionDecode.scala +++ b/lab3/src/main/scala/riscv/core/fivestage_forward/InstructionDecode.scala @@ -156,10 +156,10 @@ class InstructionDecode extends Module { val rs1 = io.instruction(19, 15) val rs2 = io.instruction(24, 20) - // Lab3(Forwarding) ID rs + // Lab3(Forward) ID rs io.regs_reg1_read_address := rs1 io.regs_reg2_read_address := rs2 - // Lab3(Forwarding) ID rs End + // Lab3(Forward) ID rs End io.ex_immediate := MuxLookup( opcode, Cat(Fill(20, io.instruction(31)), io.instruction(31, 20)), @@ -196,10 +196,10 @@ class InstructionDecode extends Module { Instructions.jalr -> RegWriteSource.NextInstructionAddress ) ) - // Lab3(Forwarding) ID rd + // Lab3(Forward) ID rd io.ex_reg_write_enable := false.B io.ex_reg_write_address := rd - // Lab3(Forwarding) ID rd End + // Lab3(Forward) ID rd End io.ex_csr_address := io.instruction(31, 20) io.ex_csr_write_enable := (opcode === Instructions.csr) && ( funct3 === InstructionsTypeCSR.csrrw || funct3 === InstructionsTypeCSR.csrrwi || diff --git a/misc/autoans.py b/misc/autoans.py index 5f66224..dbc92a9 100644 --- a/misc/autoans.py +++ b/misc/autoans.py @@ -143,6 +143,48 @@ class CodeFiller: return new_lines + def _replace_between_anchors(self, lines: List[str], begin_anchor: str, end_anchor: str, code: str) -> List[str]: + """ + Replace the contents between begin_anchor and end_anchor with the given code. + Preserves indentation of the begin_anchor. + Raises ValueError if anchors are not found or in wrong order. + """ + begin_idx = end_idx = None + anchor_indent = "" + for i, line in enumerate(lines): + if begin_anchor.strip() in line.strip(): + begin_idx = i + # Extract indentation from the begin anchor line + for char in line: + if char in [' ', '\t']: + anchor_indent += char + else: + break + if end_anchor.strip() in line.strip(): + end_idx = i + break + if begin_idx is None: + raise ValueError(f"Begin anchor '{begin_anchor}' not found in file") + if end_idx is None: + raise ValueError(f"End anchor '{end_anchor}' not found in file") + if end_idx <= begin_idx: + raise ValueError(f"End anchor '{end_anchor}' found before begin anchor '{begin_anchor}'") + + # Build new lines + new_lines = lines[:begin_idx+1] + code_lines = code.strip().split('\n') + for code_line in code_lines: + if code_line.strip(): + indented_line = anchor_indent + code_line + else: + indented_line = code_line + new_lines.append(indented_line + '\n') + new_lines.extend(lines[end_idx:]) + + print(f" Replaced code between anchors: {begin_anchor.strip()} ... {end_anchor.strip()}") + + return new_lines + def _process_file(self, target_file: str, operations: Dict) -> None: """ Process a single target file with the specified operations. @@ -174,10 +216,17 @@ class CodeFiller: if 'imports' in operations and operations['imports']: modified_lines = self._add_imports(modified_lines, operations['imports']) - # Process anchor insertions + # Process anchor insertions and replacements if 'anchors' in operations and operations['anchors']: for anchor, config in operations['anchors'].items(): - if 'code' in config: + if 'code' in config and 'end_anchor' in config: + try: + modified_lines = self._replace_between_anchors( + modified_lines, anchor, config['end_anchor'], config['code'] + ) + except ValueError as e: + raise ValueError(f"Failed to process file '{target_file}': {e}") from e + elif 'code' in config: try: modified_lines = self._insert_after_anchor( modified_lines, anchor, config['code'] diff --git a/misc/example_codes.yaml b/misc/example_codes.yaml index 0902b48..3aef5ab 100644 --- a/misc/example_codes.yaml +++ b/misc/example_codes.yaml @@ -32,6 +32,7 @@ files: anchors: "// INSERT_TEST_CASE": + end_anchor: "// END_TEST_CASE" code: | it should "handle basic operations" in { test(new MyModule) { dut =>