Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
litex
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jonathan Currier
litex
Commits
8d0f008a
Commit
8d0f008a
authored
Jun 05, 2019
by
Florent Kermarrec
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
integration/soc_core: improve readibility (add separators/comments)
parent
55ebcc00
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
66 deletions
+107
-66
litex/soc/integration/soc_core.py
litex/soc/integration/soc_core.py
+107
-66
No files found.
litex/soc/integration/soc_core.py
View file @
8d0f008a
...
...
@@ -4,6 +4,8 @@ import struct
import
inspect
import
json
import
math
import
datetime
import
time
from
operator
import
itemgetter
from
migen
import
*
...
...
@@ -25,6 +27,7 @@ __all__ = [
"soc_core_argdict"
]
# CPU Variants -------------------------------------------------------------------------------------
CPU_VARIANTS
=
{
# "official name": ["alias 1", "alias 2"],
...
...
@@ -60,11 +63,9 @@ Possible Values:
msg
+=
" - {}
\
n
"
.
format
(
e
)
ValueError
.
__init__
(
self
,
msg
)
# Helpers ------------------------------------------------------------------------------------------
def
version
(
with_time
=
True
):
import
datetime
import
time
if
with_time
:
return
datetime
.
datetime
.
fromtimestamp
(
time
.
time
()).
strftime
(
"%Y-%m-%d %H:%M:%S"
)
...
...
@@ -72,11 +73,6 @@ def version(with_time=True):
return
datetime
.
datetime
.
fromtimestamp
(
time
.
time
()).
strftime
(
"%Y-%m-%d"
)
def
mem_decoder
(
address
,
start
=
26
,
end
=
29
):
return
lambda
a
:
a
[
start
:
end
]
==
((
address
>>
(
start
+
2
))
&
(
2
**
(
end
-
start
))
-
1
)
def
get_mem_data
(
filename_or_regions
,
endianness
=
"big"
,
mem_size
=
None
):
# create memory regions
if
isinstance
(
filename_or_regions
,
dict
):
...
...
@@ -120,24 +116,14 @@ def get_mem_data(filename_or_regions, endianness="big", mem_size=None):
i
+=
1
return
data
class
ReadOnlyDict
(
dict
):
def
__readonly__
(
self
,
*
args
,
**
kwargs
):
raise
RuntimeError
(
"Cannot modify ReadOnlyDict"
)
__setitem__
=
__readonly__
__delitem__
=
__readonly__
pop
=
__readonly__
popitem
=
__readonly__
clear
=
__readonly__
update
=
__readonly__
setdefault
=
__readonly__
del
__readonly__
def
mem_decoder
(
address
,
start
=
26
,
end
=
29
):
return
lambda
a
:
a
[
start
:
end
]
==
((
address
>>
(
start
+
2
))
&
(
2
**
(
end
-
start
))
-
1
)
def
csr_map_update
(
csr_map
,
csr_peripherals
):
csr_map
.
update
(
dict
((
n
,
v
)
for
v
,
n
in
enumerate
(
csr_peripherals
,
start
=
max
(
csr_map
.
values
())
+
1
)))
# SoCController ------------------------------------------------------------------------------------
class
SoCController
(
Module
,
AutoCSR
):
def
__init__
(
self
):
...
...
@@ -162,37 +148,66 @@ class SoCController(Module, AutoCSR):
)
self
.
comb
+=
self
.
_bus_errors
.
status
.
eq
(
bus_errors
)
# SoCCore ------------------------------------------------------------------------------------------
class
SoCCore
(
Module
):
csr_map
=
{}
# default register/interrupt/memory mappings (can be redefined by user)
csr_map
=
{}
interrupt_map
=
{}
mem_map
=
{
mem_map
=
{
"rom"
:
0x00000000
,
# (default shadow @0x80000000)
"sram"
:
0x10000000
,
# (default shadow @0x90000000)
"main_ram"
:
0x40000000
,
# (default shadow @0xc0000000)
"csr"
:
0x60000000
,
# (default shadow @0xe0000000)
}
def
__init__
(
self
,
platform
,
clk_freq
,
# CPU parameters
cpu_type
=
"vexriscv"
,
cpu_reset_address
=
0x00000000
,
cpu_variant
=
None
,
# MEM MAP parameters
shadow_base
=
0x80000000
,
# ROM parameters
integrated_rom_size
=
0
,
integrated_rom_init
=
[],
# SRAM parameters
integrated_sram_size
=
4096
,
integrated_sram_init
=
[],
# MAIN_RAM parameters
integrated_main_ram_size
=
0
,
integrated_main_ram_init
=
[],
shadow_base
=
0x80000000
,
# CSR parameters
csr_data_width
=
8
,
csr_address_width
=
14
,
with_uart
=
True
,
uart_name
=
"serial"
,
uart_baudrate
=
115200
,
uart_stub
=
False
,
# Identifier parameters
ident
=
""
,
ident_version
=
False
,
wishbone_timeout_cycles
=
1e6
,
# UART parameters
with_uart
=
True
,
uart_name
=
"serial"
,
uart_baudrate
=
115200
,
uart_stub
=
False
,
# Timer parameters
with_timer
=
True
,
with_ctrl
=
True
):
self
.
config
=
dict
()
# Controller parameters
with_ctrl
=
True
,
# Wishbone parameters
wishbone_timeout_cycles
=
1e6
):
self
.
platform
=
platform
self
.
clk_freq
=
clk_freq
# config dictionary (store all SoC's parameters to be exported to software)
self
.
config
=
dict
()
# SoC's register/interrupt/memory mappings (default or user defined + dynamically allocateds)
self
.
soc_csr_map
=
{}
self
.
soc_interrupt_map
=
{}
self
.
soc_mem_map
=
self
.
mem_map
# Regions / Constants lists
self
.
_memory_regions
=
[]
# (name, origin, length)
self
.
_csr_regions
=
[]
# (name, origin, busword, csr_list/Memory)
self
.
_constants
=
[]
# (name, value)
# Wishbone masters/slaves lists
self
.
_wb_masters
=
[]
self
.
_wb_slaves
=
[]
# CSR masters list
self
.
_csr_masters
=
[]
# Parameters managment ---------------------------------------------------------------------
# FIXME: RocketChip reserves the first 256Mbytes for internal use
# remap rom to 0x10000000, sram to 0x20000000
if
cpu_type
==
"rocket"
:
...
...
@@ -207,6 +222,7 @@ class SoCCore(Module):
if
cpu_variant
is
None
:
cpu_variant
=
"standard"
cpu_variant
=
cpu_variant
.
replace
(
'_'
,
'+'
)
# Check for valid CPU variants.
cpu_variant_processor
,
*
cpu_variant_ext
=
cpu_variant
.
split
(
'+'
)
for
key
,
values
in
CPU_VARIANTS
.
items
():
...
...
@@ -228,40 +244,38 @@ class SoCCore(Module):
self
.
cpu_reset_address
=
cpu_reset_address
self
.
config
[
"CPU_RESET_ADDR"
]
=
self
.
cpu_reset_address
self
.
shadow_base
=
shadow_base
self
.
integrated_rom_size
=
integrated_rom_size
self
.
integrated_rom_initialized
=
integrated_rom_init
!=
[]
self
.
integrated_sram_size
=
integrated_sram_size
self
.
integrated_main_ram_size
=
integrated_main_ram_size
self
.
with_uart
=
with_uart
self
.
uart_baudrate
=
uart_baudrate
self
.
shadow_base
=
shadow_base
self
.
wishbone_timeout_cycles
=
wishbone_timeout_cycles
self
.
csr_data_width
=
csr_data_width
self
.
csr_address_width
=
csr_address_width
self
.
with_ctrl
=
with_ctrl
self
.
_memory_regions
=
[]
# list of (name, origin, length)
self
.
_csr_regions
=
[]
# list of (name, origin, busword, csr_list/Memory)
self
.
_constants
=
[]
# list of (name, value)
self
.
with_uart
=
with_uart
self
.
uart_baudrate
=
uart_baudrate
self
.
_wb_masters
=
[]
self
.
_wb_slaves
=
[]
self
.
_csr_masters
=
[]
self
.
wishbone_timeout_cycles
=
wishbone_timeout_cycles
# Modules instances ------------------------------------------------------------------------
#
add user csrs
#
Add user's CSRs (needs to be done before the first dynamic allocation)
for
_name
,
_id
in
self
.
csr_map
.
items
():
self
.
add_csr
(
_name
,
_id
)
# Add SoCController
if
with_ctrl
:
self
.
submodules
.
ctrl
=
SoCController
()
self
.
add_csr
(
"ctrl"
,
allow_user_defined
=
True
)
# Add CPU
self
.
config
[
"CPU_TYPE"
]
=
str
(
cpu_type
).
upper
()
if
cpu_type
is
not
None
:
# CPU selection / instance
if
cpu_type
==
"lm32"
:
self
.
add_cpu
(
lm32
.
LM32
(
platform
,
self
.
cpu_reset_address
,
self
.
cpu_variant
))
elif
cpu_type
==
"mor1kx"
or
cpu_type
==
"or1k"
:
...
...
@@ -278,36 +292,42 @@ class SoCCore(Module):
self
.
add_cpu
(
rocket
.
RocketRV64
(
platform
,
self
.
cpu_reset_address
,
self
.
cpu_variant
))
else
:
raise
ValueError
(
"Unsupported CPU type: {}"
.
format
(
cpu_type
))
self
.
add_csr
(
"cpu"
,
allow_user_defined
=
True
)
# Add Instruction/Data buses as Wisbone masters
self
.
add_wb_master
(
self
.
cpu
.
ibus
)
self
.
add_wb_master
(
self
.
cpu
.
dbus
)
if
with_ctrl
:
self
.
comb
+=
self
.
cpu
.
reset
.
eq
(
self
.
ctrl
.
reset
)
# add cpu reserved interrupts
# Add CPU CSR (dynamic)
self
.
add_csr
(
"cpu"
,
allow_user_defined
=
True
)
# Add CPU reserved interrupts
for
_name
,
_id
in
self
.
cpu
.
reserved_interrupts
.
items
():
self
.
add_interrupt
(
_name
,
_id
)
# add user interrupts
# Allow SoCController to reset the CPU
if
with_ctrl
:
self
.
comb
+=
self
.
cpu
.
reset
.
eq
(
self
.
ctrl
.
reset
)
# Add user's interrupts (needs to be done after CPU reserved interrupts are allocated)
for
_name
,
_id
in
self
.
interrupt_map
.
items
():
self
.
add_interrupt
(
_name
,
_id
)
self
.
config
[
"CPU_TYPE"
]
=
str
(
cpu_type
).
upper
()
if
self
.
cpu_variant
:
self
.
config
[
"CPU_VARIANT"
]
=
str
(
cpu_type
).
upper
()
# Add integrated ROM
if
integrated_rom_size
:
self
.
submodules
.
rom
=
wishbone
.
SRAM
(
integrated_rom_size
,
read_only
=
True
,
init
=
integrated_rom_init
)
self
.
register_rom
(
self
.
rom
.
bus
,
integrated_rom_size
)
# Add integrated SRAM
if
integrated_sram_size
:
self
.
submodules
.
sram
=
wishbone
.
SRAM
(
integrated_sram_size
,
init
=
integrated_sram_init
)
self
.
register_mem
(
"sram"
,
self
.
soc_mem_map
[
"sram"
],
self
.
sram
.
bus
,
integrated_sram_size
)
#
Note: Main Ram can be used when no external SDRAM is available and use SDRAM mapping.
#
Add integrated MAIN_RAM (only useful when no external SRAM/SDRAM is available)
if
integrated_main_ram_size
:
self
.
submodules
.
main_ram
=
wishbone
.
SRAM
(
integrated_main_ram_size
,
init
=
integrated_main_ram_init
)
self
.
register_mem
(
"main_ram"
,
self
.
soc_mem_map
[
"main_ram"
],
self
.
main_ram
.
bus
,
integrated_main_ram_size
)
# Add Wishbone to CSR bridge
self
.
submodules
.
wishbone2csr
=
wishbone2csr
.
WB2CSR
(
bus_csr
=
csr_bus
.
Interface
(
csr_data_width
,
csr_address_width
))
self
.
add_csr_master
(
self
.
wishbone2csr
.
csr
)
...
...
@@ -315,6 +335,7 @@ class SoCCore(Module):
self
.
add_constant
(
"CSR_DATA_WIDTH"
,
csr_data_width
)
self
.
register_mem
(
"csr"
,
self
.
soc_mem_map
[
"csr"
],
self
.
wishbone2csr
.
wishbone
)
# Add UART
if
with_uart
:
if
uart_stub
:
self
.
submodules
.
uart
=
uart
.
UARTStub
()
...
...
@@ -325,6 +346,7 @@ class SoCCore(Module):
self
.
add_csr
(
"uart"
,
allow_user_defined
=
True
)
self
.
add_interrupt
(
"uart"
,
allow_user_defined
=
True
)
# Add Identifier
if
ident
:
if
ident_version
:
ident
=
ident
+
" "
+
version
()
...
...
@@ -333,11 +355,14 @@ class SoCCore(Module):
self
.
config
[
"CLOCK_FREQUENCY"
]
=
int
(
clk_freq
)
self
.
add_constant
(
"SYSTEM_CLOCK_FREQUENCY"
,
int
(
clk_freq
))
# Add Timer
if
with_timer
:
self
.
submodules
.
timer0
=
timer
.
Timer
()
self
.
add_csr
(
"timer0"
,
allow_user_defined
=
True
)
self
.
add_interrupt
(
"timer0"
,
allow_user_defined
=
True
)
# Methods --------------------------------------------------------------------------------------
def
add_cpu
(
self
,
cpu
):
if
self
.
finalized
:
raise
FinalizeError
...
...
@@ -351,26 +376,26 @@ class SoCCore(Module):
self
.
cpu_or_bridge
=
self
.
cpu
def
add_interrupt
(
self
,
interrupt_name
,
interrupt_id
=
None
,
allow_user_defined
=
False
):
#
c
heck that interrupt_name is not already used
#
C
heck that interrupt_name is not already used
if
interrupt_name
in
self
.
soc_interrupt_map
.
keys
():
if
allow_user_defined
:
return
else
:
raise
ValueError
(
"Interrupt conflit, {} name already used"
.
format
(
interrupt_name
))
#
c
heck that interrupt_id is in range
#
C
heck that interrupt_id is in range
if
interrupt_id
is
not
None
and
interrupt_id
>=
32
:
raise
ValueError
(
"{} Interrupt ID out of range ({}, max=31)"
.
format
(
interrupt_name
,
interrupt_id
))
#
i
nterrupt_id not provided: allocate interrupt to the first available id
#
I
nterrupt_id not provided: allocate interrupt to the first available id
if
interrupt_id
is
None
:
for
n
in
range
(
32
):
if
n
not
in
self
.
soc_interrupt_map
.
values
():
self
.
soc_interrupt_map
.
update
({
interrupt_name
:
n
})
return
raise
ValueError
(
"No more space to allocate {} interrupt"
.
format
(
interrupt_name
))
#
i
nterrupt_id provided: check that interrupt_id is not already used and add interrupt
#
I
nterrupt_id provided: check that interrupt_id is not already used and add interrupt
else
:
for
_name
,
_id
in
self
.
soc_interrupt_map
.
items
():
if
interrupt_id
==
_id
:
...
...
@@ -379,14 +404,14 @@ class SoCCore(Module):
self
.
soc_interrupt_map
.
update
({
interrupt_name
:
interrupt_id
})
def
add_csr
(
self
,
csr_name
,
csr_id
=
None
,
allow_user_defined
=
False
):
#
c
heck that csr_name is not already used
#
C
heck that csr_name is not already used
if
csr_name
in
self
.
soc_csr_map
.
keys
():
if
allow_user_defined
:
return
else
:
raise
ValueError
(
"CSR conflit, {} name already used"
.
format
(
csr_name
))
#
c
heck that csr_id is in range
#
C
heck that csr_id is in range
if
csr_id
is
not
None
and
csr_id
>=
2
**
self
.
csr_address_width
:
raise
ValueError
(
"{} CSR ID out of range ({}, max=31)"
.
format
(
csr_name
,
csr_id
))
...
...
@@ -487,38 +512,55 @@ class SoCCore(Module):
except
ValueError
:
return
None
def
build
(
self
,
*
args
,
**
kwargs
):
return
self
.
platform
.
build
(
self
,
*
args
,
**
kwargs
)
# Finalization ---------------------------------------------------------------------------------
def
do_finalize
(
self
):
# Verify CPU has required memories
registered_mems
=
{
regions
[
0
]
for
regions
in
self
.
_memory_regions
}
if
self
.
cpu_type
is
not
None
:
for
mem
in
"rom"
,
"sram"
:
if
mem
not
in
registered_mems
:
raise
FinalizeError
(
"CPU needs a {} to be registered with SoC.register_mem()"
.
format
(
mem
))
#
Wishbone
#
Add the Wishbone Masters/Slaves interconnect
if
len
(
self
.
_wb_masters
):
self
.
submodules
.
wishbonecon
=
wishbone
.
InterconnectShared
(
self
.
_wb_masters
,
self
.
_wb_slaves
,
register
=
True
,
timeout_cycles
=
self
.
wishbone_timeout_cycles
)
if
self
.
with_ctrl
and
(
self
.
wishbone_timeout_cycles
is
not
None
):
self
.
comb
+=
self
.
ctrl
.
bus_error
.
eq
(
self
.
wishbonecon
.
timeout
.
error
)
# C
SR
# C
ollect and create CSRs
self
.
submodules
.
csrbankarray
=
csr_bus
.
CSRBankArray
(
self
,
self
.
get_csr_dev_address
,
data_width
=
self
.
csr_data_width
,
address_width
=
self
.
csr_address_width
)
# Add CSRs interconnect
self
.
submodules
.
csrcon
=
csr_bus
.
InterconnectShared
(
self
.
_csr_masters
,
self
.
csrbankarray
.
get_buses
())
# Check and add CSRs regions
for
name
,
csrs
,
mapaddr
,
rmap
in
self
.
csrbankarray
.
banks
:
self
.
check_csr_range
(
name
,
0x800
*
mapaddr
)
self
.
add_csr_region
(
name
,
(
self
.
soc_mem_map
[
"csr"
]
+
0x800
*
mapaddr
)
|
self
.
shadow_base
,
self
.
csr_data_width
,
csrs
)
self
.
add_csr_region
(
name
,
(
self
.
soc_mem_map
[
"csr"
]
+
0x800
*
mapaddr
)
|
self
.
shadow_base
,
self
.
csr_data_width
,
csrs
)
# Check and add Memory regions
for
name
,
memory
,
mapaddr
,
mmap
in
self
.
csrbankarray
.
srams
:
self
.
check_csr_range
(
name
,
0x800
*
mapaddr
)
self
.
add_csr_region
(
name
+
"_"
+
memory
.
name_override
,
(
self
.
soc_mem_map
[
"csr"
]
+
0x800
*
mapaddr
)
|
self
.
shadow_base
,
self
.
csr_data_width
,
memory
)
self
.
add_csr_region
(
name
+
"_"
+
memory
.
name_override
,
(
self
.
soc_mem_map
[
"csr"
]
+
0x800
*
mapaddr
)
|
self
.
shadow_base
,
self
.
csr_data_width
,
memory
)
# Add CSRs / Config items to constants
for
name
,
constant
in
self
.
csrbankarray
.
constants
:
self
.
_constants
.
append
(((
name
+
"_"
+
constant
.
name
).
upper
(),
constant
.
value
.
value
))
for
name
,
value
in
sorted
(
self
.
config
.
items
(),
key
=
itemgetter
(
0
)):
self
.
_constants
.
append
((
"CONFIG_"
+
name
.
upper
(),
value
))
#
I
nterrupts
#
Connect i
nterrupts
if
hasattr
(
self
,
"cpu"
):
if
hasattr
(
self
.
cpu
,
"interrupt"
):
for
_name
,
_id
in
sorted
(
self
.
soc_interrupt_map
.
items
()):
...
...
@@ -529,9 +571,8 @@ class SoCCore(Module):
assert
hasattr
(
module
,
'ev'
),
"Submodule %s does not have EventManager (xx.ev) module"
%
_name
self
.
comb
+=
self
.
cpu
.
interrupt
[
_id
].
eq
(
module
.
ev
.
irq
)
def
build
(
self
,
*
args
,
**
kwargs
):
return
self
.
platform
.
build
(
self
,
*
args
,
**
kwargs
)
# SoCCores arguments -------------------------------------------------------------------------------
def
soc_core_args
(
parser
):
parser
.
add_argument
(
"--cpu-type"
,
default
=
None
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment