Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cider 2] Invoke fixes, mult imp, and error messages #2128

Merged
merged 4 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading