forked from libre-chip/fayalite
WIP adding FPGA support -- build module should be complete
This commit is contained in:
parent
c06ef56482
commit
49530a5cf2
3 changed files with 1436 additions and 0 deletions
1232
crates/fayalite/src/build.rs
Normal file
1232
crates/fayalite/src/build.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -87,6 +87,7 @@ pub mod _docs;
|
||||||
|
|
||||||
pub mod annotations;
|
pub mod annotations;
|
||||||
pub mod array;
|
pub mod array;
|
||||||
|
pub mod build;
|
||||||
pub mod bundle;
|
pub mod bundle;
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
pub mod clock;
|
pub mod clock;
|
||||||
|
|
@ -104,6 +105,7 @@ pub mod reg;
|
||||||
pub mod reset;
|
pub mod reset;
|
||||||
pub mod sim;
|
pub mod sim;
|
||||||
pub mod source_location;
|
pub mod source_location;
|
||||||
|
pub mod target;
|
||||||
pub mod testing;
|
pub mod testing;
|
||||||
pub mod ty;
|
pub mod ty;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
|
||||||
202
crates/fayalite/src/target.rs
Normal file
202
crates/fayalite/src/target.rs
Normal file
|
|
@ -0,0 +1,202 @@
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue