https://bugs.libre-soc.org/show_bug.cgi?id=784
"""
-from dataclasses import dataclass, field, fields
from nmigen.hdl.ast import Signal, Value, Assert
from nmigen.hdl.dsl import Module
from nmutil.singlepipe import ControlBase
from nmutil.clz import CLZ, clz
+from nmutil.plain_data import plain_data
def cldivrem_shifting(n, d, shape):
return get_output()
-@dataclass(frozen=True, unsafe_hash=True)
+@plain_data(frozen=True, unsafe_hash=True)
class CLDivRemShape:
- width: int
- """bit-width of each of the carry-less div/rem inputs and outputs"""
+ __slots__ = "width", "steps_per_clock"
- steps_per_clock: int = 8
- """number of steps that should be taken per clock cycle"""
+ def __init__(self, width, steps_per_clock=8):
+ assert isinstance(width, int) and width >= 1, "invalid width"
+ assert (isinstance(steps_per_clock, int)
+ and steps_per_clock >= 1), "invalid steps_per_clock"
+ self.width = width
+ """bit-width of each of the carry-less div/rem inputs and outputs"""
- def __post_init__(self):
- assert isinstance(self.width, int) and self.width >= 1, "invalid width"
- assert (isinstance(self.steps_per_clock, int)
- and self.steps_per_clock >= 1), "invalid steps_per_clock"
+ self.steps_per_clock = steps_per_clock
+ """number of steps that should be taken per clock cycle"""
@property
def done_clock(self):
return (self.width - 1).bit_length()
-@dataclass(frozen=True, eq=False)
+@plain_data(frozen=True, eq=False)
class CLDivRemState:
- shape: CLDivRemShape
- name: str
- clock: Signal = field(init=False)
- substep: Signal = field(init=False)
- d: Signal = field(init=False)
- r: Signal = field(init=False)
- q: Signal = field(init=False)
- shift: Signal = field(init=False)
-
+ __slots__ = "shape", "name", "clock", "substep", "d", "r", "q", "shift"
def __init__(self, shape, *, name=None, src_loc_at=0):
assert isinstance(shape, CLDivRemShape)
if name is None:
name = Signal(src_loc_at=1 + src_loc_at).name
assert isinstance(name, str)
- clock = Signal(shape.clock_range, name=f"{name}_clock")
- substep = Signal(shape.substep_range, name=f"{name}_substep", reset=0)
- d = Signal(shape.d_width, name=f"{name}_d")
- r = Signal(shape.r_width, name=f"{name}_r")
- q = Signal(shape.q_width, name=f"{name}_q")
- shift = Signal(shape.shift_width, name=f"{name}_shift")
- object.__setattr__(self, "shape", shape)
- object.__setattr__(self, "name", name)
- object.__setattr__(self, "clock", clock)
- object.__setattr__(self, "substep", substep)
- object.__setattr__(self, "d", d)
- object.__setattr__(self, "r", r)
- object.__setattr__(self, "q", q)
- object.__setattr__(self, "shift", shift)
+ self.shape = shape
+ self.name = name
+ self.clock = Signal(shape.clock_range, name=f"{name}_clock")
+ self.substep = Signal(shape.substep_range, name=f"{name}_substep",
+ reset=0)
+ self.d = Signal(shape.d_width, name=f"{name}_d")
+ self.r = Signal(shape.r_width, name=f"{name}_r")
+ self.q = Signal(shape.q_width, name=f"{name}_q")
+ self.shift = Signal(shape.shift_width, name=f"{name}_shift")
def eq(self, rhs):
assert isinstance(rhs, CLDivRemState)
- for f in fields(CLDivRemState):
- if f.name in ("shape", "name"):
+ for f in CLDivRemState._fields:
+ if f in ("shape", "name"):
continue
- l = getattr(self, f.name)
- r = getattr(rhs, f.name)
+ l = getattr(self, f)
+ r = getattr(rhs, f)
yield l.eq(r)
@staticmethod
def eq_but_zero_substep(self, rhs, do_assert):
assert isinstance(rhs, CLDivRemState)
- for f in fields(CLDivRemState):
- if f.name in ("shape", "name"):
+ for f in CLDivRemState._fields:
+ if f in ("shape", "name"):
continue
- l = getattr(self, f.name)
- r = getattr(rhs, f.name)
- if f.name == "substep":
+ l = getattr(self, f)
+ r = getattr(rhs, f)
+ if f == "substep":
if do_assert:
yield Assert(r == 0)
r = 0