Subversion Repositories OpenARM Single-board Computer

Rev

Rev 135 | Rev 142 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
118 jelle 1
#!/usr/bin/perl
2
# -*- perl -*-
3
 
4
# Copyright (C) 2006 DJ Delorie dj@delorie.com
5
# Released under the terms of the GNU General Public License, version 2
6
 
7
# Usage: djboxsym sample.symdef > sample.sym
8
 
133 agaran 9
$y{left} = 300;
10
$y{right} = 300;
131 agaran 11
$y{labels} = -200;
118 jelle 12
$labelpin = 0;
13
 
14
# Read in the file, storing information about each pin.
15
 
141 agaran 16
my $pinnumwidth = 0;
17
my $blockname;
18
 
118 jelle 19
while (<>) {
20
    next if /^#/;
21
    s/^\s+//;
22
    s/\s+$//;
23
    s/[\s\t]+/ /g;
24
    s/[\r\n]+$//;
25
 
26
    # Note change of section.
27
    if (/^\[(.*)\]/) {
28
        $side = $1;
29
        $space = 0;
30
        next;
31
    }
32
 
33
    # Start a bus
34
    if (/^\.bus/) {
35
        $busmode = 1;
36
        next;
37
    }
38
 
39
    # blank lines - cancel bus, add gap.
40
    if (! /\S/) {
41
        if ($busmode) {
42
            $y{$side} += 200;
43
        }
44
        $busmode = 0;
45
        if ($space) {
46
            if ($side =~ /left|right/) {
131 agaran 47
                $y{$side} += 300;
118 jelle 48
            }
49
            if ($side =~ /top|bottom/) {
50
                $x{$side} += 400;
51
            }
52
            $space = 0;
53
        }
54
        next;
55
    }
56
 
57
    # Hidden labels are stored separately, because we don't care how
58
    # big they are.
59
    if (/! (\S.*)/ && $side eq "labels") {
60
        push(@attrs, $1);
61
        next;
62
    }
63
 
64
    # Visible labels are stored as pins because their size affects the
65
    # size of the symbols' box.
66
    if (/\S/ && $side eq "labels") {
141 agaran 67
        if ($_ =~ /^block=/) {
68
                $blockname = $_;
69
                printf STDERR "Blocname %s\n", $blockname;
70
                next;
71
        }
118 jelle 72
        $labelpin --;
73
        $pinside{$labelpin} = $side;
74
        $piny{$labelpin} = $y{labels};
75
        $pinlabel{$labelpin} = $_;
131 agaran 76
        $y{labels} -= 200;
118 jelle 77
        $rlen{$labelpin} = &textlen($_);
78
        next;
79
    }
80
 
81
    # Regular pins are handled here.
82
    if (/^([0-9A-Za-z]+)\s*(.*)/) {
83
        $space = 1;
84
        ($pin, $rest) = ($1,$2);
85
 
86
        if ($saw_pin{$pin}) {
87
            print STDERR "DUPLICATE PIN $pin (was $pinlabel{$pin}, now $rest)\n";
88
            $errors ++;
89
        }
90
        $saw_pin{$pin} = 1;
91
        $maxpin = $pin if $maxpin < $pin;
92
 
93
        $pinside{$pin} = $side;
94
        next if $side eq "nc";
95
        if ($rest =~ /^([!>]+) (.*)/) {
96
            $flags = $1;
97
            $pinlabel{$pin} = $2;
98
            $bubble{$pin} = 1 if $flags =~ /!/;
99
            $edge{$pin} = 1 if $flags =~ />/;
100
        } else {
101
            $pinlabel{$pin} = $rest;
102
        }
103
        $rlen{$pin} = &textlen($pinlabel{$pin});
104
 
141 agaran 105
        if ($pinnumwidth < &textlen($pin)) {
106
                $pinnumwidth = &textlen($pin);
107
        }
108
 
118 jelle 109
        if ($side =~ /left|right/) {
110
            $y = $piny{$pin} = $y{$side};
132 agaran 111
            $y{$side} += ($busmode ? 200 : 300);
118 jelle 112
        }
113
        if ($side =~ /top|bottom/) {
114
            $tw = &alignpin((200 + $rlen{$pin}) / 2);
115
            $pinx{$pin} = $w{$side} + $tw;
116
            $w{$side} += $tw + $tw;
117
        }
118
 
119
    }
120
 
121
}
122
 
141 agaran 123
$pinnumwidth += 100 - ($pinnumwidth % 100);
124
 
118 jelle 125
$minpin = $labelpin;
126
$boxwidth = 0;
127
%bw = ();
128
 
129
# for each horizontal slice of the symbol, keep track of how much
130
# width is used up by the left, middle, and right labels.
131
for $lp (keys %pinside) {
132
    next unless $pinside{$lp} =~ /left|right|label/;
133
    $yb = &alignpin($piny{$lp});
134
    for ($y=$yb-100; $y<=$yb+100; $y+=100) {
135
        if ($bw{$y}{$pinside{$lp}} < $rlen{$lp}) {
136
            $bw{$y}{$pinside{$lp}} = $rlen{$lp};
137
        }
138
    }
139
}
140
 
