aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/tools/scripts/viv_strategies.tcl
blob: da7c4598a061f6b04e988c543c5074b83dfb724c (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#
# Copyright 2015 Ettus Research
#

# ---------------------------------------------------
# Create namespace and initialize global parameters
# ---------------------------------------------------
namespace eval ::vivado_strategies {
    # Export commands
    namespace export \
        get_preset \
        implement_design \
        check_strategy \
        print_strategy

    variable g_viv_version [version -short]
}

# ---------------------------------------------------
# Return a preset strategy with the most commonly used options
# ---------------------------------------------------
proc ::vivado_strategies::get_impl_preset {preset} {
    variable g_viv_version

    set strategy [dict create]
    switch -nocase $preset {
        "Default" {
            dict set strategy "opt_design.is_enabled"                   1
            dict set strategy "opt_design.directive"                    "Default"
            dict set strategy "post_opt_power_opt_design.is_enabled"    0
            dict set strategy "place_design.directive"                  "Default"
            dict set strategy "post_place_power_opt_design.is_enabled"  0
            dict set strategy "post_place_phys_opt_design.is_enabled"   0
            dict set strategy "post_place_phys_opt_design.directive"    "Default"
            dict set strategy "route_design.directive"                  "Default"
            dict set strategy "route_design.more_options"               ""
            dict set strategy "post_route_phys_opt_design.is_enabled"   0
            dict set strategy "post_route_phys_opt_design.directive"    "Default"
        }
        "Performance_Explore" {
            dict set strategy "opt_design.is_enabled"                   1
            dict set strategy "opt_design.directive"                    "Explore"
            dict set strategy "post_opt_power_opt_design.is_enabled"    0
            dict set strategy "place_design.directive"                  "Explore"
            dict set strategy "post_place_power_opt_design.is_enabled"  0
            dict set strategy "post_place_phys_opt_design.is_enabled"   1
            dict set strategy "post_place_phys_opt_design.directive"    "Explore"
            dict set strategy "route_design.directive"                  "Explore"
            dict set strategy "route_design.more_options"               ""
            dict set strategy "post_route_phys_opt_design.is_enabled"   0
            dict set strategy "post_route_phys_opt_design.directive"    "Explore"
        }
        "Performance_ExplorePostRoutePhysOpt" {
            dict set strategy "opt_design.is_enabled"                   1
            dict set strategy "opt_design.directive"                    "Explore"
            dict set strategy "post_opt_power_opt_design.is_enabled"    0
            dict set strategy "place_design.directive"                  "Explore"
            dict set strategy "post_place_power_opt_design.is_enabled"  0
            dict set strategy "post_place_phys_opt_design.is_enabled"   1
            dict set strategy "post_place_phys_opt_design.directive"    "Explore"
            dict set strategy "route_design.directive"                  "Explore"
            dict set strategy "route_design.more_options"               "-tns_cleanup"
            dict set strategy "post_route_phys_opt_design.is_enabled"   1
            dict set strategy "post_route_phys_opt_design.directive"    "Explore"
        }
    }
    return $strategy
}

# ---------------------------------------------------
# Execute the specified implementation strategy
# ---------------------------------------------------
proc ::vivado_strategies::implement_design {strategy} {
    variable g_viv_version

    # Check strategy for validity and print
    vivado_strategies::check_strategy $strategy
    puts "BUILDER: Running implementation strategy with:"
    vivado_strategies::print_strategy $strategy

    # Optimize the current netlist.
    # This will perform the retarget, propconst, sweep and bram_power_opt optimizations by default.
    if [dict get $strategy "opt_design.is_enabled"] {
        set opt_dir [dict get $strategy "opt_design.directive"]
        opt_design -directive $opt_dir
    }

    # Optimize dynamic power using intelligent clock gating after optimization
    if [dict get $strategy "post_opt_power_opt_design.is_enabled"] {
        power_opt_design
    }

    # Automatically place ports and leaf-level instances
    set pla_dir [dict get $strategy "place_design.directive"]
    place_design -directive $pla_dir

    # Optimize dynamic power using intelligent clock gating after placement
    if [dict get $strategy "post_place_power_opt_design.is_enabled"] {
        power_opt_design
    }

    # Optimize the current placed netlist
    if [dict get $strategy "post_place_phys_opt_design.is_enabled"] {
        set pp_physopt_dir [dict get $strategy "post_place_phys_opt_design.directive"]
        phys_opt_design -directive $pp_physopt_dir
    }

    # Option to run commands before route
    if {[dict exist $strategy "route_design.pre_hook"]} {
      set pre_route_cmds [dict get $strategy "route_design.pre_hook"]
      eval $pre_route_cmds
    }

    # Route the current design
    set rt_dir [dict get $strategy "route_design.directive"]
    puts "BUILDER: Choosing routing directive: $rt_dir"
    if {[dict get $strategy "route_design.more_options"] eq ""} {
        route_design -directive $rt_dir
    } else {
        set rt_more [dict get $strategy "route_design.more_options"]
        puts "BUILDER: Choosing additional routing options: $rt_more"
        route_design -directive $rt_dir $rt_more
    }

    # Optimize the current routed netlist.
    if [dict get $strategy "post_route_phys_opt_design.is_enabled"] {
        set pr_physopt_dir [dict get $strategy "post_route_phys_opt_design.directive"]
        phys_opt_design -directive $pr_physopt_dir
    }
}

# ---------------------------------------------------
# Sanity-check the specified strategy
# ---------------------------------------------------
proc ::vivado_strategies::check_strategy {strategy} {
    variable g_viv_version

    set strategy_options [dict keys $strategy]
    set required_options {\
        opt_design.is_enabled \
        opt_design.directive \
        post_opt_power_opt_design.is_enabled \
        place_design.directive \
        post_place_power_opt_design.is_enabled \
        post_place_phys_opt_design.is_enabled \
        post_place_phys_opt_design.directive \
        route_design.directive \
        post_route_phys_opt_design.is_enabled \
        post_route_phys_opt_design.directive \
    }

    set invalid 0
    foreach req $required_options {
        if [expr [lsearch $strategy_options $req] < 0] {
            puts "BUILDER: ERROR: Invalid strategy. Missing option $req"
            set invalid 1
        }
    }
    if $invalid {
        error "Strategy check failed!"
    }
}

# ---------------------------------------------------
# Print strategy parameters to the console
# ---------------------------------------------------
proc ::vivado_strategies::print_strategy {strategy} {
    variable g_viv_version

    foreach opt [dict keys $strategy] {
        set val [dict get $strategy $opt]
        puts "         * $opt = $val"
    }
}