From 1bb319349386d442b8d3482261912d4a37f01c13 Mon Sep 17 00:00:00 2001 From: calebmkim Date: Wed, 8 Nov 2023 22:33:14 -0500 Subject: [PATCH 1/9] modify pass ordering --- calyx-opt/src/default_passes.rs | 5 +- z.futil | 418 ++++++++++++++++++++++++++++++++ 2 files changed, 421 insertions(+), 2 deletions(-) create mode 100644 z.futil diff --git a/calyx-opt/src/default_passes.rs b/calyx-opt/src/default_passes.rs index 940d75fe3..01e5edd05 100644 --- a/calyx-opt/src/default_passes.rs +++ b/calyx-opt/src/default_passes.rs @@ -90,15 +90,16 @@ impl PassManager { ComponentInliner, CombProp, DeadCellRemoval, // Clean up dead wires left by CombProp - CellShare, // LiveRangeAnalaysis should handle comb groups SimplifyWithControl, // Must run before compile-invoke CompileInvoke, // creates dead comb groups AttributePromotion, StaticPromotion, ScheduleCompaction, + CollapseControl, + CellShare, // LiveRangeAnalaysis should handle comb groups CompileRepeat, DeadGroupRemoval, // Since previous passes potentially create dead groups - CollapseControl, + CollapseControl ] ); register_alias!( diff --git a/z.futil b/z.futil new file mode 100644 index 000000000..67be88d45 --- /dev/null +++ b/z.futil @@ -0,0 +1,418 @@ +extern "/home/cmk265/.calyx/primitives/memories.sv" { + primitive seq_mem_d1[WIDTH, SIZE, IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); + primitive seq_mem_d2[WIDTH, D0_SIZE, D1_SIZE, D0_IDX_SIZE, D1_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); + primitive seq_mem_d3[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @data addr2: D2_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); + primitive seq_mem_d4[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D3_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE, D3_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @data addr2: D2_IDX_SIZE, @data addr3: D3_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); +} +extern "/home/cmk265/.calyx/primitives/binary_operators.sv" { + comb primitive std_fp_add<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_fp_sub<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + primitive std_fp_mult_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); + primitive std_fp_div_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_remainder: WIDTH, @stable out_quotient: WIDTH, @done done: 1); + comb primitive std_fp_gt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_fp_sadd<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_fp_ssub<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + primitive std_fp_smult_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); + primitive std_fp_sdiv_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_remainder: WIDTH, @stable out_quotient: WIDTH, @done done: 1); + comb primitive std_fp_sgt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_fp_slt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + primitive std_mult_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); + primitive std_div_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_quotient: WIDTH, @stable out_remainder: WIDTH, @done done: 1); + comb primitive std_sadd<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_ssub<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + primitive std_smult_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); + primitive std_sdiv_pipe[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (out_quotient: WIDTH, out_remainder: WIDTH, @done done: 1); + comb primitive std_sgt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_slt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_seq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_sneq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_sge<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_sle<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_slsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_srsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_signext<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); +} +extern "/home/cmk265/.calyx/primitives/core.sv" { + comb primitive std_slice<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); + comb primitive std_pad<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); + comb primitive std_cat<"share"=1>[LEFT_WIDTH, RIGHT_WIDTH, OUT_WIDTH](@data left: LEFT_WIDTH, @data right: RIGHT_WIDTH) -> (out: OUT_WIDTH); + comb primitive std_not<"share"=1>[WIDTH](@data in: WIDTH) -> (out: WIDTH); + comb primitive std_and<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_or<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_xor<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_sub<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_gt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_lt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_eq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_neq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_ge<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_le<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); + comb primitive std_lsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_rsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); + comb primitive std_mux<"share"=1>[WIDTH](@data cond: 1, @data tru: WIDTH, @data fal: WIDTH) -> (out: WIDTH); + primitive std_mem_d1[WIDTH, SIZE, IDX_SIZE](@read_together addr0: IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); + primitive std_mem_d2[WIDTH, D0_SIZE, D1_SIZE, D0_IDX_SIZE, D1_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); + primitive std_mem_d3[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @read_together @write_together(2) addr2: D2_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); + primitive std_mem_d4[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D3_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE, D3_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @read_together @write_together(2) addr2: D2_IDX_SIZE, @read_together @write_together(2) addr3: D3_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1) -> (@read_together read_data: WIDTH, @done done: 1); +} +primitive undef<"share"=1>[WIDTH]() -> (out: WIDTH) { + assign out = 'x; +} +comb primitive std_const<"share"=1>[WIDTH, VALUE]() -> (out: WIDTH) { + assign out = VALUE; +} +comb primitive std_wire<"share"=1>[WIDTH](@data in: WIDTH) -> (out: WIDTH) { + assign out = in; +} +comb primitive std_add<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH) { + assign out = left + right; +} +primitive std_reg<"state_share"=1>[WIDTH](@write_together @data in: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@stable out: WIDTH, @done done: 1) { + always_ff @(posedge clk) begin + if (reset) begin + out <= 0; + done <= 0; + end else if (write_en) begin + out <= in; + done <= 1'd1; + end else done <= 1'd0; + end +} +static<2400881> component main<"toplevel"=1>(@clk clk: 1, @reset reset: 1, @go go: 1) -> (@done done: 1) { + cells { + @data std_slice_11 = std_slice(32, 9); + @data std_slice_10 = std_slice(32, 9); + @data std_slice_9 = std_slice(32, 9); + @data std_slice_8 = std_slice(32, 9); + @data std_slice_7 = std_slice(32, 9); + @data std_slice_6 = std_slice(32, 9); + @data std_slice_5 = std_slice(32, 9); + @data std_slice_4 = std_slice(32, 9); + @data std_slice_3 = std_slice(32, 9); + @data std_slice_2 = std_slice(32, 9); + @data std_slice_1 = std_slice(32, 9); + @data std_slice_0 = std_slice(32, 9); + @data std_add_5 = std_add(32); + @data std_add_4 = std_add(32); + @data std_add_3 = std_add(32); + @data muli_1_reg = std_reg(32); + @data std_mult_pipe_1 = std_mult_pipe(32); + @data load_4_reg = std_reg(32); + @data load_3_reg = std_reg(32); + @data load_2_reg = std_reg(32); + @data std_add_2 = std_add(32); + @data std_add_1 = std_add(32); + @data muli_0_reg = std_reg(32); + @data std_mult_pipe_0 = std_mult_pipe(32); + @data load_1_reg = std_reg(32); + @data load_0_reg = std_reg(32); + @data std_add_0 = std_add(32); + @external @data mem_3 = seq_mem_d2(32, 390, 410, 9, 9); + @external @data mem_2 = seq_mem_d1(32, 410, 9); + @external @data mem_1 = seq_mem_d1(32, 410, 9); + @external @data mem_0 = seq_mem_d1(32, 390, 9); + @data for_3_induction_var_reg = std_reg(32); + @data for_2_induction_var_reg = std_reg(32); + @data for_1_induction_var_reg = std_reg(32); + @data for_0_induction_var_reg = std_reg(32); + @generated comb_reg = std_reg(32); + @generated comb_reg0 = std_reg(32); + @generated comb_reg1 = std_reg(32); + @generated comb_reg2 = std_reg(32); + } + wires { + static<1> group bb0_00 { + std_slice_9.in = muli_1_reg.out; + mem_1.addr0 = std_slice_9.out; + mem_1.write_data = 32'd0; + mem_1.write_en = 1'd1; + } + static<1> group invoke100 { + muli_1_reg.write_en = 1'd1; + muli_1_reg.in = std_add_5.out; + std_add_5.left = muli_1_reg.out; + std_add_5.right = 32'd1; + } + static<1> group beg_spl_bb0_20 { + mem_0.addr0 = std_slice_9.out; + mem_0.read_en = 1'd1; + std_slice_9.in = for_3_induction_var_reg.out; + } + static<1> group invoke40 { + load_0_reg.write_en = 1'd1; + load_0_reg.in = mem_0.read_data; + } + static<1> group beg_spl_bb0_30 { + mem_3.addr0 = std_slice_8.out; + mem_3.addr1 = std_slice_7.out; + mem_3.read_en = 1'd1; + std_slice_8.in = for_3_induction_var_reg.out; + std_slice_7.in = for_1_induction_var_reg.out; + } + static<1> group invoke50 { + load_1_reg.write_en = 1'd1; + load_1_reg.in = mem_3.read_data; + } + static<3> group invoke60 { + std_mult_pipe_0.go = 1'd1; + std_mult_pipe_0.left = load_1_reg.out; + std_mult_pipe_0.right = mem_2.read_data; + } + static<1> group invoke70 { + muli_1_reg.write_en = 1'd1; + muli_1_reg.in = std_mult_pipe_0.out; + } + static<1> group bb0_40 { + std_slice_6.in = for_1_induction_var_reg.out; + mem_2.addr0 = std_slice_6.out; + mem_2.read_en = 1'd1; + } + static<1> group bb0_70 { + std_slice_9.in = for_3_induction_var_reg.out; + mem_0.addr0 = std_slice_9.out; + mem_0.write_data = std_add_5.out; + mem_0.write_en = 1'd1; + std_add_5.left = load_0_reg.out; + std_add_5.right = std_mult_pipe_0.out; + } + static<1> group invoke80 { + for_1_induction_var_reg.write_en = 1'd1; + for_1_induction_var_reg.in = std_add_5.out; + std_add_5.left = for_1_induction_var_reg.out; + std_add_5.right = 32'd1; + } + static<1> group beg_spl_bb0_80 { + mem_0.addr0 = std_slice_9.out; + mem_0.read_en = 1'd1; + std_slice_9.in = for_3_induction_var_reg.out; + } + static<1> group invoke90 { + load_2_reg.write_en = 1'd1; + load_2_reg.in = mem_0.read_data; + } + static<1> group beg_spl_bb0_90 { + mem_1.addr0 = std_slice_9.out; + mem_1.read_en = 1'd1; + std_slice_9.in = for_2_induction_var_reg.out; + } + static<1> group invoke110 { + load_3_reg.write_en = 1'd1; + load_3_reg.in = mem_1.read_data; + } + static<1> group beg_spl_bb0_100 { + mem_3.addr0 = std_slice_8.out; + mem_3.addr1 = std_slice_7.out; + mem_3.read_en = 1'd1; + std_slice_8.in = for_3_induction_var_reg.out; + std_slice_7.in = for_2_induction_var_reg.out; + } + static<1> group invoke120 { + load_4_reg.write_en = 1'd1; + load_4_reg.in = mem_3.read_data; + } + static<3> group invoke130 { + std_mult_pipe_1.go = 1'd1; + std_mult_pipe_1.left = load_4_reg.out; + std_mult_pipe_1.right = load_2_reg.out; + } + static<1> group invoke140 { + muli_1_reg.write_en = 1'd1; + muli_1_reg.in = std_mult_pipe_1.out; + } + static<1> group bb0_130 { + std_slice_9.in = for_2_induction_var_reg.out; + mem_1.addr0 = std_slice_9.out; + mem_1.write_data = std_add_5.out; + mem_1.write_en = 1'd1; + std_add_5.left = load_3_reg.out; + std_add_5.right = std_mult_pipe_1.out; + } + static<1> group invoke150 { + for_2_induction_var_reg.write_en = 1'd1; + for_2_induction_var_reg.in = std_add_5.out; + std_add_5.left = for_2_induction_var_reg.out; + std_add_5.right = 32'd1; + } + static<1> group bb0_100 { + std_slice_9.in = for_3_induction_var_reg.out; + mem_0.addr0 = std_slice_9.out; + mem_0.write_data = 32'd0; + mem_0.write_en = 1'd1; + } + static<1> group invoke30 { + for_1_induction_var_reg.write_en = 1'd1; + for_1_induction_var_reg.in = 32'd0; + } + static<1> group invoke101 { + for_2_induction_var_reg.write_en = 1'd1; + for_2_induction_var_reg.in = 32'd0; + } + static<1> group invoke160 { + for_3_induction_var_reg.write_en = 1'd1; + for_3_induction_var_reg.in = std_add_5.out; + std_add_5.left = for_3_induction_var_reg.out; + std_add_5.right = 32'd1; + } + static<1> group invoke00 { + muli_1_reg.write_en = 1'd1; + muli_1_reg.in = 32'd0; + } + static<1> group invoke20 { + for_3_induction_var_reg.write_en = 1'd1; + for_3_induction_var_reg.in = 32'd0; + } + static<1> group no-op { + } + static<1> group no-op0 { + } + static<1> group no-op1 { + } + static<3> group no-op2 { + } + static<2> group no-op3 { + } + static<2> group no-op4 { + } + static<6> group no-op5 { + } + static<1> group no-op6 { + } + static<1> group no-op7 { + } + static<1> group no-op8 { + } + static<3> group no-op9 { + } + static<2> group no-op10 { + } + static<6> group no-op11 { + } + static<7> group no-op12 { + } + static<1> group no-op13 { + } + static<2871> group no-op14 { + } + static<2873> group no-op15 { + } + static<6153> group no-op16 { + } + static<1> group no-op17 { + } + static<821> group no-op18 { + } + } + control { + @NODE_ID(0) static<2400881> par { + @NODE_ID invoke20; + @NODE_ID(2) invoke00; + @NODE_ID(3) static<821> seq { + @NODE_ID(4) no-op17; + @NODE_ID(5) static repeat 410 { + @NODE_ID(6) static<2> par { + @NODE_ID(7) bb0_00; + @NODE_ID(8) static<2> seq { + @NODE_ID(9) no-op; + @NODE_ID(10) invoke100; + } + } + } + } + @NODE_ID(11) static<2400881> seq { + @NODE_ID(12) no-op18; + @NODE_ID(13) static repeat 390 { + @NODE_ID(14) static<6154> par { + @NODE_ID(15) invoke101; + @NODE_ID(16) invoke30; + @NODE_ID(17) bb0_100; + @NODE_ID(18) static<2871> seq { + @NODE_ID(19) no-op13; + @NODE_ID(20) static repeat 410 { + @NODE_ID(21) static<7> par { + @NODE_ID(22) bb0_40; + @NODE_ID(23) beg_spl_bb0_30; + @NODE_ID(24) static<2> seq { + @NODE_ID(25) no-op1; + @NODE_ID(26) invoke50; + } + @NODE_ID(27) static<3> seq { + @NODE_ID(28) no-op3; + @NODE_ID(29) invoke80; + } + @NODE_ID(30) static<6> seq { + @NODE_ID(31) no-op4; + @NODE_ID(32) static<4> par { + @NODE_ID(33) invoke60; + @NODE_ID(34) static<4> seq { + @NODE_ID(35) no-op2; + @NODE_ID(36) invoke70; + } + } + } + @NODE_ID(37) beg_spl_bb0_20; + @NODE_ID(38) static<2> seq { + @NODE_ID(39) no-op0; + @NODE_ID(40) invoke40; + } + @NODE_ID(41) static<7> seq { + @NODE_ID(42) no-op5; + @NODE_ID(43) bb0_70; + } + } + } + } + @NODE_ID(44) static<2873> seq { + @NODE_ID(45) no-op14; + @NODE_ID(46) static<2> par { + @NODE_ID(47) beg_spl_bb0_80; + @NODE_ID(48) static<2> seq { + @NODE_ID(49) no-op6; + @NODE_ID(50) invoke90; + } + } + } + @NODE_ID(51) static<6153> seq { + @NODE_ID(52) no-op15; + @NODE_ID(53) static repeat 410 { + @NODE_ID(54) static<8> par { + @NODE_ID(55) beg_spl_bb0_100; + @NODE_ID(56) static<2> seq { + @NODE_ID(57) no-op8; + @NODE_ID(58) invoke120; + } + @NODE_ID(59) static<6> seq { + @NODE_ID(60) no-op10; + @NODE_ID(61) static<4> par { + @NODE_ID(62) invoke130; + @NODE_ID(63) static<4> seq { + @NODE_ID(64) no-op9; + @NODE_ID(65) invoke140; + } + } + } + @NODE_ID(66) beg_spl_bb0_90; + @NODE_ID(67) static<2> seq { + @NODE_ID(68) no-op7; + @NODE_ID(69) invoke110; + } + @NODE_ID(70) static<7> seq { + @NODE_ID(71) no-op11; + @NODE_ID(72) bb0_130; + } + @NODE_ID(73) static<8> seq { + @NODE_ID(74) no-op12; + @NODE_ID(75) invoke150; + } + } + } + } + @NODE_ID(76) static<6154> seq { + @NODE_ID(77) no-op16; + @NODE_ID(78) invoke160; + } + } + } + } + } + } +} From e1af72fa3918c2ce9ee1f429c98db83d9bc9d8ac Mon Sep 17 00:00:00 2001 From: Caleb Date: Wed, 8 Nov 2023 23:41:00 -0500 Subject: [PATCH 2/9] more compact compaction --- calyx-opt/src/passes/schedule_compaction.rs | 67 +++++++++++++------ .../schedule-compaction.expect | 14 +--- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index 9b873eee4..a55a5a524 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -4,6 +4,7 @@ use crate::{ traversal::{Named, Visitor}, }; use calyx_ir as ir; +use itertools::Itertools; use petgraph::{algo, graph::NodeIndex}; use std::collections::HashMap; @@ -58,8 +59,8 @@ impl Visitor for ScheduleCompaction { if let Ok(order) = algo::toposort(&total_order, None) { let mut total_time: u64 = 0; - let mut stmts: Vec = Vec::new(); + // First we build the schedule for i in order { let mut start: u64 = 0; for node in dependency.get(&i).unwrap() { @@ -69,33 +70,54 @@ impl Visitor for ScheduleCompaction { } } schedule.insert(i, start); + total_time = std::cmp::max(start + latency_map[&i], total_time); + } + + let mut sorted_schedule: Vec<(NodeIndex, u64)> = + schedule.into_iter().collect(); + sorted_schedule.sort_by(|(_, v1), (_, v2)| v1.cmp(v2)); + // Par Threads, where each entry is (thread, thread_latency) + let mut par_threads: Vec<(Vec, u64)> = + Vec::new(); + // Now we build the ordering to minimize the number of par threads + 'outer: for (i, start) in sorted_schedule { let control = total_order[i].take().unwrap(); - let mut st_seq_stmts: Vec = Vec::new(); - if start > 0 { - let no_op = builder.add_static_group("no-op", start); - - st_seq_stmts.push(ir::StaticControl::Enable( - ir::StaticEnable { - group: no_op, - attributes: ir::Attributes::default(), - }, - )); - } - if start + latency_map[&i] > total_time { - total_time = start + latency_map[&i]; + for (thread, thread_latency) in par_threads.iter_mut() { + if *thread_latency <= start { + if *thread_latency < start { + // Might need a no-op group to align schedule + let no_op = builder.add_static_group( + "no-op", + start - *thread_latency, + ); + thread.push(ir::StaticControl::Enable( + ir::StaticEnable { + group: no_op, + attributes: ir::Attributes::default(), + }, + )); + } + thread.push(control); + *thread_latency += latency_map[&i]; + continue 'outer; + } } - - st_seq_stmts.push(control); - stmts.push(ir::StaticControl::Seq(ir::StaticSeq { - stmts: st_seq_stmts, - attributes: ir::Attributes::default(), - latency: start + latency_map[&i], - })); + par_threads.push((vec![control], latency_map[&i])); } + let mut par_control_threads: Vec = Vec::new(); + for (thread, thread_latency) in par_threads { + par_control_threads.push(ir::StaticControl::Seq( + ir::StaticSeq { + stmts: thread, + attributes: ir::Attributes::default(), + latency: thread_latency, + }, + )); + } let s_par = ir::StaticControl::Par(ir::StaticPar { - stmts, + stmts: par_control_threads, attributes: ir::Attributes::default(), latency: total_time, }); @@ -105,6 +127,7 @@ impl Visitor for ScheduleCompaction { "Error when producing topo sort. Dependency graph has a cycle." ); } + Ok(Action::Continue) } diff --git a/tests/passes/schedule-compaction/schedule-compaction.expect b/tests/passes/schedule-compaction/schedule-compaction.expect index bf7291c5c..855907b6b 100644 --- a/tests/passes/schedule-compaction/schedule-compaction.expect +++ b/tests/passes/schedule-compaction/schedule-compaction.expect @@ -26,25 +26,15 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { d_reg.write_en = %0 ? 1'd1; d_reg.in = a_reg.out; } - static<1> group no-op { - } - static<10> group no-op0 { - } } control { static<11> par { - static<10> seq { - C; - } - static<1> seq { - A; - } static<11> seq { - no-op; + A; D; } static<11> seq { - no-op0; + C; B; } } From 830cbb8ddec6c1984cedab5e636e8bfea8f02af9 Mon Sep 17 00:00:00 2001 From: Caleb Date: Wed, 8 Nov 2023 23:43:49 -0500 Subject: [PATCH 3/9] another small change --- calyx-opt/src/passes/schedule_compaction.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index a55a5a524..3bab8741a 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -116,12 +116,19 @@ impl Visitor for ScheduleCompaction { }, )); } - let s_par = ir::StaticControl::Par(ir::StaticPar { - stmts: par_control_threads, - attributes: ir::Attributes::default(), - latency: total_time, - }); - return Ok(Action::static_change(s_par)); + + if par_control_threads.len() == 1 { + return Ok(Action::static_change( + Vec::pop(&mut par_control_threads).unwrap(), + )); + } else { + let s_par = ir::StaticControl::Par(ir::StaticPar { + stmts: par_control_threads, + attributes: ir::Attributes::default(), + latency: total_time, + }); + return Ok(Action::static_change(s_par)); + } } else { println!( "Error when producing topo sort. Dependency graph has a cycle." From 10ebdc0a1101f33a5184e088abbb6368fb3de889 Mon Sep 17 00:00:00 2001 From: Caleb Date: Thu, 9 Nov 2023 00:29:03 -0500 Subject: [PATCH 4/9] dumb mistake --- calyx-opt/src/passes/schedule_compaction.rs | 14 +- z.futil | 418 -------------------- 2 files changed, 7 insertions(+), 425 deletions(-) delete mode 100644 z.futil diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index 3bab8741a..952cc6339 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -64,10 +64,8 @@ impl Visitor for ScheduleCompaction { for i in order { let mut start: u64 = 0; for node in dependency.get(&i).unwrap() { - let allow_start = schedule[node] + latency_map[node]; - if allow_start > start { - start = allow_start; - } + start = + std::cmp::max(start, schedule[node] + latency_map[node]) } schedule.insert(i, start); total_time = std::cmp::max(start + latency_map[&i], total_time); @@ -97,6 +95,7 @@ impl Visitor for ScheduleCompaction { attributes: ir::Attributes::default(), }, )); + *thread_latency = start; } thread.push(control); *thread_latency += latency_map[&i]; @@ -116,11 +115,12 @@ impl Visitor for ScheduleCompaction { }, )); } + let max = par_control_threads.iter().map(|c| c.get_latency()).max(); + assert!(max.unwrap() == total_time, "messed up"); if par_control_threads.len() == 1 { - return Ok(Action::static_change( - Vec::pop(&mut par_control_threads).unwrap(), - )); + let c = Vec::pop(&mut par_control_threads).unwrap(); + return Ok(Action::static_change(c)); } else { let s_par = ir::StaticControl::Par(ir::StaticPar { stmts: par_control_threads, diff --git a/z.futil b/z.futil deleted file mode 100644 index 67be88d45..000000000 --- a/z.futil +++ /dev/null @@ -1,418 +0,0 @@ -extern "/home/cmk265/.calyx/primitives/memories.sv" { - primitive seq_mem_d1[WIDTH, SIZE, IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); - primitive seq_mem_d2[WIDTH, D0_SIZE, D1_SIZE, D0_IDX_SIZE, D1_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); - primitive seq_mem_d3[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @data addr2: D2_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); - primitive seq_mem_d4[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D3_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE, D3_IDX_SIZE](@clk clk: 1, @reset reset: 1, @data addr0: D0_IDX_SIZE, @data addr1: D1_IDX_SIZE, @data addr2: D2_IDX_SIZE, @data addr3: D3_IDX_SIZE, @write_together @static @go write_en: 1, @write_together @data write_data: WIDTH, @static @go(2) read_en: 1) -> (@stable read_data: WIDTH, @done write_done: 1, @done(2) read_done: 1); -} -extern "/home/cmk265/.calyx/primitives/binary_operators.sv" { - comb primitive std_fp_add<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_fp_sub<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - primitive std_fp_mult_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); - primitive std_fp_div_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_remainder: WIDTH, @stable out_quotient: WIDTH, @done done: 1); - comb primitive std_fp_gt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_fp_sadd<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_fp_ssub<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - primitive std_fp_smult_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); - primitive std_fp_sdiv_pipe<"state_share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_remainder: WIDTH, @stable out_quotient: WIDTH, @done done: 1); - comb primitive std_fp_sgt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_fp_slt<"share"=1>[WIDTH, INT_WIDTH, FRAC_WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - primitive std_mult_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); - primitive std_div_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out_quotient: WIDTH, @stable out_remainder: WIDTH, @done done: 1); - comb primitive std_sadd<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_ssub<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - primitive std_smult_pipe<"state_share"=1>[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @static(3) @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (@stable out: WIDTH, @done done: 1); - primitive std_sdiv_pipe[WIDTH](@clk clk: 1, @reset reset: 1, @write_together @go go: 1, @write_together @data left: WIDTH, @write_together @data right: WIDTH) -> (out_quotient: WIDTH, out_remainder: WIDTH, @done done: 1); - comb primitive std_sgt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_slt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_seq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_sneq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_sge<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_sle<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_slsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_srsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_signext<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); -} -extern "/home/cmk265/.calyx/primitives/core.sv" { - comb primitive std_slice<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); - comb primitive std_pad<"share"=1>[IN_WIDTH, OUT_WIDTH](@data in: IN_WIDTH) -> (out: OUT_WIDTH); - comb primitive std_cat<"share"=1>[LEFT_WIDTH, RIGHT_WIDTH, OUT_WIDTH](@data left: LEFT_WIDTH, @data right: RIGHT_WIDTH) -> (out: OUT_WIDTH); - comb primitive std_not<"share"=1>[WIDTH](@data in: WIDTH) -> (out: WIDTH); - comb primitive std_and<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_or<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_xor<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_sub<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_gt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_lt<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_eq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_neq<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_ge<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_le<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: 1); - comb primitive std_lsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_rsh<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH); - comb primitive std_mux<"share"=1>[WIDTH](@data cond: 1, @data tru: WIDTH, @data fal: WIDTH) -> (out: WIDTH); - primitive std_mem_d1[WIDTH, SIZE, IDX_SIZE](@read_together addr0: IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); - primitive std_mem_d2[WIDTH, D0_SIZE, D1_SIZE, D0_IDX_SIZE, D1_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); - primitive std_mem_d3[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @read_together @write_together(2) addr2: D2_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@read_together read_data: WIDTH, @done done: 1); - primitive std_mem_d4[WIDTH, D0_SIZE, D1_SIZE, D2_SIZE, D3_SIZE, D0_IDX_SIZE, D1_IDX_SIZE, D2_IDX_SIZE, D3_IDX_SIZE](@read_together @write_together(2) addr0: D0_IDX_SIZE, @read_together @write_together(2) addr1: D1_IDX_SIZE, @read_together @write_together(2) addr2: D2_IDX_SIZE, @read_together @write_together(2) addr3: D3_IDX_SIZE, @write_together @data write_data: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1) -> (@read_together read_data: WIDTH, @done done: 1); -} -primitive undef<"share"=1>[WIDTH]() -> (out: WIDTH) { - assign out = 'x; -} -comb primitive std_const<"share"=1>[WIDTH, VALUE]() -> (out: WIDTH) { - assign out = VALUE; -} -comb primitive std_wire<"share"=1>[WIDTH](@data in: WIDTH) -> (out: WIDTH) { - assign out = in; -} -comb primitive std_add<"share"=1>[WIDTH](@data left: WIDTH, @data right: WIDTH) -> (out: WIDTH) { - assign out = left + right; -} -primitive std_reg<"state_share"=1>[WIDTH](@write_together @data in: WIDTH, @write_together @static @go write_en: 1, @clk clk: 1, @reset reset: 1) -> (@stable out: WIDTH, @done done: 1) { - always_ff @(posedge clk) begin - if (reset) begin - out <= 0; - done <= 0; - end else if (write_en) begin - out <= in; - done <= 1'd1; - end else done <= 1'd0; - end -} -static<2400881> component main<"toplevel"=1>(@clk clk: 1, @reset reset: 1, @go go: 1) -> (@done done: 1) { - cells { - @data std_slice_11 = std_slice(32, 9); - @data std_slice_10 = std_slice(32, 9); - @data std_slice_9 = std_slice(32, 9); - @data std_slice_8 = std_slice(32, 9); - @data std_slice_7 = std_slice(32, 9); - @data std_slice_6 = std_slice(32, 9); - @data std_slice_5 = std_slice(32, 9); - @data std_slice_4 = std_slice(32, 9); - @data std_slice_3 = std_slice(32, 9); - @data std_slice_2 = std_slice(32, 9); - @data std_slice_1 = std_slice(32, 9); - @data std_slice_0 = std_slice(32, 9); - @data std_add_5 = std_add(32); - @data std_add_4 = std_add(32); - @data std_add_3 = std_add(32); - @data muli_1_reg = std_reg(32); - @data std_mult_pipe_1 = std_mult_pipe(32); - @data load_4_reg = std_reg(32); - @data load_3_reg = std_reg(32); - @data load_2_reg = std_reg(32); - @data std_add_2 = std_add(32); - @data std_add_1 = std_add(32); - @data muli_0_reg = std_reg(32); - @data std_mult_pipe_0 = std_mult_pipe(32); - @data load_1_reg = std_reg(32); - @data load_0_reg = std_reg(32); - @data std_add_0 = std_add(32); - @external @data mem_3 = seq_mem_d2(32, 390, 410, 9, 9); - @external @data mem_2 = seq_mem_d1(32, 410, 9); - @external @data mem_1 = seq_mem_d1(32, 410, 9); - @external @data mem_0 = seq_mem_d1(32, 390, 9); - @data for_3_induction_var_reg = std_reg(32); - @data for_2_induction_var_reg = std_reg(32); - @data for_1_induction_var_reg = std_reg(32); - @data for_0_induction_var_reg = std_reg(32); - @generated comb_reg = std_reg(32); - @generated comb_reg0 = std_reg(32); - @generated comb_reg1 = std_reg(32); - @generated comb_reg2 = std_reg(32); - } - wires { - static<1> group bb0_00 { - std_slice_9.in = muli_1_reg.out; - mem_1.addr0 = std_slice_9.out; - mem_1.write_data = 32'd0; - mem_1.write_en = 1'd1; - } - static<1> group invoke100 { - muli_1_reg.write_en = 1'd1; - muli_1_reg.in = std_add_5.out; - std_add_5.left = muli_1_reg.out; - std_add_5.right = 32'd1; - } - static<1> group beg_spl_bb0_20 { - mem_0.addr0 = std_slice_9.out; - mem_0.read_en = 1'd1; - std_slice_9.in = for_3_induction_var_reg.out; - } - static<1> group invoke40 { - load_0_reg.write_en = 1'd1; - load_0_reg.in = mem_0.read_data; - } - static<1> group beg_spl_bb0_30 { - mem_3.addr0 = std_slice_8.out; - mem_3.addr1 = std_slice_7.out; - mem_3.read_en = 1'd1; - std_slice_8.in = for_3_induction_var_reg.out; - std_slice_7.in = for_1_induction_var_reg.out; - } - static<1> group invoke50 { - load_1_reg.write_en = 1'd1; - load_1_reg.in = mem_3.read_data; - } - static<3> group invoke60 { - std_mult_pipe_0.go = 1'd1; - std_mult_pipe_0.left = load_1_reg.out; - std_mult_pipe_0.right = mem_2.read_data; - } - static<1> group invoke70 { - muli_1_reg.write_en = 1'd1; - muli_1_reg.in = std_mult_pipe_0.out; - } - static<1> group bb0_40 { - std_slice_6.in = for_1_induction_var_reg.out; - mem_2.addr0 = std_slice_6.out; - mem_2.read_en = 1'd1; - } - static<1> group bb0_70 { - std_slice_9.in = for_3_induction_var_reg.out; - mem_0.addr0 = std_slice_9.out; - mem_0.write_data = std_add_5.out; - mem_0.write_en = 1'd1; - std_add_5.left = load_0_reg.out; - std_add_5.right = std_mult_pipe_0.out; - } - static<1> group invoke80 { - for_1_induction_var_reg.write_en = 1'd1; - for_1_induction_var_reg.in = std_add_5.out; - std_add_5.left = for_1_induction_var_reg.out; - std_add_5.right = 32'd1; - } - static<1> group beg_spl_bb0_80 { - mem_0.addr0 = std_slice_9.out; - mem_0.read_en = 1'd1; - std_slice_9.in = for_3_induction_var_reg.out; - } - static<1> group invoke90 { - load_2_reg.write_en = 1'd1; - load_2_reg.in = mem_0.read_data; - } - static<1> group beg_spl_bb0_90 { - mem_1.addr0 = std_slice_9.out; - mem_1.read_en = 1'd1; - std_slice_9.in = for_2_induction_var_reg.out; - } - static<1> group invoke110 { - load_3_reg.write_en = 1'd1; - load_3_reg.in = mem_1.read_data; - } - static<1> group beg_spl_bb0_100 { - mem_3.addr0 = std_slice_8.out; - mem_3.addr1 = std_slice_7.out; - mem_3.read_en = 1'd1; - std_slice_8.in = for_3_induction_var_reg.out; - std_slice_7.in = for_2_induction_var_reg.out; - } - static<1> group invoke120 { - load_4_reg.write_en = 1'd1; - load_4_reg.in = mem_3.read_data; - } - static<3> group invoke130 { - std_mult_pipe_1.go = 1'd1; - std_mult_pipe_1.left = load_4_reg.out; - std_mult_pipe_1.right = load_2_reg.out; - } - static<1> group invoke140 { - muli_1_reg.write_en = 1'd1; - muli_1_reg.in = std_mult_pipe_1.out; - } - static<1> group bb0_130 { - std_slice_9.in = for_2_induction_var_reg.out; - mem_1.addr0 = std_slice_9.out; - mem_1.write_data = std_add_5.out; - mem_1.write_en = 1'd1; - std_add_5.left = load_3_reg.out; - std_add_5.right = std_mult_pipe_1.out; - } - static<1> group invoke150 { - for_2_induction_var_reg.write_en = 1'd1; - for_2_induction_var_reg.in = std_add_5.out; - std_add_5.left = for_2_induction_var_reg.out; - std_add_5.right = 32'd1; - } - static<1> group bb0_100 { - std_slice_9.in = for_3_induction_var_reg.out; - mem_0.addr0 = std_slice_9.out; - mem_0.write_data = 32'd0; - mem_0.write_en = 1'd1; - } - static<1> group invoke30 { - for_1_induction_var_reg.write_en = 1'd1; - for_1_induction_var_reg.in = 32'd0; - } - static<1> group invoke101 { - for_2_induction_var_reg.write_en = 1'd1; - for_2_induction_var_reg.in = 32'd0; - } - static<1> group invoke160 { - for_3_induction_var_reg.write_en = 1'd1; - for_3_induction_var_reg.in = std_add_5.out; - std_add_5.left = for_3_induction_var_reg.out; - std_add_5.right = 32'd1; - } - static<1> group invoke00 { - muli_1_reg.write_en = 1'd1; - muli_1_reg.in = 32'd0; - } - static<1> group invoke20 { - for_3_induction_var_reg.write_en = 1'd1; - for_3_induction_var_reg.in = 32'd0; - } - static<1> group no-op { - } - static<1> group no-op0 { - } - static<1> group no-op1 { - } - static<3> group no-op2 { - } - static<2> group no-op3 { - } - static<2> group no-op4 { - } - static<6> group no-op5 { - } - static<1> group no-op6 { - } - static<1> group no-op7 { - } - static<1> group no-op8 { - } - static<3> group no-op9 { - } - static<2> group no-op10 { - } - static<6> group no-op11 { - } - static<7> group no-op12 { - } - static<1> group no-op13 { - } - static<2871> group no-op14 { - } - static<2873> group no-op15 { - } - static<6153> group no-op16 { - } - static<1> group no-op17 { - } - static<821> group no-op18 { - } - } - control { - @NODE_ID(0) static<2400881> par { - @NODE_ID invoke20; - @NODE_ID(2) invoke00; - @NODE_ID(3) static<821> seq { - @NODE_ID(4) no-op17; - @NODE_ID(5) static repeat 410 { - @NODE_ID(6) static<2> par { - @NODE_ID(7) bb0_00; - @NODE_ID(8) static<2> seq { - @NODE_ID(9) no-op; - @NODE_ID(10) invoke100; - } - } - } - } - @NODE_ID(11) static<2400881> seq { - @NODE_ID(12) no-op18; - @NODE_ID(13) static repeat 390 { - @NODE_ID(14) static<6154> par { - @NODE_ID(15) invoke101; - @NODE_ID(16) invoke30; - @NODE_ID(17) bb0_100; - @NODE_ID(18) static<2871> seq { - @NODE_ID(19) no-op13; - @NODE_ID(20) static repeat 410 { - @NODE_ID(21) static<7> par { - @NODE_ID(22) bb0_40; - @NODE_ID(23) beg_spl_bb0_30; - @NODE_ID(24) static<2> seq { - @NODE_ID(25) no-op1; - @NODE_ID(26) invoke50; - } - @NODE_ID(27) static<3> seq { - @NODE_ID(28) no-op3; - @NODE_ID(29) invoke80; - } - @NODE_ID(30) static<6> seq { - @NODE_ID(31) no-op4; - @NODE_ID(32) static<4> par { - @NODE_ID(33) invoke60; - @NODE_ID(34) static<4> seq { - @NODE_ID(35) no-op2; - @NODE_ID(36) invoke70; - } - } - } - @NODE_ID(37) beg_spl_bb0_20; - @NODE_ID(38) static<2> seq { - @NODE_ID(39) no-op0; - @NODE_ID(40) invoke40; - } - @NODE_ID(41) static<7> seq { - @NODE_ID(42) no-op5; - @NODE_ID(43) bb0_70; - } - } - } - } - @NODE_ID(44) static<2873> seq { - @NODE_ID(45) no-op14; - @NODE_ID(46) static<2> par { - @NODE_ID(47) beg_spl_bb0_80; - @NODE_ID(48) static<2> seq { - @NODE_ID(49) no-op6; - @NODE_ID(50) invoke90; - } - } - } - @NODE_ID(51) static<6153> seq { - @NODE_ID(52) no-op15; - @NODE_ID(53) static repeat 410 { - @NODE_ID(54) static<8> par { - @NODE_ID(55) beg_spl_bb0_100; - @NODE_ID(56) static<2> seq { - @NODE_ID(57) no-op8; - @NODE_ID(58) invoke120; - } - @NODE_ID(59) static<6> seq { - @NODE_ID(60) no-op10; - @NODE_ID(61) static<4> par { - @NODE_ID(62) invoke130; - @NODE_ID(63) static<4> seq { - @NODE_ID(64) no-op9; - @NODE_ID(65) invoke140; - } - } - } - @NODE_ID(66) beg_spl_bb0_90; - @NODE_ID(67) static<2> seq { - @NODE_ID(68) no-op7; - @NODE_ID(69) invoke110; - } - @NODE_ID(70) static<7> seq { - @NODE_ID(71) no-op11; - @NODE_ID(72) bb0_130; - } - @NODE_ID(73) static<8> seq { - @NODE_ID(74) no-op12; - @NODE_ID(75) invoke150; - } - } - } - } - @NODE_ID(76) static<6154> seq { - @NODE_ID(77) no-op16; - @NODE_ID(78) invoke160; - } - } - } - } - } - } -} From 649c51750a06b4acf80b661556f662137a3cd6f7 Mon Sep 17 00:00:00 2001 From: Caleb Date: Thu, 9 Nov 2023 01:06:10 -0500 Subject: [PATCH 5/9] another silly mistake --- calyx-opt/src/passes/schedule_compaction.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index 952cc6339..a453826d8 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -102,7 +102,20 @@ impl Visitor for ScheduleCompaction { continue 'outer; } } - par_threads.push((vec![control], latency_map[&i])); + if start > 0 { + let no_op = builder.add_static_group("no-op", start); + let no_op_enable = + ir::StaticControl::Enable(ir::StaticEnable { + group: no_op, + attributes: ir::Attributes::default(), + }); + par_threads.push(( + vec![no_op_enable, control], + start + latency_map[&i], + )); + } else { + par_threads.push((vec![control], latency_map[&i])); + } } let mut par_control_threads: Vec = Vec::new(); From f4cf20cec2cd617fe108c73d094fe6c9c17d3680 Mon Sep 17 00:00:00 2001 From: Caleb Date: Thu, 9 Nov 2023 12:28:27 -0500 Subject: [PATCH 6/9] documentation --- calyx-opt/src/passes/schedule_compaction.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index a453826d8..b5f7e699e 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -4,7 +4,6 @@ use crate::{ traversal::{Named, Visitor}, }; use calyx_ir as ir; -use itertools::Itertools; use petgraph::{algo, graph::NodeIndex}; use std::collections::HashMap; @@ -60,7 +59,7 @@ impl Visitor for ScheduleCompaction { if let Ok(order) = algo::toposort(&total_order, None) { let mut total_time: u64 = 0; - // First we build the schedule + // First we build the schedule. for i in order { let mut start: u64 = 0; for node in dependency.get(&i).unwrap() { @@ -71,20 +70,22 @@ impl Visitor for ScheduleCompaction { total_time = std::cmp::max(start + latency_map[&i], total_time); } + // We sort the schedule by start time. let mut sorted_schedule: Vec<(NodeIndex, u64)> = schedule.into_iter().collect(); sorted_schedule.sort_by(|(_, v1), (_, v2)| v1.cmp(v2)); - // Par Threads, where each entry is (thread, thread_latency) + // Threads for the static par, where each entry is (thread, thread_latency) let mut par_threads: Vec<(Vec, u64)> = Vec::new(); - // Now we build the ordering to minimize the number of par threads + // We encode the schedule attempting to minimize the number of + // par threads. 'outer: for (i, start) in sorted_schedule { let control = total_order[i].take().unwrap(); for (thread, thread_latency) in par_threads.iter_mut() { if *thread_latency <= start { if *thread_latency < start { - // Might need a no-op group to align schedule + // Might need a no-op group so the schedule starts correctly let no_op = builder.add_static_group( "no-op", start - *thread_latency, @@ -102,7 +103,10 @@ impl Visitor for ScheduleCompaction { continue 'outer; } } + // We must create a new par thread. if start > 0 { + // If start > 0, then we must add a delay to the start of the + // group. let no_op = builder.add_static_group("no-op", start); let no_op_enable = ir::StaticControl::Enable(ir::StaticEnable { @@ -118,6 +122,7 @@ impl Visitor for ScheduleCompaction { } } + // Turn Vec -> StaticSeq let mut par_control_threads: Vec = Vec::new(); for (thread, thread_latency) in par_threads { par_control_threads.push(ir::StaticControl::Seq( @@ -128,8 +133,9 @@ impl Visitor for ScheduleCompaction { }, )); } + // Double checking that we have built the static par correctly. let max = par_control_threads.iter().map(|c| c.get_latency()).max(); - assert!(max.unwrap() == total_time, "messed up"); + assert!(max.unwrap() == total_time, "The schedule expects latency {}. The static par that was built has latency {}", total_time, max.unwrap()); if par_control_threads.len() == 1 { let c = Vec::pop(&mut par_control_threads).unwrap(); From 5cedc7f0995dcd29915233f70eea64f61cd0479a Mon Sep 17 00:00:00 2001 From: Caleb Date: Thu, 9 Nov 2023 12:36:37 -0500 Subject: [PATCH 7/9] rewrite tests --- calyx-opt/src/default_passes.rs | 5 +- calyx-opt/src/passes/schedule_compaction.rs | 3 +- examples/futil/dot-product.expect | 78 ++++++++++----------- examples/futil/simple.expect | 32 ++++----- examples/futil/vectorized-add.expect | 68 +++++++++--------- tests/passes/cell-share/inline.expect | 23 ++---- 6 files changed, 97 insertions(+), 112 deletions(-) diff --git a/calyx-opt/src/default_passes.rs b/calyx-opt/src/default_passes.rs index 01e5edd05..940d75fe3 100644 --- a/calyx-opt/src/default_passes.rs +++ b/calyx-opt/src/default_passes.rs @@ -90,16 +90,15 @@ impl PassManager { ComponentInliner, CombProp, DeadCellRemoval, // Clean up dead wires left by CombProp + CellShare, // LiveRangeAnalaysis should handle comb groups SimplifyWithControl, // Must run before compile-invoke CompileInvoke, // creates dead comb groups AttributePromotion, StaticPromotion, ScheduleCompaction, - CollapseControl, - CellShare, // LiveRangeAnalaysis should handle comb groups CompileRepeat, DeadGroupRemoval, // Since previous passes potentially create dead groups - CollapseControl + CollapseControl, ] ); register_alias!( diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index b5f7e699e..ecba9e219 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -73,7 +73,8 @@ impl Visitor for ScheduleCompaction { // We sort the schedule by start time. let mut sorted_schedule: Vec<(NodeIndex, u64)> = schedule.into_iter().collect(); - sorted_schedule.sort_by(|(_, v1), (_, v2)| v1.cmp(v2)); + sorted_schedule + .sort_by(|(k1, v1), (k2, v2)| (v1, k1).cmp(&(v2, k2))); // Threads for the static par, where each entry is (thread, thread_latency) let mut par_threads: Vec<(Vec, u64)> = Vec::new(); diff --git a/examples/futil/dot-product.expect b/examples/futil/dot-product.expect index 0bbfdc060..65f943cb9 100644 --- a/examples/futil/dot-product.expect +++ b/examples/futil/dot-product.expect @@ -28,92 +28,92 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { @generated invoke0_done = std_wire(1); @generated early_reset_cond00_go = std_wire(1); @generated early_reset_cond00_done = std_wire(1); - @generated early_reset_static_par_go = std_wire(1); - @generated early_reset_static_par_done = std_wire(1); + @generated early_reset_static_seq_go = std_wire(1); + @generated early_reset_static_seq_done = std_wire(1); @generated wrapper_early_reset_cond00_go = std_wire(1); @generated wrapper_early_reset_cond00_done = std_wire(1); - @generated while_wrapper_early_reset_static_par_go = std_wire(1); - @generated while_wrapper_early_reset_static_par_done = std_wire(1); + @generated while_wrapper_early_reset_static_seq_go = std_wire(1); + @generated while_wrapper_early_reset_static_seq_done = std_wire(1); @generated tdcc_go = std_wire(1); @generated tdcc_done = std_wire(1); } wires { - i0.write_en = invoke0_go.out | fsm.out == 4'd1 & early_reset_static_par_go.out ? 1'd1; + i0.write_en = invoke0_go.out | fsm.out == 4'd1 & early_reset_static_seq_go.out ? 1'd1; i0.clk = clk; i0.reset = reset; - i0.in = fsm.out == 4'd1 & early_reset_static_par_go.out ? add1.out; + i0.in = fsm.out == 4'd1 & early_reset_static_seq_go.out ? add1.out; i0.in = invoke0_go.out ? const0.out; early_reset_cond00_go.in = wrapper_early_reset_cond00_go.out ? 1'd1; - add1.left = fsm.out == 4'd1 & early_reset_static_par_go.out ? i0.out; - add1.right = fsm.out == 4'd1 & early_reset_static_par_go.out ? const3.out; + add1.left = fsm.out == 4'd1 & early_reset_static_seq_go.out ? i0.out; + add1.right = fsm.out == 4'd1 & early_reset_static_seq_go.out ? const3.out; done = tdcc_done.out ? 1'd1; - fsm.write_en = early_reset_cond00_go.out | early_reset_static_par_go.out ? 1'd1; + fsm.write_en = early_reset_cond00_go.out | early_reset_static_seq_go.out ? 1'd1; fsm.clk = clk; fsm.reset = reset; fsm.in = fsm.out != 4'd0 & early_reset_cond00_go.out ? adder.out; - fsm.in = fsm.out == 4'd0 & early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_par_go.out ? 4'd0; - fsm.in = fsm.out != 4'd7 & early_reset_static_par_go.out ? adder0.out; + fsm.in = fsm.out == 4'd0 & early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_seq_go.out ? 4'd0; + fsm.in = fsm.out != 4'd7 & early_reset_static_seq_go.out ? adder0.out; adder.left = early_reset_cond00_go.out ? fsm.out; adder.right = early_reset_cond00_go.out ? 4'd1; - add0.left = fsm.out == 4'd6 & early_reset_static_par_go.out ? v0.read_data; - add0.right = fsm.out == 4'd6 & early_reset_static_par_go.out ? B_read0_0.out; - v0.write_en = fsm.out == 4'd6 & early_reset_static_par_go.out ? 1'd1; + add0.left = fsm.out == 4'd6 & early_reset_static_seq_go.out ? v0.read_data; + add0.right = fsm.out == 4'd6 & early_reset_static_seq_go.out ? B_read0_0.out; + v0.write_en = fsm.out == 4'd6 & early_reset_static_seq_go.out ? 1'd1; v0.clk = clk; - v0.addr0 = fsm.out == 4'd6 & early_reset_static_par_go.out ? const2.out; + v0.addr0 = fsm.out == 4'd6 & early_reset_static_seq_go.out ? const2.out; v0.reset = reset; - v0.write_data = fsm.out == 4'd6 & early_reset_static_par_go.out ? add0.out; - comb_reg.write_en = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_par_go.out ? 1'd1; + v0.write_data = fsm.out == 4'd6 & early_reset_static_seq_go.out ? add0.out; + comb_reg.write_en = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_seq_go.out ? 1'd1; comb_reg.clk = clk; comb_reg.reset = reset; - comb_reg.in = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_par_go.out ? le0.out; + comb_reg.in = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_seq_go.out ? le0.out; early_reset_cond00_done.in = ud.out; - while_wrapper_early_reset_static_par_go.in = !while_wrapper_early_reset_static_par_done.out & fsm0.out == 2'd2 & tdcc_go.out ? 1'd1; + while_wrapper_early_reset_static_seq_go.in = !while_wrapper_early_reset_static_seq_done.out & fsm0.out == 2'd2 & tdcc_go.out ? 1'd1; invoke0_go.in = !invoke0_done.out & fsm0.out == 2'd0 & tdcc_go.out ? 1'd1; - while_wrapper_early_reset_static_par_done.in = !comb_reg.out & fsm.out == 4'd0 ? 1'd1; tdcc_go.in = go; A0.clk = clk; - A0.addr0 = fsm.out == 4'd0 & early_reset_static_par_go.out ? i0.out; + A0.addr0 = fsm.out == 4'd0 & early_reset_static_seq_go.out ? i0.out; A0.reset = reset; - fsm0.write_en = fsm0.out == 2'd3 | fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out | fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out | fsm0.out == 2'd2 & while_wrapper_early_reset_static_par_done.out & tdcc_go.out ? 1'd1; + fsm0.write_en = fsm0.out == 2'd3 | fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out | fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out | fsm0.out == 2'd2 & while_wrapper_early_reset_static_seq_done.out & tdcc_go.out ? 1'd1; fsm0.clk = clk; fsm0.reset = reset; fsm0.in = fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out ? 2'd1; fsm0.in = fsm0.out == 2'd3 ? 2'd0; - fsm0.in = fsm0.out == 2'd2 & while_wrapper_early_reset_static_par_done.out & tdcc_go.out ? 2'd3; + fsm0.in = fsm0.out == 2'd2 & while_wrapper_early_reset_static_seq_done.out & tdcc_go.out ? 2'd3; fsm0.in = fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out ? 2'd2; mult_pipe0.clk = clk; - mult_pipe0.left = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_par_go.out ? A_read0_0.out; - mult_pipe0.go = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_par_go.out ? 1'd1; + mult_pipe0.left = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_seq_go.out ? A_read0_0.out; + mult_pipe0.go = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_seq_go.out ? 1'd1; mult_pipe0.reset = reset; - mult_pipe0.right = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_par_go.out ? B_read0_0.out; - adder0.left = early_reset_static_par_go.out ? fsm.out; - adder0.right = early_reset_static_par_go.out ? 4'd1; + mult_pipe0.right = fsm.out >= 4'd1 & fsm.out < 4'd4 & early_reset_static_seq_go.out ? B_read0_0.out; + adder0.left = early_reset_static_seq_go.out ? fsm.out; + adder0.right = early_reset_static_seq_go.out ? 4'd1; invoke0_done.in = i0.done; - early_reset_static_par_done.in = ud0.out; - le0.left = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_par_go.out ? i0.out; - le0.right = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_par_go.out ? const1.out; + early_reset_static_seq_go.in = while_wrapper_early_reset_static_seq_go.out ? 1'd1; + le0.left = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_seq_go.out ? i0.out; + le0.right = early_reset_cond00_go.out | fsm.out == 4'd7 & early_reset_static_seq_go.out ? const1.out; signal_reg.write_en = fsm.out == 4'd0 & signal_reg.out | fsm.out == 4'd0 & !signal_reg.out & wrapper_early_reset_cond00_go.out ? 1'd1; signal_reg.clk = clk; signal_reg.reset = reset; signal_reg.in = fsm.out == 4'd0 & !signal_reg.out & wrapper_early_reset_cond00_go.out ? 1'd1; signal_reg.in = fsm.out == 4'd0 & signal_reg.out ? 1'd0; B0.clk = clk; - B0.addr0 = fsm.out == 4'd0 & early_reset_static_par_go.out ? i0.out; + 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'd5 & fsm.out < 4'd6) & early_reset_static_par_go.out ? 1'd1; + 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.clk = clk; B_read0_0.reset = reset; - B_read0_0.in = fsm.out == 4'd0 & early_reset_static_par_go.out ? B0.read_data; - B_read0_0.in = fsm.out == 4'd5 & early_reset_static_par_go.out ? A_read0_0.out; + B_read0_0.in = fsm.out == 4'd0 & early_reset_static_seq_go.out ? B0.read_data; + B_read0_0.in = fsm.out == 4'd5 & early_reset_static_seq_go.out ? A_read0_0.out; wrapper_early_reset_cond00_go.in = !wrapper_early_reset_cond00_done.out & fsm0.out == 2'd1 & tdcc_go.out ? 1'd1; wrapper_early_reset_cond00_done.in = fsm.out == 4'd0 & signal_reg.out ? 1'd1; + early_reset_static_seq_done.in = ud0.out; tdcc_done.in = fsm0.out == 2'd3 ? 1'd1; - early_reset_static_par_go.in = while_wrapper_early_reset_static_par_go.out ? 1'd1; - A_read0_0.write_en = (fsm.out == 4'd0 | fsm.out == 4'd4 & fsm.out >= 4'd1 & fsm.out < 4'd5 & fsm.out < 4'd5) & early_reset_static_par_go.out ? 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'd5 & fsm.out < 4'd7) & 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_par_go.out ? A0.read_data; - A_read0_0.in = fsm.out == 4'd4 & early_reset_static_par_go.out ? mult_pipe0.out; + A_read0_0.in = fsm.out == 4'd0 & early_reset_static_seq_go.out ? A0.read_data; + A_read0_0.in = fsm.out == 4'd4 & early_reset_static_seq_go.out ? mult_pipe0.out; } control {} } diff --git a/examples/futil/simple.expect b/examples/futil/simple.expect index 16a037543..4f61bc431 100644 --- a/examples/futil/simple.expect +++ b/examples/futil/simple.expect @@ -6,29 +6,29 @@ static<5> component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done @generated ud = undef(1); @generated adder = std_add(3); @generated signal_reg = std_reg(1); - @generated early_reset_static_par_go = std_wire(1); - @generated early_reset_static_par_done = std_wire(1); - @generated wrapper_early_reset_static_par_go = std_wire(1); - @generated wrapper_early_reset_static_par_done = std_wire(1); + @generated early_reset_static_seq_go = std_wire(1); + @generated early_reset_static_seq_done = std_wire(1); + @generated wrapper_early_reset_static_seq_go = std_wire(1); + @generated wrapper_early_reset_static_seq_done = std_wire(1); } wires { - done = wrapper_early_reset_static_par_done.out ? 1'd1; - fsm.write_en = early_reset_static_par_go.out ? 1'd1; + done = wrapper_early_reset_static_seq_done.out ? 1'd1; + fsm.write_en = early_reset_static_seq_go.out ? 1'd1; fsm.clk = clk; fsm.reset = reset; - fsm.in = fsm.out != 3'd4 & early_reset_static_par_go.out ? adder.out; - fsm.in = fsm.out == 3'd4 & early_reset_static_par_go.out ? 3'd0; - adder.left = early_reset_static_par_go.out ? fsm.out; - adder.right = early_reset_static_par_go.out ? 3'd1; - wrapper_early_reset_static_par_go.in = go; - wrapper_early_reset_static_par_done.in = fsm.out == 3'd0 & signal_reg.out ? 1'd1; - early_reset_static_par_done.in = ud.out; - signal_reg.write_en = fsm.out == 3'd0 & signal_reg.out | fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_static_par_go.out ? 1'd1; + fsm.in = fsm.out != 3'd4 & early_reset_static_seq_go.out ? adder.out; + fsm.in = fsm.out == 3'd4 & early_reset_static_seq_go.out ? 3'd0; + adder.left = early_reset_static_seq_go.out ? fsm.out; + adder.right = early_reset_static_seq_go.out ? 3'd1; + wrapper_early_reset_static_seq_done.in = fsm.out == 3'd0 & signal_reg.out ? 1'd1; + early_reset_static_seq_go.in = wrapper_early_reset_static_seq_go.out ? 1'd1; + signal_reg.write_en = fsm.out == 3'd0 & signal_reg.out | fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_static_seq_go.out ? 1'd1; signal_reg.clk = clk; signal_reg.reset = reset; - signal_reg.in = fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_static_par_go.out ? 1'd1; + signal_reg.in = fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_static_seq_go.out ? 1'd1; signal_reg.in = fsm.out == 3'd0 & signal_reg.out ? 1'd0; - early_reset_static_par_go.in = wrapper_early_reset_static_par_go.out ? 1'd1; + early_reset_static_seq_done.in = ud.out; + wrapper_early_reset_static_seq_go.in = go; } control {} } diff --git a/examples/futil/vectorized-add.expect b/examples/futil/vectorized-add.expect index 507224343..005c8bc0f 100644 --- a/examples/futil/vectorized-add.expect +++ b/examples/futil/vectorized-add.expect @@ -25,85 +25,85 @@ component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) { @generated invoke0_done = std_wire(1); @generated early_reset_cond00_go = std_wire(1); @generated early_reset_cond00_done = std_wire(1); - @generated early_reset_static_par_go = std_wire(1); - @generated early_reset_static_par_done = std_wire(1); + @generated early_reset_static_seq_go = std_wire(1); + @generated early_reset_static_seq_done = std_wire(1); @generated wrapper_early_reset_cond00_go = std_wire(1); @generated wrapper_early_reset_cond00_done = std_wire(1); - @generated while_wrapper_early_reset_static_par_go = std_wire(1); - @generated while_wrapper_early_reset_static_par_done = std_wire(1); + @generated while_wrapper_early_reset_static_seq_go = std_wire(1); + @generated while_wrapper_early_reset_static_seq_done = std_wire(1); @generated tdcc_go = std_wire(1); @generated tdcc_done = std_wire(1); } wires { - i0.write_en = invoke0_go.out | fsm.out == 3'd2 & early_reset_static_par_go.out ? 1'd1; + i0.write_en = invoke0_go.out | fsm.out == 3'd2 & early_reset_static_seq_go.out ? 1'd1; i0.clk = clk; i0.reset = reset; - i0.in = fsm.out == 3'd2 & early_reset_static_par_go.out ? add1.out; + i0.in = fsm.out == 3'd2 & early_reset_static_seq_go.out ? add1.out; i0.in = invoke0_go.out ? const0.out; early_reset_cond00_go.in = wrapper_early_reset_cond00_go.out ? 1'd1; - add1.left = fsm.out == 3'd2 & early_reset_static_par_go.out ? i0.out; - add1.right = fsm.out == 3'd2 & early_reset_static_par_go.out ? const2.out; + add1.left = fsm.out == 3'd2 & early_reset_static_seq_go.out ? i0.out; + add1.right = fsm.out == 3'd2 & early_reset_static_seq_go.out ? const2.out; done = tdcc_done.out ? 1'd1; - fsm.write_en = early_reset_cond00_go.out | early_reset_static_par_go.out ? 1'd1; + fsm.write_en = early_reset_cond00_go.out | early_reset_static_seq_go.out ? 1'd1; fsm.clk = clk; fsm.reset = reset; fsm.in = fsm.out != 3'd0 & early_reset_cond00_go.out ? adder.out; - fsm.in = fsm.out != 3'd3 & early_reset_static_par_go.out ? adder0.out; - fsm.in = fsm.out == 3'd0 & early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_par_go.out ? 3'd0; + fsm.in = fsm.out != 3'd3 & early_reset_static_seq_go.out ? adder0.out; + fsm.in = fsm.out == 3'd0 & early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_seq_go.out ? 3'd0; adder.left = early_reset_cond00_go.out ? fsm.out; adder.right = early_reset_cond00_go.out ? 3'd1; - add0.left = fsm.out == 3'd1 & early_reset_static_par_go.out ? A_read0_0.out; - add0.right = fsm.out == 3'd1 & early_reset_static_par_go.out ? B_read0_0.out; - comb_reg.write_en = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_par_go.out ? 1'd1; + add0.left = fsm.out == 3'd1 & early_reset_static_seq_go.out ? A_read0_0.out; + add0.right = fsm.out == 3'd1 & early_reset_static_seq_go.out ? B_read0_0.out; + comb_reg.write_en = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_seq_go.out ? 1'd1; comb_reg.clk = clk; comb_reg.reset = reset; - comb_reg.in = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_par_go.out ? le0.out; + comb_reg.in = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_seq_go.out ? le0.out; early_reset_cond00_done.in = ud.out; - while_wrapper_early_reset_static_par_go.in = !while_wrapper_early_reset_static_par_done.out & fsm0.out == 2'd2 & tdcc_go.out ? 1'd1; + while_wrapper_early_reset_static_seq_go.in = !while_wrapper_early_reset_static_seq_done.out & fsm0.out == 2'd2 & tdcc_go.out ? 1'd1; invoke0_go.in = !invoke0_done.out & fsm0.out == 2'd0 & tdcc_go.out ? 1'd1; - while_wrapper_early_reset_static_par_done.in = !comb_reg.out & fsm.out == 3'd0 ? 1'd1; tdcc_go.in = go; A0.clk = clk; - A0.addr0 = fsm.out == 3'd0 & early_reset_static_par_go.out ? i0.out; + A0.addr0 = fsm.out == 3'd0 & early_reset_static_seq_go.out ? i0.out; A0.reset = reset; - Sum0.write_en = fsm.out == 3'd1 & early_reset_static_par_go.out ? 1'd1; + Sum0.write_en = fsm.out == 3'd1 & early_reset_static_seq_go.out ? 1'd1; Sum0.clk = clk; - Sum0.addr0 = fsm.out == 3'd1 & early_reset_static_par_go.out ? i0.out; + Sum0.addr0 = fsm.out == 3'd1 & early_reset_static_seq_go.out ? i0.out; Sum0.reset = reset; - Sum0.write_data = fsm.out == 3'd1 & early_reset_static_par_go.out ? add0.out; - fsm0.write_en = fsm0.out == 2'd3 | fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out | fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out | fsm0.out == 2'd2 & while_wrapper_early_reset_static_par_done.out & tdcc_go.out ? 1'd1; + Sum0.write_data = fsm.out == 3'd1 & early_reset_static_seq_go.out ? add0.out; + fsm0.write_en = fsm0.out == 2'd3 | fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out | fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out | fsm0.out == 2'd2 & while_wrapper_early_reset_static_seq_done.out & tdcc_go.out ? 1'd1; fsm0.clk = clk; fsm0.reset = reset; fsm0.in = fsm0.out == 2'd0 & invoke0_done.out & tdcc_go.out ? 2'd1; fsm0.in = fsm0.out == 2'd3 ? 2'd0; - fsm0.in = fsm0.out == 2'd2 & while_wrapper_early_reset_static_par_done.out & tdcc_go.out ? 2'd3; + fsm0.in = fsm0.out == 2'd2 & while_wrapper_early_reset_static_seq_done.out & tdcc_go.out ? 2'd3; fsm0.in = fsm0.out == 2'd1 & wrapper_early_reset_cond00_done.out & tdcc_go.out ? 2'd2; - adder0.left = early_reset_static_par_go.out ? fsm.out; - adder0.right = early_reset_static_par_go.out ? 3'd1; + adder0.left = early_reset_static_seq_go.out ? fsm.out; + adder0.right = early_reset_static_seq_go.out ? 3'd1; invoke0_done.in = i0.done; - early_reset_static_par_done.in = ud0.out; - le0.left = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_par_go.out ? i0.out; - le0.right = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_par_go.out ? const1.out; + early_reset_static_seq_go.in = while_wrapper_early_reset_static_seq_go.out ? 1'd1; + le0.left = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_seq_go.out ? i0.out; + le0.right = early_reset_cond00_go.out | fsm.out == 3'd3 & early_reset_static_seq_go.out ? const1.out; signal_reg.write_en = fsm.out == 3'd0 & signal_reg.out | fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_cond00_go.out ? 1'd1; signal_reg.clk = clk; signal_reg.reset = reset; signal_reg.in = fsm.out == 3'd0 & !signal_reg.out & wrapper_early_reset_cond00_go.out ? 1'd1; signal_reg.in = fsm.out == 3'd0 & signal_reg.out ? 1'd0; B0.clk = clk; - B0.addr0 = fsm.out == 3'd0 & early_reset_static_par_go.out ? i0.out; + B0.addr0 = fsm.out == 3'd0 & early_reset_static_seq_go.out ? i0.out; B0.reset = reset; - B_read0_0.write_en = fsm.out == 3'd0 & early_reset_static_par_go.out ? 1'd1; + B_read0_0.write_en = fsm.out == 3'd0 & early_reset_static_seq_go.out ? 1'd1; B_read0_0.clk = clk; B_read0_0.reset = reset; - B_read0_0.in = fsm.out == 3'd0 & early_reset_static_par_go.out ? B0.read_data; + B_read0_0.in = fsm.out == 3'd0 & early_reset_static_seq_go.out ? B0.read_data; wrapper_early_reset_cond00_go.in = !wrapper_early_reset_cond00_done.out & fsm0.out == 2'd1 & tdcc_go.out ? 1'd1; wrapper_early_reset_cond00_done.in = fsm.out == 3'd0 & signal_reg.out ? 1'd1; + early_reset_static_seq_done.in = ud0.out; tdcc_done.in = fsm0.out == 2'd3 ? 1'd1; - early_reset_static_par_go.in = while_wrapper_early_reset_static_par_go.out ? 1'd1; - A_read0_0.write_en = fsm.out == 3'd0 & early_reset_static_par_go.out ? 1'd1; + while_wrapper_early_reset_static_seq_done.in = !comb_reg.out & fsm.out == 3'd0 ? 1'd1; + A_read0_0.write_en = fsm.out == 3'd0 & early_reset_static_seq_go.out ? 1'd1; A_read0_0.clk = clk; A_read0_0.reset = reset; - A_read0_0.in = fsm.out == 3'd0 & early_reset_static_par_go.out ? A0.read_data; + A_read0_0.in = fsm.out == 3'd0 & early_reset_static_seq_go.out ? A0.read_data; } control {} } diff --git a/tests/passes/cell-share/inline.expect b/tests/passes/cell-share/inline.expect index 9a7e2e66b..73fbadbca 100644 --- a/tests/passes/cell-share/inline.expect +++ b/tests/passes/cell-share/inline.expect @@ -39,28 +39,13 @@ static<4> component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done mem.addr0 = 1'd1; mem.write_data = r.out; } - static<1> group no-op { - } - static<2> group no-op0 { - } - static<3> group no-op1 { - } } control { - static<4> par { + static<4> seq { invoke00; - static<2> seq { - no-op; - invoke10; - } - static<3> seq { - no-op0; - invoke20; - } - static<4> seq { - no-op1; - invoke30; - } + invoke10; + invoke20; + invoke30; } } } From 3989e1fd151cb7dc28a10739a92bd10aafdfbdd7 Mon Sep 17 00:00:00 2001 From: Caleb Date: Thu, 9 Nov 2023 13:14:07 -0500 Subject: [PATCH 8/9] rewrite test --- examples/futil/dot-product.expect | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/futil/dot-product.expect b/examples/futil/dot-product.expect index 65f943cb9..c5f0d0db3 100644 --- a/examples/futil/dot-product.expect +++ b/examples/futil/dot-product.expect @@ -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'd5 & fsm.out < 4'd7) & early_reset_static_seq_go.out ? 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.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 1b0c73d17f527c3a00ae12e5ae670c024e22dd68 Mon Sep 17 00:00:00 2001 From: Caleb Date: Sat, 11 Nov 2023 16:09:55 -0500 Subject: [PATCH 9/9] code cleaning --- calyx-opt/src/passes/schedule_compaction.rs | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/calyx-opt/src/passes/schedule_compaction.rs b/calyx-opt/src/passes/schedule_compaction.rs index ecba9e219..b3b3b93b5 100644 --- a/calyx-opt/src/passes/schedule_compaction.rs +++ b/calyx-opt/src/passes/schedule_compaction.rs @@ -60,12 +60,16 @@ impl Visitor for ScheduleCompaction { let mut total_time: u64 = 0; // First we build the schedule. + for i in order { - let mut start: u64 = 0; - for node in dependency.get(&i).unwrap() { - start = - std::cmp::max(start, schedule[node] + latency_map[node]) - } + // Start time is when the latest dependency finishes + let start = dependency + .get(&i) + .unwrap() + .iter() + .map(|node| schedule[node] + latency_map[node]) + .max() + .unwrap_or(0); schedule.insert(i, start); total_time = std::cmp::max(start + latency_map[&i], total_time); } @@ -140,22 +144,20 @@ impl Visitor for ScheduleCompaction { if par_control_threads.len() == 1 { let c = Vec::pop(&mut par_control_threads).unwrap(); - return Ok(Action::static_change(c)); + Ok(Action::static_change(c)) } else { let s_par = ir::StaticControl::Par(ir::StaticPar { stmts: par_control_threads, attributes: ir::Attributes::default(), latency: total_time, }); - return Ok(Action::static_change(s_par)); + Ok(Action::static_change(s_par)) } } else { - println!( + panic!( "Error when producing topo sort. Dependency graph has a cycle." ); } - - Ok(Action::Continue) } fn finish_static_repeat(