switch to using verilog for reset synchronizer so we can use attributes on FDPE instances

This commit is contained in:
Jacob Lifshay 2025-10-21 19:53:15 -07:00
parent 2bdc8a7c72
commit 409992961c
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ

View file

@ -1,14 +1,10 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information // See Notices.txt for copyright information
use std::sync::OnceLock;
use ordered_float::NotNan;
use crate::{ use crate::{
annotations::Annotation, annotations::Annotation,
intern::{Intern, Interned}, intern::{Intern, Interned},
module::{instance_with_loc, reg_builder_with_loc, wire_with_loc}, module::instance_with_loc,
platform::{ platform::{
DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory, DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory,
PeripheralsBuilderFinished, Platform, PlatformAspectSet, PeripheralsBuilderFinished, Platform, PlatformAspectSet,
@ -20,6 +16,8 @@ use crate::{
primitives::{self, BUFGCE, STARTUPE2_default_inputs}, primitives::{self, BUFGCE, STARTUPE2_default_inputs},
}, },
}; };
use ordered_float::NotNan;
use std::sync::OnceLock;
macro_rules! arty_a7_platform { 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 { impl Platform for ArtyA7Platform {
type Peripherals = ArtyA7Peripherals; type Peripherals = ArtyA7Peripherals;
@ -236,36 +273,17 @@ impl Platform for ArtyA7Platform {
let clk100_sync = instance_with_loc("clk100_sync", BUFGCE(), SourceLocation::builtin()); let clk100_sync = instance_with_loc("clk100_sync", BUFGCE(), SourceLocation::builtin());
connect(clk100_sync.CE, startup.EOS); connect(clk100_sync.CE, startup.EOS);
connect(clk100_sync.I, clk100_buf); connect(clk100_sync.I, clk100_buf);
annotate(clk100_sync.O, clock_annotation);
if let Some(clk100) = clk100.into_used() { if let Some(clk100) = clk100.into_used() {
connect(clk100.instance_io_field().clk, clk100_sync.O); connect(clk100.instance_io_field().clk, clk100_sync.O);
} }
let rst_value = {
let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", &[], true); let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", &[], true);
let rst_sync_cd = wire_with_loc( let rst_sync = instance_with_loc("rst_sync", reset_sync(), SourceLocation::builtin());
"rst_sync_cd", connect(rst_sync.clk, clk100_sync.O);
SourceLocation::builtin(), connect(rst_sync.inp, rst_buf);
ClockDomain[AsyncReset], rst_sync.out
); };
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();
if let Some(rst) = rst.into_used() { if let Some(rst) = rst.into_used() {
connect(rst.instance_io_field(), rst_value.to_reset()); connect(rst.instance_io_field(), rst_value.to_reset());
} }