This commit is contained in:
parent
def406ab52
commit
3f5dd61e46
10 changed files with 1468 additions and 218 deletions
|
|
@ -99,12 +99,12 @@ pub mod intern;
|
|||
pub mod memory;
|
||||
pub mod module;
|
||||
pub mod phantom_const;
|
||||
pub mod platform;
|
||||
pub mod prelude;
|
||||
pub mod reg;
|
||||
pub mod reset;
|
||||
pub mod sim;
|
||||
pub mod source_location;
|
||||
pub mod target;
|
||||
pub mod testing;
|
||||
pub mod ty;
|
||||
pub mod util;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use crate::{
|
|||
int::{Bool, DynSize, Size},
|
||||
intern::{Intern, Interned},
|
||||
memory::{Mem, MemBuilder, MemBuilderTarget, PortName},
|
||||
platform::PlatformIOBuilder,
|
||||
reg::Reg,
|
||||
reset::{AsyncReset, Reset, ResetType, ResetTypeDispatch, SyncReset},
|
||||
sim::{ExternModuleSimGenerator, ExternModuleSimulation},
|
||||
|
|
@ -2119,6 +2120,27 @@ impl ModuleBuilder {
|
|||
self.output_with_loc(implicit_name.0, SourceLocation::caller(), ty)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn add_platform_io_with_loc(
|
||||
&self,
|
||||
name: &str,
|
||||
source_location: SourceLocation,
|
||||
platform_io_builder: PlatformIOBuilder<'_>,
|
||||
) -> Expr<Bundle> {
|
||||
platform_io_builder.add_platform_io(name, source_location, self)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn add_platform_io(
|
||||
&self,
|
||||
implicit_name: ImplicitName<'_>,
|
||||
platform_io_builder: PlatformIOBuilder<'_>,
|
||||
) -> Expr<Bundle> {
|
||||
self.add_platform_io_with_loc(
|
||||
implicit_name.0,
|
||||
SourceLocation::caller(),
|
||||
platform_io_builder,
|
||||
)
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn run<T: BundleType>(
|
||||
name: &str,
|
||||
module_kind: ModuleKind,
|
||||
|
|
@ -2743,6 +2765,22 @@ impl<T: Type> ModuleIO<T> {
|
|||
source_location,
|
||||
}
|
||||
}
|
||||
pub fn from_canonical(canonical_module_io: ModuleIO<CanonicalType>) -> Self {
|
||||
let ModuleIO {
|
||||
containing_module_name,
|
||||
bundle_field,
|
||||
id,
|
||||
ty,
|
||||
source_location,
|
||||
} = canonical_module_io;
|
||||
Self {
|
||||
containing_module_name,
|
||||
bundle_field,
|
||||
id,
|
||||
ty: T::from_canonical(ty),
|
||||
source_location,
|
||||
}
|
||||
}
|
||||
pub fn bundle_field(&self) -> BundleField {
|
||||
self.bundle_field
|
||||
}
|
||||
|
|
|
|||
1146
crates/fayalite/src/platform.rs
Normal file
1146
crates/fayalite/src/platform.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,202 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{intern::Interned, util::job_server::AcquiredJob};
|
||||
use std::{
|
||||
any::Any,
|
||||
fmt,
|
||||
iter::FusedIterator,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub trait Peripheral: Any + Send + Sync + fmt::Debug {}
|
||||
|
||||
pub trait Tool: Any + Send + Sync + fmt::Debug {
|
||||
fn name(&self) -> Interned<str>;
|
||||
fn run(&self, acquired_job: &mut AcquiredJob);
|
||||
}
|
||||
|
||||
pub trait Target: Any + Send + Sync + fmt::Debug {
|
||||
fn name(&self) -> Interned<str>;
|
||||
fn peripherals(&self) -> Interned<[Interned<dyn Peripheral>]>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct TargetsMap(Vec<(Interned<str>, Interned<dyn Target>)>);
|
||||
|
||||
impl TargetsMap {
|
||||
fn sort(&mut self) {
|
||||
self.0.sort_by(|(k1, _), (k2, _)| str::cmp(k1, k2));
|
||||
self.0.dedup_by_key(|(k, _)| *k);
|
||||
}
|
||||
fn from_unsorted_vec(unsorted_vec: Vec<(Interned<str>, Interned<dyn Target>)>) -> Self {
|
||||
let mut retval = Self(unsorted_vec);
|
||||
retval.sort();
|
||||
retval
|
||||
}
|
||||
fn extend_from_unsorted_slice(&mut self, additional: &[(Interned<str>, Interned<dyn Target>)]) {
|
||||
self.0.extend_from_slice(additional);
|
||||
self.sort();
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TargetsMap {
|
||||
fn default() -> Self {
|
||||
Self::from_unsorted_vec(vec![
|
||||
// TODO: add default targets here
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
fn access_targets<F: FnOnce(&mut Option<Arc<TargetsMap>>) -> R, R>(f: F) -> R {
|
||||
static TARGETS: Mutex<Option<Arc<TargetsMap>>> = Mutex::new(None);
|
||||
let mut targets_lock = TARGETS.lock().expect("shouldn't be poisoned");
|
||||
f(&mut targets_lock)
|
||||
}
|
||||
|
||||
pub fn add_targets<I: IntoIterator<Item = Interned<dyn Target>>>(additional: I) {
|
||||
// run iterator and target methods outside of lock
|
||||
let additional = Vec::from_iter(additional.into_iter().map(|v| (v.name(), v)));
|
||||
access_targets(|targets| {
|
||||
Arc::make_mut(targets.get_or_insert_default()).extend_from_unsorted_slice(&additional);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn targets() -> TargetsSnapshot {
|
||||
access_targets(|targets| match targets {
|
||||
Some(targets) => TargetsSnapshot {
|
||||
targets: targets.clone(),
|
||||
},
|
||||
None => {
|
||||
let new_targets = Arc::<TargetsMap>::default();
|
||||
*targets = Some(new_targets.clone());
|
||||
TargetsSnapshot {
|
||||
targets: new_targets,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TargetsSnapshot {
|
||||
targets: Arc<TargetsMap>,
|
||||
}
|
||||
|
||||
impl TargetsSnapshot {
|
||||
pub fn get(&self, key: &str) -> Option<Interned<dyn Target>> {
|
||||
let index = self
|
||||
.targets
|
||||
.0
|
||||
.binary_search_by_key(&key, |(k, _v)| k)
|
||||
.ok()?;
|
||||
Some(self.targets.0[index].1)
|
||||
}
|
||||
pub fn iter(&self) -> TargetsIter {
|
||||
self.into_iter()
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.targets.0.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for TargetsSnapshot {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("TargetsSnapshot ")?;
|
||||
f.debug_map().entries(self).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for &'_ mut TargetsSnapshot {
|
||||
type Item = (Interned<str>, Interned<dyn Target>);
|
||||
type IntoIter = TargetsIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.clone().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for &'_ TargetsSnapshot {
|
||||
type Item = (Interned<str>, Interned<dyn Target>);
|
||||
type IntoIter = TargetsIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.clone().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for TargetsSnapshot {
|
||||
type Item = (Interned<str>, Interned<dyn Target>);
|
||||
type IntoIter = TargetsIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
TargetsIter {
|
||||
indexes: 0..self.targets.0.len(),
|
||||
targets: self.targets,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TargetsIter {
|
||||
targets: Arc<TargetsMap>,
|
||||
indexes: std::ops::Range<usize>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for TargetsIter {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("TargetsIter ")?;
|
||||
f.debug_map().entries(self.clone()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for TargetsIter {
|
||||
type Item = (Interned<str>, Interned<dyn Target>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
Some(self.targets.0[self.indexes.next()?])
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.indexes.size_hint()
|
||||
}
|
||||
|
||||
fn count(self) -> usize {
|
||||
self.indexes.len()
|
||||
}
|
||||
|
||||
fn last(mut self) -> Option<Self::Item> {
|
||||
self.next_back()
|
||||
}
|
||||
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
Some(self.targets.0[self.indexes.nth(n)?])
|
||||
}
|
||||
|
||||
fn fold<B, F: FnMut(B, Self::Item) -> B>(self, init: B, mut f: F) -> B {
|
||||
self.indexes
|
||||
.fold(init, move |retval, index| f(retval, self.targets.0[index]))
|
||||
}
|
||||
}
|
||||
|
||||
impl FusedIterator for TargetsIter {}
|
||||
|
||||
impl DoubleEndedIterator for TargetsIter {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
Some(self.targets.0[self.indexes.next_back()?])
|
||||
}
|
||||
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
Some(self.targets.0[self.indexes.nth_back(n)?])
|
||||
}
|
||||
|
||||
fn rfold<B, F: FnMut(B, Self::Item) -> B>(self, init: B, mut f: F) -> B {
|
||||
self.indexes
|
||||
.rfold(init, move |retval, index| f(retval, self.targets.0[index]))
|
||||
}
|
||||
}
|
||||
|
||||
impl ExactSizeIterator for TargetsIter {
|
||||
fn len(&self) -> usize {
|
||||
self.indexes.len()
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use fayalite::{
|
|||
int::{UIntInRange, UIntInRangeInclusive},
|
||||
intern::Intern,
|
||||
module::transform::simplify_enums::SimplifyEnumsKind,
|
||||
platform::PlatformIOBuilder,
|
||||
prelude::*,
|
||||
reset::ResetType,
|
||||
ty::StaticType,
|
||||
|
|
@ -4631,3 +4632,55 @@ circuit check_uint_in_range:
|
|||
",
|
||||
};
|
||||
}
|
||||
|
||||
#[hdl_module(outline_generated)]
|
||||
pub fn check_platform_io(platform_io_builder: PlatformIOBuilder<'_>) {
|
||||
#[hdl]
|
||||
let io = m.add_platform_io(platform_io_builder);
|
||||
}
|
||||
|
||||
#[cfg(todo)]
|
||||
#[test]
|
||||
fn test_platform_io() {
|
||||
let _n = SourceLocation::normalize_files_for_tests();
|
||||
let m = check_platform_io(todo!());
|
||||
dbg!(m);
|
||||
#[rustfmt::skip] // work around https://github.com/rust-lang/rustfmt/issues/6161
|
||||
assert_export_firrtl! {
|
||||
m =>
|
||||
"/test/check_platform_io.fir": r"FIRRTL version 3.2.0
|
||||
circuit check_platform_io:
|
||||
type Ty0 = {value: UInt<0>, range: {}}
|
||||
type Ty1 = {value: UInt<1>, range: {}}
|
||||
type Ty2 = {value: UInt<2>, range: {}}
|
||||
type Ty3 = {value: UInt<2>, range: {}}
|
||||
type Ty4 = {value: UInt<3>, range: {}}
|
||||
type Ty5 = {value: UInt<3>, range: {}}
|
||||
type Ty6 = {value: UInt<4>, range: {}}
|
||||
type Ty7 = {value: UInt<0>, range: {}}
|
||||
type Ty8 = {value: UInt<1>, range: {}}
|
||||
type Ty9 = {value: UInt<2>, range: {}}
|
||||
type Ty10 = {value: UInt<2>, range: {}}
|
||||
type Ty11 = {value: UInt<3>, range: {}}
|
||||
type Ty12 = {value: UInt<3>, range: {}}
|
||||
type Ty13 = {value: UInt<4>, range: {}}
|
||||
type Ty14 = {value: UInt<4>, range: {}}
|
||||
module check_platform_io: @[module-XXXXXXXXXX.rs 1:1]
|
||||
input i_0_to_1: Ty0 @[module-XXXXXXXXXX.rs 2:1]
|
||||
input i_0_to_2: Ty1 @[module-XXXXXXXXXX.rs 3:1]
|
||||
input i_0_to_3: Ty2 @[module-XXXXXXXXXX.rs 4:1]
|
||||
input i_0_to_4: Ty3 @[module-XXXXXXXXXX.rs 5:1]
|
||||
input i_0_to_7: Ty4 @[module-XXXXXXXXXX.rs 6:1]
|
||||
input i_0_to_8: Ty5 @[module-XXXXXXXXXX.rs 7:1]
|
||||
input i_0_to_9: Ty6 @[module-XXXXXXXXXX.rs 8:1]
|
||||
input i_0_through_0: Ty7 @[module-XXXXXXXXXX.rs 9:1]
|
||||
input i_0_through_1: Ty8 @[module-XXXXXXXXXX.rs 10:1]
|
||||
input i_0_through_2: Ty9 @[module-XXXXXXXXXX.rs 11:1]
|
||||
input i_0_through_3: Ty10 @[module-XXXXXXXXXX.rs 12:1]
|
||||
input i_0_through_4: Ty11 @[module-XXXXXXXXXX.rs 13:1]
|
||||
input i_0_through_7: Ty12 @[module-XXXXXXXXXX.rs 14:1]
|
||||
input i_0_through_8: Ty13 @[module-XXXXXXXXXX.rs 15:1]
|
||||
input i_0_through_9: Ty14 @[module-XXXXXXXXXX.rs 16:1]
|
||||
",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,4 +11,20 @@ pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) {
|
|||
let o: UInt<8> = m.output();
|
||||
}
|
||||
|
||||
#[hdl_module]
|
||||
pub fn my_module2(platform_io_builder: PlatformIOBuilder<'_>) {
|
||||
#[hdl]
|
||||
let a: UInt<8> = m.input();
|
||||
#[hdl]
|
||||
let b: UInt<8> = m.output();
|
||||
#[hdl]
|
||||
let io = m.add_platform_io(platform_io_builder);
|
||||
#[hdl]
|
||||
let c: UInt<8> = m.input();
|
||||
#[hdl]
|
||||
let d: UInt<8> = m.output();
|
||||
#[hdl]
|
||||
let io = m.add_platform_io(platform_io_builder);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,47 @@
|
|||
error: name conflicts with implicit `m: &mut ModuleBuilder<_>`
|
||||
error: name conflicts with implicit `m: &ModuleBuilder`
|
||||
--> tests/ui/module.rs:7:26
|
||||
|
|
||||
7 | pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) {
|
||||
| ^
|
||||
|
||||
error: name conflicts with implicit `m: &mut ModuleBuilder<_>`
|
||||
error: name conflicts with implicit `m: &ModuleBuilder`
|
||||
--> tests/ui/module.rs:7:35
|
||||
|
|
||||
7 | pub fn my_module(a: i32, m: u32, (m, _): (i32, u32)) {
|
||||
| ^
|
||||
|
||||
error: name conflicts with implicit `m: &mut ModuleBuilder<_>`
|
||||
error: name conflicts with implicit `m: &ModuleBuilder`
|
||||
--> tests/ui/module.rs:9:9
|
||||
|
|
||||
9 | let m: UInt<8> = m.input();
|
||||
| ^
|
||||
|
||||
error: can't have other inputs/outputs in a module using m.add_platform_io()
|
||||
--> tests/ui/module.rs:17:24
|
||||
|
|
||||
17 | let a: UInt<8> = m.input();
|
||||
| ^^^^^
|
||||
|
||||
error: can't have other inputs/outputs in a module using m.add_platform_io()
|
||||
--> tests/ui/module.rs:19:24
|
||||
|
|
||||
19 | let b: UInt<8> = m.output();
|
||||
| ^^^^^^
|
||||
|
||||
error: can't have other inputs/outputs in a module using m.add_platform_io()
|
||||
--> tests/ui/module.rs:23:24
|
||||
|
|
||||
23 | let c: UInt<8> = m.input();
|
||||
| ^^^^^
|
||||
|
||||
error: can't have other inputs/outputs in a module using m.add_platform_io()
|
||||
--> tests/ui/module.rs:25:24
|
||||
|
|
||||
25 | let d: UInt<8> = m.output();
|
||||
| ^^^^^^
|
||||
|
||||
error: can't use m.add_platform_io() more than once in a single module
|
||||
--> tests/ui/module.rs:27:16
|
||||
|
|
||||
27 | let io = m.add_platform_io(platform_io_builder);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue