back.pysim: new simulator backend (WIP).

This commit is contained in:
whitequark 2018-12-13 18:00:05 +00:00
parent 71f1f717c4
commit fb27c2520b
9 changed files with 437 additions and 17 deletions

View file

@ -10,7 +10,7 @@ from ..tools import *
__all__ = [
"Value", "Const", "Operator", "Mux", "Part", "Slice", "Cat", "Repl",
"Signal", "ClockSignal", "ResetSignal",
"Statement", "Assign", "Switch",
"Statement", "Assign", "Switch", "Delay", "Passive",
"ValueKey", "ValueDict", "ValueSet",
]
@ -216,17 +216,23 @@ class Const(Value):
nbits : int
signed : bool
"""
src_loc = None
def __init__(self, value, shape=None):
super().__init__()
self.value = int(value)
if shape is None:
shape = self.value.bit_length(), self.value < 0
shape = bits_for(self.value), self.value < 0
if isinstance(shape, int):
shape = shape, self.value < 0
self.nbits, self.signed = shape
if not isinstance(self.nbits, int) or self.nbits < 0:
raise TypeError("Width must be a positive integer")
mask = (1 << self.nbits) - 1
self.value &= mask
if self.signed and self.value >> (self.nbits - 1):
self.value |= ~mask
def shape(self):
return self.nbits, self.signed
@ -347,6 +353,8 @@ class Slice(Value):
raise IndexError("Cannot end slice {} bits into {}-bit value".format(end, n))
if end < 0:
end += n
if start > end:
raise IndexError("Slice start {} must be less than slice end {}".format(start, end))
super().__init__()
self.value = Value.wrap(value)
@ -680,6 +688,25 @@ class Switch(Statement):
return "(switch {!r} {})".format(self.test, " ".join(cases))
class Delay(Statement):
def __init__(self, interval):
self.interval = float(interval)
def _rhs_signals(self):
return ValueSet()
def __repr__(self):
return "(delay {:.3}us)".format(self.interval * 10e6)
class Passive(Statement):
def _rhs_signals(self):
return ValueSet()
def __repr__(self):
return "(passive)"
class ValueKey:
def __init__(self, value):
self.value = Value.wrap(value)

View file

@ -52,6 +52,11 @@ class Fragment:
signals = ValueSet()
signals |= self.ports.keys()
for domain, domain_signals in self.drivers.items():
if domain is not None:
cd = self.domains[domain]
signals.add(cd.clk)
if cd.rst is not None:
signals.add(cd.rst)
signals |= domain_signals
return signals