diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3aaa2a7 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +DIRU=/home/alex/Hacking/FPGA/libre-chip/fayalite/target/blinky-out +NEXTPNR_DENSITY:=--85k + +# --nextpnr /home/alex/.guix-profile/bin/nextpnr-ecp5 \ +# --ecppack /home/alex/.guix-profile/bin/ecppack \ +# --yosys /home/alex/.guix-profile/bin/yosys +# firtool executed with qemu +#FIXME --placeholder-dir + +all: + #cp $(DIRU)/*.pcf /tmp + RUST_BACKTRACE=full cargo run --example blinky yosys-nextpnr-ecp5 \ + --platform orangecrab-85k -o target/blinky-out \ + --placeholder-dir /home/alex/Hacking/FPGA/orangecrab/orangecrab-examples/fayalite/orangecrab_r0.2.1.pcf \ + --nextpnr /usr/bin/nextpnr-ecp5 + #ls -1 $(DIRU)/*.bit +ls: + ls -1 $(DIRU) +clean: + rm $(DIRU)/* +nextpnr: + cd $(DIRU) && nextpnr-ecp5 --json blinky.json --textcfg blinky.nextpnr.out $(NEXTPNR_DENSITY) \ + --package CSFBGA285 --lpf /home/alex/Hacking/FPGA/orangecrab/orangecrab-examples/fayalite/orangecrab_r0.2.1.pcf --lpf-allow-unconstrained +pack: + cd $(DIRU) && ecppack --compress --freq 38.8 --input blinky.nextpnr.out --bit blinky.nextpnr.bit + cd $(DIRU) && file *.bit +clean2: + find . -name "*.bit" -exec rm {} \; +ls2: + find . -name "*.bit" diff --git a/crates/fayalite/src/vendor.rs b/crates/fayalite/src/vendor.rs index cdf302d..e7aff58 100644 --- a/crates/fayalite/src/vendor.rs +++ b/crates/fayalite/src/vendor.rs @@ -2,11 +2,14 @@ // See Notices.txt for copyright information pub mod xilinx; +pub mod lattice; pub(crate) fn built_in_job_kinds() -> impl IntoIterator { - xilinx::built_in_job_kinds() + xilinx::built_in_job_kinds(); + lattice::built_in_job_kinds() } pub(crate) fn built_in_platforms() -> impl IntoIterator { - xilinx::built_in_platforms() + xilinx::built_in_platforms(); + lattice::built_in_platforms() } diff --git a/crates/fayalite/src/vendor/lattice.rs b/crates/fayalite/src/vendor/lattice.rs new file mode 100644 index 0000000..6b89799 --- /dev/null +++ b/crates/fayalite/src/vendor/lattice.rs @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::{ + annotations::make_annotation_enum, + build::{GlobalParams, ToArgs, WriteArgs}, + intern::Interned, + prelude::{DynPlatform, Platform}, +}; +use clap::ValueEnum; +use ordered_float::NotNan; +use serde::{Deserialize, Serialize}; +use std::fmt; + +pub mod orangecrab; +pub mod primitives; +pub mod yosys_nextpnr; + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct LatticeArgs { + #[arg(long)] + pub device: Option, +} + +impl LatticeArgs { + pub fn require_device( + &self, + platform: Option<&DynPlatform>, + global_params: &GlobalParams, + ) -> clap::error::Result { + if let Some(device) = self.device { + return Ok(device); + } + if let Some(device) = + platform.and_then(|platform| platform.aspects().get_single_by_type::().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, + lattice_part = $lattice_part:literal, + lattice_device = $lattice_device:literal, + lattice_family = $lattice_family:literal, + ] + $variant:ident, + )* + }) => { + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)] + $vis enum $Device { + $( + #[value(name = $name, alias = $lattice_part)] + $variant, + )* + } + + impl $Device { + $vis fn as_str(self) -> &'static str { + match self { + $(Self::$variant => $name,)* + } + } + $vis fn lattice_part(self) -> &'static str { + match self { + $(Self::$variant => $lattice_part,)* + } + } + $vis fn lattice_device(self) -> &'static str { + match self { + $(Self::$variant => $lattice_device,)* + } + } + $vis fn lattice_family(self) -> &'static str { + match self { + $(Self::$variant => $lattice_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(self, v: &str) -> Result + 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(self, v: &[u8]) -> Result + 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(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_string(DeviceVisitor) + } + } + + impl Serialize for $Device { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.as_str().serialize(serializer) + } + } + }; +} + +//ECP5 variants -- needs fixme +make_device_enum! { + pub enum Device { + #[ + name = "placeholder25k", + lattice_part = "fixme", + lattice_device = "fixme", + lattice_family = "fixme", + ] + Placeholder25k, + #[ + name = "placeholder85k", + lattice_part = "fixme", + lattice_device = "fimxe", + lattice_family = "fixme", + ] + Placeholder85k, + } +} + +//rest looks good + +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 { + orangecrab::built_in_job_kinds() + .into_iter() + .chain(yosys_nextpnr::built_in_job_kinds()) +} + +pub(crate) fn built_in_platforms() -> impl IntoIterator { + orangecrab::built_in_platforms() + .into_iter() + .chain(yosys_nextpnr::built_in_platforms()) +} + +//first step yosys -p "read_verilog $<; synth_ecp5 -json $@" diff --git a/crates/fayalite/src/vendor/lattice/orangecrab.rs b/crates/fayalite/src/vendor/lattice/orangecrab.rs new file mode 100644 index 0000000..3cfa57b --- /dev/null +++ b/crates/fayalite/src/vendor/lattice/orangecrab.rs @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::{ + intern::{Intern, Interned}, + module::{instance_with_loc, reg_builder_with_loc, wire_with_loc}, + platform::{ + DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory, + PeripheralsBuilderFinished, Platform, PlatformAspectSet, + peripherals::{ClockInput, Led, RgbLed, Uart}, + }, + prelude::*, + vendor::lattice::{ + Device, + primitives, + }, +}; +use ordered_float::NotNan; +use std::sync::OnceLock; + +//keep unchanged +macro_rules! orangecrab_platform { + ( + $vis:vis enum $OrangeCrabPlatform:ident { + $(#[name = $name:literal, device = $device:ident] + $Variant:ident,)* + } + ) => { + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] + #[non_exhaustive] + $vis enum $OrangeCrabPlatform { + $($Variant,)* + } + + impl $OrangeCrabPlatform { + $vis const VARIANTS: &'static [Self] = &[$(Self::$Variant,)*]; + $vis fn device(self) -> Device { + match self { + $(Self::$Variant => Device::$device,)* + } + } + $vis const fn as_str(self) -> &'static str { + match self { + $(Self::$Variant => $name,)* + } + } + fn get_aspects(self) -> &'static PlatformAspectSet { + match self { + $(Self::$Variant => { + static ASPECTS_SET: OnceLock = OnceLock::new(); + ASPECTS_SET.get_or_init(|| self.make_aspects()) + })* + } + } + } + }; +} + +//untested +orangecrab_platform! { + pub enum OrangeCrabPlatform { + #[name = "orangecrab-25k", device = Placeholder25k] + OrangeCrab_25k, + #[name = "orangecrab-85k", device = Placeholder85k] + OrangeCrab_85k, + } +} + +//FIXME rename +#[derive(Debug)] +pub struct ArtyA7Peripherals { + clk100_div_pow2: [Peripheral; 4], + rst: Peripheral, + rst_sync: Peripheral, + ld0: Peripheral, + //ld1: Peripheral, + //ld2: Peripheral, + //ld3: Peripheral, + //ld4: Peripheral, + //ld5: Peripheral, + //ld6: Peripheral, + //ld7: Peripheral, + uart: Peripheral, + // TODO: add rest of peripherals when we need them +} + +impl Peripherals for ArtyA7Peripherals { + fn append_peripherals<'a>(&'a self, peripherals: &mut Vec>) { + let Self { + clk100_div_pow2, + rst, + rst_sync, + ld0, + //ld1, + //ld2, + //ld3, + //ld4, + //ld5, + //ld6, + //ld7, + uart, + } = self; + clk100_div_pow2.append_peripherals(peripherals); + rst.append_peripherals(peripherals); + rst_sync.append_peripherals(peripherals); + ld0.append_peripherals(peripherals); + //ld1.append_peripherals(peripherals); + //ld2.append_peripherals(peripherals); + //ld3.append_peripherals(peripherals); + //ld4.append_peripherals(peripherals); + //ld5.append_peripherals(peripherals); + //ld6.append_peripherals(peripherals); + //ld7.append_peripherals(peripherals); + uart.append_peripherals(peripherals); + } +} + +impl OrangeCrabPlatform { + fn make_aspects(self) -> PlatformAspectSet { + let mut retval = PlatformAspectSet::new(); + retval.insert_new(self.device()); + retval + } +} + +#[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_orangecrab_reset_sync.v".intern(), + text: r#"module __fayalite_orangecrab_reset_sync(input clk, input inp, output out); + wire reset_0_out; + always @(posedge clk) begin + reset_0_out <= inp; + outp <= reset_0_out; + end +endmodule +"# + .intern(), + }); + m.verilog_name("__fayalite_orangecrab_reset_sync"); +} + +impl Platform for OrangeCrabPlatform { + type Peripherals = ArtyA7Peripherals; + + fn name(&self) -> Interned { + self.as_str().intern() + } + + fn new_peripherals<'builder>( + &self, + builder_factory: PeripheralsBuilderFactory<'builder>, + ) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) { + let mut builder = builder_factory.builder(); + + let clk100_div_pow2 = std::array::from_fn(|log2_divisor| { + let divisor = 1u64 << log2_divisor; + let name = if divisor != 1 { + format!("clk100_div_{divisor}") + } else { + "clk100".into() + }; + builder.input_peripheral(name, ClockInput::new(100e6 / divisor as f64)) + }); + builder.add_conflicts(Vec::from_iter(clk100_div_pow2.iter().map(|v| v.id()))); + ( + ArtyA7Peripherals { + clk100_div_pow2, + rst: builder.input_peripheral("rst", Reset), + rst_sync: builder.input_peripheral("rst_sync", SyncReset), + ld0: builder.output_peripheral("ld0", RgbLed), + //ld1: builder.output_peripheral("ld1", RgbLed), + //ld2: builder.output_peripheral("ld2", RgbLed), + //ld3: builder.output_peripheral("ld3", RgbLed), + //ld4: builder.output_peripheral("ld4", Led), + //ld5: builder.output_peripheral("ld5", Led), + //ld6: builder.output_peripheral("ld6", Led), + //ld7: builder.output_peripheral("ld7", Led), + uart: builder.output_peripheral("uart", Uart), + }, + builder.finish(), + ) + } + + fn source_location(&self) -> SourceLocation { + SourceLocation::builtin() + } + + fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) { + let ArtyA7Peripherals { + clk100_div_pow2, + rst, + rst_sync, + ld0, + //ld1, + //ld2, + //ld3, + //ld4, + //ld5, + //ld6, + //ld7, + uart, + } = peripherals; + let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| { + let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool); + /* fixme 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 } + if invert { !pin } else { pin } + }; + let make_buffered_output = |name: &str, location: &str, io_standard: &str| { + let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool); + /* fixme annotate( + pin, + XdcLocationAnnotation { + location: location.intern(), + }, + ); + annotate( + pin, + XdcIOStandardAnnotation { + value: io_standard.intern(), + }, + ); */ + //let buf = instance_with_loc( + // &format!("{name}_buf"), + // primitives::OBUFT(), + // SourceLocation::builtin(), + //); + //connect(pin, buf.O); + //connect(buf.T, false); + //buf.I + pin + }; + let mut frequency = clk100_div_pow2[0].ty().frequency(); + let mut log2_divisor = 0; + let mut clk = None; + for (cur_log2_divisor, p) in clk100_div_pow2.into_iter().enumerate() { + let Some(p) = p.into_used() else { + continue; + }; + debug_assert!( + clk.is_none(), + "conflict-handling logic should ensure at most one clock is used", + ); + frequency = p.ty().frequency(); + clk = Some(p); + log2_divisor = cur_log2_divisor; + } + let clk100_buf = make_buffered_input("clk100", "E3", "LVCMOS33", false); + //let startup = instance_with_loc( + // "startup", + // primitives::STARTUPE2_default_inputs(), + // SourceLocation::builtin(), + //); + //let clk_global_buf = instance_with_loc( + // "clk_global_buf", + // primitives::BUFGCE(), + // SourceLocation::builtin(), + //); + //connect(clk_global_buf.CE, startup.EOS); + let mut clk_global_buf_in = clk100_buf.to_clock(); + for prev_log2_divisor in 0..log2_divisor { + let prev_divisor = 1u64 << prev_log2_divisor; + let clk_in = wire_with_loc( + &format!("clk_div_{prev_divisor}"), + SourceLocation::builtin(), + Clock, + ); + connect(clk_in, clk_global_buf_in); + /* fixme + annotate( + clk_in, + XdcCreateClockAnnotation { + period: NotNan::new(1e9 / (100e6 / prev_divisor as f64)) + .expect("known to be valid"), + }, + ); */ + annotate(clk_in, DontTouchAnnotation); + let cd = wire_with_loc( + &format!("clk_div_{prev_divisor}_in"), + SourceLocation::builtin(), + ClockDomain[AsyncReset], + ); + connect(cd.clk, clk_in); + //FIXME connect(cd.rst, (!startup.EOS).to_async_reset()); + let divider = reg_builder_with_loc("divider", SourceLocation::builtin()) + .clock_domain(cd) + .reset(false) + .build(); + connect(divider, !divider); + clk_global_buf_in = divider.to_clock(); + } + //connect(clk_global_buf.I, clk_global_buf_in); + let clk_out = wire_with_loc("clk_out", SourceLocation::builtin(), Clock); + //connect(clk_out, clk_global_buf.O); + connect(clk_out, clk_global_buf_in); + /* fixme annotate( + clk_out, + XdcCreateClockAnnotation { + period: NotNan::new(1e9 / frequency).expect("known to be valid"), + }, + ); */ + annotate(clk_out, DontTouchAnnotation); + if let Some(clk) = clk { + connect(clk.instance_io_field().clk, clk_out); + } + //undo 1 + 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, clk_out); + connect(rst_sync.inp, rst_buf/* | !startup.EOS*/); //FIXME + rst_sync.out + }; + if let Some(rst) = rst.into_used() { + connect(rst.instance_io_field(), rst_value.to_reset()); + } + if let Some(rst_sync) = rst_sync.into_used() { + connect(rst_sync.instance_io_field(), rst_value); + } + let rgb_leds = [ + (ld0, ("G6", "F6", "E1")), + //(ld1, ("G3", "J4", "G4")), + //(ld2, ("J3", "J2", "H4")), + //(ld3, ("K1", "H6", "K2")), + ]; + for (rgb_led, (r_loc, g_loc, b_loc)) in rgb_leds { + let r = make_buffered_output(&format!("{}_r", rgb_led.name()), r_loc, "LVCMOS33"); + let g = make_buffered_output(&format!("{}_g", rgb_led.name()), g_loc, "LVCMOS33"); + let b = make_buffered_output(&format!("{}_b", rgb_led.name()), b_loc, "LVCMOS33"); + if let Some(rgb_led) = rgb_led.into_used() { + connect(r, rgb_led.instance_io_field().r); + connect(g, rgb_led.instance_io_field().g); + connect(b, rgb_led.instance_io_field().b); + } else { + connect(r, false); + connect(g, false); + connect(b, false); + } + } + //let leds = [(ld4, "H5"), (ld5, "J5"), (ld6, "T9"), (ld7, "T10")]; + //for (led, loc) in leds { + // let o = make_buffered_output(&led.name(), loc, "LVCMOS33"); + // if let Some(led) = led.into_used() { + // connect(o, led.instance_io_field().on); + // } else { + // connect(o, false); + // } + //} + let uart_tx = make_buffered_output("uart_tx", "D10", "LVCMOS33"); + let uart_rx = make_buffered_input("uart_rx", "A9", "LVCMOS33", false); + if let Some(uart) = uart.into_used() { + connect(uart_tx, uart.instance_io_field().tx); + connect(uart.instance_io_field().rx, uart_rx); + } else { + connect(uart_tx, true); // idle + } + } + + fn aspects(&self) -> PlatformAspectSet { + self.get_aspects().clone() + } +} + +pub(crate) fn built_in_job_kinds() -> impl IntoIterator { + [] +} + +pub(crate) fn built_in_platforms() -> impl IntoIterator { + OrangeCrabPlatform::VARIANTS + .iter() + .map(|&v| DynPlatform::new(v)) +} diff --git a/crates/fayalite/src/vendor/lattice/primitives.rs b/crates/fayalite/src/vendor/lattice/primitives.rs new file mode 100644 index 0000000..f5f07bb --- /dev/null +++ b/crates/fayalite/src/vendor/lattice/primitives.rs @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +#![allow(non_snake_case)] + +use crate::prelude::*; + +//#[hdl_module(extern)] +//pub fn IBUF() { +// m.verilog_name("IBUF"); +// #[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 FIXME_PLACEHOLDER() { + m.verilog_name("FIXME_PLACEHOLDER"); + #[hdl] + let CFGCLK: Clock = m.output(); + #[hdl] + let CFGMCLK: Clock = m.output(); + #[hdl] + let EOS: Bool = m.output(); + #[hdl] + let PREQ: Bool = m.output(); +} diff --git a/crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs b/crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs new file mode 100644 index 0000000..1e0e99e --- /dev/null +++ b/crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs @@ -0,0 +1,899 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// See Notices.txt for copyright information + +use crate::{ + annotations::{Annotation, TargetedAnnotation}, + build::{ + BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams, + JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind, + JobKindAndDependencies, ToArgs, WriteArgs, + external::{ + ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait, + }, + verilog::{UnadjustedVerilog, VerilogDialect, VerilogJob, VerilogJobKind}, + }, + bundle::{Bundle, BundleType}, + expr::target::{Target, TargetBase}, + firrtl::{ScalarizedModuleABI, ScalarizedModuleABIAnnotations, ScalarizedModuleABIPort}, + intern::{Intern, InternSlice, Interned}, + module::{ + NameId, ScopedNameId, TargetName, + transform::visit::{Visit, Visitor}, + }, + prelude::*, + source_location::SourceLocation, + util::{HashSet, job_server::AcquiredJob}, + vendor::lattice::{ + Device, + /* fixme LatticeAnnotation,*/ LatticeArgs, + }, +}; +use eyre::Context; +use serde::{Deserialize, Serialize}; +use std::{ + convert::Infallible, + ffi::{OsStr, OsString}, + fmt::{self, Write}, + ops::ControlFlow, + path::{Path, PathBuf}, +}; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] +pub struct YosysNextpnrWriteYsFileJobKind; + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrWriteYsFileArgs {} + +impl ToArgs for YosysNextpnrWriteYsFileArgs { + fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { + let Self {} = self; + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +pub struct YosysNextpnrWriteYsFile { + main_verilog_file: Interned, + ys_file: Interned, + json_file: Interned, + json_file_name: Interned, +} + +impl YosysNextpnrWriteYsFile { + pub fn main_verilog_file(&self) -> Interned { + self.main_verilog_file + } + pub fn ys_file(&self) -> Interned { + self.ys_file + } + pub fn json_file(&self) -> Interned { + self.json_file + } + pub fn json_file_name(&self) -> Interned { + self.json_file_name + } + fn write_ys( + &self, + output: &mut OsString, + additional_files: &[Interned], + main_module_name_id: NameId, + ) -> eyre::Result<()> { + let Self { + main_verilog_file, + ys_file: _, + json_file: _, + json_file_name, + } = self; + for verilog_file in VerilogJob::all_verilog_files(*main_verilog_file, additional_files)? { + output.push("read_verilog -sv \""); + output.push(verilog_file); + output.push("\"\n"); + } + let circuit_name = crate::firrtl::get_circuit_name(main_module_name_id); + writeln!( + output, + "synth_ecp5 -top {circuit_name}" + ) + .expect("writing to OsString can't fail"); + output.push("write_json \""); + output.push(json_file_name); + output.push("\"\n"); + Ok(()) + } +} + +impl JobKind for YosysNextpnrWriteYsFileJobKind { + type Args = YosysNextpnrWriteYsFileArgs; + type Job = YosysNextpnrWriteYsFile; + type Dependencies = JobKindAndDependencies; + + fn dependencies(self) -> Self::Dependencies { + Default::default() + } + + fn args_to_jobs( + mut args: JobArgsAndDependencies, + params: &JobParams, + global_params: &GlobalParams, + ) -> eyre::Result> { + args.dependencies + .dependencies + .args + .args + .additional_args + .verilog_dialect + .get_or_insert(VerilogDialect::Yosys); + args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { + let YosysNextpnrWriteYsFileArgs {} = args; + let base_job = dependencies.get_job::(); + let verilog_job = dependencies.get_job::(); + let json_file = base_job.file_with_ext("json"); + Ok(YosysNextpnrWriteYsFile { + main_verilog_file: verilog_job.main_verilog_file(), + ys_file: base_job.file_with_ext("ys"), + json_file, + json_file_name: json_file + .interned_file_name() + .expect("known to have file name"), + }) + }) + } + + fn inputs(self, _job: &Self::Job) -> Interned<[JobItemName]> { + [JobItemName::DynamicPaths { + source_job_name: VerilogJobKind.name(), + }] + .intern_slice() + } + + fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { + [JobItemName::Path { path: job.ys_file }].intern_slice() + } + + fn name(self) -> Interned { + "yosys-nextpnr-ecp5-write-ys-file".intern() + } + + fn external_command_params(self, _job: &Self::Job) -> Option { + None + } + + fn run( + self, + job: &Self::Job, + inputs: &[JobItem], + params: &JobParams, + _global_params: &GlobalParams, + _acquired_job: &mut AcquiredJob, + ) -> eyre::Result> { + assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); + let [additional_files] = inputs else { + unreachable!(); + }; + let additional_files = VerilogJob::unwrap_additional_files(additional_files); + let mut contents = OsString::new(); + job.write_ys( + &mut contents, + additional_files, + params.main_module().name_id(), + )?; + let path = job.ys_file; + std::fs::write(path, contents.as_encoded_bytes()) + .wrap_err_with(|| format!("writing {path:?} failed"))?; + Ok(vec![JobItem::Path { path }]) + } + + fn subcommand_hidden(self) -> bool { + true + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrSynthArgs {} + +impl ToArgs for YosysNextpnrSynthArgs { + fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { + let Self {} = self; + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct YosysNextpnrSynth { + #[serde(flatten)] + write_ys_file: YosysNextpnrWriteYsFile, + ys_file_name: Interned, +} + +impl fmt::Debug for YosysNextpnrSynth { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self { + write_ys_file: + YosysNextpnrWriteYsFile { + main_verilog_file, + ys_file, + json_file, + json_file_name, + }, + ys_file_name, + } = self; + f.debug_struct("YosysNextpnrSynth") + .field("main_verilog_file", main_verilog_file) + .field("ys_file", ys_file) + .field("ys_file_name", ys_file_name) + .field("json_file", json_file) + .field("json_file_name", json_file_name) + .finish() + } +} + +impl YosysNextpnrSynth { + pub fn main_verilog_file(&self) -> Interned { + self.write_ys_file.main_verilog_file() + } + pub fn ys_file(&self) -> Interned { + self.write_ys_file.ys_file() + } + pub fn ys_file_name(&self) -> Interned { + self.ys_file_name + } + pub fn json_file(&self) -> Interned { + self.write_ys_file.json_file() + } + pub fn json_file_name(&self) -> Interned { + self.write_ys_file.json_file_name() + } +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] +pub struct Yosys; + +impl ExternalProgramTrait for Yosys { + fn default_program_name() -> Interned { + "yosys".intern() //must be yosys + } +} + +impl ExternalCommand for YosysNextpnrSynth { + type AdditionalArgs = YosysNextpnrSynthArgs; + type AdditionalJobData = Self; + type BaseJobPosition = GetJobPositionDependencies< + GetJobPositionDependencies< + GetJobPositionDependencies<::BaseJobPosition>, + >, + >; + type Dependencies = JobKindAndDependencies; + type ExternalProgram = Yosys; + + fn dependencies() -> Self::Dependencies { + Default::default() + } + + fn args_to_jobs( + args: JobArgsAndDependencies>, + params: &JobParams, + global_params: &GlobalParams, + ) -> eyre::Result<( + Self::AdditionalJobData, + ::JobsAndKinds, + )> { + args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { + let YosysNextpnrSynthArgs {} = args.additional_args; + Ok(Self { + write_ys_file: dependencies.job.job.clone(), + ys_file_name: dependencies + .job + .job + .ys_file() + .interned_file_name() + .expect("known to have file name"), + }) + }) + } + + fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { + [ + JobItemName::Path { + path: job.additional_job_data().ys_file(), + }, + JobItemName::Path { + path: job.additional_job_data().main_verilog_file(), + }, + JobItemName::DynamicPaths { + source_job_name: VerilogJobKind.name(), + }, + ] + .intern_slice() + } + + fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { + [job.additional_job_data().json_file()].intern_slice() + } + + fn command_line_args(job: &ExternalCommandJob, args: &mut W) { + args.write_arg("-s"); + args.write_interned_arg(job.additional_job_data().ys_file_name()); + } + + fn current_dir(job: &ExternalCommandJob) -> Option> { + Some(job.output_dir()) + } + + fn job_kind_name() -> Interned { + "yosys-nextpnr-ecp5-synth".intern() + } + + fn subcommand_hidden() -> bool { + true + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)] +pub struct YosysNextpnrWritePcfFileJobKind; + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrWritePcfFileArgs {} + +impl ToArgs for YosysNextpnrWritePcfFileArgs { + fn to_args(&self, _args: &mut (impl WriteArgs + ?Sized)) { + let Self {} = self; + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +pub struct YosysNextpnrWritePcfFile { + firrtl_export_options: crate::firrtl::ExportOptions, + output_dir: Interned, + pcf_file: Interned, +} + +struct WritePcfContentsError(eyre::Report); + +impl From for WritePcfContentsError { + fn from(v: eyre::Report) -> Self { + Self(v) + } +} + +impl From for WritePcfContentsError { + fn from(_v: fmt::Error) -> Self { + unreachable!("String write can't fail") + } +} + +fn tcl_escape(s: impl AsRef) -> String { + let s = s.as_ref(); + if !s.contains(|ch: char| !ch.is_alphanumeric() && ch != '_') { + return s.into(); + } + let mut retval = String::with_capacity(s.len().saturating_add(2)); + retval.push('"'); + for ch in s.chars() { + if let '$' | '\\' | '[' = ch { + retval.push('\\'); + } + retval.push(ch); + } + retval.push('"'); + retval +} + +#[derive(Copy, Clone, Debug)] +enum AnnotationTarget { + None, + Module(Module), + Mem(Mem), + Target(Interned), +} + +impl AnnotationTarget { + fn source_location(self) -> SourceLocation { + match self { + AnnotationTarget::None => unreachable!(), + AnnotationTarget::Module(module) => module.source_location(), + AnnotationTarget::Mem(mem) => mem.source_location(), + AnnotationTarget::Target(target) => target.base().source_location(), + } + } +} + +struct PcfFileWriter { //TODO + output: W, + module_depth: usize, + annotation_target: AnnotationTarget, + dont_touch_targets: HashSet>, + required_dont_touch_targets: HashSet>, +} + +impl PcfFileWriter { + fn run(output: W, top_module: Module) -> Result<(), WritePcfContentsError> { + let mut this = Self { + output, + module_depth: 0, + annotation_target: AnnotationTarget::None, + dont_touch_targets: HashSet::default(), + required_dont_touch_targets: HashSet::default(), + }; + top_module.visit(&mut this)?; + let Self { + output: _, + module_depth: _, + annotation_target: _, + dont_touch_targets, + required_dont_touch_targets, + } = this; + for &target in required_dont_touch_targets.difference(&dont_touch_targets) { + return Err(eyre::eyre!( + "a DontTouchAnnotation is required since the target is also annotated with a LatticeAnnotation:\ntarget: {target:?}\nat: {}", + target.base().source_location(), + ).into()); + } + Ok(()) + } + fn default_visit_with>( + &mut self, + module_depth: usize, + annotation_target: AnnotationTarget, + v: &T, + ) -> Result<(), WritePcfContentsError> { + let Self { + output: _, + module_depth: old_module_depth, + annotation_target: old_annotation_target, + dont_touch_targets: _, + required_dont_touch_targets: _, + } = *self; + self.module_depth = module_depth; + self.annotation_target = annotation_target; + let retval = v.default_visit(self); + self.module_depth = old_module_depth; + self.annotation_target = old_annotation_target; + retval + } +} + +impl Visitor for PcfFileWriter { + type Error = WritePcfContentsError; + + fn visit_targeted_annotation(&mut self, v: &TargetedAnnotation) -> Result<(), Self::Error> { + self.default_visit_with(self.module_depth, AnnotationTarget::Target(v.target()), v) + } + + fn visit_module(&mut self, v: &Module) -> Result<(), Self::Error> { + self.default_visit_with( + self.module_depth + 1, + AnnotationTarget::Module(v.canonical()), + v, + ) + } + + fn visit_mem( + &mut self, + v: &Mem, + ) -> Result<(), Self::Error> + where + Element: Visit, + { + self.default_visit_with( + self.module_depth + 1, + AnnotationTarget::Mem(v.canonical()), + v, + ) + } + + fn visit_dont_touch_annotation(&mut self, _v: &DontTouchAnnotation) -> Result<(), Self::Error> { + if let AnnotationTarget::Target(target) = self.annotation_target { + self.dont_touch_targets.insert(target); + } + Ok(()) + } + + + /* FIXME fn visit_lattice_annotation(&mut self, v: &LatticeAnnotation) -> Result<(), Self::Error> */ +} + +impl YosysNextpnrWritePcfFile { + fn write_pcf_contents_for_port_and_annotations( + &self, + output: &mut impl fmt::Write, + port: &ScalarizedModuleABIPort, + annotations: ScalarizedModuleABIAnnotations<'_>, + ) -> Result<(), WritePcfContentsError> { + /* fixme for annotation in annotations .. */ + Ok(()) + } + fn write_pcf_contents( + &self, + output: &mut String, + top_module: &Module, + ) -> eyre::Result<()> { + let scalarized_module_abi = + ScalarizedModuleABI::new(top_module, self.firrtl_export_options) + .map_err(eyre::Report::from)?; + match scalarized_module_abi.for_each_port_and_annotations(|port, annotations| { + match self.write_pcf_contents_for_port_and_annotations(output, port, annotations) { + Ok(()) => ControlFlow::Continue(()), + Err(e) => ControlFlow::Break(e), + } + }) { + ControlFlow::Continue(()) => {} + ControlFlow::Break(e) => return Err(e.0), + } + PcfFileWriter::run(output, *top_module).map_err(|e| e.0) + } +} + +impl JobKind for YosysNextpnrWritePcfFileJobKind { + type Args = YosysNextpnrWritePcfFileArgs; + type Job = YosysNextpnrWritePcfFile; + type Dependencies = JobKindAndDependencies>; + + fn dependencies(self) -> Self::Dependencies { + Default::default() + } + + fn args_to_jobs( + args: JobArgsAndDependencies, + params: &JobParams, + global_params: &GlobalParams, + ) -> eyre::Result> { + let firrtl_export_options = args + .dependencies + .dependencies + .dependencies + .dependencies + .dependencies + .args + .args + .export_options; + args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| { + let YosysNextpnrWritePcfFileArgs {} = args; + let base_job = dependencies.get_job::(); + Ok(YosysNextpnrWritePcfFile { + firrtl_export_options, + output_dir: base_job.output_dir(), + pcf_file: base_job.file_with_ext("pcf"), + }) + }) + } + + fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]> { + [JobItemName::Path { + path: job.output_dir, + }] + .intern_slice() + } + + fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]> { + [JobItemName::Path { path: job.pcf_file }].intern_slice() + } + + fn name(self) -> Interned { + "yosys-nextpnr-ecp5-write-pcf-file".intern() + } + + fn external_command_params(self, _job: &Self::Job) -> Option { + None + } + + fn run( + self, + job: &Self::Job, + inputs: &[JobItem], + params: &JobParams, + _global_params: &GlobalParams, + _acquired_job: &mut AcquiredJob, + ) -> eyre::Result> { + assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job))); + let mut pcf = String::new(); + job.write_pcf_contents(&mut pcf, params.main_module())?; + std::fs::write(job.pcf_file, pcf)?; + Ok(vec![JobItem::Path { path: job.pcf_file }]) + } + + fn subcommand_hidden(self) -> bool { + true + } +} + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] +pub struct NextpnrLattice; + +impl ExternalProgramTrait for NextpnrLattice { + fn default_program_name() -> Interned { + "nextpnr".intern() + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrRunNextpnrArgs { + #[command(flatten)] + pub common: LatticeArgs, + #[arg(long, default_value_t = 0)] + pub nextpnr_lattice_seed: i32, +} + +impl ToArgs for YosysNextpnrRunNextpnrArgs { + fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { + let Self { + common, + nextpnr_lattice_seed, + } = self; + common.to_args(args); + args.write_display_arg(format_args!("--nextpnr-lattice-seed={nextpnr_lattice_seed}")); + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +pub struct YosysNextpnrRunNextpnr { + device: Device, + nextpnr_lattice_seed: i32, + pcf_file: Interned, + json_file: Interned, + json_file_name: Interned, + routed_json_file: Interned, + routed_json_file_name: Interned, + textcfg_file: Interned, + textcfg_file_name: Interned, +} + +impl ExternalCommand for YosysNextpnrRunNextpnr { + type AdditionalArgs = YosysNextpnrRunNextpnrArgs; + type AdditionalJobData = Self; + type BaseJobPosition = GetJobPositionDependencies< + GetJobPositionDependencies<::BaseJobPosition>, + >; + type Dependencies = JobKindAndDependencies; + type ExternalProgram = NextpnrLattice; + + fn dependencies() -> Self::Dependencies { + Default::default() + } + + fn args_to_jobs( + args: JobArgsAndDependencies>, + params: &JobParams, + global_params: &GlobalParams, + ) -> eyre::Result<( + Self::AdditionalJobData, + ::JobsAndKinds, + )> { + args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { + let YosysNextpnrRunNextpnrArgs { + common, + nextpnr_lattice_seed, + } = args.additional_args; + let base_job = dependencies.get_job::(); + let write_pcf_file = dependencies.get_job::(); + let synth = dependencies.get_job::, _>(); + let routed_json_file = base_job.file_with_ext("routed.json"); + let textcfg_file = base_job.file_with_ext("config"); //file must exist + Ok(Self { + device: common.require_device(base_job.platform(), global_params)?, + nextpnr_lattice_seed, + pcf_file: write_pcf_file.pcf_file, + json_file: synth.additional_job_data().json_file(), + json_file_name: synth.additional_job_data().json_file_name(), + routed_json_file: routed_json_file, + routed_json_file_name: routed_json_file + .interned_file_name() + .expect("known to have file name"), + textcfg_file:textcfg_file, + textcfg_file_name: textcfg_file + .interned_file_name() + .expect("known to have file name"), + }) + }) + } + + fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { + [ + JobItemName::Path { + path: job.additional_job_data().json_file, + }, + JobItemName::Path { + path: job.additional_job_data().pcf_file, + }, + ] + .intern_slice() + } + + fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { + [ + job.additional_job_data().routed_json_file, + ] + .intern_slice() + } + + fn command_line_args(job: &ExternalCommandJob, args: &mut W) { + let job_data @ YosysNextpnrRunNextpnr { + nextpnr_lattice_seed, + json_file_name, + routed_json_file_name, + textcfg_file_name, + .. + } = job.additional_job_data(); + args.write_long_option_eq("json", json_file_name); + args.write_long_option_eq("textcfg",textcfg_file_name); + args.write_long_option_eq("write",routed_json_file_name); + args.write_arg("--85k"); //FIXME do not hardcode + args.write_long_option_eq("package","CSFBGA285"); + args.write_long_option_eq("lpf","/home/alex/Hacking/FPGA/orangecrab/orangecrab-examples/fayalite/orangecrab_r0.2.1.pcf"); //just a quick test + //handwrite before adding new module, ask pj before cont + //HACK: args.write_arg("--lpf-allow-unconstrained"); + //???args.write_display_arg(format_args!("--seed={nextpnr_lattice_seed}")); + //fix ERROR: failed to open LPF file '/tmp/orangecrab_r0.2.1.pcf' FIRST + + } + + fn current_dir(job: &ExternalCommandJob) -> Option> { + Some(job.output_dir()) + } + + fn job_kind_name() -> Interned { + "yosys-nextpnr-ecp5-run-nextpnr".intern() + } + + fn subcommand_hidden() -> bool { + true + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrArgs { + #[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)] + pub pcf1: PathBuf, +} + +impl ToArgs for YosysNextpnrArgs { + fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { + let Self { pcf1 } = self; + args.write_long_option_eq("pcf1", pcf1); + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +pub struct YosysNextpnr { + pcf1: Interned, + device: Device, + frames_file: Interned, + frames_file_name: Interned, + bit_file: Interned, + bit_file_name: Interned, +} + + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)] +pub struct Ecppack; + +impl ExternalProgramTrait for Ecppack { + fn default_program_name() -> Interned { + "ecppack".intern() + } +} + +//begin +#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)] +pub struct YosysNextpnrRunEcpPackArgs { + #[arg(long, env = "DB_DIR", value_hint = clap::ValueHint::DirPath)] + pub placeholder_dir: PathBuf, +} + +impl ToArgs for YosysNextpnrRunEcpPackArgs { + fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) { + let Self { placeholder_dir } = self; + args.write_long_option_eq("placeholder-dir", placeholder_dir); + } +} + +#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] +pub struct YosysNextpnrRunEcpPack { + placeholder_dir: Interned, + device: Device, + routed_json_file: Interned, + routed_json_file_name: Interned, + textcfg_file: Interned, + textcfg_file_name: Interned, + frames_file: Interned, + frames_file_name: Interned, + bit_file: Interned, + bit_file_name: Interned, +} + +impl ExternalCommand for YosysNextpnrRunEcpPack { + type AdditionalArgs = YosysNextpnrRunEcpPackArgs; + type AdditionalJobData = Self; + type BaseJobPosition = GetJobPositionDependencies< + ::BaseJobPosition, + >; + type Dependencies = JobKindAndDependencies>; + type ExternalProgram = Ecppack; + + fn dependencies() -> Self::Dependencies { + Default::default() + } + + fn args_to_jobs( + args: JobArgsAndDependencies>, + params: &JobParams, + global_params: &GlobalParams, + ) -> eyre::Result<( + Self::AdditionalJobData, + ::JobsAndKinds, + )> { + args.args_to_jobs_external_simple(params, global_params, |args, dependencies| { + let YosysNextpnrRunEcpPackArgs { placeholder_dir } = args.additional_args; + let base_job = dependencies.get_job::(); + let frames_file = base_job.file_with_ext("frames"); + let bit_file = base_job.file_with_ext("bit"); + Ok(Self { + placeholder_dir: placeholder_dir.intern_deref(), + device: dependencies.job.job.additional_job_data().device, + //fixme glue code + routed_json_file: dependencies.job.job.additional_job_data().routed_json_file, + routed_json_file_name: dependencies.job.job.additional_job_data().routed_json_file_name, + textcfg_file: dependencies.job.job.additional_job_data().textcfg_file, + textcfg_file_name: dependencies.job.job.additional_job_data().textcfg_file_name, + frames_file, + frames_file_name: frames_file + .interned_file_name() + .expect("known to have file name"), + bit_file, + bit_file_name: bit_file + .interned_file_name() + .expect("known to have file name"), + }) + }) + } + + fn inputs(job: &ExternalCommandJob) -> Interned<[JobItemName]> { + [JobItemName::Path { + path: job.additional_job_data().routed_json_file, + }] + .intern_slice() + } + + fn output_paths(job: &ExternalCommandJob) -> Interned<[Interned]> { + [ + job.additional_job_data().bit_file, + ] + .intern_slice() + } + + fn command_line_args(job: &ExternalCommandJob, args: &mut W) { + let job_data @ YosysNextpnrRunEcpPack { + placeholder_dir, + device, + routed_json_file_name, + textcfg_file_name, + frames_file_name, + bit_file_name, + .. + } = job.additional_job_data(); + args.write_arg("--compress"); + args.write_long_option_eq("freq", "38.8"); //FIXME do not hardcode + args.write_long_option_eq("input",textcfg_file_name); + args.write_long_option_eq("bit",bit_file_name); + } + + fn current_dir(job: &ExternalCommandJob) -> Option> { + Some(job.output_dir()) + } + + fn job_kind_name() -> Interned { + "yosys-nextpnr-ecp5".intern() + } +} +//end + +pub(crate) fn built_in_job_kinds() -> impl IntoIterator { + [ + DynJobKind::new(YosysNextpnrWriteYsFileJobKind), //working + DynJobKind::new(ExternalCommandJobKind::::new()), //working + DynJobKind::new(YosysNextpnrWritePcfFileJobKind), //TODO + DynJobKind::new(ExternalCommandJobKind::::new()), //working + DynJobKind::new(ExternalCommandJobKind::::new()), //working + ] +} + +pub(crate) fn built_in_platforms() -> impl IntoIterator { + [] +} diff --git a/fix_warnings.html b/fix_warnings.html new file mode 100644 index 0000000..b331723 --- /dev/null +++ b/fix_warnings.html @@ -0,0 +1,869 @@ +
   Compiling fayalite-proc-macros v0.3.0 (/home/alex/Hacking/FPGA/libre-chip/fayalite/crates/fayalite-proc-macros)
