Subversion Repositories OpenARM Single-board Computer

Rev

Rev 141 | Rev 153 | 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 = $_;
142 agaran 69
                #printf STDERR "Blocname %s\n", $blockname;
141 agaran 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);
142 agaran 176
        if (defined $blockname && $i == -200) {
177
                my ($p,$q) = split ('=', $blockname,2);
178
                #printf STDERR "LINE %s %d w=%d\n", $bw{$i}{labels}, $i, $w;
179
                $w += &textlen($q) + 100; # same space enforcement as it was for inside labels
180
                #printf STDERR "LINE %s %d w=%d\n", $bw{$i}{labels}, $i, $w;
181
                # so we have to block name width to $w here..
182
                # but only in last line (device name)
183
        }
121 jelle 184
        #$w = (int($w/100) * 100) + (($w/100) > int($w/100))?100:0;
185
        if ($boxwidth < $w) {
186
                $boxwidth = $w;
187
        }
188
}
189
 
190
#printf STDERR "test: %d\n", $y{labels};
191
 
118 jelle 192
$boxwidth = $w{top} if $boxwidth < $w{top};
193
$boxwidth = $w{bottom} if $boxwidth < $w{bottom};
194
 
195
# Flip Y coordinates (we count from the top, but symbols coordinates
196
# are from the bottom).
197
for $p (keys %pinside) {
133 agaran 198
    next unless $pinside{$p} =~ /left|right/;
118 jelle 199
    $piny{$p} = $maxy - $piny{$p} + 300;
200
}
201
 
133 agaran 202
for $p (keys %pinside) {
203
    next unless $pinside{$p} =~ /label/;
204
    $piny{$p} = $maxy + $piny{$p} - $minpin * 200 + 400;
205
}
206
 
118 jelle 207
$boxwidth = &alignpin($boxwidth);
208
$boxwidth += 200;
209
 
210
# Adjust the position of the top/bottom pins so that, as a group,
211
# they're centered.
212
for $p (keys %pinside) {
213
    next unless $pinside{$p} =~ /top|bottom/;
141 agaran 214
    $pinx{$p} += &alignpin(($boxwidth - $w{$pinside{$p}})/2) + $pinnumwidth;
118 jelle 215
}
216
 
217
# Labels are centered in the box.
121 jelle 218
# labels have to be top, lef
118 jelle 219
for $lp ($minpin..-1) {
121 jelle 220
    #$pinx{$lp} = &alignpin($boxwidth/2) + 300;
141 agaran 221
    $pinx{$lp} = $pinnumwidth;
118 jelle 222
}
223
 
224
# Version.
225
print "v 20060123 1\n";
226
 
227
# Symbol box.
228
printf("B %d %d %d %d 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n",
141 agaran 229
       $pinnumwidth, 300, $boxwidth, $maxy);
118 jelle 230
 
231
# These are the hidden labels.
232
$ax = 300 + $boxwidth;
233
$ay = 400 + $maxy;
234
for $a (reverse @attrs) {
235
    printf("T %d %d 9 10 0 0 0 0 1\n%s\n",
236
           $ax, $ay, $a);
237
    $ay += 200;
238
}
239
 
141 agaran 240
# blockname if present
241
if(defined $blockname) {
242
    printf("T %d %d 5 10 1 1 0 6 1\n%s\n", $boxwidth + $pinnumwidth, $maxy + 400, $blockname);
243
}
244
 
118 jelle 245
# Now print all the pins.
246
for $p (sort {$a<=>$b} keys %pinside) {
247
    next unless $pinside{$p};
248
    if ($pinside{$p} eq "left") {
141 agaran 249
        $pinx{$p} = $pinnumwidth;
118 jelle 250
    }
251
    if ($pinside{$p} eq "right") {
141 agaran 252
        $pinx{$p} = $pinnumwidth + $boxwidth;
118 jelle 253
    }
254
    if ($p > 0 && !$saw_pin{$p}) {
255
        print STDERR "MISSING PIN $p\n";
256
        $errors++;
257
    } else {
258
        printf STDERR ("%3d  %-6s  %4d %4d  %s\n",
259
                       $p, $pinside{$p}, $pinx{$p}, $piny{$p}, $pinlabel{$p});
260
    }
261
 
262
    eval "&drawpin_$pinside{\"$p\"} (\"$p\")";
263
}
264
 
265
# what remains are helper functions; for drawing each type of pin,
266
# each type of label, etc.
267
 
268
sub drawpin_nc {
269
}
270
 
