multi-core-inverter: remove the List shenanigans

This commit is contained in:
2022-08-18 20:02:09 -07:00
parent 9461cc7781
commit 478db86b75

View File

@@ -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(&params, 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();