From 409992961c86e1933dd0f5a9d5fdec624fa61afe Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 21 Oct 2025 19:53:15 -0700 Subject: [PATCH] switch to using verilog for reset synchronizer so we can use attributes on FDPE instances --- crates/fayalite/src/vendor/xilinx/arty_a7.rs | 82 ++++++++++++-------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/crates/fayalite/src/vendor/xilinx/arty_a7.rs b/crates/fayalite/src/vendor/xilinx/arty_a7.rs index 0559199..f0a3f96 100644 --- a/crates/fayalite/src/vendor/xilinx/arty_a7.rs +++ b/crates/fayalite/src/vendor/xilinx/arty_a7.rs @@ -1,14 +1,10 @@ // SPDX-License-Identifier: LGPL-3.0-or-later // See Notices.txt for copyright information -use std::sync::OnceLock; - -use ordered_float::NotNan; - use crate::{ annotations::Annotation, intern::{Intern, Interned}, - module::{instance_with_loc, reg_builder_with_loc, wire_with_loc}, + module::instance_with_loc, platform::{ DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory, PeripheralsBuilderFinished, Platform, PlatformAspectSet, @@ -20,6 +16,8 @@ use crate::{ primitives::{self, BUFGCE, STARTUPE2_default_inputs}, }, }; +use ordered_float::NotNan; +use std::sync::OnceLock; macro_rules! arty_a7_platform { ( @@ -120,6 +118,45 @@ impl ArtyA7Platform { } } +#[hdl_module(extern)] +fn reset_sync() { + #[hdl] + let clk: Clock = m.input(); + #[hdl] + let inp: Bool = m.input(); + #[hdl] + let out: SyncReset = m.output(); + m.annotate_module(BlackBoxInlineAnnotation { + path: "fayalite_arty_a7_reset_sync.v".intern(), + text: r#"module __fayalite_arty_a7_reset_sync(input clk, input inp, output out); + wire reset_0_out; + (* ASYNC_REG = "TRUE" *) + FDPE #( + .INIT(1'b1) + ) reset_0 ( + .Q(reset_0_out), + .C(clk), + .CE(1'b1), + .PRE(inp), + .D(1'b0) + ); + (* ASYNC_REG = "TRUE" *) + FDPE #( + .INIT(1'b1) + ) reset_1 ( + .Q(out), + .C(clk), + .CE(1'b1), + .PRE(inp), + .D(reset_0_out) + ); +endmodule +"# + .intern(), + }); + m.verilog_name("__fayalite_arty_a7_reset_sync"); +} + impl Platform for ArtyA7Platform { type Peripherals = ArtyA7Peripherals; @@ -236,36 +273,17 @@ impl Platform for ArtyA7Platform { let clk100_sync = instance_with_loc("clk100_sync", BUFGCE(), SourceLocation::builtin()); connect(clk100_sync.CE, startup.EOS); connect(clk100_sync.I, clk100_buf); + annotate(clk100_sync.O, clock_annotation); if let Some(clk100) = clk100.into_used() { connect(clk100.instance_io_field().clk, clk100_sync.O); } - let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", &[], true); - let rst_sync_cd = wire_with_loc( - "rst_sync_cd", - SourceLocation::builtin(), - ClockDomain[AsyncReset], - ); - annotate(clk100_sync.O, clock_annotation); - connect(rst_sync_cd.clk, clk100_sync.O); - connect(rst_sync_cd.rst, rst_buf.to_async_reset()); - let [rst_sync_0, rst_sync_1] = std::array::from_fn(|index| { - let rst_sync = - reg_builder_with_loc(&format!("rst_sync_{index}"), SourceLocation::builtin()) - .clock_domain(rst_sync_cd) - .reset(true) - .build(); - annotate( - rst_sync, - SVAttributeAnnotation { - text: "ASYNC_REG = \"TRUE\"".intern(), - }, - ); - annotate(rst_sync, DontTouchAnnotation); - rst_sync - }); - connect(rst_sync_0, false); - connect(rst_sync_1, rst_sync_0); - let rst_value = rst_sync_1.to_sync_reset(); + let rst_value = { + let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", &[], true); + let rst_sync = instance_with_loc("rst_sync", reset_sync(), SourceLocation::builtin()); + connect(rst_sync.clk, clk100_sync.O); + connect(rst_sync.inp, rst_buf); + rst_sync.out + }; if let Some(rst) = rst.into_used() { connect(rst.instance_io_field(), rst_value.to_reset()); }