forked from gvsoc/gvsoc-pulp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rv64.py
128 lines (95 loc) · 4.52 KB
/
rv64.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#
# Copyright (C) 2020 ETH Zurich and University of Bologna
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import gv.gvsoc_runner
import cpu.iss.riscv as iss
import memory.memory as memory
from vp.clock_domain import Clock_domain
import interco.router as router
import devices.uart.ns16550 as ns16550
import cpu.clint
import cpu.plic
import utils.loader.loader
import gsystree as st
from interco.bus_watchpoint import Bus_watchpoint
from elftools.elf.elffile import *
import gv.gvsoc_runner as gvsoc
GAPY_TARGET = True
class Soc(st.Component):
def __init__(self, parent, name, parser):
super().__init__(parent, name)
parser.add_argument("--isa", dest="isa", type=str, default="rv64imafdc",
help="RISCV-V ISA string (default: %(default)s)")
parser.add_argument("--arg", dest="args", action="append",
help="Specify application argument (passed to main)")
[args, __] = parser.parse_known_args()
binary = None
if parser is not None:
[args, otherArgs] = parser.parse_known_args()
binary = args.binary
mem = memory.Memory(self, 'mem', size=0x80000000, atomics=True)
rom = memory.Memory(self, 'rom', size=0x10000, stim_file=self.get_file_path('pulp/chips/rv64/rom.bin'))
uart = ns16550.Ns16550(self, 'uart')
clint = cpu.clint.Clint(self, 'clint')
plic = cpu.plic.Plic(self, 'plic', ndev=1)
ico = router.Router(self, 'ico')
ico.add_mapping('mem', base=0x80000000, remove_offset=0x80000000, size=0x80000000)
self.bind(ico, 'mem', mem, 'input')
ico.add_mapping('rom', base=0x00001000, remove_offset=0x00001000, size=0x10000)
self.bind(ico, 'rom', rom, 'input')
ico.add_mapping('uart', base=0x10000000, remove_offset=0x10000000, size=0x100)
self.bind(ico, 'uart', uart, 'input')
ico.add_mapping('clint', base=0x2000000, remove_offset=0x2000000, size=0x10000)
self.bind(ico, 'clint', clint, 'input')
ico.add_mapping('plic', base=0xC000000, remove_offset=0xC000000, size=0x1000000)
self.bind(ico, 'plic', plic, 'input')
self.bind(uart, 'irq', plic, 'irq1')
host = iss.Riscv(self, 'host', isa=args.isa, boot_addr=0x1000)
loader = utils.loader.loader.ElfLoader(self, 'loader', binary=binary)
# RISCV bus watchpoint
tohost_addr = 0
fromhost_addr = 0
if binary is not None:
with open(binary, 'rb') as file:
elffile = ELFFile(file)
for section in elffile.iter_sections():
if isinstance(section, SymbolTableSection):
for symbol in section.iter_symbols():
if symbol.name == 'tohost':
tohost_addr = symbol.entry['st_value']
if symbol.name == 'fromhost':
fromhost_addr = symbol.entry['st_value']
tohost = Bus_watchpoint(self, 'tohost', tohost_addr, fromhost_addr, word_size=64, args=args.args)
self.bind(host, 'data', tohost, 'input')
self.bind(tohost, 'output', ico, 'input')
self.bind(host, 'fetch', ico, 'input')
self.bind(host, 'time', clint, 'time')
self.bind(loader, 'out', ico, 'input')
self.bind(loader, 'start', host, 'fetchen')
# self.bind(loader, 'entry', host, 'bootaddr')
self.bind(clint, 'sw_irq_0', host, 'msi')
self.bind(clint, 'timer_irq_0', host, 'mti')
self.bind(plic, 's_irq_0', host, 'sei')
self.bind(plic, 'm_irq_0', host, 'mei')
class Rv64(st.Component):
def __init__(self, parent, name, parser, options):
super(Rv64, self).__init__(parent, name, options=options)
clock = Clock_domain(self, 'clock', frequency=100000000)
soc = Soc(self, 'soc', parser)
self.bind(clock, 'out', soc, 'clock')
class Target(gvsoc.Target):
def __init__(self, parser, options):
super(Target, self).__init__(parser, options,
model=Rv64, description="RV64 virtual board")