def fifo2axi(self, clk, rst, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) readFlag = Signal(bool(0)) @always_comb def readLogic(): fifoBus.rd.next = self.tready and readFlag self.tvalid.next = fifoBus.rdout if fifoBus.rdout: self.tdata.next = fifoBus.dout self.tkeep.next = 0xFFFFFFFFFFFFFFFF self.tlast.next = fifoBus.outbusy else: self.tdata.next = 0x0 self.tkeep.next = 0x0 self.tlast.next = 0x0 @always_seq(clk.posedge, reset=rst) def readSeqLogic(): if fifoBus.hfull: readFlag.next = 1 if fifoBus.outbusy: readFlag.next = 0 return instances()
def connectorT(self, clk, rst, axi4StreamBus, axi4StreamBusDown, en, sel): functionStat(inspect.currentframe().f_code.co_name, __name__) muxTInst = self.axiSBus.demuxT(clk, rst, axi4StreamBus.axiSBus, axi4StreamBusDown.axiSBus, sel) demuxTInst = self.axiMBus.muxT(clk, rst, axi4StreamBus.axiMBus, axi4StreamBusDown.axiMBus, en, sel) return instances()
def LFSR(dout, din, run, ready, clk, rst, SIZE, TRINOMIAL, IV): functionStat(inspect.currentframe().f_code.co_name, __name__) shiftReg = Signal(modbv(0)[SIZE:]) feedback = Signal(bool(0)) counter = Signal(modbv(0)[8:]) @always_seq(clk.posedge, reset=rst) def shift(): if run: if counter < 2 * SIZE: counter.next = counter + 1 if counter == 0: shiftReg.next = IV ready.next = 0 else: shiftReg.next = concat(shiftReg[SIZE - 1:0], feedback) dout.next = shiftReg[SIZE - 1] if counter >= 2 * SIZE: ready.next = 1 else: ready.next = 0 @always_comb def taplogic(): feedback.next = shiftReg[SIZE - 1] ^ shiftReg[TRINOMIAL] ^ din return instances()
def mux(out, inp, sel): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def logic(): out.next = inp[sel] return logic
def select(insig, sel, outsig, ID=1): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def logic(): if ID == sel: outsig.next = insig else: outsig.next = 0 return instances()
def bin2grayCoSim(B, G, DATA=8): functionStat(inspect.currentframe().f_code.co_name, __name__) bin2gray_inst = bin2gray(B, G, DATA=DATA) name = 'bin2gray_' + str(DATA) bin2gray_inst.convert(hdl='Verilog', header=hdlcfg.header, directory=hdlcfg.hdl_path, name=name) os.system("iverilog -o bin2gray.o " + \ hdlcfg.hdl_path+"/{0}.v ".format(name) + \ hdlcfg.hdl_path+"/{0}.v ".format('tb_' + name)) return Cosimulation("vvp -m myhdl bin2gray.o -vcd test.vcd", B=B, G=G)
def demux(insig, outsig, sel, BITS=4): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def logic(): for i in range(BITS): if modbv(i) == sel: outsig[i].next = insig else: outsig[i].next = 0 return instances()
def sConnector(self, axiBus): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def logic(): self.tvalid.next = axiBus.tvalid axiBus.tready.next = self.tready self.tdata.next = axiBus.tdata self.tkeep.next = axiBus.tkeep self.tlast.next = axiBus.tlast self.tuser.next = axiBus.tuser return instances()
def resetDriver(rst, DELAY = 5): functionStat(inspect.currentframe().f_code.co_name, __name__) """ Reset driver rst -- output signal, 50% duty cycle drived clock DELAY -- nano second delay for derived clock """ @instance def clkgen(): yield delay(DELAY) clk.next = not clk yield delay(DELAY) clk.next = not clk return clkgen
def axi2fifo(self, clk, rst, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def writeLogic(): self.tready.next = not fifoBus.inbusy if self.tvalid: fifoBus.din.next = self.tdata fifoBus.we.next = 1 else: fifoBus.din.next = 0 fifoBus.we.next = 0 return instances()
def toBus(self, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def logic(): fifoBus.inbusy.next = self.inbusy self.we.next = fifoBus.we self.din.next = fifoBus.din fifoBus.outbusy.next = self.outbusy self.rd.next = fifoBus.rd fifoBus.dout.next = self.dout fifoBus.rdout.next = self.rdout fifoBus.hfull.next = self.hfull return instances()
def busConnect(self, inBus, outBus): functionStat(inspect.currentframe().f_code.co_name, __name__) @always_comb def connectorLogic(): inBus.inbusy.next = self.inbusy self.din.next = inBus.din self.we.next = inBus.we outBus.outbusy.next = self.outbusy self.rd.next = outBus.rd outBus.dout.next = self.dout outBus.rdout.next = self.rdout outBus.hfull.next = self.hfull outBus.length.next = self.length return instances()
def bin2gray(B, G, DATA=8): functionStat(inspect.currentframe().f_code.co_name, __name__) """ Gray encoder. B -- input intbv signal, binary encoded G -- output intbv signal, gray encoded DATA -- bit width default = 8 """ @always_comb def logic(): Bext = intbv(0)[DATA + 1:] Bext[:] = B for i in range(DATA): G.next[i] = Bext[i + 1] ^ Bext[i] return logic
def ser2par(din, we, dout, rd, clk, rst, SIZE=8): functionStat(inspect.currentframe().f_code.co_name, __name__) shiftReg = Signal(modbv(0)[SIZE:]) counter = Signal(modbv(0)[8:]) @always_seq(clk.posedge, reset=rst) def shift(): if we: shiftReg.next = concat(shiftReg[SIZE - 1:0], din) if counter == SIZE - 1: dout.next = shiftReg rd.next = 1 counter.next = 0 else: counter.next = counter + 1 rd.next = 0 return instances()
def gray2bin(G, B, DATA=8): functionStat(inspect.currentframe().f_code.co_name, __name__) """ Gray decoder. G -- input intbv signal, gray encoded B -- output intbv signal, binary encoded DATA -- bit width default = 8 """ @always_comb def logic(): Gext = intbv(0)[DATA:] Gext[:] = G for i in range(DATA): x = 0 for j in range(i, DATA): x = x ^ Gext[j] B.next[i] = x return logic
def connector(self, clk, rst): functionStat(inspect.currentframe().f_code.co_name, __name__) readFlag = Signal(bool(0)) @always_comb def connectorLogic(): self.din.next = self.dout self.we.next = self.rdout self.rd.next = not self.outbusy and not self.inbusy and readFlag @always_seq(clk.posedge, reset=rst) def Logic(): if self.hfull: readFlag.next = 1 if self.outbusy: readFlag.next = 0 return instances()
def lane(self, clkA, clkB, rst): functionStat(inspect.currentframe().f_code.co_name, __name__) busC = fifo.bus(DATA=self.DATA, ADDR=self.ADDR, UPPER=self.UPPER, LOWER=self.LOWER, OFFSET=self.OFFSET) busD = fifo.bus(DATA=self.DATA, ADDR=self.ADDR, UPPER=self.UPPER, LOWER=self.LOWER, OFFSET=self.OFFSET) fifoCInst = busC.fifo(clkA, clkB, rst) fifoDInst = busD.fifo(clkB, clkA, rst) connCInst = busC.busConnect(self.busA, self.busB) connDInst = busD.busConnect(self.busB, self.busA) return instances()
def switchSelFromUpBus(clk, rst, axiSBusUp, sel, ADDRESS=0, PRIORITY=1): functionStat(inspect.currentframe().f_code.co_name, __name__) ctr = Signal(modbv(-1)[16:]) selreg = Signal(bool(0)) length, sync, sLength, sSync = [Signal(modbv(0)[16:]) for i in range(4)] src, dst, sSrc, sDst = [Signal(modbv(0)[8:]) for i in range(4)] @always_comb def headerLogic(): sync.next = axiSBusUp.tdata[PKTSYNCPTR + PKTSYNCSIZE:PKTSYNCPTR] length.next = axiSBusUp.tdata[LENPTR + LENSIZE:LENPTR] src.next = axiSBusUp.tdata[SOURCEPTR + SOURCESIZE:SOURCEPTR] dst.next = axiSBusUp.tdata[DESTENPTR + DESTENSIZE:DESTENPTR] @always_comb def combLogic(): if axiSBusUp.tvalid: if sync == SYNC and dst == ADDRESS: sel.next = 1 else: sel.next = selreg else: sel.next = 0 @always_seq(clk.posedge, reset=rst) def SeqLogic(): if sync == SYNC and dst == ADDRESS: sSync.next = sync sLength.next = length sSrc.next = src sDst.next = dst selreg.next = 1 if sel: ctr.next = ctr + 1 if ctr == sLength - 1 and ctr != 0: ctr.next = 0 selreg.next = 0 return instances()
def signalSync(clk, rst, dIn, dOut, DATA=8): functionStat(inspect.currentframe().f_code.co_name, __name__) """ Gray decoder. clk -- clock domain for dOut rst -- Reset signal dIn -- input intbv signal, belong to different clock domain dOut -- output intbv signal, belong to clock domain clk DATA -- bit width default = 8 """ dInGray, dInGrayCrossed, dOutGray = [ Signal(intbv(0)[DATA:]) for i in range(3) ] bin2gray_inst = bin2gray(dIn, dInGray, DATA) gray2bin_inst = gray2bin(dOutGray, dOut, DATA) @always_seq(clk.posedge, reset=rst) def two_ff_sync(): dInGrayCrossed.next = dInGray dOutGray.next = dInGrayCrossed return instances()
def axi2fifo(clk, rst, axiBus, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) axi2fifoInst = axiBus.axi2fifo(clk, rst, fifoBus) return instances()
def axi2lane(self, clk, rst): functionStat(inspect.currentframe().f_code.co_name, __name__) axi2fifoInst = self.axiSBus.axi2fifo(clk, rst, self.laneBus.busA) fifo2axiInst = self.axiMBus.fifo2axi(clk, rst, self.laneBus.busA) laneInst = lane.lane(clk, clk, rst, self.laneBus) return instances()
def connector(self, axi4StreamBus): functionStat(inspect.currentframe().f_code.co_name, __name__) sConnectorInst = self.axiSBus.sConnector(axi4StreamBus.axiMBus) mConnectorInst = axi4StreamBus.axiSBus.sConnector(self.axiMBus) return instances()
def axi2lane(clk, rst, axi4StreamBus): functionStat(inspect.currentframe().f_code.co_name, __name__) axi2laneInst = axi4StreamBus.axi2lane(clk, rst) return instances()
def node(clk, rst, axi4StreamBus, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) axi2lane0 = axi4Stream.axi2lane(clk, rst, axi4StreamBus) fifoBusInst = axi4StreamBus.laneBus.busB.toBus(fifoBus) return instances()
def tester(self, inclk, outclk, rst, PRINTLOG=False, SYNCWRITE=False, SYNCREAD=False, inbuff=[], outbuff=[], SLOWFACTOR=2): functionStat(inspect.currentframe().f_code.co_name, __name__) if len(inbuff): fifobuff = inbuff else: fifobuff = self.createbuff() if len(outbuff): respbuff = outbuff else: respbuff = fifobuff #Write driver for fifo @instance def write(): self.we.next = 0 yield delay(50) i = 0 while 1: yield inclk.posedge if not self.inbusy and (SYNCWRITE or np.random.choice(SLOWFACTOR) == 0): self.we.next = 1 self.din.next = fifobuff[i] i += 1 else: self.we.next = 0 self.din.next = 0 if i == len(fifobuff): break yield inclk.posedge self.we.next = 0 #Read driver for fifo @instance def read(): self.rd.next = 0 yield outclk.posedge while (self.hfull == 0): yield outclk.posedge pass yield outclk.posedge #Extra delay is introduced to check hfull,else hfull is always one,length never dec. below '8' i = 0 while (1): yield outclk.posedge if not self.outbusy and (SYNCREAD or np.random.choice(2)): self.rd.next = 1 else: self.rd.next = 0 if self.rdout: if PRINTLOG: print(hex(self.dout), hex(respbuff[i])) else: #print(dout, modbv(respbuff[i]), i) assert hex(self.dout) == hex(respbuff[i]) i += 1 if i == len(respbuff): break yield outclk.posedge self.rd.next = 0 @always_comb def printlogic(): if PRINTLOG: if self.inbusy: print('Overflow') if self.outbusy: print('Underflow') return instances()
def fifo(self, inclk, outclk, rst): functionStat(inspect.currentframe().f_code.co_name, __name__) mem = [Signal(modbv(0)[self.DATA:]) for i in range(2**self.ADDR)] in_addr = Signal(modbv(0)[self.ADDR + 1:]) out_addr = Signal(modbv(0)[self.ADDR + 1:]) in_addr_1 = Signal(modbv(0)[self.ADDR + 1:]) out_addr_1 = Signal(modbv(0)[self.ADDR + 1:]) in_addr_gray = Signal(modbv(0)[self.ADDR + 1:]) out_addr_gray = Signal(modbv(0)[self.ADDR + 1:]) in_addr_gray_1 = Signal(modbv(0)[self.ADDR + 1:]) out_addr_gray_1 = Signal(modbv(0)[self.ADDR + 1:]) in_addr_gray_2 = Signal(modbv(0)[self.ADDR + 1:]) out_addr_gray_2 = Signal(modbv(0)[self.ADDR + 1:]) next_in_addr = Signal(modbv(0)[self.ADDR + 1:]) next_out_addr = Signal(modbv(0)[self.ADDR + 1:]) in_length = Signal(modbv(0)[self.ADDR:]) out_length = Signal(modbv(0)[self.ADDR:]) canread = Signal(bool(0)) inMsbflag = Signal(bool(0)) outMsbflag = Signal(bool(0)) bin2gray0_inst = bin2gray(in_addr, in_addr_gray, DATA=self.ADDR + 1) bin2gray1_inst = bin2gray(out_addr, out_addr_gray, DATA=self.ADDR + 1) gray2bin0_inst = gray2bin(in_addr_gray_2, in_addr_1, DATA=self.ADDR + 1) gray2bin1_inst = gray2bin(out_addr_gray_2, out_addr_1, DATA=self.ADDR + 1) @always_seq(inclk.posedge, reset=rst) def in_addr_two_ff_sync(): out_addr_gray_1.next = out_addr_gray out_addr_gray_2.next = out_addr_gray_1 @always_seq(outclk.posedge, reset=rst) def out_addr_two_ff_sync(): self.length.next = out_length in_addr_gray_1.next = in_addr_gray in_addr_gray_2.next = in_addr_gray_1 @always_comb def diffLogic(): in_length.next = in_addr - out_addr_1 out_length.next = in_addr_1 - out_addr @always_comb def writeLogic(): self.inbusy.next = in_length >= self.UPPER - 1 next_in_addr.next = in_addr if self.we: next_in_addr.next = in_addr + 1 @always_comb def readLogic2(): canread.next = (out_length > 0) and self.rd and not self.outbusy @always_comb def readLogic(): next_out_addr.next = out_addr self.hfull.next = out_length >= self.OFFSET if out_length >= self.LOWER: self.outbusy.next = 0 elif out_length < 1: self.outbusy.next = 1 if canread: next_out_addr.next = out_addr + 1 @always(inclk.posedge) def writemem(): if self.we: mem[in_addr[self.ADDR:0]].next = self.din @always(outclk.posedge) def readmem(): self.dout.next = 0 self.rdout.next = 0 if canread: self.dout.next = mem[out_addr[self.ADDR:0]] self.rdout.next = 1 @always_seq(inclk.posedge, reset=rst) def write(): in_addr.next = next_in_addr outMsbflag.next = outMsbflag if not in_addr[self.ADDR] and not out_addr_1[self.ADDR]: outMsbflag.next = 0 if out_addr_1[self.ADDR]: outMsbflag.next = 1 if in_addr[self.ADDR] and outMsbflag: in_addr.next = next_in_addr[self.ADDR:] outMsbflag.next = 0 @always_seq(outclk.posedge, reset=rst) def read(): out_addr.next = next_out_addr inMsbflag.next = inMsbflag if not in_addr_1[self.ADDR] and not out_addr[self.ADDR]: inMsbflag.next = 0 if in_addr_1[self.ADDR]: inMsbflag.next = 1 if out_addr[self.ADDR] and inMsbflag: out_addr.next = next_out_addr[self.ADDR:] inMsbflag.next = 0 return instances()
def varlane(clkS, clkL, rst, laneBus): functionStat(inspect.currentframe().f_code.co_name, __name__) laneInst = laneBus.varlane(clkS, clkL, rst) return instances()
def varlane(self, clkS, clkL, rst): functionStat(inspect.currentframe().f_code.co_name, __name__) varfifo0Inst = self.bus.one2many(clkS, clkL, rst) varfifo1Inst = self.bus.many2one(clkS, clkL, rst) return instances()
def fifo2axi(clk, rst, axiBus, fifoBus): functionStat(inspect.currentframe().f_code.co_name, __name__) fifo2axiInst = axiBus.fifo2axi(clk, rst, fifoBus) return instances()