Constraints.pm 9.11 KB
Newer Older
1
2
3
#-----------------------------------------------------------------------
# Fault InJection Instrumenter (FIJI)
# https://embsys.technikum-wien.at/projects/vecs/fiji
4
#
5
6
7
8
# The creation of this file has been supported by the publicly funded
# R&D project Josef Ressel Center for Verification of Embedded Computing
# Systems (VECS) managed by the Christian Doppler Gesellschaft (CDG).
#
9
10
11
# Authors:
# Christian Fibich <fibich@technikum-wien.at>
# Stefan Tauner <tauner@technikum-wien.at>
12
#
13
14
# This module is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
15
#
16
17
18
# 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.
19
#
20
21
# See the LICENSE file for more details.
#-----------------------------------------------------------------------
22

Christian Fibich's avatar
Christian Fibich committed
23
24
25
26
27
28
## @file Constraints.pm
# @brief Contains class \ref FIJI::Constraints

## @class FIJI::Constraints
# @brief Contains functions to generate Constraints for Synthesis/P&R Tools

29
30
31
32
33
package FIJI::Constraints;

use strict;
use warnings;

34
use Log::Log4perl qw(get_logger);
35

36
37
use FIJI qw(:fiji_version);

Christian Fibich's avatar
Christian Fibich committed
38
sub _quartus_partitions_logiclock {
39
    my $logger = get_logger("");
Christian Fibich's avatar
Christian Fibich committed
40
    my $cfg    = shift;
41

42
43
    my $DUT_TO  = $cfg->{'dut_module'} . ":" . $cfg->{'dut_inst'};
    my $FIJI_TO = $cfg->{'fiji_module'} . ":" . $cfg->{'fiji_inst'};
44

45
46
    my $DUT_PART_NAME  = "PARTITION_" . $cfg->{'dut_module'};
    my $FIJI_PART_NAME = "PARTITION_" . $cfg->{'fiji_module'};
Christian Fibich's avatar
Christian Fibich committed
47
48
    my $DUT_COLOR      = (sprintf("%d", 0xFF0000));
    my $FIJI_COLOR     = (sprintf("%d", 0x00FF00));
49
50

    my $time = localtime;
51
52
    my $fiji_version = FIJI_VERSION;
    my $design_id = sprintf("0x%04x", $cfg->{'id'});
53
54
55
56

    my $txt = <<"END_HDR";
# ------------------------------------------------------------------------------
# FIJI Physical Placement Constraints File for Quartus II
57
58
59
60
#
# Generated at $time
# by FIJI $fiji_version
# for Design ID $design_id
61
62
63
64
# ------------------------------------------------------------------------------
END_HDR
    my $fin = "# EOF";

65
    my $partitioning = <<"END_PARTITION";
66
67
68
69
70
71
72
73
74
75
set_global_assignment -name PARTITION_NETLIST_TYPE POST_SYNTH -section_id $DUT_PART_NAME
set_global_assignment -name PARTITION_COLOR $DUT_COLOR -section_id $DUT_PART_NAME
set_global_assignment -name PARTITION_NETLIST_TYPE POST_SYNTH -section_id $FIJI_PART_NAME
set_global_assignment -name PARTITION_COLOR $FIJI_COLOR -section_id $FIJI_PART_NAME
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
set_instance_assignment -name PARTITION_HIERARCHY db/dut1 -to $DUT_TO -section_id $DUT_PART_NAME
set_instance_assignment -name PARTITION_HIERARCHY db/fiji1 -to $FIJI_TO -section_id $FIJI_PART_NAME

END_PARTITION

76
    my $area = <<"END_LOCK";
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
set_global_assignment -name LL_ENABLED ON -section_id $DUT_PART_NAME
set_global_assignment -name LL_AUTO_SIZE ON -section_id $DUT_PART_NAME
set_global_assignment -name LL_STATE FLOATING -section_id $DUT_PART_NAME
set_global_assignment -name LL_WIDTH 1 -section_id $DUT_PART_NAME
set_global_assignment -name LL_HEIGHT 1 -section_id $DUT_PART_NAME
set_global_assignment -name LL_ORIGIN X1_Y1 -section_id $DUT_PART_NAME
set_instance_assignment -name LL_MEMBER_OF $DUT_PART_NAME -to $DUT_TO -section_id $DUT_PART_NAME

set_global_assignment -name LL_ENABLED ON -section_id $FIJI_PART_NAME
set_global_assignment -name LL_AUTO_SIZE ON -section_id $FIJI_PART_NAME
set_global_assignment -name LL_STATE FLOATING -section_id $FIJI_PART_NAME
set_global_assignment -name LL_WIDTH 1 -section_id $FIJI_PART_NAME
set_global_assignment -name LL_HEIGHT 1 -section_id $FIJI_PART_NAME
set_global_assignment -name LL_ORIGIN X1_Y1 -section_id $FIJI_PART_NAME
set_instance_assignment -name LL_MEMBER_OF $FIJI_PART_NAME -to $FIJI_TO -section_id $FIJI_PART_NAME
END_LOCK

94
    if ($cfg->{'mode'} eq "OPT_OFF") {
95
        $txt .= $partitioning;
Christian Fibich's avatar
Christian Fibich committed
96
    } elsif ($cfg->{'mode'} eq "FIX_PLACEMENT") {
97
        $txt .= $partitioning . $area;
Christian Fibich's avatar
Christian Fibich committed
98
    } elsif ($cfg->{'mode'} ne "ALLOW") {
Christian Fibich's avatar
Christian Fibich committed
99
        $logger->error("Unknown SYNTHESIS_MODE " . $cfg->{'mode'});
100
        return undef;
101
    }
Christian Fibich's avatar
Christian Fibich committed
102
    return ($txt . $fin , 'quartus.qsf');
103
104
}

