calyx 0.6.0

Compiler Infrastructure for Hardware Accelerator Generation
import "primitives/core.futil";
import "primitives/memories.futil";
component func(@go go: 1, @clk clk: 1, @reset reset: 1, in_out: 32, in_done: 1) -> (@stable processed: 32, @done done: 1, in_in: 32, in_write_en: 1) {
  cells {
    acc_r = std_reg(32);
    incr = std_add(32);
    add = std_add(32);
  }
  wires {
    group apply {
      incr.left = in_out;
      incr.right = 32'd10;
      in_in = incr.out;
      in_write_en = 1'd1;
      apply[done] = in_done;
    }
    group bump_proc {
      add.left = acc_r.out;
      add.right = 32'd1;
      acc_r.in = add.out;
      acc_r.write_en = 1'd1;
      bump_proc[done] = acc_r.done;
    }
    processed = acc_r.out;
  }
  control {
    seq {
      apply;
      bump_proc;
    }
  }
}
component map_f(@go go: 1, @clk clk: 1, @reset reset: 1, func_processed: 32, func_done: 1, func_in_in: 32, func_in_write_en: 1, in_read_data: 32, in_write_done: 1, in_read_done: 1, out_read_data: 32, out_write_done: 1, out_read_done: 1) -> (@done done: 1, func_go: 1, func_in_done: 1, func_in_out: 32, in_addr0: 4, in_write_en: 1, in_write_data: 32, in_read_en: 1, out_addr0: 4, out_write_en: 1, out_write_data: 32, out_read_en: 1) {
  cells {
    idx = std_reg(4);
    lt = std_lt(4);
    add = std_add(4);
    r = std_reg(32);
  }
  wires {
    group init {
      idx.write_en = 1'd1;
      idx.in = 4'd0;
      init[done] = idx.done;
    }
    group incr {
      add.left = idx.out;
      add.right = 4'd1;
      idx.in = add.out;
      idx.write_en = 1'd1;
      incr[done] = idx.done;
    }
    group read_in {
      in_read_en = 1'd1;
      in_addr0 = idx.out;
      read_in[done] = in_read_done;
    }
    group write_r {
      r.write_en = 1'd1;
      r.in = in_read_data;
      write_r[done] = r.done;
    }
    group write_out {
      out_write_en = 1'd1;
      out_addr0 = idx.out;
      out_write_data = r.out;
      write_out[done] = out_write_done;
    }
    group invoke0 {
      r.in = func_in_in;
      r.write_en = func_in_write_en;
      func_in_out = r.out;
      func_in_done = r.done;
      func_go = 1'd1;
      invoke0[done] = func_done;
    }
    comb group cmp {
      lt.left = idx.out;
      lt.right = 4'd10;
    }
  }
  control {
    seq {
      init;
      while lt.out with cmp {
        seq {
          read_in;
          write_r;
          invoke0;
          write_out;
          incr;
        }
      }
    }
  }
}
component main(@go go: 1, @clk clk: 1, @reset reset: 1) -> (@done done: 1) {
  cells {
    @external A = seq_mem_d1(32, 10, 4);
    @external B = seq_mem_d1(32, 10, 4);
    @external stats = seq_mem_d1(32, 2, 2);
    f1 = func();
    f2 = func();
    map = map_f();
  }
  wires {
    group invoke0 {
      A.addr0 = map.in_addr0;
      A.write_en = map.in_write_en;
      A.write_data = map.in_write_data;
      A.read_en = map.in_read_en;
      map.in_read_data = A.read_data;
      map.in_write_done = A.write_done;
      map.in_read_done = A.read_done;
      map.func_processed = f2.processed;
      f2.go = map.func_go;
      map.func_done = f2.done;
      f2.in_done = map.func_in_done;
      f2.in_out = map.func_in_out;
      map.func_in_in = f2.in_in;
      map.func_in_write_en = f2.in_write_en;
      A.addr0 = map.out_addr0;
      A.write_en = map.out_write_en;
      A.write_data = map.out_write_data;
      A.read_en = map.out_read_en;
      map.out_read_data = A.read_data;
      map.out_write_done = A.write_done;
      map.out_read_done = A.read_done;
      map.go = 1'd1;
      invoke0[done] = map.done;
    }
    static<1> group f1_stats {
      stats.addr0 = 2'd0;
      stats.write_data = f1.processed;
      stats.write_en = 1'd1;
    }
    static<1> group f2_stats {
      stats.addr0 = 2'd1;
      stats.write_data = f2.processed;
      stats.write_en = 1'd1;
    }
  }
  control {
    seq {
      invoke0;
      f1_stats;
      f2_stats;
    }
  }
}