Compare commits
1 commit
d2efb94686
...
2848f3dee4
| Author | SHA1 | Date | |
|---|---|---|---|
| 2848f3dee4 |
8 changed files with 48 additions and 390 deletions
|
|
@ -1,64 +1,55 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
use fayalite::prelude::*;
|
use fayalite::{
|
||||||
|
build::{ToArgs, WriteArgs},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
|
|
||||||
#[hdl_module]
|
#[hdl_module]
|
||||||
fn blinky(platform_io_builder: PlatformIOBuilder<'_>) {
|
fn blinky(clock_frequency: u64) {
|
||||||
let clk_input =
|
#[hdl]
|
||||||
platform_io_builder.peripherals_with_type::<peripherals::ClockInput>()[0].use_peripheral();
|
let clk: Clock = m.input();
|
||||||
let rst = platform_io_builder.peripherals_with_type::<Reset>()[0].use_peripheral();
|
#[hdl]
|
||||||
|
let rst: SyncReset = m.input();
|
||||||
let cd = #[hdl]
|
let cd = #[hdl]
|
||||||
ClockDomain {
|
ClockDomain {
|
||||||
clk: clk_input.clk,
|
clk,
|
||||||
rst,
|
rst: rst.to_reset(),
|
||||||
};
|
};
|
||||||
let max_value = (Expr::ty(clk_input).frequency() / 2.0).round_ties_even() as u64 - 1;
|
let max_value = clock_frequency / 2 - 1;
|
||||||
let int_ty = UInt::range_inclusive(0..=max_value);
|
let int_ty = UInt::range_inclusive(0..=max_value);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let counter_reg: UInt = reg_builder().clock_domain(cd).reset(0u8.cast_to(int_ty));
|
let counter_reg: UInt = reg_builder().clock_domain(cd).reset(0u8.cast_to(int_ty));
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let output_reg: Bool = reg_builder().clock_domain(cd).reset(false);
|
let output_reg: Bool = reg_builder().clock_domain(cd).reset(false);
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let rgb_output_reg = reg_builder().clock_domain(cd).reset(
|
|
||||||
#[hdl]
|
|
||||||
peripherals::RgbLed {
|
|
||||||
r: false,
|
|
||||||
g: false,
|
|
||||||
b: false,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
#[hdl]
|
|
||||||
if counter_reg.cmp_eq(max_value) {
|
if counter_reg.cmp_eq(max_value) {
|
||||||
connect_any(counter_reg, 0u8);
|
connect_any(counter_reg, 0u8);
|
||||||
connect(output_reg, !output_reg);
|
connect(output_reg, !output_reg);
|
||||||
connect(rgb_output_reg.r, !rgb_output_reg.r);
|
|
||||||
#[hdl]
|
|
||||||
if rgb_output_reg.r {
|
|
||||||
connect(rgb_output_reg.g, !rgb_output_reg.g);
|
|
||||||
#[hdl]
|
|
||||||
if rgb_output_reg.g {
|
|
||||||
connect(rgb_output_reg.b, !rgb_output_reg.b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
connect_any(counter_reg, counter_reg + 1_hdl_u1);
|
connect_any(counter_reg, counter_reg + 1_hdl_u1);
|
||||||
}
|
}
|
||||||
for led in platform_io_builder.peripherals_with_type::<peripherals::Led>() {
|
|
||||||
if let Ok(led) = led.try_use_peripheral() {
|
|
||||||
connect(led.on, output_reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for rgb_led in platform_io_builder.peripherals_with_type::<peripherals::RgbLed>() {
|
|
||||||
if let Ok(rgb_led) = rgb_led.try_use_peripheral() {
|
|
||||||
connect(rgb_led, rgb_output_reg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[hdl]
|
#[hdl]
|
||||||
let io = m.add_platform_io(platform_io_builder);
|
let led: Bool = m.output();
|
||||||
|
connect(led, output_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(clap::Args, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
struct ExtraArgs {
|
||||||
|
/// clock frequency in hertz
|
||||||
|
#[arg(long, default_value = "1000000", value_parser = clap::value_parser!(u64).range(2..))]
|
||||||
|
clock_frequency: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToArgs for ExtraArgs {
|
||||||
|
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||||
|
let Self { clock_frequency } = self;
|
||||||
|
args.write_arg(format!("--clock-frequency={clock_frequency}"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
BuildCli::main("blinky", |_, platform, _| {
|
BuildCli::main(|_cli, ExtraArgs { clock_frequency }| {
|
||||||
Ok(JobParams::new(platform.wrap_main_module(blinky)))
|
Ok(JobParams::new(blinky(clock_frequency), "blinky"))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -530,7 +530,6 @@ impl<'a, S: PeripheralsOnUseSharedState> PeripheralsBuilder<'a, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub struct Peripheral<T: Type> {
|
pub struct Peripheral<T: Type> {
|
||||||
ty: T,
|
ty: T,
|
||||||
common: PeripheralCommon,
|
common: PeripheralCommon,
|
||||||
|
|
@ -541,27 +540,6 @@ impl<T: Type> Peripheral<T> {
|
||||||
let Self { ty, ref common } = *self;
|
let Self { ty, ref common } = *self;
|
||||||
PeripheralRef { ty, common }
|
PeripheralRef { ty, common }
|
||||||
}
|
}
|
||||||
pub fn ty(&self) -> T {
|
|
||||||
self.as_ref().ty()
|
|
||||||
}
|
|
||||||
pub fn id(&self) -> PeripheralId {
|
|
||||||
self.as_ref().id()
|
|
||||||
}
|
|
||||||
pub fn name(&self) -> Interned<str> {
|
|
||||||
self.as_ref().name()
|
|
||||||
}
|
|
||||||
pub fn is_input(&self) -> bool {
|
|
||||||
self.as_ref().is_input()
|
|
||||||
}
|
|
||||||
pub fn is_output(&self) -> bool {
|
|
||||||
self.as_ref().is_output()
|
|
||||||
}
|
|
||||||
pub fn conflicts_with(&self) -> Interned<BTreeSet<PeripheralId>> {
|
|
||||||
self.as_ref().conflicts_with()
|
|
||||||
}
|
|
||||||
pub fn availability(&self) -> PeripheralAvailability {
|
|
||||||
self.as_ref().availability()
|
|
||||||
}
|
|
||||||
pub fn is_available(&self) -> bool {
|
pub fn is_available(&self) -> bool {
|
||||||
self.as_ref().is_available()
|
self.as_ref().is_available()
|
||||||
}
|
}
|
||||||
|
|
@ -651,24 +629,6 @@ impl<T: Type> UsedPeripheral<T> {
|
||||||
pub fn instance_io_field(&self) -> Expr<T> {
|
pub fn instance_io_field(&self) -> Expr<T> {
|
||||||
self.instance_io_field
|
self.instance_io_field
|
||||||
}
|
}
|
||||||
pub fn ty(&self) -> T {
|
|
||||||
self.as_ref().ty()
|
|
||||||
}
|
|
||||||
pub fn id(&self) -> PeripheralId {
|
|
||||||
self.as_ref().id()
|
|
||||||
}
|
|
||||||
pub fn name(&self) -> Interned<str> {
|
|
||||||
self.as_ref().name()
|
|
||||||
}
|
|
||||||
pub fn is_input(&self) -> bool {
|
|
||||||
self.as_ref().is_input()
|
|
||||||
}
|
|
||||||
pub fn is_output(&self) -> bool {
|
|
||||||
self.as_ref().is_output()
|
|
||||||
}
|
|
||||||
pub fn conflicts_with(&self) -> Interned<BTreeSet<PeripheralId>> {
|
|
||||||
self.as_ref().conflicts_with()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
|
|
||||||
use crate::{intern::Intern, prelude::*};
|
use crate::prelude::*;
|
||||||
use ordered_float::NotNan;
|
use ordered_float::NotNan;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
@ -11,42 +11,10 @@ pub struct ClockInputProperties {
|
||||||
pub frequency: NotNan<f64>,
|
pub frequency: NotNan<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[hdl(no_runtime_generics, no_static)]
|
type PhantomConstClockInputProperties = PhantomConst<ClockInputProperties>;
|
||||||
|
|
||||||
|
#[hdl(no_static)]
|
||||||
pub struct ClockInput {
|
pub struct ClockInput {
|
||||||
pub clk: Clock,
|
pub clk: Clock,
|
||||||
pub properties: PhantomConst<ClockInputProperties>,
|
pub properties: PhantomConstClockInputProperties,
|
||||||
}
|
|
||||||
|
|
||||||
impl ClockInput {
|
|
||||||
#[track_caller]
|
|
||||||
pub fn new(frequency: f64) -> Self {
|
|
||||||
assert!(
|
|
||||||
frequency > 0.0 && frequency.is_finite(),
|
|
||||||
"invalid clock frequency: {frequency}"
|
|
||||||
);
|
|
||||||
Self {
|
|
||||||
clk: Clock,
|
|
||||||
properties: PhantomConst::new(
|
|
||||||
ClockInputProperties {
|
|
||||||
frequency: NotNan::new(frequency).expect("just checked"),
|
|
||||||
}
|
|
||||||
.intern_sized(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn frequency(self) -> f64 {
|
|
||||||
self.properties.get().frequency.into_inner()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
pub struct Led {
|
|
||||||
pub on: Bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl]
|
|
||||||
pub struct RgbLed {
|
|
||||||
pub r: Bool,
|
|
||||||
pub g: Bool,
|
|
||||||
pub b: Bool,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ pub use crate::{
|
||||||
memory, memory_array, memory_with_init, reg_builder, wire,
|
memory, memory_array, memory_with_init, reg_builder, wire,
|
||||||
},
|
},
|
||||||
phantom_const::PhantomConst,
|
phantom_const::PhantomConst,
|
||||||
platform::{DynPlatform, Platform, PlatformIOBuilder, peripherals},
|
|
||||||
reg::Reg,
|
reg::Reg,
|
||||||
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
reset::{AsyncReset, Reset, SyncReset, ToAsyncReset, ToReset, ToSyncReset},
|
||||||
sim::{
|
sim::{
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
// See Notices.txt for copyright information
|
// See Notices.txt for copyright information
|
||||||
use crate::{
|
use crate::{
|
||||||
build::{
|
build::{
|
||||||
BaseJobArgs, BaseJobKind, GlobalParams, JobArgsAndDependencies, JobKindAndArgs, JobParams,
|
BaseJobArgs, BaseJobKind, JobArgsAndDependencies, JobKindAndArgs, JobParams, NoArgs,
|
||||||
NoArgs, RunBuild,
|
RunBuild,
|
||||||
external::{ExternalCommandArgs, ExternalCommandJobKind},
|
external::{ExternalCommandArgs, ExternalCommandJobKind},
|
||||||
firrtl::{FirrtlArgs, FirrtlJobKind},
|
firrtl::{FirrtlArgs, FirrtlJobKind},
|
||||||
formal::{Formal, FormalAdditionalArgs, FormalArgs, FormalMode, WriteSbyFileJobKind},
|
formal::{Formal, FormalAdditionalArgs, FormalArgs, FormalMode, WriteSbyFileJobKind},
|
||||||
|
|
@ -106,7 +106,7 @@ fn make_assert_formal_args(
|
||||||
) -> eyre::Result<JobArgsAndDependencies<ExternalCommandJobKind<Formal>>> {
|
) -> eyre::Result<JobArgsAndDependencies<ExternalCommandJobKind<Formal>>> {
|
||||||
let args = JobKindAndArgs {
|
let args = JobKindAndArgs {
|
||||||
kind: BaseJobKind,
|
kind: BaseJobKind,
|
||||||
args: BaseJobArgs::from_output_dir_and_env(get_assert_formal_target_path(&test_name), None),
|
args: BaseJobArgs::from_output_dir_and_env(get_assert_formal_target_path(&test_name)),
|
||||||
};
|
};
|
||||||
let dependencies = JobArgsAndDependencies {
|
let dependencies = JobArgsAndDependencies {
|
||||||
args,
|
args,
|
||||||
|
|
@ -168,9 +168,9 @@ pub fn try_assert_formal<M: AsRef<Module<T>>, T: BundleType>(
|
||||||
solver,
|
solver,
|
||||||
export_options,
|
export_options,
|
||||||
)?
|
)?
|
||||||
.run_without_platform(
|
.run(
|
||||||
|NoArgs {}| Ok(JobParams::new(module)),
|
|NoArgs {}| Ok(JobParams::new(module, APP_NAME)),
|
||||||
&GlobalParams::new(None, APP_NAME),
|
clap::Command::new(APP_NAME), // not actually used, so we can use an arbitrary value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1
crates/fayalite/src/vendor/xilinx.rs
vendored
1
crates/fayalite/src/vendor/xilinx.rs
vendored
|
|
@ -11,7 +11,6 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
pub mod arty_a7;
|
pub mod arty_a7;
|
||||||
pub mod primitives;
|
|
||||||
pub mod yosys_nextpnr_prjxray;
|
pub mod yosys_nextpnr_prjxray;
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
|
|
||||||
207
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
207
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
|
|
@ -3,17 +3,9 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
intern::{Intern, Interned},
|
intern::{Intern, Interned},
|
||||||
module::instance_with_loc,
|
platform::{DynPlatform, PeripheralsBuilderFactory, PeripheralsBuilderFinished, Platform},
|
||||||
platform::{
|
prelude::{ModuleBuilder, SourceLocation},
|
||||||
DynPlatform, Peripheral, PeripheralRef, Peripherals, PeripheralsBuilderFactory,
|
vendor::xilinx::Device,
|
||||||
PeripheralsBuilderFinished, Platform,
|
|
||||||
peripherals::{ClockInput, Led, RgbLed},
|
|
||||||
},
|
|
||||||
prelude::*,
|
|
||||||
vendor::xilinx::{
|
|
||||||
Device, XdcIOStandardAnnotation, XdcLocationAnnotation,
|
|
||||||
primitives::{self, BUFGCE, FDPE, STARTUPE2_default_inputs},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! arty_a7_platform {
|
macro_rules! arty_a7_platform {
|
||||||
|
|
@ -54,53 +46,8 @@ arty_a7_platform! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ArtyA7Peripherals {
|
|
||||||
clk100: Peripheral<ClockInput>,
|
|
||||||
rst: Peripheral<Reset>,
|
|
||||||
rst_sync: Peripheral<SyncReset>,
|
|
||||||
ld0: Peripheral<RgbLed>,
|
|
||||||
ld1: Peripheral<RgbLed>,
|
|
||||||
ld2: Peripheral<RgbLed>,
|
|
||||||
ld3: Peripheral<RgbLed>,
|
|
||||||
ld4: Peripheral<Led>,
|
|
||||||
ld5: Peripheral<Led>,
|
|
||||||
ld6: Peripheral<Led>,
|
|
||||||
ld7: Peripheral<Led>,
|
|
||||||
// TODO: add rest of peripherals when we need them
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Peripherals for ArtyA7Peripherals {
|
|
||||||
fn append_peripherals<'a>(&'a self, peripherals: &mut Vec<PeripheralRef<'a, CanonicalType>>) {
|
|
||||||
let Self {
|
|
||||||
clk100,
|
|
||||||
rst,
|
|
||||||
rst_sync,
|
|
||||||
ld0,
|
|
||||||
ld1,
|
|
||||||
ld2,
|
|
||||||
ld3,
|
|
||||||
ld4,
|
|
||||||
ld5,
|
|
||||||
ld6,
|
|
||||||
ld7,
|
|
||||||
} = self;
|
|
||||||
clk100.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Platform for ArtyA7Platform {
|
impl Platform for ArtyA7Platform {
|
||||||
type Peripherals = ArtyA7Peripherals;
|
type Peripherals = ();
|
||||||
|
|
||||||
fn name(&self) -> Interned<str> {
|
fn name(&self) -> Interned<str> {
|
||||||
self.as_str().intern()
|
self.as_str().intern()
|
||||||
|
|
@ -110,23 +57,8 @@ impl Platform for ArtyA7Platform {
|
||||||
&self,
|
&self,
|
||||||
builder_factory: PeripheralsBuilderFactory<'builder>,
|
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||||
) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) {
|
) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) {
|
||||||
let mut builder = builder_factory.builder();
|
let builder = builder_factory.builder();
|
||||||
(
|
(todo!(), builder.finish())
|
||||||
ArtyA7Peripherals {
|
|
||||||
clk100: builder.input_peripheral("clk100", ClockInput::new(100e6)),
|
|
||||||
rst: builder.input_peripheral("rst", Reset),
|
|
||||||
rst_sync: builder.input_peripheral("rst_sync", SyncReset),
|
|
||||||
ld0: builder.input_peripheral("ld0", RgbLed),
|
|
||||||
ld1: builder.input_peripheral("ld1", RgbLed),
|
|
||||||
ld2: builder.input_peripheral("ld2", RgbLed),
|
|
||||||
ld3: builder.input_peripheral("ld3", RgbLed),
|
|
||||||
ld4: builder.input_peripheral("ld4", Led),
|
|
||||||
ld5: builder.input_peripheral("ld5", Led),
|
|
||||||
ld6: builder.input_peripheral("ld6", Led),
|
|
||||||
ld7: builder.input_peripheral("ld7", Led),
|
|
||||||
},
|
|
||||||
builder.finish(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn source_location(&self) -> SourceLocation {
|
fn source_location(&self) -> SourceLocation {
|
||||||
|
|
@ -134,132 +66,7 @@ impl Platform for ArtyA7Platform {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) {
|
fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) {
|
||||||
let ArtyA7Peripherals {
|
let () = peripherals;
|
||||||
clk100,
|
|
||||||
rst,
|
|
||||||
rst_sync,
|
|
||||||
ld0,
|
|
||||||
ld1,
|
|
||||||
ld2,
|
|
||||||
ld3,
|
|
||||||
ld4,
|
|
||||||
ld5,
|
|
||||||
ld6,
|
|
||||||
ld7,
|
|
||||||
} = peripherals;
|
|
||||||
let make_buffered_input = |name: &str, location: &str, io_standard: &str, invert: bool| {
|
|
||||||
let pin = m.input_with_loc(name, SourceLocation::builtin(), Bool);
|
|
||||||
annotate(
|
|
||||||
pin,
|
|
||||||
XdcLocationAnnotation {
|
|
||||||
location: location.intern(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
annotate(
|
|
||||||
pin,
|
|
||||||
XdcIOStandardAnnotation {
|
|
||||||
value: io_standard.intern(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let buf = instance_with_loc(
|
|
||||||
&format!("{name}_buf"),
|
|
||||||
primitives::IBUF(),
|
|
||||||
SourceLocation::builtin(),
|
|
||||||
);
|
|
||||||
connect(buf.I, pin);
|
|
||||||
if invert { !buf.O } else { buf.O }
|
|
||||||
};
|
|
||||||
let make_buffered_output = |name: &str, location: &str, io_standard: &str| {
|
|
||||||
let pin = m.output_with_loc(name, SourceLocation::builtin(), Bool);
|
|
||||||
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
|
|
||||||
};
|
|
||||||
let clk100_buf = make_buffered_input("clk100", "E3", "LVCMOS33", false);
|
|
||||||
let startup = instance_with_loc(
|
|
||||||
"startup",
|
|
||||||
STARTUPE2_default_inputs(),
|
|
||||||
SourceLocation::builtin(),
|
|
||||||
);
|
|
||||||
let clk100_sync = instance_with_loc("clk100_sync", BUFGCE(), SourceLocation::builtin());
|
|
||||||
connect(clk100_sync.CE, startup.EOS);
|
|
||||||
connect(clk100_sync.I, clk100_buf);
|
|
||||||
if let Some(clk100) = clk100.into_used() {
|
|
||||||
connect(clk100.instance_io_field().clk, clk100_sync.O);
|
|
||||||
}
|
|
||||||
let rst_buf = make_buffered_input("rst", "C2", "LVCMOS33", true);
|
|
||||||
let [rst_sync_0, rst_sync_1] = std::array::from_fn(|index| {
|
|
||||||
let rst_sync = instance_with_loc(
|
|
||||||
&format!("rst_sync_{index}"),
|
|
||||||
FDPE(true),
|
|
||||||
SourceLocation::builtin(),
|
|
||||||
);
|
|
||||||
annotate(
|
|
||||||
rst_sync,
|
|
||||||
SVAttributeAnnotation {
|
|
||||||
text: "ASYNC_REG = \"TRUE\"".intern(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
connect(rst_sync.C, clk100_sync.O);
|
|
||||||
connect(rst_sync.CE, true);
|
|
||||||
connect(rst_sync.PRE, rst_buf.to_async_reset());
|
|
||||||
rst_sync
|
|
||||||
});
|
|
||||||
connect(rst_sync_0.D, false);
|
|
||||||
connect(rst_sync_1.D, rst_sync_0.Q);
|
|
||||||
let rst_value = rst_sync_1.Q.to_sync_reset();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
66
crates/fayalite/src/vendor/xilinx/primitives.rs
vendored
66
crates/fayalite/src/vendor/xilinx/primitives.rs
vendored
|
|
@ -1,66 +0,0 @@
|
||||||
// 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: Bool = m.input();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl_module(extern)]
|
|
||||||
pub fn STARTUPE2_default_inputs() {
|
|
||||||
m.verilog_name("STARTUPE2");
|
|
||||||
#[hdl]
|
|
||||||
let CFGCLK: Clock = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let CFGMCLK: Clock = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let EOS: Bool = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let PREQ: Bool = m.output();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[hdl_module(extern)]
|
|
||||||
pub fn FDPE(init: bool) {
|
|
||||||
m.verilog_name("FDPE");
|
|
||||||
m.parameter_raw_verilog("INIT", if init { "1'b1" } else { "1'b0" });
|
|
||||||
#[hdl]
|
|
||||||
let Q: Bool = m.output();
|
|
||||||
#[hdl]
|
|
||||||
let C: Clock = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let CE: Bool = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let PRE: AsyncReset = m.input();
|
|
||||||
#[hdl]
|
|
||||||
let D: Bool = m.input();
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue