Skip to content

Release v0.4.1#18

Merged
ktok07b6 merged 30 commits intomainfrom
devel
Mar 13, 2026
Merged

Release v0.4.1#18
ktok07b6 merged 30 commits intomainfrom
devel

Conversation

@ktok07b6
Copy link
Member

Release v0.4.1

Features

  • Python simulation debug feature (watch/VCD/text log)
  • Module constructor function/tuple args support
  • Generic type support for List with type and capacity parameters

Bug Fixes

  • Auto-reg variables crossing clksleep in timed scopes
  • TypeSpecializer infinite loop
  • AHDLVarReducer field variable protection
  • WaitTransformer trailing codes with META_WAIT
  • constopt array inlining and class constants
  • Python simulation improvements

Build & CI

  • Migrate from Travis CI to GitHub Actions
  • Migrate to pyproject.toml with uv and ruff
  • Convert README from rst to markdown

ktok07b6 added 29 commits June 21, 2025 23:22
When a module's constructor FSM was removed during HDL generation
(hdlgen.py), its state_var signal was left in the hdlscope signal
table, resulting in an invalid `reg [-2:0] __init___state` declaration
in the output Verilog.

- hdlgen.py: call remove_sig(fsm.state_var) when deleting ctor FSM
- statereducer.py: also remove empty FSMs (with no remaining STGs)
  and their state signals; fix empty_stgs scope bug
In timed scopes, variables defined before a clksleep and used after it
are now kept as reg (not aliased to wire). This prevents incorrect
behavior where a wire reflects the current input rather than the
latched value at the point of assignment.

Only clksleep is treated as a clock boundary; wait_until and its
derivatives are excluded because they can pass in 0 clocks.
Add SimulationObserver for signal change logging and VCD output in
Python simulation. Includes:
- SimulationObserver class with text log and VCD output
- watch() function for runtime signal registration (lazy observer)
- --watch CLI option for simu.py (affects both Python and HDL sim)
- HDL $monitor generation via veritestgen.py
- Hierarchical signal name resolution via model tree walking
- _internal/_simulator.py stub for compiler compatibility
- Add vcd/log keyword args to watch() for custom output paths
- Auto-create output directories (os.makedirs)
- Fix --watch resolution for nested signals (e.g. s.i.tvalid)
Copilot AI review requested due to automatic review settings March 13, 2026 07:44
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 modernizes packaging/CI for Polyphony (pyproject + GitHub Actions), adds signal “watch” support for both Verilog and Python simulation, and expands compiler support for additional module argument patterns (e.g., functions and sequence-like ctor args), with new tests covering those scenarios.

Changes:

  • Migrate packaging to pyproject.toml/hatchling and add uv.lock; remove legacy setup.py, .travis.yml, .flake8, and README.rst.
  • Add --watch support and a Python-side SimulationObserver to emit VCD/text logs for selected signals.
  • Update compiler/type propagation/instantiation passes to better handle function-typed and sequence-typed module parameters; add targeted tests.

Reviewed changes

