diff --git a/calyx-py/calyx/builder.py b/calyx-py/calyx/builder.py index a942e61fc5..0eb60fe952 100644 --- a/calyx-py/calyx/builder.py +++ b/calyx-py/calyx/builder.py @@ -637,6 +637,8 @@ def binary_use(self, left, right, cell, groupname=None): with self.comb_group(groupname) as comb_group: cell.left = left cell.right = right + if not cell.is_comb(): + cell.go = HI return CellAndGroup(cell, comb_group) def binary_use_names(self, cellname, leftname, rightname, groupname=None): @@ -718,6 +720,16 @@ def not_use(self, input, cellname=None, width=None): width = self.try_infer_width(width, input, input) return self.unary_use(input, self.not_(width, cellname)) + def mult_use(self, left, right, signed=False, cellname=None, width=None): + """Inserts wiring into `self` to compute `left` * `right`.""" + width = self.try_infer_width(width, left, right) + return self.binary_use(left, right, self.mult_pipe(width, cellname, signed)) + + def div_use(self, left, right, signed=False, cellname=None, width=None): + """Inserts wiring into `self` to compute `left` * `right`.""" + width = self.try_infer_width(width, left, right) + return self.binary_use(left, right, self.div_pipe(width, cellname, signed)) + def bitwise_flip_reg(self, reg, cellname=None): """Inserts wiring into `self` to bitwise-flip the contents of `reg` and put the result back into `reg`. @@ -885,18 +897,25 @@ def op_store_in_reg( right, cellname, width, - ans_reg=None, + ans_reg=None ): """Inserts wiring into `self` to perform `reg := left op right`, where `op_cell`, a Cell that performs some `op`, is provided. """ + + is_comb = op_cell.is_comb() ans_reg = ans_reg or self.reg(width, f"reg_{cellname}") with self.group(f"{cellname}_group") as op_group: op_cell.left = left op_cell.right = right - ans_reg.write_en = 1 - ans_reg.in_ = op_cell.out + + if not is_comb: + op_cell.go = HI + + ans_reg.write_en = 1 if is_comb else op_cell.done @ 1 + ans_reg.in_ = op_cell.out if is_comb else op_cell.done @ op_cell.out op_group.done = ans_reg.done + return op_group, ans_reg def add_store_in_reg( @@ -955,6 +974,35 @@ def neq_store_in_reg( cell = self.neq(width, cellname, signed) return self.op_store_in_reg(cell, left, right, cell.name, 1, ans_reg) + def mult_store_in_reg( + self, + left, + right, + ans_reg=None, + cellname=None, + width=None, + signed=False + ): + """Inserts wiring into `self` to perform `reg := left * right`.""" + width = width or self.try_infer_width(width, left, right) + cell = self.mult_pipe(width, cellname, signed) + return self.op_store_in_reg(cell, left, right, cell.name, width, ans_reg) + + def div_store_in_reg( + self, + left, + right, + ans_reg=None, + cellname=None, + width=None, + signed=False + ): + """Inserts wiring into `self` to perform `reg := left / right`.""" + width = width or self.try_infer_width(width, left, right) + cell = self.div_pipe(width, cellname, signed) + return self.op_store_in_reg(cell, left, right, cell.name, width, ans_reg) + + def infer_width(self, expr) -> int: """Infer the width of an expression.""" if isinstance(expr, int): # We can't infer the width of an integer. @@ -1342,6 +1390,22 @@ def is_primitive(self, prim_name) -> bool: and self._cell.comp.id == prim_name ) + def is_comb(self) -> bool: + return self._cell.comp.id in ( + "std_add", + "std_sub", + "std_lt", + "std_le", + "std_ge", + "std_gt", + "std_eq", + "std_neq", + "std_sgt", + "std_slt", + "std_fp_sgt", + "std_fp_slt", + ) + def is_comb_mem_d1(self) -> bool: """Check if the cell is a StdMemD1 cell.""" return self.is_primitive("comb_mem_d1")