def bench(self): clk = Signal(0) sig1 = Signal(0) sig2 = Signal(0) td = 10 def gen(s, n): for i in range(n-1): yield delay(td) s.next = 1 yield delay(td) for i in range(10): offset = now() n0 = randrange(1, 50) n1 = randrange(1, 50) n2 = randrange(1, 50) sig1.next = 0 sig2.next = 0 yield join(delay(n0*td), gen(sig1, n1), gen(sig2, n2)) assert sig1.val == 1 assert sig2.val == 1 assert now() == offset + td * max(n0, n1, n2) raise StopSimulation("Joined concurrent generator yield")
def assign_config(sig, val): keep = Signal(bool(0)) keep.driven = 'wire' @always_comb def beh_assign(): sig.next = val if keep else val return beh_assign
def testValAttrReadOnly(self): """ val attribute should not be writable""" s1 = Signal(1) try: s1.val = 1 except AttributeError: pass else: self.fail()
def testDrivenAttrValue(self): """ driven attribute only accepts value 'reg' or 'wire' """ s1 = Signal(1) try: s1.driven = "signal" except ValueError: pass else: self.fail()
def testSignalBoolBounds(self): if type(bool) is not type: # bool not a type in 2.2 return s = Signal(bool()) s.next = 1 s.next = 0 for v in (-1, -8, 2, 5): with pytest.raises(ValueError): s.next = v
def get_unsigned_intbv_rand_signal(width, init_value=0): '''Create an unsigned intbv random signal. ''' min_val = 0 max_val = 2**(width) signal = Signal(intbv(val=init_value, min=min_val, max=max_val)) signal.val[:] = randrange(min_val, max_val) return signal, min_val, max_val
def testNegedgeAttrReadOnly(self): """ negedge attribute should not be writable""" s1 = Signal(1) try: s1.negedge = 1 except AttributeError: pass else: self.fail()
def stimulus(): a = Signal(0) yield delay(10) a.next = 1 yield None, delay(10) assert a.val == 0 assert now() == 10 yield delay(0) assert a.val == 1 assert now() == 10
def stimulus(): a = Signal(0) yield delay(10) a.next = 1 yield None, delay(10) self.assertEqual(a.val, 0) self.assertEqual(now(), 10) yield delay(0) self.assertEqual(a.val, 1) self.assertEqual(now(), 10)
def inst(): yield delay(200 * nsec) addr = Signal(intbv(0x10)[len(bus.A):]) while 1: yield system.CLK.posedge bus.CS_B.next = 0 bus.RAS_B.next = 0 bus.A.next = 0x4 bus.BA.next = 0x2 yield system.CLK.posedge bus.CS_B.next = 1 bus.RAS_B.next = 1 bus.A.next = ~0 & mask(bus.A) bus.BA.next = ~0 & mask(bus.BA) yield system.CLK.posedge bus.CS_B.next = 0 bus.CAS_B.next = 0 bus.A.next = addr bus.BA.next = 0 yield system.CLK.posedge bus.CS_B.next = 1 bus.CAS_B.next = 1 bus.A.next = ~0 & mask(bus.A) bus.BA.next = ~0 & mask(bus.BA) addr.next = 0 if addr != n - 1: addr.next = addr + 4 yield system.CLK.posedge bus.CS_B.next = 0 bus.CAS_B.next = 0 bus.A.next = addr yield system.CLK.posedge bus.CS_B.next = 1 bus.CAS_B.next = 1 bus.A.next = ~0 & mask(bus.A) addr.next = 0 if addr != n - 1: addr.next = addr + 4 yield delay(interval - 1)
def test(B, G): w = len(B) G_Z = Signal(intbv(0)[w:]) B.next = intbv(0) yield delay(10) for i in range(1, 2**w): G_Z.next = G B.next = intbv(i) yield delay(10) diffcode = bin(G ^ G_Z) self.assertEqual(diffcode.count('1'), 1)
def stimulus(): N = Signal(intbv(0)[32:]) yield bus.reset() # Send a clear yield whitebox_clear(bus) # Check the fifo flags yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WES_SPACE assert not (bus.rdata & WES_DATA) yield bus.transmit(WE_THRESHOLD_ADDR, concat(intbv(1)[16:], intbv(3)[16:])) yield bus.receive(WE_THRESHOLD_ADDR) assert bus.rdata == concat(intbv(1)[16:], intbv(3)[16:]) yield bus.transmit(WE_INTERP_ADDR, INTERP) yield bus.receive(WE_INTERP_ADDR) assert bus.rdata == INTERP ## Insert samples until overrun yield bus.receive(WE_RUNS_ADDR) while not (bus.rdata & 0x0000ffff): x = intbv(int(sin(1000 * (2 * pi) * N / 50000) * 2**15), min=-2**15, max=2**15)[16:] yield bus.transmit(WE_SAMPLE_ADDR, concat(x, x)) N.next = N + 1 yield bus.receive(WE_RUNS_ADDR) # Check that we're full yield bus.receive(WE_STATUS_ADDR) assert not (bus.rdata & WES_SPACE) assert bus.rdata & WES_DATA ## Now start transmitting yield bus.transmit(WE_STATUS_ADDR, WES_TXEN) yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WES_TXEN ## Wait until underrun yield bus.receive(WE_RUNS_ADDR) while not (bus.rdata & 0xffff0000): yield bus.delay(1000) yield bus.receive(WE_RUNS_ADDR) ## Make sure we're both over and underrun assert bus.rdata & 0xffff0000 and bus.rdata & 0x0000ffff # Check the fifo flags yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WES_SPACE assert not (bus.rdata & WES_DATA) raise StopSimulation
def assign_config(sig, val): """ Arguments: sig (Signal): The signals to be assigned to a constant value val (int): The constant value """ keep = Signal(bool(0)) keep.driven = 'wire' @always_comb def beh_assign(): sig.next = val if keep else val return beh_assign
def get_signed_intbv_rand_signal(width, val_range=None, init_value=0): '''Create a signed intbv random signal. ''' if val_range is not None: min_val = val_range[0] max_val = val_range[1] else: min_val = -(2**(width - 1) - 1) max_val = 2**(width - 1) signal = Signal(intbv(init_value, min=min_val, max=max_val)) signal.val[:] = randrange(min_val, max_val) return signal, min_val, max_val
def testSignalBoolBounds(self): if type(bool) is not type: # bool not a type in 2.2 return s = Signal(bool()) s.next = 1 s.next = 0 for v in (-1, -8, 2, 5): try: s.next = v #s._update() #s.val except ValueError: pass else: self.fail()
def testUpdateNoEvent(self): """ update without value change should not return event waiters """ s1 = Signal(1) s1.next = 4 s1._update() s1.next = 4 s1._eventWaiters = self.eventWaiters[:] s1._posedgeWaiters = self.posedgeWaiters[:] s1._negedgeWaiters = self.negedgeWaiters[:] waiters = s1._update() self.assertEqual(waiters, []) self.assertEqual(s1._eventWaiters, self.eventWaiters) self.assertEqual(s1._posedgeWaiters, self.posedgeWaiters) self.assertEqual(s1._negedgeWaiters, self.negedgeWaiters)
def testSliceAssign(self): s = Signal(intbv(min=-24, max=34)) for i in (-24, -2, 13, 33): for k in (6, 9, 10): s.next[:] = 0 s.next[k:] = i self.assertEqual(s.next, i) for i in (-25, -128, 34, 35, 229): for k in (0, 9, 10): try: s.next[k:] = i # s._update() except ValueError: pass else: self.fail() s = Signal(intbv(5)[8:]) for v in (0, 2**8-1, 100): s.next[:] = v for v in (-1, 2**8, -10, 1000): try: s.next[:] = v # s._update() except ValueError: pass else: self.fail()
def assign(a, b): """ assign a = b """ if isinstance(b, SignalType): @always_comb def beh_assign(): a.next = b else: # this is a work around for preserving constant assigns keep = Signal(True) keep.driven = "wire" @always_comb def beh_assign(): a.next = b if keep else b return beh_assign
def testUpdateNegedge(self): """ update on negedge should return event and negedge waiters """ s1 = Signal(1) s1.next = 1 s1._update() s1.next = 0 s1._eventWaiters = self.eventWaiters[:] s1._posedgeWaiters = self.posedgeWaiters[:] s1._negedgeWaiters = self.negedgeWaiters[:] waiters = s1._update() expected = self.eventWaiters + self.negedgeWaiters self.assertEqual(set(waiters), set(expected)) self.assertEqual(s1._eventWaiters, []) self.assertEqual(s1._posedgeWaiters, self.posedgeWaiters) self.assertEqual(s1._negedgeWaiters, [])
def testUpdateEvent(self): """ update on non-edge event should return event waiters """ s1 = Signal(1) s1.next = 4 s1._update() s1.next = 5 s1._eventWaiters = self.eventWaiters[:] s1._posedgeWaiters = self.posedgeWaiters[:] s1._negedgeWaiters = self.negedgeWaiters[:] waiters = s1._update() expected = self.eventWaiters self.assertEqual(set(waiters), set(expected)) self.assertEqual(s1._eventWaiters, []) self.assertEqual(s1._posedgeWaiters, self.posedgeWaiters) self.assertEqual(s1._negedgeWaiters, self.negedgeWaiters)
def testUpdatePosedge(self): """ update on posedge should return event and posedge waiters """ s1 = Signal(1) s1.next = 0 s1._update() s1.next = 1 s1._eventWaiters = self.eventWaiters[:] s1._posedgeWaiters = self.posedgeWaiters[:] s1._negedgeWaiters = self.negedgeWaiters[:] waiters = s1._update() expected = self.eventWaiters + self.posedgeWaiters assert set(waiters) == set(expected) assert s1._eventWaiters == [] assert s1._posedgeWaiters == [] assert s1._negedgeWaiters == self.negedgeWaiters
def testSliceAssign(self): s = Signal(intbv(min=-24, max=34)) for i in (-24, -2, 13, 33): for k in (6, 9, 10): s.next[:] = 0 s.next[k:] = i assert s.next == i for i in (-25, -128, 34, 35, 229): for k in (0, 9, 10): with pytest.raises(ValueError): s.next[k:] = i s = Signal(intbv(5)[8:]) for v in (0, 2**8-1, 100): s.next[:] = v for v in (-1, 2**8, -10, 1000): with pytest.raises(ValueError): s.next[:] = v
def testBench_FA(flag=0): """The test bench mark to test the full adder hardware module""" A, B, A1, B1, C_in, K1, K2, K3, K4, K5, K6, Sum_out, Sum1_out, C_out = [ Signal(bool(0)) for i in range(14) ] FA_inst = full_adder(A, B, A1, B1, C_in, K1, K2, K3, K4, K5, K6, Sum_out, Sum1_out, C_out) @instance def simulate(): ham = {} hamSum = 0 for p in range(64): keyset = format(p, "06b") beforeS = [] beforeS1 = [] beforeC = [] before = [] #print('A B Cin SumOut Cout') for i in range(32): K1.next = 0 K2.next = 0 K3.next = 0 K4.next = 0 K5.next = 0 K6.next = 0 set = format(i, "05b") A.next = int(set[0]) B.next = int(set[1]) C_in.next = int(set[2]) A1.next = int(set[3]) B1.next = int(set[4]) yield delay(10) #print ('{} {} {} {} {} BEFORE'.format(bin(A,1),bin(B,1),bin(C_in,1),bin(Sum_out,1),bin(C_out,1))) beforeS.append(int(bin(Sum_out))) beforeS1.append(int(bin(Sum1_out))) beforeC.append(int(bin(C_out))) before = beforeS + beforeS1 + beforeC print('Sum0:') print(beforeS) print('Sum1:') print(beforeS1) print('Carry:') print(beforeC) print(before) K1.next = int(keyset[0]) K2.next = int(keyset[1]) K3.next = int(keyset[2]) K4.next = int(keyset[3]) K5.next = int(keyset[4]) K6.next = int(keyset[5]) afterS = [] afterS1 = [] afterC = [] after = [] for i in range(32): set = format(i, "05b") A.next = int(set[0]) B.next = int(set[1]) C_in.next = int(set[2]) A1.next = int(set[3]) B1.next = int(set[4]) yield delay(10) afterS.append(int(bin(Sum_out))) afterS1.append(int(bin(Sum1_out))) afterC.append(int(bin(C_out))) after = afterS + afterS1 + afterC print('After:') print(afterS) print(afterC) print(after) t = [] for i in range(len(before)): if before[i] != after[i]: t.append(before[i]) hamming = len(t) / len(before) print('Key1: {} Key2: {} Key3: {}'.format(keyset[0], keyset[1], keyset[2])) print('Hamming = {}'.format(hamming)) ham[hamming] = p hamSum += hamming print('Hamming List:') print(ham) smallest = nsmallest(1, ham, key=lambda x: abs(x - 0.5)) key = format(ham[smallest[0]], "06b") print('Best Key Combination: {}'.format(key)) print('Hamming Distance: {}'.format(smallest)) print('Ave Hamming = {}'.format(hamSum / 63)) return FA_inst, simulate
def control(opcode, RegDst, Branch, MemRead, MemtoReg, ALUop, MemWrite, ALUSrc, RegWrite, NopSignal=Signal(intbv(0)[1:]), Stall=Signal(intbv(0)[1:])): """ Control Unit @param opcode 6位操作码 @param RegDst, ALUSrc, MemtoReg 1位信号,控制多路选择器 @param RegWrite, MemRead, MemWrite 1位信号,控制寄存器和内存的读写 @param Branch 1位信号,确定是否有分支 @param ALUop 2位信号,控制ALU """ @always_comb def logic(): if NopSignal == 1 or Stall == 1: RegDst.next = 0 ALUSrc.next = 0 MemtoReg.next = 0 RegWrite.next = 0 MemRead.next = 0 MemWrite.next = 0 Branch.next = 0 ALUop.next = intbv('00') else: if opcode == 0: #r-format RegDst.next = 1 ALUSrc.next = 0 MemtoReg.next = 0 RegWrite.next = 1 MemRead.next = 0 MemWrite.next = 0 Branch.next = 0 ALUop.next = intbv('10') elif opcode == 0x23: #lw RegDst.next = 0 ALUSrc.next = 1 MemtoReg.next = 1 RegWrite.next = 1 MemRead.next = 1 MemWrite.next = 0 Branch.next = 0 ALUop.next = intbv('00') elif opcode == 0x2b: #sw ALUSrc.next = 1 RegWrite.next = 0 MemRead.next = 0 MemWrite.next = 1 Branch.next = 0 ALUop.next = intbv('00') elif opcode == 0x04: #beq ALUSrc.next = 0 RegWrite.next = 0 MemRead.next = 0 MemWrite.next = 0 Branch.next = 1 ALUop.next = intbv('01') return logic
def exciter( resetn, system_clock, pclk, paddr, psel, penable, pwrite, pwdata, pready, prdata, pslverr, dac_clock, dac_data): ####### FIFO ############ # Read re = Signal(bool(False)) rclk = system_clock Q = Signal(intbv(0)[32:]) # Write we = Signal(bool(False)) wclk = pclk data = Signal(intbv(0)[32:]) # Threshold full = Signal(bool(False)) full.driven = 'wire' afull = Signal(bool(False)) afull.driven = 'wire' empty = Signal(bool(False)) empty.driven = 'wire' aempty = Signal(bool(False)) aempty.driven = 'wire' fifo_args = resetn, re, rclk, Q, we, wclk, data, full, afull, \ empty, aempty fifo = FIFO(*fifo_args, width=32, depth=1024) ######### RESAMPLER ########### ######### INTERLEAVER ######### in_phase = Signal(bool(0)) sample_i = Signal(intbv(0, 0, 2**10)) sample_q = Signal(intbv(0, 0, 2**10)) ########## STATE MACHINE ###### state_t = enum('IDLE', 'WRITE_SAMPLE', 'DONE',) state = Signal(state_t.IDLE) ############ TX EN ########### txen = Signal(bool(0)) @always_seq(pclk.posedge, reset=resetn) def state_machine(): if state == state_t.IDLE: if penable and psel and pwrite: if paddr[8:] == 0x00: state.next = state_t.WRITE_SAMPLE pready.next = 0 we.next = 1 data.next = pwdata if full: raise OverrunError elif paddr[8:] == 0x01: print 'hi', pwdata txen.next = pwdata[0] elif psel and not pwrite: pass elif state == state_t.WRITE_SAMPLE: we.next = 0 state.next = state_t.DONE elif state == state_t.DONE: pready.next = 1 state.next = state_t.IDLE @always(system_clock.posedge) def resampler(): if txen: # Update the sample out of phase, locking if re: sample_i.next = Q[9:] sample_q.next = Q[32:23] re.next = not re @always(system_clock.posedge) def interleaver(): if txen: dac_data.next = sample_i[10:2] if in_phase else sample_q[10:2] dac_clock.next = not in_phase in_phase.next = not in_phase return fifo, state_machine, resampler, interleaver
def whitebox( resetn, pclk, paddr, psel, penable, pwrite, pwdata, pready, prdata, #pslverr, clearn, clear_enable, dac_clock, dac2x_clock, dac_en, dac_data, adc_idata, adc_qdata, tx_status_led, tx_dmaready, rx_status_led, rx_dmaready, tx_fifo_re, tx_fifo_rdata, tx_fifo_we, tx_fifo_wdata, tx_fifo_full, tx_fifo_afull, tx_fifo_empty, tx_fifo_aempty, tx_fifo_afval, tx_fifo_aeval, tx_fifo_wack, tx_fifo_dvld, tx_fifo_overflow, tx_fifo_underflow, tx_fifo_rdcnt, tx_fifo_wrcnt, rx_fifo_re, rx_fifo_rdata, rx_fifo_we, rx_fifo_wdata, rx_fifo_full, rx_fifo_afull, rx_fifo_empty, rx_fifo_aempty, rx_fifo_afval, rx_fifo_aeval, rx_fifo_wack, rx_fifo_dvld, rx_fifo_overflow, rx_fifo_underflow, rx_fifo_rdcnt, rx_fifo_wrcnt, fir_coeff_ram_addr, fir_coeff_ram_din0, fir_coeff_ram_din1, fir_coeff_ram_blk, fir_coeff_ram_wen, fir_coeff_ram_dout0, fir_coeff_ram_dout1, fir_load_coeff_ram_addr, fir_load_coeff_ram_din0, fir_load_coeff_ram_din1, fir_load_coeff_ram_blk, fir_load_coeff_ram_wen, fir_load_coeff_ram_dout0, fir_load_coeff_ram_dout1, fir_delay_line_i_ram_addr, fir_delay_line_i_ram_din, fir_delay_line_i_ram_blk, fir_delay_line_i_ram_wen, fir_delay_line_i_ram_dout, fir_delay_line_q_ram_addr, fir_delay_line_q_ram_din, fir_delay_line_q_ram_blk, fir_delay_line_q_ram_wen, fir_delay_line_q_ram_dout, **kwargs): """The whitebox. :param resetn: Reset the whole radio front end. :param clearn: Clear the DSP Chain :param dac_clock: Clock running at DAC rate :param dac2x_clock: Clock running at double DAC rate :param pclk: The system bus clock :param paddr: The bus assdress :param psel: The bus slave select :param penable: The bus slave enable line :param pwrite: The bus read/write flag :param pwdata: The bus write data :param pready: The bus slave ready signal :param prdata: The bus read data :param pslverr: The bus slave error flag :param dac_clock: The DAC clock :param dac_data: The DAC data :param dac_en: Enable DAC output :param status_led: Output pin for whitebox status :param dmaready: Ready signal to DMA controller :param txirq: Almost empty interrupt to CPU :param clear_enable: To reset controller, set this high for reset """ dspsim = kwargs.get('dspsim', None) interp_default = kwargs.get('interp', 1) fcw_bitwidth = kwargs.get('fcw_bitwidth', 25) ######### VARS AND FLAGS ########### print 'interp=', interp_default interp = Signal(intbv(interp_default)[11:]) shift = Signal(intbv(0, min=0, max=21)) firen = Signal(bool(0)) fir_bank1 = Signal(bool(0)) fir_bank0 = Signal(bool(0)) fir_N = Signal(intbv(0, min=0, max=2**7)) tx_correct_i = Signal(intbv(0, min=-2**9, max=2**9)) tx_correct_q = Signal(intbv(0, min=-2**9, max=2**9)) tx_gain_i = Signal(intbv(int(1.0 * 2**9 + .5))[10:]) tx_gain_q = Signal(intbv(int(1.0 * 2**9 + .5))[10:]) fcw = Signal(intbv(1)[fcw_bitwidth:]) txen = Signal(bool(0)) txstop = Signal(bool(0)) txfilteren = Signal(bool(0)) ddsen = Signal(bool(False)) loopen = Signal(bool(False)) decim = Signal(intbv(interp_default)[11:]) rx_correct_i = Signal(intbv(0, min=-2**9, max=2**9)) rx_correct_q = Signal(intbv(0, min=-2**9, max=2**9)) rxen = Signal(bool(0)) rxstop = Signal(bool(0)) rxfilteren = Signal(bool(0)) ########### DIGITAL SIGNAL PROCESSING ####### loopback = Signature("loopback", False, bits=10) duc_underrun = Signal(modbv(0, min=0, max=2**16)) dac_last = Signal(bool(0)) ddc_overrun = Signal(modbv(0, min=0, max=2**16)) ddc_flags = Signal(intbv(0)[4:]) adc_last = Signal(bool(0)) tx_sample = Signature("tx_sample", True, bits=16) tx_sample_valid = tx_sample.valid tx_sample_last = tx_sample.last tx_sample_i = tx_sample.i tx_sample_q = tx_sample.q rx_sample = Signature("rx_sample", True, bits=16) rx_sample_valid = rx_sample.valid rx_sample_last = rx_sample.last rx_sample_i = rx_sample.i rx_sample_q = rx_sample.q duc_args = ( clearn, dac_clock, dac2x_clock, loopen, loopback, tx_fifo_empty, tx_fifo_re, tx_fifo_dvld, tx_fifo_rdata, tx_fifo_underflow, txen, txstop, ddsen, txfilteren, interp, shift, fcw, tx_correct_i, tx_correct_q, tx_gain_i, tx_gain_q, duc_underrun, tx_sample, dac_en, dac_data, dac_last, rx_fifo_full, rx_fifo_we, rx_fifo_wdata, rxen, rxstop, rxfilteren, decim, rx_correct_i, rx_correct_q, ddc_overrun, rx_sample, adc_idata, adc_qdata, adc_last, fir_coeff_ram_addr, fir_coeff_ram_din0, fir_coeff_ram_din1, fir_coeff_ram_blk, fir_coeff_ram_wen, fir_coeff_ram_dout0, fir_coeff_ram_dout1, fir_delay_line_i_ram_addr, fir_delay_line_i_ram_din, fir_delay_line_i_ram_blk, fir_delay_line_i_ram_wen, fir_delay_line_i_ram_dout, fir_delay_line_q_ram_addr, fir_delay_line_q_ram_din, fir_delay_line_q_ram_blk, fir_delay_line_q_ram_wen, fir_delay_line_q_ram_dout, firen, fir_bank1, fir_bank0, fir_N, ) duc_kwargs = dict(dspsim=dspsim, interp=interp_default, cic_enable=kwargs.get('cic_enable', True), cic_order=kwargs.get('cic_order', 4), cic_delay=kwargs.get('cic_delay', 1), fir_enable=kwargs.get('fir_enable', True), dds_enable=kwargs.get('dds_enable', True), conditioning_enable=kwargs.get('conditioning_enable', True)) if kwargs.get("duc_enable", True): duc = DUC(*duc_args, **duc_kwargs) else: duc = None ########### RADIO FRONT END ############## rfe_args = ( resetn, pclk, paddr, psel, penable, pwrite, pwdata, pready, prdata, #pslverr, clearn, clear_enable, loopen, tx_status_led, tx_dmaready, rx_status_led, rx_dmaready, tx_fifo_we, tx_fifo_wdata, tx_fifo_empty, tx_fifo_full, tx_fifo_afval, tx_fifo_aeval, tx_fifo_afull, tx_fifo_aempty, tx_fifo_wack, tx_fifo_dvld, tx_fifo_overflow, tx_fifo_underflow, tx_fifo_rdcnt, tx_fifo_wrcnt, rx_fifo_re, rx_fifo_rdata, rx_fifo_empty, rx_fifo_full, rx_fifo_afval, rx_fifo_aeval, rx_fifo_afull, rx_fifo_aempty, rx_fifo_wack, rx_fifo_dvld, rx_fifo_overflow, rx_fifo_underflow, rx_fifo_rdcnt, rx_fifo_wrcnt, fir_load_coeff_ram_addr, fir_load_coeff_ram_din0, fir_load_coeff_ram_din1, fir_load_coeff_ram_blk, fir_load_coeff_ram_wen, fir_load_coeff_ram_dout0, fir_load_coeff_ram_dout1, firen, fir_bank1, fir_bank0, fir_N, interp, shift, fcw, tx_correct_i, tx_correct_q, tx_gain_i, tx_gain_q, txen, txstop, ddsen, txfilteren, decim, rx_correct_i, rx_correct_q, rxen, rxstop, rxfilteren, duc_underrun, dac_last, ddc_overrun, adc_last) rfe = RFE(*rfe_args) return rfe, duc
def AnimatedBall(refr_tick, pixel_x, pixel_y, bar_yt, bar_yb, ball_on, rd_ball_on, ball_rgb, clk, rst): MAX_COLOR = 2 ** (len(ball_rgb) // 3) - 1 code = [None] * 8 for key, value in encoding.items(): if 0 <= key <= 7: code[key] = int(value, 2) code = tuple(code) WALL_X_R = 35 BAR_X_L = 600 BAR_X_R = 603 BALL_SIZE = 8 BALL_VELOCITY_POS = 2 BALL_VELOCITY_NEG = -2 ball_xl, ball_xr = [Signal(intbv(0)[len(pixel_x):]) for _ in range(2)] ball_yt, ball_yb = [Signal(intbv(0)[len(pixel_y):]) for _ in range(2)] ball_xreg, ball_xr_next = [Signal(intbv(0)[len(pixel_x):]) for _ in range(2)] ball_yreg, ball_yr_next = [Signal(intbv(0)[len(pixel_y):]) for _ in range(2)] x_delta_reg, xd_next = [Signal(intbv(0)[len(pixel_x):]) for _ in range(2)] y_delta_reg, yd_next = [Signal(intbv(0)[len(pixel_y):]) for _ in range(2)] rom_addr, rom_col = [Signal(intbv(0)[3:]) for _ in range(2)] rom_data = Signal(intbv(0)[8:]) rom_bit = Signal(False) @always(clk.posedge, rst.posedge) def clocked_logic(): if rst: ball_xreg.next = 0 ball_yreg.next = 0 x_delta_reg.next = 4 y_delta_reg.next = 4 else: ball_xreg.next = ball_xr_next ball_yreg.next = ball_yr_next x_delta_reg.next = xd_next y_delta_reg.next = yd_next @always_comb def ball_logic(): ball_xl.next = ball_xreg ball_yt.next = ball_yreg @always_comb def ball2_logic(): ball_yb.next = ball_yt + BALL_SIZE - 1 ball_xr.next = ball_xl + BALL_SIZE - 1 @always_comb def ball3_logic(): ball_on.next = 1 if ball_xl <= pixel_x and pixel_x <= ball_xr and ball_yt <= pixel_y and pixel_y <= ball_yb else 0 # Map pixel to rom rom_addr.next = pixel_y[3:] - ball_yt[3:] rom_col.next = pixel_x[3:] - ball_xl[3:] @always_comb def rom_lookup(): rom_data.next = code[rom_addr] @always_comb def rom_lookup2(): rom_bit.next = rom_data[rom_col] @always_comb def on_off_gen(): rd_ball_on.next = 1 if ball_on and rom_bit else 0 @always_comb def output_logic(): # Output ball_rgb.next = concat(intbv(MAX_COLOR)[8:], intbv(0)[16:]) ball_xr_next.next = ball_xreg + x_delta_reg if refr_tick else ball_xreg ball_yr_next.next = ball_yreg + y_delta_reg if refr_tick else ball_yreg @always(x_delta_reg, y_delta_reg, ball_yt, ball_yb, ball_xl, ball_xr, bar_yt, bar_yb) def ball_velocity(): xd_next.next = x_delta_reg yd_next.next = y_delta_reg if ball_yt < 1: yd_next.next = BALL_VELOCITY_POS elif ball_yb > HEIGHT - 1: yd_next.next = BALL_VELOCITY_NEG elif ball_xl <= WALL_X_R: xd_next.next = BALL_VELOCITY_POS elif BAR_X_L <= ball_xr and ball_xr <= BAR_X_R: if bar_yt <= ball_yb and ball_yt <= bar_yb: xd_next.next = BALL_VELOCITY_NEG return clocked_logic, ball_logic, ball2_logic, ball3_logic, output_logic, ball_velocity, rom_lookup, rom_lookup2, on_off_gen
def convert_qround(): signals = [Signal(modbv(0, min=0, max=2**32)) for _ in range(8)] q1 = core.q_round(*signals) q1.convert(hdl='Verilog')
def bytestuffer(clock, reset, bs_in_stream, bs_out_stream, bs_cntrl, num_enc_bytes): """ Byte stuffer checks for 0xFF byte and adds a 0xFF00 Byte Constants: width_addr_out : maximum adress width of the output RAM width_out : width of the data in the ouput RAM I/O Ports : bs_in_stream : input interface to the byte stuffer bs_cntrl : control interface to the byte stuffer bs_out_stream : output interface to the byte stuffer num_enc_byte : number of bytes encoded to output RAM """ assert isinstance(bs_in_stream, BSInputDataStream) assert isinstance(bs_out_stream, BSOutputDataStream) assert isinstance(bs_cntrl, BScntrl) # maximum address width of output RAM width_addr_out = len(bs_out_stream.addr) # maximum width of the output data width_out = len(bs_out_stream.byte) # temporary latch used to store byte latch_byte = Signal(intbv(0)[width_out:]) read_in_temp = Signal(bool(0)) # pointer to write address to output RAM write_addr = Signal(intbv(0)[width_addr_out:]) # used to validate data after four clocks data_val = Signal(intbv(0)[4:]) # used to read data read_enable = Signal(bool(0)) read_enable_temp = Signal(bool(0)) data_valid = Signal(bool(0)) # wait signal used to handle sedning data wait_ndata = Signal(bool(0)) # it gets a value two when it encounter 0xFF wr_cnt_stuff = Signal(intbv(0)[2:]) # used to store 0xFF00 byte or processed bytes wdata_reg = Signal(intbv(0)[(2 * width_out):]) @always_comb def assign(): """assign read signal to interface""" bs_in_stream.read.next = read_in_temp @always_seq(clock.posedge, reset=reset) def toggle(): """Input Buffer Selection""" if bs_cntrl.start: bs_in_stream.buffer_sel.next = not bs_in_stream.buffer_sel @always_seq(clock.posedge, reset=reset) def control_bs(): """control sending data into the byte stuffer""" read_in_temp.next = False bs_cntrl.ready.next = False data_val.next = concat(data_val[3:0], read_in_temp) read_enable_temp.next = read_enable bs_out_stream.data_valid.next = False data_valid.next = False # enable reading inputs if bs_cntrl.start: read_enable.next = True # read fifo till it becomes empty # wait till last byte is read if read_enable_temp and not wait_ndata: # fifo is empty or when all the inputs processed if bs_in_stream.fifo_empty: read_enable.next = False read_enable_temp.next = False bs_cntrl.ready.next = True else: read_in_temp.next = True wait_ndata.next = True # show ahead fifo, capture data early if read_in_temp: # store the input data in latch latch_byte.next = bs_in_stream.data_in data_valid.next = True # send the next input from FIFO if data_val[1]: wait_ndata.next = False # data from FIFO is valid if data_valid: # stuffing required if latch_byte == 0xFF: wr_cnt_stuff.next = 0b10 wdata_reg.next = 0xFF00 # stuffing not required else: wr_cnt_stuff.next = 0b01 wdata_reg.next = latch_byte # restore the value of wr_cnt_stuff and validate o/p signals if wr_cnt_stuff > 0: wr_cnt_stuff.next = wr_cnt_stuff - 1 bs_out_stream.data_valid.next = True write_addr.next = write_addr + 1 # delayed to make address post-increment bs_out_stream.addr.next = write_addr #stuffing if wr_cnt_stuff == 2: bs_out_stream.byte.next = wdata_reg[16:8] else: bs_out_stream.byte.next = wdata_reg[8:0] # start of frame signal if bs_cntrl.sof: write_addr.next = 0 @always_seq(clock.posedge, reset=reset) def num_bytes(): """calulate the number of output bytes written""" # the plus 2 bytes are for EOI marker num_enc_bytes.next = write_addr + 2 return assign, toggle, control_bs, num_bytes
def test_converge(n=50, emb_spread=0.1, rand_seed=42): """Testing bench for covergence.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign( new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign( new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) clk = Signal(bool(False)) # modules wcupdated = WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res) # test stimulus random.seed(rand_seed) HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def stimulus(): zero = fixbv(0.0, min=fix_min, max=fix_max, res=fix_res) yield clk.posedge # random initialization for j in range(embedding_dim): word_emb[j].next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) context_emb[j].next = fixbv(random.uniform(0.0, emb_spread), min=fix_min, max=fix_max, res=fix_res) # iterate to converge for i in range(n): yield clk.negedge print "%4s mse: %f, y: %f, word: %s, context: %s" % ( now(), error, y, [float(el.val) for el in word_emb ], [float(el.val) for el in context_emb]) if error == zero: break # transfer new values for j in range(embedding_dim): word_emb[j].next = new_word_emb[j] context_emb[j].next = new_context_emb[j] raise StopSimulation() return clk_gen, stimulus, wcupdated
def gain_corrector(clearn, clock, gain_i, gain_q, in_sign, out_sign): """Analog quadrature gain corrector. Lets you correct for gain imbalance with an AQM. :param clearn: The reset signal. :param clock: The clock. :param correct_i: An intbv to add to multiply each sample's i channel by. :param correct_q: An intbv to add to multiply each sample's q channel by. :param in_sign: The incomming signature. :param out_sign: The outgoing signature. :returns: A synthesizable MyHDL instance. """ in_valid = in_sign.valid in_last = in_sign.last in_i = in_sign.i in_q = in_sign.q out_valid = out_sign.valid out_last = out_sign.last out_i = out_sign.i out_q = out_sign.q s = len(in_i) + len(gain_i) mul_i = Signal(intbv(0, min=-2**s, max=2**s)) mul_q = Signal(intbv(0, min=-2**s, max=2**s)) mul_valid = Signal(bool(False)) mul_last = Signal(bool(False)) @always_seq(clock.posedge, reset=clearn) def gain_correct(): if in_valid: mul_valid.next = in_valid mul_last.next = in_last #print 'i', ia.signed()/2.**9, '*', ix.signed() / float(ix.max), '=', ia.signed()/2**9 * (ix.signed() / float(ix.max)) mul_i.next = in_i.signed() * concat(bool(0), gain_i).signed() mul_q.next = in_q.signed() * concat(bool(0), gain_q).signed() else: mul_valid.next = False mul_last.next = False mul_i.next = 0 mul_q.next = 0 if mul_valid: out_valid.next = mul_valid out_last.next = mul_last #print 'm', mul_q[len(mul_q)-2] ^ mul_q[len(mul_q)-3] out_i.next = mul_i[len(mul_i) - 2:len(mul_i) - len(out_i) - 2].signed() out_q.next = mul_q[len(mul_q) - 2:len(mul_q) - len(out_q) - 2].signed() else: out_valid.next = False out_last.next = False out_i.next = 0 out_q.next = 0 return gain_correct
def get_Nbit_signal(N): if N <= 0: return [] return [Signal(0) for _ in range(N)]
def test_vgasys(args=None): if args is None: args = Namespace(resolution=(80, 60), color_depth=(8, 8, 8), line_rate=31250, refresh_rate=60) args = tb_default_args(args) resolution = args.resolution refresh_rate = args.refresh_rate line_rate = args.line_rate color_depth = args.color_depth args = tb_default_args(args) clock = Clock(0, frequency=50e6) reset = Reset(0, active=0, async=False) vselect = Signal(bool(0)) # interface to the VGA driver and emulated display vga = VGA(color_depth=color_depth) @myhdl.block def bench_vgasys(): # top-level VGA system tbdut = mm_vgasys( clock, reset, vselect, vga.hsync, vga.vsync, vga.red, vga.green, vga.blue, vga.pxlen, vga.active, resolution=resolution, color_depth=color_depth, refresh_rate=refresh_rate, line_rate=line_rate ) # group global signals glbl = Global(clock=clock, reset=reset) # a display for each dut mvd = VGADisplay( frequency=clock.frequency, resolution=resolution, refresh_rate=refresh_rate, line_rate=line_rate, color_depth=color_depth ) # connect VideoDisplay model to the VGA signals tbvd = mvd.process(glbl, vga) # clock generator tbclk = clock.gen() @instance def tbstim(): reset.next = reset.active yield delay(18) reset.next = not reset.active # Wait till a full screen has been updated while mvd.update_cnt < 3: yield delay(1000) print("display updates complete") time.sleep(1) # @todo: verify video system memory is correct! # @todo: (self checking!). Read one of the frame # @todo: png's and verify a couple bars are expected raise StopSimulation return tbclk, tbvd, tbstim, tbdut # run the verification simulation run_testbench(bench_vgasys, args=args)
def test_entropycoder(): """ We will test the functionality of entropy coder in this block constants: width_data : width of the input data size_data : size required to store the data """ # width of the input data width_data = 12 # size required to store input data size_data = (width_data-1).bit_length() # clock and reset signals clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # declaration of input signal data_in = Signal(intbv(0)[width_data:].signed()) # declaration of output signals size = Signal(intbv(0)[size_data:]) amplitude = Signal(intbv(0)[width_data:].signed()) @block def bench_entropycoder(): """This bench is used to test the functionality""" # instantiate module and clock inst = entropycoder(clock, reset, data_in, size, amplitude) inst_clock = clock_driver(clock) @instance def tbstim(): """stimulus generates inputs for entropy coder""" # reset the module yield pulse_reset(reset, clock) # send input test cases into the module for i in range(-2**(width_data-1)+1, 2**(width_data-1), 1): data_in.next = i yield clock.posedge yield clock.posedge # extract results from reference design amplitude_ref, size_ref = entropy_encode(int(data_in)) # comparing reference and module results assert size == size_ref assert amplitude == amplitude_ref raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_entropycoder)
def test_quantizer(): """The functionality of the module is tested here""" # declare clock and reset clock = Signal(bool(0)) reset = ResetSignal(0, active=True, async=True) # width of the input data width_data = 12 # width of input address width_addr = 6 # bus declaration for the module quanto_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanto_datastream, QuantIODataStream) quanti_datastream = QuantIODataStream(width_data, width_addr) assert isinstance(quanti_datastream, QuantIODataStream) quant_ctrl = QuantCtrl() assert isinstance(quant_ctrl, QuantCtrl) # declare constants max_addr = 2**width_addr component = Component() assert isinstance(component, Component) @block def bench_quant(): """instantiation of quantizer module and clock""" inst = quantizer(clock, reset, quanti_datastream, quant_ctrl, quanto_datastream) inst_clock = clock_driver(clock) @instance def tbstim(): """we send test cases here""" # reset the block before processing yield pulse_reset(reset, clock) # select Cb or Cr component color = component.y2_space # process Cb or Cr component yield quant_top_block_process(clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) print("===============================================") # select Y1 or Y2 component color = component.cr_space # process Cb or Cr component yield quant_top_block_process(clock, quant_ctrl, color, quanto_datastream, quanti_datastream, quant_in, quant_rom, max_addr, 1) raise StopSimulation return tbstim, inst, inst_clock run_testbench(bench_quant)
import sys import random # for randint import copy # for deepcopy # for path issues in virtual environments sys.path.append('/usr/local/lib/python3.6/dist-packages') try: # test for failure import myhdl except: print('failed to import myhdl, bailing') sys.exit(1) # no explosions? carry on as usual from myhdl import block, always_comb, Signal, intbv, delay, instances, instance ZERO = Signal(0) # get vector of Signals of length N def get_Nbit_signal(N): if N <= 0: return [] return [Signal(0) for _ in range(N)] # get a random N-bit binary string def get_random_Nbit_str(N): if N > 64 or N < 1 or type(N) != int: return ''
def __init__(self): self.start = Signal(bool(0)) self.ready = Signal(bool(0)) self.sof = Signal(bool(0))
def __init__(self, x): self.x = Signal(intbv(0, min=x.min, max=x.max))
def testbench_core(): clock = Signal(bool(0)) done = Signal(bool(0)) data = Signal(intbv(0, max=2**((16 - 4) * 32))) reset = ResetSignal(False, True, False) start = Signal(bool(0)) output = Signal(intbv(0, max=2**512)) dut = core.core(data, done, output, start, clock, reset) @always(delay(10)) def clockgen(): clock.next = not clock @instance def check(): yield clock.negedge data.next = 0 start.next = True yield clock.negedge start.next = False yield done.posedge print('Done') res_str = format_output(output.val) print('Result: ' + res_str) target = format_state(chacha20.state([0] * 12)) print('Should: ' + target) assert res_str == target yield clock.negedge data.next = 555 start.next = True yield clock.negedge start.next = False yield done.posedge res_str = format_output(output.val) print('Result:' + res_str) target = format_state(chacha20.state([555] + [0] * 11)) print('Should: ' + target) assert res_str == target for _ in range(30): rng = random.randrange(2**32) yield clock.negedge data.next[32 * 4:0] = rng data.next[32 * 12:32 * 11] = rng start.next = True yield clock.negedge start.next = False yield done.posedge res_str = format_output(output.val) print('Result: ' + res_str) target = format_state(chacha20.state([rng] + ([0] * 10) + [rng])) print('Should: ' + target) assert res_str == target return dut, clockgen, check
def WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res): """Word-context embeddings updated model. :param y: return relu(dot(word_emb, context_emb)) as fixbv :param error: return MSE prediction error as fixbv :param new_word_embv: return updated word embedding vector of fixbv :param new_context_embv: return updated context embedding vector of fixbv :param y_actual: actual training value as fixbv :param word_embv: word embedding vector of fixbv :param context_embv: context embedding vector of fixbv :param embedding_dim: embedding dimensionality :param leaky_val: factor for leaky ReLU, 0.0 without :param rate_val: learning rate factor :param fix_min: fixbv min value :param fix_max: fixbv max value :param fix_res: fixbv resolution """ fix_width = len(word_embv) // embedding_dim # internal values one = fixbv(1.0, min=fix_min, max=fix_max, res=fix_res) rate = fixbv(rate_val, min=fix_min, max=fix_max, res=fix_res) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): word_emb[j].assign(word_embv((j + 1) * fix_width, j * fix_width)) context_emb[j].assign(context_embv((j + 1) * fix_width, j * fix_width)) y_dword_vec = Signal(intbv(0)[embedding_dim * fix_width:]) y_dcontext_vec = Signal(intbv(0)[embedding_dim * fix_width:]) y_dword_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] y_dcontext_list = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): y_dword_list[j].assign(y_dword_vec((j + 1) * fix_width, j * fix_width)) y_dcontext_list[j].assign( y_dcontext_vec((j + 1) * fix_width, j * fix_width)) # modules wcprod = WordContextProduct(y, y_dword_vec, y_dcontext_vec, word_embv, context_embv, embedding_dim, leaky_val, fix_min, fix_max, fix_res) @always_comb def mse(): diff = fixbv(y - y_actual, min=fix_min, max=fix_max, res=fix_res) error.next = fixbv(diff * diff, min=fix_min, max=fix_max, res=fix_res) @always_comb def updated_word(): diff = fixbv(y - y_actual, min=fix_min, max=fix_max, res=fix_res) for j in range(embedding_dim): y_dword = fixbv(y_dword_list[j], min=fix_min, max=fix_max, res=fix_res) delta = fixbv(rate * diff * y_dword, min=fix_min, max=fix_max, res=fix_res) new = fixbv(word_emb[j] - delta, min=fix_min, max=fix_max, res=fix_res) new_word_embv.next[(j + 1) * fix_width:j * fix_width] = new[:] @always_comb def updated_context(): diff = fixbv(y - y_actual, min=fix_min, max=fix_max, res=fix_res) for j in range(embedding_dim): y_dcontext = fixbv(y_dcontext_list[j], min=fix_min, max=fix_max, res=fix_res) delta = fixbv(rate * diff * y_dcontext, min=fix_min, max=fix_max, res=fix_res) new = fixbv(context_emb[j] - delta, min=fix_min, max=fix_max, res=fix_res) new_context_embv.next[(j + 1) * fix_width:j * fix_width] = new[:] return wcprod, mse, updated_word, updated_context
def ICache(clk_i, rst_i, cpu, mem, invalidate, ENABLE=True, D_WIDTH=32, BLOCK_WIDTH=5, SET_WIDTH=9, WAYS=2, LIMIT_WIDTH=32): """ The Instruction Cache module. :param clk: System clock :param rst: System reset :param cpu: CPU slave interface (Wishbone Interconnect to master port) :param mem: Memory master interface (Wishbone Interconnect to slave port) :param invalidate: Enable flush cache :param D_WIDTH: Data width :param BLOCK_WIDTH: Address width for byte access inside a block line :param SET_WIDTH: Address width for line access inside a block :param WAYS: Number of ways for associative cache (Minimum: 2) :param LIMIT_WIDTH: Maximum width for address """ if ENABLE: assert D_WIDTH == 32, "Error: Unsupported D_WIDTH. Supported values: {32}" assert BLOCK_WIDTH > 0, "Error: BLOCK_WIDTH must be a value > 0" assert SET_WIDTH > 0, "Error: SET_WIDTH must be a value > 0" assert not (WAYS & (WAYS - 1)), "Error: WAYS must be a power of 2" # -------------------------------------------------------------------------- WAY_WIDTH = BLOCK_WIDTH + SET_WIDTH # cache mem_wbm address width TAG_WIDTH = LIMIT_WIDTH - WAY_WIDTH # tag size TAGMEM_WAY_WIDTH = TAG_WIDTH + 1 # Add the valid bit TAGMEM_WAY_VALID = TAGMEM_WAY_WIDTH - 1 # Valid bit index TAG_LRU_WIDTH = (WAYS * (WAYS - 1)) >> 1 # (N*(N-1))/2 # -------------------------------------------------------------------------- ic_states = enum('IDLE', 'READ', 'FETCH', 'FLUSH', 'FLUSH_LAST') cpu_wbs = WishboneSlave(cpu) mem_wbm = WishboneMaster(mem) cpu_busy = Signal(False) cpu_err = Signal(False) cpu_wait = Signal(False) mem_read = Signal(False) mem_write = Signal(False) mem_rmw = Signal(False) tag_rw_port = [ RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS) ] tag_flush_port = [ RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS) ] tag_lru_rw_port = RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH) tag_lru_flush_port = RAMIOPort(A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH) cache_read_port = [ RAMIOPort(A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for _ in range(0, WAYS) ] cache_update_port = [ RAMIOPort(A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for _ in range(0, WAYS) ] data_cache = [cache_read_port[i].data_o for i in range(0, WAYS)] state = Signal(ic_states.IDLE) n_state = Signal(ic_states.IDLE) busy = Signal(False) miss = Signal(False) miss_w = Signal(modbv(0)[WAYS:]) miss_w_and = Signal(False) final_fetch = Signal(False) final_flush = Signal(False) lru_select = Signal(modbv(0)[WAYS:]) current_lru = Signal(modbv(0)[TAG_LRU_WIDTH:]) update_lru = Signal(modbv(0)[TAG_LRU_WIDTH:]) access_lru = Signal(modbv(0)[WAYS:]) lru_pre = Signal(modbv(0)[WAYS:]) tag_in = [Signal(modbv(0)[TAGMEM_WAY_WIDTH:]) for _ in range(0, WAYS)] tag_out = [Signal(modbv(0)[TAGMEM_WAY_WIDTH:]) for _ in range(0, WAYS)] lru_in = Signal(modbv(0)[TAG_LRU_WIDTH:]) lru_out = Signal(modbv(0)[TAG_LRU_WIDTH:]) tag_we = Signal(False) refill_addr = Signal(modbv(0)[LIMIT_WIDTH - 2:]) refill_valid = Signal(False) n_refill_addr = Signal(modbv(0)[LIMIT_WIDTH - 2:]) n_refill_valid = Signal(False) flush_addr = Signal(modbv(0)[SET_WIDTH:]) flush_we = Signal(False) n_flush_addr = Signal(modbv(0)[SET_WIDTH:]) n_flush_we = Signal(False) @always_comb def assignments(): final_fetch.next = (refill_addr[BLOCK_WIDTH - 2:] == modbv( -1)[BLOCK_WIDTH - 2:]) and mem_wbm.ack_i and mem_wbm.stb_o and mem_wbm.cyc_o lru_select.next = lru_pre current_lru.next = lru_out access_lru.next = ~miss_w busy.next = state != ic_states.IDLE final_flush.next = flush_addr == 0 @always_comb def miss_check(): """ For each way, check tag and valid flag, and reduce the vector using AND. If the vector is full of ones, the data is not in the cache: assert the miss flag. MISS: data not in cache and the memory operation is a valid read. Ignore this if the module is flushing data. """ value = modbv(0)[WAYS:] for i in range(0, WAYS): value[i] = (not tag_out[i][TAGMEM_WAY_VALID] or tag_out[i][TAG_WIDTH:0] != cpu_wbs.addr_i[LIMIT_WIDTH:WAY_WIDTH]) miss_w.next = value @always_comb def miss_check_2(): """ Vector reduce: check for full miss. """ value = True for i in range(0, WAYS): value = value and miss_w[i] miss_w_and.next = value @always_comb def miss_check_3(): """ Check for valid wishbone cycle, and full miss. """ valid_read = cpu_wbs.cyc_i and cpu_wbs.stb_i and not cpu_wbs.we_i miss.next = miss_w_and and valid_read and not invalidate trwp_clk = [tag_rw_port[i].clk for i in range(WAYS)] trwp_addr = [tag_rw_port[i].addr for i in range(WAYS)] trwp_data_i = [tag_rw_port[i].data_i for i in range(WAYS)] trwp_data_o = [tag_rw_port[i].data_o for i in range(WAYS)] trwp_we = [tag_rw_port[i].we for i in range(WAYS)] @always_comb def tag_rport(): for i in range(WAYS): trwp_clk[i].next = clk_i trwp_addr[i].next = cpu_wbs.addr_i[WAY_WIDTH:BLOCK_WIDTH] trwp_data_i[i].next = tag_in[i] trwp_we[i].next = tag_we tag_out[i].next = trwp_data_o[i] # LRU memory tag_lru_rw_port.clk.next = clk_i tag_lru_rw_port.data_i.next = lru_in lru_out.next = tag_lru_rw_port.data_o tag_lru_rw_port.addr.next = cpu_wbs.addr_i[WAY_WIDTH:BLOCK_WIDTH] tag_lru_rw_port.we.next = tag_we @always_comb def next_state_logic(): n_state.next = state if state == ic_states.IDLE: if invalidate: # cache flush n_state.next = ic_states.FLUSH elif cpu_wbs.cyc_i and not cpu_wbs.we_i: # miss: refill line n_state.next = ic_states.READ elif state == ic_states.READ: if not miss: # miss: refill line n_state.next = ic_states.IDLE else: n_state.next = ic_states.FETCH elif state == ic_states.FETCH: # fetch a line from memory if final_fetch: n_state.next = ic_states.IDLE elif state == ic_states.FLUSH: # invalidate tag memory if final_flush: n_state.next = ic_states.FLUSH_LAST else: n_state.next = ic_states.FLUSH elif state == ic_states.FLUSH_LAST: # last cycle for flush n_state.next = ic_states.IDLE @always(clk_i.posedge) def update_state(): if rst_i: state.next = ic_states.FLUSH else: state.next = n_state @always_comb def fetch_fsm(): n_refill_addr.next = refill_addr n_refill_valid.next = False # refill_valid if state == ic_states.IDLE: if invalidate: n_refill_valid.next = False elif state == ic_states.READ: if miss: n_refill_addr.next = concat( cpu_wbs.addr_i[LIMIT_WIDTH:BLOCK_WIDTH], modbv(0)[BLOCK_WIDTH - 2:]) n_refill_valid.next = True # not mem_wbm.ready? elif state == ic_states.FETCH: n_refill_valid.next = True if refill_valid and mem_wbm.ack_i: if final_fetch: n_refill_valid.next = False n_refill_addr.next = 0 else: n_refill_valid.next = True n_refill_addr.next = refill_addr + modbv( 1)[BLOCK_WIDTH - 2:] @always(clk_i.posedge) def update_fetch(): if rst_i: refill_addr.next = 0 refill_valid.next = False else: refill_addr.next = n_refill_addr refill_valid.next = n_refill_valid @always_comb def tag_write(): for i in range(0, WAYS): tag_in[i].next = tag_out[i] tag_we.next = False lru_in.next = lru_out if state == ic_states.IDLE: if invalidate: tag_we.next = False elif state == ic_states.READ: if miss: for i in range(0, WAYS): if lru_select[i]: tag_in[i].next = concat( True, cpu_wbs.addr_i[LIMIT_WIDTH:WAY_WIDTH]) tag_we.next = True else: lru_in.next = update_lru tag_we.next = True @always_comb def flush_next_state(): n_flush_we.next = False n_flush_addr.next = flush_addr if state == ic_states.IDLE: if invalidate: n_flush_addr.next = modbv(-1)[SET_WIDTH:] n_flush_we.next = True elif state == ic_states.FLUSH: n_flush_addr.next = flush_addr - modbv(1)[SET_WIDTH:] n_flush_we.next = True elif state == ic_states.FLUSH_LAST: n_flush_we.next = False @always(clk_i.posedge) def update_flush(): if rst_i: flush_addr.next = modbv(-1)[SET_WIDTH:] flush_we.next = False else: flush_addr.next = n_flush_addr flush_we.next = n_flush_we tfp_clk = [tag_flush_port[i].clk for i in range(WAYS)] tfp_addr = [tag_flush_port[i].addr for i in range(WAYS)] tfp_data_i = [tag_flush_port[i].data_i for i in range(WAYS)] tfp_we = [tag_flush_port[i].we for i in range(WAYS)] @always_comb def tag_flush_port_assign(): for i in range(WAYS): tfp_clk[i].next = clk_i tfp_addr[i].next = flush_addr tfp_data_i[i].next = modbv(0)[TAGMEM_WAY_WIDTH:] tfp_we[i].next = flush_we # connect to the LRU memory tag_lru_flush_port.clk.next = clk_i tag_lru_flush_port.addr.next = flush_addr tag_lru_flush_port.data_i.next = modbv(0)[TAG_LRU_WIDTH:] tag_lru_flush_port.we.next = flush_we @always_comb def cpu_data_assign(): # cpu data_in assignment: instruction. temp = data_cache[0] for i in range(0, WAYS): if not miss_w[i]: temp = data_cache[i] cpu_wbs.dat_o.next = temp @always_comb def mem_port_assign(): mem_wbm.addr_o.next = concat(refill_addr, modbv(0)[2:]) mem_wbm.dat_o.next = cpu_wbs.dat_i mem_wbm.sel_o.next = modbv(0)[4:] # To Verilog crp_clk = [cache_read_port[i].clk for i in range(0, WAYS)] crp_addr = [cache_read_port[i].addr for i in range(0, WAYS)] crp_data_i = [cache_read_port[i].data_i for i in range(0, WAYS)] crp_we = [cache_read_port[i].we for i in range(0, WAYS)] @always_comb def cache_mem_r(): for i in range(0, WAYS): crp_clk[i].next = clk_i crp_addr[i].next = cpu_wbs.addr_i[WAY_WIDTH:2] crp_data_i[i].next = 0xAABBCCDD crp_we[i].next = False # To Verilog cup_clk = [cache_update_port[i].clk for i in range(0, WAYS)] cup_addr = [cache_update_port[i].addr for i in range(0, WAYS)] cup_data_i = [cache_update_port[i].data_i for i in range(0, WAYS)] cup_we = [cache_update_port[i].we for i in range(0, WAYS)] @always_comb def cache_mem_update(): for i in range(0, WAYS): # ignore data_o from update port cup_clk[i].next = clk_i cup_addr[i].next = refill_addr[WAY_WIDTH - 2:] cup_data_i[i].next = mem_wbm.dat_i cup_we[i].next = lru_select[i] & mem_wbm.ack_i @always_comb def wbs_cpu_flags(): cpu_err.next = mem_wbm.err_i cpu_wait.next = miss_w_and or state != ic_states.READ cpu_busy.next = busy @always_comb def wbm_mem_flags(): mem_read.next = refill_valid and not final_fetch mem_write.next = False mem_rmw.next = False # Remove warnings: Signal is driven but not read for i in range(WAYS): cache_update_port[i].data_o = None tag_flush_port[i].data_o = None tag_lru_flush_port.data_o = None # Generate the wishbone interfaces wbs_cpu = WishboneSlaveGenerator(clk_i, rst_i, cpu_wbs, cpu_busy, cpu_err, cpu_wait).gen_wbs() # noqa wbm_mem = WishboneMasterGenerator(clk_i, rst_i, mem_wbm, mem_read, mem_write, mem_rmw).gen_wbm() # noqa # Instantiate tag memories tag_mem = [ RAM_DP(tag_rw_port[i], tag_flush_port[i], A_WIDTH=SET_WIDTH, D_WIDTH=TAGMEM_WAY_WIDTH) for i in range(WAYS) ] # noqa tag_lru = RAM_DP(tag_lru_rw_port, tag_lru_flush_port, A_WIDTH=SET_WIDTH, D_WIDTH=TAG_LRU_WIDTH) # noqa # instantiate main memory (cache) cache_mem = [ RAM_DP(cache_read_port[i], cache_update_port[i], A_WIDTH=WAY_WIDTH - 2, D_WIDTH=D_WIDTH) for i in range(0, WAYS) ] # noqa # LRU unit. lru_m = CacheLRU(current_lru, access_lru, update_lru, lru_pre, None, NUMWAYS=WAYS) # noqa return instances() else: @always_comb def rtl(): mem.addr.next = cpu.addr mem.dat_o.next = cpu.dat_o mem.sel.next = cpu.sel mem.we.next = cpu.we cpu.dat_i.next = mem.dat_i cpu.ack.next = mem.ack cpu.err.next = mem.err @always(clk_i.posedge) def classic_cycle(): mem.cyc.next = cpu.cyc if not mem.ack else False mem.stb.next = cpu.stb if not mem.ack else False return instances()
@always(delay(period // 2)) def driver(): clk.next = not clk return driver def counter(clk, q): ''' A Cosimulation object, used to simulate Verilog modules ''' os.system('iverilog -o counter counter.v counter_top.v') return Cosimulation('vvp -m ./myhdl.vpi counter', clk=clk, q=q) def checker(clk, q): ''' Checker which prints the value of counter at posedge ''' @always(clk.posedge) def check(): print('from checker, time=', now(), ' q=', q) return check clk = Signal(0) q = Signal(intbv(0)[4:]) clk_driver_inst = clk_driver(clk) counter_inst = counter(clk, q) checker_inst = checker(clk, q) sim = Simulation(clk_driver_inst, counter_inst, checker_inst) sim.run(200)
def __init__(self, width_data, width_addr_out): self.byte = Signal(intbv(0)[width_data:]) self.addr = Signal(intbv(0)[width_addr_out:]) self.data_valid = Signal(bool(0))
def uartbaud(glbl, baudce, baudce16, baudrate=115200): """ Generate the UART baudrate strobe Three separate strobes are create: baudce, baudceh Arguments: glbl: rhea.Global interface, clk from glbl baudce: The baudce stobe baudce16: The baudce16 strobe Both of these are calculated in the function. Parameters: baudrate: The desired baudrate Return: myHDL generators rtlbaud: baudce strobe generator rtlbaud16: baudce16 strobe generator """ clock, reset = glbl.clock, glbl.reset # determine the actual baud rate given the system clock and then # calculate the limit. The following creates a counter that counts # in increments of baudfreq, this creates a strobe on average equal # to the desired frequency. # @todo: this didn't work as well as I thought it would ??? div = gcd(clock.frequency, 16 * baudrate) baudfreq = int((16 * baudrate) / div) baudlimit = int((clock.frequency / div)) cbaud = clock.frequency / (16 * (baudlimit / baudfreq)) print("") print("uartlite ") print(" baudrate: {:f} actual {:f} ".format(baudrate, cbaud)) print(" baud frequency: {:.3f}, baud limit: {:.3f}".format( baudfreq, baudlimit)) print(" remainder {:f}".format(baudlimit / baudfreq)) print("") cntmax = baudlimit - baudfreq cnt = Signal(intbv(0, min=0, max=2 * cntmax)) cnt16 = Signal(modbv(0, min=0, max=16)) @always_seq(clock.posedge, reset=reset) def rtlbaud16(): if cnt >= cntmax: cnt.next = cnt - cntmax #baudlimit baudce16.next = True else: cnt.next = cnt + baudfreq baudce16.next = False @always_seq(clock.posedge, reset=reset) def rtlbaud(): # this strobe will be delayed one clocke from # the baudce16 strobe (non-issue) if baudce16: cnt16.next = cnt16 + 1 if cnt16 == 0: baudce.next = True else: baudce.next = False else: baudce.next = False return rtlbaud16, rtlbaud
rfe = RFE(*rfe_args) return rfe, duc if __name__ == '__main__': from apb3_utils import Apb3Bus from fifo import fifo as FIFO fifo_depth = 1024 fifo_width = 32 duc_enable = True rfe_enable = True clearn = ResetSignal(0, 0, async=True) clear_enable = Signal(bool(0)) dac2x_clock = Signal(bool(0)) dac_clock = Signal(bool(0)) dac_data = Signal(intbv(0)[10:]) dac_en = Signal(bool(0)) adc_idata = Signal(intbv(0, min=-2**9, max=2**9)) adc_qdata = Signal(intbv(0, min=-2**9, max=2**9)) tx_status_led = Signal(bool(0)) tx_dmaready = Signal(bool(1)) rx_status_led = Signal(bool(0)) rx_dmaready = Signal(bool(1)) bus = Apb3Bus() bus_presetn = bus.presetn bus_pclk = bus.pclk bus_paddr = bus.paddr
def stimulus(): N = Signal(intbv(0)[32:]) s = self.s bus = self.bus yield bus.reset() # Send a clear yield whitebox_clear(bus) # Turn on and off the fir filter yield bus.receive(WE_STATUS_ADDR) assert not bus.rdata & WS_FIREN yield bus.transmit(WE_STATUS_ADDR, bus.rdata | WS_FIREN) yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WS_FIREN yield bus.transmit(WE_STATUS_ADDR, bus.rdata & ~WS_FIREN) yield bus.receive(WE_STATUS_ADDR) assert not bus.rdata & WS_FIREN gain_word = lambda i: intbv(((intbv(int(i[1]*2.**9))[32:] << 16) & 0x03ff0000) | (intbv(int(i[0]*2.**9))[32:] & 0x3ff))[32:] yield bus.transmit(WE_GAIN_ADDR, gain_word((self.i_gain, self.q_gain))) # Set the threshold afval = intbv(self.fifo_depth - self.bulk_size)[16:] aeval = intbv(self.bulk_size)[16:] yield bus.transmit(WE_THRESHOLD_ADDR, concat(afval, aeval)) if hasattr(self, 'taps') and self.taps: yield bus.transmit(W_FIR_ADDR, len(self.taps) | WF_ACCESS_COEFFS) for t in self.taps: yield bus.transmit(0, intbv(t << 12)[32:]) yield bus.receive(W_FIR_ADDR) assert bus.rdata == len(self.taps) yield bus.transmit(W_FIR_ADDR, len(self.taps) | WF_ACCESS_COEFFS) for t in self.taps: yield bus.receive(0) assert bus.rdata.signed() == t << 12 # Check the fifo flags yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WES_SPACE assert not (bus.rdata & WES_DATA) if hasattr(self, 'shift'): interp = concat(intbv(self.shift)[16:], intbv(self.interp)[16:]) else: interp = intbv(self.interp)[32:] yield bus.transmit(WE_INTERP_ADDR, interp) yield bus.receive(WE_INTERP_ADDR) assert bus.rdata == interp def quadrature_bit_vector(N): return \ intbv(int(self.x[int(N)].real), min=-2**15, max=2**15), \ intbv(int(self.x[int(N)].imag), min=-2**15, max=2**15) ## Insert some samples for j in range(self.bulk_size): i, q = quadrature_bit_vector(N) yield bus.transmit(WE_SAMPLE_ADDR, concat(q, i)) N.next = N + 1 yield delay(1) ## Set the FCW fcw = intbv(freq_to_fcw(self.freq, sample_rate=48e3))[32:] yield bus.transmit(WE_FCW_ADDR, fcw) yield bus.receive(WE_FCW_ADDR) print 'FCW', fcw, 'bus.rdata', bus.rdata assert bus.rdata == fcw ## Now start transmitting yield bus.transmit(WE_STATUS_ADDR, self.status | WES_TXEN) yield bus.receive(WE_STATUS_ADDR) assert bus.rdata & WES_TXEN ## Insert some more samples while len(self.n) - N > self.bulk_size - 1: ## Make sure there were no overruns or underruns yield bus.receive(WE_RUNS_ADDR) assert bus.rdata == 0 ## Wait for space yield bus.receive(WE_STATUS_ADDR) while bus.rdata & WES_AFULL: yield bus.delay(2) yield bus.receive(WE_STATUS_ADDR) for j in range(self.bulk_size): i, q = quadrature_bit_vector(N) yield bus.transmit(WE_SAMPLE_ADDR, concat(q, i)) N.next = N + 1 ## Insert remaining samples while N < len(self.n)-1: ## Wait for space yield bus.receive(WE_STATUS_ADDR) while not (bus.rdata & WES_SPACE): yield bus.delay(2) yield bus.receive(WE_STATUS_ADDR) i, q = quadrature_bit_vector(N) yield bus.transmit(WE_SAMPLE_ADDR, concat(q, i)) N.next = N + 1 ## Stop the transmission yield bus.transmit(WE_STATUS_ADDR, WES_TXSTOP) ## Wait for TXEN to go low yield bus.receive(WE_STATUS_ADDR) while bus.rdata & WES_TXEN: yield bus.delay(2) yield bus.receive(WE_STATUS_ADDR) ## Make sure there were no overruns or underruns yield bus.receive(WE_RUNS_ADDR) assert bus.rdata == 0 raise StopSimulation
def PongPixelGenerator(data, video_on, pixel_x, pixel_y, r, g, b, clk, rst): MAX_COLOR = r.max - 1 COLOR_BITS = len(r) * 3 RED_BITS_MIN = COLOR_BITS - COLOR_BITS // 3 GREEN_BITS_MIN = COLOR_BITS // 3 refr_tick = Signal(False) # Vertical stripe as wall WALL_X_L = 32 WALL_X_R = 35 BAR_Y_SIZE = 72 bar_yt, bar_yb = [Signal(intbv(0)[len(pixel_y):]) for _ in range(2)] bar_yreg = Signal(intbv(0)[len(pixel_y):]) wall_on = Signal(bool(0)) bar_on = Signal(bool(0)) ball_on, rd_ball_on = [Signal(bool(0)) for _ in range(2)] wall_rgb = Signal(intbv(0)[COLOR_BITS:]) bar_rgb = Signal(intbv(0)[COLOR_BITS:]) ball_rgb = Signal(intbv(0)[COLOR_BITS:]) @always_comb def reference(): refr_tick.next = 1 if pixel_x == 0 and pixel_y == HEIGHT + 1 else 0 @always_comb def wall_logic(): wall_on.next = 1 if WALL_X_L <= pixel_x and pixel_x <= WALL_X_R else 0 wall_rgb.next = MAX_COLOR @always_comb def yt_logic(): bar_yt.next = bar_yreg @always_comb def yb_logic(): bar_yb.next = bar_yt + BAR_Y_SIZE - 1 bar_logic = AnimatedBar(data, refr_tick, pixel_x, pixel_y, bar_yt, bar_yb, bar_yreg, bar_on, bar_rgb, clk, rst) ball_logic = AnimatedBall(refr_tick, pixel_x, pixel_y, bar_yt, bar_yb, ball_on, rd_ball_on, ball_rgb, clk, rst) @always(video_on, wall_on, bar_on, rd_ball_on, wall_rgb, bar_rgb, ball_rgb) def pixel_select(): if not video_on: r.next = 0 g.next = 0 b.next = 0 else: if wall_on: r.next = wall_rgb[COLOR_BITS:RED_BITS_MIN] g.next = wall_rgb[RED_BITS_MIN:GREEN_BITS_MIN] b.next = wall_rgb[GREEN_BITS_MIN:] elif bar_on: r.next = bar_rgb[COLOR_BITS:RED_BITS_MIN] g.next = bar_rgb[RED_BITS_MIN:GREEN_BITS_MIN] b.next = bar_rgb[GREEN_BITS_MIN:] elif rd_ball_on: r.next = ball_rgb[COLOR_BITS:RED_BITS_MIN] g.next = ball_rgb[RED_BITS_MIN:GREEN_BITS_MIN] b.next = ball_rgb[GREEN_BITS_MIN:] else: r.next = MAX_COLOR // 8 g.next = MAX_COLOR // 8 b.next = MAX_COLOR // 8 return reference, wall_logic, yt_logic, yb_logic, bar_logic, ball_logic, pixel_select
def __init__(self): self.l = [] self.sync = Signal(0) self.item = None
def command_bridge(glbl, fifobusi, fifobuso, mmbus): """ Convert a command packet to a memory-mapped bus transaction This module will decode the incomming packet and start a bus transaction, the memmap_controller_basic is used to generate the bus transactions, it convertes the Barebone interface to the MemoryMapped interface being used. The variable length command packet is: 00: 0xDE 01: command byte (response msb indicates error) 02: address high byte 03: address byte 04: address byte 05: address low byte 06: length of data (max length 256 bytes) 07: 0xCA # sequence number, fixed for now 08: data high byte 09: data byte 10: data byte 11: data low byte Fixed 12 byte packet currently supported, future to support block write/reads up to 256-8-4 12 - 253: write / read (big-endian) @todo: last 2 bytes crc The total packet length is 16 + data_length Ports: glbl: global signals and control fifobusi: input fifobus, host packets to device (interface) fifobuso: output fifobus, device responses to host (interface) mmbus: memory-mapped bus (interface) this module is convertible """ assert isinstance(fifobusi, FIFOBus) assert isinstance(fifobuso, FIFOBus) assert isinstance(mmbus, MemoryMapped) fbrx, fbtx = fifobusi, fifobuso clock, reset = glbl.clock, glbl.reset bb = Barebone(glbl, data_width=mmbus.data_width, address_width=mmbus.address_width) states = enum( 'idle', 'wait_for_packet', # receive a command packet 'check_packet', # basic command check 'write', # bus write 'write_end', # end of the write cycle 'read', # read bus cycles for response 'read_end', # end of the read cycle 'response', # send response packet 'response_full', # check of RX FIFO full 'error', # error occurred 'end' # end state ) state = Signal(states.idle) ready = Signal(bool(0)) error = Signal(bool(0)) bytecnt = intbv(0, min=0, max=256) # known knows pidx = (0, 7,) pval = (0xDE, 0xCA,) assert len(pidx) == len(pval) nknown = len(pidx) bytemon = Signal(intbv(0)[8:]) # only supporting 12byte packets (single read/write) for now packet_length = 12 data_offset = 8 packet = [Signal(intbv(0)[8:]) for _ in range(packet_length)] command = packet[1] address = ConcatSignal(*packet[2:6]) data = ConcatSignal(*packet[8:12]) datalen = packet[6] # convert generic memory-mapped bus to the memory-mapped interface # passed to the controller mmc_inst = controller_basic(bb, mmbus) @always_comb def beh_fifo_read(): if ready and not fbrx.empty: fbrx.rd.next = True else: fbrx.rd.next = False @always_seq(clock.posedge, reset=reset) def beh_state_machine(): if state == states.idle: state.next = states.wait_for_packet ready.next = True bytecnt[:] = 0 elif state == states.wait_for_packet: if fbrx.rvld: # check the known bytes, if the values is unexpected # goto the error state and flush all received bytes. for ii in range(nknown): idx = pidx[ii] val = pval[ii] if bytecnt == idx: if fbrx.rdata != val: error.next = True state.next = states.error packet[bytecnt].next = fbrx.rdata bytecnt[:] = bytecnt + 1 # @todo: replace 20 with len(CommandPacket().header) if bytecnt == packet_length: ready.next = False state.next = states.check_packet elif state == states.check_packet: # @todo: some packet checking # @todo: need to support different address widths, use # @todo: `bb` attributes to determine which bits to assign bb.per_addr.next = address[32:28] bb.mem_addr.next = address[28:0] assert bb.done bytecnt[:] = 0 if command == 1: state.next = states.read elif command == 2: bb.write_data.next = data state.next = states.write else: error.next = True state.next = states.error elif state == states.write: # @todo: add timeout if bb.done: bb.write.next = True state.next = states.write_end elif state == states.write_end: bb.write.next = False if bb.done: state.next = states.read elif state == states.read: # @todo: add timeout if bb.done: bb.read.next = True state.next = states.read_end elif state == states.read_end: bb.read.next = False if bb.done: # @todo: support different data_width bus packet[data_offset+0].next = bb.read_data[32:24] packet[data_offset+1].next = bb.read_data[24:16] packet[data_offset+2].next = bb.read_data[16:8] packet[data_offset+3].next = bb.read_data[8:0] state.next = states.response elif state == states.response: fbtx.wr.next = False if bytecnt < packet_length: if not fbtx.full: fbtx.wr.next = True fbtx.wdata.next = packet[bytecnt] bytecnt[:] = bytecnt + 1 state.next = states.response_full else: state.next = states.end elif state == states.response_full: fbtx.wr.next = False state.next = states.response elif state == states.error: if not fbrx.rvld: state.next = states.end ready.next = False elif state == states.end: error.next = False ready.next = False state.next = states.idle else: assert False, "Invalid state %s" % (state,) bytemon.next = bytecnt return beh_fifo_read, mmc_inst, beh_state_machine
def test_dim0(n=10, step_word=0.5, step_context=0.5): """Testing bench around zero in dimension 0.""" embedding_dim = 3 leaky_val = 0.01 rate_val = 0.1 fix_min = -2**7 fix_max = -fix_min fix_res = 2**-8 fix_width = 1 + 7 + 8 # signals y = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) error = Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) new_word_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_context_embv = Signal(intbv(0)[embedding_dim * fix_width:]) new_word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] new_context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for j in range(embedding_dim) ] for j in range(embedding_dim): new_word_emb[j].assign( new_word_embv((j + 1) * fix_width, j * fix_width)) new_context_emb[j].assign( new_context_embv((j + 1) * fix_width, j * fix_width)) y_actual = Signal(fixbv(1.0, min=fix_min, max=fix_max, res=fix_res)) word_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] word_embv = ConcatSignal(*reversed(word_emb)) context_emb = [ Signal(fixbv(0.0, min=fix_min, max=fix_max, res=fix_res)) for _ in range(embedding_dim) ] context_embv = ConcatSignal(*reversed(context_emb)) clk = Signal(bool(False)) # modules wcupdated = WordContextUpdated(y, error, new_word_embv, new_context_embv, y_actual, word_embv, context_embv, embedding_dim, leaky_val, rate_val, fix_min, fix_max, fix_res) # test stimulus HALF_PERIOD = delay(5) @always(HALF_PERIOD) def clk_gen(): clk.next = not clk @instance def stimulus(): yield clk.negedge for i in range(n): # new values word_emb[0].next = fixbv(step_word * i - step_word * n // 2, min=fix_min, max=fix_max, res=fix_res) context_emb[0].next = fixbv(step_context * i, min=fix_min, max=fix_max, res=fix_res) yield clk.negedge print "%3s word: %s, context: %s, mse: %f, y: %f, new_word: %s, new_context: %s" % ( now(), [float(el.val) for el in word_emb], [ float(el.val) for el in context_emb ], error, y, [float(el.val) for el in new_word_emb ], [float(el.val) for el in new_context_emb]) raise StopSimulation() return clk_gen, stimulus, wcupdated
def uarttx(glbl, fbustx, tx, baudce): """UART transmitter function Arguments(Ports): glbl : rhea.Global interface, clock and reset fbustx : FIFOBus interface to the TX fifo tx : The actual transmition line Parameters: baudce : The transmittion baud rate Returns: myHDL generator rtltx : Generator to keep open the transmittion line and write into it from the TX fifo. """ clock, reset = glbl.clock, glbl.reset states = enum('wait', 'start', 'byte', 'stop', 'end') state = Signal(states.wait) txbyte = Signal(intbv(0)[8:]) bitcnt = Signal(intbv(0, min=0, max=9)) @always_seq(clock.posedge, reset=reset) def rtltx(): # default values fbustx.read.next = False # state handlers if state == states.wait: if not fbustx.empty and baudce: txbyte.next = fbustx.read_data fbustx.read.next = True state.next = states.start elif state == states.start: if baudce: bitcnt.next = 0 tx.next = False state.next = states.byte elif state == states.byte: if baudce: bitcnt.next = bitcnt + 1 tx.next = txbyte[bitcnt] elif bitcnt == 8: state.next = states.stop bitcnt.next = 0 elif state == states.stop: if baudce: tx.next = True state.next = states.end elif state == states.end: if baudce: state.next = states.wait else: assert False, "Invalid state %s" % (state) return rtltx
def testValAttrReadOnly(self): """ val attribute should not be writable""" s1 = Signal(1) with pytest.raises(AttributeError): s1.val = 1
def uartrx(glbl, fbusrx, rx, baudce16): """UART receiver function Arguments(Ports): glbl : rhea.Global interface, clock and reset fbusrx : FIFOBus interface to the RX fifo rx : The actual reciever line Parameters: baudce16 : The receive baud rate Returns: myHDL generators rtlmid : Get the mid bits rtlrx : Generator to keep open the receive line and read from it into RX fifo. """ clock, reset = glbl.clock, glbl.reset states = enum('wait', 'byte', 'stop', 'end') state = Signal(states.wait) rxbyte = Signal(intbv(0)[8:]) bitcnt = Signal(intbv(0, min=0, max=9)) # signals use do find the mid bit rxd = Signal(bool(0)) mcnt = Signal(modbv(0, min=0, max=16)) midbit = Signal(bool(0)) rxinprog = Signal(bool(0)) # get the middle of the bits, always sync to the beginning # (negedge) of the start bit @always(clock.posedge) def rtlmid(): rxd.next = rx if (rxd and not rx) and state == states.wait: mcnt.next = 0 rxinprog.next = True elif rxinprog and state == states.end: rxinprog.next = False elif baudce16: mcnt.next = mcnt + 1 # 7 or 8 doesn't really matter if rxinprog and mcnt == 7 and baudce16: midbit.next = True else: midbit.next = False @always_seq(clock.posedge, reset=reset) def rtlrx(): # defaults fbusrx.write.next = False # state handlers if state == states.wait: if midbit and not rx: state.next = states.byte elif state == states.byte: if midbit: rxbyte.next[bitcnt] = rx bitcnt.next = bitcnt + 1 elif bitcnt == 8: state.next = states.stop bitcnt.next = 0 elif state == states.stop: if midbit: #assert rx state.next = states.end fbusrx.write.next = True fbusrx.write_data.next = rxbyte elif state == states.end: state.next = states.wait bitcnt.next = 0 return rtlmid, rtlrx
def testDrivenAttrValue(self): """ driven attribute only accepts value 'reg' or 'wire' """ s1 = Signal(1) with pytest.raises(ValueError): s1.driven = "signal"
def top(din, init_b, cclk, ref_clk, soc_clk_p, soc_clk_n, soc_cs, soc_ras, soc_cas, soc_we, soc_ba, soc_a, soc_dqs, soc_dm, soc_dq, adc_clk_p, adc_clk_n, adc_dat_p, adc_dat_n, adc_ovr_p, adc_ovr_n, shifter_sck, shifter_sdo, bu2506_ld, adf4360_le, adc08d500_cs, lmh6518_cs, dac8532_sync, trig_p, trig_n, ba7406_vd, ba7406_hd, ac_trig, probe_comp, ext_trig_out, i2c_scl, i2c_sda, mcb3_dram_ck, mcb3_dram_ck_n, mcb3_dram_ras_n, mcb3_dram_cas_n, mcb3_dram_we_n, mcb3_dram_ba, mcb3_dram_a, mcb3_dram_odt, mcb3_dram_dqs, mcb3_dram_dqs_n, mcb3_dram_udqs, mcb3_dram_udqs_n, mcb3_dram_dm, mcb3_dram_udm, mcb3_dram_dq, bank2): insts = [] # Clock generator using STARTUP_SPARTAN primitive clk_unbuf = Signal(False) clk_unbuf_inst = startup_spartan6('startup_inst', cfgmclk = clk_unbuf) insts.append(clk_unbuf_inst) clk_buf = Signal(False) clk_inst = bufg('bufg_clk', clk_unbuf, clk_buf) insts.append(clk_inst) system = System(clk_buf, None) mux = WbMux() # Rename and adapt external SPI bus signals slave_spi_bus = SpiInterface() slave_cs = Signal(False) slave_cs_inst = syncro(clk_buf, din, slave_spi_bus.CS) insts.append(slave_cs_inst) slave_sck_inst = syncro(clk_buf, cclk, slave_spi_bus.SCK) insts.append(slave_sck_inst) slave_sdioinst = tristate(init_b, slave_spi_bus.SD_I, slave_spi_bus.SD_O, slave_spi_bus.SD_OE) insts.append(slave_sdioinst) #################################################################### # SoC bus if 0: soc_clk = Signal(False) soc_clk_b = Signal(False) soc_clk_inst = ibufgds_diff_out('ibufgds_diff_out_soc_clk', soc_clk_p, soc_clk_n, soc_clk, soc_clk_b) insts.append(soc_clk_inst) soc_clk._name = 'soc_clk' # Must match name of timing spec in ucf file soc_clk_b._name = 'soc_clk_b' # Must match name of timing spec in ucf file soc_system = System(soc_clk, None) soc_bus = DdrBus(2, 12, 2) soc_connect_inst = ddr_connect( soc_bus, soc_clk, soc_clk_b, None, soc_cs, soc_ras, soc_cas, soc_we, soc_ba, soc_a, soc_dqs, soc_dm, soc_dq) insts.append(soc_connect_inst) if 1: soc_source0 = DdrSource(soc_system, 16, 16) soc_source1 = DdrSource(soc_system, 16, 16) soc_ddr = Ddr(soc_source0, soc_source1) soc_inst = soc_ddr.gen(soc_system, soc_bus) insts.append(soc_inst) if 1: # Trace soc bus control signals soc_capture = Signal(False) soc_ctl = RegFile('soc_ctl', "SOC control", [ RwField(system, 'soc_capture', "Capture samples", soc_capture), ]) mux.add(soc_ctl, 0x231) soc_capture_sync = Signal(False) soc_capture_sync_inst = syncro(soc_clk, soc_capture, soc_capture_sync) insts.append(soc_capture_sync_inst) soc_sdr = ConcatSignal( soc_a, soc_ba, soc_we, soc_cas, soc_ras, soc_cs) soc_sdr_sampler = Sampler(addr_depth = 0x800, sample_clk = soc_clk, sample_data = soc_sdr, sample_enable = soc_capture_sync) mux.add(soc_sdr_sampler, 0x2000) soc_reg = ConcatSignal( soc_bus.A, soc_bus.BA, soc_bus.WE_B, soc_bus.CAS_B, soc_bus.RAS_B, soc_bus.CS_B) soc_reg_sampler = Sampler(addr_depth = 0x800, sample_clk = soc_clk, sample_data = soc_reg, sample_enable = soc_capture_sync) mux.add(soc_reg_sampler, 0x2800) soc_ddr_0 = ConcatSignal(soc_bus.DQ1_OE, soc_bus.DQS1_O, soc_bus.DQS1_OE, soc_bus.DQ0_I, soc_bus.DM0_I, soc_bus.DQS0_I) soc_ddr_1 = ConcatSignal(soc_bus.DQ0_OE, soc_bus.DQS0_O, soc_bus.DQS0_OE, soc_bus.DQ1_I, soc_bus.DM1_I, soc_bus.DQS1_I) soc_ddr_sampler_0 = Sampler(addr_depth = 0x800, sample_clk = soc_clk, sample_data = soc_ddr_0, sample_enable = soc_capture_sync) mux.add(soc_ddr_sampler_0, 0x3000) soc_ddr_sampler_1 = Sampler(addr_depth = 0x800, sample_clk = soc_clk, sample_data = soc_ddr_1, sample_enable = soc_capture_sync) mux.add(soc_ddr_sampler_1, 0x3800) #################################################################### # ADC bus adc_clk_ibuf = Signal(False) adc_clk_ibuf_b = Signal(False) adc_clk_ibuf_inst = ibufgds_diff_out('ibufgds_diff_out_adc_clk', adc_clk_p, adc_clk_n, adc_clk_ibuf, adc_clk_ibuf_b) insts.append(adc_clk_ibuf_inst) if 0: adc_clk = Signal(False) adc_clk_buf_inst = bufg('bufg_adc_clk', adc_clk_ibuf, adc_clk) insts.append(adc_clk_buf_inst) adc_clk_b = Signal(False) adc_clk_b_buf_inst = bufg('bufg_adc_clk_b', adc_clk_ibuf_b, adc_clk_b) insts.append(adc_clk_b_buf_inst) else: adc_clk = adc_clk_ibuf adc_clk_b = adc_clk_ibuf_b adc_clk._name = 'adc_clk' # Must match name of timing spec in ucf file adc_clk_b._name = 'adc_clk_b' # Must match name of timing spec in ucf file if 0: # For some reason myhdl doesn't recognize these signals adc_dat_p._name = 'adc_dat_p' adc_dat_n._name = 'adc_dat_n' if 0: adc_dat_p.read = True adc_dat_n.read = True print "adc_dat_p", type(adc_dat_p), len(adc_dat_p) print "adc_dat_n", type(adc_dat_n), len(adc_dat_n) if 0: adc_dat_array = [ Signal(False) for _ in range(len(adc_dat_p)) ] for i in range(len(adc_dat_p)): adc_dat_inst = ibufds('ibufds_adc_dat%d' % i, adc_dat_p[i], adc_dat_n[i], adc_dat_array[i]) insts.append(adc_dat_inst) print 'adc_dat_array', adc_dat_array adc_dat = ConcatSignal(*adc_dat_array) print len(adc_dat) else: adc_dat = Signal(intbv(0)[len(adc_dat_p):]) if 0: adc_dat._name = 'adc_dat' adc_dat.read = True adc_dat_inst = ibufds_vec('adc_dat_ibufds', adc_dat_p, adc_dat_n, adc_dat) insts.append(adc_dat_inst) adc_dat_0 = Signal(intbv(0)[len(adc_dat):]) adc_dat_1 = Signal(intbv(0)[len(adc_dat):]) adc_dat_ddr_inst = iddr2('adc_dat_iddr2', adc_dat, adc_dat_0, adc_dat_1, c0 = adc_clk, c1 = adc_clk_b, ddr_alignment = 'C0') insts.append(adc_dat_ddr_inst) adc_ovr = Signal(False) adc_ovr_inst = ibufds('ibufds_adc_ovr', adc_ovr_p, adc_ovr_n, adc_ovr) insts.append(adc_ovr_inst) if 1: adc_capture = Signal(False) adc_ctl = RegFile('adc_ctl', "ADC control", [ RwField(system, 'adc_capture', "Capture samples", adc_capture), ]) mux.add(adc_ctl, 0x230) adc_capture_sync = Signal(False) adc_capture_sync_inst = syncro(adc_clk, adc_capture, adc_capture_sync) insts.append(adc_capture_sync_inst) adc_sampler_0 = Sampler(addr_depth = 1024, sample_clk = adc_clk, sample_data = adc_dat_0, sample_enable = adc_capture_sync, skip_cnt = 99) mux.add(adc_sampler_0, 0x4000) adc_sampler_1 = Sampler(addr_depth = 1024, sample_clk = adc_clk, sample_data = adc_dat_1, sample_enable = adc_capture_sync, skip_cnt = 99) mux.add(adc_sampler_1, 0x6000) #################################################################### # Analog frontend if 1: shifter_bus = ShifterBus(6) @always_comb def shifter_comb(): shifter_sck.next = shifter_bus.SCK shifter_sdo.next = shifter_bus.SDO bu2506_ld.next = shifter_bus.CS[0] adf4360_le.next = shifter_bus.CS[1] adc08d500_cs.next = not shifter_bus.CS[2] lmh6518_cs.next[0] = not shifter_bus.CS[3] lmh6518_cs.next[1] = not shifter_bus.CS[4] dac8532_sync.next = not shifter_bus.CS[5] insts.append(shifter_comb) shifter = Shifter(system, shifter_bus, divider = 100) addr = 0x210 for reg in shifter.create_regs(): mux.add(reg, addr) addr += 1 insts.append(shifter.gen()) trig = Signal(intbv(0)[len(trig_p):]) trig_inst = ibufds_vec('ibufds_trig', trig_p, trig_n, trig) insts.append(trig_inst) #################################################################### # Probe compensation output and external trigger output # Just toggle them at 1kHz probe_comb_div = 25000 probe_comp_ctr = Signal(intbv(0, 0, probe_comb_div)) probe_comp_int = Signal(False) @always_seq (system.CLK.posedge, system.RST) def probe_comp_seq(): if probe_comp_ctr == probe_comb_div - 1: probe_comp_int.next = not probe_comp_int probe_comp_ctr.next = 0 else: probe_comp_ctr.next = probe_comp_ctr + 1 insts.append(probe_comp_seq) @always_comb def probe_comp_comb(): probe_comp.next = probe_comp_int ext_trig_out.next = probe_comp_int insts.append(probe_comp_comb) #################################################################### dram_rst_i = Signal(False) dram_clk_p = soc_clk_p dram_clk_n = soc_clk_n dram_calib_done = Signal(False) dram_error = Signal(False) dram_ctl = RegFile('dram_ctl', "DRAM control", [ RwField(system, 'dram_rst_i', "Reset", dram_rst_i), RoField(system, 'dram_calib_done', "Calib flag", dram_calib_done), RoField(system, 'dram_error', "Error flag", dram_error), ]) mux.add(dram_ctl, 0x250) mig_inst = mig( dram_rst_i, dram_clk_p, dram_clk_n, dram_calib_done, dram_error, mcb3_dram_ck, mcb3_dram_ck_n, mcb3_dram_ras_n, mcb3_dram_cas_n, mcb3_dram_we_n, mcb3_dram_ba, mcb3_dram_a, mcb3_dram_odt, mcb3_dram_dqs, mcb3_dram_dqs_n, mcb3_dram_udqs, mcb3_dram_udqs_n, mcb3_dram_dm, mcb3_dram_udm, mcb3_dram_dq) insts.append(mig_inst) #################################################################### # Random stuff if 1: pins = ConcatSignal(cclk, i2c_sda, i2c_scl, ext_trig_out, probe_comp, ac_trig, ba7406_hd, ba7406_vd, trig, ref_clk, bank2) hc = HybridCounter() mux.add(hc, 0, pins) # I have a bug somewhere in my Mux, unless I add this the adc # sample buffer won't show up in the address range. I should fix # it but I haven't managed to figure out what's wrong yet. if 1: ram3 = Ram(addr_depth = 1024, data_width = 32) mux.add(ram3, 0x8000) wb_slave = mux # Create the wishbone bus wb_bus = wb_slave.create_bus() wb_bus.CLK_I = clk_buf wb_bus.RST_I = None # Create the SPI slave spi = SpiSlave() spi.addr_width = 32 spi.data_width = 32 wb_inst = wb_slave.gen(wb_bus) insts.append(wb_inst) slave_spi_inst = spi.gen(slave_spi_bus, wb_bus) insts.append(slave_spi_inst) return insts
def testNegedgeAttrReadOnly(self): """ negedge attribute should not be writable""" s1 = Signal(1) with pytest.raises(AttributeError): s1.negedge = 1
def io_stub(clock, reset, sdi, sdo, pin, pout): """ serial-in, serial-out This module is a simple module used for synthesis testing for particular FPGA devices. This module allows a bunch of inputs to be tied to a couple IO (pins). Typically this is not used in a functionally working implementation but a circuit valid and timing valid implementation to determine a rought number of resources required for a design. Ports ----- clock : reset : sdi : serial-data in, this should be assigned to a pin on the device sdo : serial-data out, this should be assigned to a pin on the device pdin : number of inputs desired pdout : number of outputs desired Parameters None Limitations each member in the pin and pout lists need to be the same type. ---------- """ # verify pin and pout are lists assert isinstance(pin, list) assert isinstance(pout, list) Nin = len(pin) # number of inputs (outputs of this module) Nout = len(pout) # number of outputs (inputs to this module) nbx = len(pin[0]) # bit lengths of the inputs nby = len(pout[0]) # bit lengths of the outputs Signed = True if pin[0].min < 0 else False # make the input and output registers same length xl, yl = Nin * nbx, Nout * nby Nbits = max(xl, yl) irei = Signal(bool(0)) oreo = Signal(bool(0)) ireg = [Signal(intbv(0)[nbx:]) for _ in range(Nin)] oreg = [Signal(intbv(0)[nby:]) for _ in range(Nin)] scnt = Signal(intbv(0, min=0, max=Nbits + 1)) imax = scnt.max - 1 @always_seq(clock.posedge, reset=reset) def rtl_shifts(): irei.next = sdi oreo.next = oreg[Nout - 1][nby - 1] sdo.next = oreo # build the large shift register out of the logical # list of signals (array) for ii in range(Nin): if ii == 0: ireg[ii].next = concat(ireg[ii][nbx - 1:0], irei) else: ireg[ii].next = concat(ireg[ii][nbx - 1:0], ireg[ii - 1][nbx - 1]) if scnt == imax: scnt.next = 0 for oo in range(Nout): oreg[oo].next = pout[oo] else: scnt.next = scnt + 1 for oo in range(Nout): if oo == 0: oreg[oo].next = oreg[oo] << 1 else: oreg[oo].next = concat(oreg[oo][nby - 1:0], oreg[oo - 1][nby - 1]) @always_comb def rtl_assign(): for ii in range(Nin): pin[ii].next = ireg[ii] return rtl_shifts, rtl_assign
def __init__(self, width_data): self.data_in = Signal(intbv(0)[width_data:]) self.read = Signal(bool(0)) self.fifo_empty = Signal(bool(0)) self.buffer_sel = Signal(bool(0))