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 core16550 module
10 from nmigen
import (Elaboratable
, Cat
, Module
, Signal
, ClockSignal
, Instance
,
12 from nmigen
.cli
import rtlil
, verilog
14 from soc
.debug
.dmi
import DMIInterface
15 from nmigen_soc
.wishbone
.bus
import Interface
18 __all__
= ["ExternalCore"]
21 class ExternalCore(Elaboratable
):
22 """External Core verilog wrapper for microwatt and libre-soc
23 (actually, anything prepared to map to the Signals defined below)
24 remember to call ExternalCore.add_verilog_source
27 def __init__(self
, ibus
=None, dbus
=None, features
=None, name
=None):
29 # set up the icache wishbone bus
31 features
= frozenset(("stall",))
33 ibus
= Interface(addr_width
=32,
39 dbus
= Interface(addr_width
=32,
44 self
.dmi
= DMIInterface(name
="dmi")
48 assert len(self
.ibus
.dat_r
) == 64, "bus width must be 64"
49 assert len(self
.dbus
.dat_r
) == 64, "bus width must be 64"
51 # IRQ for data buffer receive/xmit
54 # debug monitoring signals
56 self
.nia_req
= Signal()
58 self
.msr_req
= Signal()
59 self
.ldst_addr
= Signal(64)
60 self
.ldst_req
= Signal()
62 # alternative reset and termination indicator
63 self
.alt_reset
= Signal()
64 self
.terminated_o
= Signal()
67 def add_verilog_source(cls
, verilog_src_dir
, platform
):
68 # add each of the verilog sources, needed for when doing platform.build
69 for fname
in ['external_core_top.v',
71 # prepend the src directory to each filename, add its contents
72 fullname
= os
.path
.join(verilog_src_dir
, fname
)
73 with
open(fullname
) as f
:
74 platform
.add_file(fullname
, f
)
76 def elaborate(self
, platform
):
79 # create definition of external core here, so that
80 # nmigen understands I/O directions (defined by i_ and o_ prefixes)
81 ibus
, dbus
, dmi
= self
.ibus
, self
.dbus
, self
.dmi
84 'i_clk_i': ClockSignal(),
85 'i_rst_i': ResetSignal(),
87 'i_dmi_addr': dmi
.addr_i
,
88 'i_dmi_req': dmi
.req_i
,
91 'o_dmi_dout': dmi
.dout
,
92 'o_dmi_ack': dmi
.ack_o
,
93 # debug/monitor signals
95 'o_nia_req': self
.nia_req
,
97 'o_msr_req': self
.msr_req
,
98 'o_ldst_addr': self
.ldst_addr
,
99 'o_ldst_req': self
.ldst_req
,
100 'i_alt_reset': self
.alt_reset
,
101 'o_terminated_out': self
.terminated_o
,
102 # wishbone instruction bus
103 'i_wishbone_insn_out.adr': ibus
.adr
,
104 'i_wishbone_insn_out.dat': ibus
.dat_w
,
105 'i_wishbone_insn_out.sel': ibus
.sel
,
106 'i_wishbone_insn_out.cyc': ibus
.cyc
,
107 'i_wishbone_insn_out.stb': ibus
.stb
,
108 'i_wishbone_insn_out.we': ibus
.we
,
109 'o_wishbone_insn_in.dat': ibus
.dat_r
,
110 'o_wishbone_insn_in.ack': ibus
.ack
,
111 'o_wishbone_insn_in.stall': ibus
.stall
,
113 'i_wishbone_data_out.adr': dbus
.adr
,
114 'i_wishbone_data_out.dat': dbus
.dat_w
,
115 'i_wishbone_data_out.sel': dbus
.sel
,
116 'i_wishbone_data_out.cyc': dbus
.cyc
,
117 'i_wishbone_data_out.stb': dbus
.stb
,
118 'i_wishbone_data_out.we': dbus
.we
,
119 'o_wishbone_data_in.dat': dbus
.dat_r
,
120 'o_wishbone_data_in.ack': dbus
.ack
,
121 'o_wishbone_data_in.stall': dbus
.stall
,
122 # external interrupt request
123 'i_ext_irq': self
.irq
,
125 core
= Instance("core_top", **kwargs
)
126 m
.submodules
['core_top'] = core
131 def create_ilang(dut
, ports
, test_name
):
132 vl
= rtlil
.convert(dut
, name
=test_name
, ports
=ports
)
133 with
open("%s.il" % test_name
, "w") as f
:
136 def create_verilog(dut
, ports
, test_name
):
137 vl
= verilog
.convert(dut
, name
=test_name
, ports
=ports
)
138 with
open("%s.v" % test_name
, "w") as f
:
142 if __name__
== "__main__":
143 core
= ExternalCore(name
="core")
145 core
.ibus
.cyc
, core
.ibus
.stb
, core
.ibus
.ack
,
146 core
.ibus
.dat_r
, core
.ibus
.dat_w
, core
.ibus
.adr
,
147 core
.ibus
.we
, core
.ibus
.sel
, core
.ibus
.stall
,
148 core
.dbus
.cyc
, core
.dbus
.stb
, core
.dbus
.ack
,
149 core
.dbus
.dat_r
, core
.dbus
.dat_w
, core
.dbus
.adr
,
150 core
.dbus
.we
, core
.dbus
.sel
,
151 core
.irq
, core
.alt_reset
, core
.terminated_o
,
152 core
.nia
, core
.nia_req
,
153 core
.msr
, core
.msr_req
,
154 core
.ldst_addr
, core
.ldst_req
,
155 core
.dmi
.addr_i
, core
.dmi
.req_i
, core
.dmi
.we_i
,
156 core
.dmi
.din
, core
.dmi
.dout
, core
.dmi
.ack_o
,