Summary
The slashkit link command exposes a --clock-hz argument that is documented as the "Target clock frequency in MHz" (the help string is also misleading — the value is actually interpreted in Hz, see linker/slashkit/command_config.py:196-197). However, the value is only used as metadata that ends up in system_map.xml. It is not forwarded to Vivado as a timing constraint. As a consequence, Vivado always places and routes the user region against the hard-coded 400 MHz that is baked into the static shell, and then reports whatever it could close timing at — regardless of what the user requested.
Expected behavior
When the user passes --clock-hz <freq>:
- The requested frequency should be turned into a real Vivado constraint on the user-region clock (e.g. by overriding
CONFIG.FREQ_HZ on the relevant shell ports, by emitting a create_clock / set_clock_groups constraint in the user region, or by parameterising the static-shell clocking IP).
- Vivado should target exactly that frequency, so that:
- place-and-route can terminate early once the target is met instead of always optimising toward 400 MHz;
- the value written to
system_map.xml actually matches the constraint that PnR was run against.
Actual behavior
--clock-hz only flows through resolve_system_map_clock into the rendered system_map.xml. The clock that Vivado actually sees is always 400 MHz, fixed by the static shell template.
Pointers to the relevant code
Suggested fix direction
Thread config.clock_hz (with a sensible default such as the existing DEFAULT_CLOCK_HZ = 200_000_000 from linker/slashkit/emit/metadata/system_map_ctx.py:32) into the hardware Tcl generation so that:
- The
CONFIG.FREQ_HZ properties in slash_base.tcl / the user-region wrapper are templated rather than hard-coded 400000000, or
- A
create_clock -period constraint is emitted into the user-region XDC at link time.
Either way, the value should be the single source of truth that is also written into system_map.xml.
Summary
The
slashkit linkcommand exposes a--clock-hzargument that is documented as the "Target clock frequency in MHz" (the help string is also misleading — the value is actually interpreted in Hz, seelinker/slashkit/command_config.py:196-197). However, the value is only used as metadata that ends up insystem_map.xml. It is not forwarded to Vivado as a timing constraint. As a consequence, Vivado always places and routes the user region against the hard-coded 400 MHz that is baked into the static shell, and then reports whatever it could close timing at — regardless of what the user requested.Expected behavior
When the user passes
--clock-hz <freq>:CONFIG.FREQ_HZon the relevant shell ports, by emitting acreate_clock/set_clock_groupsconstraint in the user region, or by parameterising the static-shell clocking IP).system_map.xmlactually matches the constraint that PnR was run against.Actual behavior
--clock-hzonly flows throughresolve_system_map_clockinto the renderedsystem_map.xml. The clock that Vivado actually sees is always 400 MHz, fixed by the static shell template.Pointers to the relevant code
linker/slashkit/command_config.py:196-197(and the duplicate inlinker/slashkit/core/command_config.py:196-197). Note that the help text says "MHz" but the value is consumed as Hz everywhere downstream.linker/slashkit/command_config.py:319-321(LinkerConfiguration.clock_hz).config.clock_hz:linker/slashkit/emit/hw/tcl_gen.py:313— passed intoresolve_system_map_clock(...)and then intobuild_system_map_context(..., clock_hz=clock_hz, ...)at lines 313–321, which renderssystem_map.xml.linker/slashkit/emit/sim/tcl_gen.py:356andlinker/slashkit/emit/emu/tcl_gen.py:72— same pattern for the sim / emu flows.resolve_system_map_clockitself:linker/slashkit/emit/metadata/system_map_ctx.py:39-56. This is the entire "use" of--clock-hz— it picks a number and hands it to the XML template atlinker/slashkit/resources/templates/system_map.xml:3(<ClockFrequency>{{ clock_hz }}</ClockFrequency>).linker/slashkit/resources/base/scripts/slash_base.tcl— every shell-facing AXI/clock port is configured withCONFIG.FREQ_HZ {400000000}(≈30 occurrences, starting at line 208).linker/slashkit/emit/hw/user_region/kernel_ctx.py:32-48does not currently override any of this.Suggested fix direction
Thread
config.clock_hz(with a sensible default such as the existingDEFAULT_CLOCK_HZ = 200_000_000fromlinker/slashkit/emit/metadata/system_map_ctx.py:32) into the hardware Tcl generation so that:CONFIG.FREQ_HZproperties inslash_base.tcl/ the user-region wrapper are templated rather than hard-coded400000000, orcreate_clock -periodconstraint is emitted into the user-region XDC at link time.Either way, the value should be the single source of truth that is also written into
system_map.xml.