From 07379d4fea765d462ffdc015d8c856347473fb63 Mon Sep 17 00:00:00 2001 From: David Volz Date: Wed, 23 Mar 2022 16:44:37 +0100 Subject: [PATCH 1/6] multiple interrupts per PE --- toolflow/vivado/arch/axi4mm/axi4mm.tcl | 1 + 1 file changed, 1 insertion(+) diff --git a/toolflow/vivado/arch/axi4mm/axi4mm.tcl b/toolflow/vivado/arch/axi4mm/axi4mm.tcl index b20a5bae..8cbbdfe4 100644 --- a/toolflow/vivado/arch/axi4mm/axi4mm.tcl +++ b/toolflow/vivado/arch/axi4mm/axi4mm.tcl @@ -360,6 +360,7 @@ namespace eval arch { set intr_name "PE_${i}_${pe_sub_interrupt}" puts "Creating interrupt $intr_name" connect_bd_net $pin [::tapasco::ip::add_interrupt $intr_name "design"] + incr pe_sub_interrupt } incr i } From bf136442ef9160c2f0b1e0662700a83dbb547c3e Mon Sep 17 00:00:00 2001 From: David Volz Date: Wed, 23 Mar 2022 16:45:56 +0100 Subject: [PATCH 2/6] addrmap & statuscore for PEs with many intf and ipec --- toolflow/vivado/arch/common/arch.tcl | 85 ++++++++++++++++++---------- toolflow/vivado/common/ip.tcl | 10 ++++ 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/toolflow/vivado/arch/common/arch.tcl b/toolflow/vivado/arch/common/arch.tcl index 82385281..485b510f 100644 --- a/toolflow/vivado/arch/common/arch.tcl +++ b/toolflow/vivado/arch/common/arch.tcl @@ -35,40 +35,65 @@ namespace eval arch { set pes [lsort [get_processing_elements]] foreach pe $pes { - puts " processing $pe registers ..." - set usrs [lsort [get_bd_addr_segs -filter { USAGE == register } $pe/*]] - for {set i 0} {$i < [llength $usrs]} {incr i} { - set seg [lindex $usrs $i] - puts " seg: $seg" - if {[get_property MODE [get_bd_intf_pins -of_objects $seg]] == "Master"} { - puts " skipping master seg $seg" - } else { - set intf [get_bd_intf_pins -of_objects $seg] - set range [get_property RANGE $seg] - set offset [next_valid_address $offset $range] - ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range - dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register" - incr offset $range + set reg_segs [lsort [get_bd_addr_segs -filter { USAGE == register } $pe/*]] + set mem_segs [lsort [get_bd_addr_segs -filter { USAGE == memory } $pe/*]] + if {[llength $reg_segs] <= 1 && [llength $mem_segs] <= 1} { + puts " processing $pe registers ..." + for {set i 0} {$i < [llength $reg_segs]} {incr i} { + set seg [lindex $reg_segs $i] + puts " seg: $seg" + if {[get_property MODE [get_bd_intf_pins -of_objects $seg]] == "Master"} { + puts " skipping master seg $seg" + } else { + set intf [get_bd_intf_pins -of_objects $seg] + set range [get_property RANGE $seg] + set offset [next_valid_address $offset $range] + ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register" + incr offset $range + } } - } - puts " processing $pe memories ..." - set usrs [lsort [get_bd_addr_segs -filter { USAGE == memory } $pe/*]] - for {set i 0} {$i < [llength $usrs]} {incr i} { - set seg [lindex $usrs $i] - puts " seg: $seg" - if {[get_property MODE [get_bd_intf_pins -of_objects $seg]] == "Master"} { - puts " skipping master seg $seg" - continue - } else { - set intf [get_bd_intf_pins -of_objects $seg] - set range [get_property RANGE $seg] - set offset [next_valid_address $offset $range] - ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range - dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory" - incr offset $range + puts " processing $pe memories ..." + for {set i 0} {$i < [llength $mem_segs]} {incr i} { + set seg [lindex $mem_segs $i] + puts " seg: $seg" + if {[get_property MODE [get_bd_intf_pins -of_objects $seg]] == "Master"} { + puts " skipping master seg $seg" + } else { + set intf [get_bd_intf_pins -of_objects $seg] + set range [get_property RANGE $seg] + set offset [next_valid_address $offset $range] + ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory" + incr offset $range + } + } + } else { + # if there is more than one reg/mem interface, we assume that the user knows what they are doing and add them in the same order + puts " processing $pe registers and memories ..." + set all_segs [lsort [get_bd_addr_segs $pe/*]] + for {set i 0} {$i < [llength $all_segs]} {incr i} { + set seg [lindex $all_segs $i] + puts " seg: $seg" + if {[get_property MODE [get_bd_intf_pins -of_objects $seg]] == "Master"} { + puts " skipping master seg $seg" + } else { + set intf [get_bd_intf_pins -of_objects $seg] + set range [get_property RANGE $seg] + set usage [get_property USAGE $seg] + set offset [next_valid_address $offset $range] + ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range + if { $usage == "register" } { + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register subintf $i" + } else { + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory subintf $i" + } + incr offset $range + } } } } return $ret } + } diff --git a/toolflow/vivado/common/ip.tcl b/toolflow/vivado/common/ip.tcl index 5a8858c1..c8d3d950 100644 --- a/toolflow/vivado/common/ip.tcl +++ b/toolflow/vivado/common/ip.tcl @@ -540,6 +540,16 @@ namespace eval ::tapasco::ip { set kid [dict get [::tapasco::get_composition] $kind id] set vlnv [dict get [::tapasco::get_composition] $kind vlnv] + if {[tapasco::is_feature_enabled "IPEC"]} { + set feature [tapasco::get_feature "IPEC"] + if {[dict exists $feature $vlnv]} { + set subintf [dict get $addr $intf "subintf"] + set kid [lindex [dict get $feature $vlnv "kid"] $subintf] + set kid [expr int($kid)] + set vlnv [lindex [dict get $feature $vlnv "vlnv"] $subintf] + } + } + lappend slots [json::write object "Type" [json::write string "Kernel"] "SlotId" $slot_id "Kernel" $kid \ "Offset" [json::write string [format "0x%016x" [expr "[dict get $addr $intf "offset"] - [::platform::get_pe_base_address]"]]] \ "Size" [json::write string [format "0x%016x" [dict get $addr $intf "range"]]] \ From 710519b542330f62f645f532fbde871ad0407a81 Mon Sep 17 00:00:00 2001 From: David Volz Date: Thu, 24 Mar 2022 09:32:23 +0100 Subject: [PATCH 3/6] simplified replacing (vlnv kid) --- toolflow/vivado/arch/common/arch.tcl | 4 ++-- toolflow/vivado/common/ip.tcl | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/toolflow/vivado/arch/common/arch.tcl b/toolflow/vivado/arch/common/arch.tcl index 485b510f..f4da07e1 100644 --- a/toolflow/vivado/arch/common/arch.tcl +++ b/toolflow/vivado/arch/common/arch.tcl @@ -84,9 +84,9 @@ namespace eval arch { set offset [next_valid_address $offset $range] ::platform::addressmap::add_processing_element [llength [dict keys $ret]] $offset $range if { $usage == "register" } { - dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register subintf $i" + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind register" } else { - dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory subintf $i" + dict set ret $intf "interface $intf [format "offset 0x%08x range 0x%08x" $offset $range] kind memory" } incr offset $range } diff --git a/toolflow/vivado/common/ip.tcl b/toolflow/vivado/common/ip.tcl index c8d3d950..6dcda786 100644 --- a/toolflow/vivado/common/ip.tcl +++ b/toolflow/vivado/common/ip.tcl @@ -540,14 +540,13 @@ namespace eval ::tapasco::ip { set kid [dict get [::tapasco::get_composition] $kind id] set vlnv [dict get [::tapasco::get_composition] $kind vlnv] - if {[tapasco::is_feature_enabled "IPEC"]} { - set feature [tapasco::get_feature "IPEC"] - if {[dict exists $feature $vlnv]} { - set subintf [dict get $addr $intf "subintf"] - set kid [lindex [dict get $feature $vlnv "kid"] $subintf] - set kid [expr int($kid)] - set vlnv [lindex [dict get $feature $vlnv "vlnv"] $subintf] - } + set ipecfeature [tapasco::get_feature "IPEC"] + set intfname [lindex [split $intf /] end] + if {[dict exists $ipecfeature $vlnv $intfname]} { + set kid [dict get $ipecfeature $vlnv $intfname "kid"] + set kid [expr int($kid)] + set vlnv [dict get $ipecfeature $vlnv $intfname "vlnv"] + puts " replaced vlnv $vlnv kid $kid" } lappend slots [json::write object "Type" [json::write string "Kernel"] "SlotId" $slot_id "Kernel" $kid \ From 79714d096d741958b3d9cc599338265a1766266c Mon Sep 17 00:00:00 2001 From: David Volz Date: Thu, 24 Mar 2022 11:27:57 +0100 Subject: [PATCH 4/6] fix indentation --- toolflow/vivado/common/ip.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolflow/vivado/common/ip.tcl b/toolflow/vivado/common/ip.tcl index 6dcda786..2fde19dc 100644 --- a/toolflow/vivado/common/ip.tcl +++ b/toolflow/vivado/common/ip.tcl @@ -541,7 +541,7 @@ namespace eval ::tapasco::ip { set vlnv [dict get [::tapasco::get_composition] $kind vlnv] set ipecfeature [tapasco::get_feature "IPEC"] - set intfname [lindex [split $intf /] end] + set intfname [lindex [split $intf /] end] if {[dict exists $ipecfeature $vlnv $intfname]} { set kid [dict get $ipecfeature $vlnv $intfname "kid"] set kid [expr int($kid)] From 7e8f313789e7a18eede39414006a4fee8ac16f19 Mon Sep 17 00:00:00 2001 From: David Volz Date: Thu, 24 Mar 2022 15:31:42 +0100 Subject: [PATCH 5/6] moved status core interface renaming into plugin --- toolflow/vivado/common/ip.tcl | 13 +++---- .../common/plugins/status_core_interface.tcl | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 toolflow/vivado/platform/common/plugins/status_core_interface.tcl diff --git a/toolflow/vivado/common/ip.tcl b/toolflow/vivado/common/ip.tcl index 2fde19dc..dccc842b 100644 --- a/toolflow/vivado/common/ip.tcl +++ b/toolflow/vivado/common/ip.tcl @@ -540,14 +540,11 @@ namespace eval ::tapasco::ip { set kid [dict get [::tapasco::get_composition] $kind id] set vlnv [dict get [::tapasco::get_composition] $kind vlnv] - set ipecfeature [tapasco::get_feature "IPEC"] - set intfname [lindex [split $intf /] end] - if {[dict exists $ipecfeature $vlnv $intfname]} { - set kid [dict get $ipecfeature $vlnv $intfname "kid"] - set kid [expr int($kid)] - set vlnv [dict get $ipecfeature $vlnv $intfname "vlnv"] - puts " replaced vlnv $vlnv kid $kid" - } + set intfinfo [tapasco::call_plugins "status-core-interface" $vlnv $intf] + if { $intfinfo != {} } { + set kid [lindex $intfinfo 0] + set vlnv [lindex $intfinfo 1] + } lappend slots [json::write object "Type" [json::write string "Kernel"] "SlotId" $slot_id "Kernel" $kid \ "Offset" [json::write string [format "0x%016x" [expr "[dict get $addr $intf "offset"] - [::platform::get_pe_base_address]"]]] \ diff --git a/toolflow/vivado/platform/common/plugins/status_core_interface.tcl b/toolflow/vivado/platform/common/plugins/status_core_interface.tcl new file mode 100644 index 00000000..a60df6fe --- /dev/null +++ b/toolflow/vivado/platform/common/plugins/status_core_interface.tcl @@ -0,0 +1,37 @@ +# Copyright (c) 2014-2020 Embedded Systems and Applications, TU Darmstadt. +# +# This file is part of TaPaSCo +# (see https://github.com/esa-tu-darmstadt/tapasco). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# + +namespace eval status_core_interface { + + proc get_interface_info { vlnv intf } { + set intf_rename [tapasco::get_feature "IPEC"] + set intfname [lindex [split $intf /] end] + if {[dict exists $intf_rename $vlnv $intfname]} { + set kid [dict get $intf_rename $vlnv $intfname "kid"] + set kid [expr int($kid)] + set vlnv [dict get $intf_rename $vlnv $intfname "vlnv"] + puts " replaced vlnv $vlnv kid $kid" + return [list $kid $vlnv] + } + return {} + } + +} + +tapasco::register_plugin "platform::status_core_interface::get_interface_info" "status-core-interface" From e8e3c677efb5e5c33101ca560a3eecf13870e4b5 Mon Sep 17 00:00:00 2001 From: David Volz Date: Tue, 29 Mar 2022 14:00:33 +0200 Subject: [PATCH 6/6] clarifying comment --- toolflow/vivado/arch/common/arch.tcl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/toolflow/vivado/arch/common/arch.tcl b/toolflow/vivado/arch/common/arch.tcl index f4da07e1..af1ab687 100644 --- a/toolflow/vivado/arch/common/arch.tcl +++ b/toolflow/vivado/arch/common/arch.tcl @@ -69,7 +69,10 @@ namespace eval arch { } } } else { - # if there is more than one reg/mem interface, we assume that the user knows what they are doing and add them in the same order + # If there is more than one reg/mem interface, we add them in the same order as declared in the IP-XACT core. + # The current runtime uses the order to detect control-register-interface & memory-interface pairs. + # When a PE has multiple such interfaces, ordering them regs first, mems second leads to the runtime recognizing only one reg-memory pair. + # When using the same ordering as the IP-XACT core, the user can define which memory-interface belongs to a certain control-register-interface by ordering them accordingly. puts " processing $pe registers and memories ..." set all_segs [lsort [get_bd_addr_segs $pe/*]] for {set i 0} {$i < [llength $all_segs]} {incr i} {