16e28d97095a1388dca14c82ce9a1502b1abac77
[soc.git] / src / soc / litex / core.py
1 # Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.fr>
2 # Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
3 # License: BSD
4
5 import os
6 import subprocess
7
8 from migen import *
9
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
13
14 CPU_VARIANTS = ["standard"]
15
16
17 class LibreSOC(CPU):
18 name = "libre-soc"
19 human_name = "Libre-SOC"
20 variants = CPU_VARIANTS
21 data_width = 64
22 endianness = "little"
23 gcc_triple = ("powerpc64le-linux", "powerpc64le-linux-gnu")
24 linker_output_format = "elf64-powerpcle"
25 nop = "nop"
26 io_regions = {0xc0000000: 0x10000000} # origin, length
27
28 @property
29 def mem_map(self):
30 return {"csr": 0xc0000000}
31
32 @property
33 def gcc_flags(self):
34 flags = "-m64 "
35 flags += "-mabi=elfv2 "
36 flags += "-msoft-float "
37 flags += "-mno-string "
38 flags += "-mno-multiple "
39 flags += "-mno-vsx "
40 flags += "-mno-altivec "
41 flags += "-mlittle-endian "
42 flags += "-mstrict-align "
43 flags += "-fno-stack-protector "
44 flags += "-D__microwatt__ "
45 return flags
46
47 def __init__(self, platform, variant="standard"):
48 self.platform = platform
49 self.variant = variant
50 self.reset = Signal()
51 self.interrupt = Signal(32)
52
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)
60
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)
64
65 self.periph_buses = [self.ibus, self.dbus]
66 self.memory_buses = []
67
68 # TODO: create variants
69
70 # # #
71
72 self.cpu_params = dict(
73 # clock / reset
74 i_clk=ClockSignal(),
75 i_rst=ResetSignal() | self.reset,
76
77 # TODO interrupts
78 #i_timer_interrupt = 0,
79 #i_software_interrupt = 0,
80 #i_external_interrupt = self.interrupt,
81
82 # ibus
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,
94
95 # dbus
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,
107
108 # monitoring / debugging
109 i_go_insn_i = 1, # set to "always running"
110 i_pc_i = self.pc,
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
117 )
118
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
123
124 @staticmethod
125 def elaborate(verilog_filename):
126 cli_params = []
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],
130 ):
131 raise OSError("Unable to elaborate Libre-SOC CPU, "
132 "please check your nMigen/Yosys install")
133
134 def do_finalize(self):
135 verilog_filename = os.path.join(self.platform.output_dir,
136 "gateware", "libre-soc.v")
137 self.elaborate(
138 verilog_filename = verilog_filename)
139 self.platform.add_source(verilog_filename)
140 self.specials += Instance("test_issuer", **self.cpu_params)
141