Copilot reviewed 45 out of 48 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
uv.lock Adds uv lockfile for dev tooling deps (pytest/ruff, etc.).
pyproject.toml New PEP 621 project metadata + hatchling build config + ruff config.
setup.py Removed legacy setuptools packaging entrypoint.
requirements.txt Present but empty in this PR snapshot.
README.rst Removed legacy RST readme.
README.md New Markdown readme targeting pyproject-based packaging.
.travis.yml Removed Travis CI configuration.
.github/workflows/test.yml Adds GitHub Actions workflow running suite with HDL+Python sim.
.flake8 Removed legacy flake8 config (ruff now configured).
.gitignore Updated ignore rules for tooling/artifacts.
.suite_ignores Expanded ignore list for known failing/hanging tests.
suite.py Adds per-test timeout handling + CLI help text improvements.
simu.py Adds --watch, builds observer, and resolves watched signals for Python sim.
error.py Ensures error-test options include hdl_debug_mode and targets.
polyphony/version.py Bumps version to 0.4.1.
polyphony/_internal/init.py Version bump to 0.4.1.
polyphony/_internal/_simulator.py Adds stub watch() for internal/builtin surface.
polyphony/init.py Improves runtime behavior of pipelined/unroll and TYPE_CHECKING stubs.
polyphony/typing.py Updates generic handling for List[...] and TYPE_CHECKING aliases.
polyphony/simulator.py Adds SimulationObserver, watch() helper, and simulator observer hooks.
polyphony/compiler/main.py Plumbs watch_signals into compiler env.
polyphony/compiler/common/env.py Adds watch_signals and seq_id_to_array storage.
polyphony/compiler/target/verilog/vericodegen.py Escapes % in emitted source text.
polyphony/compiler/target/verilog/veritestgen.py Emits $monitor for watched signals in Verilog TBs.
polyphony/compiler/ir/types/type.py Adds mangling for function types.
polyphony/compiler/ir/types/functiontype.py Broadens assignability for compatible function types.
polyphony/compiler/ir/analysis/typecheck.py Allows function/seq module args in NEW checks.
polyphony/compiler/ir/analysis/regreducer.py Avoids reg-reduction across clksleep boundaries; safer module lookup.
polyphony/compiler/ir/transformers/typeprop.py Prevents infinite worklist loops; handles superseded/specialized scopes.
polyphony/compiler/ir/transformers/objtransform.py Records seq ctor arrays in env for later resolution.
polyphony/compiler/ir/transformers/instantiator.py Restores seq ctor args from stored arrays/usedef when binding params.
polyphony/compiler/ir/transformers/copyopt.py Adds cycle protection to root-def tracing; skips function-typed moves.
polyphony/compiler/ir/transformers/constopt.py Constant-folds ARRAY MREFs; propagates constants to origin scopes.
polyphony/compiler/ir/scope.py Adds superseded tag; avoids cloning it into specialized scopes.
polyphony/compiler/ahdl/transformers/iotransformer.py Sinks trailing codes into wait-containing IFs before IO transform.
polyphony/compiler/ahdl/transformers/statereducer.py Cleans up empty FSMs and associated state vars.
polyphony/compiler/ahdl/transformers/ahdlopt.py Prevents reducing field signals in AHDL var reduction.
polyphony/compiler/ahdl/hdlgen.py Removes ctor FSM state var when dropping ctor FSMs.
polyphony/compiler/ahdl/hdlmodule.py Improves __str__ formatting + resource counting guards.
tests/timed/watch_test.py Adds manual “watch()” test case for debugging workflow.
tests/timed/timed_reg_test.py Adds timed test for register behavior across fences.
tests/module/ctor_type01.py Adds ctor arg typing test using different dtype params.
tests/module/ctor_tuple01.py Adds ctor tuple parameter passing test.
tests/module/ctor_multi01.py Adds multi-arg ctor parameter binding tests.
tests/module/ctor_global01.py Adds ctor global constant argument test.
tests/module/ctor_func01.py Adds ctor function argument binding test.
tests/io/fifo01.py Adds FIFO test module (timed) + read/write API.
tests/io/port_edge02.py Adjusts quoting and adds additional timing prints in loop.

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

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 117 to 121
hdl_finishes, py_finishes = simu.exec_test(t, options)
if options.enable_python:
suite_results[t] = f'HDL Result: {','.join(hdl_finishes)} Python Result: {",".join(py_finishes)}'
suite_results[t] = f'HDL Result: {",".join(hdl_finishes)} Python Result: {",".join(py_finishes)}'
else:
suite_results[t] = f'{",".join(hdl_finishes)}'
Comment on lines +149 to +158
for t, r in async_results:
try:
r.get(timeout=TEST_TIMEOUT)
except mp.TimeoutError:
print(f'TIMEOUT: {t} exceeded {TEST_TIMEOUT}s - skipping')
suite_results[t] = 'Timeout'
except Exception as e:
print(f'ERROR: {t} raised {e}')
suite_results[t] = 'Internal Error'
pool.terminate()
Comment on lines +264 to +269
for val_id, hier_name in name_table.items():
if hier_name == sig_name:
value = reverse_table.get(val_id)
if value:
simulator.observer.add_watch(sig_name, value)
found = True
Comment on lines +314 to +318
if isinstance(val, (Net, Reg)):
table[id(val)] = val
elif isinstance(val, Port):
if val.value:
table[id(val.value)] = val.value
Comment on lines +84 to +87
all_sigs = {sig.name: sig for sig in self.hdlmodule.get_signals(
{'reg', 'net', 'regarray', 'netarray'}, {'input', 'output'})}
# Also include input/output signals
for sig in self.hdlmodule.get_signals({'input', 'output'}):
Comment on lines +29 to +33
| Option | Description |
|--------|-------------|
| `-o FILE, --output FILE` | output filename (default is "polyphony_out") |
| `-d DIR, --dir DIR` | output directory |
| `-c CONFIG, --config CONFIG` | set configuration (JSON literal or file) |
Comment on lines +1 to +3
from polyphony import testbench, module
from polyphony.io import connect, Port
from polyphony.timing import timed, wait_value, clkfence
Comment on lines +65 to +76
if (self.write.rd()
and not self._full
and self.wp + 1 == self.rp):
self._full = 1
elif self._full and self.wp == self.rp:
self._full = 1
else:
self._full = 0
if (self.read.rd()
and not self._empty
and self.rp + 1 == self.wp):
self._empty = 1
Comment on lines 546 to +555
def _eval_decls(self):
self.updated_sigs.add(None)
_max_iter = 1000
while self.updated_sigs:
self.updated_sigs.clear()
for decl in self.model._decls:
self.visit(decl)
_max_iter -= 1
if _max_iter <= 0:
break
@ktok07b6 ktok07b6 merged commit f5dc8b9 into main Mar 13, 2026
2 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