141
# Compute the height of the box. 
142
for $p (keys %pinside) {
143
    next unless $pinside{$p} =~ /left|right/;
144
    if ($maxy < $piny{$p}) {
145
        $maxy = $piny{$p};
146
    }
147
}
133 agaran 148
$maxy += 300;
118 jelle 149
 
150
# Now, use the slice widths to compute the minimum width of the box.
151
for ($i=0; $i<$maxy; $i+=100) {
152
    $w = $bw{$i}{left} + $bw{$i}{labels} + $bw{$i}{right};
153
    if ($bw{$i}{labels}) {
154
        $wl = ($bw{$i}{left} + $bw{$i}{labels}/2) * 2;
155
        $w = $wl if $w < $wl;
156
        $wl = ($bw{$i}{right} + $bw{$i}{labels}/2) * 2;
157
        $w = $wl if $w < $wl;
158
    }
159
    if ($bw{$i}{left} && $bw{$i}{labels}) {
160
        $w += 100;
161
    } elsif ($bw{$i}{left} && $bw{$i}{right}) {
162
        $w += 200;
163
    }
164
    if ($bw{$i}{right} && $bw{$i}{labels}) {
165
        $w += 100;
166
    }
167
    if ($boxwidth < $w) {
168
        $boxwidth = $w;
169
    }
170
}
171
 
121 jelle 172
 
173
for ($i = $y{labels}; $i <= 0; $i+=100) {
174
        my $w = $bw{$i}{labels};
175
        $w += 100 - ($w%100);
176
        #$w = (int($w/100) * 100) + (($w/100) > int($w/100))?100:0;
177
        if ($boxwidth < $w) {
178
                $boxwidth = $w;
179
        }
180
}
181
 
182
#printf STDERR "test: %d\n", $y{labels};
183
 
118 jelle 184
$boxwidth = $w{top} if $boxwidth < $w{top};
185
$boxwidth = $w{bottom} if $boxwidth < $w{bottom};
186
 
187
# Flip Y coordinates (we count from the top, but symbols coordinates
188
# are from the bottom).
189
for $p (keys %pinside) {
133 agaran 190
    next unless $pinside{$p} =~ /left|right/;
118 jelle 191
    $piny{$p} = $maxy - $piny{$p} + 300;
192
}
193
 
133 agaran 194
for $p (keys %pinside) {
195
    next unless $pinside{$p} =~ /label/;
196
    $piny{$p} = $maxy + $piny{$p} - $minpin * 200 + 400;
197
}
198
 
118 jelle 199
$boxwidth = &alignpin($boxwidth);
200
$boxwidth += 200;
201
 
202
# Adjust the position of the top/bottom pins so that, as a group,
203
# they're centered.
204
for $p (keys %pinside) {
205
    next unless $pinside{$p} =~ /top|bottom/;
141 agaran 206
    $pinx{$p} += &alignpin(($boxwidth - $w{$pinside{$p}})/2) + $pinnumwidth;
118 jelle 207
}
208
 
209
# Labels are centered in the box.
121 jelle 210
# labels have to be top, lef
118 jelle 211
for $lp ($minpin..-1) {
121 jelle 212
    #$pinx{$lp} = &alignpin($boxwidth/2) + 300;
141 agaran 213
    $pinx{$lp} = $pinnumwidth;
118 jelle 214
}
215
 
216
# Version.
217
print "v 20060123 1\n";
218
 
219
# Symbol box.
220
printf("B %d %d %d %d 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n",
141 agaran 221
       $pinnumwidth, 300, $boxwidth, $maxy);
118 jelle 222
 
223
# These are the hidden labels.
224
$ax = 300 + $boxwidth;
225
$ay = 400 + $maxy;
226
for $a (reverse @attrs) {
227
    printf("T %d %d 9 10 0 0 0 0 1\n%s\n",
228
           $ax, $ay, $a);
229
    $ay += 200;
230
}
231
 
141 agaran 232
# blockname if present
233
if(defined $blockname) {
234
    printf("T %d %d 5 10 1 1 0 6 1\n%s\n", $boxwidth + $pinnumwidth, $maxy + 400, $blockname);
235
    printf STDERR "BLOCKNAME %s\n", $blockname;
236
}
237
 
118 jelle 238
# Now print all the pins.
239
for $p (sort {$a<=>$b} keys %pinside) {
240
    next unless $pinside{$p};
241
    if ($pinside{$p} eq "left") {
141 agaran 242
        $pinx{$p} = $pinnumwidth;
118 jelle 243
    }
244
    if ($pinside{$p} eq "right") {
141 agaran 245
        $pinx{$p} = $pinnumwidth + $boxwidth;
118 jelle 246
    }
247
    if ($p > 0 && !$saw_pin{$p}) {
248
        print STDERR "MISSING PIN $p\n";
249
        $errors++;
250
    } else {
251
        printf STDERR ("%3d  %-6s  %4d %4d  %s\n",
252
                       $p, $pinside{$p}, $pinx{$p}, $piny{$p}, $pinlabel{$p});
253
    }
254
 
255
    eval "&drawpin_$pinside{\"$p\"} (\"$p\")";
256
}
257
 
