def _impl(self): START_BIT = 0 STOP_BIT = 1 os = int(self.OVERSAMPLING) baud = int(self.BAUD) freq = int(self.FREQ) assert freq >= baud * os, "Frequency too low for current Baud rate and oversampling" assert os >= 8 and (os & (os - 1)) == 0, "Invalid oversampling value" propagateClkRstn(self) clkBuilder = ClkBuilder(self, self.clk) en = self._reg("en", defVal=0) first = self._reg("first", defVal=1) RxD_data = self._reg("RxD_data", Bits(1 + 8)) startBitWasNotStartbit = self._sig("startBitWasNotStartbit") # it can happen that there is just glitch on wire and bit was not startbit only begin was resolved wrong # eval because otherwise vhdl int overflows sampleTick = clkBuilder.timer( ("sampleTick", self.FREQ // self.BAUD // self.OVERSAMPLING), enableSig=en, rstSig=~en) # synchronize RxD to our clk domain RxD_sync = self._reg("RxD_sync", defVal=1) RxD_sync(self.rxd) rxd, rxd_vld = clkBuilder.oversample(RxD_sync, self.OVERSAMPLING, sampleTick, rstSig=~en) isLastBit = clkBuilder.timer(("isLastBitTick", 10), enableSig=rxd_vld, rstSig=~en) If( en, If( rxd_vld, RxD_data(Concat(rxd, RxD_data[9:1])), # shift data from left If( startBitWasNotStartbit, en(0), first(1), ).Else( en(~isLastBit), first(isLastBit), ))).Elif( RxD_sync._eq(START_BIT), # potential start bit detected, begin scanning sequence en(1), ) startBitWasNotStartbit(first & rxd_vld & (rxd != START_BIT)) self.dataOut.vld(isLastBit & RxD_data[0]._eq(START_BIT) & rxd._eq(STOP_BIT)) self.dataOut.data(RxD_data[9:1])
def _impl(self): START_BIT = 0 STOP_BIT = 1 os = int(self.OVERSAMPLING) baud = int(self.BAUD) freq = int(self.FREQ) assert freq >= baud * os, "Frequency too low for current Baud rate and oversampling" assert os >= 8 and (os & (os - 1)) == 0, "Invalid oversampling value" propagateClkRstn(self) clkBuilder = ClkBuilder(self, self.clk) en = self._reg("en", defVal=0) first = self._reg("first", defVal=1) RxD_data = self._reg("RxD_data", Bits(1 + 8)) startBitWasNotStartbit = self._sig("startBitWasNotStartbit") # it can happen that there is just glitch on wire and bit was not startbit only begin was resolved wrong # eval because otherwise vhdl int overflows sampleTick = clkBuilder.timer(("sampleTick", self.FREQ // self.BAUD // self.OVERSAMPLING), enableSig=en, rstSig=~en) # synchronize RxD to our clk domain RxD_sync = self._reg("RxD_sync", defVal=1) RxD_sync(self.rxd) rxd, rxd_vld = clkBuilder.oversample(RxD_sync, self.OVERSAMPLING, sampleTick, rstSig=~en) isLastBit = clkBuilder.timer(("isLastBitTick", 10), enableSig=rxd_vld, rstSig=~en) If(en, If(rxd_vld, RxD_data(Concat(rxd, RxD_data[9:1])), # shift data from left If(startBitWasNotStartbit, en(0), first(1), ).Else( en(~isLastBit), first(isLastBit), ) ) ).Elif(RxD_sync._eq(START_BIT), # potential start bit detected, begin scanning sequence en(1), ) startBitWasNotStartbit(first & rxd_vld & (rxd != START_BIT)) self.dataOut.vld(isLastBit & RxD_data[0]._eq(START_BIT) & rxd._eq(STOP_BIT)) self.dataOut.data(RxD_data[9:1])
def _impl(self): """ * read on 'en' faling edge, write on 'en' rising edge * 'en' max frequency = LCD_FREQ / 10 * rs has to be set at least 1 clk (LCD_FREQ) before rising edge of 'en' """ LCD_DW = self.LCD_DATA_WIDTH assert LCD_DW in (4, 8), LCD_DW cmd_timer_rst = self._sig("cmd_timer_rst") HALF_LCD_PERIOD = ceil(self.FREQ / (self.LCD_FREQ * 2)) LCD_CLK_PER = 2 * HALF_LCD_PERIOD lcd_clk_en, = ClkBuilder(self, self.clk).timers([ ("lcd_clk_en", LCD_CLK_PER), ]) delay_cmd_half_done, delay_cmd_done, delay_cmd_long_done =\ ClkBuilder(self, self.clk)\ .timers([ # used to signalize that the 'en' should be asserted low ("delay_cmd_half_done", Hd44780Intf.DELAY_CMD // 2), # used to signalize that the processing of command is completed ("delay_cmd_done", Hd44780Intf.DELAY_CMD), # used to signalize that the long command (return home, etc.) is completed ("delay_cmd_long_done", Hd44780Intf.DELAY_RETURN_HOME) ], enableSig=lcd_clk_en, rstSig=cmd_timer_rst ) data_in_tmp = Hd44780CmdIntf() data_in_tmp.DATA_WIDTH = self.LCD_DATA_WIDTH self.data_in_tmp = data_in_tmp self._io_core(data_in_tmp, cmd_timer_rst, lcd_clk_en, delay_cmd_half_done, delay_cmd_done, delay_cmd_long_done) INIT_SEQUENCE = [ Hd44780Intf.CMD_FUNCTION_SET( Hd44780Intf.DATA_LEN_8b if LCD_DW == 8 else Hd44780Intf.DATA_LEN_4b, self.LCD_ROWS - 1, Hd44780Intf.FONT_5x8), Hd44780Intf.CMD_DISPLAY_CONTROL(1, 0, 0), Hd44780Intf.CMD_ENTRY_MODE_SET(1, 1), ] init_seq = Hd44780CmdIntfBurst() init_seq.DATA_WIDTH = self.LCD_DATA_WIDTH init_seq.DATA = tuple( (Hd44780Intf.RS_CONTROL, Hd44780Intf.RW_WRITE, 0, d) for d in INIT_SEQUENCE ) self.init_seq = init_seq propagateClkRstn(self) data_in = self._translate_data_in(self.dataIn) data_in_tmp(HsBuilder.join_prioritized(self, [init_seq.dataOut, data_in]).end)
def _impl(self): propagateClkRstn(self) r = self._reg START_BIT = hBit(0) STOP_BIT = hBit(1) BITS_TO_SEND = 1 + 8 + 1 BIT_RATE = self.FREQ // self.BAUD assert BIT_RATE >= 1 din = self.dataIn data = r("data", Bits(BITS_TO_SEND)) # data + start bit + stop bit en = r("en", defVal=False) tick, last = ClkBuilder(self, self.clk).timers( [BIT_RATE, BIT_RATE * BITS_TO_SEND], en) If(~en & din.vld, data(Concat(STOP_BIT, din.data, START_BIT)), en(1)).Elif( tick & en, # srl where 1 is shifted from left data(hBit(1)._concat(data[:1])), If( last, en(0), )) din.rd(~en) txd = r("reg_txd", defVal=1) If(tick & en, txd(data[0])) self.txd(txd)
def spiClkGen(self, requiresInitWait, en): """ create clock generator for SPI writeTick is 1 on falling edge of spi clk readTick is 1 on rising edge of spi clk :return: tuple of tick signals (if data should be send, if data should be read) """ builder = ClkBuilder(self, self.clk) timersRst = self._sig("timersRst") PESCALER = self.SPI_FREQ_PESCALER SPI_HALF_PERIOD = PESCALER // 2 spiClkHalfTick, initWaitDone, endOfWord = builder.timers( [("spiClkHalfTick", SPI_HALF_PERIOD), ("initWait", SPI_HALF_PERIOD * self.SS_WAIT_CLK_TICKS * 2), ("endOfWord", SPI_HALF_PERIOD * 8 * 2) ], enableSig=en, rstSig=timersRst) timersRst(~en | (requiresInitWait & initWaitDone)) clkIntern = self._reg("clkIntern", defVal=1) clkOut = self._reg("clkOut", defVal=1) If(spiClkHalfTick, clkIntern(~clkIntern) ) If(~requiresInitWait & spiClkHalfTick, clkOut(~clkOut) ) self.spi.clk(clkOut) # clk idle value is high clkRisign, clkFalling = builder.edgeDetector(clkIntern.next, rise=True, fall=True, initVal=1) rdEn = clkRisign & ~requiresInitWait wrEn = clkFalling & ~requiresInitWait return (wrEn, rdEn, initWaitDone, endOfWord)
def spiClkGen(self, requiresInitWait, en): """ create clock generator for SPI writeTick is 1 on falling edge of spi clk readTick is 1 on rising edge of spi clk :return: tuple of tick signals (if data should be send, if data should be read) """ builder = ClkBuilder(self, self.clk) timersRst = self._sig("timersRst") PESCALER = self.SPI_FREQ_PESCALER SPI_HALF_PERIOD = PESCALER // 2 spiClkHalfTick, initWaitDone, endOfWord = builder.timers( [("spiClkHalfTick", SPI_HALF_PERIOD), ("initWait", SPI_HALF_PERIOD * self.SS_WAIT_CLK_TICKS * 2), ("endOfWord", SPI_HALF_PERIOD * 8 * 2)], enableSig=en, rstSig=timersRst) timersRst(~en | (requiresInitWait & initWaitDone)) clkIntern = self._reg("clkIntern", def_val=1) clkOut = self._reg("clkOut", def_val=1) If(spiClkHalfTick, clkIntern(~clkIntern)) If(~requiresInitWait & spiClkHalfTick, clkOut(~clkOut)) self.spi.clk(clkOut) # clk idle value is high clkRisign, clkFalling = builder.edgeDetector(clkIntern.next, rise=True, fall=True, initVal=1) rdEn = clkRisign & ~requiresInitWait wrEn = clkFalling & ~requiresInitWait return (wrEn, rdEn, initWaitDone, endOfWord)
def _impl(self): tick1, tick2, tick16, tick17, tick34, tick256, tick384 =\ ClkBuilder(self, self.clk)\ .timers([1, 2, 16, 17, 34, 256, 384]) self.tick1(tick1) self.tick2(tick2) self.tick16(tick16) self.tick17(tick17) self.tick34(tick34) self.tick256(tick256) self.tick384(tick384)
def filter(self, name, sig): """attempt to remove glitches""" filter0 = ClkBuilder(self, self.clk, "filter")\ .reg_path(sig, 2, "filter", def_val=0) # let filter_cnt to be shared between filters try: filter_clk_cntr = self.filter_clk_cntr except AttributeError: filter_clk_cntr = self.filter_clk_cntr = self._reg( "filter_clk_cntr", Bits(self.CLK_CNTR_WIDTH), def_val=self.clk_cnt_initVal) If(filter_clk_cntr._eq(0), filter_clk_cntr(self.clk_cnt_initVal)).Else( filter_clk_cntr(filter_clk_cntr - 1)) filter1 = self._reg(name + "_filter1", dtype=Bits(3), def_val=0b111) If(filter_clk_cntr._eq(0), filter1(Concat(filter1[2:], filter0))) filtered = ((filter1[2] & filter1[1]) | (filter1[2] & filter1[0]) | (filter1[1] & filter1[0])) return filtered
def _impl(self): # timers and other registers CLK_HALF_PERIOD_DIV = ceil(self.clk.FREQ / (self.MDIO_FREQ * 2)) mdio_clk = self._reg("mdio_clk", def_val=0) r_data_vld = self._reg("r_data_vld", def_val=0) req = self.req clk_half_period_en = ClkBuilder(self, self.clk).timer( ("clk_half_period_en", CLK_HALF_PERIOD_DIV)) If( clk_half_period_en, mdio_clk(~mdio_clk), ) mdio_clk_rising = clk_half_period_en & ~mdio_clk mdio_clk_falling = clk_half_period_en & mdio_clk idle = self._sig("idle") preamble_last, addr_block_last, turnarround_last_en, data_last =\ self._packet_sequence_timer( mdio_clk_rising, mdio_clk_falling, ~idle) is_rx = self._reg("is_rx", def_val=0) # protocol FSM st_t = HEnum("st_t", ["idle", "pre", "addr_block", "ta", "data"]) st = FsmBuilder(self, st_t)\ .Trans(st_t.idle, (req.vld & ~r_data_vld, st_t.pre))\ .Trans(st_t.pre, (preamble_last, st_t.addr_block))\ .Trans(st_t.addr_block, (addr_block_last, st_t.ta))\ .Trans(st_t.ta, (turnarround_last_en & ( (is_rx & mdio_clk_falling) | (~is_rx & mdio_clk_rising)), st_t.data))\ .Trans(st_t.data, (data_last, st_t.idle)).stateReg idle(st._eq(st_t.idle)) req.rd(idle & ~r_data_vld) If(idle, is_rx(req.opcode._eq(Mdio.OP.READ))) # TX logic md = self.md TX_W = md.ST_W + md.OP_W + md.PA_W + md.RA_W + md.TA_W + md.D_W tx_reg = self._reg("tx_reg", Bits(TX_W)) If( idle & req.vld, tx_reg( Concat( Mdio.ST, req.opcode, req.addr.phy, req.addr.reg, Mdio.TA, req.wdata))).Elif( mdio_clk_falling & In(st, [st_t.addr_block, st_t.data, st_t.ta, st_t.data]), tx_reg(tx_reg << 1)) md.c(mdio_clk) # because MDIO uses open-drain, this means that if t=0 the value of the signal is 1 md.io.o(0) tx_bit = tx_reg[tx_reg._dtype.bit_length() - 1] md.io.t(~idle & ~tx_bit & (st._eq(st_t.addr_block) | (In(st, [st_t.data, st_t.ta]) & ~is_rx))) # RX logic rx_reg = self._reg("rx_reg", Bits(md.D_W)) If( st._eq(st_t.data) & is_rx & mdio_clk_rising, shift_in_msb_first(rx_reg, self.md.io.i)) If(idle & self.rdata.rd, r_data_vld(0)).Elif(addr_block_last, r_data_vld(is_rx)) self.rdata.vld(idle & r_data_vld) self.rdata.data(rx_reg)
def _impl(self): b = ClkBuilder(self, self.clk) self.cntr0(b.timerDynamic(self.period, self.en)) self.cntr1(b.timerDynamic(self.period, self.en, rstSig=self.rstCntr))