CIRCT 20.0.0git
Loading...
Searching...
No Matches
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
5from . import hw
6from . import seq
7from .._mlir_libs._circt._seq import *
8from ..dialects._ods_common import _cext as _ods_cext
9from ..ir import IntegerType, OpView, StringAttr, InsertionPoint
10from ..support import BackedgeBuilder, NamedValueOpView
11from ._seq_ops_gen import *
12from ._seq_ops_gen import _Dialect
13from .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.
21def 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
44class 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 @staticmethod
60 def init(op,
61 data_type,
62 input,
63 clk,
64 clockEnable=None,
65 *,
66 reset=None,
67 reset_value=None,
68 power_on_value=None,
69 name=None,
70 sym_name=None,
71 loc=None,
72 ip=None):
73 operands = [input, clk]
74 results = []
75 attributes = {}
76 results.append(data_type)
77 operand_segment_sizes = [1, 1]
78 if isinstance(op, CompRegOp):
79 if clockEnable is not None:
80 raise Exception("Clock enable not supported on compreg")
81 elif isinstance(op, CompRegClockEnabledOp):
82 if clockEnable is None:
83 raise Exception("Clock enable required on compreg.ce")
84 operands.append(clockEnable)
85 operand_segment_sizes.append(1)
86 else:
87 assert False, "Class not recognized"
88 if reset is not None and reset_value is not None:
89 operands.append(reset)
90 operands.append(reset_value)
91 operand_segment_sizes += [1, 1]
92 else:
93 operand_segment_sizes += [0, 0]
94 operands += [None, None]
95
96 if power_on_value is not None:
97 if isinstance(power_on_value.type, seq.ImmutableType):
98 pass
99 else:
100 if power_on_value.owner is None:
101 assert False, "Initial value must not be port"
102 elif isinstance(power_on_value.owner.opview, hw.ConstantOp):
103 init = InitialOp([seq.ImmutableType.get(power_on_value.type)], [])
104 init.body.blocks.append()
105 with InsertionPoint(init.body.blocks[0]):
106 cloned_constant = power_on_value.owner.clone()
107 seq.YieldOp(cloned_constant)
108
109 power_on_value = init.results[0]
110 else:
111 assert False, "Non-constant initial value not supported"
112 operands.append(power_on_value)
113 operand_segment_sizes.append(1)
114 else:
115 operands.append(None)
116 operand_segment_sizes.append(0)
117 if name is None:
118 attributes["name"] = StringAttr.get("")
119 else:
120 attributes["name"] = StringAttr.get(name)
121 if sym_name is not None:
122 attributes["inner_sym"] = hw.InnerSymAttr.get(StringAttr.get(sym_name))
123
124 op._ODS_OPERAND_SEGMENTS = operand_segment_sizes
125
126 OpView.__init__(
127 op,
128 op.build_generic(
129 attributes=attributes,
130 results=results,
131 operands=operands,
132 loc=loc,
133 ip=ip,
134 ),
135 )
136
137
139
140 def operand_names(self):
141 return ["input", "clk"]
142
143
144@_ods_cext.register_operation(_Dialect, replace=True)
146
147 def __init__(self, *args, **kwargs):
148 CompRegLike.init(self, *args, **kwargs)
149
150 @classmethod
151 def create(cls,
152 result_type,
153 reset=None,
154 reset_value=None,
155 name=None,
156 sym_name=None,
157 **kwargs):
158 return CompRegBuilder(cls,
159 result_type,
160 kwargs,
161 reset=reset,
162 reset_value=reset_value,
163 name=name,
164 sym_name=sym_name,
165 needs_result_type=True)
166
167
169
170 def operand_names(self):
171 return ["input", "clk", "clockEnable"]
172
173
174@_ods_cext.register_operation(_Dialect, replace=True)
176
177 def __init__(self, *args, **kwargs):
178 CompRegLike.init(self, *args, **kwargs)
179
180 @classmethod
181 def create(cls,
182 result_type,
183 reset=None,
184 reset_value=None,
185 name=None,
186 sym_name=None,
187 **kwargs):
189 result_type,
190 kwargs,
191 reset=reset,
192 reset_value=reset_value,
193 name=name,
194 sym_name=sym_name,
195 needs_result_type=True)
operand_names(self)
Definition seq.py:140
create(cls, result_type, reset=None, reset_value=None, name=None, sym_name=None, **kwargs)
Definition seq.py:187
__init__(self, *args, **kwargs)
Definition seq.py:177
create_initial_value(self, index, data_type, arg_name)
Definition seq.py:49
init(op, 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:72
__init__(self, *args, **kwargs)
Definition seq.py:147
create(cls, result_type, reset=None, reset_value=None, name=None, sym_name=None, **kwargs)
Definition seq.py:157
reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None)
Definition seq.py:21