예제 #1
0
파일: rx.py 프로젝트: jesseclin/hwtLib
    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])
예제 #2
0
파일: rx.py 프로젝트: Nic30/hwtLib
    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])
예제 #3
0
파일: driver.py 프로젝트: mfkiwl/hwtLib
    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)
예제 #4
0
파일: tx.py 프로젝트: jesseclin/hwtLib
    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)
예제 #5
0
파일: master.py 프로젝트: Nic30/hwtLib
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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
예제 #9
0
파일: master.py 프로젝트: mfkiwl/hwtLib
    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)
예제 #10
0
 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))
예제 #11
0
파일: timers.py 프로젝트: Nic30/hwtLib
 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))