1
0
Fork 0

WIP adding FPGA support -- build module should be complete

This commit is contained in:
Jacob Lifshay 2025-09-16 01:40:42 -07:00
parent c06ef56482
commit 49530a5cf2
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
3 changed files with 1436 additions and 0 deletions

1232
crates/fayalite/src/build.rs Normal file

File diff suppressed because it is too large Load diff

View file

@ -87,6 +87,7 @@ pub mod _docs;
pub mod annotations;
pub mod array;
pub mod build;
pub mod bundle;
pub mod cli;
pub mod clock;
@ -104,6 +105,7 @@ 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;

View 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()
}
}