Skip to content

Commit

Permalink
[Cider 2] Invoke fixes, mult imp, and error messages (#2128)
Browse files Browse the repository at this point in the history
* add multiplier and fix an invoke bug

* Update the errors to be a bit more helpful

* all hail clippy
  • Loading branch information
EclecticGriffin authored Jun 11, 2024
1 parent c8d1633 commit be274e6
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 84 deletions.
14 changes: 14 additions & 0 deletions interp/cider2-tests/invoke/invoke.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"a0": [
1,
8,
27,
64,
125,
216,
343,
512,
729,
1000
]
}
8 changes: 8 additions & 0 deletions interp/cider2-tests/invoke/k3.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"depth_output": [
1
],
"path_ids1": [
1
]
}
6 changes: 0 additions & 6 deletions interp/cider2-tests/primitives/flickering_go.expect
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
{
"mult0": [
0
],
"mult1": [
32
],
"mult_reg0": [
0
],
Expand Down
1 change: 1 addition & 0 deletions interp/cider2-tests/runt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ cmd = """
fud2 {} --from calyx --to dat --through interp-flat -s sim.data={}.data | jq --sort-keys
"""
timeout = 10
expect_dir = "invoke"

# [[tests]]
# name = "invoke comp"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---STDERR---
Error: Attempted to write an undefined value to register or memory
Error: Attempted to write an undefined value to register or memory named "main.reg0"
thread 'main' panicked at interp/src/serialization/data_dump.rs:162:48:
called `Result::unwrap()` on an `Err` value: Error { kind: UnexpectedEof, message: "failed to fill whole buffer" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
24 changes: 18 additions & 6 deletions interp/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ pub type InterpreterResult<T> = Result<T, BoxedInterpreterError>;

pub struct BoxedInterpreterError(Box<InterpreterError>);

impl BoxedInterpreterError {
pub fn into_inner(&mut self) -> &mut InterpreterError {
&mut self.0
}
}

impl std::fmt::Display for BoxedInterpreterError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&*self.0, f)
Expand Down Expand Up @@ -179,16 +185,22 @@ pub enum InterpreterError {
IOError(#[from] std::io::Error),

//TODO Griffin: Make this more descriptive
#[error("Attempted to write an undefined value to register or memory")]
UndefinedWrite,
#[error(
"Attempted to write an undefined value to register or memory named \"{0}\""
)]
UndefinedWrite(String),

//TODO Griffin: Make this more descriptive
#[error("Attempted to write an undefined memory address")]
UndefinedWriteAddr,
#[error(
"Attempted to write an undefined memory address in memory named \"{0}\""
)]
UndefinedWriteAddr(String),

// TODO Griffin: Make this more descriptive
#[error("Attempted to read an undefined memory address")]
UndefinedReadAddr,
#[error(
"Attempted to read an undefined memory address from memory named \"{0}\""
)]
UndefinedReadAddr(String),

