WIP adding xdc create_clock -- nextpnr-xilinx currently ignores it
All checks were successful
/ test (pull_request) Successful in 4m35s
All checks were successful
/ test (pull_request) Successful in 4m35s
This commit is contained in:
parent
477a1f2d29
commit
2bdc8a7c72
6 changed files with 53 additions and 10 deletions
|
@ -1907,7 +1907,8 @@ impl<'a> Exporter<'a> {
|
||||||
additional_fields: (*additional_fields).into(),
|
additional_fields: (*additional_fields).into(),
|
||||||
},
|
},
|
||||||
Annotation::Xilinx(XilinxAnnotation::XdcLocation(_))
|
Annotation::Xilinx(XilinxAnnotation::XdcLocation(_))
|
||||||
| Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(_)) => return,
|
| Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(_))
|
||||||
|
| Annotation::Xilinx(XilinxAnnotation::XdcCreateClock(_)) => return,
|
||||||
};
|
};
|
||||||
self.annotations.push(FirrtlAnnotation {
|
self.annotations.push(FirrtlAnnotation {
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -33,7 +33,9 @@ use crate::{
|
||||||
sim::{ExternModuleSimulation, value::DynSimOnly},
|
sim::{ExternModuleSimulation, value::DynSimOnly},
|
||||||
source_location::SourceLocation,
|
source_location::SourceLocation,
|
||||||
ty::{CanonicalType, Type},
|
ty::{CanonicalType, Type},
|
||||||
vendor::xilinx::{XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation},
|
vendor::xilinx::{
|
||||||
|
XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation,
|
||||||
|
},
|
||||||
wire::Wire,
|
wire::Wire,
|
||||||
};
|
};
|
||||||
use num_bigint::{BigInt, BigUint};
|
use num_bigint::{BigInt, BigUint};
|
||||||
|
|
8
crates/fayalite/src/vendor/xilinx.rs
vendored
8
crates/fayalite/src/vendor/xilinx.rs
vendored
|
@ -8,6 +8,7 @@ use crate::{
|
||||||
prelude::{DynPlatform, Platform},
|
prelude::{DynPlatform, Platform},
|
||||||
};
|
};
|
||||||
use clap::ValueEnum;
|
use clap::ValueEnum;
|
||||||
|
use ordered_float::NotNan;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
@ -25,11 +26,18 @@ pub struct XdcLocationAnnotation {
|
||||||
pub location: Interned<str>,
|
pub location: Interned<str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
pub struct XdcCreateClockAnnotation {
|
||||||
|
/// clock period in nanoseconds
|
||||||
|
pub period: NotNan<f64>,
|
||||||
|
}
|
||||||
|
|
||||||
make_annotation_enum! {
|
make_annotation_enum! {
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum XilinxAnnotation {
|
pub enum XilinxAnnotation {
|
||||||
XdcIOStandard(XdcIOStandardAnnotation),
|
XdcIOStandard(XdcIOStandardAnnotation),
|
||||||
XdcLocation(XdcLocationAnnotation),
|
XdcLocation(XdcLocationAnnotation),
|
||||||
|
XdcCreateClock(XdcCreateClockAnnotation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
26
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
|
@ -3,7 +3,10 @@
|
||||||
|
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
|
use ordered_float::NotNan;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
annotations::Annotation,
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
module::{instance_with_loc, reg_builder_with_loc, wire_with_loc},
|
module::{instance_with_loc, reg_builder_with_loc, wire_with_loc},
|
||||||
platform::{
|
platform::{
|
||||||
|
@ -13,7 +16,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
vendor::xilinx::{
|
vendor::xilinx::{
|
||||||
Device, XdcIOStandardAnnotation, XdcLocationAnnotation,
|
Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation,
|
||||||
primitives::{self, BUFGCE, STARTUPE2_default_inputs},
|
primitives::{self, BUFGCE, STARTUPE2_default_inputs},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -165,7 +168,11 @@ impl Platform for ArtyA7Platform {
|
||||||
ld6,
|
ld6,
|
||||||
ld7,
|
ld7,
|
||||||
} = peripherals;
|
} = peripherals;
|
||||||
let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| {
|
let make_buffered_input = |name: &str,
|
||||||
|
location: &str,
|
||||||
|
io_standard: &str,
|
||||||
|
additional_annotations: &[Annotation],
|
||||||
|
invert: bool| {
|
||||||
let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool);
|
let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool);
|
||||||
annotate(
|
annotate(
|
||||||
pin,
|
pin,
|
||||||
|
@ -179,6 +186,7 @@ impl Platform for ArtyA7Platform {
|
||||||
value: io_standard.intern(),
|
value: io_standard.intern(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
annotate(pin, additional_annotations);
|
||||||
let buf = instance_with_loc(
|
let buf = instance_with_loc(
|
||||||
&format!("{name}_buf"),
|
&format!("{name}_buf"),
|
||||||
primitives::IBUF(),
|
primitives::IBUF(),
|
||||||
|
@ -210,7 +218,16 @@ impl Platform for ArtyA7Platform {
|
||||||
connect(buf.T, false);
|
connect(buf.T, false);
|
||||||
buf.I
|
buf.I
|
||||||
};
|
};
|
||||||
let clk100_buf = make_buffered_input("clk100", "E3", "LVCMOS33", false);
|
let clock_annotation = XdcCreateClockAnnotation {
|
||||||
|
period: NotNan::new(1e9 / clk100.ty().frequency()).expect("known to be valid"),
|
||||||
|
};
|
||||||
|
let clk100_buf = make_buffered_input(
|
||||||
|
"clk100",
|
||||||
|
"E3",
|
||||||
|
"LVCMOS33",
|
||||||
|
&[clock_annotation.into()],
|
||||||
|
false,
|
||||||
|
);
|
||||||
let startup = instance_with_loc(
|
let startup = instance_with_loc(
|
||||||
"startup",
|
"startup",
|
||||||
STARTUPE2_default_inputs(),
|
STARTUPE2_default_inputs(),
|
||||||
|
@ -222,12 +239,13 @@ impl Platform for ArtyA7Platform {
|
||||||
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_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_cd = wire_with_loc(
|
||||||
"rst_sync_cd",
|
"rst_sync_cd",
|
||||||
SourceLocation::builtin(),
|
SourceLocation::builtin(),
|
||||||
ClockDomain[AsyncReset],
|
ClockDomain[AsyncReset],
|
||||||
);
|
);
|
||||||
|
annotate(clk100_sync.O, clock_annotation);
|
||||||
connect(rst_sync_cd.clk, clk100_sync.O);
|
connect(rst_sync_cd.clk, clk100_sync.O);
|
||||||
connect(rst_sync_cd.rst, rst_buf.to_async_reset());
|
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_0, rst_sync_1] = std::array::from_fn(|index| {
|
||||||
|
|
|
@ -19,7 +19,8 @@ use crate::{
|
||||||
prelude::JobParams,
|
prelude::JobParams,
|
||||||
util::job_server::AcquiredJob,
|
util::job_server::AcquiredJob,
|
||||||
vendor::xilinx::{
|
vendor::xilinx::{
|
||||||
Device, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation, XilinxArgs,
|
Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation,
|
||||||
|
XilinxAnnotation, XilinxArgs,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use eyre::Context;
|
use eyre::Context;
|
||||||
|
@ -390,7 +391,7 @@ impl YosysNextpnrXrayWriteXdcFile {
|
||||||
output,
|
output,
|
||||||
"set_property LOC {} [get_ports {}]",
|
"set_property LOC {} [get_ports {}]",
|
||||||
tcl_escape(location),
|
tcl_escape(location),
|
||||||
tcl_escape(port.scalarized_name())
|
tcl_escape(port.scalarized_name()),
|
||||||
)?,
|
)?,
|
||||||
Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(XdcIOStandardAnnotation {
|
Annotation::Xilinx(XilinxAnnotation::XdcIOStandard(XdcIOStandardAnnotation {
|
||||||
value,
|
value,
|
||||||
|
@ -398,7 +399,14 @@ impl YosysNextpnrXrayWriteXdcFile {
|
||||||
output,
|
output,
|
||||||
"set_property IOSTANDARD {} [get_ports {}]",
|
"set_property IOSTANDARD {} [get_ports {}]",
|
||||||
tcl_escape(value),
|
tcl_escape(value),
|
||||||
tcl_escape(port.scalarized_name())
|
tcl_escape(port.scalarized_name()),
|
||||||
|
)?,
|
||||||
|
Annotation::Xilinx(XilinxAnnotation::XdcCreateClock(
|
||||||
|
XdcCreateClockAnnotation { period },
|
||||||
|
)) => writeln!(
|
||||||
|
output,
|
||||||
|
"create_clock -period {period} [get_ports {}]",
|
||||||
|
tcl_escape(port.scalarized_name()),
|
||||||
)?,
|
)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1219,7 +1219,8 @@
|
||||||
"data": {
|
"data": {
|
||||||
"$kind": "Enum",
|
"$kind": "Enum",
|
||||||
"XdcLocation": "Visible",
|
"XdcLocation": "Visible",
|
||||||
"XdcIOStandard": "Visible"
|
"XdcIOStandard": "Visible",
|
||||||
|
"XdcCreateClock": "Visible"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"XdcLocationAnnotation": {
|
"XdcLocationAnnotation": {
|
||||||
|
@ -1232,6 +1233,11 @@
|
||||||
"$kind": "Opaque"
|
"$kind": "Opaque"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"XdcCreateClockAnnotation": {
|
||||||
|
"data": {
|
||||||
|
"$kind": "Opaque"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Target": {
|
"Target": {
|
||||||
"data": {
|
"data": {
|
||||||
"$kind": "Enum",
|
"$kind": "Enum",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue