1 # Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
2 # Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
8 from migen
import ClockSignal
, ResetSignal
, Signal
, Instance
, Cat
10 from litex
import get_data_mod
11 from litex
.soc
.interconnect
import wishbone
12 from litex
.soc
.cores
.cpu
import CPU
, CPU_GCC_TRIPLE_RISCV32
14 CPU_VARIANTS
= ["standard"]
19 human_name
= "Libre-SOC"
20 variants
= CPU_VARIANTS
23 gcc_triple
= ("powerpc64le-linux", "powerpc64le-linux-gnu")
24 linker_output_format
= "elf64-powerpcle"
26 io_regions
= {0xc0000000: 0x10000000} # origin, length
30 return {"csr": 0xc0000000}
35 flags
+= "-mabi=elfv2 "
36 flags
+= "-msoft-float "
37 flags
+= "-mno-string "
38 flags
+= "-mno-multiple "
40 flags
+= "-mno-altivec "
41 flags
+= "-mlittle-endian "
42 flags
+= "-mstrict-align "
43 flags
+= "-fno-stack-protector "
44 flags
+= "-D__microwatt__ "
47 def __init__(self
, platform
, variant
="standard"):
48 self
.platform
= platform
49 self
.variant
= variant
51 self
.interrupt
= Signal(32)
53 self
.pc
= Signal(64) # new program counter
54 self
.pc_ok
= Signal() # change PC
55 self
.core_start
= Signal() # stop the core
56 self
.core_stop
= Signal() # start the core
57 self
.bigendian
= Signal() # set to 1 for bigendian
58 self
.core_halted
= Signal() # core is halted
59 self
.core_busy
= Signal() # core is running (busy)
61 # instruction and data bus: 64-bit, 48 bit addressing
62 self
.ibus
= wishbone
.Interface(data_width
=64, adr_width
=48)
63 self
.dbus
= wishbone
.Interface(data_width
=64, adr_width
=48)
65 self
.periph_buses
= [self
.ibus
, self
.dbus
]
66 self
.memory_buses
= []
68 # TODO: create variants
72 self
.cpu_params
= dict(
75 i_rst
=ResetSignal() | self
.reset
,
78 #i_timer_interrupt = 0,
79 #i_software_interrupt = 0,
80 #i_external_interrupt = self.interrupt,
83 o_ibus__stb
= self
.ibus
.stb
,
84 o_ibus__cyc
= self
.ibus
.cyc
,
85 o_ibus__cti
= self
.ibus
.cti
,
86 o_ibus__bte
= self
.ibus
.bte
,
87 o_ibus__we
= self
.ibus
.we
,
88 o_ibus__adr
= Cat(Signal(3), self
.ibus
.adr
), # 64-bit
89 o_ibus__dat_w
= self
.ibus
.dat_w
,
90 o_ibus__sel
= self
.ibus
.sel
,
91 i_ibus__ack
= self
.ibus
.ack
,
92 i_ibus__err
= self
.ibus
.err
,
93 i_ibus__dat_r
= self
.ibus
.dat_r
,
96 o_dbus__stb
= self
.dbus
.stb
,
97 o_dbus__cyc
= self
.dbus
.cyc
,
98 o_dbus__cti
= self
.dbus
.cti
,
99 o_dbus__bte
= self
.dbus
.bte
,
100 o_dbus__we
= self
.dbus
.we
,
101 o_dbus__adr
= Cat(Signal(3), self
.dbus
.adr
), # 64-bit
102 o_dbus__dat_w
= self
.dbus
.dat_w
,
103 o_dbus__sel
= self
.dbus
.sel
,
104 i_dbus__ack
= self
.dbus
.ack
,
105 i_dbus__err
= self
.dbus
.err
,
106 i_dbus__dat_r
= self
.dbus
.dat_r
,
108 # monitoring / debugging
109 i_go_insn_i
= 1, # set to "always running"
111 i_pc_i_ok
= self
.pc_ok
,
112 i_core_start_i
= self
.core_start
,
113 i_core_stop_i
= self
.core_stop
,
114 i_core_bigendian_i
= self
.bigendian
,
115 o_halted_o
= self
.core_halted
,
116 o_busy_o
= self
.core_busy
119 def set_reset_address(self
, reset_address
):
120 assert not hasattr(self
, "reset_address")
121 self
.reset_address
= reset_address
122 assert reset_address
== 0x00000000
125 def elaborate(verilog_filename
):
127 sdir
= get_data_mod("cpu", "libre-soc").data_location
128 if subprocess
.call(["python3", os
.path
.join(sdir
, "cli.py"),
129 *cli_params
, verilog_filename
],
131 raise OSError("Unable to elaborate Libre-SOC CPU, "
132 "please check your nMigen/Yosys install")
134 def do_finalize(self
):
135 verilog_filename
= os
.path
.join(self
.platform
.output_dir
,
136 "gateware", "libre-soc.v")
138 verilog_filename
= verilog_filename
)
139 self
.platform
.add_source(verilog_filename
)
140 self
.specials
+= Instance("test_issuer", **self
.cpu_params
)