From 14127772cdb3567dc94e71e6e67ebe24f178701f Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 20:00:39 -0500 Subject: [PATCH 1/8] command line cycle limit parse --- calyx-opt/src/passes/static_promotion.rs | 132 ++++++++++++++++------- 1 file changed, 95 insertions(+), 37 deletions(-) diff --git a/calyx-opt/src/passes/static_promotion.rs b/calyx-opt/src/passes/static_promotion.rs index 0236941a1..c0a4635d3 100644 --- a/calyx-opt/src/passes/static_promotion.rs +++ b/calyx-opt/src/passes/static_promotion.rs @@ -143,7 +143,7 @@ pub struct StaticPromotion { /// Threshold for promotion threshold: u64, /// Whether we should stop promoting when we see a loop. - stop_loop: bool, + cycle_limit: Option, } // Override constructor to build latency_data information from the primitives @@ -177,13 +177,13 @@ impl ConstructVisitor for StaticPromotion { } latency_data.insert(prim.name, GoDone::new(go_ports)); } - let (threshold, stop_loop) = Self::get_threshold(ctx); + let (threshold, cycle_limit) = Self::get_threshold(ctx); Ok(StaticPromotion { latency_data, static_group_name: HashMap::new(), static_component_latencies: HashMap::new(), threshold, - stop_loop, + cycle_limit, }) } @@ -206,7 +206,7 @@ impl Named for StaticPromotion { impl StaticPromotion { // Looks through ctx to get the given command line threshold. // Default threshold = 1 - fn get_threshold(ctx: &ir::Context) -> (u64, bool) + fn get_threshold(ctx: &ir::Context) -> (u64, Option) where Self: Named, { @@ -226,12 +226,33 @@ impl StaticPromotion { }) .collect(); - let mut stop_loop = false; - given_opts.iter().for_each(|arg| { - if *arg == "stop_loop" { - stop_loop = true + // searching for "-x static-promotion:cycle-limit=200" and getting back "200" + let cycle_limit_str: Option<&str> = given_opts.iter().find_map(|arg| { + let split: Vec<&str> = arg.split('=').collect(); + if let Some(str) = split.first() { + if str == &"cycle-limit" { + return Some(split[1]); + } } + None }); + // If they don't give a cycle_limit_str, then we set it to the Default. + // If they explicitly say "None" or "none", hten we set it to None. + // Makes things a bit confusing. + let cycle_limt = if cycle_limit_str == None { + Some(33554432) + } else if cycle_limit_str.unwrap() == "None" + || cycle_limit_str.unwrap() == "none" + { + None + } else { + Some( + cycle_limit_str + .unwrap_or("33554432") + .parse::() + .unwrap_or(33554432), + ) + }; // searching for "-x static-promotion:threshold=1" and getting back "1" let threshold: Option<&str> = given_opts.iter().find_map(|arg| { @@ -246,9 +267,10 @@ impl StaticPromotion { // Need to convert string argument into int argument // Always default to threshold=1 + // Default cycle limit = 2^25 = 33554432 ( threshold.unwrap_or("1").parse::().unwrap_or(1), - stop_loop, + cycle_limt, ) } @@ -502,6 +524,13 @@ impl StaticPromotion { c.is_static() || c.has_attribute(ir::NumAttr::PromoteStatic) } + fn within_cycle_limit(&self, latency: u64) -> bool { + if self.cycle_limit == None { + return true; + } + return latency < self.cycle_limit.unwrap(); + } + /// If we've already constructed the static group then use the already existing /// group. Otherwise construct `static group` and then return that. fn construct_static_group( @@ -742,18 +771,26 @@ impl StaticPromotion { v.iter().map(Self::approx_size).sum() } - /// First checks if the vec of control statements meets the self.threshold. + /// First checks if the vec of control statements satsifies the threshold + /// and cycle count threshold /// (That is, whether the combined approx_size of the static_vec is greater) - /// Than the threshold. + /// than the threshold and cycle count is less than cycle limit). /// If so, converts vec of control to a static seq, and returns a vec containing /// the static seq. /// Otherwise, just returns the vec without changing it. - fn convert_vec_seq_if_threshold( + fn convert_vec_seq_if_sat( &mut self, builder: &mut ir::Builder, control_vec: Vec, ) -> Vec { - if Self::approx_control_vec_size(&control_vec) <= self.threshold { + if Self::approx_control_vec_size(&control_vec) <= self.threshold + || self.within_cycle_limit( + control_vec + .iter() + .map(|c| Self::get_inferred_latency(c)) + .sum(), + ) + { // Return unchanged vec return control_vec; } @@ -767,16 +804,25 @@ impl StaticPromotion { vec![sseq] } - /// First checks if the vec of control statements meets the self.threshold. + /// First checks if the vec of control statements meets the self.threshold + /// and is within self.cycle_limit /// If so, converts vec of control to a static par, and returns a vec containing /// the static par. /// Otherwise, just returns the vec without changing it. - fn convert_vec_par_if_threshold( + fn convert_vec_par_if_sat( &mut self, builder: &mut ir::Builder, control_vec: Vec, ) -> Vec { - if Self::approx_control_vec_size(&control_vec) <= self.threshold { + if Self::approx_control_vec_size(&control_vec) <= self.threshold + || self.within_cycle_limit( + control_vec + .iter() + .map(|c| Self::get_inferred_latency(c)) + .max() + .unwrap_or_else(|| unreachable!("Non Empty Par Block")), + ) + { // Return unchanged vec return control_vec; } @@ -929,17 +975,22 @@ impl Visitor for StaticPromotion { } else { // Accumualte cur_vec into a static seq if it meets threshold let possibly_promoted_stmts = - self.convert_vec_seq_if_threshold(&mut builder, cur_vec); + self.convert_vec_seq_if_sat(&mut builder, cur_vec); new_stmts.extend(possibly_promoted_stmts); - cur_vec = Vec::new(); // Add the current (non-promotable) stmt new_stmts.push(stmt); + // New cur_vec + cur_vec = Vec::new(); } } if new_stmts.is_empty() { // The entire seq can be promoted let approx_size: u64 = cur_vec.iter().map(Self::approx_size).sum(); - if approx_size > self.threshold { + if approx_size > self.threshold + && self.within_cycle_limit( + cur_vec.iter().map(|c| Self::get_inferred_latency(c)).sum(), + ) + { // Promote entire seq to a static seq let s_seq_stmts = self.convert_vec_to_static(&mut builder, cur_vec); @@ -966,7 +1017,7 @@ impl Visitor for StaticPromotion { // Entire seq is not static, so we're only promoting the last // bit of it if possible. let possibly_promoted_stmts = - self.convert_vec_seq_if_threshold(&mut builder, cur_vec); + self.convert_vec_seq_if_sat(&mut builder, cur_vec); new_stmts.extend(possibly_promoted_stmts); let new_seq = ir::Control::Seq(ir::Seq { @@ -993,7 +1044,15 @@ impl Visitor for StaticPromotion { }); if d_stmts.is_empty() { // Entire par block can be promoted to static - if Self::approx_control_vec_size(&s_stmts) > self.threshold { + if Self::approx_control_vec_size(&s_stmts) > self.threshold + && self.within_cycle_limit( + s_stmts + .iter() + .map(|c| Self::get_inferred_latency(c)) + .max() + .unwrap_or_else(|| unreachable!("Empty Par Block")), + ) + { // Promote entire par block to static let static_par_stmts = self.convert_vec_to_static(&mut builder, s_stmts); @@ -1021,7 +1080,7 @@ impl Visitor for StaticPromotion { } // Otherwise just promote the par threads that we can into a static par let s_stmts_possibly_promoted = - self.convert_vec_par_if_threshold(&mut builder, s_stmts); + self.convert_vec_par_if_sat(&mut builder, s_stmts); new_stmts.extend(s_stmts_possibly_promoted); new_stmts.extend(d_stmts); let new_par = ir::Control::Par(ir::Par { @@ -1046,16 +1105,18 @@ impl Visitor for StaticPromotion { let approx_size_if = Self::approx_size(&s.tbranch) + Self::approx_size(&s.fbranch) + APPROX_IF_SIZE; - if approx_size_if > self.threshold { + let latency = std::cmp::max( + Self::get_inferred_latency(&s.tbranch), + Self::get_inferred_latency(&s.fbranch), + ); + if approx_size_if > self.threshold + && self.within_cycle_limit(latency) + { // Meets size threshold so promote to static let static_tbranch = self.convert_to_static(&mut s.tbranch, &mut builder); let static_fbranch = self.convert_to_static(&mut s.fbranch, &mut builder); - let latency = std::cmp::max( - static_tbranch.get_latency(), - static_fbranch.get_latency(), - ); return Ok(Action::change(ir::Control::Static( ir::StaticControl::static_if( Rc::clone(&s.port), @@ -1086,9 +1147,6 @@ impl Visitor for StaticPromotion { sigs: &LibrarySignatures, _comps: &[ir::Component], ) -> VisResult { - if self.stop_loop { - return Ok(Action::Continue); - } let mut builder = ir::Builder::new(comp, sigs); // First check that while loop is bounded if let Some(num_repeats) = s.get_attributes().get(ir::NumAttr::Bound) { @@ -1096,11 +1154,13 @@ impl Visitor for StaticPromotion { if Self::can_be_promoted(&s.body) { let approx_size = Self::approx_size(&s.body) + APPROX_WHILE_REPEAT_SIZE; + let latency = Self::get_inferred_latency(&s.body) * num_repeats; // Then check that it reaches the threshold - if approx_size > self.threshold { + if approx_size > self.threshold + && self.within_cycle_limit(latency) + { // Turn repeat into static repeat let sc = self.convert_to_static(&mut s.body, &mut builder); - let latency = sc.get_latency() * num_repeats; let static_repeat = ir::StaticControl::repeat( num_repeats, latency, @@ -1130,18 +1190,16 @@ impl Visitor for StaticPromotion { sigs: &LibrarySignatures, _comps: &[ir::Component], ) -> VisResult { - if self.stop_loop { - return Ok(Action::Continue); - } let mut builder = ir::Builder::new(comp, sigs); if Self::can_be_promoted(&s.body) { // Body can be promoted let approx_size = Self::approx_size(&s.body) + APPROX_WHILE_REPEAT_SIZE; - if approx_size > self.threshold { + let latency = Self::get_inferred_latency(&s.body) * s.num_repeats; + if approx_size > self.threshold && self.within_cycle_limit(latency) + { // Meets size threshold, so turn repeat into static repeat let sc = self.convert_to_static(&mut s.body, &mut builder); - let latency = s.num_repeats * sc.get_latency(); let static_repeat = ir::StaticControl::repeat( s.num_repeats, latency, From 659d143d2afb9c4a473adeb8297c6d9e22819dc0 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 20:06:07 -0500 Subject: [PATCH 2/8] clippy --- calyx-opt/src/passes/static_promotion.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/calyx-opt/src/passes/static_promotion.rs b/calyx-opt/src/passes/static_promotion.rs index c0a4635d3..30e48737f 100644 --- a/calyx-opt/src/passes/static_promotion.rs +++ b/calyx-opt/src/passes/static_promotion.rs @@ -239,7 +239,7 @@ impl StaticPromotion { // If they don't give a cycle_limit_str, then we set it to the Default. // If they explicitly say "None" or "none", hten we set it to None. // Makes things a bit confusing. - let cycle_limt = if cycle_limit_str == None { + let cycle_limit = if cycle_limit_str.is_none() { Some(33554432) } else if cycle_limit_str.unwrap() == "None" || cycle_limit_str.unwrap() == "none" @@ -270,7 +270,7 @@ impl StaticPromotion { // Default cycle limit = 2^25 = 33554432 ( threshold.unwrap_or("1").parse::().unwrap_or(1), - cycle_limt, + cycle_limit, ) } @@ -525,10 +525,10 @@ impl StaticPromotion { } fn within_cycle_limit(&self, latency: u64) -> bool { - if self.cycle_limit == None { + if self.cycle_limit.is_none() { return true; } - return latency < self.cycle_limit.unwrap(); + latency < self.cycle_limit.unwrap() } /// If we've already constructed the static group then use the already existing @@ -784,11 +784,8 @@ impl StaticPromotion { control_vec: Vec, ) -> Vec { if Self::approx_control_vec_size(&control_vec) <= self.threshold - || self.within_cycle_limit( - control_vec - .iter() - .map(|c| Self::get_inferred_latency(c)) - .sum(), + || !self.within_cycle_limit( + control_vec.iter().map(Self::get_inferred_latency).sum(), ) { // Return unchanged vec @@ -815,10 +812,10 @@ impl StaticPromotion { control_vec: Vec, ) -> Vec { if Self::approx_control_vec_size(&control_vec) <= self.threshold - || self.within_cycle_limit( + || !self.within_cycle_limit( control_vec .iter() - .map(|c| Self::get_inferred_latency(c)) + .map(Self::get_inferred_latency) .max() .unwrap_or_else(|| unreachable!("Non Empty Par Block")), ) @@ -988,7 +985,7 @@ impl Visitor for StaticPromotion { let approx_size: u64 = cur_vec.iter().map(Self::approx_size).sum(); if approx_size > self.threshold && self.within_cycle_limit( - cur_vec.iter().map(|c| Self::get_inferred_latency(c)).sum(), + cur_vec.iter().map(Self::get_inferred_latency).sum(), ) { // Promote entire seq to a static seq @@ -1048,7 +1045,7 @@ impl Visitor for StaticPromotion { && self.within_cycle_limit( s_stmts .iter() - .map(|c| Self::get_inferred_latency(c)) + .map(Self::get_inferred_latency) .max() .unwrap_or_else(|| unreachable!("Empty Par Block")), ) From 0b27e17a630afa4b74530704c46fca48322e403c Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 20:39:18 -0500 Subject: [PATCH 3/8] better static guard simplification --- .../src/passes/simplify_static_guards.rs | 34 +++++++++++++++---- .../simplify-static-guards/simplify-or.expect | 21 ++++++++++++ .../simplify-static-guards/simplify-or.futil | 24 +++++++++++++ 3 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 tests/passes/simplify-static-guards/simplify-or.expect create mode 100644 tests/passes/simplify-static-guards/simplify-or.futil diff --git a/calyx-opt/src/passes/simplify_static_guards.rs b/calyx-opt/src/passes/simplify_static_guards.rs index e22d3c2da..7371cf94e 100644 --- a/calyx-opt/src/passes/simplify_static_guards.rs +++ b/calyx-opt/src/passes/simplify_static_guards.rs @@ -35,11 +35,8 @@ impl SimplifyStaticGuards { cur_anded_intervals: &mut Vec<(u64, u64)>, ) -> Option> { match g { - ir::Guard::Not(_) - | ir::Guard::Or(_, _) - | ir::Guard::True - | ir::Guard::CompOp(_, _, _) - | ir::Guard::Port(_) => Some(g), + ir::Guard::Not(_) => panic!(""), + ir::Guard::Or(_, _) => panic!(""), ir::Guard::And(g1, g2) => { // recursively call separate_anded_intervals on g1 and g2 let rest_g1 = @@ -65,6 +62,9 @@ impl SimplifyStaticGuards { cur_anded_intervals.push(static_timing_info.get_interval()); None } + ir::Guard::True + | ir::Guard::CompOp(_, _, _) + | ir::Guard::Port(_) => Some(g), } } @@ -75,7 +75,7 @@ impl SimplifyStaticGuards { /// For example: (port.out | !port1.out) & (port2.out == port3.out) & %[2:8] & %[5:10] ? /// becomes (port.out | !port1.out) & (port2.out == port3.out) & %[5:8] ? /// by "combining: %[2:8] & %[5:10] - fn simplify_guard( + fn simplify_anded_guards( guard: ir::Guard, group_latency: u64, ) -> ir::Guard { @@ -121,6 +121,28 @@ impl SimplifyStaticGuards { (Some(rg), Some(ig)) => ir::Guard::And(Box::new(rg), Box::new(ig)), } } + + fn simplify_guard( + guard: ir::Guard, + group_latency: u64, + ) -> ir::Guard { + match guard { + ir::Guard::Not(g) => ir::Guard::Not(Box::new( + Self::simplify_guard(*g, group_latency), + )), + ir::Guard::Or(g1, g2) => ir::Guard::Or( + Box::new(Self::simplify_guard(*g1, group_latency)), + Box::new(Self::simplify_guard(*g2, group_latency)), + ), + ir::Guard::And(_, _) => { + Self::simplify_anded_guards(guard, group_latency) + } + ir::Guard::Info(_) + | ir::Guard::Port(_) + | ir::Guard::True + | ir::Guard::CompOp(_, _, _) => guard, + } + } } impl Visitor for SimplifyStaticGuards { diff --git a/tests/passes/simplify-static-guards/simplify-or.expect b/tests/passes/simplify-static-guards/simplify-or.expect new file mode 100644 index 000000000..b126ad06c --- /dev/null +++ b/tests/passes/simplify-static-guards/simplify-or.expect @@ -0,0 +1,21 @@ +import "primitives/core.futil"; +import "primitives/binary_operators.futil"; +component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { + cells { + a = std_reg(32); + b = std_reg(32); + c = std_reg(32); + d = std_reg(32); + e = std_reg(32); + lt = std_lt(32); + gt = std_lt(32); + } + wires { + static<10> group my_group { + a.write_en = %2 | %5 | lt.out & %7 ? 1'd1; + } + } + control { + my_group; + } +} diff --git a/tests/passes/simplify-static-guards/simplify-or.futil b/tests/passes/simplify-static-guards/simplify-or.futil new file mode 100644 index 000000000..a01944f16 --- /dev/null +++ b/tests/passes/simplify-static-guards/simplify-or.futil @@ -0,0 +1,24 @@ +// -p simplify-static-guards + +import "primitives/core.futil"; +import "primitives/binary_operators.futil"; +component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { + cells { + a = std_reg(32); + b = std_reg(32); + c = std_reg(32); + d = std_reg(32); + e = std_reg(32); + lt = std_lt(32); + gt = std_lt(32); + } + wires { + static<10> group my_group { + a.write_en = (%[2:3] & %[2:9]) | (%[5:9] & %[5:6]) | (%[7:9] & %[7:8] & lt.out) ? 1'd1; // don't simplify + } + } + + control { + my_group; + } +} From 18c38b735dae41990da3af1751cfa64300a23485 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 21:02:01 -0500 Subject: [PATCH 4/8] rewrite test --- .../static-promotion/no_promote_loop.expect | 27 ++++++++++++++----- .../static-promotion/no_promote_loop.futil | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/tests/passes/static-promotion/no_promote_loop.expect b/tests/passes/static-promotion/no_promote_loop.expect index 26a22869a..2aa38ac2b 100644 --- a/tests/passes/static-promotion/no_promote_loop.expect +++ b/tests/passes/static-promotion/no_promote_loop.expect @@ -6,6 +6,21 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { c = std_reg(2); } wires { + group A<"promote_static"=1> { + a.in = 2'd0; + a.write_en = 1'd1; + A[done] = a.done; + } + group B<"promote_static"=1> { + b.in = 2'd1; + b.write_en = 1'd1; + B[done] = b.done; + } + group C<"promote_static"=1> { + c.in = 2'd2; + c.write_en = 1'd1; + C[done] = c.done; + } static<1> group A0 { a.in = 2'd0; a.write_en = 1'd1; @@ -20,8 +35,8 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { } } control { - seq { - repeat 10 { + @promote_static(43) seq { + @promote_static(40) repeat 10 { @compactable static<4> seq { A0; B0; @@ -29,11 +44,9 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { C0; } } - @compactable static<3> seq { - A0; - B0; - C0; - } + @promote_static A; + @promote_static B; + @promote_static C; } } } diff --git a/tests/passes/static-promotion/no_promote_loop.futil b/tests/passes/static-promotion/no_promote_loop.futil index 36d9575ca..727917504 100644 --- a/tests/passes/static-promotion/no_promote_loop.futil +++ b/tests/passes/static-promotion/no_promote_loop.futil @@ -1,4 +1,4 @@ -// -p well-formed -p static-promotion -p dead-group-removal -x static-promotion:stop_loop +// -p well-formed -p static-promotion -p dead-group-removal -x static-promotion:cycle-limit=25 import "primitives/core.futil"; From cfa9cc099f8a27209e71753689c7b493b856cc62 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 21:05:52 -0500 Subject: [PATCH 5/8] small change --- calyx-opt/src/passes/simplify_static_guards.rs | 10 ++++++---- .../passes/simplify-static-guards/basic.futil | 18 +++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/calyx-opt/src/passes/simplify_static_guards.rs b/calyx-opt/src/passes/simplify_static_guards.rs index 7371cf94e..3f8ac99b6 100644 --- a/calyx-opt/src/passes/simplify_static_guards.rs +++ b/calyx-opt/src/passes/simplify_static_guards.rs @@ -35,8 +35,6 @@ impl SimplifyStaticGuards { cur_anded_intervals: &mut Vec<(u64, u64)>, ) -> Option> { match g { - ir::Guard::Not(_) => panic!(""), - ir::Guard::Or(_, _) => panic!(""), ir::Guard::And(g1, g2) => { // recursively call separate_anded_intervals on g1 and g2 let rest_g1 = @@ -64,6 +62,8 @@ impl SimplifyStaticGuards { } ir::Guard::True | ir::Guard::CompOp(_, _, _) + | ir::Guard::Not(_) + | ir::Guard::Or(_, _) | ir::Guard::Port(_) => Some(g), } } @@ -137,8 +137,10 @@ impl SimplifyStaticGuards { ir::Guard::And(_, _) => { Self::simplify_anded_guards(guard, group_latency) } - ir::Guard::Info(_) - | ir::Guard::Port(_) + ir::Guard::Info(_) => { + Self::simplify_anded_guards(guard, group_latency) + } + ir::Guard::Port(_) | ir::Guard::True | ir::Guard::CompOp(_, _, _) => guard, } diff --git a/tests/passes/simplify-static-guards/basic.futil b/tests/passes/simplify-static-guards/basic.futil index 4c3dbeec6..5108bd5a6 100644 --- a/tests/passes/simplify-static-guards/basic.futil +++ b/tests/passes/simplify-static-guards/basic.futil @@ -14,15 +14,15 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { } wires { static<10> group my_group { - a.write_en = (%[2:3] | lt.out) & %[1:5] ? 1'd1; // don't simplify - b.write_en = %[2:3] & (lt.out | gt.out) & %[1:5] ? 1'd1; // %[1:5] is redundant - c.write_en = %[2:5] & (%[5:7] | lt.out) & %[3:7] & %[4:10] ? 1'd1; // %[5:7] shouldn't change, but can simplify rest to %[4:5] - d.write_en = %[2:5] & %[6:9] ? 1'd1; // assignment is false - e.write_en = %[0:10] & lt.out ? 1'd1; // no static timing necesary, since %[0:10] is same as group - a.in = 32'd1; - b.in = 32'd2; - c.in = 32'd3; - d.in = 32'd4; + a.write_en = (%[2:3] | lt.out) & %[1:5] ? 1'd1; // don't simplify + // b.write_en = %[2:3] & (lt.out | gt.out) & %[1:5] ? 1'd1; // %[1:5] is redundant + // c.write_en = %[2:5] & (%[5:7] | lt.out) & %[3:7] & %[4:10] ? 1'd1; // %[5:7] shouldn't change, but can simplify rest to %[4:5] + // d.write_en = %[2:5] & %[6:9] ? 1'd1; // assignment is false + // e.write_en = %[0:10] & lt.out ? 1'd1; // no static timing necesary, since %[0:10] is same as group + // a.in = 32'd1; + // b.in = 32'd2; + // c.in = 32'd3; + // d.in = 32'd4; } } From 25f2297ac3f5141d08fd32d16d4c2b9b7b73ce61 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 21:06:31 -0500 Subject: [PATCH 6/8] small change --- tests/passes/simplify-static-guards/basic.futil | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/passes/simplify-static-guards/basic.futil b/tests/passes/simplify-static-guards/basic.futil index 5108bd5a6..4351d57eb 100644 --- a/tests/passes/simplify-static-guards/basic.futil +++ b/tests/passes/simplify-static-guards/basic.futil @@ -15,14 +15,14 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { wires { static<10> group my_group { a.write_en = (%[2:3] | lt.out) & %[1:5] ? 1'd1; // don't simplify - // b.write_en = %[2:3] & (lt.out | gt.out) & %[1:5] ? 1'd1; // %[1:5] is redundant - // c.write_en = %[2:5] & (%[5:7] | lt.out) & %[3:7] & %[4:10] ? 1'd1; // %[5:7] shouldn't change, but can simplify rest to %[4:5] - // d.write_en = %[2:5] & %[6:9] ? 1'd1; // assignment is false - // e.write_en = %[0:10] & lt.out ? 1'd1; // no static timing necesary, since %[0:10] is same as group - // a.in = 32'd1; - // b.in = 32'd2; - // c.in = 32'd3; - // d.in = 32'd4; + b.write_en = %[2:3] & (lt.out | gt.out) & %[1:5] ? 1'd1; // %[1:5] is redundant + c.write_en = %[2:5] & (%[5:7] | lt.out) & %[3:7] & %[4:10] ? 1'd1; // %[5:7] shouldn't change, but can simplify rest to %[4:5] + d.write_en = %[2:5] & %[6:9] ? 1'd1; // assignment is false + e.write_en = %[0:10] & lt.out ? 1'd1; // no static timing necesary, since %[0:10] is same as group + a.in = 32'd1; + b.in = 32'd2; + c.in = 32'd3; + d.in = 32'd4; } } From f0db9a5b887723fa066b2993f96b37189eec01de Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 21:22:41 -0500 Subject: [PATCH 7/8] rewrite test --- examples/futil/dot-product.expect | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/futil/dot-product.expect b/examples/futil/dot-product.expect index c5f0d0db3..4021912c6 100644 --- a/examples/futil/dot-product.expect +++ b/examples/futil/dot-product.expect @@ -99,7 +99,7 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { B0.clk = clk; B0.addr0 = fsm.out == 4'd0 & early_reset_static_seq_go.out ? i0.out; B0.reset = reset; - B_read0_0.write_en = (fsm.out == 4'd0 & fsm.out < 4'd7 | fsm.out == 4'd5 & fsm.out < 4'd7) & early_reset_static_seq_go.out ? 1'd1; + B_read0_0.write_en = (fsm.out == 4'd0 | fsm.out == 4'd5) & early_reset_static_seq_go.out ? 1'd1; B_read0_0.clk = clk; B_read0_0.reset = reset; B_read0_0.in = fsm.out == 4'd0 & early_reset_static_seq_go.out ? B0.read_data; @@ -109,7 +109,7 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { early_reset_static_seq_done.in = ud0.out; tdcc_done.in = fsm0.out == 2'd3 ? 1'd1; while_wrapper_early_reset_static_seq_done.in = !comb_reg.out & fsm.out == 4'd0 ? 1'd1; - A_read0_0.write_en = (fsm.out == 4'd0 & fsm.out < 4'd7 | fsm.out == 4'd4 & fsm.out < 4'd7) & early_reset_static_seq_go.out ? 1'd1; + A_read0_0.write_en = (fsm.out == 4'd0 | fsm.out == 4'd4) & early_reset_static_seq_go.out ? 1'd1; A_read0_0.clk = clk; A_read0_0.reset = reset; A_read0_0.in = fsm.out == 4'd0 & early_reset_static_seq_go.out ? A0.read_data; From 0ea4e9a0973fd05a2a25ba0f47c252309b13f4f1 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sun, 19 Nov 2023 23:31:34 -0500 Subject: [PATCH 8/8] default to none --- calyx-opt/src/passes/static_promotion.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/calyx-opt/src/passes/static_promotion.rs b/calyx-opt/src/passes/static_promotion.rs index 30e48737f..960218cf6 100644 --- a/calyx-opt/src/passes/static_promotion.rs +++ b/calyx-opt/src/passes/static_promotion.rs @@ -236,22 +236,12 @@ impl StaticPromotion { } None }); - // If they don't give a cycle_limit_str, then we set it to the Default. - // If they explicitly say "None" or "none", hten we set it to None. - // Makes things a bit confusing. - let cycle_limit = if cycle_limit_str.is_none() { - Some(33554432) - } else if cycle_limit_str.unwrap() == "None" - || cycle_limit_str.unwrap() == "none" + + // Default to None. There may be a more idiomatic way to do this. + let cycle_limit = match cycle_limit_str.unwrap_or("None").parse::() { - None - } else { - Some( - cycle_limit_str - .unwrap_or("33554432") - .parse::() - .unwrap_or(33554432), - ) + Ok(n) => Some(n), + Err(_) => None, }; // searching for "-x static-promotion:threshold=1" and getting back "1"