Commit c4d81df5 authored by Jens Korinth's avatar Jens Korinth
Browse files

WIP: started to work on generic address mapping

parent 2fba2589
Pipeline #87 passed with stage
in 3 minutes and 1 second
namespace eval arch {
namespace export create
namespace export get_address_map
# Returns the address map of the current composition.
# Format: <INTF> -> <BASE ADDR> <RANGE> <KIND>
# Kind is either memory, register or master.
# Must be implemented by Platforms.
proc get_address_map {offset} {
if {$offset == ""} { set offset [platform::get_pe_base_address] }
set ret [dict create]
set pes [lsort [get_processing_elements]]
foreach pe $pes {
set usrs [lsort [get_bd_addr_segs $pe/* -filter { USAGE != memory }]]
for {set i 0} {$i < [llength $usrs]} {incr i; incr offset 0x10000} {
set seg [lindex $usrs $i]
set intf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register"
}
set usrs [lsort [get_bd_addr_segs $pe/* -filter { USAGE == memory }]]
for {set i 0} {$i < [llength $usrs]} {incr i; incr offset 0x10000} {
set seg [lindex $usrs $i]
set intf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory"
}
set masters [lsort [tapasco::get_aximm_interfaces $pe]]
foreach intf $masters {
set space [get_bd_addr_spaces -of_objects $intf]
set offset [get_property OFFSET $space]
if {$offset == ""} { set offset 0 }
set range [get_property RANGE $space]
if {$range == ""} { error "no range found on $space for $intf!" }
dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind master"
}
}
return $ret
}
}
......@@ -1017,24 +1017,31 @@ namespace eval tapasco {
set addr [platform::get_address_map [platform::get_pe_base_address]]
set slots [list]
set slot_id 0
foreach a $addr {
if {[dict get $a "kind"] != "memory"} {
set kind [format "%d" [regsub {.*target_ip_([0-9][0-9]).*} [dict get $a "interface"] {\1}]]
set kid [dict get [tapasco::get_composition] $kind id]
lappend slots [json::write object "Type" [json::write string "Kernel"] "SlotId" $slot_id "Kernel" $kid]
} else {
lappend slots [json::write object "Type" [json::write string "Memory"] "SlotId" $slot_id "Bytes" [format "%d" [dict get $a "range"]]]
foreach intf [dict keys $addr] {
switch [dict get $addr $intf "kind"] {
"register" {
set kind [format "%d" [regsub {.*target_ip_([0-9][0-9]).*} $intf {\1}]]
set kid [dict get [tapasco::get_composition] $kind id]
lappend slots [json::write object "Type" [json::write string "Kernel"] "SlotId" $slot_id "Kernel" $kid]
incr slot_id
}
"memory" {
lappend slots [json::write object "Type" [json::write string "Memory"] "SlotId" $slot_id "Bytes" [format "%d" [dict get $addr $intf "range"]]]
incr slot_id
}
"master" {}
default { error "invalid kind: [dict get $addr $intf kind]" }
}
incr slot_id
}
set regex {([0-9][0-9][0-9][0-9]).([0-9][0-9]*)}
set no_pes [llength [arch::get_processing_elements]]
set no_intc [expr "$no_pes > 96 ? 4 : ($no_pes > 64 ? 3 : ($no_pes > 32 ? 2 : 1))"]
set ts [clock seconds]
return [json::write object \
"Composition" [json::write array {*}$slots] \
"Timestamp" [clock seconds] \
"Timestamp" [expr "$ts - ($ts \% 86400)"] \
"Interrupt Controllers" $no_intc \
"Versions" [json::write array \
[json::write object "Software" [json::write string "Vivado"] "Year" [regsub $regex [version -short] {\1}] "Release" [regsub $regex [version -short] {\2}]] \
......@@ -1043,7 +1050,7 @@ namespace eval tapasco {
"Clocks" [json::write array \
[json::write object "Domain" [json::write string "Host"] "Frequency" [tapasco::get_host_frequency]] \
[json::write object "Domain" [json::write string "Design"] "Frequency" [tapasco::get_design_frequency]] \
[json::write object "Domain" [json::write string "Memory"] "Frequency" [tapasco::get_memory_frequency]] \
[json::write object "Domain" [json::write string "Memory"] "Frequency" [tapasco::get_mem_frequency]] \
] \
"Capabilities" [json::write object "Capabilities 0" [get_capabilities_flags]] \
]
......
......@@ -37,6 +37,7 @@ tapasco::call_plugins "pre-header"
@@HEADER@@
# source architecture-specific Tcl scripts
source -notrace "$env(TAPASCO_HOME)/arch/common/arch.tcl"
source -notrace @@ARCHITECTURE_TCL@@
# source platform-specific Tcl scripts
......
......@@ -67,11 +67,6 @@ namespace eval platform {
construct_address_map
}
proc construct_address_map {{map ""}} {
if {$map == ""} { set map [get_address_map [get_pe_base_address]] }
puts "ADDRESS MAP: $map"
}
proc connect_subsystems {} {
foreach s {host design mem} {
connect_bd_net [get_bd_pins -of_objects [get_bd_cells] -filter "NAME == ${s}_clk && DIR == O"] \
......@@ -85,10 +80,6 @@ namespace eval platform {
}
}
proc get_pe_base_address {} {
error "Platform does not implement mandatory proc get_pe_base_address!"
}
proc create_subsystem_tapasco {} {
set port [create_bd_intf_pin -vlnv [tapasco::get_vlnv "aximm_intf"] -mode Slave "S_TAPASCO"]
set tapasco_status [tapasco::createTapascoStatus "tapasco_status"]
......@@ -98,12 +89,12 @@ namespace eval platform {
}
proc wire_subsystem_wires {} {
foreach p [get_bd_pins -of_objects [get_bd_cells] -filter {INTF == false && DIR == I}] {
if {[llength [get_bd_nets -of_objects $p]] == 0} {
foreach p [get_bd_pins -quiet -of_objects [get_bd_cells] -filter {INTF == false && DIR == I}] {
if {[llength [get_bd_nets -quiet -of_objects $p]] == 0} {
set name [get_property NAME $p]
set type [get_property TYPE $p]
puts "Looking for matching source for $p ($name) with type $type ..."
set src [get_bd_pins -of_objects [get_bd_cells] -filter "NAME == $name && TYPE == $type && INTF == false && DIR == O"]
set src [lsort [get_bd_pins -quiet -of_objects [get_bd_cells] -filter "NAME == $name && TYPE == $type && INTF == false && DIR == O"]]
if {[llength $src] > 0} {
puts " found pin: $src, connecting $p -> $src"
connect_bd_net $src $p
......@@ -115,14 +106,14 @@ namespace eval platform {
}
proc wire_subsystem_intfs {} {
foreach p [get_bd_intf_pins -of_objects [get_bd_cells] -filter {MODE == Slave}] {
if {[llength [get_bd_intf_nets -of_objects $p]] == 0} {
foreach p [get_bd_intf_pins -quiet -of_objects [get_bd_cells] -filter {MODE == Slave}] {
if {[llength [get_bd_intf_nets -quiet -of_objects $p]] == 0} {
set name [regsub {^S_} [get_property NAME $p] {M_}]
set vlnv [get_property VLNV $p]
puts "Looking for matching source for $p ($name) with VLNV $vlnv ..."
set srcs [lsort [get_bd_intf_pins -of_objects [get_bd_cells] -filter "NAME == $name && VLNV == $vlnv && MODE == Master"]]
set srcs [lsort [get_bd_intf_pins -quiet -of_objects [get_bd_cells] -filter "NAME == $name && VLNV == $vlnv && MODE == Master"]]
foreach src $srcs {
if {[llength [get_bd_intf_nets -of_objects $src]] == 0} {
if {[llength [get_bd_intf_nets -quiet -of_objects $src]] == 0} {
puts " found pin: $src, connecting $p -> $src"
connect_bd_intf_net $src $p
break
......@@ -134,33 +125,6 @@ namespace eval platform {
}
}
# Returns the address map of the current composition.
# Format: <SLAVE INTF> <BASE ADDR> <RANGE> <KIND>
# Kind is either Mem or Register, depending on the usage.
# Must be implemented by Platforms.
proc get_address_map {offset} {
set ret [list]
set pes [lsort [arch::get_processing_elements]]
#set offset 0x00300000
foreach pe $pes {
set usrs [lsort [get_bd_addr_segs $pe/* -filter { USAGE != memory }]]
for {set i 0} {$i < [llength $usrs]} {incr i; incr offset 0x10000} {
set seg [lindex $usrs $i]
set intf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
lappend ret "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register"
}
set usrs [lsort [get_bd_addr_segs $pe/* -filter { USAGE == memory }]]
for {set i 0} {$i < [llength $usrs]} {incr i; incr offset 0x10000} {
set seg [lindex $usrs $i]
set intf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
lappend ret "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory"
}
}
return $ret
}
# Checks all current runs at given step for errors, outputs their log files in case.
# @param synthesis Checks synthesis runs if true, implementation runs otherwise.
proc check_run_errors {{synthesis true}} {
......@@ -230,4 +194,115 @@ namespace eval platform {
error "timing failure, WNS: $wns"
}
}
# Returns the base address of the PEs in the device address space.
proc get_pe_base_address {} {
error "Platform does not implement mandatory proc get_pe_base_address!"
}
proc get_address_map {{pe_base ""}} {
if {$pe_base == ""} { set pe_base [get_pe_base_address] }
set peam [::arch::get_address_map $pe_base]
foreach m [tapasco::get_aximm_interfaces [get_bd_cells -filter {PATH !~ /uArch/*}]] {
set as [get_bd_addr_segs -addressables -of_objects $m]
puts "master: $m, segs: $as"
switch -glob [get_property NAME $m] {
"M_DMA" {
set base 0x00300000
foreach seg [lsort [get_bd_addr_segs -addressables -of_objects $m]] {
puts [format " $seg -> 0x%08x" $base]
set sintf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
set kind [get_property USAGE $seg]
dict set peam $sintf "interface $sintf offset $base range $range kind $kind"
incr base 0x00010000
}
}
"M_INTC" {
set base 0x00400000
foreach seg [lsort [get_bd_addr_segs -addressables -of_objects $m]] {
puts [format " $seg -> 0x%08x" $base]
set sintf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
set kind [get_property USAGE $seg]
dict set peam $sintf "interface $sintf offset $base range $range kind $kind"
incr base 0x00010000
}
}
"M_MSIX" {
set base 0x00500000
foreach seg [lsort [get_bd_addr_segs -addressables -of_objects $m]] {
puts [format " $seg -> 0x%08x" $base]
set sintf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
set kind [get_property USAGE $seg]
dict set peam $sintf "interface $sintf offset $base range $range kind $kind"
incr base 0x00010000
}
}
"M_TAPASCO" {
set base 0x02800000
foreach seg [lsort [get_bd_addr_segs -addressables -of_objects $m]] {
puts [format " $seg -> 0x%08x" $base]
set sintf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
set kind [get_property USAGE $seg]
dict set peam $sintf "interface $sintf offset $base range $range kind $kind"
incr base $range
}
}
"M_ARCH" {}
default {
puts "unknown master: $m"
set base 0
foreach seg [lsort [get_bd_addr_segs -addressables -of_objects $m]] {
puts [format " $seg -> 0x%08x" $base]
set sintf [get_bd_intf_pins -of_objects $seg]
set range [get_property RANGE $seg]
set kind [get_property USAGE $seg]
dict set peam $sintf "interface $sintf offset $base range $range kind $kind"
incr base $range
}
}
}
}
return $peam
}
proc construct_address_map {{map ""}} {
if {$map == ""} { set map [get_address_map [get_pe_base_address]] }
puts "ADDRESS MAP: $map"
set seg_i 0
foreach space [get_bd_addr_spaces] {
puts "space: $space"
set intfs [get_bd_intf_pins -quiet -of_objects $space]
foreach intf $intfs {
set segs [get_bd_addr_segs -addressables -of_objects $intf]
foreach seg $segs {
puts "seg: $seg"
set sintf [get_bd_intf_pins -quiet -of_objects $seg]
if {[catch {dict get $map $intf}]} {
if {[catch {dict get $map $sintf}]} {
error "neither $intf nor $sintf were found in address map for $seg: $::errorInfo"
}
set me [dict get $map $sintf]
} else {
set me [dict get $map $intf]
}
puts " address map info: $me]"
set range [dict get $me "range"]
set offset [dict get $me "offset"]
puts " offset: $offset"
puts " range: $range"
create_bd_addr_seg \
-range $range \
-offset $offset \
$space \
$seg \
[format "AM_SEG_%03d" $seg_i]
incr seg_i
}
}
}
}
}
......@@ -228,6 +228,7 @@ namespace eval platform {
# create hierarchical ports
set s_axi [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_HOST"]
set s_msix [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_MSIX"]
set m_arch [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_ARCH"]
set m_intc [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_INTC"]
set m_tapasco [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_TAPASCO"]
......@@ -252,7 +253,7 @@ namespace eval platform {
set mm_to_lite_dwidth [tapasco::createDWidthConverter "mm_to_lite_dwidth" 256]
# connect PCIe slave to external port
connect_bd_intf_net $s_axi [get_bd_intf_pins axi_pcie3_0/S_AXI]
#connect_bd_intf_net $s_axi [get_bd_intf_pins axi_pcie3_0/S_AXI]
# connect PCIe master to external port
connect_bd_intf_net [get_bd_intf_pins axi_pcie3_0/M_AXI] [get_bd_intf_pins mm_to_lite_slice_before/S_AXI]
# connect mm_to_lite datawidth converter to protocol converter
......@@ -266,6 +267,12 @@ namespace eval platform {
connect_bd_intf_net [get_bd_intf_pins mm_to_lite_slice_after/M_AXI] \
[get_bd_intf_pins -of_objects $out_ic -filter "VLNV == [tapasco::get_vlnv aximm_intf] && MODE == Slave"]
set in_ic [tapasco::createInterconnect "in_ic" 2 1]
connect_bd_intf_net [get_bd_intf_pins S_HOST] [get_bd_intf_pins $in_ic/S00_AXI]
connect_bd_intf_net [get_bd_intf_pins S_MSIX] [get_bd_intf_pins $in_ic/S01_AXI]
connect_bd_intf_net [get_bd_intf_pins -of_object $in_ic -filter { MODE == Master }] \
[get_bd_intf_pins $pcie/S_AXI]
connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M00_AXI}] $m_arch
connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M01_AXI}] $m_intc
connect_bd_intf_net [get_bd_intf_pins -of_objects $out_ic -filter {NAME == M02_AXI}] $m_tapasco
......@@ -275,19 +282,26 @@ namespace eval platform {
[get_bd_pins $out_ic/ACLK] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ S0* && TYPE == clk}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M01_* && TYPE == clk}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == clk}]
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == clk}] \
[get_bd_pins -of_objects $in_ic -filter {NAME =~ *00* && TYPE == clk}] \
[get_bd_pins -of_objects $in_ic -filter {NAME == ACLK && TYPE == clk}]
connect_bd_net [tapasco::subsystem::get_port "design" "clk"] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M00_* && TYPE == clk}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M02_* && TYPE == clk}]
connect_bd_net [tapasco::subsystem::get_port "mem" "clk"] \
[get_bd_pins -of_objects $in_ic -filter {NAME =~ S01_* && TYPE == clk}]
connect_bd_net [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"] \
[get_bd_pins $out_ic/ARESETN] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ S0* && TYPE == rst}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M01_* && TYPE == rst}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == rst}]
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M03_* && TYPE == rst}] \
[get_bd_pins -of_objects $in_ic -filter {NAME =~ *00* && TYPE == rst}]
connect_bd_net [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M00_* && TYPE == rst}] \
[get_bd_pins -of_objects $out_ic -filter {NAME =~ M02_* && TYPE == rst}]
connect_bd_net [tapasco::subsystem::get_port "mem" "rst" "peripheral" "resetn"] \
[get_bd_pins -of_objects $in_ic -filter {NAME =~ S01_* && TYPE == rst}]
set version [lindex [split [get_property VLNV [get_bd_cells axi_pcie3_0]] :] end]
if {[expr "$version < 3.0"]} {
......@@ -456,7 +470,7 @@ namespace eval platform {
}
proc get_pe_base_address {} {
return 0x00300000
return 0x02000000
}
proc platform_address_map_set {{tapasco_base 0x0}} {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment