multi-core-inverter: remove the List shenanigans
This commit is contained in:
@@ -37,18 +37,6 @@
|
||||
//! ```
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use coremem::cross::compound::list::{
|
||||
IndexableExplicit as _,
|
||||
IntoList,
|
||||
Empty,
|
||||
EnumerateU32,
|
||||
Flatten as _,
|
||||
IntoVec as _,
|
||||
List1,
|
||||
Map,
|
||||
MapVisitor,
|
||||
Meta as _,
|
||||
};
|
||||
use coremem::geom::{Coord as _, Meters, Torus};
|
||||
use coremem::mat::{Ferroxcube3R1MH, IsoConductorOr, IsomorphicConductor};
|
||||
use coremem::meas;
|
||||
@@ -64,48 +52,6 @@ type Mat = IsoConductorOr<R, Ferroxcube3R1MH>;
|
||||
type Backend = spirv::WgpuBackend;
|
||||
type Sim = SpirvSim::<R, Mat, Backend>;
|
||||
|
||||
/// maps an element `(a, b, c)` into `((0, a), (1, b), (2, c)).into_list()`
|
||||
struct MapIntoEnumeratedList;
|
||||
impl<L> MapVisitor<L> for MapIntoEnumeratedList
|
||||
where
|
||||
L: IntoList,
|
||||
L::List: EnumerateU32,
|
||||
{
|
||||
type Output = <L::List as EnumerateU32>::Output;
|
||||
fn map(&self, v: L) -> Self::Output {
|
||||
v.into_list().enumerate_u32()
|
||||
}
|
||||
}
|
||||
|
||||
/// maps an element `a` into `(self.0, a)`.
|
||||
struct PrependIntoTuple(u32);
|
||||
impl<V> MapVisitor<V> for PrependIntoTuple {
|
||||
type Output = (u32, V);
|
||||
fn map(&self, v: V) -> (u32, V) {
|
||||
(self.0, v)
|
||||
}
|
||||
}
|
||||
|
||||
/// for each list elem (tag: u32, List<E0, E1, ...>),
|
||||
/// map to List<(tag, E0), (tag, E1), ...>.
|
||||
struct PropagateEnum;
|
||||
impl<V> MapVisitor<(u32, V)> for PropagateEnum
|
||||
where
|
||||
V: Map<PrependIntoTuple>
|
||||
{
|
||||
type Output = V::Output;
|
||||
fn map(&self, (e, l): (u32, V)) -> Self::Output {
|
||||
l.map(PrependIntoTuple(e))
|
||||
}
|
||||
}
|
||||
|
||||
struct MapIntoBoxStimulus;
|
||||
impl<S: Stimulus + 'static> MapVisitor<S> for MapIntoBoxStimulus {
|
||||
type Output = Box<dyn Stimulus>;
|
||||
fn map(&self, s: S) -> Self::Output {
|
||||
Box::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum DriveDirection {
|
||||
@@ -121,53 +67,34 @@ impl DriveDirection {
|
||||
}
|
||||
}
|
||||
|
||||
// different states each control signal can be in for some clock cycle.
|
||||
struct HoldHigh;
|
||||
struct ReleaseHigh;
|
||||
struct HoldLow;
|
||||
struct ReleaseLow;
|
||||
struct Float;
|
||||
/// different states each control signal can be in for some clock cycle.
|
||||
#[derive(Copy, Clone)]
|
||||
enum ClockState {
|
||||
HoldHigh,
|
||||
ReleaseHigh,
|
||||
HoldLow,
|
||||
ReleaseLow,
|
||||
Float,
|
||||
}
|
||||
|
||||
impl ClockState {
|
||||
fn stimulus(&self, params: &Params, cycle: u32, ctl: u32)
|
||||
-> Option<Box<dyn Stimulus>>
|
||||
{
|
||||
use ClockState::*;
|
||||
match self {
|
||||
HoldHigh => Some(Box::new(params.control_signal_hold(cycle, ctl, DriveDirection::High))),
|
||||
ReleaseHigh => Some(Box::new(params.control_signal_release(cycle, ctl, DriveDirection::High))),
|
||||
HoldLow => Some(Box::new(params.control_signal_hold(cycle, ctl, DriveDirection::Low))),
|
||||
ReleaseLow => Some(Box::new(params.control_signal_release(cycle, ctl, DriveDirection::Low))),
|
||||
Float => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type HoldStim = Gated<CurlStimulus<Torus, f32>>;
|
||||
type ReleaseStim = Shifted<Gated<Exp<CurlStimulus<Torus, f32>>>>;
|
||||
|
||||
struct IntoMaybeStimulus(Params);
|
||||
|
||||
impl MapVisitor<(u32, (u32, HoldHigh))> for IntoMaybeStimulus {
|
||||
type Output = List1<HoldStim>;
|
||||
fn map(&self, (cycle, (ctl, _)): (u32, (u32, HoldHigh))) -> Self::Output {
|
||||
(self.0.control_signal_hold(cycle, ctl, DriveDirection::High),).into_list()
|
||||
}
|
||||
}
|
||||
|
||||
impl MapVisitor<(u32, (u32, ReleaseHigh))> for IntoMaybeStimulus {
|
||||
type Output = List1<ReleaseStim>;
|
||||
fn map(&self, (cycle, (ctl, _)): (u32, (u32, ReleaseHigh))) -> Self::Output {
|
||||
(self.0.control_signal_release(cycle, ctl, DriveDirection::High),).into_list()
|
||||
}
|
||||
}
|
||||
|
||||
impl MapVisitor<(u32, (u32, HoldLow))> for IntoMaybeStimulus {
|
||||
type Output = List1<HoldStim>;
|
||||
fn map(&self, (cycle, (ctl, _)): (u32, (u32, HoldLow))) -> Self::Output {
|
||||
(self.0.control_signal_hold(cycle, ctl, DriveDirection::Low),).into_list()
|
||||
}
|
||||
}
|
||||
|
||||
impl MapVisitor<(u32, (u32, ReleaseLow))> for IntoMaybeStimulus {
|
||||
type Output = List1<ReleaseStim>;
|
||||
fn map(&self, (cycle, (ctl, _)): (u32, (u32, ReleaseLow))) -> Self::Output {
|
||||
(self.0.control_signal_release(cycle, ctl, DriveDirection::Low),).into_list()
|
||||
}
|
||||
}
|
||||
|
||||
impl MapVisitor<(u32, (u32, Float))> for IntoMaybeStimulus {
|
||||
type Output = Empty;
|
||||
fn map(&self, (_cycle, (_ctl, _)): (u32, (u32, Float))) -> Self::Output {
|
||||
Empty::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct Params {
|
||||
input_magnitude: f32,
|
||||
@@ -276,60 +203,65 @@ fn main() {
|
||||
//////// define the control signals/transitions
|
||||
// each row N denotes the drive currents at clock cycle N.
|
||||
// each col M denotes the drive current at core M.
|
||||
use ClockState::*;
|
||||
// let s0_init_state = HoldHigh; // logic high
|
||||
let s0_init_state = HoldLow; // logic low
|
||||
let s0_rel_state = ReleaseLow;
|
||||
let drive_map = (
|
||||
let drive_map = [
|
||||
// charge each device to '1'
|
||||
(s0_init_state,HoldHigh, HoldHigh, HoldHigh, HoldHigh),
|
||||
[s0_init_state,HoldHigh, HoldHigh, HoldHigh, HoldHigh],
|
||||
// this is when we'd ordinarily open S0 for write
|
||||
(s0_rel_state, HoldHigh, HoldHigh, HoldHigh, HoldHigh),
|
||||
[s0_rel_state, HoldHigh, HoldHigh, HoldHigh, HoldHigh],
|
||||
|
||||
// this is when S0 would ordinarily receive a write
|
||||
(Float, HoldHigh, HoldHigh, HoldHigh, HoldHigh),
|
||||
[Float, HoldHigh, HoldHigh, HoldHigh, HoldHigh],
|
||||
// open S1 for write
|
||||
(Float, ReleaseHigh, HoldHigh, HoldHigh, HoldHigh),
|
||||
[Float, ReleaseHigh, HoldHigh, HoldHigh, HoldHigh],
|
||||
|
||||
// write S0' => S1
|
||||
(HoldLow, Float, HoldHigh, HoldHigh, HoldHigh),
|
||||
[HoldLow, Float, HoldHigh, HoldHigh, HoldHigh],
|
||||
// open S2 for write
|
||||
(HoldLow, Float, ReleaseHigh, HoldHigh, HoldHigh),
|
||||
[HoldLow, Float, ReleaseHigh, HoldHigh, HoldHigh],
|
||||
|
||||
// write S1' => S2
|
||||
(HoldLow, HoldLow, Float, HoldHigh, HoldHigh),
|
||||
[HoldLow, HoldLow, Float, HoldHigh, HoldHigh],
|
||||
// open S3 for write
|
||||
(HoldLow, HoldLow, Float, ReleaseHigh, HoldHigh),
|
||||
[HoldLow, HoldLow, Float, ReleaseHigh, HoldHigh],
|
||||
|
||||
// write S2' => S3; RESET S0
|
||||
(HoldHigh, HoldLow, HoldLow, Float, HoldHigh),
|
||||
[HoldHigh, HoldLow, HoldLow, Float, HoldHigh],
|
||||
// open S4 for write
|
||||
(HoldHigh, HoldLow, HoldLow, Float, ReleaseHigh),
|
||||
[HoldHigh, HoldLow, HoldLow, Float, ReleaseHigh],
|
||||
|
||||
// write S3' => S4; RESET S1
|
||||
(HoldHigh, HoldHigh, HoldLow, HoldLow, Float),
|
||||
[HoldHigh, HoldHigh, HoldLow, HoldLow, Float],
|
||||
// open S0 for write
|
||||
(ReleaseHigh, HoldHigh, HoldLow, HoldLow, Float),
|
||||
[ReleaseHigh, HoldHigh, HoldLow, HoldLow, Float],
|
||||
|
||||
// write S4' => output; RESET S2
|
||||
(Float, HoldHigh, HoldHigh, HoldLow, HoldLow),
|
||||
[Float, HoldHigh, HoldHigh, HoldLow, HoldLow],
|
||||
// open S1 for write
|
||||
(Float, ReleaseHigh, HoldHigh, HoldLow, HoldLow),
|
||||
);
|
||||
let drive_map = drive_map
|
||||
.into_list()
|
||||
.map(MapIntoEnumeratedList);
|
||||
let num_cycles = drive_map.len();
|
||||
let num_cores = drive_map.get_first_ref().len();
|
||||
let stim = drive_map
|
||||
.enumerate_u32()
|
||||
.map(PropagateEnum)
|
||||
.flatten()
|
||||
.map(IntoMaybeStimulus(params))
|
||||
.flatten();
|
||||
|
||||
[Float, ReleaseHigh, HoldHigh, HoldLow, HoldLow],
|
||||
];
|
||||
let num_cycles = drive_map.len() as u32;
|
||||
let num_cores = drive_map[0].len() as u32;
|
||||
let stim: Vec<_> = drive_map.into_iter()
|
||||
.enumerate()
|
||||
.flat_map(|(cycle, cores)| {
|
||||
cores.into_iter()
|
||||
.enumerate()
|
||||
.flat_map(move |(core, clock_state)| {
|
||||
clock_state.stimulus(¶ms, cycle as u32, core as u32)
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
// temporary sanity checks
|
||||
assert_eq!(num_cycles, 14);
|
||||
assert_eq!(num_cores, 5);
|
||||
assert_eq!(stim.len(), 14*5 - 12);
|
||||
let stim = DynStimuli::from_vec(stim);
|
||||
|
||||
|
||||
let wire_mat = IsomorphicConductor::new(1e6f32.cast::<R>());
|
||||
// let ferro_mat = wire_mat;
|
||||
let ferro_mat = Ferroxcube3R1MH::new();
|
||||
|
Reference in New Issue
Block a user