--- /dev/null
+import enum
+from nmigen import Elaboratable, Module, Signal
+from soc.fu.div.pipe_data import CoreInputData, CoreOutputData
+
+
+class FSMDivCoreConfig:
+ n_stages = 1
+ bit_width = 64
+ fract_width = 64
+
+
+class FSMDivCoreInputData:
+ def __init__(self, core_config, reset_less=True):
+ self.core_config = core_config
+ self.dividend = Signal(128, reset_less=reset_less)
+ self.divisor_radicand = Signal(64, reset_less=reset_less)
+ self.operation = DivPipeCoreOperation.create_signal(
+ reset_less=reset_less)
+
+ def __iter__(self):
+ """ Get member signals. """
+ yield self.dividend
+ yield self.divisor_radicand
+ yield self.operation
+
+ def eq(self, rhs):
+ """ Assign member signals. """
+ return [self.dividend.eq(rhs.dividend),
+ self.divisor_radicand.eq(rhs.divisor_radicand),
+ self.operation.eq(rhs.operation),
+ ]
+
+
+class FSMDivCoreOutputData:
+ def __init__(self, core_config, reset_less=True):
+ self.core_config = core_config
+ self.quotient_root = Signal(64, reset_less=reset_less)
+ self.remainder = Signal(3 * 64, reset_less=reset_less)
+
+ def __iter__(self):
+ """ Get member signals. """
+ yield self.quotient_root
+ yield self.remainder
+ return
+
+ def eq(self, rhs):
+ """ Assign member signals. """
+ return [self.quotient_root.eq(rhs.quotient_root),
+ self.remainder.eq(rhs.remainder)]
+
+
+class FSMDivCorePrev:
+ def __init__(self, pspec):
+ self.data_i = CoreInputData(pspec)
+ self.valid_i = Signal()
+ self.ready_o = Signal()
+
+ def __iter__(self):
+ yield from self.data_i
+ yield self.valid_i
+ yield self.ready_o
+
+
+class FSMDivCoreNext:
+ def __init__(self, pspec):
+ self.data_o = CoreOutputData(pspec)
+ self.valid_o = Signal()
+ self.ready_i = Signal()
+
+ def __iter__(self):
+ yield from self.data_o
+ yield self.valid_o
+ yield self.ready_i
+
+
+class DivState(enum.Enum):
+ Empty = 0
+ Computing = 1
+ WaitingOnOutput = 2
+
+
+class FSMDivCoreStage(Elaboratable):
+ def __init__(self, pspec):
+ self.p = FSMDivCorePrev(pspec)
+ self.n = FSMDivCoreNext(pspec)
+ self.saved_input_data = CoreInputData(pspec)
+ self.canceled = Signal()
+ self.state = Signal(DivState, reset=DivState.Empty)
+
+ def elaborate(self, platform):
+ m = Module()
+
+ # TODO: calculate self.canceled from self.p.data_i.ctx
+ m.d.comb += self.canceled.eq(False)
+
+ # TODO(programmerjake): finish
+
+ return m
+
+ def __iter__(self):
+ yield from self.p
+ yield from self.n
+
+ def ports(self):
+ return list(self)
self.cr0 = self.cr_a
-class DivPipeKindConfig:
+class DivPipeKindConfigBase:
def __init__(self,
core_config,
core_input_data_class,
core_interstage_data_class,
- core_output_data_class,
- core_setup_stage_class,
- core_calculate_stage_class,
- core_final_stage_class):
+ core_output_data_class):
self.core_config = core_config
self.core_input_data_class = core_input_data_class
self.core_interstage_data_class = core_interstage_data_class
self.core_output_data_class = core_output_data_class
+
+
+class DivPipeKindConfigCombPipe(DivPipeKindConfigBase):
+ def __init__(self,
+ core_config,
+ core_input_data_class,
+ core_interstage_data_class,
+ core_output_data_class,
+ core_setup_stage_class,
+ core_calculate_stage_class,
+ core_final_stage_class):
+ super().__init__(core_config, core_input_data_class,
+ core_interstage_data_class, core_output_data_class)
self.core_setup_stage_class = core_setup_stage_class
self.core_calculate_stage_class = core_calculate_stage_class
self.core_final_stage_class = core_final_stage_class
+class DivPipeKindConfigFSM(DivPipeKindConfigBase):
+ def __init__(self,
+ core_config,
+ core_input_data_class,
+ core_output_data_class,
+ core_stage_class):
+ core_interstage_data_class = None
+ super().__init__(core_config, core_input_data_class,
+ core_interstage_data_class, core_output_data_class)
+ self.core_stage_class = core_stage_class
+
+
class DivPipeKind(enum.Enum):
# use ieee754.div_rem_sqrt_rsqrt.core.DivPipeCore*
DivPipeCore = enum.auto()
# simulation
SimOnly = enum.auto()
# use a FSM-based div core
- FSMCore = enum.auto()
+ FSMDivCore = enum.auto()
@property
def config(self):
if self == DivPipeKind.DivPipeCore:
- return DivPipeKindConfig(
+ return DivPipeKindConfigCombPipe(
core_config=DivPipeCoreConfig(
bit_width=64,
fract_width=64,
core_setup_stage_class=DivPipeCoreSetupStage,
core_calculate_stage_class=DivPipeCoreCalculateStage,
core_final_stage_class=DivPipeCoreFinalStage)
- elif self == DivPipeKind.SimOnly:
+ if self == DivPipeKind.SimOnly:
# import here to avoid import loop
from soc.fu.div.sim_only_core import (
SimOnlyCoreConfig, SimOnlyCoreInputData,
SimOnlyCoreInterstageData, SimOnlyCoreOutputData,
SimOnlyCoreSetupStage, SimOnlyCoreCalculateStage,
SimOnlyCoreFinalStage)
- return DivPipeKindConfig(
+ return DivPipeKindConfigCombPipe(
core_config=SimOnlyCoreConfig(),
core_input_data_class=SimOnlyCoreInputData,
core_interstage_data_class=SimOnlyCoreInterstageData,
core_setup_stage_class=SimOnlyCoreSetupStage,
core_calculate_stage_class=SimOnlyCoreCalculateStage,
core_final_stage_class=SimOnlyCoreFinalStage)
- else:
- # ensure we didn't forget any cases
- # -- I wish Python had a switch/match statement
- assert self == DivPipeKind.FSMCore
- # TODO(programmerjake): implement
- raise NotImplementedError()
+ # ensure we didn't forget any cases
+ # -- I wish Python had a switch/match statement
+ assert self == DivPipeKind.FSMDivCore
+
+ # import here to avoid import loop
+ from soc.fu.div.fsm import (
+ FSMDivCoreConfig, FSMDivCoreInputData,
+ FSMDivCoreOutputData, FSMDivCoreStage)
+ return DivPipeKindConfigFSM(
+ core_config=FSMDivCoreConfig(),
+ core_input_data_class=FSMDivCoreInputData,
+ core_output_data_class=FSMDivCoreOutputData,
+ core_stage_class=FSMDivCoreStage)
class DivPipeSpec(CommonPipeSpec):
class CoreInterstageData(CoreBaseData):
def __init__(self, pspec):
- super().__init__(pspec,
- pspec.div_pipe_kind.config.core_interstage_data_class)
+ data_class = pspec.div_pipe_kind.config.core_interstage_data_class
+ if data_class is None:
+ raise ValueError(
+ f"CoreInterstageData not supported for {pspec.div_pipe_kind}")
+ super().__init__(pspec, data_class)
class CoreOutputData(CoreBaseData):