Compare commits

..

1 commit

Author SHA1 Message Date
Tobias Alexandra Platen
3dd7b9b107 add lattice files 2026-01-18 11:50:59 +01:00
5 changed files with 123 additions and 344 deletions

View file

@ -2,14 +2,11 @@
// See Notices.txt for copyright information // See Notices.txt for copyright information
pub mod xilinx; pub mod xilinx;
pub mod lattice;
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> { pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
xilinx::built_in_job_kinds(); xilinx::built_in_job_kinds()
lattice::built_in_job_kinds()
} }
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> { pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
xilinx::built_in_platforms(); xilinx::built_in_platforms()
lattice::built_in_platforms()
} }

View file

@ -12,180 +12,4 @@ use ordered_float::NotNan;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
pub mod orangecrab; // copy of xilinx.rs with same header
pub mod primitives;
pub mod yosys_nextpnr;
/* fixme make_annotation_enum! {
#[non_exhaustive]
pub enum LatticeAnnotation {
XdcIOStandard(XdcIOStandardAnnotation),
XdcLocation(XdcLocationAnnotation),
XdcCreateClock(XdcCreateClockAnnotation),
}
} */
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct LatticeArgs {
#[arg(long)]
pub device: Option<Device>,
}
impl LatticeArgs {
pub fn require_device(
&self,
platform: Option<&DynPlatform>,
global_params: &GlobalParams,
) -> clap::error::Result<Device> {
if let Some(device) = self.device {
return Ok(device);
}
if let Some(device) =
platform.and_then(|platform| platform.aspects().get_single_by_type::<Device>().copied())
{
return Ok(device);
}
Err(global_params.clap_error(
clap::error::ErrorKind::MissingRequiredArgument,
"missing --device option",
))
}
}
impl ToArgs for LatticeArgs {
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
if let Some(device) = self.device {
args.write_long_option_eq("device", device.as_str());
}
}
}
macro_rules! make_device_enum {
($vis:vis enum $Device:ident {
$(
#[
name = $name:literal,
xray_part = $xray_part:literal,
xray_device = $xray_device:literal,
xray_family = $xray_family:literal,
]
$variant:ident,
)*
}) => {
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)]
$vis enum $Device {
$(
#[value(name = $name, alias = $xray_part)]
$variant,
)*
}
impl $Device {
$vis fn as_str(self) -> &'static str {
match self {
$(Self::$variant => $name,)*
}
}
$vis fn xray_part(self) -> &'static str {
match self {
$(Self::$variant => $xray_part,)*
}
}
$vis fn xray_device(self) -> &'static str {
match self {
$(Self::$variant => $xray_device,)*
}
}
$vis fn xray_family(self) -> &'static str {
match self {
$(Self::$variant => $xray_family,)*
}
}
}
struct DeviceVisitor;
impl<'de> serde::de::Visitor<'de> for DeviceVisitor {
type Value = $Device;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a Lattice device string")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match $Device::from_str(v, false) {
Ok(v) => Ok(v),
Err(_) => Err(E::invalid_value(serde::de::Unexpected::Str(v), &self)),
}
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
match str::from_utf8(v).ok().and_then(|v| $Device::from_str(v, false).ok()) {
Some(v) => Ok(v),
None => Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)),
}
}
}
impl<'de> Deserialize<'de> for $Device {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_string(DeviceVisitor)
}
}
impl Serialize for $Device {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.as_str().serialize(serializer)
}
}
};
}
make_device_enum! {
pub enum Device {
#[
name = "xc7a35ticsg324-1L",
xray_part = "xc7a35tcsg324-1",
xray_device = "xc7a35t",
xray_family = "artix7",
]
Xc7a35ticsg324_1l,
#[
name = "xc7a100ticsg324-1L",
xray_part = "xc7a100tcsg324-1",
xray_device = "xc7a100t",
xray_family = "artix7",
]
Xc7a100ticsg324_1l,
}
}
impl fmt::Display for Device {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
orangecrab::built_in_job_kinds()
.into_iter()
.chain(yosys_nextpnr::built_in_job_kinds())
}
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
orangecrab::built_in_platforms()
.into_iter()
.chain(yosys_nextpnr::built_in_platforms())
}

View file

