calyx 0.7.1

Compiler Infrastructure for Hardware Accelerator Generation
import "primitives/core.futil";
import "primitives/memories/comb.futil";
import "primitives/unsynthesizable.futil";
component main() -> () {
  cells {
    t0_idx = std_reg(2);
    t0_add = std_add(2);
    @external(1) t0 = comb_mem_d1(32, 3, 2);
    t1_idx = std_reg(2);
    t1_add = std_add(2);
    @external(1) t1 = comb_mem_d1(32, 3, 2);
    l0_idx = std_reg(2);
    l0_add = std_add(2);
    @external(1) l0 = comb_mem_d1(32, 3, 2);
    l1_idx = std_reg(2);
    l1_add = std_add(2);
    @external(1) l1 = comb_mem_d1(32, 3, 2);
    @external(1) out_mem = comb_mem_d1(32, 4, 3);
    top_0_0 = std_reg(32);
    left_0_0 = std_reg(32);
    top_0_1 = std_reg(32);
    left_0_1 = std_reg(32);
    top_1_0 = std_reg(32);
    left_1_0 = std_reg(32);
    top_1_1 = std_reg(32);
    left_1_1 = std_reg(32);
    @inline pe_1_0 = mac_pe();
    @inline pe_1_1 = mac_pe();
    @inline pe_0_1 = mac_pe();
    @inline pe_0_0 = mac_pe();
  }
  wires {
    group t0_idx_init {
      t0_idx.in = 2'd3;
      t0_idx.write_en = 1'd1;
      t0_idx_init[done] = t0_idx.done;
    }
    group t0_idx_update {
      t0_add.left = 2'd1;
      t0_add.right = t0_idx.out;
      t0_idx.in = t0_add.out;
      t0_idx.write_en = 1'd1;
      t0_idx_update[done] = t0_idx.done;
    }
    group t0_move {
      t0.addr0 = t0_idx.out;
      top_0_0.in = t0.read_data;
      top_0_0.write_en = 1'd1;
      t0_move[done] = top_0_0.done;
    }
    group t1_idx_init {
      t1_idx.in = 2'd3;
      t1_idx.write_en = 1'd1;
      t1_idx_init[done] = t1_idx.done;
    }
    group t1_idx_update {
      t1_add.left = 2'd1;
      t1_add.right = t1_idx.out;
      t1_idx.in = t1_add.out;
      t1_idx.write_en = 1'd1;
      t1_idx_update[done] = t1_idx.done;
    }
    group t1_move {
      t1.addr0 = t1_idx.out;
      top_0_1.in = t1.read_data;
      top_0_1.write_en = 1'd1;
      t1_move[done] = top_0_1.done;
    }
    group l0_idx_init {
      l0_idx.in = 2'd3;
      l0_idx.write_en = 1'd1;
      l0_idx_init[done] = l0_idx.done;
    }
    group l0_idx_update {
      l0_add.left = 2'd1;
      l0_add.right = l0_idx.out;
      l0_idx.in = l0_add.out;
      l0_idx.write_en = 1'd1;
      l0_idx_update[done] = l0_idx.done;
    }
    group l0_move {
      l0.addr0 = l0_idx.out;
      left_0_0.in = l0.read_data;
      left_0_0.write_en = 1'd1;
      l0_move[done] = left_0_0.done;
    }
    group l1_idx_init {
      l1_idx.in = 2'd3;
      l1_idx.write_en = 1'd1;
      l1_idx_init[done] = l1_idx.done;
    }
    group l1_idx_update {
      l1_add.left = 2'd1;
      l1_add.right = l1_idx.out;
      l1_idx.in = l1_add.out;
      l1_idx.write_en = 1'd1;
      l1_idx_update[done] = l1_idx.done;
    }
    group l1_move {
      l1.addr0 = l1_idx.out;
      left_1_0.in = l1.read_data;
      left_1_0.write_en = 1'd1;
      l1_move[done] = left_1_0.done;
    }
    group pe_0_0_right_move {
      left_0_1.in = left_0_0.out;
      left_0_1.write_en = 1'd1;
      pe_0_0_right_move[done] = left_0_1.done;
    }
    group pe_0_0_down_move {
      top_1_0.in = top_0_0.out;
      top_1_0.write_en = 1'd1;
      pe_0_0_down_move[done] = top_1_0.done;
    }
    group pe_0_0_out_write {
      out_mem.addr0 = 3'd0;
      out_mem.write_data = pe_0_0.out;
      out_mem.write_en = 1'd1;
      pe_0_0_out_write[done] = out_mem.done;
    }
    group pe_0_1_down_move {
      top_1_1.in = top_0_1.out;
      top_1_1.write_en = 1'd1;
      pe_0_1_down_move[done] = top_1_1.done;
    }
    group pe_0_1_out_write {
      out_mem.addr0 = 3'd1;
      out_mem.write_data = pe_0_1.out;
      out_mem.write_en = 1'd1;
      pe_0_1_out_write[done] = out_mem.done;
    }
    group pe_1_0_right_move {
      left_1_1.in = left_1_0.out;
      left_1_1.write_en = 1'd1;
      pe_1_0_right_move[done] = left_1_1.done;
    }
    group pe_1_0_out_write {
      out_mem.addr0 = 3'd2;
      out_mem.write_data = pe_1_0.out;
      out_mem.write_en = 1'd1;
      pe_1_0_out_write[done] = out_mem.done;
    }
    group pe_1_1_out_write {
      out_mem.addr0 = 3'd3;
      out_mem.write_data = pe_1_1.out;
      out_mem.write_en = 1'd1;
      pe_1_1_out_write[done] = out_mem.done;
    }
  }
  control {
    seq {
      par {
        t0_idx_init;
        t1_idx_init;
        l0_idx_init;
        l1_idx_init;
      }
      par {
        t0_idx_update;
        l0_idx_update;
      }
      par {
        t0_move;
        l0_move;
      }
      par {
        t0_idx_update;
        l0_idx_update;
        t1_idx_update;
        l1_idx_update;
        invoke pe_0_0(top=top_0_0.out, left=left_0_0.out)();
      }
      par {
        t0_move;
        t1_move;
        pe_0_0_down_move;
        l0_move;
        pe_0_0_right_move;
        l1_move;
      }
      par {
        t0_idx_update;
        l0_idx_update;
        t1_idx_update;
        l1_idx_update;
        invoke pe_0_0(top=top_0_0.out, left=left_0_0.out)();
        invoke pe_0_1(top=top_0_1.out, left=left_0_1.out)();
        invoke pe_1_0(top=top_1_0.out, left=left_1_0.out)();
      }
      par {
        t0_move;
        t1_move;
        pe_0_0_down_move;
        pe_0_1_down_move;
        l0_move;
        pe_0_0_right_move;
        l1_move;
        pe_1_0_right_move;
      }
      par {
        t1_idx_update;
        l1_idx_update;
        invoke pe_0_0(top=top_0_0.out, left=left_0_0.out)();
        invoke pe_0_1(top=top_0_1.out, left=left_0_1.out)();
        invoke pe_1_0(top=top_1_0.out, left=left_1_0.out)();
        invoke pe_1_1(top=top_1_1.out, left=left_1_1.out)();
      }
      par {
        t1_move;
        pe_0_0_down_move;
        pe_0_1_down_move;
        pe_0_0_right_move;
        l1_move;
        pe_1_0_right_move;
      }
      par {
        invoke pe_0_1(top=top_0_1.out, left=left_0_1.out)();
        invoke pe_1_0(top=top_1_0.out, left=left_1_0.out)();
        invoke pe_1_1(top=top_1_1.out, left=left_1_1.out)();
      }
      par {
        pe_0_1_down_move;
        pe_1_0_right_move;
      }
      par {
        invoke pe_1_1(top=top_1_1.out, left=left_1_1.out)();
      }
      seq {
        pe_0_0_out_write;
        pe_0_1_out_write;
        pe_1_0_out_write;
        pe_1_1_out_write;
      }
    }
  }
}

component mac_pe(top: 32, left: 32) -> (out: 32) {
  cells {
    // Storage
    mul_out = std_reg(32);
    acc = std_reg(32);
    // Computation
    add = std_add(32);
    mult0 = std_unsyn_mult(32);
  }
  wires {
    group do_mul {
      mult0.left = top;
      mult0.right = left;
      mul_out.in = mult0.out;
      mul_out.write_en = 1'd1;
      do_mul[done] = mul_out.done;
    }
    group do_add {
      add.left = acc.out;
      add.right = mul_out.out;
      acc.in = add.out;
      acc.write_en = 1'd1;
      do_add[done] = acc.done;
    }
    out = acc.out;
  }
  control {
    seq {
      do_mul;
      do_add;
    }
  }
}