Sanitize a name to be a valid Verilog identifier.
Fast path first: sanitizeName is called once per NAME OCCURRENCE
during emission — millions of times on XiangShan's Rob — and the
five-String.replace chain (each a Slice walk + fresh string) was
~20% of the whole emit. Almost every name is already clean; one
byte scan decides.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emit a symbolic hardware dimension as a SystemVerilog constant expression.
Convert HWType to Verilog type declaration
Equations
- Sparkle.Backend.Verilog.emitType Sparkle.IR.Type.HWType.bit = "logic"
- Sparkle.Backend.Verilog.emitType (Sparkle.IR.Type.HWType.bitVector 1) = "logic"
- Sparkle.Backend.Verilog.emitType (Sparkle.IR.Type.HWType.bitVector w) = toString "logic [" ++ toString (w - 1) ++ toString ":0]"
- Sparkle.Backend.Verilog.emitType (Sparkle.IR.Type.HWType.bitVectorDim width) = toString "logic [" ++ toString (Sparkle.Backend.Verilog.emitDimExpr width) ++ toString "-1:0]"
- Sparkle.Backend.Verilog.emitType (Sparkle.IR.Type.HWType.array size elemType) = toString (Sparkle.Backend.Verilog.emitType elemType) ++ toString " [" ++ toString (size - 1) ++ toString ":0]"
Instances For
Convert Operator to Verilog operator symbol
Equations
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.and = "&"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.or = "|"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.xor = "^"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.not = "~"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.add = "+"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.sub = "-"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.mul = "*"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.eq = "=="
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.lt_u = "<"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.lt_s = "<"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.le_u = "<="
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.le_s = "<="
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.gt_u = ">"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.gt_s = ">"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.ge_u = ">="
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.ge_s = ">="
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.shl = "<<"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.shr = ">>"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.asr = ">>>"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.neg = "-"
- Sparkle.Backend.Verilog.emitOperator Sparkle.IR.AST.Operator.mux = "?"
Instances For
Best-effort bit width of an IR expression against the declared-wire
width map. Used by the signed-comparison emitter: $signed(expr)
reads the sign at expr's VERILOG width, which for shapes like
(({6'd0, x} >> 0) & 6'h3f) (a lowered size cast) is the 12-bit
concat width, not the 6-bit value width — the sign bit lands on a
padding zero and the comparison degenerates.
Convert IR expression to Verilog expression.
widthOf maps a wire name to its declared bit width (when known),
so a full-width / scalar .slice can be elided — Verilog forbids a
part-select on a scalar (s[0:0] → "can not select part of
scalar").
Emit a single statement.
The optional wires parameter provides wire declarations for register
reset value width lookup.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emit port declarations for module header
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emit wire declarations.
regInits maps register-output names to their IR initial value: a
register's declaration gets an = <init> initializer so simulation
starts from the IR's defined state. The IR register model HAS an
initial value (CSim's reset() applies it), but a register with no
reset arm (_no_rst) starts as X in event simulators without this —
XiangShan's golden files randomize such registers in an initial
block, so the roundtrip diverged into X (CounterFilter class).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emit a SystemVerilog module parameter list.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Emit the full module
Equations
- One or more equations did not get rendered due to their size.
Instances For
Main entry point: Convert a Module to SystemVerilog
Instances For
Convert a full Design to SystemVerilog.
Each module is run through the IR optimizer first — exactly as
#synthesizeVerilog does before toVerilog (see
Sparkle.Compiler.Elab). This is essential, not cosmetic: the
optimizer's 0-bit elimination pass strips the degenerate 0-width
concat tails that circuit do / Signal.loop bundles leave behind
({reg, <0-bit>}). Without it those tails reach emitConst, which
promotes a 0-width literal to 1'd0, widening the concat by one bit
so the intermediate wire (sized for the real field) TRUNCATES the
real value away — silently freezing the least-significant register of
every bundle at its reset value. Hierarchical emission
(#writeVerilogDesign) is the only source of the @[hardware_module]
submodules, so skipping this here broke every sub-module's last
register (e.g. uartRxHW's rxValid).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Write module to a file
Equations
- Sparkle.Backend.Verilog.writeVerilogFile m filename = do IO.FS.writeFile { toString := filename } (Sparkle.Backend.Verilog.toVerilog m) IO.println (toString "Generated " ++ toString filename)
Instances For
Write a full design to a file
Equations
- One or more equations did not get rendered due to their size.