From 7c3eb26aa3f813fa1d97fb5671c5e2dc65e39350 Mon Sep 17 00:00:00 2001 From: Stavros Avramidis Date: Tue, 3 Nov 2026 13:18:43 +0200 Subject: [PATCH] Enhance Verilog support by adding BRAM read/write port handling and updating documentation Signed-off-by: Stavros Avramidis --- README.md | 7 ++++--- src/verilog.typ | 15 ++++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index cec154a..2098965 100644 --- a/README.md +++ b/README.md @@ -75,9 +75,10 @@ To use this package, simply import [circuiteria](https://typst.app/universe/pack ### Verilog modules Blocks can be generated automatically from Verilog/SystemVerilog sources. -AXI4, AXI4-Lite, AXI4-Stream, APB and Vivado BRAM interface signals are -grouped into single bus ports, and clock/reset signals are detected and placed -together: +AXI4, AXI4-Lite, AXI4-Stream, APB and BRAM signals (Vivado BRAM interface, or +`_addr`/`_dout`/`_wr_en`/`_wr_addr`/`_wr_data`/`_rd_addr`/`_rd_data` +RAM ports) are grouped into single bus ports, and clock/reset signals are +detected and placed together: ```typ #circuiteria.circuit({ import circuiteria: * diff --git a/src/verilog.typ b/src/verilog.typ index 9232abd..5e475f7 100644 --- a/src/verilog.typ +++ b/src/verilog.typ @@ -317,7 +317,9 @@ ) #let bram-suffixes = ( - "clk", "rst", "en", "we", "wen", "regce", "addr", "din", "dout" + "clk", "rst", "en", "we", "wen", "regce", "addr", "din", "dout", + // separate read/write ports (e.g. simple dual-port RAMs) + "rd_en", "rd_addr", "rd_data", "wr_en", "wr_addr", "wr_data" ) // Signals that only exist on full AXI4 (used to tell AXI4 from AXI4-Lite) @@ -428,7 +430,10 @@ return none } } else if kind == "bram" { - if "addr" not in sig or ("din" not in sig and "dout" not in sig) { return none } + // the address requirement keeps FIFOs (`wr_en`, `rd_data`, ...) out + let has-addr = ("addr", "wr_addr", "rd_addr").any(it => it in sig) + let has-data = ("din", "dout", "wr_data", "rd_data").any(it => it in sig) + if not has-addr or not has-data { return none } } else if kind == "apb" { if "paddr" not in sig or "penable" not in sig { return none } } else { @@ -443,7 +448,7 @@ let ref = if kind == "axi-stream" { sig.at("tvalid", default: sig.at("tdata", default: none)) } else if kind == "bram" { - sig.at("addr", default: sig.at("din", default: sig.at("dout", default: none))) + sig.at("addr", default: sig.at("wr_addr", default: sig.at("rd_addr", default: none))) } else if kind == "apb" { sig.paddr } else { @@ -456,8 +461,8 @@ prefix: group.prefix, role: role, dir: if role == "master" { "output" } else { "input" }, - data-width: _bus-width(group, "tdata", "wdata", "rdata", "din", "dout", "pwdata", "prdata"), - addr-width: _bus-width(group, "awaddr", "araddr", "addr", "paddr"), + data-width: _bus-width(group, "tdata", "wdata", "rdata", "din", "dout", "wr_data", "rd_data", "pwdata", "prdata"), + addr-width: _bus-width(group, "awaddr", "araddr", "addr", "wr_addr", "rd_addr", "paddr"), signals: sig, ports: sig.values() )