from migen.fhdl.structure import * from migen.bank.description import * from migen.bank import csrgen class UART: def __init__(self, address, clk_freq, baud=115200): self._rxtx = rxtx = Register("rxtx", BV(8)) divisor = Register("divisor") self._f_divisor = Field(divisor, "divisor", 8) # TODO: 16 stat = Register("stat") # TODO: autogenerated event manager self._f_thre = Field(stat, "thre", access_bus=READ_ONLY, access_dev=WRITE_ONLY) self.bank = csrgen.Bank([rxtx, divisor, stat], address=address) self.tx = Signal(reset=1) self.rx = Signal() self.divisor = int(clk_freq/baud/16) # TODO def get_fragment(self): enable16 = Signal() enable16_counter = Signal(BV(16)) comb = [ enable16.eq(enable16_counter == Constant(0, BV(16))) ] sync = [ enable16_counter.eq(enable16_counter - 1), If(enable16, enable16_counter.eq(self.divisor - 1)) # TODO ] tx_reg = Signal(BV(8)) tx_bitcount = Signal(BV(4)) tx_count16 = Signal(BV(4)) tx_busy = Signal() sync += [ If(self._rxtx.dev_re, tx_reg.eq(self._rxtx.dev_r), tx_bitcount.eq(0), tx_count16.eq(1), tx_busy.eq(1), self.tx.eq(0) ).Elif(enable16 & tx_busy, tx_count16.eq(tx_count16 + 1), If(tx_count16 == Constant(0, BV(4)), tx_bitcount.eq(tx_bitcount + 1), If(tx_bitcount == 8, self.tx.eq(1) ).Elif(tx_bitcount == 9, self.tx.eq(1), tx_busy.eq(0) ).Else( self.tx.eq(tx_reg[0]), tx_reg.eq(Cat(tx_reg[1:], 0)) ) ) ) ] comb += [ self._f_thre.dev_we.eq(1), self._f_thre.dev_w.eq(~tx_busy) ] return self.bank.get_fragment() + Fragment(comb, sync, pads={self.tx, self.rx})