258
# what remains are helper functions; for drawing each type of pin,
259
# each type of label, etc.
260
 
261
sub drawpin_nc {
262
}
263
 
264
sub drawpin_top {
265
    my($pin) = @_;
266
    $y = $maxy + 300;
267
    printf("P %d %d %d %d 1 0 0\n",
268
           $pinx{$pin}, $y+300, $pinx{$pin}, $y);
269
    print "{\n";
270
    &pltext($pinx{$pin}, $y-50, 5, $pinlabel{$pin});
271
    &ntext($pinx{$pin}+50, $y+50, 0, $pin);
272
    print "}\n";
273
}
274
 
275
sub drawpin_bottom {
276
    my($pin) = @_;
277
    printf("P %d %d %d %d 1 0 0\n",
278
           $pinx{$pin}, 0, $pinx{$pin}, 300);
279
    print "{\n";
280
    &pltext($pinx{$pin}, 350, 3, $pinlabel{$pin});
281
    &ntext($pinx{$pin}+50, 250, 2, $pin);
282
    print "}\n";
283
}
284
 
285
sub drawpin_labels {
286
    my($pin) = @_;
131 agaran 287
    &ltext($pinx{$pin}, $piny{$pin}, 0, $pinlabel{$pin});
118 jelle 288
}
289
 
290
sub circle {
291
    my ($x, $y) = @_;
292
    print "V $x $y 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
293
}
294
 
295
sub drawpin_left {
296
    my($pin) = @_;
297
    $x = $pinx{$pin};
298
    $px = 50;
299
    if ($bubble{$pin}) {
300
        $x -= 100;
301
        &circle($x+50, $piny{$pin});
302
    }
303
    if ($edge{$pin}) {
304
        $px += 100;
305
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
306
               $pinx{$pin}, $piny{$pin}-50,
307
               $pinx{$pin}+100, $piny{$pin});
308
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
309
               $pinx{$pin}+100, $piny{$pin},
310
               $pinx{$pin}, $piny{$pin}+50);
311
 
312
    }
313
    printf("P %d %d %d %d 1 0 0\n",
141 agaran 314
           $pinx{$pin} - $pinnumwidth, $piny{$pin}, $x, $piny{$pin});
118 jelle 315
    print "{\n";
316
    &pltext($pinx{$pin} + $px, $piny{$pin}, 1, $pinlabel{$pin});
317
    &ntext($pinx{$pin} -100, $piny{$pin} + 50, 6, $pin);
318
    print "}\n";
319
}
320
 
321
sub drawpin_right {
322
    my($pin) = @_;
323
    $x = $pinx{$pin};
324
    $px = 50;
325
    if ($bubble{$pin}) {
326
        $x += 100;
327
        &circle($x-50, $piny{$pin});
328
    }
329
    if ($edge{$pin}) {
330
        $px += 100;
331
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
332
               $pinx{$pin}, $piny{$pin}-50,
333
               $pinx{$pin}-100, $piny{$pin});
334
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
335
               $pinx{$pin}-100, $piny{$pin},
336
               $pinx{$pin}, $piny{$pin}+50);
337
 
338
    }
339
    printf("P %d %d %d %d 1 0 0\n",
141 agaran 340
           $pinx{$pin} + $pinnumwidth, $piny{$pin}, $x, $piny{$pin});
118 jelle 341
    print "{\n";
342
    &pltext($pinx{$pin} - $px, $piny{$pin}, 7, $pinlabel{$pin});
343
    &ntext($pinx{$pin} +100, $piny{$pin} + 50, 0, $pin);
344
    print "}\n";
345
}
346
 
347
sub ntext {
348
    my ($x, $y, $a, $s) = @_;
349
    printf("T %d %d 5 8 1 1 0 %s 1\npinnumber=%s\n", $x, $y, $a, $s);
350
    printf("T %d %d 5 8 0 1 0 %s 1\npinseq=%s\n", $x, $y, $a, $s);
351
}
352
 
353
sub pltext {
354
    my ($x, $y, $a, $s) = @_;
355
    $s = "pinlabel=$s" unless $s =~ /=/;
356
    printf("T %d %d 9 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
357
}
358
 
359
sub ltext {
360
    my ($x, $y, $a, $s) = @_;
134 agaran 361
    printf("T %d %d 5 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
118 jelle 362
}
363
 
364
sub textlen {
365
    my($t) = @_;
366
    $t =~ s/^[^=]*=//;
367
    $t =~ s@\\_@@g;
368
    return length($t) * 120;
369
}
370
 
371
sub alignpin {
372
    my($v) = @_;
373
    return int(($v + 99) / 100) * 100;
374
}
375
 
376
exit $errors;