nishi_synth_gates.nx
buildroot/runtime/nishi_synth_gates.nx
about
nishi_synth_gates.nx -- sovereign gate-netlist emitter.
Replaces Verilog as the canonical synth output target. Emits a
NishiLang-native gate-netlist text format (.nxgate) that downstream
nishi-pnr can consume. No Verilog syntax anywhere -- no `module`,
no `wire`, no `assign`, no `always_comb`, no `endmodule`.
Per the operator's cardinal (2026-05-26): "our own verilog without
any of this being something we can be legally hit on" + the
[[feedback-open-source-licensed-is-still-third-party]] memory:
Verilog 2005 (IEEE 1364) is an external spec; emitting it bakes
in a third-party dependency even though the emitter itself is
ours. The .nxgate format below is fully sovereign -- the SPEC
is here, the EMITTER is here, the CONSUMER (nishi-pnr, future)
is also here.
The Verilog emitter (nishi_synth.nx + synth_emit_alu.nx) stays
as a Wheeler-only test comparator per
[[feedback-c-is-wheeler-test-only]] -- run both emitters in
parallel during development, diff the resulting netlists for
correctness, NEVER ship the Verilog path as canonical.
.nxgate v1 format spec:
.NXGATE 1 format version
.MODULE <name> one per file
.PORT IN <name> width=<W> input port; W in 1..512
.PORT OUT <name> width=<W> output port
.PORT INOUT <name> width=<W> bidirectional port
.PORT CLK <name> clock (always 1-bit)
.PORT RST <name> reset (always 1-bit)
.NET <id> width=<W> internal net; id 0..n_nets-1
.CELL <id> kind=<K> fanout=<net> combinational cell
fanin=<net>,<net>,...
.FLOP <id> kind=DFF fanout=<net> sequential cell (D-flipflop)
d=<net> clk=<port> rst=<port>
.CONST <id> width=<W> value=<V> compile-time constant
.END module end
Cell kinds (sealed):
dependencies 3 imports · 7 importers
imports: nx_syscalls.nxnishi_hdl_primitives.nxnishi_synth.nx
imported by: nx_alu_op_kind.nxnx_cell_sink.nxnx_nxgate_sim.nxsynth_emit_alu_gates.nxsynth_emit_alu_gates_smoke.nxsynth_emit_regfile_gates.nxsynth_emit_regfile_gates_smoke.nx
structs
| none |
consts
| 62 | const NX_GATE_KIND_AND: i64 = 0 |
| 63 | const NX_GATE_KIND_OR: i64 = 1 |
| 64 | const NX_GATE_KIND_NOT: i64 = 2 |
| 65 | const NX_GATE_KIND_XOR: i64 = 3 |
| 66 | const NX_GATE_KIND_NAND: i64 = 4 |
| 67 | const NX_GATE_KIND_NOR: i64 = 5 |
| 68 | const NX_GATE_KIND_XNOR: i64 = 6 |
| 69 | const NX_GATE_KIND_ADD: i64 = 7 |
| 70 | const NX_GATE_KIND_SUB: i64 = 8 |
| 71 | const NX_GATE_KIND_MUL: i64 = 9 |
| 72 | const NX_GATE_KIND_MUX: i64 = 10 |
| 73 | const NX_GATE_KIND_SHL: i64 = 11 |
| 74 | const NX_GATE_KIND_SHR: i64 = 12 |
| 75 | const NX_GATE_KIND_SAR: i64 = 13 |
| 76 | const NX_GATE_KIND_EQ: i64 = 14 |
| 77 | const NX_GATE_KIND_NEQ: i64 = 15 |
| 78 | const NX_GATE_KIND_LT: i64 = 16 |
| 79 | const NX_GATE_KIND_LTU: i64 = 17 |
| 80 | const NX_GATE_KIND_GE: i64 = 18 |
| 81 | const NX_GATE_KIND_GEU: i64 = 19 |
| 82 | const NX_GATE_KIND_CONCAT: i64 = 20 |
| 83 | const NX_GATE_KIND_EXT_S: i64 = 21 // sign-extend |
| 84 | const NX_GATE_KIND_EXT_U: i64 = 22 // zero-extend |
| 85 | const NX_GATE_KIND_DFF: i64 = 23 // sequential (clocked) |
| 86 | const NX_GATE_KIND_CONST: i64 = 24 |
| 87 | const NX_GATE_KIND_N: i64 = 25 |
functions
| 89 | func nx_gate_kind_is_valid(k: i64) -> i64 |
| 96 | func nx_gate_kind_name(k: i64) -> *u8 |
| 130 | func nx_gate_port_kind_token(kind: i64) -> *u8 |
| 144 | func nx_gate_emit_net_ref(s: *NxSynthSink, handle: i64) -> i64 |
| 154 | func nx_gate_emit_header(s: *NxSynthSink, m: *NxHdlModule) -> i64 |
| 195 | func nx_gate_emit_nets(s: *NxSynthSink, m: *NxHdlModule) -> i64 |
| 222 | func nx_gate_emit_cell(s: *NxSynthSink, cell_id: i64, kind: i64, |
| 243 | func nx_gate_emit_flop(s: *NxSynthSink, cell_id: i64, fanout: i64, |
| 260 | func nx_gate_emit_const(s: *NxSynthSink, const_id: i64, width: i64, value: i64) -> i64 |
| 272 | func nx_gate_emit_end(s: *NxSynthSink) -> i64 |
| 283 | func nx_gate_emit_module_skeleton(s: *NxSynthSink, m: *NxHdlModule) -> i64 |