Christian Fibich's avatar
Christian Fibich committed
105
sub _synplify_optimizations {
106
    my $logger = get_logger("");
Christian Fibich's avatar
Christian Fibich committed
107
    my $cfg    = shift;
108
109
110
111
112

    my $DUT_NAME  = $cfg->{'dut_module'};
    my $FIJI_NAME = $cfg->{'fiji_module'};

    my $time = localtime;
113
114
    my $fiji_version = FIJI_VERSION;
    my $design_id = sprintf("0x%04x", $cfg->{'id'});
115
116
117
118

    my $txt = <<"END_HDR";
# ------------------------------------------------------------------------------
# FIJI Constraints File for Synplify
119
120
121
122
#
# Generated at $time
# by FIJI $fiji_version
# for Design ID $design_id
123
124
125
126
# ------------------------------------------------------------------------------
END_HDR
    my $fin = "# EOF";

Christian Fibich's avatar
Christian Fibich committed
127
    my $no_optimization = <<"END_OPTIMIZATION";
128
###==== BEGIN Attributes 
Christian Fibich's avatar
Christian Fibich committed
129
130
131
132
133
134
define_compile_point {v:work.$DUT_NAME} -type {locked}
define_compile_point {v:work.$FIJI_NAME} -type {locked}
define_attribute {v:work.$DUT_NAME}  syn_allow_retiming {0}
define_attribute {v:work.$DUT_NAME}  syn_sharing {0}
define_attribute {v:work.$DUT_NAME}  syn_pipeline {0}
define_attribute {v:work.$DUT_NAME}  syn_netlist_hierarchy {1}
135
###==== END Attributes 
136
END_OPTIMIZATION
137

138
    if ($cfg->{'mode'} eq "OPT_OFF" || $cfg->{'mode'} eq "FIX_PLACEMENT") {
139
        $txt .= $no_optimization;
Christian Fibich's avatar
Christian Fibich committed
140
    } elsif ($cfg->{'mode'} ne "ALLOW") {
Christian Fibich's avatar
Christian Fibich committed
141
        $logger->error("Unknown SYNTHESIS_MODE " . $cfg->{'mode'});
142
        return undef;
143
    }
Christian Fibich's avatar
Christian Fibich committed
144
    return ($txt . $fin, 'synplify.fdc');
145
146
}

