switch to using verilog for reset synchronizer so we can use attributes on FDPE instances
This commit is contained in:
parent
2bdc8a7c72
commit
409992961c
1 changed files with 50 additions and 32 deletions
80
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
80
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue