def test_shift_register(): N = 4 Register4 = DefineRegister(4) T = Bits(N) class ShiftRegister(Circuit): name = "ShiftRegister" IO = ["I", In(T), "O", Out(T), "CLK", In(Clock)] @classmethod def definition(io): regs = [Register4() for _ in range(N)] wireclock(io, regs) wire(io.I, regs[0].I) fold(regs, foldargs={"I": "O"}) wire(regs[-1].O, io.O) simulator = PythonSimulator(ShiftRegister, clock=ShiftRegister.CLK) expected = [0, 0, 0] + list(range(0, 1 << N, 3))[:-3] actual = [] for i in range(0, 1 << N, 3): simulator.set_value(ShiftRegister.I, uint(i, N)) simulator.advance(2) actual.append(seq2int(simulator.get_value(ShiftRegister.O))) assert actual == expected
def store_value(inst_name, wire_name, value, scope, isinput, cycle, values): if not isinstance(value, list): value = [value] value = seq2int(value) inout = 'inputs' if isinput else 'outputs' values[scope.value()][inst_name][inout][wire_name].append(value)
def LUT(init, N=None, **kwargs): """ n-bit LUT I : In(Bits(n)), O : Out(Bit) """ if isinstance(init, Sequence): if N is None: if 2**N < len(init): raise ValueError("init is too large for N={}".format(N)) else: N = math.clog2(len(init)) init = seq2int(init) else: if N is None: raise ValueError("N requires for not sequence init") io = [] for i in range(N): io += ["I{}".format(i), In(Bit)] io += ["O", Out(Bit)] class LUT(Circuit): name = "LUT{}_{}".format(N, init) IO = io @classmethod def definition(cls): lutN = DeclareCoreirLUT(N, init)() for i in range(N): wire(getattr(lutN, "in")[i], getattr(cls, "I{}".format(i))) wire(lutN.out, cls.O) return LUT()
def tick_sim_collect_outputs(): sim.evaluate() sim.advance_cycle() if sim.get_value(LineBufferDef.valid, scope): actual.append([[ seq2int(sim.get_value(LineBufferDef.O[par][pix], scope)) for pix in range(window_width) ] for par in range(parallelism)])
def lfsr_sim(): regs = int2seq(init, N) while True: O = seq2int(regs) print(O) yield O I = 0 for tap in taps: I ^= regs[tap - 1] regs = [I] + regs[:-1]
def _RegisterName(name, n, init, ce, r): name += str(n) if ce: name += 'CE' if r: name += 'R' if isinstance(init, Sequence): init = seq2int(init) if init != 0: name += "_%04X" % init return name
def mux(I, S, **kwargs): if isinstance(S, int): return I[S] elif S.const(): return I[seq2int(S.bits())] T = type(I[0]) # Support using Bits(1) for select on 2 elements if len(I) == 2 and isinstance(S, m.Array) and \ issubclass(S.T, m.Digital) and len(S) == 1: S = S[0] return Mux(len(I), T=T, **kwargs)(*I, S)
def test_ceil_floor_updown_counter(): scope = Scope() counter = DefineCeilFloorUpDownCounter(5, False) sim = CoreIRSimulator( counter, counter.CLK, namespaces=["commonlib", "mantle", "coreir", "global"]) # This pattern tests corner cases. # Pattern: set D on first clock to do nothing, then hold by setting U and D for a clock, # then count up to 4, then do nothing by trying to overflow, and finally hold by setting U and D for a clock u_pattern = [False, True, True, True, True, True, True, True] d_pattern = [True, True, False, False, False, False, False, True] out_pattern = [0, 0, 0, 1, 2, 3, 4, 4, 4] for i in range(len(u_pattern)): sim.set_value(counter.U, u_pattern[i], scope) sim.set_value(counter.D, d_pattern[i], scope) sim.evaluate() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i] sim.advance_cycle() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i + 1]
def test_updown_counter(): width = 2 scope = Scope() counter = DefineUpDownCounter(width, False) sim = CoreIRSimulator( counter, counter.CLK, namespaces=["commonlib", "mantle", "coreir", "global"]) # This pattern tests corner cases. # Pattern: set D on first clock to underflow to 3, then hold by setting U and D for a clock, # finally, counter from 3 to 1 and back to 3 u_pattern = [False, True, False, False, True, True] d_pattern = [True, True, True, True, False, False] out_pattern = [0, 3, 3, 2, 1, 2, 3] for i in range(len(u_pattern)): sim.set_value(counter.U, u_pattern[i], scope) sim.set_value(counter.D, d_pattern[i], scope) sim.evaluate() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i] sim.advance_cycle() assert seq2int(sim.get_value(counter.O, scope)) == out_pattern[i + 1]
def test_zext(type_, value): if type_ != sint: value = abs(value) in_ = type_(value, 16) # TODO(rsetaluri): Ideally, zext(bits) should return an object of type # BitsType, instead it returns an object of type ArrayType. For now, we wrap # the result of zext() in bits(). out = type_(zext(in_, 16)) assert len(out.bits()) == 32 # If we have a negative number, then zext should not return the same (signed # value). It will instead return the unsigned interpretation of the original # bits. if value < 0: assert int(out) == seq2int(in_.bits()) else: assert int(out) == value
def LUT(init, N=None, **kwargs): """ n-bit LUT I0 : In(Bit), I1 : In(Bit), ..., In : In(Bit), O : Out(Bit) """ if isinstance(init, FunctionType): init = fun2seq(init, 1 << N) if isinstance(init, Sequence): if N is not None: if 2**N < len(init): raise ValueError("init is too large for N={}".format(N)) else: N = clog2(len(init)) init = seq2int(init) else: if N is None: raise ValueError("N requires for not sequence init") return DefineLUT(init, N)()
def get_pixel(window_index, y, x): return seq2int( sim.get_value(LineBufferDef.O[window_index][y][x], scope))
def mux(I, S): if isinstance(S, int): return I[S] elif S.const(): return I[seq2int(S.bits())] return Mux(len(I), get_length(I[0]))(*I, S)
def simulate(self, value_store, state_store): in_ = value_store.get_value(getattr(self, "in")) value_store.set_value(self.out, [bool(i) for i in int2seq(init, 2**N)][seq2int(in_)])