Christian Fibich's avatar
Christian Fibich committed
147
sub _vivado_pblocks {
148
    my $logger = get_logger("");
Christian Fibich's avatar
Christian Fibich committed
149
    my $cfg    = shift;
150

Christian Fibich's avatar
Christian Fibich committed
151
152
153
    my $DUT_NAME    = $cfg->{'dut_inst'};
    my $FIJI_NAME   = $cfg->{'fiji_gen'}.'.'.$cfg->{'fiji_inst'};
    my $FIJI_PBLOCK = $cfg->{'fiji_gen'}.'_'.$cfg->{'fiji_inst'};
154

155

Christian Fibich's avatar
Christian Fibich committed
156
    my $time      = localtime;
157
158
    my $fiji_version = FIJI_VERSION;
    my $design_id = sprintf("0x%04x", $cfg->{'id'});
159
160
    my $txt = <<"END_HDR";
# ------------------------------------------------------------------------------
Christian Fibich's avatar
Christian Fibich committed
161
# FIJI Constraints File for Vivado
162
163
164
165
#
# Generated at $time
# by FIJI $fiji_version
# for Design ID $design_id
166
167
168
# ------------------------------------------------------------------------------
END_HDR
    my $fin = "# EOF";
169
170
171
172
173
174
175
176
177
178
179
    my $no_opt = <<"END_NO_OPT";
# Turn off cross-boundary optimizations

# do not even look at the original netlist
set_property dont_touch TRUE [get_cells -quiet [list $DUT_NAME]]

# do not optimize accross FIJI boundaries
set_property keep_hierarchy TRUE [get_cells -quiet [list $FIJI_NAME]]

END_NO_OPT

Christian Fibich's avatar
Christian Fibich committed
180
    my $area = <<"END_AREA";
181
182
183

# Create physical constraints for FIJI and DUI

Christian Fibich's avatar
Christian Fibich committed
184
185
186
187
188
create_pblock pblock_$DUT_NAME
create_pblock pblock_$FIJI_PBLOCK
add_cells_to_pblock [get_pblocks pblock_$DUT_NAME] [get_cells -quiet [list $DUT_NAME]]
add_cells_to_pblock [get_pblocks pblock_$FIJI_PBLOCK] [get_cells -quiet [list $FIJI_NAME]]

189
190
191
192
193
# Set size and location of the PBlocks. This default size will likely fail.
# You will likely need to resize them in the GUI.
resize_pblock [get_pblocks pblock_$DUT_NAME] -add {SLICE_X1Y1:SLICE_X10Y10}
resize_pblock [get_pblocks pblock_$FIJI_PBLOCK] -add {SLICE_X11Y1:SLICE_X15Y3}
END_AREA
Christian Fibich's avatar
Christian Fibich committed
194
    if ($cfg->{'mode'} eq "FIX_PLACEMENT") {
195
        $txt .= $no_opt;
Christian Fibich's avatar
Christian Fibich committed
196
        $txt .=  $area;
197
198
    } elsif ($cfg->{'mode'} eq "OPT_OFF") {
        $txt .= $no_opt;
199
    } elsif ($cfg->{'mode'} ne "ALLOW" && $cfg->{'mode'} ne "OPT_OFF") {
Christian Fibich's avatar
Christian Fibich committed
200
        $logger->error("Unknown SYNTHESIS_MODE " . $cfg->{'mode'});
201
        return undef;
202
    }
Christian Fibich's avatar
Christian Fibich committed
203
    return ($txt . $fin, 'vivado.xdc');
204
205
}

Christian Fibich's avatar
Christian Fibich committed
206
## @var %$toolhash stores which sub to execute for which tool
Christian Fibich's avatar
Christian Fibich committed
207
my $syn_toolhash = {
208
    SYNPLIFY_PRO => {
Christian Fibich's avatar
Christian Fibich committed
209
210
        ALTERA_QUARTUS => \&_synplify_optimizations,
        XILINX_VIVADO  => \&_synplify_optimizations,
211
212
213
    },
};

Christian Fibich's avatar
Christian Fibich committed
214
215
216
217
218
219
my $pr_toolhash = {
    ALTERA_QUARTUS => \&_quartus_partitions_logiclock,
    XILINX_VIVADO  => \&_vivado_pblocks,
};

sub generate_constraints {
220
    my $logger = get_logger("");
Christian Fibich's avatar
Christian Fibich committed
221
    my ($class, $synthesis_tool, $pr_tool, $cfg, $basename) = @_;
222

Christian Fibich's avatar
Christian Fibich committed
223
224
225
226
    my ($file,$txt,$postfix);

    my $synhash = $syn_toolhash->{$synthesis_tool};
    my $prhash  = $pr_toolhash->{$pr_tool};
227

Christian Fibich's avatar
Christian Fibich committed
228
229
    return "No entries for synthesis tool found" if (!defined $synhash);
    return "No entries for P&R tool found" if (!defined $prhash);
230
231

    my $sub = $synhash->{$pr_tool};
232

Christian Fibich's avatar
Christian Fibich committed
233
    return "No subentries for P&R tool in Synthesis toolhash found" if (!defined $sub);
234

Christian Fibich's avatar
Christian Fibich committed
235
    ($txt, $postfix) = &{$sub}($cfg);
236
    return "Could not generate constraints for $synthesis_tool/$pr_tool." if (!defined $txt);
237

Christian Fibich's avatar
Christian Fibich committed
238
239
240
241
242
243
244
245
246
247
248
249
    my $filename = $basename.'.'.$postfix;

    open($file, ">", $filename) or return "Cannot open file $filename: $!";
    print $file $txt;
    close($file) or return "Cannot close file $filename: $!";
    $logger->info("Successfully generated synthesis constraints for $synthesis_tool/$pr_tool.");

    ($txt, $postfix) = &{$prhash}($cfg);
    return "Could not generate P&R constraints for $pr_tool." if (!defined $txt);
    $filename = $basename.'.'.$postfix;

    open($file, ">", $filename) or return "Cannot open file $filename: $!";
250
    print $file $txt;
Christian Fibich's avatar
Christian Fibich committed
251
252
    close($file) or return "Cannot close file $filename: $!";
    $logger->info("Successfully generated P&R constraints for $pr_tool.");
253
254
255
256
257

    return undef;
}

1;