calyx 0.7.1

Compiler Infrastructure for Hardware Accelerator Generation
import "primitives/core.futil";
import "primitives/memories/comb.futil";
import "primitives/binary_operators.futil";

component exponent(base: 32, exp: 4) -> (out: 32) {
  cells {
    pow = std_reg(32);
    count = std_reg(4);
    mul = std_mult_pipe(32);
    lt = std_lt(4);
    incr = std_add(4);
    const0 = std_const(4, 3);
  }
  wires {
    group init<"static"=1> {
      pow.in = 32'd1;
      pow.write_en = 1'd1;
      count.in = 4'd0;
      count.write_en = 1'd1;
      init[done] = pow.done & count.done ? 1'd1;
    }
    group do_mul {
      mul.left = base;
      mul.right = pow.out;
      mul.go = !mul.done ? 1'd1;
      pow.in = mul.out;
      pow.write_en = mul.done;
      do_mul[done] = pow.done;
    }
    group incr_count<"static"=1> {
      incr.left = 4'd1;
      incr.right = count.out;
      count.in = incr.out;
      count.write_en = 1'd1;
      incr_count[done] = count.done;
    }
    comb group cond {
      lt.right = exp;
      lt.left = count.out;
    }

    out = pow.out;
  }
  control {
    seq {
      init;
      while lt.out with cond {
        par { do_mul; incr_count; }
      }
    }
  }
}

component main() -> () {
  cells {
    @external(1) a0 = comb_mem_d1(32,10,4);
    a_read0_0 = std_reg(32);
    add0 = std_add(4);
    const0 = std_const(4,0);
    const1 = std_const(4,9);
    const2 = std_const(4,1);
    const3 = std_const(4,3);
    exp0 = exponent();
    i0 = std_reg(4);
    le0 = std_le(4);
    tmp_0 = std_reg(32);
  }
  wires {
    comb group cond0 {
      le0.left = i0.out;
      le0.right = const1.out;
    }
    group let0 {
      i0.in = const0.out;
      i0.write_en = 1'd1;
      let0[done] = i0.done;
    }
    group let1 {
      tmp_0.in = exp0.out;
      tmp_0.write_en = 1'd1;
      let1[done] = tmp_0.done;
    }
    group upd0 {
      a_read0_0.write_en = 1'd1;
      a0.addr0 = i0.out;
      a_read0_0.in = 1'd1 ? a0.read_data;
      upd0[done] = a_read0_0.done ? 1'd1;
    }
    group upd1 {
      a0.addr0 = i0.out;
      a0.write_en = 1'd1;
      a0.write_data = 1'd1 ? tmp_0.out;
      upd1[done] = a0.done ? 1'd1;
    }
    group upd2 {
      i0.write_en = 1'd1;
      add0.left = i0.out;
      add0.right = const2.out;
      i0.in = 1'd1 ? add0.out;
      upd2[done] = i0.done ? 1'd1;
    }
  }
  control {
    seq {
      let0;
      while le0.out with cond0 {
        seq {
          upd0;
          invoke exp0(base = a_read0_0.out, exp = const3.out)();
          let1;
          upd1;
          upd2;
        }
      }
    }
  }
}