Merge branch 'dev' into docs

# Conflicts:
#	.gitignore
This commit is contained in:
PurplePower
2025-07-23 20:42:38 +08:00
4 changed files with 313 additions and 1 deletions

View File

@@ -72,7 +72,7 @@ class Execute extends Module {
)
io.if_jump_address := io.immediate + Mux(opcode === Instructions.jalr, io.reg1_data, io.instruction_address)
io.mem_alu_result := alu.io.result
// lab2(CLINTCSR)
//lab2(CLINTCSR)
/*
io.csr_reg_write_data :=
*/

268
misc/autoans.py Normal file
View File

@@ -0,0 +1,268 @@
#!/usr/bin/env python3
"""
Code Auto-Filler Tool
This tool reads a YAML configuration file containing code snippets and operations,
then applies them to target files. It supports two main operations:
1. Adding import statements at the beginning of files
2. Inserting code blocks after specific anchor comments
"""
import yaml
import os
import sys
import argparse
from pathlib import Path
from typing import Dict, List, Optional
class CodeFiller:
def __init__(self, config_file: str, base_path: str = "."):
"""
Initialize the code filler.
Args:
config_file: Path to the YAML configuration file
base_path: Base directory for resolving relative target file paths
"""
self.config_file = config_file
self.base_path = Path(base_path).resolve()
self.config = self._load_config()
def _load_config(self) -> Dict:
"""Load and parse the YAML configuration file."""
try:
with open(self.config_file, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
return config
except FileNotFoundError:
print(f"Error: Configuration file '{self.config_file}' not found.")
sys.exit(1)
except yaml.YAMLError as e:
print(f"Error parsing YAML file: {e}")
sys.exit(1)
def _resolve_target_path(self, target_file: str) -> Path:
"""Resolve the target file path relative to base path."""
if os.path.isabs(target_file):
return Path(target_file)
return self.base_path / target_file
def _backup_file(self, file_path: Path) -> None:
"""Create a backup of the original file."""
backup_path = file_path.with_suffix(file_path.suffix + '.backup')
if file_path.exists():
with open(file_path, 'r', encoding='utf-8') as src:
with open(backup_path, 'w', encoding='utf-8') as dst:
dst.write(src.read())
print(f" Backup created: {backup_path}")
def _add_imports(self, lines: List[str], imports: List[str]) -> List[str]:
"""
Add import statements after the package declaration.
Args:
lines: Original file lines
imports: List of import statements to add
Returns:
Modified file lines with imports added
"""
# Find the insertion point (after package declaration)
insert_index = 0
# Find package declaration
for i, line in enumerate(lines):
stripped = line.strip()
if stripped.startswith('package '):
insert_index = i + 1
break
# Insert imports after package declaration
new_lines = lines[:insert_index]
# Add the imports
for import_stmt in imports:
new_lines.append(import_stmt + '\n')
# Add a blank line after imports if there are remaining lines
if insert_index < len(lines):
new_lines.append('\n')
new_lines.extend(lines[insert_index:])
print(f" Added {len(imports)} import statement(s)")
return new_lines
def _insert_after_anchor(self, lines: List[str], anchor: str, code: str) -> List[str]:
"""
Insert code after a specific anchor comment.
Args:
lines: Original file lines
anchor: The anchor comment to search for
code: The code block to insert
Returns:
Modified file lines with code inserted
Raises:
ValueError: If the anchor comment is not found in the file
"""
anchor_found = False
new_lines = []
for i, line in enumerate(lines):
new_lines.append(line)
if anchor.strip() in line.strip():
anchor_found = True
# Extract indentation from the anchor line
anchor_indent = ""
for char in line:
if char in [' ', '\t']:
anchor_indent += char
else:
break
# Add the code block after the anchor with proper indentation
code_lines = code.strip().split('\n')
for code_line in code_lines:
# Apply anchor indentation to non-empty lines
if code_line.strip():
indented_line = anchor_indent + code_line
else:
indented_line = code_line # Keep empty lines as-is
new_lines.append(indented_line + '\n')
print(f" Inserted code after anchor: {anchor.strip()}")
if not anchor_found:
raise ValueError(f"Anchor '{anchor.strip()}' not found in file")
return new_lines
def _process_file(self, target_file: str, operations: Dict) -> None:
"""
Process a single target file with the specified operations.
Args:
target_file: Path to the target file
operations: Dictionary containing imports and anchors operations
"""
file_path = self._resolve_target_path(target_file)
print(f"Processing: {file_path}")
# Check if file exists
if not file_path.exists():
print(f" Warning: Target file does not exist, creating new file")
file_path.parent.mkdir(parents=True, exist_ok=True)
with open(file_path, 'w', encoding='utf-8') as f:
f.write('')
# Create backup
self._backup_file(file_path)
# Read the original file
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
modified_lines = lines[:]
# Process imports
if 'imports' in operations and operations['imports']:
modified_lines = self._add_imports(modified_lines, operations['imports'])
# Process anchor insertions
if 'anchors' in operations and operations['anchors']:
for anchor, config in operations['anchors'].items():
if 'code' in config:
try:
modified_lines = self._insert_after_anchor(
modified_lines, anchor, config['code']
)
except ValueError as e:
raise ValueError(f"Failed to process file '{target_file}': {e}") from e
# Write the modified file
with open(file_path, 'w', encoding='utf-8') as f:
f.writelines(modified_lines)
print(f" ✓ File processed successfully")
def fill_codes(self, dry_run: bool = False) -> None:
"""
Execute the code filling process for all files in the configuration.
Args:
dry_run: If True, only show what would be done without making changes
"""
if 'files' not in self.config:
print("Error: No 'files' section found in configuration")
return
if dry_run:
print("DRY RUN MODE - No files will be modified\n")
print(f"Base directory: {self.base_path}")
print(f"Configuration: {self.config_file}\n")
for target_file, operations in self.config['files'].items():
if dry_run:
print(f"Would process: {target_file}")
if 'imports' in operations:
print(f" Would add {len(operations['imports'])} import(s)")
if 'anchors' in operations:
print(f" Would process {len(operations['anchors'])} anchor(s)")
print()
else:
try:
self._process_file(target_file, operations)
print()
except ValueError as e:
print(f"{e}")
print(f"\nExecution stopped due to configuration error.")
sys.exit(1)
except Exception as e:
print(f" ✗ Unexpected error processing file: {e}")
print(f"\nExecution stopped due to unexpected error.")
sys.exit(1)
if not dry_run:
print("Code filling completed!")
def main():
parser = argparse.ArgumentParser(
description="Automatically fill code into target files based on YAML configuration"
)
parser.add_argument(
'config_file',
help='Path to the YAML configuration file'
)
parser.add_argument(
'-b', '--base-path',
default='.',
help='Base directory for resolving target file paths (default: current directory)'
)
parser.add_argument(
'-d', '--dry-run',
action='store_true',
help='Show what would be done without making any changes'
)
parser.add_argument(
'-v', '--version',
action='version',
version='Code Auto-Filler 1.0.0'
)
args = parser.parse_args()
# Create and run the code filler
filler = CodeFiller(args.config_file, args.base_path)
filler.fill_codes(dry_run=args.dry_run)
if __name__ == '__main__':
main()

43
misc/example_codes.yaml Normal file
View File

@@ -0,0 +1,43 @@
# Example configuration file for code insertion
# Format: target_file -> operations
files:
# Example target file 1
"src/main/scala/MyModule.scala":
imports:
- "import chisel3.util._"
- "import chisel3.experimental._"
anchors:
"// INSERT_REGISTERS_HERE":
code: |
val regA = RegInit(0.U(32.W))
val regB = RegInit(0.U(32.W))
val counter = RegInit(0.U(8.W))
"// INSERT_LOGIC_HERE":
code: |
when(io.enable) {
regA := io.dataIn
counter := counter + 1.U
}.otherwise {
regA := 0.U
}
# Example target file 2
"src/test/scala/MyModuleTest.scala":
imports:
- "import chiseltest._"
- "import org.scalatest.flatspec.AnyFlatSpec"
anchors:
"// INSERT_TEST_CASE":
code: |
it should "handle basic operations" in {
test(new MyModule) { dut =>
dut.io.enable.poke(true.B)
dut.io.dataIn.poke(42.U)
dut.clock.step()
dut.io.dataOut.expect(42.U)
}
}

1
misc/requirements.txt Normal file
View File

@@ -0,0 +1 @@
PyYAML>=6.0