@ -10,15 +10,15 @@ use crate::{
peripherals::{ClockInput, Led, RgbLed, Uart}, peripherals::{ClockInput, Led, RgbLed, Uart},
}, },
prelude::*, prelude::*,
vendor::lattice::{ vendor::xilinx::{
Device, Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation,
primitives, primitives,
}, },
}; };
use ordered_float::NotNan; use ordered_float::NotNan;
use std::sync::OnceLock; use std::sync::OnceLock;
macro_rules! orangecrab_platform { macro_rules! arty_a7_platform {
( (
$vis:vis enum $ArtyA7Platform:ident { $vis:vis enum $ArtyA7Platform:ident {
$(#[name = $name:literal, device = $device:ident] $(#[name = $name:literal, device = $device:ident]
@ -55,7 +55,7 @@ macro_rules! orangecrab_platform {
}; };
} }
orangecrab_platform! { arty_a7_platform! {
pub enum ArtyA7Platform { pub enum ArtyA7Platform {
#[name = "arty-a7-35t", device = Xc7a35ticsg324_1l] #[name = "arty-a7-35t", device = Xc7a35ticsg324_1l]
ArtyA7_35T, ArtyA7_35T,
@ -129,8 +129,8 @@ fn reset_sync() {
#[hdl] #[hdl]
let out: SyncReset = m.output(); let out: SyncReset = m.output();
m.annotate_module(BlackBoxInlineAnnotation { m.annotate_module(BlackBoxInlineAnnotation {
path: "fayalite_orangecrab_reset_sync.v".intern(), path: "fayalite_arty_a7_reset_sync.v".intern(),
text: r#"module __fayalite_orangecrab_reset_sync(input clk, input inp, output out); text: r#"module __fayalite_arty_a7_reset_sync(input clk, input inp, output out);
wire reset_0_out; wire reset_0_out;
(* ASYNC_REG = "TRUE" *) (* ASYNC_REG = "TRUE" *)
FDPE #( FDPE #(
@ -156,7 +156,7 @@ endmodule
"# "#
.intern(), .intern(),
}); });
m.verilog_name("__fayalite_orangecrab_reset_sync"); m.verilog_name("__fayalite_arty_a7_reset_sync");
} }
impl Platform for ArtyA7Platform { impl Platform for ArtyA7Platform {
@ -222,29 +222,7 @@ impl Platform for ArtyA7Platform {
} = 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, invert: bool| {
let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool); let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool);
/* fixme annotate( annotate(
pin,
XdcLocationAnnotation {
location: location.intern(),
},
); */
/* fixme annotate(
pin,
XdcIOStandardAnnotation {
value: io_standard.intern(),
},
); */
let buf = instance_with_loc(
&format!("{name}_buf"),
primitives::IBUF(),
SourceLocation::builtin(),
);
connect(buf.I, pin);
if invert { !buf.O } else { buf.O }
};
let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool);
/* fixme annotate(
pin, pin,
XdcLocationAnnotation { XdcLocationAnnotation {
location: location.intern(), location: location.intern(),
@ -255,7 +233,29 @@ impl Platform for ArtyA7Platform {
XdcIOStandardAnnotation { XdcIOStandardAnnotation {
value: io_standard.intern(), value: io_standard.intern(),
}, },
); */ );
let buf = instance_with_loc(
&format!("{name}_buf"),
primitives::IBUF(),
SourceLocation::builtin(),
);
connect(buf.I, pin);
if invert { !buf.O } else { buf.O }
};
let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool);
annotate(
pin,
XdcLocationAnnotation {
location: location.intern(),
},
);
annotate(
pin,
XdcIOStandardAnnotation {
value: io_standard.intern(),
},
);
let buf = instance_with_loc( let buf = instance_with_loc(
&format!("{name}_buf"), &format!("{name}_buf"),
primitives::OBUFT(), primitives::OBUFT(),
@ -301,14 +301,13 @@ impl Platform for ArtyA7Platform {
Clock, Clock,
); );
connect(clk_in, clk_global_buf_in); connect(clk_in, clk_global_buf_in);
/* fixme
annotate( annotate(
clk_in, clk_in,
XdcCreateClockAnnotation { XdcCreateClockAnnotation {
period: NotNan::new(1e9 / (100e6 / prev_divisor as f64)) period: NotNan::new(1e9 / (100e6 / prev_divisor as f64))
.expect("known to be valid"), .expect("known to be valid"),
}, },
); */ );
annotate(clk_in, DontTouchAnnotation); annotate(clk_in, DontTouchAnnotation);
let cd = wire_with_loc( let cd = wire_with_loc(
&format!("clk_div_{prev_divisor}_in"), &format!("clk_div_{prev_divisor}_in"),
@ -327,12 +326,12 @@ impl Platform for ArtyA7Platform {
connect(clk_global_buf.I, clk_global_buf_in); connect(clk_global_buf.I, clk_global_buf_in);
let clk_out = wire_with_loc("clk_out", SourceLocation::builtin(), Clock); let clk_out = wire_with_loc("clk_out", SourceLocation::builtin(), Clock);
connect(clk_out, clk_global_buf.O); connect(clk_out, clk_global_buf.O);
/* fixme annotate( annotate(
clk_out, clk_out,
XdcCreateClockAnnotation { XdcCreateClockAnnotation {
period: NotNan::new(1e9 / frequency).expect("known to be valid"), period: NotNan::new(1e9 / frequency).expect("known to be valid"),
}, },
); */ );
annotate(clk_out, DontTouchAnnotation); annotate(clk_out, DontTouchAnnotation);
if let Some(clk) = clk { if let Some(clk) = clk {
connect(clk.instance_io_field().clk, clk_out); connect(clk.instance_io_field().clk, clk_out);

View file

@ -5,46 +5,6 @@
use crate::prelude::*; use crate::prelude::*;
#[hdl_module(extern)] //#[hdl_module(extern)]
pub fn IBUF() { //pub fn PLACEHOLDER() {
m.verilog_name("IBUF"); //do this first
#[hdl]
let O: Bool = m.output();
#[hdl]
let I: Bool = m.input();
}
#[hdl_module(extern)]
pub fn OBUFT() {
m.verilog_name("OBUFT");
#[hdl]
let O: Bool = m.output();
#[hdl]
let I: Bool = m.input();
#[hdl]
let T: Bool = m.input();
}
#[hdl_module(extern)]
pub fn BUFGCE() {
m.verilog_name("BUFGCE");
#[hdl]
let O: Clock = m.output();
#[hdl]
let CE: Bool = m.input();
#[hdl]
let I: Clock = m.input();
}
#[hdl_module(extern)]
pub fn STARTUPE2_default_inputs() {
m.verilog_name("STARTUPE2");
#[hdl]
let CFGCLK: Clock = m.output();
#[hdl]
let CFGMCLK: Clock = m.output();
#[hdl]
let EOS: Bool = m.output();
#[hdl]
let PREQ: Bool = m.output();
}

View file

@ -24,8 +24,8 @@ use crate::{
source_location::SourceLocation, source_location::SourceLocation,
util::{HashSet, job_server::AcquiredJob}, util::{HashSet, job_server::AcquiredJob},
vendor::lattice::{ vendor::lattice::{
Device, Device, XdcCreateClockAnnotation, XdcIOStandardAnnotation, XdcLocationAnnotation,
/* fixme LatticeAnnotation,*/ LatticeArgs, LatticeAnnotation, LatticeArgs,
}, },
}; };
use eyre::Context; use eyre::Context;
@ -39,26 +39,26 @@ use std::{
}; };
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
pub struct YosysNextpnrXrayWriteYsFileJobKind; pub struct YosysNextpnrTrellisWriteYsFileJobKind;
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] #[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct YosysNextpnrXrayWriteYsFileArgs {} pub struct YosysNextpnrTrellisWriteYsFileArgs {}
impl ToArgs for YosysNextpnrXrayWriteYsFileArgs { impl ToArgs for YosysNextpnrTrellisWriteYsFileArgs {
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
let Self {} = self; let Self {} = self;
} }
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct YosysNextpnrXrayWriteYsFile { pub struct YosysNextpnrTrellisWriteYsFile {
main_verilog_file: Interned<Path>, main_verilog_file: Interned<Path>,
ys_file: Interned<Path>, ys_file: Interned<Path>,
json_file: Interned<Path>, json_file: Interned<Path>,
json_file_name: Interned<OsStr>, json_file_name: Interned<OsStr>,
} }
impl YosysNextpnrXrayWriteYsFile { impl YosysNextpnrTrellisWriteYsFile {
pub fn main_verilog_file(&self) -> Interned<Path> { pub fn main_verilog_file(&self) -> Interned<Path> {
self.main_verilog_file self.main_verilog_file
} }
@ -101,9 +101,9 @@ impl YosysNextpnrXrayWriteYsFile {
} }
} }
impl JobKind for YosysNextpnrXrayWriteYsFileJobKind { impl JobKind for YosysNextpnrTrellisWriteYsFileJobKind {
type Args = YosysNextpnrXrayWriteYsFileArgs; type Args = YosysNextpnrTrellisWriteYsFileArgs;
type Job = YosysNextpnrXrayWriteYsFile; type Job = YosysNextpnrTrellisWriteYsFile;
type Dependencies = JobKindAndDependencies<VerilogJobKind>; type Dependencies = JobKindAndDependencies<VerilogJobKind>;
fn dependencies(self) -> Self::Dependencies { fn dependencies(self) -> Self::Dependencies {
@ -123,11 +123,11 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
.verilog_dialect .verilog_dialect
.get_or_insert(VerilogDialect::Yosys); .get_or_insert(VerilogDialect::Yosys);
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
let YosysNextpnrXrayWriteYsFileArgs {} = args; let YosysNextpnrTrellisWriteYsFileArgs {} = args;
let base_job = dependencies.get_job::<BaseJob, _>(); let base_job = dependencies.get_job::<BaseJob, _>();
let verilog_job = dependencies.get_job::<VerilogJob, _>(); let verilog_job = dependencies.get_job::<VerilogJob, _>();
let json_file = base_job.file_with_ext("json"); let json_file = base_job.file_with_ext("json");
Ok(YosysNextpnrXrayWriteYsFile { Ok(YosysNextpnrTrellisWriteYsFile {
main_verilog_file: verilog_job.main_verilog_file(), main_verilog_file: verilog_job.main_verilog_file(),
ys_file: base_job.file_with_ext("ys"), ys_file: base_job.file_with_ext("ys"),
json_file, json_file,
@ -150,7 +150,7 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
} }
fn name(self) -> Interned<str> { fn name(self) -> Interned<str> {
"yosys-nextpnr-xray-write-ys-file".intern() "yosys-nextpnr-trellis-write-ys-file".intern()
} }
fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> { fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> {
@ -188,26 +188,26 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] #[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct YosysNextpnrXraySynthArgs {} pub struct YosysNextpnrTrellisSynthArgs {}
impl ToArgs for YosysNextpnrXraySynthArgs { impl ToArgs for YosysNextpnrTrellisSynthArgs {
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
let Self {} = self; let Self {} = self;
} }
} }
#[derive(Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] #[derive(Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
pub struct YosysNextpnrXraySynth { pub struct YosysNextpnrTrellisSynth {
#[serde(flatten)] #[serde(flatten)]
write_ys_file: YosysNextpnrXrayWriteYsFile, write_ys_file: YosysNextpnrTrellisWriteYsFile,
ys_file_name: Interned<OsStr>, ys_file_name: Interned<OsStr>,
} }
impl fmt::Debug for YosysNextpnrXraySynth { impl fmt::Debug for YosysNextpnrTrellisSynth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { let Self {
write_ys_file: write_ys_file:
YosysNextpnrXrayWriteYsFile { YosysNextpnrTrellisWriteYsFile {
main_verilog_file, main_verilog_file,
ys_file, ys_file,
json_file, json_file,
@ -215,7 +215,7 @@ impl fmt::Debug for YosysNextpnrXraySynth {
}, },
ys_file_name, ys_file_name,
} = self; } = self;
f.debug_struct("YosysNextpnrXraySynth") f.debug_struct("YosysNextpnrTrellisSynth")
.field("main_verilog_file", main_verilog_file) .field("main_verilog_file", main_verilog_file)
.field("ys_file", ys_file) .field("ys_file", ys_file)
.field("ys_file_name", ys_file_name) .field("ys_file_name", ys_file_name)
@ -225,7 +225,7 @@ impl fmt::Debug for YosysNextpnrXraySynth {
} }
} }
impl YosysNextpnrXraySynth { impl YosysNextpnrTrellisSynth {
pub fn main_verilog_file(&self) -> Interned<Path> { pub fn main_verilog_file(&self) -> Interned<Path> {
self.write_ys_file.main_verilog_file() self.write_ys_file.main_verilog_file()
} }
@ -252,15 +252,15 @@ impl ExternalProgramTrait for Yosys {
} }
} }
impl ExternalCommand for YosysNextpnrXraySynth { impl ExternalCommand for YosysNextpnrTrellisSynth {
type AdditionalArgs = YosysNextpnrXraySynthArgs; type AdditionalArgs = YosysNextpnrTrellisSynthArgs;
type AdditionalJobData = Self; type AdditionalJobData = Self;
type BaseJobPosition = GetJobPositionDependencies< type BaseJobPosition = GetJobPositionDependencies<
GetJobPositionDependencies< GetJobPositionDependencies<
GetJobPositionDependencies<<UnadjustedVerilog as ExternalCommand>::BaseJobPosition>, GetJobPositionDependencies<<UnadjustedVerilog as ExternalCommand>::BaseJobPosition>,
>, >,
>; >;
type Dependencies = JobKindAndDependencies<YosysNextpnrXrayWriteYsFileJobKind>; type Dependencies = JobKindAndDependencies<YosysNextpnrTrellisWriteYsFileJobKind>;
type ExternalProgram = Yosys; type ExternalProgram = Yosys;
fn dependencies() -> Self::Dependencies { fn dependencies() -> Self::Dependencies {
@ -276,7 +276,7 @@ impl ExternalCommand for YosysNextpnrXraySynth {
<Self::Dependencies as JobDependencies>::JobsAndKinds, <Self::Dependencies as JobDependencies>::JobsAndKinds,
)> { )> {
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
let YosysNextpnrXraySynthArgs {} = args.additional_args; let YosysNextpnrTrellisSynthArgs {} = args.additional_args;
Ok(Self { Ok(Self {
write_ys_file: dependencies.job.job.clone(), write_ys_file: dependencies.job.job.clone(),
ys_file_name: dependencies ys_file_name: dependencies
@ -318,7 +318,7 @@ impl ExternalCommand for YosysNextpnrXraySynth {
} }
fn job_kind_name() -> Interned<str> { fn job_kind_name() -> Interned<str> {
"yosys-nextpnr-xray-synth".intern() "yosys-nextpnr-trellis-synth".intern()
} }
fn subcommand_hidden() -> bool { fn subcommand_hidden() -> bool {
@ -327,19 +327,19 @@ impl ExternalCommand for YosysNextpnrXraySynth {
} }
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
pub struct YosysNextpnrXrayWriteXdcFileJobKind; pub struct YosysNextpnrTrellisWriteXdcFileJobKind;
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] #[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct YosysNextpnrXrayWriteXdcFileArgs {} pub struct YosysNextpnrTrellisWriteXdcFileArgs {}
impl ToArgs for YosysNextpnrXrayWriteXdcFileArgs { impl ToArgs for YosysNextpnrTrellisWriteXdcFileArgs {
fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) {
let Self {} = self; let Self {} = self;
} }
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct YosysNextpnrXrayWriteXdcFile { pub struct YosysNextpnrTrellisWriteXdcFile {
firrtl_export_options: crate::firrtl::ExportOptions, firrtl_export_options: crate::firrtl::ExportOptions,
output_dir: Interned<Path>, output_dir: Interned<Path>,
xdc_file: Interned<Path>, xdc_file: Interned<Path>,
@ -486,8 +486,7 @@ impl<W: fmt::Write> Visitor for XdcFileWriter<W> {
Ok(()) Ok(())
} }
fn visit_lattice_annotation(&mut self, v: &LatticeAnnotation) -> Result<(), Self::Error> {
/* FIXME fn visit_lattice_annotation(&mut self, v: &LatticeAnnotation) -> Result<(), Self::Error> {
fn todo( fn todo(
msg: &str, msg: &str,
annotation: &LatticeAnnotation, annotation: &LatticeAnnotation,
@ -596,17 +595,17 @@ impl<W: fmt::Write> Visitor for XdcFileWriter<W> {
} }
} }
} }
} */ }
} }
impl YosysNextpnrXrayWriteXdcFile { impl YosysNextpnrTrellisWriteXdcFile {
fn write_xdc_contents_for_port_and_annotations( fn write_xdc_contents_for_port_and_annotations(
&self, &self,
output: &mut impl fmt::Write, output: &mut impl fmt::Write,
port: &ScalarizedModuleABIPort, port: &ScalarizedModuleABIPort,
annotations: ScalarizedModuleABIAnnotations<'_>, annotations: ScalarizedModuleABIAnnotations<'_>,
) -> Result<(), WriteXdcContentsError> { ) -> Result<(), WriteXdcContentsError> {
/* fixme for annotation in annotations { for annotation in annotations {
match annotation.annotation() { match annotation.annotation() {
Annotation::DontTouch(_) Annotation::DontTouch(_)
| Annotation::SVAttribute(_) | Annotation::SVAttribute(_)
@ -638,7 +637,7 @@ impl YosysNextpnrXrayWriteXdcFile {
tcl_escape(port.scalarized_name()), tcl_escape(port.scalarized_name()),
)?, )?,
} }
} */ }
Ok(()) Ok(())
} }
fn write_xdc_contents( fn write_xdc_contents(
@ -662,10 +661,10 @@ impl YosysNextpnrXrayWriteXdcFile {
} }
} }
impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind { impl JobKind for YosysNextpnrTrellisWriteXdcFileJobKind {
type Args = YosysNextpnrXrayWriteXdcFileArgs; type Args = YosysNextpnrTrellisWriteXdcFileArgs;
type Job = YosysNextpnrXrayWriteXdcFile; type Job = YosysNextpnrTrellisWriteXdcFile;
type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrXraySynth>>; type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrTrellisSynth>>;
fn dependencies(self) -> Self::Dependencies { fn dependencies(self) -> Self::Dependencies {
Default::default() Default::default()
@ -686,9 +685,9 @@ impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind {
.args .args
.export_options; .export_options;
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
let YosysNextpnrXrayWriteXdcFileArgs {} = args; let YosysNextpnrTrellisWriteXdcFileArgs {} = args;
let base_job = dependencies.get_job::<BaseJob, _>(); let base_job = dependencies.get_job::<BaseJob, _>();
Ok(YosysNextpnrXrayWriteXdcFile { Ok(YosysNextpnrTrellisWriteXdcFile {
firrtl_export_options, firrtl_export_options,
output_dir: base_job.output_dir(), output_dir: base_job.output_dir(),
xdc_file: base_job.file_with_ext("xdc"), xdc_file: base_job.file_with_ext("xdc"),
@ -708,7 +707,7 @@ impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind {
} }
fn name(self) -> Interned<str> { fn name(self) -> Interned<str> {
"yosys-nextpnr-xray-write-xdc-file".intern() "yosys-nextpnr-trellis-write-xdc-file".intern()
} }
fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> { fn external_command_params(self, _job: &Self::Job) -> Option<CommandParams> {
@ -740,12 +739,12 @@ pub struct NextpnrLattice;
impl ExternalProgramTrait for NextpnrLattice { impl ExternalProgramTrait for NextpnrLattice {
fn default_program_name() -> Interned<str> { fn default_program_name() -> Interned<str> {
"nextpnr".intern() "nextpnr-lattice".intern()
} }
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] #[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct YosysNextpnrXrayRunNextpnrArgs { pub struct YosysNextpnrTrellisRunNextpnrArgs {
#[command(flatten)] #[command(flatten)]
pub common: LatticeArgs, pub common: LatticeArgs,
#[arg(long, env = "CHIPDB_DIR", value_hint = clap::ValueHint::DirPath)] #[arg(long, env = "CHIPDB_DIR", value_hint = clap::ValueHint::DirPath)]
@ -754,7 +753,7 @@ pub struct YosysNextpnrXrayRunNextpnrArgs {
pub nextpnr_lattice_seed: i32, pub nextpnr_lattice_seed: i32,
} }
impl ToArgs for YosysNextpnrXrayRunNextpnrArgs { impl ToArgs for YosysNextpnrTrellisRunNextpnrArgs {
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
let Self { let Self {
common, common,
@ -768,7 +767,7 @@ impl ToArgs for YosysNextpnrXrayRunNextpnrArgs {
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct YosysNextpnrXrayRunNextpnr { pub struct YosysNextpnrTrellisRunNextpnr {
nextpnr_lattice_chipdb_dir: Interned<Path>, nextpnr_lattice_chipdb_dir: Interned<Path>,
device: Device, device: Device,
nextpnr_lattice_seed: i32, nextpnr_lattice_seed: i32,
@ -782,23 +781,23 @@ pub struct YosysNextpnrXrayRunNextpnr {
fasm_file_name: Interned<OsStr>, fasm_file_name: Interned<OsStr>,
} }
impl YosysNextpnrXrayRunNextpnr { impl YosysNextpnrTrellisRunNextpnr {
fn chipdb_file(&self) -> Interned<Path> { fn chipdb_file(&self) -> Interned<Path> {
let mut retval = self let mut retval = self
.nextpnr_lattice_chipdb_dir .nextpnr_lattice_chipdb_dir
.join(self.device.xray_device()); .join(self.device.trellis_device());
retval.set_extension("bin"); retval.set_extension("bin");
retval.intern_deref() retval.intern_deref()
} }
} }
impl ExternalCommand for YosysNextpnrXrayRunNextpnr { impl ExternalCommand for YosysNextpnrTrellisRunNextpnr {
type AdditionalArgs = YosysNextpnrXrayRunNextpnrArgs; type AdditionalArgs = YosysNextpnrTrellisRunNextpnrArgs;
type AdditionalJobData = Self; type AdditionalJobData = Self;
type BaseJobPosition = GetJobPositionDependencies< type BaseJobPosition = GetJobPositionDependencies<
GetJobPositionDependencies<<YosysNextpnrXraySynth as ExternalCommand>::BaseJobPosition>, GetJobPositionDependencies<<YosysNextpnrTrellisSynth as ExternalCommand>::BaseJobPosition>,
>; >;
type Dependencies = JobKindAndDependencies<YosysNextpnrXrayWriteXdcFileJobKind>; type Dependencies = JobKindAndDependencies<YosysNextpnrTrellisWriteXdcFileJobKind>;
type ExternalProgram = NextpnrLattice; type ExternalProgram = NextpnrLattice;
fn dependencies() -> Self::Dependencies { fn dependencies() -> Self::Dependencies {
@ -814,14 +813,14 @@ impl ExternalCommand for YosysNextpnrXrayRunNextpnr {
<Self::Dependencies as JobDependencies>::JobsAndKinds, <Self::Dependencies as JobDependencies>::JobsAndKinds,
)> { )> {
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
let YosysNextpnrXrayRunNextpnrArgs { let YosysNextpnrTrellisRunNextpnrArgs {
common, common,
nextpnr_lattice_chipdb_dir, nextpnr_lattice_chipdb_dir,
nextpnr_lattice_seed, nextpnr_lattice_seed,
} = args.additional_args; } = args.additional_args;
let base_job = dependencies.get_job::<BaseJob, _>(); let base_job = dependencies.get_job::<BaseJob, _>();
let write_xdc_file = dependencies.get_job::<YosysNextpnrXrayWriteXdcFile, _>(); let write_xdc_file = dependencies.get_job::<YosysNextpnrTrellisWriteXdcFile, _>();
let synth = dependencies.get_job::<ExternalCommandJob<YosysNextpnrXraySynth>, _>(); let synth = dependencies.get_job::<ExternalCommandJob<YosysNextpnrTrellisSynth>, _>();
let routed_json_file = base_job.file_with_ext("routed.json"); let routed_json_file = base_job.file_with_ext("routed.json");
let fasm_file = base_job.file_with_ext("fasm"); let fasm_file = base_job.file_with_ext("fasm");
Ok(Self { Ok(Self {
@ -868,7 +867,7 @@ impl ExternalCommand for YosysNextpnrXrayRunNextpnr {
} }
fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) { fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) {
let job_data @ YosysNextpnrXrayRunNextpnr { let job_data @ YosysNextpnrTrellisRunNextpnr {
nextpnr_lattice_seed, nextpnr_lattice_seed,
xdc_file_name, xdc_file_name,
json_file_name, json_file_name,
@ -889,7 +888,7 @@ impl ExternalCommand for YosysNextpnrXrayRunNextpnr {
} }
fn job_kind_name() -> Interned<str> { fn job_kind_name() -> Interned<str> {
"yosys-nextpnr-xray-run-nextpnr".intern() "yosys-nextpnr-trellis-run-nextpnr".intern()
} }
fn subcommand_hidden() -> bool { fn subcommand_hidden() -> bool {
@ -907,21 +906,21 @@ impl ExternalProgramTrait for Xcfasm {
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] #[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
pub struct YosysNextpnrXrayArgs { pub struct YosysNextpnrTrellisArgs {
#[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)] #[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)]
pub prjxray_db_dir: PathBuf, pub prjtrellis_db_dir: PathBuf,
} }
impl ToArgs for YosysNextpnrXrayArgs { impl ToArgs for YosysNextpnrTrellisArgs {
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
let Self { prjxray_db_dir } = self; let Self { prjtrellis_db_dir } = self;
args.write_long_option_eq("prjxray-db-dir", prjxray_db_dir); args.write_long_option_eq("prjtrellis-db-dir", prjtrellis_db_dir);
} }
} }
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
pub struct YosysNextpnrXray { pub struct YosysNextpnrTrellis {
prjxray_db_dir: Interned<Path>, prjtrellis_db_dir: Interned<Path>,
device: Device, device: Device,
fasm_file: Interned<Path>, fasm_file: Interned<Path>,
fasm_file_name: Interned<OsStr>, fasm_file_name: Interned<OsStr>,
@ -931,27 +930,27 @@ pub struct YosysNextpnrXray {
bit_file_name: Interned<OsStr>, bit_file_name: Interned<OsStr>,
} }
impl YosysNextpnrXray { impl YosysNextpnrTrellis {
fn db_root(&self) -> Interned<Path> { fn db_root(&self) -> Interned<Path> {
self.prjxray_db_dir self.prjtrellis_db_dir
.join(self.device.xray_family()) .join(self.device.trellis_family())
.intern_deref() .intern_deref()
} }
fn part_file(&self) -> Interned<Path> { fn part_file(&self) -> Interned<Path> {
let mut retval = self.prjxray_db_dir.join(self.device.xray_family()); let mut retval = self.prjtrellis_db_dir.join(self.device.trellis_family());
retval.push(self.device.xray_part()); retval.push(self.device.trellis_part());
retval.push("part.yaml"); retval.push("part.yaml");
retval.intern_deref() retval.intern_deref()
} }
} }
impl ExternalCommand for YosysNextpnrXray { impl ExternalCommand for YosysNextpnrTrellis {
type AdditionalArgs = YosysNextpnrXrayArgs; type AdditionalArgs = YosysNextpnrTrellisArgs;
type AdditionalJobData = Self; type AdditionalJobData = Self;
type BaseJobPosition = GetJobPositionDependencies< type BaseJobPosition = GetJobPositionDependencies<
<YosysNextpnrXrayRunNextpnr as ExternalCommand>::BaseJobPosition, <YosysNextpnrTrellisRunNextpnr as ExternalCommand>::BaseJobPosition,
>; >;
type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrXrayRunNextpnr>>; type Dependencies = JobKindAndDependencies<ExternalCommandJobKind<YosysNextpnrTrellisRunNextpnr>>;
type ExternalProgram = Xcfasm; type ExternalProgram = Xcfasm;
fn dependencies() -> Self::Dependencies { fn dependencies() -> Self::Dependencies {
@ -967,12 +966,12 @@ impl ExternalCommand for YosysNextpnrXray {
<Self::Dependencies as JobDependencies>::JobsAndKinds, <Self::Dependencies as JobDependencies>::JobsAndKinds,
)> { )> {
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
let YosysNextpnrXrayArgs { prjxray_db_dir } = args.additional_args; let YosysNextpnrTrellisArgs { prjtrellis_db_dir } = args.additional_args;
let base_job = dependencies.get_job::<BaseJob, _>(); let base_job = dependencies.get_job::<BaseJob, _>();
let frames_file = base_job.file_with_ext("frames"); let frames_file = base_job.file_with_ext("frames");
let bit_file = base_job.file_with_ext("bit"); let bit_file = base_job.file_with_ext("bit");
Ok(Self { Ok(Self {
prjxray_db_dir: prjxray_db_dir.intern_deref(), prjtrellis_db_dir: prjtrellis_db_dir.intern_deref(),
device: dependencies.job.job.additional_job_data().device, device: dependencies.job.job.additional_job_data().device,
fasm_file: dependencies.job.job.additional_job_data().fasm_file, fasm_file: dependencies.job.job.additional_job_data().fasm_file,
fasm_file_name: dependencies.job.job.additional_job_data().fasm_file_name, fasm_file_name: dependencies.job.job.additional_job_data().fasm_file_name,
@ -1004,7 +1003,7 @@ impl ExternalCommand for YosysNextpnrXray {
} }
fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) { fn command_line_args<W: ?Sized + WriteArgs>(job: &ExternalCommandJob<Self>, args: &mut W) {
let job_data @ YosysNextpnrXray { let job_data @ YosysNextpnrTrellis {
device, device,
fasm_file_name, fasm_file_name,
frames_file_name, frames_file_name,
@ -1013,7 +1012,7 @@ impl ExternalCommand for YosysNextpnrXray {
} = job.additional_job_data(); } = job.additional_job_data();
args.write_arg("--sparse"); args.write_arg("--sparse");
args.write_long_option_eq("db-root", job_data.db_root()); args.write_long_option_eq("db-root", job_data.db_root());
args.write_long_option_eq("part", device.xray_part()); args.write_long_option_eq("part", device.trellis_part());
args.write_long_option_eq("part_file", job_data.part_file()); args.write_long_option_eq("part_file", job_data.part_file());
args.write_long_option_eq("fn_in", fasm_file_name); args.write_long_option_eq("fn_in", fasm_file_name);
args.write_long_option_eq("frm_out", frames_file_name); args.write_long_option_eq("frm_out", frames_file_name);
@ -1025,17 +1024,17 @@ impl ExternalCommand for YosysNextpnrXray {
} }
fn job_kind_name() -> Interned<str> { fn job_kind_name() -> Interned<str> {
"yosys-nextpnr-xray".intern() "yosys-nextpnr-trellis".intern()
} }
} }
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = DynJobKind> { pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = DynJobKind> {
[ [
DynJobKind::new(YosysNextpnrXrayWriteYsFileJobKind), DynJobKind::new(YosysNextpnrTrellisWriteYsFileJobKind),
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrXraySynth>::new()), DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrTrellisSynth>::new()),
DynJobKind::new(YosysNextpnrXrayWriteXdcFileJobKind), DynJobKind::new(YosysNextpnrTrellisWriteXdcFileJobKind),
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrXrayRunNextpnr>::new()), DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrTrellisRunNextpnr>::new()),
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrXray>::new()), DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrTrellis>::new()),
] ]
} }