271
sub drawpin_top {
272
    my($pin) = @_;
273
    $y = $maxy + 300;
274
    printf("P %d %d %d %d 1 0 0\n",
275
           $pinx{$pin}, $y+300, $pinx{$pin}, $y);
276
    print "{\n";
277
    &pltext($pinx{$pin}, $y-50, 5, $pinlabel{$pin});
278
    &ntext($pinx{$pin}+50, $y+50, 0, $pin);
279
    print "}\n";
280
}
281
 
282
sub drawpin_bottom {
283
    my($pin) = @_;
284
    printf("P %d %d %d %d 1 0 0\n",
285
           $pinx{$pin}, 0, $pinx{$pin}, 300);
286
    print "{\n";
287
    &pltext($pinx{$pin}, 350, 3, $pinlabel{$pin});
288
    &ntext($pinx{$pin}+50, 250, 2, $pin);
289
    print "}\n";
290
}
291
 
292
sub drawpin_labels {
293
    my($pin) = @_;
131 agaran 294
    &ltext($pinx{$pin}, $piny{$pin}, 0, $pinlabel{$pin});
118 jelle 295
}
296
 
297
sub circle {
298
    my ($x, $y) = @_;
299
    print "V $x $y 50 3 0 0 0 -1 -1 0 -1 -1 -1 -1 -1\n";
300
}
301
 
302
sub drawpin_left {
303
    my($pin) = @_;
304
    $x = $pinx{$pin};
305
    $px = 50;
306
    if ($bubble{$pin}) {
307
        $x -= 100;
308
        &circle($x+50, $piny{$pin});
309
    }
310
    if ($edge{$pin}) {
311
        $px += 100;
312
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
313
               $pinx{$pin}, $piny{$pin}-50,
314
               $pinx{$pin}+100, $piny{$pin});
315
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
316
               $pinx{$pin}+100, $piny{$pin},
317
               $pinx{$pin}, $piny{$pin}+50);
318
 
319
    }
320
    printf("P %d %d %d %d 1 0 0\n",
141 agaran 321
           $pinx{$pin} - $pinnumwidth, $piny{$pin}, $x, $piny{$pin});
118 jelle 322
    print "{\n";
323
    &pltext($pinx{$pin} + $px, $piny{$pin}, 1, $pinlabel{$pin});
324
    &ntext($pinx{$pin} -100, $piny{$pin} + 50, 6, $pin);
325
    print "}\n";
326
}
327
 
328
sub drawpin_right {
329
    my($pin) = @_;
330
    $x = $pinx{$pin};
331
    $px = 50;
332
    if ($bubble{$pin}) {
333
        $x += 100;
334
        &circle($x-50, $piny{$pin});
335
    }
336
    if ($edge{$pin}) {
337
        $px += 100;
338
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
339
               $pinx{$pin}, $piny{$pin}-50,
340
               $pinx{$pin}-100, $piny{$pin});
341
        printf("L %d %d %d %d 3 0 0 0 0 0\n",
342
               $pinx{$pin}-100, $piny{$pin},
343
               $pinx{$pin}, $piny{$pin}+50);
344
 
345
    }
346
    printf("P %d %d %d %d 1 0 0\n",
141 agaran 347
           $pinx{$pin} + $pinnumwidth, $piny{$pin}, $x, $piny{$pin});
118 jelle 348
    print "{\n";
349
    &pltext($pinx{$pin} - $px, $piny{$pin}, 7, $pinlabel{$pin});
350
    &ntext($pinx{$pin} +100, $piny{$pin} + 50, 0, $pin);
351
    print "}\n";
352
}
353
 
354
sub ntext {
355
    my ($x, $y, $a, $s) = @_;
356
    printf("T %d %d 5 8 1 1 0 %s 1\npinnumber=%s\n", $x, $y, $a, $s);
357
    printf("T %d %d 5 8 0 1 0 %s 1\npinseq=%s\n", $x, $y, $a, $s);
358
}
359
 
360
sub pltext {
361
    my ($x, $y, $a, $s) = @_;
362
    $s = "pinlabel=$s" unless $s =~ /=/;
363
    printf("T %d %d 9 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
364
}
365
 
366
sub ltext {
367
    my ($x, $y, $a, $s) = @_;
134 agaran 368
    printf("T %d %d 5 10 1 1 0 %s 1\n%s\n", $x, $y, $a, $s);
118 jelle 369
}
370
 
371
sub textlen {
372
    my($t) = @_;
373
    $t =~ s/^[^=]*=//;
374
    $t =~ s@\\_@@g;
375
    return length($t) * 120;
376
}
377
 
378
sub alignpin {
379
    my($v) = @_;
380
    return int(($v + 99) / 100) * 100;
381
}
382
 
383
exit $errors;