#[error(transparent)]
SerializationError(
Expand Down
11 changes: 8 additions & 3 deletions interp/src/flatten/flat_ir/control/structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,18 @@ pub struct InvokeSignature {
pub inputs: SmallVec<[(PortRef, PortRef); 1]>,
/// The ports attached to the outputs of the invoked cell, an association list
/// of the port ref in the **PARENT** context, and the port connected
/// to it in the parent context. i.e. (dst, src)
/// to it in the parent context. i.e. (src, dst)
pub outputs: SmallVec<[(PortRef, PortRef); 1]>,
}

impl InvokeSignature {
pub fn iter(&self) -> impl Iterator<Item = &(PortRef, PortRef)> {
self.inputs.iter().chain(self.outputs.iter())
// TODO Griffin: fix this it's stupid
pub fn iter(&self) -> impl Iterator<Item = (&PortRef, &PortRef)> {
self.inputs
.iter()
.map(|x| (&x.0, &x.1))
// need to reverse the outputs because invoke is confusing
.chain(self.outputs.iter().map(|(src, dest)| (dest, src)))
}
}

Expand Down
4 changes: 3 additions & 1 deletion interp/src/flatten/primitives/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ pub fn build_primitive(
PrimType1::SignedLe => Box::new(StdSle::new(base_port)),
PrimType1::SignedLsh => Box::new(StdSlsh::new(base_port)),
PrimType1::SignedRsh => Box::new(StdSrsh::new(base_port)),
PrimType1::MultPipe => todo!(),
PrimType1::MultPipe => {
Box::new(StdMultPipe::<2>::new(base_port, *width))
}
PrimType1::SignedMultPipe => todo!(),
PrimType1::DivPipe => todo!(),
PrimType1::SignedDivPipe => todo!(),
Expand Down
114 changes: 114 additions & 0 deletions interp/src/flatten/primitives/stateful/math.rs
Original file line number Diff line number Diff line change
@@ -1 +1,115 @@
use crate::{
flatten::{flat_ir::prelude::*, primitives::declare_ports},
primitives::prim_utils::ShiftBuffer,
};
use crate::{
flatten::{
primitives::{ports, prim_trait::*},
structures::environment::PortMap,
},
values::Value,
};

pub struct StdMultPipe<const DEPTH: usize> {
base_port: GlobalPortIdx,
pipeline: ShiftBuffer<(PortValue, PortValue), DEPTH>,
current_output: PortValue,
width: u32,
done_is_high: bool,
}

impl<const DEPTH: usize> StdMultPipe<DEPTH> {
declare_ports![_CLK: 0, RESET: 1, GO: 2, LEFT: 3, RIGHT: 4, OUT: 5, DONE: 6];
pub fn new(base_port: GlobalPortIdx, width: u32) -> Self {
Self {
base_port,
pipeline: ShiftBuffer::default(),
current_output: PortValue::new_cell(Value::zeroes(width)),
width,
done_is_high: false,
}
}
}

impl<const DEPTH: usize> Primitive for StdMultPipe<DEPTH> {
fn exec_comb(&self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port; out: Self::OUT, done: Self::DONE];

let out_changed = if self.current_output.is_def() {
port_map.insert_val(
out,
self.current_output.as_option().unwrap().clone(),
)?
} else {
UpdateStatus::Unchanged
};

let done_signal = port_map.insert_val(
done,
AssignedValue::cell_value(if self.done_is_high {
Value::bit_high()
} else {
Value::bit_low()
}),
)?;

Ok(out_changed | done_signal)
}

fn exec_cycle(&mut self, port_map: &mut PortMap) -> UpdateResult {
ports![&self.base_port;
left: Self::LEFT,
right: Self::RIGHT,
reset: Self::RESET,
go: Self::GO,
out: Self::OUT,
done: Self::DONE
];

if port_map[reset].as_bool().unwrap_or_default() {
self.current_output =
PortValue::new_cell(Value::zeroes(self.width));
self.done_is_high = false;
self.pipeline.reset();
} else if port_map[go].as_bool().unwrap_or_default() {
let output = self
.pipeline
.shift(Some((port_map[left].clone(), port_map[right].clone())));
if let Some((l, r)) = output {
let out_val = l.as_option().and_then(|left| {
r.as_option().map(|right| {
Value::from(
left.val().as_unsigned()
* right.val().as_unsigned(),
self.width,
)
})
});
self.current_output =
out_val.map_or(PortValue::new_undef(), PortValue::new_cell);
self.done_is_high = true;
} else {
self.current_output =
PortValue::new_cell(Value::zeroes(self.width));
self.done_is_high = false;
}
} else {
self.pipeline.reset();
self.done_is_high = false;
}

let done_signal = port_map.insert_val(
done,
AssignedValue::cell_value(if self.done_is_high {
Value::bit_high()
} else {
Value::bit_low()
}),
)?;

Ok(
port_map.write_exact_unchecked(out, self.current_output.clone())
| done_signal,
)
}
}
15 changes: 8 additions & 7 deletions interp/src/flatten/primitives/stateful/memories.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl Primitive for StdReg {
} else if port_map[write_en].as_bool().unwrap_or_default() {
self.internal_state = port_map[input]
.as_option()
.ok_or(InterpreterError::UndefinedWrite)?
.ok_or(InterpreterError::UndefinedWrite(String::new()))?
.val()
.clone();

Expand Down Expand Up @@ -348,11 +348,12 @@ impl Primitive for CombMem {
let (read_data, done) = (self.read_data(), self.done());

let done = if write_en && !reset {
let addr = addr.ok_or(InterpreterError::UndefinedWriteAddr)?;
let addr = addr
.ok_or(InterpreterError::UndefinedWriteAddr(String::new()))?;

let write_data = port_map[self.write_data()]
.as_option()
.ok_or(InterpreterError::UndefinedWrite)?;
.ok_or(InterpreterError::UndefinedWrite(String::new()))?;
self.internal_state[addr] = write_data.val().clone();
self.done_is_high = true;
port_map.insert_val(done, AssignedValue::cell_b_high())?
Expand Down Expand Up @@ -543,16 +544,16 @@ impl Primitive for SeqMem {
} else if content_en && write_en {
self.done_is_high = true;
self.read_out = PortValue::new_undef();
let addr_actual =
addr.ok_or(InterpreterError::UndefinedWriteAddr)?;
let addr_actual = addr
.ok_or(InterpreterError::UndefinedWriteAddr(String::new()))?;
let write_data = port_map[self.write_data()]
.as_option()
.ok_or(InterpreterError::UndefinedWrite)?;
.ok_or(InterpreterError::UndefinedWrite(String::new()))?;
self.internal_state[addr_actual] = write_data.val().clone();
} else if content_en {
self.done_is_high = true;
let addr_actual =
addr.ok_or(InterpreterError::UndefinedReadAddr)?;
addr.ok_or(InterpreterError::UndefinedReadAddr(String::new()))?;
self.read_out =
PortValue::new_cell(self.internal_state[addr_actual].clone());
} else {
Expand Down
1 change: 1 addition & 0 deletions interp/src/flatten/primitives/stateful/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod math;
pub mod memories;

pub use math::*;
pub use memories::*;
Loading

0 comments on commit be274e6

Please sign in to comment.