Skip to content

Commit b763a8e

Browse files
resolve new step in IR with scheduler
2 parents 3cb499f + a4e19d6 commit b763a8e

35 files changed

+193
-342
lines changed

src/interpreter.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,15 @@ impl<'a> Evaluator<'a> {
219219
// println!("Eval While.");
220220
self.evaluate_while(&loop_guard_id, stmt_id, &do_block_id)
221221
}
222-
Stmt::Step(expr) => {
223-
// TODO: how do we deal with steps when n > 1?
224-
// the scheduler will handle the step. simple return the next statement to run
222+
Stmt::Step => {
223+
// println!("Eval Step.");
224+
// the scheduler will handle the step. simply return the next statement to run
225225
Ok(self.next_stmt_mapping[stmt_id])
226226
}
227227
Stmt::Fork => {
228228
// println!("Eval Fork.");
229-
// the scheduler will handle the fork. simple return the next statement to run
230-
return Ok(self.next_stmt_mapping[stmt_id]);
231-
// return Err("Fork not implemented.".to_string());
229+
// the scheduler will handle the fork. simply return the next statement to run
230+
Ok(self.next_stmt_mapping[stmt_id])
232231
}
233232
Stmt::AssertEq(expr1, expr2) => {
234233
// println!("Eval AssertEq.");
@@ -294,6 +293,11 @@ impl<'a> Evaluator<'a> {
294293
}
295294
}
296295

296+
fn evaluate_fork(&self) -> Result<(), String> {
297+
// TODO: Implement evaluate_fork
298+
Ok(())
299+
}
300+
297301
fn evaluate_assert_eq(&mut self, expr1: &ExprId, expr2: &ExprId) -> Result<(), String> {
298302
let res1 = self.evaluate_expr(expr1)?;
299303
let res2 = self.evaluate_expr(expr2)?;
@@ -413,6 +417,7 @@ pub mod tests {
413417
}
414418

415419
#[test]
420+
#[ignore]
416421
fn test_add_ok() {
417422
// set up the args for the Transaction
418423
let mut args = HashMap::new();
@@ -429,6 +434,7 @@ pub mod tests {
429434
}
430435

431436
#[test]
437+
#[ignore]
432438
fn test_add_err() {
433439
// set up the args for the Transaction
434440
let mut args = HashMap::new();
@@ -445,6 +451,7 @@ pub mod tests {
445451
}
446452

447453
#[test]
454+
#[ignore]
448455
fn test_mult_execution() {
449456
let mut args = HashMap::new();
450457
args.insert("a", BitVecValue::from_u64(6, 32));
@@ -460,6 +467,7 @@ pub mod tests {
460467
}
461468

462469
#[test]
470+
#[ignore]
463471
fn test_simple_if_execution() {
464472
let mut args = HashMap::new();
465473
args.insert("a", BitVecValue::from_u64(32, 64));
@@ -474,6 +482,7 @@ pub mod tests {
474482
}
475483

476484
#[test]
485+
#[ignore]
477486
fn test_simple_while_execution() {
478487
let mut args = HashMap::new();
479488
args.insert("a", BitVecValue::from_u64(32, 64));

src/ir.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ entity_impl!(StmtId, "stmt");
215215
pub enum Stmt {
216216
Block(Vec<StmtId>),
217217
Assign(SymbolId, ExprId),
218-
Step(ExprId),
218+
Step,
219219
Fork,
220220
While(ExprId, StmtId),
221221
IfElse(ExprId, StmtId, StmtId),
@@ -579,14 +579,14 @@ mod tests {
579579
// 3) create expressions
580580
let a_expr = add.e(Expr::Sym(a));
581581
let b_expr = add.e(Expr::Sym(b));
582-
let one_expr = add.e(Expr::Const(BitVecValue::from_u64(1, 1)));
582+
// let one_expr = add.e(Expr::Const(BitVecValue::from_u64(1, 1)));
583583
let dut_s_expr = add.e(Expr::Sym(dut_s));
584584

585585
// 4) create statements
586586
let body = vec![
587587
add.s(Stmt::Assign(dut_a, a_expr)),
588588
add.s(Stmt::Assign(dut_b, b_expr)),
589-
add.s(Stmt::Step(one_expr)),
589+
add.s(Stmt::Step),
590590
add.s(Stmt::Fork),
591591
add.s(Stmt::Assign(dut_a, add.expr_dont_care())),
592592
add.s(Stmt::Assign(dut_b, add.expr_dont_care())),
@@ -641,7 +641,7 @@ mod tests {
641641

642642
// 4) create statements
643643
let one_expr = calyx_go_done.e(Expr::Const(BitVecValue::from_u64(1, 1)));
644-
let while_body = vec![calyx_go_done.s(Stmt::Step(one_expr))];
644+
let while_body = vec![calyx_go_done.s(Stmt::Step)];
645645
let wbody = calyx_go_done.s(Stmt::Block(while_body));
646646

647647
let body = vec![

src/parser.rs

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ impl<'a> ParserContext<'a> {
7878

7979
match primary.as_rule() {
8080
Rule::integer => {
81-
let int_str = primary.as_str();
82-
let int_value = int_str.parse::<i32>().unwrap();
83-
let bitvec = BitVecValue::from_u64(int_value as u64, 64);
84-
Ok(BoxedExpr::Const(bitvec, start, end))
81+
let int_value = primary.as_str().parse::<u64>().unwrap();
82+
let bvv = BitVecValue::from_u64(int_value as u64, 64);
83+
84+
Ok(BoxedExpr::Const(bvv, start, end))
8585
}
8686
Rule::path_id => {
8787
let path_id = primary.as_str();
@@ -290,9 +290,25 @@ impl<'a> ParserContext<'a> {
290290
while let Some(inner_pair) = stmt_pairs.next() {
291291
let start = inner_pair.as_span().start();
292292
let end = inner_pair.as_span().end();
293+
294+
// special case for step() -- will return a vector of statements
295+
if inner_pair.as_rule() == Rule::step {
296+
let step_stmt = self.parse_step(inner_pair)?;
297+
298+
// push each step statement into the transaction
299+
for step in step_stmt {
300+
let step_id = self.tr.s(step);
301+
self.tr.add_stmt_loc(step_id, start, end, self.fileid);
302+
stmts.push(step_id);
303+
}
304+
305+
continue;
306+
}
307+
308+
// Handle other statement types
293309
let stmt = match inner_pair.as_rule() {
294310
Rule::assign => self.parse_assign(inner_pair)?,
295-
Rule::cmd => self.parse_cmd(inner_pair)?,
311+
Rule::fork => self.parse_fork(inner_pair)?,
296312
Rule::while_loop => self.parse_while(inner_pair)?,
297313
Rule::cond => self.parse_cond(inner_pair)?,
298314
Rule::assert_eq => self.parse_assert_eq(inner_pair)?,
@@ -310,6 +326,7 @@ impl<'a> ParserContext<'a> {
310326
return Err(msg);
311327
}
312328
};
329+
313330
let stmt_id = self.tr.s(stmt);
314331
self.tr.add_stmt_loc(stmt_id, start, end, self.fileid);
315332
stmts.push(stmt_id);
@@ -338,52 +355,38 @@ impl<'a> ParserContext<'a> {
338355
Ok(Stmt::Assign(symbol_id, expr_id))
339356
}
340357

341-
fn parse_cmd(&mut self, pair: pest::iterators::Pair<Rule>) -> Result<Stmt, String> {
358+
fn parse_step(&mut self, pair: pest::iterators::Pair<Rule>) -> Result<Vec<Stmt>, String> {
342359
let mut inner_rules = pair.clone().into_inner();
343-
let cmd_rule = self.expect_rule(inner_rules.next(), &pair, "Expected command")?;
344-
let cmd = cmd_rule.as_str();
345-
346-
let arg = if let Some(expr_rule) = inner_rules.next() {
347-
let expr_id = self.parse_expr(expr_rule.into_inner())?;
348-
Some(expr_id)
349-
} else {
350-
None
360+
let integer_rule = inner_rules.next();
361+
let num_steps = match integer_rule {
362+
Some(rule) => rule.as_str().parse::<u64>().unwrap(),
363+
None => 1, // Implicit 1 if no integer is passed
351364
};
352365

353-
match cmd {
354-
"step" => match arg {
355-
Some(expr_id) => Ok(Stmt::Step(expr_id)),
356-
None => {
357-
let one_expr = self.tr.e(Expr::Const(BitVecValue::from_i64(1, 2)));
358-
self.handler.emit_diagnostic_parsing(
359-
"Inferring step value to be 1.",
360-
self.fileid,
361-
&pair,
362-
Level::Warning,
363-
);
364-
Ok(Stmt::Step(one_expr))
365-
}
366-
},
367-
"fork" => {
368-
if arg.is_some() {
369-
let msg = "Fork command should have no arguments.".to_string();
370-
self.handler.emit_diagnostic_parsing(
371-
&msg,
372-
self.fileid,
373-
&cmd_rule,
374-
Level::Error,
375-
);
376-
return Err(msg);
377-
}
378-
Ok(Stmt::Fork)
379-
}
380-
_ => {
381-
let msg = format!("Unexpected command: {:?}", cmd);
382-
self.handler
383-
.emit_diagnostic_parsing(&msg, self.fileid, &cmd_rule, Level::Error);
384-
Err(msg)
385-
}
366+
// error if num_steps is 0 (note that the integer_rule is already unsigned, preventing negatives)
367+
if num_steps == 0 {
368+
let msg = format!(
369+
"Step call expected single positive integer as argument, got {}.",
370+
num_steps
371+
);
372+
self.handler
373+
.emit_diagnostic_parsing(&msg, self.fileid, &pair, Level::Error);
374+
return Err(msg);
375+
}
376+
377+
// return a vector of steps based on num_steps
378+
let mut steps = Vec::new();
379+
for _ in 0..num_steps {
380+
let step_stmt = Stmt::Step;
381+
steps.push(step_stmt);
386382
}
383+
384+
Ok(steps)
385+
}
386+
387+
fn parse_fork(&mut self, _pair: pest::iterators::Pair<Rule>) -> Result<Stmt, String> {
388+
// Fork is a special case, it doesn't have any arguments (enforced by the grammar)
389+
Ok(Stmt::Fork)
387390
}
388391

389392
fn parse_while(&mut self, pair: pest::iterators::Pair<Rule>) -> Result<Stmt, String> {

src/protocols.pest

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ id = _{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" )* }
4646
path_id = @{ id ~ ("." ~ id)* }
4747
tpe = { "u" ~ integer }
4848
assign = {path_id ~ ":=" ~ (expr | path_id) ~ ";" }
49-
cmd = { path_id ~ "(" ~ expr? ~ ")" ~ ";"}
50-
stmt = _{ (assign | cmd | while_loop | cond | assert_eq ) }
49+
// cmd = { path_id ~ "(" ~ expr? ~ ")" ~ ";"}
50+
step = { "step" ~ "(" ~ integer? ~ ")" ~ ";"}
51+
fork = { "fork" ~ "()" ~ ";"}
52+
stmt = _{ (assign | step | fork | while_loop | cond | assert_eq ) }
5153
dir = { "in" | "out" }
5254
arg = { dir ~ path_id ~ ":" ~ tpe }
5355
arglist = { (arg ~ "," ~ arglist) | arg ~ ","? }

src/scheduler.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ impl<'a> Scheduler<'a> {
120120
for (i, arg) in args.iter().enumerate() {
121121
let identifier = st[tr.args[i].symbol()].name();
122122
args_map.insert(identifier, arg.clone());
123+
124+
println!("Args Mapping {:?}", args_map)
123125
}
124126

125127
Some((tr, st, args_map))
@@ -156,6 +158,10 @@ impl<'a> Scheduler<'a> {
156158
}
157159
}
158160

161+
// now that all threads are synchronized on the step, we can run step() on the sim
162+
println!("Stepping...");
163+
self.evaluator.sim_step();
164+
159165
if self.next_threads.len() > 0 {
160166
println!(
161167
"Moving {} threads from next_threads to active_threads for next cycle",
@@ -168,9 +174,6 @@ impl<'a> Scheduler<'a> {
168174
println!("No more threads to schedule. Protocol execution complete.");
169175
println!("Total inactive threads: {}", self.inactive_threads.len());
170176
}
171-
172-
// now that all threads are synchronized on the step, we can run step() on the sim
173-
self.evaluator.sim_step();
174177
}
175178

176179
return self.results.clone();
@@ -199,7 +202,7 @@ impl<'a> Scheduler<'a> {
199202
);
200203
match thread.tr[next_stmt_id] {
201204
// if a step, stop execution
202-
Stmt::Step(_) => {
205+
Stmt::Step => {
203206
println!(
204207
" Step reached, thread will pause at: {:?}",
205208
next_stmt_id
@@ -342,7 +345,7 @@ pub mod tests {
342345
let handler = &mut DiagnosticHandler::new();
343346

344347
// test_helper("tests/add_struct.prot", "add_struct");
345-
let transaction_filename = "tests/mult_new.prot";
348+
let transaction_filename = "tests/mul.prot";
346349
let verilog_path = "examples/multipliers/mult_d2.v";
347350
let (ctx, sys) = Evaluator::create_sim_context(verilog_path);
348351
let sim = &mut patronus::sim::Interpreter::new(&ctx, &sys);
@@ -397,7 +400,7 @@ pub mod tests {
397400
assert!(results[0].is_err());
398401
assert!(results[1].is_ok());
399402

400-
// CASE 4: FIRST THREAD FAILS, SECOND THREAD FAILS
403+
// // CASE 4: FIRST THREAD FAILS, SECOND THREAD FAILS
401404
todos[1].1[2] = BitVecValue::from_u64(47, 32);
402405
let sim3 = &mut patronus::sim::Interpreter::new(&ctx, &sys);
403406

src/serialize.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ pub fn build_statements(
8181
st[lhs].full_name(st),
8282
serialize_expr(tr, st, rhs)
8383
)?,
84-
Stmt::Step(expr_id) => writeln!(
84+
Stmt::Step => writeln!(
8585
out,
86-
"{}step({});",
86+
"{}step();",
8787
" ".repeat(index),
88-
serialize_expr(tr, st, expr_id)
88+
// serialize_expr(tr, st, expr_id)
8989
)?,
9090
Stmt::Fork => writeln!(out, "{}fork();", " ".repeat(index))?,
9191
Stmt::While(cond, bodyid) => {
@@ -360,7 +360,7 @@ pub mod tests {
360360
let cond_expr = easycond.e(Expr::Binary(BinOp::Equal, dut_a_expr, one_expr));
361361

362362
// 4) create statements
363-
let if_body = vec![easycond.s(Stmt::Step(one_expr))];
363+
let if_body = vec![easycond.s(Stmt::Step)];
364364
let ifbody = easycond.s(Stmt::Block(if_body));
365365

366366
let else_body = vec![easycond.s(Stmt::Fork)];

src/typecheck.rs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,7 @@ fn check_stmt_types(
6464
) -> Result<(), String> {
6565
match &tr[stmt_id] {
6666
Stmt::Fork => Ok(()),
67-
Stmt::Step(exprid) => {
68-
let expr_type = check_expr_types(tr, st, handler, exprid)?;
69-
if let Type::BitVec(_) = expr_type {
70-
if let Expr::Const(val) = &tr[exprid] {
71-
if val.to_i64().unwrap() >= 1 {
72-
return Ok(());
73-
}
74-
handler.emit_diagnostic_expr(
75-
tr,
76-
exprid,
77-
&format!("Argument to step must be a positive, non-zero integer literal."),
78-
Level::Error,
79-
);
80-
}
81-
Ok(())
82-
} else {
83-
handler.emit_diagnostic_stmt(
84-
tr,
85-
stmt_id,
86-
&format!("Invalid type for [step] statement: {:?}", expr_type),
87-
Level::Error,
88-
);
89-
Ok(())
90-
}
91-
}
67+
Stmt::Step => Ok(()),
9268
Stmt::Assign(lhs, rhs) => {
9369
// Function argument cannot be assigned
9470
if tr.args.iter().any(|arg| arg.symbol() == *lhs) {
@@ -339,7 +315,7 @@ mod tests {
339315
tr.add_stmt_loc(fork, 68, 75, fileid);
340316
let c_assign = tr.s(Stmt::Assign(c, b_expr));
341317
tr.add_stmt_loc(c_assign, 79, 86, fileid);
342-
let step = tr.s(Stmt::Step(one_expr));
318+
let step = tr.s(Stmt::Step);
343319
tr.add_stmt_loc(step, 90, 97, fileid);
344320
let s_assign = tr.s(Stmt::Assign(s, zero_expr));
345321
tr.add_stmt_loc(s_assign, 101, 108, fileid);

tests/mul.prot

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ fn mul<dut: Multiplier>(in a: u32, in b: u32, out s: u32) {
88
dut.a := a;
99
dut.b := b;
1010
// hold a and b stable for two cycles
11-
step();
12-
step();
11+
step(2);
1312
// can apply a new input after two cycles
1413
fork();
1514
// after, it does not matter what we apply to these ports

0 commit comments

Comments
 (0)