docs
This commit is contained in:
1 parent
8957db48ab
commit
ecb7171c37
3 files changed
+30
-23
No files matched your search
@@ -81,6 +81,7 @@ def hr_time(seconds):
|
|||||||
|
|
||||||
|
|
||||||
def batchrange(nitems, maxsize):
|
def batchrange(nitems, maxsize):
|
||||||
|
assert nitems >= maxsize
|
||||||
for offset in range(0, nitems, maxsize):
|
for offset in range(0, nitems, maxsize):
|
||||||
yield offset, min(nitems-offset, maxsize)
|
yield offset, min(nitems-offset, maxsize)
|
||||||
|
|
||||||
|
|||||||
+27
-23
@@ -11,18 +11,18 @@ import math
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from . import numba, logic, hr_bytes, sim
|
from . import numba, logic, hr_bytes, sim
|
||||||
|
from .circuit import Circuit
|
||||||
|
|
||||||
class LogicSim(sim.SimOps):
|
class LogicSim(sim.SimOps):
|
||||||
"""A bit-parallel naïve combinational simulator for 2-, 4-, or 8-valued logic.
|
"""A bit-parallel naïve combinational simulator for 2-, 4-, or 8-valued logic.
|
||||||
|
|
||||||
:param circuit: The circuit to simulate.
|
:param circuit: The circuit to simulate.
|
||||||
:type circuit: :py:class:`~kyupy.circuit.Circuit`
|
|
||||||
:param sims: The number of parallel logic simulations to perform.
|
:param sims: The number of parallel logic simulations to perform.
|
||||||
:type sims: int
|
|
||||||
:param m: The arity of the logic, must be 2, 4, or 8.
|
:param m: The arity of the logic, must be 2, 4, or 8.
|
||||||
:type m: int
|
:param c_reuse: If True, intermediate signal values may get overwritten when not needed anymore.
|
||||||
|
:param strip_forks: If True, forks are not included in the simulation model.
|
||||||
"""
|
"""
|
||||||
def __init__(self, circuit, sims=8, m=8, c_reuse=False, strip_forks=False):
|
def __init__(self, circuit: Circuit, sims: int = 8, m: int = 8, c_reuse: bool = False, strip_forks: bool = False):
|
||||||
assert m in [2, 4, 8]
|
assert m in [2, 4, 8]
|
||||||
super().__init__(circuit, c_reuse=c_reuse, strip_forks=strip_forks)
|
super().__init__(circuit, c_reuse=c_reuse, strip_forks=strip_forks)
|
||||||
self.m = m
|
self.m = m
|
||||||
@@ -32,26 +32,25 @@ class LogicSim(sim.SimOps):
|
|||||||
|
|
||||||
self.c = np.zeros((self.c_len, self.mdim, nbytes), dtype=np.uint8)
|
self.c = np.zeros((self.c_len, self.mdim, nbytes), dtype=np.uint8)
|
||||||
self.s = np.zeros((2, self.s_len, 3, nbytes), dtype=np.uint8)
|
self.s = np.zeros((2, self.s_len, 3, nbytes), dtype=np.uint8)
|
||||||
|
"""Logic values of the sequential elements (flip-flops) and ports.
|
||||||
|
|
||||||
|
The elements are as follows:
|
||||||
|
|
||||||
|
* ``s[0]`` Assigned values. Simulator will read (P)PI value from here.
|
||||||
|
* ``s[1]`` Result values. Simulator will write (P)PO values here.
|
||||||
|
"""
|
||||||
self.s[:,:,1,:] = 255 # unassigned
|
self.s[:,:,1,:] = 255 # unassigned
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'<LogicSim {self.circuit.name} sims={self.sims} m={self.m} state_mem={hr_bytes(self.c.nbytes)}>'
|
return f'{{name: "{self.circuit.name}", sims: {self.sims}, m: {self.m}, c_bytes: {self.c.nbytes}}}'
|
||||||
|
|
||||||
def s_to_c(self):
|
def s_to_c(self):
|
||||||
"""Assign stimuli to the primary inputs and state-elements (flip-flops).
|
"""Copies the values from ``s[0]`` the inputs of the combinational portion.
|
||||||
|
|
||||||
:param stimuli: The input data to assign. Must be in bit-parallel storage format and in a compatible shape.
|
|
||||||
:type stimuli: :py:class:`~kyupy.logic.BPArray`
|
|
||||||
:returns: The given stimuli object.
|
|
||||||
"""
|
"""
|
||||||
self.c[self.pippi_c_locs] = self.s[0, self.pippi_s_locs, :self.mdim]
|
self.c[self.pippi_c_locs] = self.s[0, self.pippi_s_locs, :self.mdim]
|
||||||
|
|
||||||
def c_to_s(self):
|
def c_to_s(self):
|
||||||
"""Capture the current values at the primary outputs and in the state-elements (flip-flops).
|
"""Copies the results of the combinational portion to ``s[1]``.
|
||||||
|
|
||||||
For primary outputs, the logic value is stored unmodified in the given target array.
|
|
||||||
For flip-flops, the logic value is either stored unmodified (`ff_transitions=False`)
|
|
||||||
or constructed from the previous state and the new state (`ff_transitions=True`).
|
|
||||||
"""
|
"""
|
||||||
self.s[1, self.poppo_s_locs, :self.mdim] = self.c[self.poppo_c_locs]
|
self.s[1, self.poppo_s_locs, :self.mdim] = self.c[self.poppo_c_locs]
|
||||||
if self.mdim == 1:
|
if self.mdim == 1:
|
||||||
@@ -103,22 +102,27 @@ class LogicSim(sim.SimOps):
|
|||||||
if inject_cb is not None: inject_cb(o0, self.s[o0])
|
if inject_cb is not None: inject_cb(o0, self.s[o0])
|
||||||
|
|
||||||
def s_ppo_to_ppi(self):
|
def s_ppo_to_ppi(self):
|
||||||
|
"""Constructs a new assignment based on the current data in ``s``.
|
||||||
|
|
||||||
|
Use this function for simulating consecutive clock cycles.
|
||||||
|
|
||||||
|
For 2-valued or 4-valued simulations, all valued from PPOs (in ``s[1]``) and copied to the PPIs (in ``s[0]).
|
||||||
|
For 8-valued simulations, PPI transitions are constructed from the initial values of the assignment and the
|
||||||
|
final values of the results.
|
||||||
|
"""
|
||||||
# TODO: handle latches correctly
|
# TODO: handle latches correctly
|
||||||
if self.m == 2:
|
if self.mdim < 3:
|
||||||
self.s[0, self.ppio_s_locs, 0] = self.s[1, self.ppio_s_locs, 0]
|
self.s[0, self.ppio_s_locs] = self.s[1, self.ppio_s_locs]
|
||||||
else:
|
else:
|
||||||
self.s[0, self.ppio_s_locs, 1] = self.s[0, self.ppio_s_locs, 0] # initial value is previously assigned final value
|
self.s[0, self.ppio_s_locs, 1] = self.s[0, self.ppio_s_locs, 0] # initial value is previously assigned final value
|
||||||
self.s[0, self.ppio_s_locs, 0] = self.s[1, self.ppio_s_locs, 0] # final value is newly captured final value
|
self.s[0, self.ppio_s_locs, 0] = self.s[1, self.ppio_s_locs, 0] # final value is newly captured final value
|
||||||
self.s[0, self.ppio_s_locs, 2] = self.s[0, self.ppio_s_locs, 0] ^ self.s[0, self.ppio_s_locs, 1] # TODO: not correct for X, -
|
self.s[0, self.ppio_s_locs, 2] = self.s[0, self.ppio_s_locs, 0] ^ self.s[0, self.ppio_s_locs, 1] # TODO: not correct for X, -
|
||||||
|
|
||||||
def cycle(self, cycles=1, inject_cb=None):
|
def cycle(self, cycles: int = 1, inject_cb=None):
|
||||||
"""Assigns the given state, propagates it and captures the new state.
|
"""Assigns the given state, propagates it and captures the new state.
|
||||||
|
|
||||||
:param state: A bit-parallel array in a compatible shape holding the current circuit state.
|
:param cycles: The number of cycles to simulate.
|
||||||
The contained data is assigned to the PI and PPI and overwritten by data at the PO and PPO after
|
:param inject_cb: A callback function for manipulating intermediate signal values. See :py:func:`c_prop`.
|
||||||
propagation.
|
|
||||||
:type state: :py:class:`~kyupy.logic.BPArray`
|
|
||||||
:param inject_cb: A callback function for manipulating intermediate signal values. See :py:func:`propagate`.
|
|
||||||
:returns: The given state object.
|
:returns: The given state object.
|
||||||
"""
|
"""
|
||||||
for _ in range(cycles):
|
for _ in range(cycles):
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class WaveSim(sim.SimOps):
|
|||||||
The remaining values are written by ``c_to_s()``.
|
The remaining values are written by ``c_to_s()``.
|
||||||
|
|
||||||
The elements are as follows:
|
The elements are as follows:
|
||||||
|
|
||||||
* ``s[0]`` (P)PI initial value
|
* ``s[0]`` (P)PI initial value
|
||||||
* ``s[1]`` (P)PI transition time
|
* ``s[1]`` (P)PI transition time
|
||||||
* ``s[2]`` (P)PI final value
|
* ``s[2]`` (P)PI final value
|
||||||
@@ -75,6 +76,7 @@ class WaveSim(sim.SimOps):
|
|||||||
* ``s[10]`` Overflow indicator: If non-zero, some signals in the input cone of this output had more
|
* ``s[10]`` Overflow indicator: If non-zero, some signals in the input cone of this output had more
|
||||||
transitions than specified in ``c_caps``. Some transitions have been discarded, the
|
transitions than specified in ``c_caps``. Some transitions have been discarded, the
|
||||||
final values in the waveforms are still valid.
|
final values in the waveforms are still valid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.simctl_int = np.zeros((2, sims), dtype=np.int32)
|
self.simctl_int = np.zeros((2, sims), dtype=np.int32)
|
||||||
|
|||||||
Reference in new issue
Block a user