calyx 0.7.1

Compiler Infrastructure for Hardware Accelerator Generation
import "core.futil";
import "binary_operators.futil";

extern "math.sv" {
  // Fixed point square root operator, using a digit-by-digit algorithm.
  // en.wikipedia.org/wiki/Methods_of_computing_square_roots#Digit-by-digit_calculation
  primitive fp_sqrt[
    WIDTH, INT_WIDTH, FRAC_WIDTH
  ](
    @clk clk: 1,
    @reset reset: 1,
    @write_together(1) @go go: 1,
    @write_together(1) in: WIDTH
  ) -> (
    @stable out: WIDTH,
    @done done: 1
  );

  primitive sqrt[
    WIDTH
  ](
    @clk clk: 1,
    @reset reset: 1,
    @write_together(1) @go go: 1,
    @write_together(1) in: WIDTH
  ) -> (
    @stable out: WIDTH,
    @done done: 1
  );
}

// Computes the unsigned value b^e, where
// b is the `base` and e is the `exp`.
component pow(base: 32, exp: 32) -> (out: 32) {
  cells {
    t = std_reg(32);
    count = std_reg(32);
    mul = std_mult_pipe(32);
    lt = std_lt(32);
    incr = std_add(32);
  }
  wires {
    group init<"static"=1> {
      t.in = 32'd1;
      t.write_en = 1'd1;
      count.in = 32'd0;
      count.write_en = 1'd1;
      init[done] = t.done & count.done ? 1'd1;
    }
    group do_mul {
      mul.left = base;
      mul.right = t.out;
      mul.go = !mul.done ? 1'd1;
      t.in = mul.out;
      t.write_en = mul.done;
      do_mul[done] = t.done;
    }
    group incr_count<"static"=1> {
      incr.left = 32'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 = t.out;
  }
  control {
    seq {
      init;
      while lt.out with cond {
        par { do_mul; incr_count; }
      }
    }
  }
}