CIRCT  20.0.0git
seq.py
Go to the documentation of this file.
1 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2 # See https://llvm.org/LICENSE.txt for license information.
3 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4 
5 from . import hw
6 from . import seq
7 from .._mlir_libs._circt._seq import *
8 from ..dialects._ods_common import _cext as _ods_cext
9 from ..ir import IntegerType, OpView, StringAttr, InsertionPoint
10 from ..support import BackedgeBuilder, NamedValueOpView
11 from ._seq_ops_gen import *
12 from ._seq_ops_gen import _Dialect
13 from .seq import CompRegOp, InitialOp
14 
15 
16 # Create a computational register whose input is the given value, and is clocked
17 # by the given clock. If a reset is provided, the register will be reset by that
18 # signal. If a reset value is provided, the register will reset to that,
19 # otherwise it will reset to zero. If name is provided, the register will be
20 # named.
21 def reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None):
22  from . import hw
23  from ..ir import IntegerAttr
24  value_type = value.type
25  if reset:
26  if not reset_value:
27  zero = IntegerAttr.get(value_type, 0)
28  reset_value = hw.ConstantOp(zero).result
29  return CompRegOp.create(value_type,
30  input=value,
31  clk=clock,
32  reset=reset,
33  reset_value=reset_value,
34  name=name,
35  sym_name=sym_name).data.value
36  else:
37  return CompRegOp.create(value_type,
38  input=value,
39  clk=clock,
40  name=name,
41  sym_name=sym_name).data.value
42 
43 
44 class CompRegLikeBuilder(NamedValueOpView):
45 
46  def result_names(self):
47  return ["data"]
48 
49  def create_initial_value(self, index, data_type, arg_name):
50  if arg_name == "input":
51  operand_type = data_type
52  else:
53  operand_type = IntegerType.get_signless(1)
54  return BackedgeBuilder.create(operand_type, arg_name, self)
55 
56 
58 
59  def __init__(self,
60  data_type,
61  input,
62  clk,
63  clockEnable=None,
64  *,
65  reset=None,
66  reset_value=None,
67  power_on_value=None,
68  name=None,
69  sym_name=None,
70  loc=None,
71  ip=None):
72  operands = [input, clk]
73  results = []
74  attributes = {}
75  results.append(data_type)
76  operand_segment_sizes = [1, 1]
77  if isinstance(self, CompRegOp):
78  if clockEnable is not None:
79  raise Exception("Clock enable not supported on compreg")
80  elif isinstance(self, CompRegClockEnabledOp):
81  if clockEnable is None:
82  raise Exception("Clock enable required on compreg.ce")
83  operands.append(clockEnable)
84  operand_segment_sizes.append(1)
85  else:
86  assert False, "Class not recognized"
87  if reset is not None and reset_value is not None:
88  operands.append(reset)
89  operands.append(reset_value)
90  operand_segment_sizes += [1, 1]
91  else:
92  operand_segment_sizes += [0, 0]
93  operands += [None, None]
94 
95  if power_on_value is not None:
96  if isinstance(power_on_value.type, seq.ImmutableType):
97  pass
98  else:
99  if power_on_value.owner is None:
100  assert False, "Initial value must not be port"
101  elif isinstance(power_on_value.owner.opview, hw.ConstantOp):
102  init = InitialOp([seq.ImmutableType.get(power_on_value.type)], [])
103  init.body.blocks.append()
104  with InsertionPoint(init.body.blocks[0]):
105  cloned_constant = power_on_value.owner.clone()
106  seq.YieldOp(cloned_constant)
107 
108  power_on_value = init.results[0]
109  else:
110  assert False, "Non-constant initial value not supported"
111  operands.append(power_on_value)
112  operand_segment_sizes.append(1)
113  else:
114  operands.append(None)
115  operand_segment_sizes.append(0)
116  if name is None:
117  attributes["name"] = StringAttr.get("")
118  else:
119  attributes["name"] = StringAttr.get(name)
120  if sym_name is not None:
121  attributes["inner_sym"] = hw.InnerSymAttr.get(StringAttr.get(sym_name))
122 
123  self._ODS_OPERAND_SEGMENTS_ODS_OPERAND_SEGMENTS = operand_segment_sizes
124 
125  OpView.__init__(
126  self,
127  self.build_generic(
128  attributes=attributes,
129  results=results,
130  operands=operands,
131  loc=loc,
132  ip=ip,
133  ),
134  )
135 
136 
138 
139  def operand_names(self):
140  return ["input", "clk"]
141 
142 
143 @_ods_cext.register_operation(_Dialect, replace=True)
145 
146  @classmethod
147  def create(cls,
148  result_type,
149  reset=None,
150  reset_value=None,
151  name=None,
152  sym_name=None,
153  **kwargs):
154  return CompRegBuilder(cls,
155  result_type,
156  kwargs,
157  reset=reset,
158  reset_value=reset_value,
159  name=name,
160  sym_name=sym_name,
161  needs_result_type=True)
162 
163 
165 
166  def operand_names(self):
167  return ["input", "clk", "clockEnable"]
168 
169 
170 @_ods_cext.register_operation(_Dialect, replace=True)
172 
173  @classmethod
174  def create(cls,
175  result_type,
176  reset=None,
177  reset_value=None,
178  name=None,
179  sym_name=None,
180  **kwargs):
181  return CompRegClockEnabledBuilder(cls,
182  result_type,
183  kwargs,
184  reset=reset,
185  reset_value=reset_value,
186  name=name,
187  sym_name=sym_name,
188  needs_result_type=True)
def operand_names(self)
Definition: seq.py:139
def create(cls, result_type, reset=None, reset_value=None, name=None, sym_name=None, **kwargs)
Definition: seq.py:180
def create_initial_value(self, index, data_type, arg_name)
Definition: seq.py:49
def result_names(self)
Definition: seq.py:46
def __init__(self, data_type, input, clk, clockEnable=None, *reset=None, reset_value=None, power_on_value=None, name=None, sym_name=None, loc=None, ip=None)
Definition: seq.py:71
_ODS_OPERAND_SEGMENTS
Definition: seq.py:123
def create(cls, result_type, reset=None, reset_value=None, name=None, sym_name=None, **kwargs)
Definition: seq.py:153
def reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None)
Definition: seq.py:21