133df974bac22211ec945e320032385ea1a77f8f
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
.ldst_addr
= Signal(64)
59 self
.ldst_req
= Signal()
61 # alternative reset and termination indicator
62 self
.alt_reset
= Signal()
63 self
.terminated_o
= Signal()
66 def add_verilog_source(cls
, verilog_src_dir
, platform
):
67 # add each of the verilog sources, needed for when doing platform.build
68 for fname
in ['external_core_top.v',
70 # prepend the src directory to each filename, add its contents
71 fullname
= os
.path
.join(verilog_src_dir
, fname
)
72 with
open(fullname
) as f
:
73 platform
.add_file(fullname
, f
)
75 def elaborate(self
, platform
):
78 # create definition of external core here, so that
79 # nmigen understands I/O directions (defined by i_ and o_ prefixes)
80 ibus
, dbus
, dmi
= self
.ibus
, self
.dbus
, self
.dmi
83 'i_clk': ClockSignal(),
84 'i_rst': ResetSignal(),
86 'i_dmi_addr': dmi
.addr_i
,
87 'i_dmi_req': dmi
.req_i
,
90 'o_dmi_dout': dmi
.dout
,
91 'o_dmi_ack': dmi
.ack_o
,
92 # debug/monitor signals
94 'o_nia_req': self
.nia_req
,
96 'o_ldst_addr': self
.ldst_addr
,
97 'o_ldst_req': self
.ldst_req
,
98 'i_alt_reset': self
.alt_reset
,
99 'o_terminated_out': self
.terminated_o
,
100 # wishbone instruction bus
101 'o_wishbone_insn_out.adr': ibus
.adr
,
102 'o_wishbone_insn_out.dat': ibus
.dat_w
,
103 'o_wishbone_insn_out.sel': ibus
.sel
,
104 'o_wishbone_insn_out.cyc': ibus
.cyc
,
105 'o_wishbone_insn_out.stb': ibus
.stb
,
106 'o_wishbone_insn_out.we': ibus
.we
,
107 'i_wishbone_insn_in.dat': ibus
.dat_r
,
108 'i_wishbone_insn_in.ack': ibus
.ack
,
109 'i_wishbone_insn_in.stall': ibus
.stall
,
111 'o_wishbone_data_out.adr': dbus
.adr
,
112 'o_wishbone_data_out.dat': dbus
.dat_w
,
113 'o_wishbone_data_out.sel': dbus
.sel
,
114 'o_wishbone_data_out.cyc': dbus
.cyc
,
115 'o_wishbone_data_out.stb': dbus
.stb
,
116 'o_wishbone_data_out.we': dbus
.we
,
117 'i_wishbone_data_in.dat': dbus
.dat_r
,
118 'i_wishbone_data_in.ack': dbus
.ack
,
119 'i_wishbone_data_in.stall': dbus
.stall
,
120 # external interrupt request
121 'i_ext_irq': self
.irq
,
123 core
= Instance("external_core_top", **kwargs
)
124 m
.submodules
['core_top'] = core
129 def create_ilang(dut
, ports
, test_name
):
130 vl
= rtlil
.convert(dut
, name
=test_name
, ports
=ports
)
131 with
open("%s.il" % test_name
, "w") as f
:
134 def create_verilog(dut
, ports
, test_name
):
135 vl
= verilog
.convert(dut
, name
=test_name
, ports
=ports
)
136 with
open("%s.v" % test_name
, "w") as f
:
140 if __name__
== "__main__":
141 core
= ExternalCore(name
="core")
143 core
.ibus
.cyc
, core
.ibus
.stb
, core
.ibus
.ack
,
144 core
.ibus
.dat_r
, core
.ibus
.dat_w
, core
.ibus
.adr
,
145 core
.ibus
.we
, core
.ibus
.sel
, core
.ibus
.stall
,
146 core
.dbus
.cyc
, core
.dbus
.stb
, core
.dbus
.ack
,
147 core
.dbus
.dat_r
, core
.dbus
.dat_w
, core
.dbus
.adr
,
148 core
.dbus
.we
, core
.dbus
.sel
,
149 core
.irq
, core
.alt_reset
, core
.terminated_o
,
150 core
.msr
, core
.nia
, core
.nia_req
,
151 core
.ldst_addr
, core
.ldst_req
,
152 core
.dmi
.addr_i
, core
.dmi
.req_i
, core
.dmi
.we_i
,
153 core
.dmi
.din
, core
.dmi
.dout
, core
.dmi
.ack_o
,