+   Compiling fayalite v0.3.0 (/home/alex/Hacking/FPGA/libre-chip/fayalite/crates/fayalite)
+warning: unused import: `make_impls`
+   --> crates/fayalite/src/expr/ops.rs:582:16
+    |
+582 | pub(crate) use make_impls;
+    |                ^^^^^^^^^^
+    |
+    = note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
+
+warning: unused imports: `annotations::make_annotation_enum` and `intern::Interned`
+ --> crates/fayalite/src/vendor/lattice.rs:5:5
+  |
+5 |     annotations::make_annotation_enum,
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+6 |     build::{GlobalParams, ToArgs, WriteArgs},
+7 |     intern::Interned,
+  |     ^^^^^^^^^^^^^^^^
+
+warning: unused import: `ordered_float::NotNan`
+  --> crates/fayalite/src/vendor/lattice.rs:11:5
+   |
+11 | use ordered_float::NotNan;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+warning: unused import: `primitives`
+  --> crates/fayalite/src/vendor/lattice/orangecrab.rs:15:9
+   |
+15 |         primitives,
+   |         ^^^^^^^^^^
+
+warning: unused import: `ordered_float::NotNan`
+  --> crates/fayalite/src/vendor/lattice/orangecrab.rs:18:5
+   |
+18 | use ordered_float::NotNan;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+warning: variant `OrangeCrab_25k` should have an upper camel case name
+  --> crates/fayalite/src/vendor/lattice/orangecrab.rs:63:9
+   |
+63 |         OrangeCrab_25k,
+   |         ^^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OrangeCrab25k`
+   |
+   = note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default
+
+warning: variant `OrangeCrab_85k` should have an upper camel case name
+  --> crates/fayalite/src/vendor/lattice/orangecrab.rs:65:9
+   |
+65 |         OrangeCrab_85k,
+   |         ^^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OrangeCrab85k`
+
+warning: unused imports: `Annotation`, `ScopedNameId`, `TargetBase`, and `TargetName`
+  --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:5:19
+   |
+ 5 |     annotations::{Annotation, TargetedAnnotation},
+   |                   ^^^^^^^^^^
+...
+16 |     expr::target::{Target, TargetBase},
+   |                            ^^^^^^^^^^
+...
+20 |         NameId, ScopedNameId, TargetName,
+   |                 ^^^^^^^^^^^^  ^^^^^^^^^^
+
+warning: unused import: `convert::Infallible`
+  --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:34:5
+   |
+34 |     convert::Infallible,
+   |     ^^^^^^^^^^^^^^^^^^^
+
+warning: unused variable: `lhs_ty`
+    --> crates/fayalite/src/sim/compiler.rs:3809:37
+     |
+3809 |                 CanonicalType::Enum(lhs_ty) => {
+     |                                     ^^^^^^ help: if this is intentional, prefix it with an underscore: `_lhs_ty`
+     |
+     = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default
+
+warning: unused variable: `rhs_ty`
+    --> crates/fayalite/src/sim/compiler.rs:3810:45
+     |
+3810 |                     let CanonicalType::Enum(rhs_ty) = rhs.ty() else {
+     |                                             ^^^^^^ help: if this is intentional, prefix it with an underscore: `_rhs_ty`
+
+warning: unused variable: `part_name`
+    --> crates/fayalite/src/sim/compiler.rs:3898:37
+     |
+3898 |         let mut alloc_small_slot = |part_name: &str| {
+     |                                     ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_part_name`
+
+warning: unused variable: `annotations`
+    --> crates/fayalite/src/sim/compiler.rs:4080:23
+     |
+4080 |         let StmtReg { annotations, reg } = stmt_reg;
+     |                       ^^^^^^^^^^^ help: try ignoring the field: `annotations: _`
+
+warning: unused variable: `annotations`
+    --> crates/fayalite/src/sim/compiler.rs:4118:46
+     |
+4118 |             StmtDeclaration::Wire(StmtWire { annotations, wire }) => {}
+     |                                              ^^^^^^^^^^^ help: try ignoring the field: `annotations: _`
+
+warning: unused variable: `wire`
+    --> crates/fayalite/src/sim/compiler.rs:4118:59
+     |
+4118 |             StmtDeclaration::Wire(StmtWire { annotations, wire }) => {}
+     |                                                           ^^^^ help: try ignoring the field: `wire: _`
+
+warning: unused variable: `annotations`
+    --> crates/fayalite/src/sim/compiler.rs:4129:17
+     |
+4129 |                 annotations,
+     |                 ^^^^^^^^^^^ help: try ignoring the field: `annotations: _`
+
+warning: unused variable: `location`
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:233:49
+    |
+233 |         let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
+    |                                                 ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_location`
+
+warning: unused variable: `io_standard`
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:233:65
+    |
+233 |         let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
+    |                                                                 ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_io_standard`
+
+warning: unused variable: `location`
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:210:48
+    |
+210 |         let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| {
+    |                                                ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_location`
+
+warning: unused variable: `io_standard`
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:210:64
+    |
+210 |         let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| {
+    |                                                                ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_io_standard`
+
+warning: variable `frequency` is assigned to, but never used
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:257:13
+    |
+257 |         let mut frequency = clk100_div_pow2[0].ty().frequency();
+    |             ^^^^^^^^^^^^^
+    |
+    = note: consider using `_frequency` instead
+
+warning: value assigned to `frequency` is never read
+   --> crates/fayalite/src/vendor/lattice/orangecrab.rs:268:13
+    |
+268 |             frequency = p.ty().frequency();
+    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    |
+    = help: maybe it is overwritten before being read?
+    = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default
+
+warning: unused variable: `output`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:496:9
+    |
+496 |         output: &mut impl fmt::Write,
+    |         ^^^^^^ help: if this is intentional, prefix it with an underscore: `_output`
+
+warning: unused variable: `port`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:497:9
+    |
+497 |         port: &ScalarizedModuleABIPort,
+    |         ^^^^ help: if this is intentional, prefix it with an underscore: `_port`
+
+warning: unused variable: `annotations`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:498:9
+    |
+498 |         annotations: ScalarizedModuleABIAnnotations<'_>,
+    |         ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_annotations`
+
+warning: unused variable: `job_data`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:707:13
+    |
+707 |         let job_data @ YosysNextpnrRunNextpnr {
+    |             ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_job_data`
+
+warning: unused variable: `nextpnr_lattice_seed`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:708:13
+    |
+708 |             nextpnr_lattice_seed,
+    |             ^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `nextpnr_lattice_seed: _`
+
+warning: unused variable: `routed_json_file_name`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:710:13
+    |
+710 |             routed_json_file_name,
+    |             ^^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `routed_json_file_name: _`
+
+warning: unused variable: `job_data`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:861:13
+    |
+861 |         let job_data @ YosysNextpnrRunEcpPack {
+    |             ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_job_data`
+
+warning: unused variable: `placeholder_dir`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:862:4
+    |
+862 |             placeholder_dir,
+    |             ^^^^^^^^^^^^^^^ help: try ignoring the field: `placeholder_dir: _`
+
+warning: unused variable: `device`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:863:13
+    |
+863 |             device,
+    |             ^^^^^^ help: try ignoring the field: `device: _`
+
+warning: unused variable: `routed_json_file_name`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:864:13
+    |
+864 |             routed_json_file_name,
+    |             ^^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `routed_json_file_name: _`
+
+warning: unused variable: `frames_file_name`
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:866:13
+    |
+866 |             frames_file_name,
+    |             ^^^^^^^^^^^^^^^^ help: try ignoring the field: `frames_file_name: _`
+
+warning: struct `SliceAsMapDebug` is never constructed
+    --> crates/fayalite/src/sim.rs:3231:8
+     |
+3231 | struct SliceAsMapDebug<'a, T>(&'a [Option<T>]);
+     |        ^^^^^^^^^^^^^^^
+     |
+     = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
+
+warning: method `element_dyn` is never used
+   --> crates/fayalite/src/sim/compiler.rs:397:8
+    |
+385 | impl CompiledValue<Array> {
+    | ------------------------- method in this implementation
+...
+397 |     fn element_dyn(
+    |        ^^^^^^^^^^^
+
+warning: methods `len`, `index`, `is_empty`, and `stride` are never used
+   --> crates/fayalite/src/sim/compiler.rs:444:27
+    |
+434 |           impl TypeArrayIndex {
+    |           ------------------- methods in this implementation
+...
+444 |               pub(crate) fn len(self) -> usize {
+    |                             ^^^
+...
+449 |               pub(crate) fn index(self) -> StatePartIndex<StatePartKindSmallSlots> {
+    |                             ^^^^^
+...
+454 |               pub(crate) fn is_empty(self) -> bool {
+    |                             ^^^^^^^^
+...
+457 |               pub(crate) fn stride(self) -> TypeLen {
+    |                             ^^^^^^
+...
+569 | / get_state_part_kinds! {
+570 | |     make_type_array_indexes! {
+571 | |         type_plural_fields;
+572 | |         type_kinds;
+573 | |     }
+574 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `iter`, `for_each_offset`, `split_first`, and `for_each_offset2` are never used
+   --> crates/fayalite/src/sim/compiler.rs:478:27
+    |
+469 |           impl<'a> TypeArrayIndexesRef<'a> {
+    |           -------------------------------- methods in this implementation
+...
+478 |               pub(crate) fn iter(self) -> impl Iterator<Item = TypeArrayIndex> + 'a {
+    |                             ^^^^
+...
+483 |               pub(crate) fn for_each_offset(
+    |                             ^^^^^^^^^^^^^^^
+...
+491 |               pub(crate) fn split_first(self) -> Option<(TypeArrayIndex, Self)> {
+    |                             ^^^^^^^^^^^
+...
+501 |               pub(crate) fn for_each_offset2(
+    |                             ^^^^^^^^^^^^^^^^
+...
+569 | / get_state_part_kinds! {
+570 | |     make_type_array_indexes! {
+571 | |         type_plural_fields;
+572 | |         type_kinds;
+573 | |     }
+574 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: struct `TypeArrayIndexed` is never constructed
+   --> crates/fayalite/src/sim/compiler.rs:534:27
+    |
+534 |           pub(crate) struct TypeArrayIndexed {
+    |                             ^^^^^^^^^^^^^^^^
+...
+569 | / get_state_part_kinds! {
+570 | |     make_type_array_indexes! {
+571 | |         type_plural_fields;
+572 | |         type_kinds;
+573 | |     }
+574 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: associated items `from_parts`, `base`, and `indexes` are never used
+   --> crates/fayalite/src/sim/compiler.rs:539:27
+    |
+538 |           impl TypeArrayIndexed {
+    |           --------------------- associated items in this implementation
+539 |               pub(crate) fn from_parts(base: TypeIndex, indexes: TypeArrayIndexes) -> Self {
+    |                             ^^^^^^^^^^
+...
+547 |               pub(crate) fn base(self) -> TypeIndex {
+    |                             ^^^^
+...
+552 |               pub(crate) fn indexes(self) -> TypeArrayIndexes {
+    |                             ^^^^^^^
+...
+569 | / get_state_part_kinds! {
+570 | |     make_type_array_indexes! {
+571 | |         type_plural_fields;
+572 | |         type_kinds;
+573 | |     }
+574 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `add_target_without_indexes_to_set` and `add_target_and_indexes_to_set` are never used
+   --> crates/fayalite/src/sim/compiler.rs:602:8
+    |
+591 | impl<T: Type> CompiledExpr<T> {
+    | ----------------------------- methods in this implementation
+...
+602 |     fn add_target_without_indexes_to_set(self, inputs: &mut SlotSet) {
+    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+611 |     fn add_target_and_indexes_to_set(self, inputs: &mut SlotSet) {
+    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: method `field_by_name` is never used
+   --> crates/fayalite/src/sim/compiler.rs:628:8
+    |
+621 | impl CompiledExpr<Bundle> {
+    | ------------------------- method in this implementation
+...
+628 |     fn field_by_name(self, name: Interned<str>) -> CompiledExpr<CanonicalType> {
+    |        ^^^^^^^^^^^^^
+
+warning: method `for_each` is never used
+    --> crates/fayalite/src/sim/compiler.rs:1272:16
+     |
+1251 |           impl SlotToAssignmentIndexFullMap {
+     |           --------------------------------- method in this implementation
+...
+1272 |               fn for_each(
+     |                  ^^^^^^^^
+...
+1413 | / get_state_part_kinds! {
+1414 | |     make_assignment_graph! {
+1415 | |         type_plural_fields;
+1416 | |         type_singular_variants;
+...    |
+1422 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_assignment_graph` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: struct `SlotVec` is never constructed
+    --> crates/fayalite/src/sim/compiler.rs:1509:16
+     |
+1509 |           struct SlotVec {
+     |                  ^^^^^^^
+...
+1521 | / get_state_part_kinds! {
+1522 | |     make_slot_vec! {
+1523 | |         type_plural_fields;
+1524 | |         type_kinds;
+1525 | |     }
+1526 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_slot_vec` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `is_empty` is never used
+    --> crates/fayalite/src/sim/compiler.rs:1514:16
+     |
+1513 |           impl SlotVec {
+     |           ------------ method in this implementation
+1514 |               fn is_empty(&self) -> bool {
+     |                  ^^^^^^^^
+...
+1521 | / get_state_part_kinds! {
+1522 | |     make_slot_vec! {
+1523 | |         type_plural_fields;
+1524 | |         type_kinds;
+1525 | |     }
+1526 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_slot_vec` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `is_empty`, `for_each`, and `all` are never used
+    --> crates/fayalite/src/sim/compiler.rs:1539:16
+     |
+1538 |           impl SlotSet {
+     |           ------------ methods in this implementation
+1539 |               fn is_empty(&self) -> bool {
+     |                  ^^^^^^^^
+...
+1542 |               fn for_each(
+     |                  ^^^^^^^^
+...
+1548 |               fn all(
+     |                  ^^^
+...
+1619 | / get_state_part_kinds! {
+1620 | |     make_slot_set! {
+1621 | |         type_plural_fields;
+1622 | |         type_kinds;
+1623 | |     }
+1624 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_slot_set` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: constant `MIN_BITS_FOR_NEEDING_BIG` is never used
+  --> crates/fayalite/src/sim/interpreter.rs:33:18
+   |
+33 | pub(crate) const MIN_BITS_FOR_NEEDING_BIG: usize = SmallUInt::BITS as usize + 1;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: struct `InsnFieldTypeTransformUnit` is never constructed
+  --> crates/fayalite/src/sim/interpreter.rs:50:19
+   |
+50 | pub(crate) struct InsnFieldTypeTransformUnit;
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: struct `InsnFieldTypeTransformValue` is never constructed
+  --> crates/fayalite/src/sim/interpreter.rs:80:19
+   |
+80 | pub(crate) struct InsnFieldTypeTransformValue;
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: associated constant `UNIT` is never used
+  --> crates/fayalite/src/sim/interpreter.rs:90:11
+   |
+89 | pub trait InsnFieldTrait: Send + Sync + 'static + Copy + Eq + Hash + fmt::Debug {
+   |           -------------- associated constant in this trait
+90 |     const UNIT: InsnFieldType<InsnFieldTypeTransformUnit>;
+   |           ^^^^
+
+warning: field `orig_insns` is never read
+    --> crates/fayalite/src/sim/interpreter.rs:1035:24
+     |
+1034 |           pub(crate) struct BorrowedState<'a> {
+     |                             ------------- field in this struct
+1035 |               pub(crate) orig_insns: Interned<Insns<InsnsBuildingDone>>,
+     |                          ^^^^^^^^^^
+...
+1052 | / get_state_part_kinds! {
+1053 | |     make_state! {
+1054 | |         state_plural_fields;
+1055 | |         state_kinds;
+1056 | |     }
+1057 | | }
+     | |_- in this macro invocation
+     |
+     = note: `BorrowedState` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+     = note: this warning originates in the macro `make_state` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: struct `StatePartIndexMap` is never constructed
+    --> crates/fayalite/src/sim/interpreter.rs:1060:19
+     |
+1060 | pub(crate) struct StatePartIndexMap<K: StatePartKind, V> {
+     |                   ^^^^^^^^^^^^^^^^^
+
+warning: multiple associated items are never used
+    --> crates/fayalite/src/sim/interpreter.rs:1079:19
+     |
+1078 | impl<K: StatePartKind, V> StatePartIndexMap<K, V> {
+     | ------------------------------------------------- associated items in this implementation
+1079 |     pub(crate) fn new() -> Self {
+     |                   ^^^
+...
+1085 |     pub(crate) fn get(&self, key: StatePartIndex<K>) -> Option<&V> {
+     |                   ^^^
+...
+1088 |     pub(crate) fn get_mut(&mut self, key: StatePartIndex<K>) -> Option<&mut V> {
+     |                   ^^^^^^^
+...
+1091 |     pub(crate) fn keys(&self) -> impl Iterator<Item = StatePartIndex<K>> + '_ {
+     |                   ^^^^
+...
+1094 |     pub(crate) fn values(&self) -> vec_map::Values<'_, V> {
+     |                   ^^^^^^
+...
+1097 |     pub(crate) fn values_mut(&mut self) -> vec_map::ValuesMut<'_, V> {
+     |                   ^^^^^^^^^^
+...
+1100 |     pub(crate) fn iter(&self) -> impl Iterator<Item = (StatePartIndex<K>, &V)> + '_ {
+     |                   ^^^^
+...
+1105 |     pub(crate) fn iter_mut(&mut self) -> impl Iterator<Item = (StatePartIndex<K>, &mut V)> + '_ {
+     |                   ^^^^^^^^
+...
+1110 |     pub(crate) fn len(&self) -> usize {
+     |                   ^^^
+...
+1113 |     pub(crate) fn is_empty(&self) -> bool {
+     |                   ^^^^^^^^
+...
+1116 |     pub(crate) fn insert(&mut self, key: StatePartIndex<K>, value: V) -> Option<V> {
+     |                   ^^^^^^
+...
+1119 |     pub(crate) fn remove(&mut self, key: StatePartIndex<K>) -> Option<V> {
+     |                   ^^^^^^
+...
+1122 |     pub(crate) fn entry(&mut self, key: StatePartIndex<K>) -> StatePartIndexMapEntry<'_, K, V> {
+     |                   ^^^^^
+
+warning: struct `StatePartIndexMapVacantEntry` is never constructed
+    --> crates/fayalite/src/sim/interpreter.rs:1154:19
+     |
+1154 | pub(crate) struct StatePartIndexMapVacantEntry<'a, K: StatePartKind, V>(
+     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: struct `StatePartIndexMapOccupiedEntry` is never constructed
+    --> crates/fayalite/src/sim/interpreter.rs:1159:19
+     |
+1159 | pub(crate) struct StatePartIndexMapOccupiedEntry<'a, K: StatePartKind, V>(
+     |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: enum `StatePartIndexMapEntry` is never used
+    --> crates/fayalite/src/sim/interpreter.rs:1164:17
+     |
+1164 | pub(crate) enum StatePartIndexMapEntry<'a, K: StatePartKind, V> {
+     |                 ^^^^^^^^^^^^^^^^^^^^^^
+
+warning: methods `or_insert` and `or_insert_with` are never used
+    --> crates/fayalite/src/sim/interpreter.rs:1170:19
+     |
+1169 | impl<'a, K: StatePartKind, V> StatePartIndexMapEntry<'a, K, V> {
+     | -------------------------------------------------------------- methods in this implementation
+1170 |     pub(crate) fn or_insert(self, default: V) -> &'a mut V {
+     |                   ^^^^^^^^^
+...
+1176 |     pub(crate) fn or_insert_with(self, f: impl FnOnce() -> V) -> &'a mut V {
+     |                   ^^^^^^^^^^^^^^
+
+warning: method `last_insn_pc` is never used
+    --> crates/fayalite/src/sim/interpreter.rs:1193:19
+     |
+1184 | impl Insns<InsnsBuilding> {
+     | ------------------------- method in this implementation
+...
+1193 |     pub(crate) fn last_insn_pc(&self) -> usize {
+     |                   ^^^^^^^^^^^^
+
+warning: function `bigint_pow2` is never used
+    --> crates/fayalite/src/sim/interpreter.rs:1338:4
+     |
+1338 | fn bigint_pow2(width: usize) -> Interned<BigInt> {
+     |    ^^^^^^^^^^^
+
+warning: methods `fields_unit` and `into_fields` are never used
+    --> crates/fayalite/src/sim/interpreter.rs:449:27
+     |
+ 448 |           impl $Insn {
+     |           ---------- methods in this implementation
+ 449 |               $vis const fn fields_unit(&self) -> &'static [InsnField<InsnFieldTypeTransformUnit>] {
+     |                             ^^^^^^^^^^^
+...
+ 521 |               $vis fn into_fields(self) -> std::array::IntoIter<InsnField<InsnFieldTypeTransformValue>, { $Insn::MAX_FIELDS }> {
+     |                       ^^^^^^^^^^^
+...
+1435 | / impl_insns! {
+1436 | |     #[insn = Insn, next_macro = next, branch_macro = branch]
+1437 | |     pub(crate) fn State::run(&mut self) -> () {
+1438 | |         #[state]
+...    |
+2106 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `impl_insns` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `offset` is never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:490:19
+    |
+469 | impl<K: StatePartKind> StatePartIndexRange<K> {
+    | --------------------------------------------- method in this implementation
+...
+490 |     pub(crate) fn offset(self, offset: StatePartIndex<K>) -> Self {
+    |                   ^^^^^^
+
+warning: methods `len` and `is_empty` are never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:574:27
+    |
+573 |           impl<BK: InsnsBuildingKind> StateLayout<BK> {
+    |           ------------------------------------------- methods in this implementation
+574 |               pub(crate) fn len(&self) -> StateLen {
+    |                             ^^^
+...
+580 |               pub(crate) fn is_empty(&self) -> bool {
+    |                             ^^^^^^^^
+...
+677 | / get_state_part_kinds! {
+678 | |     make_state_layout! {
+679 | |         state_plural_fields;
+680 | |         state_kinds;
+681 | |     }
+682 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `next_index` and `allocate` are never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:592:27
+    |
+591 |           impl StateLayout<InsnsBuilding> {
+    |           ------------------------------- methods in this implementation
+592 |               pub(crate) fn next_index(&self) -> StateIndex {
+    |                             ^^^^^^^^^^
+...
+598 |               pub(crate) fn allocate<BK: InsnsBuildingKind>(
+    |                             ^^^^^^^^
+...
+677 | / get_state_part_kinds! {
+678 | |     make_state_layout! {
+679 | |         state_plural_fields;
+680 | |         state_kinds;
+681 | |     }
+682 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `is_empty` is never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:631:27
+    |
+625 |           impl<BK: InsnsBuildingKind> TypeLayout<BK> {
+    |           ------------------------------------------ method in this implementation
+...
+631 |               pub(crate) fn is_empty(&self) -> bool {
+    |                             ^^^^^^^^
+...
+677 | / get_state_part_kinds! {
+678 | |     make_state_layout! {
+679 | |         state_plural_fields;
+680 | |         state_kinds;
+681 | |     }
+682 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `next_index` is never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:652:27
+    |
+651 |           impl TypeLayout<InsnsBuilding> {
+    |           ------------------------------ method in this implementation
+652 |               pub(crate) fn next_index(&self) -> TypeIndex {
+    |                             ^^^^^^^^^^
+...
+677 | / get_state_part_kinds! {
+678 | |     make_state_layout! {
+679 | |         state_plural_fields;
+680 | |         state_kinds;
+681 | |     }
+682 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `is_empty` is never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:702:19
+    |
+693 | impl<K: StatePartKind, BK: InsnsBuildingKind> StatePartLayout<K, BK> {
+    | -------------------------------------------------------------------- method in this implementation
+...
+702 |     pub(crate) fn is_empty(&self) -> bool {
+    |                   ^^^^^^^^
+
+warning: struct `StateLen` is never constructed
+   --> crates/fayalite/src/sim/interpreter/parts.rs:809:27
+    |
+809 |           pub(crate) struct StateLen {
+    |                             ^^^^^^^^
+...
+863 | / get_state_part_kinds! {
+864 | |     make_state_len! {
+865 | |         state_plural_fields;
+866 | |         state_kinds;
+...   |
+870 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_len` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `only_small` is never used
+   --> crates/fayalite/src/sim/interpreter/parts.rs:849:33
+    |
+824 |           impl TypeLen {
+    |           ------------ method in this implementation
+...
+849 |               pub(crate) const fn only_small(mut self) -> Option<StatePartLen<StatePartKindSmallSlots>> {
+    |                                   ^^^^^^^^^^
+...
+863 | / get_state_part_kinds! {
+864 | |     make_state_len! {
+865 | |         state_plural_fields;
+866 | |         state_kinds;
+...   |
+870 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_len` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: struct `StateIndex` is never constructed
+   --> crates/fayalite/src/sim/interpreter/parts.rs:926:27
+    |
+926 |           pub(crate) struct StateIndex {
+    |                             ^^^^^^^^^^
+...
+949 | / get_state_part_kinds! {
+950 | |     make_state_index! {
+951 | |         state_plural_fields;
+952 | |         state_kinds;
+953 | |     }
+954 | | }
+    | |_- in this macro invocation
+    |
+    = note: this warning originates in the macro `make_state_index` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: struct `StateIndexRange` is never constructed
+    --> crates/fayalite/src/sim/interpreter/parts.rs:963:27
+     |
+ 963 |           pub(crate) struct StateIndexRange {
+     |                             ^^^^^^^^^^^^^^^
+...
+1041 | / get_state_part_kinds! {
+1042 | |     make_state_index_range! {
+1043 | |         state_plural_fields;
+1044 | |         state_kinds;
+...    |
+1047 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `start`, `len`, and `is_empty` are never used
+    --> crates/fayalite/src/sim/interpreter/parts.rs:969:27
+     |
+ 968 |           impl StateIndexRange {
+     |           -------------------- methods in this implementation
+ 969 |               pub(crate) fn start(self) -> StateIndex {
+     |                             ^^^^^
+...
+ 975 |               pub(crate) fn len(self) -> StateLen {
+     |                             ^^^
+...
+ 981 |               pub(crate) fn is_empty(self) -> bool {
+     |                             ^^^^^^^^
+...
+1041 | / get_state_part_kinds! {
+1042 | |     make_state_index_range! {
+1043 | |         state_plural_fields;
+1044 | |         state_kinds;
+...    |
+1047 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: method `offset` is never used
+    --> crates/fayalite/src/sim/interpreter/parts.rs:1023:27
+     |
+ 991 |           impl TypeIndexRange {
+     |           ------------------- method in this implementation
+...
+1023 |               pub(crate) fn offset(self, offset: TypeIndex) -> Self {
+     |                             ^^^^^^
+...
+1041 | / get_state_part_kinds! {
+1042 | |     make_state_index_range! {
+1043 | |         state_plural_fields;
+1044 | |         state_kinds;
+...    |
+1047 | | }
+     | |_- in this macro invocation
+     |
+     = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: methods `is_unique` and `is_shared` are never used
+  --> crates/fayalite/src/util/alternating_cell.rs:59:19
+   |
+40 | impl<T: ?Sized> AlternatingCell<T> {
+   | ---------------------------------- methods in this implementation
+...
+59 |     pub(crate) fn is_unique(&self) -> bool {
+   |                   ^^^^^^^^^
+...
+62 |     pub(crate) fn is_shared(&self) -> bool {
+   |                   ^^^^^^^^^
+
+warning: function `tcl_escape` is never used
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:362:4
+    |
+362 | fn tcl_escape(s: impl AsRef<str>) -> String {
+    |    ^^^^^^^^^^
+
+warning: field `0` is never read
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:382:12
+    |
+382 |     Module(Module<Bundle>),
+    |     ------ ^^^^^^^^^^^^^^
+    |     |
+    |     field in this variant
+    |
+    = note: `AnnotationTarget` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
+help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
+    |
+382 -     Module(Module<Bundle>),
+382 +     Module(()),
+    |
+
+warning: field `0` is never read
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:383:9
+    |
+383 |     Mem(Mem),
+    |     --- ^^^
+    |     |
+    |     field in this variant
+    |
+    = note: `AnnotationTarget` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis
+help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
+    |
+383 -     Mem(Mem),
+383 +     Mem(()),
+    |
+
+warning: method `source_location` is never used
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:388:8
+    |
+387 | impl AnnotationTarget {
+    | --------------------- method in this implementation
+388 |     fn source_location(self) -> SourceLocation {
+    |        ^^^^^^^^^^^^^^^
+
+warning: field `output` is never read
+   --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:399:5
+    |
+398 | struct PcfFileWriter<W: fmt::Write> { //TODO
+    |        ------------- field in this struct
+399 |     output: W,
+    |     ^^^^^^
+
+warning: `fayalite` (lib) generated 77 warnings (run `cargo fix --lib -p fayalite` to apply 29 suggestions)
+    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 00s
+     Running `target/debug/examples/blinky yosys-nextpnr-ecp5 --nextpnr /home/alex/.guix-profile/bin/nextpnr-ecp5 --platform orangecrab-85k -o target/blinky-out --ecppack /home/alex/.guix-profile/bin/ecppack --placeholder-dir /tmp/anyPathBuf/orangecrab_r0.2.1.pcf --yosys /home/alex/.guix-profile/bin/yosys`
+error: invalid value '/home/alex/.guix-profile/bin/nextpnr-ecp5' for '--nextpnr <NEXTPNR>': nextpnr: failed to resolve "/home/alex/.guix-profile/bin/nextpnr-ecp5" to a valid program: cannot find binary path
+
+For more information, try '--help'.
+make: *** [Makefile:6: all] Error 2
diff --git a/fix_warnings.txt b/fix_warnings.txt new file mode 100644 index 0000000..8205249 --- /dev/null +++ b/fix_warnings.txt @@ -0,0 +1,869 @@ + Compiling fayalite-proc-macros v0.3.0 (/home/alex/Hacking/FPGA/libre-chip/fayalite/crates/fayalite-proc-macros) + Compiling fayalite v0.3.0 (/home/alex/Hacking/FPGA/libre-chip/fayalite/crates/fayalite) +warning: unused import: `make_impls` + --> crates/fayalite/src/expr/ops.rs:582:16 + | +582 | pub(crate) use make_impls; + | ^^^^^^^^^^ + | + = note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default + +warning: unused imports: `annotations::make_annotation_enum` and `intern::Interned` + --> crates/fayalite/src/vendor/lattice.rs:5:5 + | +5 | annotations::make_annotation_enum, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +6 | build::{GlobalParams, ToArgs, WriteArgs}, +7 | intern::Interned, + | ^^^^^^^^^^^^^^^^ + +warning: unused import: `ordered_float::NotNan` + --> crates/fayalite/src/vendor/lattice.rs:11:5 + | +11 | use ordered_float::NotNan; + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: unused import: `primitives` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:15:9 + | +15 | primitives, + | ^^^^^^^^^^ + +warning: unused import: `ordered_float::NotNan` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:18:5 + | +18 | use ordered_float::NotNan; + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: variant `OrangeCrab_25k` should have an upper camel case name + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:63:9 + | +63 | OrangeCrab_25k, + | ^^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OrangeCrab25k` + | + = note: `#[warn(non_camel_case_types)]` (part of `#[warn(nonstandard_style)]`) on by default + +warning: variant `OrangeCrab_85k` should have an upper camel case name + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:65:9 + | +65 | OrangeCrab_85k, + | ^^^^^^^^^^^^^^ help: convert the identifier to upper camel case: `OrangeCrab85k` + +warning: unused imports: `Annotation`, `ScopedNameId`, `TargetBase`, and `TargetName` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:5:19 + | + 5 | annotations::{Annotation, TargetedAnnotation}, + | ^^^^^^^^^^ +... +16 | expr::target::{Target, TargetBase}, + | ^^^^^^^^^^ +... +20 | NameId, ScopedNameId, TargetName, + | ^^^^^^^^^^^^ ^^^^^^^^^^ + +warning: unused import: `convert::Infallible` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:34:5 + | +34 | convert::Infallible, + | ^^^^^^^^^^^^^^^^^^^ + +warning: unused variable: `lhs_ty` + --> crates/fayalite/src/sim/compiler.rs:3809:37 + | +3809 | CanonicalType::Enum(lhs_ty) => { + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_lhs_ty` + | + = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default + +warning: unused variable: `rhs_ty` + --> crates/fayalite/src/sim/compiler.rs:3810:45 + | +3810 | let CanonicalType::Enum(rhs_ty) = rhs.ty() else { + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_rhs_ty` + +warning: unused variable: `part_name` + --> crates/fayalite/src/sim/compiler.rs:3898:37 + | +3898 | let mut alloc_small_slot = |part_name: &str| { + | ^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_part_name` + +warning: unused variable: `annotations` + --> crates/fayalite/src/sim/compiler.rs:4080:23 + | +4080 | let StmtReg { annotations, reg } = stmt_reg; + | ^^^^^^^^^^^ help: try ignoring the field: `annotations: _` + +warning: unused variable: `annotations` + --> crates/fayalite/src/sim/compiler.rs:4118:46 + | +4118 | StmtDeclaration::Wire(StmtWire { annotations, wire }) => {} + | ^^^^^^^^^^^ help: try ignoring the field: `annotations: _` + +warning: unused variable: `wire` + --> crates/fayalite/src/sim/compiler.rs:4118:59 + | +4118 | StmtDeclaration::Wire(StmtWire { annotations, wire }) => {} + | ^^^^ help: try ignoring the field: `wire: _` + +warning: unused variable: `annotations` + --> crates/fayalite/src/sim/compiler.rs:4129:17 + | +4129 | annotations, + | ^^^^^^^^^^^ help: try ignoring the field: `annotations: _` + +warning: unused variable: `location` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:233:49 + | +233 | let make_buffered_output = |name: &str, location: &str, io_standard: &str| { + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_location` + +warning: unused variable: `io_standard` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:233:65 + | +233 | let make_buffered_output = |name: &str, location: &str, io_standard: &str| { + | ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_io_standard` + +warning: unused variable: `location` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:210:48 + | +210 | let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| { + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_location` + +warning: unused variable: `io_standard` + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:210:64 + | +210 | let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| { + | ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_io_standard` + +warning: variable `frequency` is assigned to, but never used + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:257:13 + | +257 | let mut frequency = clk100_div_pow2[0].ty().frequency(); + | ^^^^^^^^^^^^^ + | + = note: consider using `_frequency` instead + +warning: value assigned to `frequency` is never read + --> crates/fayalite/src/vendor/lattice/orangecrab.rs:268:13 + | +268 | frequency = p.ty().frequency(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` (part of `#[warn(unused)]`) on by default + +warning: unused variable: `output` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:496:9 + | +496 | output: &mut impl fmt::Write, + | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_output` + +warning: unused variable: `port` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:497:9 + | +497 | port: &ScalarizedModuleABIPort, + | ^^^^ help: if this is intentional, prefix it with an underscore: `_port` + +warning: unused variable: `annotations` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:498:9 + | +498 | annotations: ScalarizedModuleABIAnnotations<'_>, + | ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_annotations` + +warning: unused variable: `job_data` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:707:13 + | +707 | let job_data @ YosysNextpnrRunNextpnr { + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_job_data` + +warning: unused variable: `nextpnr_lattice_seed` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:708:13 + | +708 | nextpnr_lattice_seed, + | ^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `nextpnr_lattice_seed: _` + +warning: unused variable: `routed_json_file_name` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:710:13 + | +710 | routed_json_file_name, + | ^^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `routed_json_file_name: _` + +warning: unused variable: `job_data` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:861:13 + | +861 | let job_data @ YosysNextpnrRunEcpPack { + | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_job_data` + +warning: unused variable: `placeholder_dir` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:862:4 + | +862 | placeholder_dir, + | ^^^^^^^^^^^^^^^ help: try ignoring the field: `placeholder_dir: _` + +warning: unused variable: `device` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:863:13 + | +863 | device, + | ^^^^^^ help: try ignoring the field: `device: _` + +warning: unused variable: `routed_json_file_name` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:864:13 + | +864 | routed_json_file_name, + | ^^^^^^^^^^^^^^^^^^^^^ help: try ignoring the field: `routed_json_file_name: _` + +warning: unused variable: `frames_file_name` + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:866:13 + | +866 | frames_file_name, + | ^^^^^^^^^^^^^^^^ help: try ignoring the field: `frames_file_name: _` + +warning: struct `SliceAsMapDebug` is never constructed + --> crates/fayalite/src/sim.rs:3231:8 + | +3231 | struct SliceAsMapDebug<'a, T>(&'a [Option]); + | ^^^^^^^^^^^^^^^ + | + = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default + +warning: method `element_dyn` is never used + --> crates/fayalite/src/sim/compiler.rs:397:8 + | +385 | impl CompiledValue { + | ------------------------- method in this implementation +... +397 | fn element_dyn( + | ^^^^^^^^^^^ + +warning: methods `len`, `index`, `is_empty`, and `stride` are never used + --> crates/fayalite/src/sim/compiler.rs:444:27 + | +434 | impl TypeArrayIndex { + | ------------------- methods in this implementation +... +444 | pub(crate) fn len(self) -> usize { + | ^^^ +... +449 | pub(crate) fn index(self) -> StatePartIndex { + | ^^^^^ +... +454 | pub(crate) fn is_empty(self) -> bool { + | ^^^^^^^^ +... +457 | pub(crate) fn stride(self) -> TypeLen { + | ^^^^^^ +... +569 | / get_state_part_kinds! { +570 | | make_type_array_indexes! { +571 | | type_plural_fields; +572 | | type_kinds; +573 | | } +574 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `iter`, `for_each_offset`, `split_first`, and `for_each_offset2` are never used + --> crates/fayalite/src/sim/compiler.rs:478:27 + | +469 | impl<'a> TypeArrayIndexesRef<'a> { + | -------------------------------- methods in this implementation +... +478 | pub(crate) fn iter(self) -> impl Iterator + 'a { + | ^^^^ +... +483 | pub(crate) fn for_each_offset( + | ^^^^^^^^^^^^^^^ +... +491 | pub(crate) fn split_first(self) -> Option<(TypeArrayIndex, Self)> { + | ^^^^^^^^^^^ +... +501 | pub(crate) fn for_each_offset2( + | ^^^^^^^^^^^^^^^^ +... +569 | / get_state_part_kinds! { +570 | | make_type_array_indexes! { +571 | | type_plural_fields; +572 | | type_kinds; +573 | | } +574 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: struct `TypeArrayIndexed` is never constructed + --> crates/fayalite/src/sim/compiler.rs:534:27 + | +534 | pub(crate) struct TypeArrayIndexed { + | ^^^^^^^^^^^^^^^^ +... +569 | / get_state_part_kinds! { +570 | | make_type_array_indexes! { +571 | | type_plural_fields; +572 | | type_kinds; +573 | | } +574 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: associated items `from_parts`, `base`, and `indexes` are never used + --> crates/fayalite/src/sim/compiler.rs:539:27 + | +538 | impl TypeArrayIndexed { + | --------------------- associated items in this implementation +539 | pub(crate) fn from_parts(base: TypeIndex, indexes: TypeArrayIndexes) -> Self { + | ^^^^^^^^^^ +... +547 | pub(crate) fn base(self) -> TypeIndex { + | ^^^^ +... +552 | pub(crate) fn indexes(self) -> TypeArrayIndexes { + | ^^^^^^^ +... +569 | / get_state_part_kinds! { +570 | | make_type_array_indexes! { +571 | | type_plural_fields; +572 | | type_kinds; +573 | | } +574 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_type_array_indexes` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `add_target_without_indexes_to_set` and `add_target_and_indexes_to_set` are never used + --> crates/fayalite/src/sim/compiler.rs:602:8 + | +591 | impl CompiledExpr { + | ----------------------------- methods in this implementation +... +602 | fn add_target_without_indexes_to_set(self, inputs: &mut SlotSet) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +611 | fn add_target_and_indexes_to_set(self, inputs: &mut SlotSet) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: method `field_by_name` is never used + --> crates/fayalite/src/sim/compiler.rs:628:8 + | +621 | impl CompiledExpr { + | ------------------------- method in this implementation +... +628 | fn field_by_name(self, name: Interned) -> CompiledExpr { + | ^^^^^^^^^^^^^ + +warning: method `for_each` is never used + --> crates/fayalite/src/sim/compiler.rs:1272:16 + | +1251 | impl SlotToAssignmentIndexFullMap { + | --------------------------------- method in this implementation +... +1272 | fn for_each( + | ^^^^^^^^ +... +1413 | / get_state_part_kinds! { +1414 | | make_assignment_graph! { +1415 | | type_plural_fields; +1416 | | type_singular_variants; +... | +1422 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_assignment_graph` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: struct `SlotVec` is never constructed + --> crates/fayalite/src/sim/compiler.rs:1509:16 + | +1509 | struct SlotVec { + | ^^^^^^^ +... +1521 | / get_state_part_kinds! { +1522 | | make_slot_vec! { +1523 | | type_plural_fields; +1524 | | type_kinds; +1525 | | } +1526 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_slot_vec` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `is_empty` is never used + --> crates/fayalite/src/sim/compiler.rs:1514:16 + | +1513 | impl SlotVec { + | ------------ method in this implementation +1514 | fn is_empty(&self) -> bool { + | ^^^^^^^^ +... +1521 | / get_state_part_kinds! { +1522 | | make_slot_vec! { +1523 | | type_plural_fields; +1524 | | type_kinds; +1525 | | } +1526 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_slot_vec` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `is_empty`, `for_each`, and `all` are never used + --> crates/fayalite/src/sim/compiler.rs:1539:16 + | +1538 | impl SlotSet { + | ------------ methods in this implementation +1539 | fn is_empty(&self) -> bool { + | ^^^^^^^^ +... +1542 | fn for_each( + | ^^^^^^^^ +... +1548 | fn all( + | ^^^ +... +1619 | / get_state_part_kinds! { +1620 | | make_slot_set! { +1621 | | type_plural_fields; +1622 | | type_kinds; +1623 | | } +1624 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_slot_set` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: constant `MIN_BITS_FOR_NEEDING_BIG` is never used + --> crates/fayalite/src/sim/interpreter.rs:33:18 + | +33 | pub(crate) const MIN_BITS_FOR_NEEDING_BIG: usize = SmallUInt::BITS as usize + 1; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: struct `InsnFieldTypeTransformUnit` is never constructed + --> crates/fayalite/src/sim/interpreter.rs:50:19 + | +50 | pub(crate) struct InsnFieldTypeTransformUnit; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: struct `InsnFieldTypeTransformValue` is never constructed + --> crates/fayalite/src/sim/interpreter.rs:80:19 + | +80 | pub(crate) struct InsnFieldTypeTransformValue; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: associated constant `UNIT` is never used + --> crates/fayalite/src/sim/interpreter.rs:90:11 + | +89 | pub trait InsnFieldTrait: Send + Sync + 'static + Copy + Eq + Hash + fmt::Debug { + | -------------- associated constant in this trait +90 | const UNIT: InsnFieldType; + | ^^^^ + +warning: field `orig_insns` is never read + --> crates/fayalite/src/sim/interpreter.rs:1035:24 + | +1034 | pub(crate) struct BorrowedState<'a> { + | ------------- field in this struct +1035 | pub(crate) orig_insns: Interned>, + | ^^^^^^^^^^ +... +1052 | / get_state_part_kinds! { +1053 | | make_state! { +1054 | | state_plural_fields; +1055 | | state_kinds; +1056 | | } +1057 | | } + | |_- in this macro invocation + | + = note: `BorrowedState` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis + = note: this warning originates in the macro `make_state` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: struct `StatePartIndexMap` is never constructed + --> crates/fayalite/src/sim/interpreter.rs:1060:19 + | +1060 | pub(crate) struct StatePartIndexMap { + | ^^^^^^^^^^^^^^^^^ + +warning: multiple associated items are never used + --> crates/fayalite/src/sim/interpreter.rs:1079:19 + | +1078 | impl StatePartIndexMap { + | ------------------------------------------------- associated items in this implementation +1079 | pub(crate) fn new() -> Self { + | ^^^ +... +1085 | pub(crate) fn get(&self, key: StatePartIndex) -> Option<&V> { + | ^^^ +... +1088 | pub(crate) fn get_mut(&mut self, key: StatePartIndex) -> Option<&mut V> { + | ^^^^^^^ +... +1091 | pub(crate) fn keys(&self) -> impl Iterator> + '_ { + | ^^^^ +... +1094 | pub(crate) fn values(&self) -> vec_map::Values<'_, V> { + | ^^^^^^ +... +1097 | pub(crate) fn values_mut(&mut self) -> vec_map::ValuesMut<'_, V> { + | ^^^^^^^^^^ +... +1100 | pub(crate) fn iter(&self) -> impl Iterator, &V)> + '_ { + | ^^^^ +... +1105 | pub(crate) fn iter_mut(&mut self) -> impl Iterator, &mut V)> + '_ { + | ^^^^^^^^ +... +1110 | pub(crate) fn len(&self) -> usize { + | ^^^ +... +1113 | pub(crate) fn is_empty(&self) -> bool { + | ^^^^^^^^ +... +1116 | pub(crate) fn insert(&mut self, key: StatePartIndex, value: V) -> Option { + | ^^^^^^ +... +1119 | pub(crate) fn remove(&mut self, key: StatePartIndex) -> Option { + | ^^^^^^ +... +1122 | pub(crate) fn entry(&mut self, key: StatePartIndex) -> StatePartIndexMapEntry<'_, K, V> { + | ^^^^^ + +warning: struct `StatePartIndexMapVacantEntry` is never constructed + --> crates/fayalite/src/sim/interpreter.rs:1154:19 + | +1154 | pub(crate) struct StatePartIndexMapVacantEntry<'a, K: StatePartKind, V>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: struct `StatePartIndexMapOccupiedEntry` is never constructed + --> crates/fayalite/src/sim/interpreter.rs:1159:19 + | +1159 | pub(crate) struct StatePartIndexMapOccupiedEntry<'a, K: StatePartKind, V>( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: enum `StatePartIndexMapEntry` is never used + --> crates/fayalite/src/sim/interpreter.rs:1164:17 + | +1164 | pub(crate) enum StatePartIndexMapEntry<'a, K: StatePartKind, V> { + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: methods `or_insert` and `or_insert_with` are never used + --> crates/fayalite/src/sim/interpreter.rs:1170:19 + | +1169 | impl<'a, K: StatePartKind, V> StatePartIndexMapEntry<'a, K, V> { + | -------------------------------------------------------------- methods in this implementation +1170 | pub(crate) fn or_insert(self, default: V) -> &'a mut V { + | ^^^^^^^^^ +... +1176 | pub(crate) fn or_insert_with(self, f: impl FnOnce() -> V) -> &'a mut V { + | ^^^^^^^^^^^^^^ + +warning: method `last_insn_pc` is never used + --> crates/fayalite/src/sim/interpreter.rs:1193:19 + | +1184 | impl Insns { + | ------------------------- method in this implementation +... +1193 | pub(crate) fn last_insn_pc(&self) -> usize { + | ^^^^^^^^^^^^ + +warning: function `bigint_pow2` is never used + --> crates/fayalite/src/sim/interpreter.rs:1338:4 + | +1338 | fn bigint_pow2(width: usize) -> Interned { + | ^^^^^^^^^^^ + +warning: methods `fields_unit` and `into_fields` are never used + --> crates/fayalite/src/sim/interpreter.rs:449:27 + | + 448 | impl $Insn { + | ---------- methods in this implementation + 449 | $vis const fn fields_unit(&self) -> &'static [InsnField] { + | ^^^^^^^^^^^ +... + 521 | $vis fn into_fields(self) -> std::array::IntoIter, { $Insn::MAX_FIELDS }> { + | ^^^^^^^^^^^ +... +1435 | / impl_insns! { +1436 | | #[insn = Insn, next_macro = next, branch_macro = branch] +1437 | | pub(crate) fn State::run(&mut self) -> () { +1438 | | #[state] +... | +2106 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `impl_insns` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `offset` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:490:19 + | +469 | impl StatePartIndexRange { + | --------------------------------------------- method in this implementation +... +490 | pub(crate) fn offset(self, offset: StatePartIndex) -> Self { + | ^^^^^^ + +warning: methods `len` and `is_empty` are never used + --> crates/fayalite/src/sim/interpreter/parts.rs:574:27 + | +573 | impl StateLayout { + | ------------------------------------------- methods in this implementation +574 | pub(crate) fn len(&self) -> StateLen { + | ^^^ +... +580 | pub(crate) fn is_empty(&self) -> bool { + | ^^^^^^^^ +... +677 | / get_state_part_kinds! { +678 | | make_state_layout! { +679 | | state_plural_fields; +680 | | state_kinds; +681 | | } +682 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `next_index` and `allocate` are never used + --> crates/fayalite/src/sim/interpreter/parts.rs:592:27 + | +591 | impl StateLayout { + | ------------------------------- methods in this implementation +592 | pub(crate) fn next_index(&self) -> StateIndex { + | ^^^^^^^^^^ +... +598 | pub(crate) fn allocate( + | ^^^^^^^^ +... +677 | / get_state_part_kinds! { +678 | | make_state_layout! { +679 | | state_plural_fields; +680 | | state_kinds; +681 | | } +682 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `is_empty` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:631:27 + | +625 | impl TypeLayout { + | ------------------------------------------ method in this implementation +... +631 | pub(crate) fn is_empty(&self) -> bool { + | ^^^^^^^^ +... +677 | / get_state_part_kinds! { +678 | | make_state_layout! { +679 | | state_plural_fields; +680 | | state_kinds; +681 | | } +682 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `next_index` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:652:27 + | +651 | impl TypeLayout { + | ------------------------------ method in this implementation +652 | pub(crate) fn next_index(&self) -> TypeIndex { + | ^^^^^^^^^^ +... +677 | / get_state_part_kinds! { +678 | | make_state_layout! { +679 | | state_plural_fields; +680 | | state_kinds; +681 | | } +682 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_layout` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `is_empty` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:702:19 + | +693 | impl StatePartLayout { + | -------------------------------------------------------------------- method in this implementation +... +702 | pub(crate) fn is_empty(&self) -> bool { + | ^^^^^^^^ + +warning: struct `StateLen` is never constructed + --> crates/fayalite/src/sim/interpreter/parts.rs:809:27 + | +809 | pub(crate) struct StateLen { + | ^^^^^^^^ +... +863 | / get_state_part_kinds! { +864 | | make_state_len! { +865 | | state_plural_fields; +866 | | state_kinds; +... | +870 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_len` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `only_small` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:849:33 + | +824 | impl TypeLen { + | ------------ method in this implementation +... +849 | pub(crate) const fn only_small(mut self) -> Option> { + | ^^^^^^^^^^ +... +863 | / get_state_part_kinds! { +864 | | make_state_len! { +865 | | state_plural_fields; +866 | | state_kinds; +... | +870 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_len` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: struct `StateIndex` is never constructed + --> crates/fayalite/src/sim/interpreter/parts.rs:926:27 + | +926 | pub(crate) struct StateIndex { + | ^^^^^^^^^^ +... +949 | / get_state_part_kinds! { +950 | | make_state_index! { +951 | | state_plural_fields; +952 | | state_kinds; +953 | | } +954 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_index` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: struct `StateIndexRange` is never constructed + --> crates/fayalite/src/sim/interpreter/parts.rs:963:27 + | + 963 | pub(crate) struct StateIndexRange { + | ^^^^^^^^^^^^^^^ +... +1041 | / get_state_part_kinds! { +1042 | | make_state_index_range! { +1043 | | state_plural_fields; +1044 | | state_kinds; +... | +1047 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `start`, `len`, and `is_empty` are never used + --> crates/fayalite/src/sim/interpreter/parts.rs:969:27 + | + 968 | impl StateIndexRange { + | -------------------- methods in this implementation + 969 | pub(crate) fn start(self) -> StateIndex { + | ^^^^^ +... + 975 | pub(crate) fn len(self) -> StateLen { + | ^^^ +... + 981 | pub(crate) fn is_empty(self) -> bool { + | ^^^^^^^^ +... +1041 | / get_state_part_kinds! { +1042 | | make_state_index_range! { +1043 | | state_plural_fields; +1044 | | state_kinds; +... | +1047 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: method `offset` is never used + --> crates/fayalite/src/sim/interpreter/parts.rs:1023:27 + | + 991 | impl TypeIndexRange { + | ------------------- method in this implementation +... +1023 | pub(crate) fn offset(self, offset: TypeIndex) -> Self { + | ^^^^^^ +... +1041 | / get_state_part_kinds! { +1042 | | make_state_index_range! { +1043 | | state_plural_fields; +1044 | | state_kinds; +... | +1047 | | } + | |_- in this macro invocation + | + = note: this warning originates in the macro `make_state_index_range` which comes from the expansion of the macro `get_state_part_kinds` (in Nightly builds, run with -Z macro-backtrace for more info) + +warning: methods `is_unique` and `is_shared` are never used + --> crates/fayalite/src/util/alternating_cell.rs:59:19 + | +40 | impl AlternatingCell { + | ---------------------------------- methods in this implementation +... +59 | pub(crate) fn is_unique(&self) -> bool { + | ^^^^^^^^^ +... +62 | pub(crate) fn is_shared(&self) -> bool { + | ^^^^^^^^^ + +warning: function `tcl_escape` is never used + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:362:4 + | +362 | fn tcl_escape(s: impl AsRef) -> String { + | ^^^^^^^^^^ + +warning: field `0` is never read + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:382:12 + | +382 | Module(Module), + | ------ ^^^^^^^^^^^^^^ + | | + | field in this variant + | + = note: `AnnotationTarget` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis +help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field + | +382 - Module(Module), +382 + Module(()), + | + +warning: field `0` is never read + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:383:9 + | +383 | Mem(Mem), + | --- ^^^ + | | + | field in this variant + | + = note: `AnnotationTarget` has derived impls for the traits `Debug` and `Clone`, but these are intentionally ignored during dead code analysis +help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field + | +383 - Mem(Mem), +383 + Mem(()), + | + +warning: method `source_location` is never used + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:388:8 + | +387 | impl AnnotationTarget { + | --------------------- method in this implementation +388 | fn source_location(self) -> SourceLocation { + | ^^^^^^^^^^^^^^^ + +warning: field `output` is never read + --> crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs:399:5 + | +398 | struct PcfFileWriter { //TODO + | ------------- field in this struct +399 | output: W, + | ^^^^^^ + +warning: `fayalite` (lib) generated 77 warnings (run `cargo fix --lib -p fayalite` to apply 29 suggestions) + Finished `dev` profile [unoptimized + debuginfo] target(s) in 2m 00s + Running `target/debug/examples/blinky yosys-nextpnr-ecp5 --nextpnr /home/alex/.guix-profile/bin/nextpnr-ecp5 --platform orangecrab-85k -o target/blinky-out --ecppack /home/alex/.guix-profile/bin/ecppack --placeholder-dir /tmp/anyPathBuf/orangecrab_r0.2.1.pcf --yosys /home/alex/.guix-profile/bin/yosys` +error: invalid value '/home/alex/.guix-profile/bin/nextpnr-ecp5' for '--nextpnr ': nextpnr: failed to resolve "/home/alex/.guix-profile/bin/nextpnr-ecp5" to a valid program: cannot find binary path + +For more information, try '--help'. +make: *** [Makefile:6: all] Error 2 diff --git a/nextpnr.txt b/nextpnr.txt new file mode 100644 index 0000000..85d5678 --- /dev/null +++ b/nextpnr.txt @@ -0,0 +1,5 @@ +nextpnr-ecp5 for orangecrab +nextpnr-ice40 for other one* + +modified: Makefile +modified: crates/fayalite/src/vendor/lattice/yosys_nextpnr.rs diff --git a/tools/firrtl.tar.gz b/tools/firrtl.tar.gz new file mode 100644 index 0000000..1676917 Binary files /dev/null and b/tools/firrtl.tar.gz differ