radix: reading first page table entry
[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 ClockSignal, ResetSignal, Signal, Instance, Cat
9
10 from litex import get_data_mod
11 from litex.soc.interconnect import wishbone
12 from litex.soc.cores.cpu import CPU
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 # sigh self.ibus = wishbone.Interface(data_width=32, adr_width=48)
63 self.ibus = wishbone.Interface(data_width=64, adr_width=48)
64 self.dbus = wishbone.Interface(data_width=64, adr_width=48)
65
66 self.periph_buses = [self.ibus, self.dbus]
67 self.memory_buses = []
68
69 # TODO: create variants
70
71 # # #
72
73 self.cpu_params = dict(
74 # clock / reset
75 i_clk=ClockSignal(),
76 i_rst=ResetSignal() | self.reset,
77
78 # TODO interrupts
79 #i_timer_interrupt = 0,
80 #i_software_interrupt = 0,
81 #i_external_interrupt = self.interrupt,
82
83 # ibus
84 o_ibus__stb = self.ibus.stb,
85 o_ibus__cyc = self.ibus.cyc,
86 o_ibus__cti = self.ibus.cti,
87 o_ibus__bte = self.ibus.bte,
88 o_ibus__we = self.ibus.we,
89 # sigh o_ibus__adr = self.ibus.adr, # for 32-bit
90 o_ibus__adr = Cat(Signal(3), self.ibus.adr), # 64-bit
91 o_ibus__dat_w = self.ibus.dat_w,
92 o_ibus__sel = self.ibus.sel,
93 i_ibus__ack = self.ibus.ack,
94 i_ibus__err = self.ibus.err,
95 i_ibus__dat_r = self.ibus.dat_r,
96
97 # dbus
98 o_dbus__stb = self.dbus.stb,
99 o_dbus__cyc = self.dbus.cyc,
100 o_dbus__cti = self.dbus.cti,
101 o_dbus__bte = self.dbus.bte,
102 o_dbus__we = self.dbus.we,
103 o_dbus__adr = Cat(Signal(3), self.dbus.adr), # 64-bit
104 o_dbus__dat_w = self.dbus.dat_w,
105 o_dbus__sel = self.dbus.sel,
106 i_dbus__ack = self.dbus.ack,
107 i_dbus__err = self.dbus.err,
108 i_dbus__dat_r = self.dbus.dat_r,
109
110 # monitoring / debugging
111 i_go_insn_i = 1, # set to "always running"
112 i_pc_i = self.pc,
113 i_pc_i_ok = self.pc_ok,
114 i_core_start_i = self.core_start,
115 i_core_stop_i = self.core_stop,
116 i_core_bigendian_i = self.bigendian,
117 o_halted_o = self.core_halted,
118 o_busy_o = self.core_busy
119 )
120
121 def set_reset_address(self, reset_address):
122 assert not hasattr(self, "reset_address")
123 self.reset_address = reset_address
124 assert reset_address == 0x00000000
125
126 @staticmethod
127 def elaborate(verilog_filename):
128 cli_params = []
129 #sdir = get_data_mod("cpu", "libre_soc").data_location
130 sdir = "./simple"
131 if subprocess.call(["python3", os.path.join(sdir, "issuer_verilog.py"),
132 *cli_params, verilog_filename],
133 ):
134 raise OSError("Unable to elaborate Libre-SOC CPU, "
135 "please check your nMigen/Yosys install")
136
137 def do_finalize(self):
138 verilog_filename = os.path.join(self.platform.output_dir,
139 "gateware", "libre-soc.v")
140 self.elaborate(verilog_filename=verilog_filename)
141 self.platform.add_source(verilog_filename)
142 self.specials += Instance("test_issuer", **self.cpu_params)
143