3 # SPDX-License-Identifier: LGPLv3+
4 # Copyright (C) 2022 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5 # Sponsored by NLnet and NGI POINTER under EU Grants 871528 and 957073
6 # Part of the Libre-SOC Project.
8 # this is a wrapper around the opencores verilog uart16550 module
10 from nmigen
import (Elaboratable
, Cat
, Module
, Signal
, ClockSignal
, Instance
,
13 from nmigen_soc
.wishbone
.bus
import Interface
14 from nmigen
.cli
import rtlil
, verilog
16 __all__
= ["UART16550"]
19 class UART16550(Elaboratable
):
20 """16550 UART from opencores, nmigen wrapper
23 def __init__(self
, bus
=None, features
=None, name
=None):
25 # convention: give the name in the format "name_number"
26 self
.idx
= int(name
.split("_")[-1])
30 # set up the wishbone bus
32 features
= frozenset()
34 bus
= Interface(addr_width
=5,
37 name
=name
+"_wb_%d" % self
.idx
)
39 assert len(self
.bus
.dat_r
) == 32, "bus width must be 32"
41 # IRQ for data buffer receive/xmit
44 # 9-pin UART signals (if anyone still remembers those...)
45 self
.tx_o
= Signal() # transmit
46 self
.rx_i
= Signal() # receive
47 self
.rts_o
= Signal() # ready to send
48 self
.cts_i
= Signal() # clear to send
49 self
.dtr_o
= Signal() # data terminal ready
50 self
.dsr_i
= Signal() # data send ready
51 self
.ri_i
= Signal() # can't even remember what this is!
52 self
.dcd_i
= Signal() # or this!
54 def elaborate(self
, platform
):
57 # create external verilog 16550 uart here
58 idx
, bus
= self
.idx
, self
.bus
59 uart
= Instance("uart_top_%d" % idx
,
60 i_wb_clk_i
=ClockSignal(),
61 i_wb_rst_i
=ResetSignal(),
71 o_stx_pad_o
=self
.tx_o
,
72 i_srx_pad_i
=self
.rx_i
,
73 o_rts_pad_o
=self
.rts_o
,
74 i_cts_pad_i
=self
.cts_i
,
75 o_dtr_pad_o
=self
.dtr_o
,
76 i_dsr_pad_i
=self
.dsr_i
,
78 i_dcd_pad_i
=self
.dcd_i
81 m
.submodules
['uart16550_%d' % self
.idx
] = uart
86 def create_ilang(dut
, ports
, test_name
):
87 vl
= rtlil
.convert(dut
, name
=test_name
, ports
=ports
)
88 with
open("%s.il" % test_name
, "w") as f
:
91 def create_verilog(dut
, ports
, test_name
):
92 vl
= verilog
.convert(dut
, name
=test_name
, ports
=ports
)
93 with
open("%s.v" % test_name
, "w") as f
:
97 if __name__
== "__main__":
98 uart
= UART16550(name
="uart_0")
99 create_ilang(uart
, [uart
.bus
.cyc
, uart
.bus
.stb
, uart
.bus
.ack
,
100 uart
.bus
.dat_r
, uart
.bus
.dat_w
, uart
.bus
.adr
,
101 uart
.bus
.we
, uart
.bus
.sel
,
103 uart
.tx_o
, uart
.rx_i
, uart
.rts_o
, uart
.cts_i
,
104 uart
.dtr_o
, uart
.dsr_i
, uart
.ri_i
, uart
.dcd_i