Repository navigation
Conversation
The previous commit converted genWrapper to the shared signal classes but left genWrapperSlave referencing an undefined `ctx`, and dropped the explicit tab levels that OpTab used to take, so assignments inside the clocked processes were emitted at the wrong indentation. - Give genWrapperSlave its own VHDLContext, and flush portInitString after the IO declarations and signalInitString before "begin", matching genWrapper (both buffers are filled lazily by signalInit()). - Raise the context indent around the Op() loops so the generated VHDL keeps the indentation OpTab produced. Generated VHDL is byte-identical to before for master/slave wrappers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
VHDLLogicType, VHDLLogicVecType, VHDLLogicTypeArray and VHDLLogicVecTypeArray were a second copy of Logic, LogicVec, LogicArray and LogicVecArray from core_gen/signals.py, differing only in returning their declarations as strings instead of buffering them in a VHDLContext, and in omitting the _i/_o port suffixes. Now that the LSQ wrapper builds its signals through signals.py with dyn_comp=True, nothing uses them. Drop the four classes and OpTab (superseded by operators.assign.Op), along with the now-unused `re` import and the stale re-exports in core_gen/__init__.py. The remaining helper functions in utils.py are unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
getNameWrite computed the dyn_comp-aware suffix and then passed the raw
f'_{i}' to Logic.getNameWrite anyway, so a dyn_comp LogicArray would have
written to <name>_0 where it reads from <name>. LogicVecArray.getNameWrite
already used the computed suffix; make LogicArray match.
Not reachable from the current wrapper code, which indexes these arrays
through __getitem__ rather than calling getNameWrite(i) directly, so the
generated VHDL is unchanged.
Also reformat the touched files with autopep8 --max-line-length 200, which
CI enforces on modified Python files.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JasmijnB
force-pushed
the
emitter-structure
branch
from
September 15, 2026 12:44
5c7a4a5 to
5627b89
Compare
JasmijnB
force-pushed
the
emitter-structure
branch
2 times, most recently
from
October 15, 2026 09:35
8664d6a to
d27b093
Compare
Introduces the two pieces the generators will be rewritten against:
- core_gen/ir.py: a small expression IR (Statement, Val, Bin, Un, Bit,
WhenElse, CustomStatement) with Python operator overloads, so the
generators can describe logic instead of formatting HDL text.
- core_gen/emitters/: the abstract Emitter, which replaces VHDLContext
as the code-generation context, plus VHDLEmitter, which renders the
IR as VHDL. A second language only needs another Emitter subclass.
Both are unused at this point; the next commit ports the generators onto
them.
Taken from the lsq-verilog branch.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRJyvC1t9ivZeRVp35SAn3
Rewrites the generators to build the IR and hand it to an Emitter,
rather than formatting VHDL strings inline. VHDLContext, its Op helper
and the unused cli.py go away; signals.py, the operators, the
generators, codegen.py and lsq-generator.py all now take an `em`.
Formatting of literals moves to the emitter too, so MaskLess, IntToBits
and Zero leave utils.py (mask_less / int_to_str on VHDLEmitter).
The generated VHDL is no longer byte-identical to what main emits. It is
structurally the same design, but the emitter drops the pass-through
wires that main emitted for disabled pipeline stages, names temporaries
differently, and formats literals, comments and instantiations its own
way.
Taken from the lsq-verilog branch, minus VerilogEmitter and the --hdl
flag, which follow separately. On top of that:
- Carried forward the four main-side LSQ commits that lsq-verilog
predates: the ldq_head_oh_pcomp pipeline register and the stricter
IntToBits (EPFL-LAP#993), the single-group-allocation assertion (EPFL-LAP#1011), and
the master-interface stall handling in the slave wrapper (EPFL-LAP#903).
- Fixed a net -4 indent imbalance in genWrapperSlave that pinned every
line after the first process to column 0.
- add_comment and add_custom_statement now emit a blank line rather
than a bare "-- " for an empty line, which is what the block
separators in the operators were asking for.
- Dropped LSQWrapper.lsq_wrapper_str, which nothing reads now that the
emitter writes the file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRJyvC1t9ivZeRVp35SAn3
The three bugs all sat on paths the lsq-verilog branch does not exercise
(the slave wrapper and single-bit register init); each aborted generation
outright. Across a 7168-config sweep they accounted for every failure,
and with them fixed the sweep is clean on both sides.
- VHDLEmitter.logic_reg_init called self.in_to_bits, which does not
exist. Every scalar register initialiser hit it: 5376/7168 configs.
- lsq.py passed a bare 0 to add_assignment where a Statement is
expected, in the non-master write-request path.
- The same path built when/else with misplaced parentheses, calling
.else_() on the condition rather than on the value.
Emitter also only declared about half the methods the generators call on
it, so a new subclass would fail at run time rather than at the contract.
Added stubs for the remaining thirteen, and implemented print_custom_str
on VHDLEmitter, which CustomStatement._to_str had always called and no
emitter defined.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MRJyvC1t9ivZeRVp35SAn3
JasmijnB
force-pushed
the
emitter-structure
branch
from
October 15, 2026 09:37
d27b093 to
ab8e68d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Instead of directly pasting strings into the
Opcommand, go through anEmitterclass. This adds a layer of abstraction when adding LSQ code, allows for adding new emitters to add a new output language. In preparation of the full #914The structure works as follows:
Emitterimplementing functions such asadd_assignment,int_to_bitetc. this superclass is then implemented by theVHDLEmitteradd_assignmenttakes a aSignaland aStatement, this statement is the superclass of a simple IR which contains objects such as aBin,Valetc.Statementclass overrides some operators to make the code look nice. E.g. you can doVal(1) + Val(2)which evaluates toBin(Val(1), BinOp.ADD, Val(2)get_binop_strinVHDLEmitterthen generates the actual stringThis change might seem huge, this is because every single
Opcall has been rewritten, but looking at the actual code you will see that there are no structural code changes, just the change fromOptoem.add_assignment(...). I've used claude to perform part of the rewrite against the current main as I couldn't cherry pick, and then checked this and the VHDL output.Don't merge this branch yet before merging #1048 which it's based on, I'm just setting up the pull request ahead of time