HDLRuby 3.9.1 → 3.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.html +4121 -4648
- data/README.md +16 -1
- data/ext/hruby_sim/hruby_rcsim_build.c +26 -0
- data/ext/hruby_sim/hruby_sim.h +6 -0
- data/ext/hruby_sim/hruby_sim_calc.c +68 -1
- data/lib/HDLRuby/hdr_samples/constant_prop_bench.rb +2 -2
- data/lib/HDLRuby/hdr_samples/with_henumerable.rb +281 -258
- data/lib/HDLRuby/hdr_samples/with_to_svg.rb +37 -0
- data/lib/HDLRuby/hdr_samples/with_unary_reduction.rb +23 -0
- data/lib/HDLRuby/hdr_samples/with_values.rb +4 -0
- data/lib/HDLRuby/hdrcc.rb +3 -0
- data/lib/HDLRuby/hruby_bstr.rb +2 -1
- data/lib/HDLRuby/hruby_high.rb +36 -8
- data/lib/HDLRuby/hruby_low.rb +52 -87
- data/lib/HDLRuby/hruby_low_split_signals.rb +213 -0
- data/lib/HDLRuby/hruby_rcsim.rb +6 -1
- data/lib/HDLRuby/hruby_types.rb +6 -2
- data/lib/HDLRuby/hruby_viz.rb +1099 -792
- data/lib/HDLRuby/std/hruby_enum.rb +104 -28
- data/lib/HDLRuby/std/sequencer.rb +23 -10
- data/lib/HDLRuby/verilog_hruby.rb +70 -28
- data/lib/HDLRuby/verilog_parser.rb +38 -18
- data/lib/HDLRuby/version.rb +1 -1
- metadata +5 -2
data/lib/HDLRuby/hruby_viz.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# An IC netlist
|
|
1
|
+
# An IC netlist model and SVG-based vizualizer for HDLRuby
|
|
2
2
|
|
|
3
3
|
# require 'stackprof'
|
|
4
4
|
|
|
@@ -12,6 +12,21 @@ module HDLRuby::Viz
|
|
|
12
12
|
DOWN = 8
|
|
13
13
|
BLOCKED = 16
|
|
14
14
|
|
|
15
|
+
# Get the base name of the port.
|
|
16
|
+
def self.port_base_name(name)
|
|
17
|
+
return name.sub(/\[.*\]\z/,"")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Get the bit part of the port name if any.
|
|
21
|
+
def self.port_bit_name(name)
|
|
22
|
+
return name.match(/\[.*\]\z/)[0]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Tell if a port name is for a sub port.
|
|
26
|
+
def self.port_bit_name?(name)
|
|
27
|
+
return name =~ /\[.*\]\z/
|
|
28
|
+
end
|
|
29
|
+
|
|
15
30
|
|
|
16
31
|
# An IC Port
|
|
17
32
|
class Port
|
|
@@ -71,6 +86,7 @@ module HDLRuby::Viz
|
|
|
71
86
|
@cwidths = [] # The widths of each column in number of routes
|
|
72
87
|
# @border = 2 # The IC border size for routing to external ports.
|
|
73
88
|
@border = 4 # The IC border size for routing to external ports.
|
|
89
|
+
# @cell_border = 4 # The cell border size
|
|
74
90
|
@cell_border = 4 # The cell border size
|
|
75
91
|
@routes = [] # The connection routes.
|
|
76
92
|
@port_width = 3 # The width in tiles for a port
|
|
@@ -110,6 +126,9 @@ module HDLRuby::Viz
|
|
|
110
126
|
|
|
111
127
|
# Give the size of the IC in number of statements.
|
|
112
128
|
def number_statements
|
|
129
|
+
if self.type == :instance then
|
|
130
|
+
return self.system.number_statements
|
|
131
|
+
end
|
|
113
132
|
# Get the number from the branches.
|
|
114
133
|
snum = @branches.reduce(0) do |sum,branch|
|
|
115
134
|
sum + branch.number_statements
|
|
@@ -118,6 +137,7 @@ module HDLRuby::Viz
|
|
|
118
137
|
snum += @children.reduce(0) do |sum,child|
|
|
119
138
|
sum + child.number_statements
|
|
120
139
|
end
|
|
140
|
+
return snum
|
|
121
141
|
end
|
|
122
142
|
|
|
123
143
|
|
|
@@ -153,8 +173,8 @@ module HDLRuby::Viz
|
|
|
153
173
|
|
|
154
174
|
# Compute the distance between to IC.
|
|
155
175
|
def distance(ic0,ic1)
|
|
156
|
-
res = Math.sqrt((ic0.xpos-ic1.xpos)**2+(ic0.ypos-ic1.ypos)**2)
|
|
157
|
-
|
|
176
|
+
# res = Math.sqrt((ic0.xpos-ic1.xpos)**2+(ic0.ypos-ic1.ypos)**2)
|
|
177
|
+
res = (ic0.xpos-ic1.xpos).abs+(ic0.ypos-ic1.ypos).abs
|
|
158
178
|
return res
|
|
159
179
|
end
|
|
160
180
|
|
|
@@ -269,43 +289,54 @@ module HDLRuby::Viz
|
|
|
269
289
|
@uports.clear
|
|
270
290
|
@rports.clear
|
|
271
291
|
@dports.clear
|
|
292
|
+
# Ports sides by direction and base name.
|
|
293
|
+
@port_base_dir = {}
|
|
294
|
+
# Process the ports.
|
|
272
295
|
@ports.each do |port|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
port.side = LEFT
|
|
279
|
-
else
|
|
280
|
-
port.side = UP
|
|
281
|
-
end
|
|
282
|
-
else
|
|
283
|
-
if rports.size <= dports.size then
|
|
284
|
-
port.side = RIGHT
|
|
285
|
-
else
|
|
286
|
-
port.side = DOWN
|
|
287
|
-
end
|
|
288
|
-
end
|
|
296
|
+
# Maybe there is a port with the same direction.
|
|
297
|
+
side = @port_base_dir[[HDLRuby::Viz.port_base_name(port.name),
|
|
298
|
+
port.direction]]
|
|
299
|
+
if side then
|
|
300
|
+
port.side = side
|
|
289
301
|
else
|
|
290
|
-
#
|
|
291
|
-
if port.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
302
|
+
# No, process to port.
|
|
303
|
+
if port.targets.empty? then
|
|
304
|
+
puts "Dangling port: #{port.name} (of #{port.ic.name})"
|
|
305
|
+
# Not connected port, put it on the side with the less ports.
|
|
306
|
+
if port.direction == :input then
|
|
307
|
+
if lports.size <= uports.size then
|
|
308
|
+
port.side = LEFT
|
|
309
|
+
else
|
|
310
|
+
port.side = UP
|
|
311
|
+
end
|
|
298
312
|
else
|
|
299
|
-
|
|
313
|
+
if rports.size <= dports.size then
|
|
314
|
+
port.side = RIGHT
|
|
315
|
+
else
|
|
316
|
+
port.side = DOWN
|
|
317
|
+
end
|
|
300
318
|
end
|
|
301
319
|
else
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
320
|
+
# The port is connected.
|
|
321
|
+
if port.direction == :input then
|
|
322
|
+
# For now, use the first target only for deciding.
|
|
323
|
+
d_left = port.targets[0].ic.xpos - @box[0]
|
|
324
|
+
d_up = @box[3] -
|
|
325
|
+
port.targets[0].ic.ypos + port.targets[0].ic.height
|
|
326
|
+
if d_left <= d_up then
|
|
327
|
+
port.side = LEFT
|
|
328
|
+
else
|
|
329
|
+
port.side = UP
|
|
330
|
+
end
|
|
307
331
|
else
|
|
308
|
-
|
|
332
|
+
d_right = @box[2] -
|
|
333
|
+
port.targets[0].ic.xpos + port.targets[0].ic.width
|
|
334
|
+
d_down = port.targets[0].ic.ypos - @box[1]
|
|
335
|
+
if d_right <= d_down then
|
|
336
|
+
port.side = RIGHT
|
|
337
|
+
else
|
|
338
|
+
port.side = DOWN
|
|
339
|
+
end
|
|
309
340
|
end
|
|
310
341
|
end
|
|
311
342
|
end
|
|
@@ -321,13 +352,17 @@ module HDLRuby::Viz
|
|
|
321
352
|
when DOWN
|
|
322
353
|
@dports << port
|
|
323
354
|
end
|
|
355
|
+
# Also for the handling of bits.
|
|
356
|
+
@port_base_dir[[HDLRuby::Viz.port_base_name(port.name),
|
|
357
|
+
port.direction]] = port.side
|
|
324
358
|
end
|
|
325
359
|
end
|
|
326
360
|
|
|
327
361
|
|
|
328
362
|
# Select the side of the ports of the children according to the
|
|
329
363
|
# position of their targets.
|
|
330
|
-
def side_children
|
|
364
|
+
# def side_children
|
|
365
|
+
def side_children(ic_matrix_coordinates)
|
|
331
366
|
@children.each do |child|
|
|
332
367
|
puts "side_children for child=#{child.name} with #{child.ports.size} ports"
|
|
333
368
|
# Resets the port sides.
|
|
@@ -339,8 +374,9 @@ module HDLRuby::Viz
|
|
|
339
374
|
# (Information used for certain types of IC).
|
|
340
375
|
left_for, up_for, right_for, down_for = nil, nil, nil, nil
|
|
341
376
|
# Recompute the ports sides.
|
|
342
|
-
cx = child.xpos
|
|
343
|
-
cy = child.ypos
|
|
377
|
+
# cx = child.xpos
|
|
378
|
+
# cy = child.ypos
|
|
379
|
+
cx,cy = ic_matrix_coordinates[child]
|
|
344
380
|
child.ports.each do |port|
|
|
345
381
|
puts "For port: #{port.name} (of #{port.ic.name})"
|
|
346
382
|
unless left_for || up_for || right_for || down_for then
|
|
@@ -365,58 +401,89 @@ module HDLRuby::Viz
|
|
|
365
401
|
# Current IC, do not use its position, but the side.
|
|
366
402
|
case port.targets[0].side
|
|
367
403
|
when LEFT
|
|
368
|
-
tx = cx + 1.0
|
|
404
|
+
# tx = cx + 1.0
|
|
405
|
+
tx = cx + 1
|
|
369
406
|
ty = cy
|
|
370
407
|
when UP
|
|
371
408
|
tx = cx
|
|
372
|
-
ty = -cy - 1.0
|
|
409
|
+
# ty = -cy - 1.0
|
|
410
|
+
ty = -cy - 1
|
|
373
411
|
when RIGHT
|
|
374
|
-
tx = -cx - 1.0
|
|
412
|
+
# tx = -cx - 1.0
|
|
413
|
+
tx = -cx - 1
|
|
375
414
|
ty = cy
|
|
376
415
|
when DOWN
|
|
377
416
|
tx = cx
|
|
378
|
-
ty = cy + 1.0
|
|
417
|
+
# ty = cy + 1.0
|
|
418
|
+
ty = cy + 1
|
|
379
419
|
end
|
|
380
420
|
else
|
|
381
|
-
tx = port.targets[0].ic.xpos
|
|
382
|
-
ty = port.targets[0].ic.ypos
|
|
421
|
+
# tx = port.targets[0].ic.xpos
|
|
422
|
+
# ty = port.targets[0].ic.ypos
|
|
423
|
+
tx,ty = ic_matrix_coordinates[port.targets[0].ic]
|
|
383
424
|
end
|
|
384
425
|
dx = cx-tx
|
|
385
426
|
dy = cy-ty
|
|
386
|
-
|
|
427
|
+
puts "cx=#{cx} cy=#{cy} tx=#{tx} ty=#{ty} dx=#{dx} dy=#{dy}"
|
|
428
|
+
if dx == 0 then
|
|
429
|
+
if dy > 0 then
|
|
430
|
+
port.side = this_port ? UP : DOWN
|
|
431
|
+
else
|
|
432
|
+
port.side = this_port ? DOWN : UP
|
|
433
|
+
end
|
|
434
|
+
elsif dy == 0 then
|
|
435
|
+
if dx > 0 then
|
|
436
|
+
port.side = this_port ? RIGHT : LEFT
|
|
437
|
+
else
|
|
438
|
+
port.side = this_port ? LEFT : RIGHT
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# if dx > 0 then
|
|
442
|
+
elsif dx > 0 then
|
|
443
|
+
# if dy > 0 then
|
|
444
|
+
# if dx > dy then
|
|
445
|
+
# port.side = this_port ? RIGHT : LEFT
|
|
446
|
+
# else
|
|
447
|
+
# port.side = this_port ? UP : DOWN
|
|
448
|
+
# end
|
|
449
|
+
# else
|
|
450
|
+
# if dx > -dy then
|
|
451
|
+
# port.side = this_port ? RIGHT : LEFT
|
|
452
|
+
# else
|
|
453
|
+
# port.side = this_port ? DOWN : UP
|
|
454
|
+
# end
|
|
455
|
+
# end
|
|
387
456
|
if dy > 0 then
|
|
388
|
-
|
|
389
|
-
port.side = this_port ? RIGHT : LEFT
|
|
390
|
-
else
|
|
391
|
-
port.side = this_port ? UP : DOWN
|
|
392
|
-
end
|
|
457
|
+
port.side = this_port ? RIGHT : LEFT
|
|
393
458
|
else
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
else
|
|
397
|
-
port.side = this_port ? DOWN : UP
|
|
398
|
-
end
|
|
459
|
+
# port.side = this_port ? UP : DOWN
|
|
460
|
+
port.side = this_port ? DOWN : UP
|
|
399
461
|
end
|
|
400
462
|
else
|
|
463
|
+
# if dy > 0 then
|
|
464
|
+
# if -dx > dy then
|
|
465
|
+
# port.side = this_port ? LEFT : RIGHT
|
|
466
|
+
# else
|
|
467
|
+
# port.side = this_port ? UP : DOWN
|
|
468
|
+
# end
|
|
469
|
+
# else
|
|
470
|
+
# if -dx > -dy then
|
|
471
|
+
# port.side = this_port ? LEFT : RIGHT
|
|
472
|
+
# else
|
|
473
|
+
# port.side = this_port ? DOWN : UP
|
|
474
|
+
# end
|
|
475
|
+
# end
|
|
401
476
|
if dy > 0 then
|
|
402
|
-
|
|
403
|
-
port.side = this_port ? LEFT : RIGHT
|
|
404
|
-
else
|
|
405
|
-
port.side = this_port ? UP : DOWN
|
|
406
|
-
end
|
|
477
|
+
port.side = this_port ? LEFT : RIGHT
|
|
407
478
|
else
|
|
408
|
-
|
|
409
|
-
port.side = this_port ? LEFT : RIGHT
|
|
410
|
-
else
|
|
411
|
-
port.side = this_port ? DOWN : UP
|
|
412
|
-
end
|
|
479
|
+
port.side = this_port ? DOWN : UP
|
|
413
480
|
end
|
|
414
481
|
end
|
|
415
482
|
end
|
|
416
483
|
end
|
|
417
484
|
# Case of IC of type assign or register if a side is used for
|
|
418
485
|
# output, the opposite must be used for input, and vice versa.
|
|
419
|
-
if child.type == :assign or child.type == :register then
|
|
486
|
+
if child.type == :assign then # or child.type == :register then
|
|
420
487
|
# puts "left_for=#{left_for} up_for=#{up_for} right_for=#{right_for} down_for=#{down_for}"
|
|
421
488
|
if left_for then
|
|
422
489
|
if port.direction == left_for then
|
|
@@ -675,6 +742,7 @@ module HDLRuby::Viz
|
|
|
675
742
|
nd = child.dports.size * @port_width
|
|
676
743
|
child.height = nl > nr ? nl : nr
|
|
677
744
|
child.width = nu > nd ? nu : nd
|
|
745
|
+
puts "For assign" if child.type == :assign
|
|
678
746
|
puts "First width=#{child.width} height=#{child.height} [#{child.lports.size},#{child.uports.size},#{child.rports.size},#{child.dports.size}]"
|
|
679
747
|
# Ensure IC have some thickness.
|
|
680
748
|
if child.type != :register then
|
|
@@ -684,15 +752,17 @@ module HDLRuby::Viz
|
|
|
684
752
|
child.width = @port_width if child.width < @port_width
|
|
685
753
|
# But enlarge if more than one port horizontally or
|
|
686
754
|
# vertically for easier routing and readability.
|
|
687
|
-
if child.
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
755
|
+
if child.type != :assign then # However assign are treated appart
|
|
756
|
+
if child.lports.size + child.rports.size > 1 and
|
|
757
|
+
child.height == @port_width and
|
|
758
|
+
child.width == @port_width then
|
|
759
|
+
child.width *= 2
|
|
760
|
+
end
|
|
761
|
+
if child.uports.size + child.dports.size > 1 and
|
|
762
|
+
child.width == @port_width and
|
|
763
|
+
child.height == @port_width then
|
|
764
|
+
child.height *= 2
|
|
765
|
+
end
|
|
696
766
|
end
|
|
697
767
|
# Also ensure the chip is wide enough.
|
|
698
768
|
if child.type == :assign then
|
|
@@ -728,8 +798,9 @@ module HDLRuby::Viz
|
|
|
728
798
|
child.height = 3 if child.height < @port_width
|
|
729
799
|
child.width = 3 if child.width < @port_width
|
|
730
800
|
end
|
|
731
|
-
puts "for register: #{child.name} ports.size=#{child.ports.size}, width=#{child.width} height=#{child.height}"
|
|
801
|
+
# puts "for register: #{child.name} ports.size=#{child.ports.size}, width=#{child.width} height=#{child.height}"
|
|
732
802
|
end
|
|
803
|
+
puts "Then width=#{child.width} height=#{child.height} [#{child.lports.size},#{child.uports.size},#{child.rports.size},#{child.dports.size}]"
|
|
733
804
|
|
|
734
805
|
end
|
|
735
806
|
end
|
|
@@ -759,6 +830,7 @@ module HDLRuby::Viz
|
|
|
759
830
|
puts "With number of statements: #{num} are base area=#{area}"
|
|
760
831
|
# First compute the target area, and width and height of each type.
|
|
761
832
|
ics.each do |ic|
|
|
833
|
+
puts "For ic=#{ic.name}"
|
|
762
834
|
# Update the target area.
|
|
763
835
|
n_area = ic.width * ic.height
|
|
764
836
|
area = n_area if n_area > area
|
|
@@ -782,11 +854,13 @@ module HDLRuby::Viz
|
|
|
782
854
|
pH = ic.height if ic.height > pH
|
|
783
855
|
# Ensure the target area is reached.
|
|
784
856
|
if ic.branches[0].type == :par then
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
pW
|
|
788
|
-
|
|
789
|
-
|
|
857
|
+
while pW*pW < area do
|
|
858
|
+
# For par processes, increase squarely.
|
|
859
|
+
if pW <= pH then
|
|
860
|
+
pW += 1
|
|
861
|
+
else
|
|
862
|
+
pH += 1
|
|
863
|
+
end
|
|
790
864
|
end
|
|
791
865
|
else
|
|
792
866
|
# For non par processes, increase vertically.
|
|
@@ -804,7 +878,7 @@ module HDLRuby::Viz
|
|
|
804
878
|
if ic.type == :instance then
|
|
805
879
|
ic.width = iW
|
|
806
880
|
ic.height = iH
|
|
807
|
-
|
|
881
|
+
elsif [:process, :clocked_process, :timed_process]. include?(ic.type) then
|
|
808
882
|
puts "For process #{ic.name} setting size from #{ic.width},#{ic.height} to #{pW},#{pH}"
|
|
809
883
|
ic.width = pW
|
|
810
884
|
ic.height = pH
|
|
@@ -829,6 +903,10 @@ module HDLRuby::Viz
|
|
|
829
903
|
cw = @cwidths[j]
|
|
830
904
|
@cwidths[j] = child.width if child.width > cw
|
|
831
905
|
@rheights[i] = child.height if child.height > rh
|
|
906
|
+
# fix_size = child.width > child.height ? child.width : child.height
|
|
907
|
+
# @cwidths[j] = fix_size if fix_size > cw
|
|
908
|
+
# @rheights[i] = fix_size if fix_size > rh
|
|
909
|
+
|
|
832
910
|
end
|
|
833
911
|
end
|
|
834
912
|
# Increase the space to allow placing the routes.
|
|
@@ -885,9 +963,9 @@ module HDLRuby::Viz
|
|
|
885
963
|
elsif child.lports.any? then
|
|
886
964
|
step = child.height / child.lports.size
|
|
887
965
|
child.lports.each_with_index do |port,i|
|
|
888
|
-
puts "Preplace left port=#{port.name}"
|
|
889
966
|
port.xpos = xpos
|
|
890
967
|
port.ypos = ypos + i*step + step/2
|
|
968
|
+
puts "Preplace left port=#{port.name} ypos=#{port.ypos}"
|
|
891
969
|
end
|
|
892
970
|
end
|
|
893
971
|
# The up ports.
|
|
@@ -899,9 +977,9 @@ module HDLRuby::Viz
|
|
|
899
977
|
elsif child.uports.any? then
|
|
900
978
|
step = child.width / child.uports.size
|
|
901
979
|
child.uports.each_with_index do |port,i|
|
|
902
|
-
puts "Preplace up port=#{port.name}"
|
|
903
980
|
port.xpos = xpos + i*step + step/2
|
|
904
981
|
port.ypos = ypos + height - 1
|
|
982
|
+
puts "Preplace up port=#{port.name} xpos=#{port.xpos}"
|
|
905
983
|
end
|
|
906
984
|
end
|
|
907
985
|
# The right ports.
|
|
@@ -913,9 +991,9 @@ module HDLRuby::Viz
|
|
|
913
991
|
elsif child.rports.any? then
|
|
914
992
|
step = child.height / child.rports.size
|
|
915
993
|
child.rports.each_with_index do |port,i|
|
|
916
|
-
puts "Preplace right port=#{port.name}"
|
|
917
994
|
port.xpos = xpos + width - 1
|
|
918
995
|
port.ypos = ypos + i*step + step/2
|
|
996
|
+
puts "Preplace right port=#{port.name} ypos=#{port.ypos}"
|
|
919
997
|
end
|
|
920
998
|
end
|
|
921
999
|
# The down ports.
|
|
@@ -927,13 +1005,14 @@ module HDLRuby::Viz
|
|
|
927
1005
|
elsif child.dports.any? then
|
|
928
1006
|
step = child.width / child.dports.size
|
|
929
1007
|
child.dports.each_with_index do |port,i|
|
|
930
|
-
puts "Preplace down port=#{port.name}"
|
|
931
1008
|
port.xpos = xpos + i*step + step/2
|
|
932
1009
|
port.ypos = ypos
|
|
1010
|
+
puts "Preplace down port=#{port.name} xpos=#{port.xpos}"
|
|
933
1011
|
end
|
|
934
1012
|
end
|
|
935
1013
|
end
|
|
936
1014
|
|
|
1015
|
+
# TRUCMUCHE
|
|
937
1016
|
# Optimize the place.
|
|
938
1017
|
@children.each do |child|
|
|
939
1018
|
xpos = child.xpos
|
|
@@ -946,11 +1025,11 @@ module HDLRuby::Viz
|
|
|
946
1025
|
step = child.height / child.lports.size
|
|
947
1026
|
lefts = child.lports.clone
|
|
948
1027
|
|
|
949
|
-
# Sort the ports by reverse order
|
|
1028
|
+
# Sort the ports by reverse order in difference with their
|
|
950
1029
|
# targets.
|
|
951
1030
|
lefts.sort! do |p0,p1|
|
|
952
|
-
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p0.ypos } <=>
|
|
953
|
-
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p1.ypos }
|
|
1031
|
+
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.ypos - p0.ypos).abs } <=>
|
|
1032
|
+
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.ypos - p1.ypos).abs }
|
|
954
1033
|
end
|
|
955
1034
|
# Apply the order.
|
|
956
1035
|
lefts.each_with_index do |port,i|
|
|
@@ -967,8 +1046,8 @@ module HDLRuby::Viz
|
|
|
967
1046
|
# Sort the ports by reverse order x difference with their
|
|
968
1047
|
# targets.
|
|
969
1048
|
ups.sort! do |p0,p1|
|
|
970
|
-
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p0.xpos } <=>
|
|
971
|
-
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p1.xpos }
|
|
1049
|
+
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.xpos - p0.xpos).abs } <=>
|
|
1050
|
+
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.xpos - p1.xpos).abs }
|
|
972
1051
|
end
|
|
973
1052
|
# Apply the order.
|
|
974
1053
|
ups.each_with_index do |port,i|
|
|
@@ -986,8 +1065,8 @@ module HDLRuby::Viz
|
|
|
986
1065
|
# targets.
|
|
987
1066
|
rights.sort! do |p0,p1|
|
|
988
1067
|
# puts "p0=#{p0.name} p1=#{p1.name}"
|
|
989
|
-
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p0.ypos } <=>
|
|
990
|
-
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p1.ypos }
|
|
1068
|
+
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.ypos - p0.ypos).abs } <=>
|
|
1069
|
+
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.ypos - p1.ypos).abs }
|
|
991
1070
|
end
|
|
992
1071
|
# Apply the order.
|
|
993
1072
|
rights.each_with_index do |port,i|
|
|
@@ -1004,8 +1083,8 @@ module HDLRuby::Viz
|
|
|
1004
1083
|
# Sort the ports by reverse order x difference with their
|
|
1005
1084
|
# targets.
|
|
1006
1085
|
downs.sort! do |p0,p1|
|
|
1007
|
-
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p0.xpos } <=>
|
|
1008
|
-
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p1.xpos }
|
|
1086
|
+
p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.xpos - p0.xpos).abs } <=>
|
|
1087
|
+
p1.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + (t.xpos - p1.xpos).abs }
|
|
1009
1088
|
end
|
|
1010
1089
|
# Apply the order.
|
|
1011
1090
|
downs.each_with_index do |port,i|
|
|
@@ -1021,112 +1100,8 @@ module HDLRuby::Viz
|
|
|
1021
1100
|
# Also fine-place the ports of the current IC to also increase the
|
|
1022
1101
|
# aligment of connected ports.
|
|
1023
1102
|
def place_children_port_matrix
|
|
1024
|
-
# xpos, ypos = 0, 0
|
|
1025
|
-
# @matrix.each_with_index do |row,i|
|
|
1026
|
-
# xpos = 0
|
|
1027
|
-
# mypos = ypos + @rheights[i]
|
|
1028
|
-
# row.each_with_index do |child,j|
|
|
1029
|
-
# mxpos = xpos + @cwidths[j]
|
|
1030
|
-
# if child then
|
|
1031
|
-
# # Tune x position.
|
|
1032
|
-
# # Find the best delta.
|
|
1033
|
-
# bdx = 0 # Best y delta
|
|
1034
|
-
# bcost = 1/0.0 # Best score
|
|
1035
|
-
# xpos_in_cell = child.xpos - xpos # Initial position in cell
|
|
1036
|
-
# xpos_in_cell -= @border if j == 0 # Do not go inside the border
|
|
1037
|
-
# (@cwidths[j]-child.width).times do |dx|
|
|
1038
|
-
# dx = dx - xpos_in_cell # Adjust delta x to the initial position
|
|
1039
|
-
# cost = child.ports.reduce(0) do |sum,port|
|
|
1040
|
-
# pxpos = port.xpos + dx
|
|
1041
|
-
# sum + port.targets.reduce(0) do |subsum,tport|
|
|
1042
|
-
# # There is cost when the port is not align with the target.
|
|
1043
|
-
# if (port.side == LEFT and tport.side == RIGHT) or
|
|
1044
|
-
# (port.side == UP and tport.side == UP) then
|
|
1045
|
-
# # For left to right or up yo up connections,
|
|
1046
|
-
# # the first side should be 2 tiles on the left for
|
|
1047
|
-
# # straight wire or avoiding routing conjestion.
|
|
1048
|
-
# subsum + (pxpos-tport.xpos-2) != 0 ? 1 : 0
|
|
1049
|
-
# elsif (port.side == RIGHT and tport.side == LEFT) or
|
|
1050
|
-
# (port.side == DOWN and tport.side == DOWN) then
|
|
1051
|
-
# # For right to left or down to down connections,
|
|
1052
|
-
# # the first side should be 2 tiles on the right for
|
|
1053
|
-
# # straight wire or avoiding routing conjestion.
|
|
1054
|
-
# subsum + (pxpos-tport.xpos+2) != 0 ? 1 : 0
|
|
1055
|
-
# else
|
|
1056
|
-
# # Otherwise, perfect aligment is the best.
|
|
1057
|
-
# subsum + (pxpos-tport.xpos) != 0 ? 1 : 0
|
|
1058
|
-
# end
|
|
1059
|
-
# end
|
|
1060
|
-
# end
|
|
1061
|
-
# if cost < bcost then
|
|
1062
|
-
# bcost = cost
|
|
1063
|
-
# bdx = dx
|
|
1064
|
-
# end
|
|
1065
|
-
# end
|
|
1066
|
-
# # Ensure the child does not goes out of its cell.
|
|
1067
|
-
# if child.xpos + bdx < xpos then
|
|
1068
|
-
# bdx = xpos - child.xpos
|
|
1069
|
-
# elsif child.xpos + child.width + bdx >= mxpos then
|
|
1070
|
-
# bdx = mxpos - child.xpos - child.width - 1
|
|
1071
|
-
# end
|
|
1072
|
-
# # Apply the best delta.
|
|
1073
|
-
# child.xpos += bdx
|
|
1074
|
-
# # Update the ports position.
|
|
1075
|
-
# child.ports.each {|port| port.xpos += bdx }
|
|
1076
|
-
|
|
1077
|
-
# # Tune y position.
|
|
1078
|
-
# puts "for child=#{child.name}"
|
|
1079
|
-
# # Find the best delta.
|
|
1080
|
-
# bdy = 0 # Best x delta
|
|
1081
|
-
# bcost = 1/0.0 # Best score
|
|
1082
|
-
# ypos_in_cell = child.ypos - ypos # Initial position in cell
|
|
1083
|
-
# ypos_in_cell -= @border if i == 0 # Do not go to the outer border
|
|
1084
|
-
# (@rheights[i]-child.height).times do |dy|
|
|
1085
|
-
# dy = dy - ypos_in_cell # Adjust dela y with initial position
|
|
1086
|
-
# cost = child.ports.reduce(0) do |sum,port|
|
|
1087
|
-
# pypos = port.ypos + dy
|
|
1088
|
-
# sum + port.targets.reduce(0) do |subsum,tport|
|
|
1089
|
-
# # There is cost when the port is not align with the target.
|
|
1090
|
-
# if (port.side == UP and tport.side == DOWN) or
|
|
1091
|
-
# (port.side == RIGHT and tport.side == RIGHT) then
|
|
1092
|
-
# # For up to down or right to right connections,
|
|
1093
|
-
# # the first side should be 2 tiles on the right for
|
|
1094
|
-
# # straight wire or avoiding routing conjestion.
|
|
1095
|
-
# subsum + (pypos-tport.ypos+2) != 0 ? 1 : 0
|
|
1096
|
-
# elsif (port.side == DOWN and tport.side == UP) or
|
|
1097
|
-
# (port.side == LEFT and tport.side == LEFT) then
|
|
1098
|
-
# # For down to up or left to left connections,
|
|
1099
|
-
# # the forst side should be 2 tiles on the down for
|
|
1100
|
-
# # straight wire or avoiding routing conjestion.
|
|
1101
|
-
# subsum + (pypos-tport.ypos-2) != 0 ? 1 : 0
|
|
1102
|
-
# else
|
|
1103
|
-
# subsum + (pypos-tport.ypos) != 0 ? 1 : 0
|
|
1104
|
-
# end
|
|
1105
|
-
# end
|
|
1106
|
-
# end
|
|
1107
|
-
# if cost < bcost then
|
|
1108
|
-
# bcost = cost
|
|
1109
|
-
# bdy = dy
|
|
1110
|
-
# end
|
|
1111
|
-
# end
|
|
1112
|
-
# # puts "mypos=#{mypos} child.ypos=#{child.ypos} bdy=#{bdy}"
|
|
1113
|
-
# # Ensure the child does not goes out of its cell.
|
|
1114
|
-
# if child.ypos + bdy < ypos then
|
|
1115
|
-
# bdy = ypos - child.ypos
|
|
1116
|
-
# elsif child.ypos + child.height + bdy >= mypos then
|
|
1117
|
-
# bdy = mypos - child.ypos - child.height - 1
|
|
1118
|
-
# end
|
|
1119
|
-
# # Apply the best delta.
|
|
1120
|
-
# child.ypos += bdy
|
|
1121
|
-
# # Update the ports position.
|
|
1122
|
-
# child.ports.each {|port| port.ypos += bdy }
|
|
1123
|
-
# end
|
|
1124
|
-
# xpos += @cwidths[j]
|
|
1125
|
-
# end
|
|
1126
|
-
# ypos += @rheights[i]
|
|
1127
|
-
# end
|
|
1128
1103
|
|
|
1129
|
-
# First prepare the
|
|
1104
|
+
# First prepare the algorthms: sort the children for
|
|
1130
1105
|
# vertical and horizontal processing and locate their
|
|
1131
1106
|
# respective row and column intervals.
|
|
1132
1107
|
# Sort the children by decreasing number of left and right ports,
|
|
@@ -1278,6 +1253,7 @@ module HDLRuby::Viz
|
|
|
1278
1253
|
# Also place the ports of the current IC.
|
|
1279
1254
|
poses = []
|
|
1280
1255
|
@lports.each do |lport|
|
|
1256
|
+
next unless lport.targets[0] # Skip dangling port.
|
|
1281
1257
|
lport.ypos = lport.targets[0].ypos
|
|
1282
1258
|
lport.ypos += 1 if lport.targets[0].side == UP
|
|
1283
1259
|
lport.ypos -= 1 if lport.targets[0].side == DOWN
|
|
@@ -1290,10 +1266,10 @@ module HDLRuby::Viz
|
|
|
1290
1266
|
end
|
|
1291
1267
|
poses = []
|
|
1292
1268
|
@uports.each do |uport|
|
|
1269
|
+
next unless uport.targets[0] # Skip dangling port.
|
|
1293
1270
|
uport.xpos = uport.targets[0].xpos
|
|
1294
1271
|
uport.xpos -= 1 if uport.targets[0].side == LEFT
|
|
1295
1272
|
uport.xpos += 1 if uport.targets[0].side == RIGHT
|
|
1296
|
-
puts "Now uport.xpos=#{uport.xpos}"
|
|
1297
1273
|
# Ensure ports do not overlap.
|
|
1298
1274
|
while poses[uport.xpos] do
|
|
1299
1275
|
uport.xpos += 1
|
|
@@ -1303,6 +1279,7 @@ module HDLRuby::Viz
|
|
|
1303
1279
|
end
|
|
1304
1280
|
poses = []
|
|
1305
1281
|
@rports.each do |rport|
|
|
1282
|
+
next unless rport.targets[0] # Skip dangling port.
|
|
1306
1283
|
rport.ypos = rport.targets[0].ypos
|
|
1307
1284
|
rport.ypos += 1 if rport.targets[0].side == UP
|
|
1308
1285
|
rport.ypos -= 1 if rport.targets[0].side == DOWN
|
|
@@ -1315,6 +1292,7 @@ module HDLRuby::Viz
|
|
|
1315
1292
|
end
|
|
1316
1293
|
poses = []
|
|
1317
1294
|
@dports.each do |dport|
|
|
1295
|
+
next unless dport.targets[0] # Skip dangling port.
|
|
1318
1296
|
dport.xpos = dport.targets[0].xpos
|
|
1319
1297
|
dport.xpos -= 1 if dport.targets[0].side == LEFT
|
|
1320
1298
|
dport.xpos += 1 if dport.targets[0].side == RIGHT
|
|
@@ -1504,68 +1482,344 @@ module HDLRuby::Viz
|
|
|
1504
1482
|
return (pos0[0] - pos1[0]).abs + (pos0[1] - pos1[1]).abs
|
|
1505
1483
|
end
|
|
1506
1484
|
|
|
1485
|
+
# Build a can for wire conflicting with port.
|
|
1486
|
+
def build_port_conflict_cache
|
|
1487
|
+
@port_conflict_cache = {}
|
|
1488
|
+
@route_matrix.each do |row|
|
|
1489
|
+
row.each do |elem|
|
|
1490
|
+
next unless elem&.ic
|
|
1491
|
+
ic = elem.ic
|
|
1492
|
+
ic.lports.each do |p|
|
|
1493
|
+
key = p.xpos + p.ypos * 10000 + LEFT * 100000000
|
|
1494
|
+
@port_conflict_cache[key] = p
|
|
1495
|
+
end
|
|
1496
|
+
ic.uports.each do |p|
|
|
1497
|
+
key = p.xpos + p.ypos * 10000 + UP * 100000000
|
|
1498
|
+
@port_conflict_cache[key] = p
|
|
1499
|
+
end
|
|
1500
|
+
ic.rports.each do |p|
|
|
1501
|
+
key = p.xpos + p.ypos * 10000 + RIGHT * 100000000
|
|
1502
|
+
@port_conflict_cache[key] = p
|
|
1503
|
+
end
|
|
1504
|
+
ic.dports.each do |p|
|
|
1505
|
+
key = p.xpos + p.ypos * 10000 + DOWN * 100000000
|
|
1506
|
+
@port_conflict_cache[key] = p
|
|
1507
|
+
end
|
|
1508
|
+
end
|
|
1509
|
+
end
|
|
1510
|
+
end
|
|
1511
|
+
|
|
1507
1512
|
# Check if there is a port at location +pos+ in +side+ that conflict
|
|
1508
1513
|
# with both +port0+ and +port1+.
|
|
1509
|
-
def ic_port_conflict(port0,port1,pos,side)
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
return false unless
|
|
1514
|
-
#
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
when
|
|
1520
|
-
|
|
1521
|
-
when
|
|
1522
|
-
|
|
1523
|
-
when
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1514
|
+
# def ic_port_conflict(port0,port1,pos,side)
|
|
1515
|
+
ic_port = nil
|
|
1516
|
+
def ic_port_conflict(port0,port1,pos0,pos1,side)
|
|
1517
|
+
# return false unless @route_matrix[pos[1]]
|
|
1518
|
+
# return false unless @route_matrix[pos[1]][pos[0]]
|
|
1519
|
+
# ic = @route_matrix[pos[1]][pos[0]].ic
|
|
1520
|
+
# return false unless ic # No IC here, so not possible port to conflict
|
|
1521
|
+
# # There is an IC get the port at pos from side if any.
|
|
1522
|
+
# p = nil
|
|
1523
|
+
# case side
|
|
1524
|
+
# when LEFT
|
|
1525
|
+
# port = ic.lports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
|
|
1526
|
+
# when UP
|
|
1527
|
+
# port = ic.uports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
|
|
1528
|
+
# when RIGHT
|
|
1529
|
+
# port = ic.rports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
|
|
1530
|
+
# when DOWN
|
|
1531
|
+
# port = ic.dports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
|
|
1532
|
+
# end
|
|
1533
|
+
# if port and port != port0 and port != port1 then
|
|
1534
|
+
# return true
|
|
1535
|
+
# else
|
|
1536
|
+
# return false
|
|
1537
|
+
# end
|
|
1538
|
+
|
|
1539
|
+
ic_port = @port_conflict_cache[pos0 + pos1 * 10000 + side * 100000000]
|
|
1540
|
+
return ic_port && ic_port != port0 && ic_port != port1
|
|
1531
1541
|
end
|
|
1532
1542
|
|
|
1543
|
+
# # Get the neighbor free positions for port.
|
|
1544
|
+
# def free_neighbors(port0,port1,cpos)
|
|
1545
|
+
# res = []
|
|
1546
|
+
# # For cosmetic reasons of the wires, the order of processing depends
|
|
1547
|
+
# # on the relative position of the ports.
|
|
1548
|
+
# if port0.xpos < port1.xpos and port0.ypos < port1.ypos then
|
|
1549
|
+
# # Left neighbor.
|
|
1550
|
+
# lpos = [cpos[0]-1,cpos[1]]
|
|
1551
|
+
# if lpos[0] >= 0 then
|
|
1552
|
+
# elem = @route_matrix[lpos[1]][lpos[0]]
|
|
1553
|
+
# res << lpos if elem.free_from_right?(port0,port1) and
|
|
1554
|
+
# # !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
|
|
1555
|
+
# !ic_port_conflict(port0,port1,lpos[0]-1,lpos[1],RIGHT)
|
|
1556
|
+
# end
|
|
1557
|
+
# # Up neighbor.
|
|
1558
|
+
# upos = [cpos[0],cpos[1]+1]
|
|
1559
|
+
# if upos[1] < @route_height then
|
|
1560
|
+
# elem = @route_matrix[upos[1]][upos[0]]
|
|
1561
|
+
# res << upos if elem.free_from_down?(port0,port1) and
|
|
1562
|
+
# # !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
|
|
1563
|
+
# !ic_port_conflict(port0,port1,upos[0],upos[1]+1,DOWN)
|
|
1564
|
+
# end
|
|
1565
|
+
# # Right neighbor.
|
|
1566
|
+
# rpos = [cpos[0]+1,cpos[1]]
|
|
1567
|
+
# if rpos[0] < @route_width then
|
|
1568
|
+
# elem = @route_matrix[rpos[1]][rpos[0]]
|
|
1569
|
+
# res << rpos if elem.free_from_left?(port0,port1) and
|
|
1570
|
+
# # !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
|
|
1571
|
+
# !ic_port_conflict(port0,port1,rpos[0]+1,rpos[1],LEFT)
|
|
1572
|
+
# end
|
|
1573
|
+
# # Down neighbor.
|
|
1574
|
+
# dpos = [cpos[0],cpos[1]-1]
|
|
1575
|
+
# if dpos[1] >= 0 then
|
|
1576
|
+
# elem = @route_matrix[dpos[1]][dpos[0]]
|
|
1577
|
+
# res << dpos if elem.free_from_up?(port0,port1) and
|
|
1578
|
+
# # !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
|
|
1579
|
+
# !ic_port_conflict(port0,port1,dpos[0],dpos[1]-1,UP)
|
|
1580
|
+
# end
|
|
1581
|
+
# elsif port0.xpos < port1.xpos and port0.ypos > port1.ypos then
|
|
1582
|
+
# # Left neighbor.
|
|
1583
|
+
# lpos = [cpos[0]-1,cpos[1]]
|
|
1584
|
+
# if lpos[0] >= 0 then
|
|
1585
|
+
# elem = @route_matrix[lpos[1]][lpos[0]]
|
|
1586
|
+
# res << lpos if elem.free_from_right?(port0,port1) and
|
|
1587
|
+
# # !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
|
|
1588
|
+
# !ic_port_conflict(port0,port1,lpos[0]-1,lpos[1],RIGHT)
|
|
1589
|
+
# end
|
|
1590
|
+
# # Down neighbor.
|
|
1591
|
+
# dpos = [cpos[0],cpos[1]-1]
|
|
1592
|
+
# if dpos[1] >= 0 then
|
|
1593
|
+
# elem = @route_matrix[dpos[1]][dpos[0]]
|
|
1594
|
+
# res << dpos if elem.free_from_up?(port0,port1) and
|
|
1595
|
+
# # !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
|
|
1596
|
+
# !ic_port_conflict(port0,port1,dpos[0],dpos[1]-1,UP)
|
|
1597
|
+
# end
|
|
1598
|
+
# # Right neighbor.
|
|
1599
|
+
# rpos = [cpos[0]+1,cpos[1]]
|
|
1600
|
+
# if rpos[0] < @route_width then
|
|
1601
|
+
# elem = @route_matrix[rpos[1]][rpos[0]]
|
|
1602
|
+
# res << rpos if elem.free_from_left?(port0,port1) and
|
|
1603
|
+
# # !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
|
|
1604
|
+
# !ic_port_conflict(port0,port1,rpos[0]+1,rpos[1],LEFT)
|
|
1605
|
+
# end
|
|
1606
|
+
# # Up neighbor.
|
|
1607
|
+
# upos = [cpos[0],cpos[1]+1]
|
|
1608
|
+
# if upos[1] < @route_height then
|
|
1609
|
+
# elem = @route_matrix[upos[1]][upos[0]]
|
|
1610
|
+
# res << upos if elem.free_from_down?(port0,port1) and
|
|
1611
|
+
# # !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
|
|
1612
|
+
# !ic_port_conflict(port0,port1,upos[0],upos[1]+1,DOWN)
|
|
1613
|
+
# end
|
|
1614
|
+
# elsif port0.xpos > port1.xpos and port0.ypos > port1.ypos then
|
|
1615
|
+
# # Right neighbor.
|
|
1616
|
+
# rpos = [cpos[0]+1,cpos[1]]
|
|
1617
|
+
# if rpos[0] < @route_width then
|
|
1618
|
+
# elem = @route_matrix[rpos[1]][rpos[0]]
|
|
1619
|
+
# res << rpos if elem.free_from_left?(port0,port1) and
|
|
1620
|
+
# # !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
|
|
1621
|
+
# !ic_port_conflict(port0,port1,rpos[0]+1,rpos[1],LEFT)
|
|
1622
|
+
# end
|
|
1623
|
+
# # Down neighbor.
|
|
1624
|
+
# dpos = [cpos[0],cpos[1]-1]
|
|
1625
|
+
# if dpos[1] >= 0 then
|
|
1626
|
+
# elem = @route_matrix[dpos[1]][dpos[0]]
|
|
1627
|
+
# res << dpos if elem.free_from_up?(port0,port1) and
|
|
1628
|
+
# # !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
|
|
1629
|
+
# !ic_port_conflict(port0,port1,dpos[0],dpos[1]-1,UP)
|
|
1630
|
+
# end
|
|
1631
|
+
# # Left neighbor.
|
|
1632
|
+
# lpos = [cpos[0]-1,cpos[1]]
|
|
1633
|
+
# if lpos[0] >= 0 then
|
|
1634
|
+
# elem = @route_matrix[lpos[1]][lpos[0]]
|
|
1635
|
+
# res << lpos if elem.free_from_right?(port0,port1) and
|
|
1636
|
+
# # !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
|
|
1637
|
+
# !ic_port_conflict(port0,port1,lpos[0]-1,lpos[1],RIGHT)
|
|
1638
|
+
# end
|
|
1639
|
+
# # Up neighbor.
|
|
1640
|
+
# upos = [cpos[0],cpos[1]+1]
|
|
1641
|
+
# if upos[1] < @route_height then
|
|
1642
|
+
# elem = @route_matrix[upos[1]][upos[0]]
|
|
1643
|
+
# res << upos if elem.free_from_down?(port0,port1) and
|
|
1644
|
+
# # !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
|
|
1645
|
+
# !ic_port_conflict(port0,port1,upos[0],upos[1]+1,DOWN)
|
|
1646
|
+
# end
|
|
1647
|
+
# else
|
|
1648
|
+
# # Right neighbor.
|
|
1649
|
+
# rpos = [cpos[0]+1,cpos[1]]
|
|
1650
|
+
# if rpos[0] < @route_width then
|
|
1651
|
+
# elem = @route_matrix[rpos[1]][rpos[0]]
|
|
1652
|
+
# res << rpos if elem.free_from_left?(port0,port1) and
|
|
1653
|
+
# # !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
|
|
1654
|
+
# !ic_port_conflict(port0,port1,rpos[0]+1,rpos[1],LEFT)
|
|
1655
|
+
# end
|
|
1656
|
+
# # Up neighbor.
|
|
1657
|
+
# upos = [cpos[0],cpos[1]+1]
|
|
1658
|
+
# if upos[1] < @route_height then
|
|
1659
|
+
# elem = @route_matrix[upos[1]][upos[0]]
|
|
1660
|
+
# res << upos if elem.free_from_down?(port0,port1) and
|
|
1661
|
+
# # !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
|
|
1662
|
+
# !ic_port_conflict(port0,port1,upos[0],upos[1]+1,DOWN)
|
|
1663
|
+
# end
|
|
1664
|
+
# # Left neighbor.
|
|
1665
|
+
# lpos = [cpos[0]-1,cpos[1]]
|
|
1666
|
+
# if lpos[0] >= 0 then
|
|
1667
|
+
# elem = @route_matrix[lpos[1]][lpos[0]]
|
|
1668
|
+
# res << lpos if elem.free_from_right?(port0,port1) and
|
|
1669
|
+
# # !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
|
|
1670
|
+
# !ic_port_conflict(port0,port1,lpos[0]-1,lpos[1],RIGHT)
|
|
1671
|
+
# end
|
|
1672
|
+
# # Down neighbor.
|
|
1673
|
+
# dpos = [cpos[0],cpos[1]-1]
|
|
1674
|
+
# if dpos[1] >= 0 then
|
|
1675
|
+
# elem = @route_matrix[dpos[1]][dpos[0]]
|
|
1676
|
+
# res << dpos if elem.free_from_up?(port0,port1) and
|
|
1677
|
+
# # !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
|
|
1678
|
+
# !ic_port_conflict(port0,port1,dpos[0],dpos[1]-1,UP)
|
|
1679
|
+
# end
|
|
1680
|
+
# end
|
|
1681
|
+
# # Return the free neigbor positions.
|
|
1682
|
+
# return res
|
|
1683
|
+
# end
|
|
1533
1684
|
# Get the neighbor free positions for port.
|
|
1534
|
-
|
|
1685
|
+
res = p0 = p1 = nil
|
|
1535
1686
|
def free_neighbors(port0,port1,cpos)
|
|
1536
1687
|
res = []
|
|
1537
|
-
#
|
|
1538
|
-
|
|
1539
|
-
if
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1688
|
+
# For cosmetic reasons of the wires, the order of processing depends
|
|
1689
|
+
# on the relative position of the ports.
|
|
1690
|
+
if port0.xpos < port1.xpos and port0.ypos < port1.ypos then
|
|
1691
|
+
# Left neighbor.
|
|
1692
|
+
p0 = cpos[0]-1
|
|
1693
|
+
p1 = cpos[1]
|
|
1694
|
+
if p0 >= 0 then
|
|
1695
|
+
elem = @route_matrix[p1][p0]
|
|
1696
|
+
res << [p0,p1] if elem.free_from_right?(port0,port1) and
|
|
1697
|
+
!ic_port_conflict(port0,port1,p0-1,p1,RIGHT)
|
|
1698
|
+
end
|
|
1699
|
+
# Up neighbor.
|
|
1700
|
+
p0 = cpos[0]
|
|
1701
|
+
p1 = cpos[1]+1
|
|
1702
|
+
if p1 < @route_height then
|
|
1703
|
+
elem = @route_matrix[p1][p0]
|
|
1704
|
+
res << [p0,p1] if elem.free_from_down?(port0,port1) and
|
|
1705
|
+
!ic_port_conflict(port0,port1,p0,p1+1,DOWN)
|
|
1706
|
+
end
|
|
1707
|
+
# Right neighbor.
|
|
1708
|
+
p0 = cpos[0]+1
|
|
1709
|
+
p1 = cpos[1]
|
|
1710
|
+
if p0 < @route_width then
|
|
1711
|
+
elem = @route_matrix[p1][p0]
|
|
1712
|
+
res << [p0,p1] if elem.free_from_left?(port0,port1) and
|
|
1713
|
+
!ic_port_conflict(port0,port1,p0+1,p1,LEFT)
|
|
1714
|
+
end
|
|
1715
|
+
# Down neighbor.
|
|
1716
|
+
p0 = cpos[0]
|
|
1717
|
+
p1 = cpos[1]-1
|
|
1718
|
+
if p1 >= 0 then
|
|
1719
|
+
elem = @route_matrix[p1][p0]
|
|
1720
|
+
res << [p0,p1] if elem.free_from_up?(port0,port1) and
|
|
1721
|
+
!ic_port_conflict(port0,port1,p0,p1-1,UP)
|
|
1722
|
+
end
|
|
1723
|
+
elsif port0.xpos < port1.xpos and port0.ypos > port1.ypos then
|
|
1724
|
+
# Left neighbor.
|
|
1725
|
+
p0 = cpos[0]-1
|
|
1726
|
+
p1 = cpos[1]
|
|
1727
|
+
if p0 >= 0 then
|
|
1728
|
+
elem = @route_matrix[p1][p0]
|
|
1729
|
+
res << [p0,p1] if elem.free_from_right?(port0,port1) and
|
|
1730
|
+
!ic_port_conflict(port0,port1,p0-1,p1,RIGHT)
|
|
1731
|
+
end
|
|
1732
|
+
# Down neighbor.
|
|
1733
|
+
p0 = cpos[0]
|
|
1734
|
+
p1 = cpos[1]-1
|
|
1735
|
+
if p1 >= 0 then
|
|
1736
|
+
elem = @route_matrix[p1][p0]
|
|
1737
|
+
res << [p0,p1] if elem.free_from_up?(port0,port1) and
|
|
1738
|
+
!ic_port_conflict(port0,port1,p0,p1-1,UP)
|
|
1739
|
+
end
|
|
1740
|
+
# Right neighbor.
|
|
1741
|
+
p0 = cpos[0]+1
|
|
1742
|
+
p1 = cpos[1]
|
|
1743
|
+
if p0 < @route_width then
|
|
1744
|
+
elem = @route_matrix[p1][p0]
|
|
1745
|
+
res << [p0,p1] if elem.free_from_left?(port0,port1) and
|
|
1746
|
+
!ic_port_conflict(port0,port1,p0+1,p1,LEFT)
|
|
1747
|
+
end
|
|
1748
|
+
# Up neighbor.
|
|
1749
|
+
p0 = cpos[0]
|
|
1750
|
+
p1 = cpos[1]+1
|
|
1751
|
+
if p1 < @route_height then
|
|
1752
|
+
elem = @route_matrix[p1][p0]
|
|
1753
|
+
res << [p0,p1] if elem.free_from_down?(port0,port1) and
|
|
1754
|
+
!ic_port_conflict(port0,port1,p0,p1+1,DOWN)
|
|
1755
|
+
end
|
|
1756
|
+
elsif port0.xpos > port1.xpos and port0.ypos > port1.ypos then
|
|
1757
|
+
# Right neighbor.
|
|
1758
|
+
p0 = cpos[0]+1
|
|
1759
|
+
p1 = cpos[1]
|
|
1760
|
+
if p0 < @route_width then
|
|
1761
|
+
elem = @route_matrix[p1][p0]
|
|
1762
|
+
res << [p0,p1] if elem.free_from_left?(port0,port1) and
|
|
1763
|
+
!ic_port_conflict(port0,port1,p0+1,p1,LEFT)
|
|
1764
|
+
end
|
|
1765
|
+
# Down neighbor.
|
|
1766
|
+
p0 = cpos[0]
|
|
1767
|
+
p1 = cpos[1]-1
|
|
1768
|
+
if p1 >= 0 then
|
|
1769
|
+
elem = @route_matrix[p1][p0]
|
|
1770
|
+
res << [p0,p1] if elem.free_from_up?(port0,port1) and
|
|
1771
|
+
!ic_port_conflict(port0,port1,p0,p1-1,UP)
|
|
1772
|
+
end
|
|
1773
|
+
# Left neighbor.
|
|
1774
|
+
p0 = cpos[0]-1
|
|
1775
|
+
p1 = cpos[1]
|
|
1776
|
+
if p0 >= 0 then
|
|
1777
|
+
elem = @route_matrix[p1][p0]
|
|
1778
|
+
res << [p0,p1] if elem.free_from_right?(port0,port1) and
|
|
1779
|
+
!ic_port_conflict(port0,port1,p0-1,p1,RIGHT)
|
|
1780
|
+
end
|
|
1781
|
+
# Up neighbor.
|
|
1782
|
+
p0 = cpos[0]
|
|
1783
|
+
p1 = cpos[1]+1
|
|
1784
|
+
if p1 < @route_height then
|
|
1785
|
+
elem = @route_matrix[p1][p0]
|
|
1786
|
+
res << [p0,p1] if elem.free_from_down?(port0,port1) and
|
|
1787
|
+
!ic_port_conflict(port0,port1,p0,p1+1,DOWN)
|
|
1788
|
+
end
|
|
1789
|
+
else
|
|
1790
|
+
# Right neighbor.
|
|
1791
|
+
p0 = cpos[0]+1
|
|
1792
|
+
p1 = cpos[1]
|
|
1793
|
+
if p0 < @route_width then
|
|
1794
|
+
elem = @route_matrix[p1][p0]
|
|
1795
|
+
res << [p0,p1] if elem.free_from_left?(port0,port1) and
|
|
1796
|
+
!ic_port_conflict(port0,port1,p0+1,p1,LEFT)
|
|
1797
|
+
end
|
|
1798
|
+
# Up neighbor.
|
|
1799
|
+
p0 = cpos[0]
|
|
1800
|
+
p1 = cpos[1]+1
|
|
1801
|
+
if p1 < @route_height then
|
|
1802
|
+
elem = @route_matrix[p1][p0]
|
|
1803
|
+
res << [p0,p1] if elem.free_from_down?(port0,port1) and
|
|
1804
|
+
!ic_port_conflict(port0,port1,p0,p1+1,DOWN)
|
|
1805
|
+
end
|
|
1806
|
+
# Left neighbor.
|
|
1807
|
+
p0 = cpos[0]-1
|
|
1808
|
+
p1 = cpos[1]
|
|
1809
|
+
if p0 >= 0 then
|
|
1810
|
+
elem = @route_matrix[p1][p0]
|
|
1811
|
+
res << [p0,p1] if elem.free_from_right?(port0,port1) and
|
|
1812
|
+
!ic_port_conflict(port0,port1,p0-1,p1,RIGHT)
|
|
1813
|
+
end
|
|
1814
|
+
# Down neighbor.
|
|
1815
|
+
p0 = cpos[0]
|
|
1816
|
+
p1 = cpos[1]-1
|
|
1817
|
+
if p1 >= 0 then
|
|
1818
|
+
elem = @route_matrix[p1][p0]
|
|
1819
|
+
res << [p0,p1] if elem.free_from_up?(port0,port1) and
|
|
1820
|
+
!ic_port_conflict(port0,port1,p0,p1-1,UP)
|
|
1821
|
+
end
|
|
1822
|
+
end
|
|
1569
1823
|
# Return the free neigbor positions.
|
|
1570
1824
|
return res
|
|
1571
1825
|
end
|
|
@@ -1643,6 +1897,20 @@ module HDLRuby::Viz
|
|
|
1643
1897
|
((pos0[1]-pos1[1]).abs < 2 and pos0[0] == pos1[0]))
|
|
1644
1898
|
end
|
|
1645
1899
|
|
|
1900
|
+
#BENDCOST
|
|
1901
|
+
# Compute the direction between two positions in a path.
|
|
1902
|
+
def path_dir(pos0, pos1)
|
|
1903
|
+
if pos0[0] > pos1[0] then
|
|
1904
|
+
return LEFT
|
|
1905
|
+
elsif pos0[0] < pos1[0] then
|
|
1906
|
+
return RIGHT
|
|
1907
|
+
elsif pos0[1] > pos1[1] then
|
|
1908
|
+
return UP
|
|
1909
|
+
else
|
|
1910
|
+
return DOWN
|
|
1911
|
+
end
|
|
1912
|
+
end
|
|
1913
|
+
|
|
1646
1914
|
# Route from +port0+ to +port1.
|
|
1647
1915
|
# NOTE: uses the A* algorithm with taxi cab distance.
|
|
1648
1916
|
def connection_route(port0,port1)
|
|
@@ -1651,60 +1919,55 @@ module HDLRuby::Viz
|
|
|
1651
1919
|
pos0 = [port0.xpos,port0.ypos]
|
|
1652
1920
|
pos1 = [port1.xpos,port1.ypos]
|
|
1653
1921
|
oset = [pos0]
|
|
1654
|
-
# oset = Set.new
|
|
1655
|
-
oset << pos0
|
|
1656
1922
|
from = { }
|
|
1657
|
-
# gscore = Hash.new(1/0.0)
|
|
1658
|
-
# gscore[pos0] = 0
|
|
1659
1923
|
gscore = Array.new(@route_matrix.size) { Array.new(@route_matrix[0].size) { 1/0.0 } }
|
|
1660
1924
|
gscore[pos0[1]][pos0[0]] = 0
|
|
1661
|
-
# fscore =
|
|
1662
|
-
|
|
1663
|
-
fscore = Array.new(@route_matrix.size) { [] }
|
|
1925
|
+
# fscore = Array.new(@route_matrix.size) { [] }
|
|
1926
|
+
fscore = Array.new(@route_matrix.size) { Array.new(@route_matrix[0].size) { 1/0.0 } }
|
|
1664
1927
|
fscore[pos0[1]][pos0[0]] = taxi_distance(pos0,pos1)
|
|
1928
|
+
|
|
1929
|
+
closed = { } # Closed set
|
|
1665
1930
|
while oset.any? do
|
|
1666
1931
|
# Pick the position from oset with the minimum fscore.
|
|
1667
|
-
cpos = nil # Current position
|
|
1668
|
-
mscore = 1/0.0 # Minimum score
|
|
1669
|
-
# oset.each do |pos|
|
|
1670
|
-
# # score = fscore[pos]
|
|
1671
|
-
# score = fscore[pos[1]][pos[0]]
|
|
1672
|
-
# if score < mscore then
|
|
1673
|
-
# mscore = score
|
|
1674
|
-
# cpos = pos
|
|
1675
|
-
# end
|
|
1676
|
-
# end
|
|
1932
|
+
# cpos = nil # Current position
|
|
1933
|
+
# mscore = 1/0.0 # Minimum score
|
|
1677
1934
|
# The best score is necessily at the end of oset.
|
|
1678
1935
|
cpos = oset.pop
|
|
1936
|
+
next if closed[cpos] # Skip already teated position
|
|
1937
|
+
closed[cpos] = true
|
|
1679
1938
|
# puts "cpos=#{cpos}"
|
|
1680
1939
|
if touch?(cpos,pos1) then
|
|
1681
1940
|
# The goal is reached.
|
|
1682
1941
|
from[pos1] = cpos
|
|
1683
1942
|
return reconstruct_path(port0,port1,from,pos1)
|
|
1684
1943
|
end
|
|
1685
|
-
# oset.delete(cpos) # No need anymore since pop
|
|
1686
1944
|
# Get the neighbor positions for port.
|
|
1687
|
-
# poses = free_neighbors(port0,cpos)
|
|
1688
1945
|
poses = free_neighbors(port0,port1,cpos)
|
|
1946
|
+
#BENDCOST
|
|
1947
|
+
ppos = poses.first
|
|
1948
|
+
pdir = nil
|
|
1689
1949
|
poses.each do |pos|
|
|
1690
1950
|
# Try it.
|
|
1691
|
-
# tscore = gscore[cpos] + cost_position(port0,pos)
|
|
1692
|
-
|
|
1693
|
-
|
|
1951
|
+
# tscore = gscore[cpos[1]][cpos[0]] + cost_position(port0,pos)
|
|
1952
|
+
# BENDCOST
|
|
1953
|
+
dir = path_dir(ppos,pos)
|
|
1954
|
+
tscore = gscore[cpos[1]][cpos[0]] + cost_position(port0,pos) +
|
|
1955
|
+
((dir != pdir) ? 1024 : 0)
|
|
1694
1956
|
if tscore < gscore[pos[1]][pos[0]] then
|
|
1695
1957
|
# This path to neigbor is better than any previous one, keep it.
|
|
1696
1958
|
from[pos] = cpos
|
|
1697
|
-
# gscore[pos] = tscore
|
|
1698
1959
|
gscore[pos[1]][pos[0]] = tscore
|
|
1699
|
-
# fscore[pos] = tscore + taxi_distance(pos,pos1)
|
|
1700
1960
|
fscore[pos[1]][pos[0]] = tscore + taxi_distance(pos,pos1)
|
|
1701
|
-
# oset
|
|
1702
|
-
idx = oset.bsearch_index {|p| fscore[p[1]][p[0]]
|
|
1961
|
+
# idx = oset.bsearch_index {|p| fscore[p[1]][p[0]] <= fscore[pos[1]][pos[0]] }
|
|
1962
|
+
idx = oset.bsearch_index {|p| fscore[p[1]][p[0]] < fscore[pos[1]][pos[0]] }
|
|
1703
1963
|
if idx then
|
|
1704
1964
|
oset.insert(idx,pos)
|
|
1705
1965
|
else
|
|
1706
1966
|
oset << pos
|
|
1707
1967
|
end
|
|
1968
|
+
#BENDCOST
|
|
1969
|
+
ppos = pos
|
|
1970
|
+
pdir = dir
|
|
1708
1971
|
end
|
|
1709
1972
|
end
|
|
1710
1973
|
end
|
|
@@ -1747,6 +2010,7 @@ module HDLRuby::Viz
|
|
|
1747
2010
|
(to_route.size/2).times do |epoch|
|
|
1748
2011
|
puts "Routing epoch=#{epoch}..."
|
|
1749
2012
|
self.init_route # Reinitialize the route matrix.
|
|
2013
|
+
build_port_conflict_cache
|
|
1750
2014
|
routed_pairs = [] # The list of already routed pair of ports.
|
|
1751
2015
|
@routes = [] # The list of created routes.
|
|
1752
2016
|
# Do the routing.
|
|
@@ -1838,6 +2102,7 @@ module HDLRuby::Viz
|
|
|
1838
2102
|
route.path.append([eport.xpos,eport.ypos-1])
|
|
1839
2103
|
end
|
|
1840
2104
|
end
|
|
2105
|
+
# Add the wires to the tiles.
|
|
1841
2106
|
route.path.each_cons(3).with_index do |((x0,y0),(x1,y1),(x2,y2)),i|
|
|
1842
2107
|
# puts "x0,y0=#{x0},#{y0} x1,y1=#{x1},#{y1} x2,y2=#{x2},#{y2}"
|
|
1843
2108
|
# puts "i=#{i} dir=#{dir}"
|
|
@@ -2076,6 +2341,14 @@ module HDLRuby::Viz
|
|
|
2076
2341
|
puts "matrix:"
|
|
2077
2342
|
matrix.each { |row| puts "#{row.map{|ic| ic ? ic.name : " " }}" }
|
|
2078
2343
|
|
|
2344
|
+
# And the ic to coordinate table. TRUCMUCHE
|
|
2345
|
+
ic_matrix_coordinates = {}
|
|
2346
|
+
matrix.each_with_index do |row,y|
|
|
2347
|
+
row.each_with_index do |ic,x|
|
|
2348
|
+
ic_matrix_coordinates[ic] = [x,y] if ic
|
|
2349
|
+
end
|
|
2350
|
+
end
|
|
2351
|
+
|
|
2079
2352
|
# Compute the side of the ports.
|
|
2080
2353
|
self.bounding_children
|
|
2081
2354
|
|
|
@@ -2092,7 +2365,8 @@ module HDLRuby::Viz
|
|
|
2092
2365
|
end
|
|
2093
2366
|
|
|
2094
2367
|
# For the children.
|
|
2095
|
-
self.side_children
|
|
2368
|
+
# self.side_children
|
|
2369
|
+
self.side_children(ic_matrix_coordinates)
|
|
2096
2370
|
|
|
2097
2371
|
puts "Children ports side results: "
|
|
2098
2372
|
self.children.each_with_index do |child|
|
|
@@ -2205,51 +2479,54 @@ module HDLRuby::Viz
|
|
|
2205
2479
|
# Generate a system description SVG text for +ic+
|
|
2206
2480
|
def system_svg(ic)
|
|
2207
2481
|
return "<rect fill=\"#fff\" stroke=\"#000\" " +
|
|
2208
|
-
"stroke-width=\"#{@scale/8.0}\" " +
|
|
2209
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2210
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2211
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2482
|
+
"stroke-width=\"#{(@scale/8.0).round(3)}\" " +
|
|
2483
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2484
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2485
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2212
2486
|
end
|
|
2213
2487
|
|
|
2214
2488
|
# Generate an instance description SVG text for +ic+
|
|
2215
2489
|
def instance_svg(ic)
|
|
2216
|
-
id = Viz.to_svg_id(ic.name)
|
|
2490
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2491
|
+
id = ic.__id__.to_s
|
|
2217
2492
|
# The rectangle representing the instance.
|
|
2218
2493
|
res = "<rect id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
|
|
2219
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
2220
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2221
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2222
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2494
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
2495
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2496
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2497
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2223
2498
|
# Its name.
|
|
2224
2499
|
sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
|
|
2225
2500
|
res += "<text id=\"text#{id}\" " +
|
|
2226
2501
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2227
2502
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2228
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2229
|
-
"y=\"#{(ic.ypos + ic.height/2.0 + sy)*@scale}\">" +
|
|
2503
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2504
|
+
"y=\"#{((ic.ypos + ic.height/2.0 + sy)*@scale).round(3)}\">" +
|
|
2230
2505
|
ic.name + "</text>\n"
|
|
2231
2506
|
# Its text resizing.
|
|
2232
|
-
res += Viz.svg_text_fit("text#{id}",
|
|
2233
|
-
|
|
2507
|
+
res += Viz.svg_text_fit("text#{id}",
|
|
2508
|
+
((ic.width-0.6)*@scale).round(3),
|
|
2509
|
+
(0.6*@scale).round(3))
|
|
2234
2510
|
return res
|
|
2235
2511
|
end
|
|
2236
2512
|
|
|
2237
2513
|
# Generate a process description SVG text for +ic+
|
|
2238
2514
|
def process_svg(ic)
|
|
2239
|
-
id = Viz.to_svg_id(ic.name)
|
|
2515
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2516
|
+
id = ic.__id__.to_s
|
|
2240
2517
|
res = "<rect id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
|
|
2241
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2242
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2243
|
-
"rx=\"#{@scale}\" " +
|
|
2244
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2245
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2518
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2519
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2520
|
+
"rx=\"#{@scale.round(3)}\" " +
|
|
2521
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2522
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2246
2523
|
# Its name.
|
|
2247
2524
|
sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
|
|
2248
2525
|
res += "<text id=\"text#{id}\" " +
|
|
2249
2526
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2250
2527
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2251
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2252
|
-
"y=\"#{(ic.ypos + ic.height/2.0 + sy)*@scale}\">" +
|
|
2528
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2529
|
+
"y=\"#{((ic.ypos + ic.height/2.0 + sy)*@scale).round(3)}\">" +
|
|
2253
2530
|
ic.name + "</text>\n"
|
|
2254
2531
|
# Its text resizing.
|
|
2255
2532
|
res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
|
|
@@ -2259,26 +2536,27 @@ module HDLRuby::Viz
|
|
|
2259
2536
|
|
|
2260
2537
|
# Generate a clocked process description SVG text for +ic+
|
|
2261
2538
|
def clocked_process_svg(ic)
|
|
2262
|
-
id = Viz.to_svg_id(ic.name)
|
|
2539
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2540
|
+
id = ic.__id__.to_s
|
|
2263
2541
|
res = "<rect fill=\"#ddd\" stroke=\"#000\" " +
|
|
2264
|
-
"stroke-width=\"#{@scale/32.0}\" " +
|
|
2265
|
-
"x=\"#{(ic.xpos-1/16.0)*@scale}\" y=\"#{(ic.ypos-1/16.0)*@scale}\" " +
|
|
2266
|
-
"rx=\"#{(1+1/16.0)*@scale}\" " +
|
|
2267
|
-
"width=\"#{(ic.width+1/8.0)*@scale}\" "+
|
|
2268
|
-
"height=\"#{(ic.height+1/8.0)*@scale}\"/>\n"
|
|
2542
|
+
"stroke-width=\"#{(@scale/32.0).round(3)}\" " +
|
|
2543
|
+
"x=\"#{((ic.xpos-1/16.0)*@scale).round(3)}\" y=\"#{((ic.ypos-1/16.0)*@scale).round(3)}\" " +
|
|
2544
|
+
"rx=\"#{((1+1/16.0)*@scale).round(3)}\" " +
|
|
2545
|
+
"width=\"#{((ic.width+1/8.0)*@scale).round(3)}\" "+
|
|
2546
|
+
"height=\"#{((ic.height+1/8.0)*@scale).round(3)}\"/>\n"
|
|
2269
2547
|
res += "<rect id=\"#{id}\" fill=\"#ddd\" stroke=\"#000\" " +
|
|
2270
|
-
"stroke-width=\"#{@scale/32.0}\" " +
|
|
2271
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2272
|
-
"rx=\"#{@scale}\" " +
|
|
2273
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2274
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2548
|
+
"stroke-width=\"#{(@scale/32.0).round(3)}\" " +
|
|
2549
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2550
|
+
"rx=\"#{@scale.round(3)}\" " +
|
|
2551
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2552
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2275
2553
|
# Its name.
|
|
2276
2554
|
sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
|
|
2277
2555
|
res += "<text id=\"text#{id}\" " +
|
|
2278
2556
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2279
2557
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2280
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2281
|
-
"y=\"#{(ic.ypos + ic.height/2.0 + sy)*@scale}\">" +
|
|
2558
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2559
|
+
"y=\"#{((ic.ypos + ic.height/2.0 + sy)*@scale).round(3)}\">" +
|
|
2282
2560
|
ic.name + "</text>\n"
|
|
2283
2561
|
# Its text resizing.
|
|
2284
2562
|
res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
|
|
@@ -2288,20 +2566,21 @@ module HDLRuby::Viz
|
|
|
2288
2566
|
|
|
2289
2567
|
# Generate a timed process description SVG text for +ic+
|
|
2290
2568
|
def timed_process_svg(ic)
|
|
2291
|
-
id = Viz.to_svg_id(ic.name)
|
|
2569
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2570
|
+
id = ic.__id__.to_s
|
|
2292
2571
|
res = "<rect id=\"#{id}\" fill=\"#bbb\" stroke=\"#000\" " +
|
|
2293
|
-
"stroke-width=\"#{@scale/8.0}\" " +
|
|
2294
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2295
|
-
"rx=\"#{@scale}\" " +
|
|
2296
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2297
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2572
|
+
"stroke-width=\"#{(@scale/8.0).round(3)}\" " +
|
|
2573
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2574
|
+
"rx=\"#{@scale.round(3)}\" " +
|
|
2575
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2576
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2298
2577
|
# Its name.
|
|
2299
2578
|
sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
|
|
2300
2579
|
res += "<text id=\"text#{id}\" " +
|
|
2301
2580
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2302
2581
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2303
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2304
|
-
"y=\"#{(ic.ypos + ic.height/2.0 + sy)*@scale}\">" +
|
|
2582
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2583
|
+
"y=\"#{((ic.ypos + ic.height/2.0 + sy)*@scale).round(3)}\">" +
|
|
2305
2584
|
ic.name + "</text>\n"
|
|
2306
2585
|
# Its text resizing.
|
|
2307
2586
|
res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
|
|
@@ -2311,20 +2590,21 @@ module HDLRuby::Viz
|
|
|
2311
2590
|
|
|
2312
2591
|
# Generate a register description SVG text for +ic+
|
|
2313
2592
|
def register_svg(ic)
|
|
2314
|
-
id = Viz.to_svg_id(ic.name)
|
|
2593
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2594
|
+
id = ic.__id__.to_s
|
|
2315
2595
|
res = "<rect id=\"#{id}\" fill=\"#fff\" stroke=\"#000\" " +
|
|
2316
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2317
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2318
|
-
"rx=\"#{@scale/4}\" " +
|
|
2319
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2320
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2596
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2597
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2598
|
+
"rx=\"#{(@scale/4).round(3)}\" " +
|
|
2599
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2600
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2321
2601
|
# Its name.
|
|
2322
2602
|
sy = (ic.lports.size <= 2 or ic.lports.size.even?) ? 0 : -0.5 # Shift to avoid ports (Note: register prots are symetrics, so check left only).
|
|
2323
2603
|
res += "<text id=\"text#{id}\" " +
|
|
2324
2604
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2325
2605
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2326
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2327
|
-
"y=\"#{(ic.ypos + ic.height/2.0+sy)*@scale}\">" +
|
|
2606
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2607
|
+
"y=\"#{((ic.ypos + ic.height/2.0+sy)*@scale).round(3)}\">" +
|
|
2328
2608
|
ic.name + "</text>\n"
|
|
2329
2609
|
# Its text resizing.
|
|
2330
2610
|
res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
|
|
@@ -2334,37 +2614,38 @@ module HDLRuby::Viz
|
|
|
2334
2614
|
|
|
2335
2615
|
# Generate a memory description SVG text for +ic+
|
|
2336
2616
|
def memory_svg(ic)
|
|
2337
|
-
id = Viz.to_svg_id(ic.name)
|
|
2617
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2618
|
+
id = ic.__id__.to_s
|
|
2338
2619
|
res = "<rect id=\"#{id}\" fill=\"#fff\" stroke=\"#000\" " +
|
|
2339
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2340
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
2341
|
-
"rx=\"#{@scale/4}\" " +
|
|
2342
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
2343
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
2620
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2621
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
2622
|
+
"rx=\"#{(@scale/4).round(3)}\" " +
|
|
2623
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
2624
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
2344
2625
|
res += "<rect fill=\"#fff\" stroke=\"#333\" " +
|
|
2345
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2346
|
-
"x=\"#{(ic.xpos+1/4.0)*@scale}\" "+
|
|
2347
|
-
"y=\"#{(ic.ypos+1/4.0)*@scale}\" " +
|
|
2348
|
-
"width=\"#{(ic.width-1/2.0)*@scale}\" "+
|
|
2349
|
-
"height=\"#{(ic.height-1/2.0)*@scale}\"/>\n"
|
|
2626
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2627
|
+
"x=\"#{((ic.xpos+1/4.0)*@scale).round(3)}\" "+
|
|
2628
|
+
"y=\"#{((ic.ypos+1/4.0)*@scale).round(3)}\" " +
|
|
2629
|
+
"width=\"#{((ic.width-1/2.0)*@scale).round(3)}\" "+
|
|
2630
|
+
"height=\"#{((ic.height-1/2.0)*@scale).round(3)}\"/>\n"
|
|
2350
2631
|
res += "<line stroke=\"#333\" " +
|
|
2351
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2352
|
-
"x1=\"#{(ic.xpos+1/4.0+1/8.0)*@scale}\" "+
|
|
2353
|
-
"y1=\"#{(ic.ypos+1/4.0)*@scale}\" " +
|
|
2354
|
-
"x2=\"#{(ic.xpos+1/4.0+1/8.0)*@scale}\" "+
|
|
2355
|
-
"y2=\"#{(ic.ypos+ic.height-1/4.0)*@scale}\"/>\n"
|
|
2632
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2633
|
+
"x1=\"#{((ic.xpos+1/4.0+1/8.0)*@scale).round(3)}\" "+
|
|
2634
|
+
"y1=\"#{((ic.ypos+1/4.0)*@scale).round(3)}\" " +
|
|
2635
|
+
"x2=\"#{((ic.xpos+1/4.0+1/8.0)*@scale).round(3)}\" "+
|
|
2636
|
+
"y2=\"#{((ic.ypos+ic.height-1/4.0)*@scale).round(3)}\"/>\n"
|
|
2356
2637
|
res += "<line stroke=\"#333\" " +
|
|
2357
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2358
|
-
"x1=\"#{(ic.xpos+1/4.0)*@scale}\" "+
|
|
2359
|
-
"y1=\"#{(ic.ypos+1/4.0+1/8.0)*@scale}\" " +
|
|
2360
|
-
"x2=\"#{(ic.xpos+ic.width-1/4.0)*@scale}\" "+
|
|
2361
|
-
"y2=\"#{(ic.ypos+1/4.0+1/8.0)*@scale}\"/>\n"
|
|
2638
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2639
|
+
"x1=\"#{((ic.xpos+1/4.0)*@scale).round(3)}\" "+
|
|
2640
|
+
"y1=\"#{((ic.ypos+1/4.0+1/8.0)*@scale).round(3)}\" " +
|
|
2641
|
+
"x2=\"#{((ic.xpos+ic.width-1/4.0)*@scale).round(3)}\" "+
|
|
2642
|
+
"y2=\"#{((ic.ypos+1/4.0+1/8.0)*@scale).round(3)}\"/>\n"
|
|
2362
2643
|
# Its name.
|
|
2363
2644
|
res += "<text id=\"text#{id}\" " +
|
|
2364
2645
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2365
2646
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2366
|
-
"x=\"#{(ic.xpos + ic.width/2.0 + 1/10.0)*@scale}\" "+
|
|
2367
|
-
"y=\"#{(ic.ypos + ic.height/2.0)*@scale}\">" +
|
|
2647
|
+
"x=\"#{((ic.xpos + ic.width/2.0 + 1/10.0)*@scale).round(3)}\" "+
|
|
2648
|
+
"y=\"#{((ic.ypos + ic.height/2.0)*@scale).round(3)}\">" +
|
|
2368
2649
|
ic.name + "</text>\n"
|
|
2369
2650
|
# Its text resizing.
|
|
2370
2651
|
res += Viz.svg_text_fit("text#{id}",(ic.width-1.0)*@scale,
|
|
@@ -2374,17 +2655,30 @@ module HDLRuby::Viz
|
|
|
2374
2655
|
|
|
2375
2656
|
# Generate an ALU description SVG text for +ic+
|
|
2376
2657
|
def alu_svg(ic)
|
|
2377
|
-
id = Viz.to_svg_id(ic.name)
|
|
2658
|
+
# id = Viz.to_svg_id(ic.name)
|
|
2659
|
+
id = ic.__id__.to_s
|
|
2378
2660
|
# Determine the side of the inputs (and consequently of the outputs),
|
|
2379
2661
|
# and the number of inputs.
|
|
2380
|
-
iside =
|
|
2662
|
+
iside = nil
|
|
2381
2663
|
inum = 0
|
|
2382
2664
|
ic.ports.each do |port|
|
|
2383
2665
|
if port.direction == :input then
|
|
2384
2666
|
iside = port.side
|
|
2385
2667
|
inum += 1
|
|
2668
|
+
elsif port.direction == :output then
|
|
2669
|
+
case port.side
|
|
2670
|
+
when LEFT
|
|
2671
|
+
iside = RIGHT
|
|
2672
|
+
when RIGHT
|
|
2673
|
+
iside = LEFT
|
|
2674
|
+
when UP
|
|
2675
|
+
iside = DOWN
|
|
2676
|
+
when DOWN
|
|
2677
|
+
iside = UP
|
|
2678
|
+
end
|
|
2386
2679
|
end
|
|
2387
2680
|
end
|
|
2681
|
+
raise "Connection with no port for #{ic.name}" unless iside
|
|
2388
2682
|
# NOTE: inum is zero in case of a constant, force at least 1.
|
|
2389
2683
|
inum = 1 if inum < 1
|
|
2390
2684
|
# The length of a leg
|
|
@@ -2395,80 +2689,72 @@ module HDLRuby::Viz
|
|
|
2395
2689
|
end
|
|
2396
2690
|
# Generate the resulting polygon.
|
|
2397
2691
|
res = "<polygon id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
|
|
2398
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2692
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2399
2693
|
"points=\""
|
|
2400
2694
|
# The result depends on the size of the input.
|
|
2401
2695
|
case(iside)
|
|
2402
2696
|
when LEFT
|
|
2403
2697
|
# The left side
|
|
2404
|
-
res += "#{ic.xpos*@scale} #{(ic.ypos)*@scale} "
|
|
2698
|
+
res += "#{(ic.xpos*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2405
2699
|
(inum-1).times do |i|
|
|
2406
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+i*leg+0.25)*@scale} "
|
|
2407
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+(i+1)*leg-0.25)*@scale} "
|
|
2408
|
-
res += "#{(ic.xpos+0.25)*@scale} #{(ic.ypos+(i+1)*leg)*@scale} "
|
|
2409
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+(i+1)*leg+0.25)*@scale} "
|
|
2700
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+i*leg+0.25)*@scale).round(3)} "
|
|
2701
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+(i+1)*leg-0.25)*@scale).round(3)} "
|
|
2702
|
+
res += "#{((ic.xpos+0.25)*@scale).round(3)} #{((ic.ypos+(i+1)*leg)*@scale).round(3)} "
|
|
2703
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+(i+1)*leg+0.25)*@scale).round(3)} "
|
|
2410
2704
|
end
|
|
2411
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+inum*leg)*@scale} "
|
|
2705
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+inum*leg)*@scale).round(3)} "
|
|
2412
2706
|
# The up side
|
|
2413
|
-
|
|
2414
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+ic.height*0.7)*@scale} "
|
|
2707
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+ic.height*0.7)*@scale).round(3)} "
|
|
2415
2708
|
# The right side.
|
|
2416
|
-
|
|
2417
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+ic.height*0.3)*@scale}"
|
|
2709
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+ic.height*0.3)*@scale).round(3)}"
|
|
2418
2710
|
# The down side is not necessary, close the shape.
|
|
2419
2711
|
res += "\"/>"
|
|
2420
2712
|
when UP
|
|
2421
2713
|
# The right side
|
|
2422
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2714
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2423
2715
|
(inum-1).times do |i|
|
|
2424
|
-
res += "#{(ic.xpos+i*leg+0.25)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2425
|
-
res += "#{(ic.xpos+(i+1)*leg-0.25)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2426
|
-
res += "#{(ic.xpos+(i+1)*leg)*@scale} #{(ic.ypos-0.25+ic.height)*@scale} "
|
|
2427
|
-
res += "#{(ic.xpos+(i+1)*leg+0.25)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2716
|
+
res += "#{((ic.xpos+i*leg+0.25)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2717
|
+
res += "#{((ic.xpos+(i+1)*leg-0.25)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2718
|
+
res += "#{((ic.xpos+(i+1)*leg)*@scale).round(3)} #{((ic.ypos-0.25+ic.height)*@scale).round(3)} "
|
|
2719
|
+
res += "#{((ic.xpos+(i+1)*leg+0.25)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2428
2720
|
end
|
|
2429
|
-
res += "#{(ic.xpos+inum*leg)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2721
|
+
res += "#{((ic.xpos+inum*leg)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2430
2722
|
# The up side
|
|
2431
|
-
|
|
2432
|
-
res += "#{(ic.xpos+ic.width*0.7)*@scale} #{(ic.ypos)*@scale} "
|
|
2723
|
+
res += "#{((ic.xpos+ic.width*0.7)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2433
2724
|
# The right side.
|
|
2434
|
-
|
|
2435
|
-
res += "#{(ic.xpos+ic.width*0.3)*@scale} #{(ic.ypos)*@scale}"
|
|
2725
|
+
res += "#{((ic.xpos+ic.width*0.3)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)}"
|
|
2436
2726
|
# The down side is not necessary, close the shape.
|
|
2437
2727
|
res += "\"/>"
|
|
2438
2728
|
when RIGHT
|
|
2439
2729
|
# The right side
|
|
2440
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos)*@scale} "
|
|
2730
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2441
2731
|
(inum-1).times do |i|
|
|
2442
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+i*leg+0.25)*@scale} "
|
|
2443
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+(i+1)*leg-0.25)*@scale} "
|
|
2444
|
-
res += "#{(ic.xpos-0.25+ic.width)*@scale} #{(ic.ypos+(i+1)*leg)*@scale} "
|
|
2445
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+(i+1)*leg+0.25)*@scale} "
|
|
2732
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+i*leg+0.25)*@scale).round(3)} "
|
|
2733
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+(i+1)*leg-0.25)*@scale).round(3)} "
|
|
2734
|
+
res += "#{((ic.xpos-0.25+ic.width)*@scale).round(3)} #{((ic.ypos+(i+1)*leg)*@scale).round(3)} "
|
|
2735
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+(i+1)*leg+0.25)*@scale).round(3)} "
|
|
2446
2736
|
end
|
|
2447
|
-
res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+inum*leg)*@scale} "
|
|
2737
|
+
res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos+inum*leg)*@scale).round(3)} "
|
|
2448
2738
|
# The up side
|
|
2449
|
-
|
|
2450
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+ic.height*0.7)*@scale} "
|
|
2739
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+ic.height*0.7)*@scale).round(3)} "
|
|
2451
2740
|
# The right side.
|
|
2452
|
-
|
|
2453
|
-
res += "#{(ic.xpos)*@scale} #{(ic.ypos+ic.height*0.3)*@scale}"
|
|
2741
|
+
res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+ic.height*0.3)*@scale).round(3)}"
|
|
2454
2742
|
# The down side is not necessary, close the shape.
|
|
2455
2743
|
res += "\"/>"
|
|
2456
2744
|
when DOWN
|
|
2457
2745
|
# The down side
|
|
2458
|
-
res += "#{ic.xpos*@scale} #{(ic.ypos)*@scale} "
|
|
2746
|
+
res += "#{(ic.xpos*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2459
2747
|
(inum-1).times do |i|
|
|
2460
|
-
res += "#{(ic.xpos+i*leg+0.25)*@scale} #{(ic.ypos)*@scale} "
|
|
2461
|
-
res += "#{(ic.xpos+(i+1)*leg-0.25)*@scale} #{(ic.ypos)*@scale} "
|
|
2462
|
-
res += "#{(ic.xpos+(i+1)*leg)*@scale} #{(ic.ypos+0.25)*@scale} "
|
|
2463
|
-
res += "#{(ic.xpos+(i+1)*leg+0.25)*@scale} #{(ic.ypos)*@scale} "
|
|
2748
|
+
res += "#{((ic.xpos+i*leg+0.25)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2749
|
+
res += "#{((ic.xpos+(i+1)*leg-0.25)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2750
|
+
res += "#{((ic.xpos+(i+1)*leg)*@scale).round(3)} #{((ic.ypos+0.25)*@scale).round(3)} "
|
|
2751
|
+
res += "#{((ic.xpos+(i+1)*leg+0.25)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2464
2752
|
end
|
|
2465
|
-
res += "#{(ic.xpos+inum*leg)*@scale} #{(ic.ypos)*@scale} "
|
|
2753
|
+
res += "#{((ic.xpos+inum*leg)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
|
|
2466
2754
|
# The up side
|
|
2467
|
-
|
|
2468
|
-
res += "#{(ic.xpos+ic.width*0.7)*@scale} #{(ic.ypos+ic.height)*@scale} "
|
|
2755
|
+
res += "#{((ic.xpos+ic.width*0.7)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
|
|
2469
2756
|
# The right side.
|
|
2470
|
-
|
|
2471
|
-
res += "#{(ic.xpos+ic.width*0.3)*@scale} #{(ic.ypos+ic.height)*@scale}"
|
|
2757
|
+
res += "#{((ic.xpos+ic.width*0.3)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)}"
|
|
2472
2758
|
# The down side is not necessary, close the shape.
|
|
2473
2759
|
res += "\"/>"
|
|
2474
2760
|
else
|
|
@@ -2480,8 +2766,8 @@ module HDLRuby::Viz
|
|
|
2480
2766
|
res += "<text id=\"text#{id}\" " +
|
|
2481
2767
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
2482
2768
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
2483
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
2484
|
-
"y=\"#{(ic.ypos + ic.height/2.0 + sy)*@scale}\">" +
|
|
2769
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
2770
|
+
"y=\"#{((ic.ypos + ic.height/2.0 + sy)*@scale).round(3)}\">" +
|
|
2485
2771
|
ic.name + "</text>\n"
|
|
2486
2772
|
# Its text resizing.
|
|
2487
2773
|
res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
|
|
@@ -2498,15 +2784,17 @@ module HDLRuby::Viz
|
|
|
2498
2784
|
res = "<rect fill=\"#88f\" stroke=\"#000\" "
|
|
2499
2785
|
when :negedge
|
|
2500
2786
|
res = "<rect fill=\"#f88\" stroke=\"#000\" "
|
|
2787
|
+
when :anyedge
|
|
2788
|
+
res = "<rect fill=\"#888\" stroke=\"#000\" "
|
|
2501
2789
|
else
|
|
2502
2790
|
res = "<rect fill=\"#ff0\" stroke=\"#000\" "
|
|
2503
2791
|
end
|
|
2504
|
-
res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2505
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2506
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2792
|
+
res += "x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2793
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2794
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2507
2795
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2508
|
-
"points=\"#{xpos},#{ypos+height/2.0} #{xpos+width},#{ypos} " +
|
|
2509
|
-
"#{xpos+width},#{ypos+height}\"/>\n"
|
|
2796
|
+
"points=\"#{xpos.round(3)},#{(ypos+height/2.0).round(3)} #{(xpos+width).round(3)},#{ypos.round(3)} " +
|
|
2797
|
+
"#{(xpos+width).round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2510
2798
|
return res
|
|
2511
2799
|
end
|
|
2512
2800
|
|
|
@@ -2517,30 +2805,32 @@ module HDLRuby::Viz
|
|
|
2517
2805
|
res = "<rect fill=\"#88f\" stroke=\"#000\" "
|
|
2518
2806
|
when :negedge
|
|
2519
2807
|
res = "<rect fill=\"#f88\" stroke=\"#000\" "
|
|
2808
|
+
when :anyedge
|
|
2809
|
+
res = "<rect fill=\"#888\" stroke=\"#000\" "
|
|
2520
2810
|
else
|
|
2521
2811
|
res = "<rect fill=\"#ff0\" stroke=\"#000\" "
|
|
2522
2812
|
end
|
|
2523
|
-
res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2524
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2525
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2813
|
+
res += "x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2814
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2815
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2526
2816
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2527
|
-
"points=\"#{xpos},#{ypos} #{xpos+width},#{ypos+height/2.0} " +
|
|
2528
|
-
"#{xpos},#{ypos+height}\"/>\n"
|
|
2817
|
+
"points=\"#{xpos.round(3)},#{ypos.round(3)} #{(xpos+width).round(3)},#{(ypos+height/2.0).round(3)} " +
|
|
2818
|
+
"#{xpos.round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2529
2819
|
return res
|
|
2530
2820
|
end
|
|
2531
2821
|
|
|
2532
2822
|
# Generate a left-right port description SVG text.
|
|
2533
2823
|
def left_right_port_svg(name,type,xpos,ypos,width,height)
|
|
2534
2824
|
res = "<rect fill=\"#FF0\" stroke=\"#000\" " +
|
|
2535
|
-
"x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2825
|
+
"x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2536
2826
|
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2537
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2827
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2538
2828
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2539
|
-
"points=\"#{xpos},#{ypos+height/2} #{xpos+width},#{ypos} " +
|
|
2540
|
-
"#{xpos+width},#{ypos+height}\"/>\n"
|
|
2829
|
+
"points=\"#{xpos.round(3)},#{(ypos+height/2).round(3)} #{(xpos+width).round(3)},#{ypos.round(3)} " +
|
|
2830
|
+
"#{(xpos+width).round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2541
2831
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2542
|
-
"points=\"#{xpos},#{ypos} #{xpos+width},#{ypos+height/2.0} " +
|
|
2543
|
-
"#{xpos},#{ypos+height}\"/>\n"
|
|
2832
|
+
"points=\"#{xpos.round(3)},#{ypos.round(3)} #{(xpos+width).round(3)},#{(ypos+height/2.0).round(3)} " +
|
|
2833
|
+
"#{xpos.round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2544
2834
|
return res
|
|
2545
2835
|
end
|
|
2546
2836
|
|
|
@@ -2551,15 +2841,17 @@ module HDLRuby::Viz
|
|
|
2551
2841
|
res = "<rect fill=\"#88f\" stroke=\"#000\" "
|
|
2552
2842
|
when :negedge
|
|
2553
2843
|
res = "<rect fill=\"#f88\" stroke=\"#000\" "
|
|
2844
|
+
when :anyedge
|
|
2845
|
+
res = "<rect fill=\"#888\" stroke=\"#000\" "
|
|
2554
2846
|
else
|
|
2555
2847
|
res = "<rect fill=\"#ff0\" stroke=\"#000\" "
|
|
2556
2848
|
end
|
|
2557
|
-
res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2558
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2559
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2849
|
+
res += "x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2850
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2851
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2560
2852
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2561
|
-
"points=\"#{xpos},#{ypos} #{xpos+width/2.0},#{ypos+height} " +
|
|
2562
|
-
"#{xpos+width},#{ypos}\"/>\n"
|
|
2853
|
+
"points=\"#{xpos.round(3)},#{ypos.round(3)} #{(xpos+width/2.0).round(3)},#{(ypos+height).round(3)} " +
|
|
2854
|
+
"#{(xpos+width).round(3)},#{ypos.round(3)}\"/>\n"
|
|
2563
2855
|
return res
|
|
2564
2856
|
end
|
|
2565
2857
|
|
|
@@ -2570,30 +2862,32 @@ module HDLRuby::Viz
|
|
|
2570
2862
|
res = "<rect fill=\"#88f\" stroke=\"#000\" "
|
|
2571
2863
|
when :negedge
|
|
2572
2864
|
res = "<rect fill=\"#f88\" stroke=\"#000\" "
|
|
2865
|
+
when :anyedge
|
|
2866
|
+
res = "<rect fill=\"#888\" stroke=\"#000\" "
|
|
2573
2867
|
else
|
|
2574
2868
|
res = "<rect fill=\"#ff0\" stroke=\"#000\" "
|
|
2575
2869
|
end
|
|
2576
|
-
res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2577
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2578
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2870
|
+
res += "x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2871
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2872
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2579
2873
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2580
|
-
"points=\"#{xpos+width/2.0},#{ypos} #{xpos},#{ypos+height} " +
|
|
2581
|
-
"#{xpos+width},#{ypos+height}\"/>\n"
|
|
2874
|
+
"points=\"#{(xpos+width/2.0).round(3)},#{ypos.round(3)} #{xpos.round(3)},#{(ypos+height).round(3)} " +
|
|
2875
|
+
"#{(xpos+width).round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2582
2876
|
return res
|
|
2583
2877
|
end
|
|
2584
2878
|
|
|
2585
2879
|
# Generate an up-down port description SVG text.
|
|
2586
2880
|
def up_down_port_svg(name,type,xpos,ypos,width,height)
|
|
2587
2881
|
res = "<rect fill=\"#FF0\" stroke=\"#000\" " +
|
|
2588
|
-
"x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
2589
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
2590
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2882
|
+
"x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
2883
|
+
"stroke-width=\"#{(@scale/16.0).round(3)}\" " +
|
|
2884
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
2591
2885
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2592
|
-
"points=\"#{xpos},#{ypos} #{xpos+width/2},#{ypos+height} " +
|
|
2593
|
-
"#{xpos+width},#{ypos}\"/>\n"
|
|
2886
|
+
"points=\"#{xpos.round(3)},#{ypos.round(3)} #{(xpos+width/2).round(3)},#{(ypos+height).round(3)} " +
|
|
2887
|
+
"#{(xpos+width).round(3)},#{ypos.round(3)}\"/>\n"
|
|
2594
2888
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
2595
|
-
"points=\"#{xpos+width/2.0},#{ypos} #{xpos},#{ypos+height} " +
|
|
2596
|
-
"#{xpos+width},#{ypos+height}\"/>\n"
|
|
2889
|
+
"points=\"#{(xpos+width/2.0).round(3)},#{ypos.round(3)} #{xpos.round(3)},#{(ypos+height).round(3)} " +
|
|
2890
|
+
"#{(xpos+width).round(3)},#{(ypos+height).round(3)}\"/>\n"
|
|
2597
2891
|
return res
|
|
2598
2892
|
end
|
|
2599
2893
|
|
|
@@ -2605,15 +2899,22 @@ module HDLRuby::Viz
|
|
|
2605
2899
|
# Generate the string representing a port for display in the SVG
|
|
2606
2900
|
def port_str(port)
|
|
2607
2901
|
# Generate the port name (strip everything before the last ".")
|
|
2608
|
-
name = port.name.sub(/^.*\./,"")
|
|
2902
|
+
# name = port.name.sub(/^.*\./,"")
|
|
2903
|
+
name = port.name.split(/(?<!\.)\.(?!\.)/).last
|
|
2609
2904
|
# Strip the suffix $I and $O
|
|
2610
2905
|
name = name.sub(/\$(I|O)$/,"")
|
|
2906
|
+
# For registers' bit ports, only keep the bit number.
|
|
2907
|
+
if port.ic.type==:register and HDLRuby::Viz.port_bit_name?(name) then
|
|
2908
|
+
name = HDLRuby::Viz.port_bit_name(name)
|
|
2909
|
+
end
|
|
2611
2910
|
# Add a suffix for edge properties.
|
|
2612
2911
|
case port.type
|
|
2613
2912
|
when :posedge
|
|
2614
2913
|
return name + " \u2197"
|
|
2615
2914
|
when :negedge
|
|
2616
2915
|
return name + " \u2198"
|
|
2916
|
+
when :anyedge
|
|
2917
|
+
return name + " \u2195"
|
|
2617
2918
|
else
|
|
2618
2919
|
return name
|
|
2619
2920
|
end
|
|
@@ -2660,23 +2961,28 @@ module HDLRuby::Viz
|
|
|
2660
2961
|
# Sets the styles.
|
|
2661
2962
|
res += "<style>\n"
|
|
2662
2963
|
# Fonts
|
|
2663
|
-
res += ".small#{self.idC} { font: #{sF}px sans-serif; }\n"
|
|
2964
|
+
res += ".small#{self.idC} { font: #{sF}px sans-serif; " # }\n" # +
|
|
2965
|
+
res += "stroke=\"yellow\"; stroke-width=\"6\"; paint-order=\"stroke fill;\" }\n"
|
|
2966
|
+
# "border: 2px solid black; padding: 10px; display: inline-block; " +
|
|
2967
|
+
# " background-color: rgba(0, 128, 255, 0.2); }\n"
|
|
2664
2968
|
res += ".medium#{self.idC} { font: #{mF}px sans-serif; }\n"
|
|
2665
2969
|
res += ".large#{self.idC} { font: #{lF}px sans-serif; }\n"
|
|
2666
2970
|
res += "</style>\n"
|
|
2667
2971
|
|
|
2668
2972
|
# Generate the group containing all the IC description.
|
|
2669
|
-
res += "<g id=\"#{self.name}\" visibility=\"#{visibility}\" " +
|
|
2973
|
+
# res += "<g id=\"#{self.name}\" visibility=\"#{visibility}\" " +
|
|
2974
|
+
# "transform=\"translate(#{tx},#{ty})\">\n"
|
|
2975
|
+
res += "<g id=\"#{self.__id__}\" visibility=\"#{visibility}\" " +
|
|
2670
2976
|
"transform=\"translate(#{tx},#{ty})\">\n"
|
|
2671
2977
|
# Generate the rectangle of the bounding box.
|
|
2672
2978
|
res += "<rect fill=\"#bbb\" stroke=\"#555\" " +
|
|
2673
|
-
"stroke-width=\"#{@scale/4.0}\" " +
|
|
2979
|
+
"stroke-width=\"#{(@scale/4.0).round(3)}\" " +
|
|
2674
2980
|
# "x=\"#{x0-bT*2.5}\" y=\"#{y0-bT*2.5}\" "+
|
|
2675
|
-
"x=\"#{x0}\" y=\"#{y0}\" "+
|
|
2981
|
+
"x=\"#{x0.round(3)}\" y=\"#{y0.round(3)}\" "+
|
|
2676
2982
|
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
2677
2983
|
|
|
2678
2984
|
# Generate the group containing the top system and its contents.
|
|
2679
|
-
res += "<g transform=\"translate(#{stx},#{sty})\">\n"
|
|
2985
|
+
res += "<g transform=\"translate(#{stx.round(3)},#{sty.round(3)})\">\n"
|
|
2680
2986
|
|
|
2681
2987
|
# Generate current IC's box.
|
|
2682
2988
|
# The SVG object representing a system.
|
|
@@ -2687,9 +2993,9 @@ module HDLRuby::Viz
|
|
|
2687
2993
|
row.each_with_index do |tile,x|
|
|
2688
2994
|
# # Draw the tiles contour for debug.
|
|
2689
2995
|
# res += "<rect fill=\"none\" stroke=\"#00F\" " +
|
|
2690
|
-
# "x=\"#{x*@scale}\" " +
|
|
2691
|
-
# "y=\"#{y*@scale}\" " +
|
|
2692
|
-
# "width=\"#{@scale}\" height=\"#{@scale}\"/>\n"
|
|
2996
|
+
# "x=\"#{(x*@scale).round(3)}\" " +
|
|
2997
|
+
# "y=\"#{(y*@scale).round(3)}\" " +
|
|
2998
|
+
# "width=\"#{@scale.round(3)}\" height=\"#{@scale.round(3)}\"/>\n"
|
|
2693
2999
|
#
|
|
2694
3000
|
# Draw the wires.
|
|
2695
3001
|
tile.wires.each do |wire_dir|
|
|
@@ -2697,69 +3003,69 @@ module HDLRuby::Viz
|
|
|
2697
3003
|
# Draw the wire (as a thin rectangle).
|
|
2698
3004
|
case wire_dir
|
|
2699
3005
|
when LEFT|RIGHT
|
|
2700
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3006
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2701
3007
|
"stroke-linecap=\"round\" " +
|
|
2702
|
-
"x1=\"#{(x)*@scale}\" " +
|
|
2703
|
-
"y1=\"#{(y+0.5)*@scale}\" " +
|
|
2704
|
-
"x2=\"#{(x+1)*@scale}\" " +
|
|
2705
|
-
"y2=\"#{(y+0.5)*@scale}\" />\n"
|
|
3008
|
+
"x1=\"#{((x)*@scale).round(3)}\" " +
|
|
3009
|
+
"y1=\"#{((y+0.5)*@scale).round(3)}\" " +
|
|
3010
|
+
"x2=\"#{((x+1)*@scale).round(3)}\" " +
|
|
3011
|
+
"y2=\"#{((y+0.5)*@scale).round(3)}\" />\n"
|
|
2706
3012
|
when RIGHT|DOWN
|
|
2707
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3013
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2708
3014
|
"stroke-linecap=\"round\" " +
|
|
2709
|
-
"x1=\"#{(x+1)*@scale}\" " +
|
|
2710
|
-
"y1=\"#{(y+0.5)*@scale}\" " +
|
|
2711
|
-
"x2=\"#{(x+0.5)*@scale}\" " +
|
|
2712
|
-
"y2=\"#{(y)*@scale}\" />\n"
|
|
3015
|
+
"x1=\"#{((x+1)*@scale).round(3)}\" " +
|
|
3016
|
+
"y1=\"#{((y+0.5)*@scale).round(3)}\" " +
|
|
3017
|
+
"x2=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3018
|
+
"y2=\"#{((y)*@scale).round(3)}\" />\n"
|
|
2713
3019
|
when RIGHT|UP
|
|
2714
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3020
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2715
3021
|
"stroke-linecap=\"round\" " +
|
|
2716
|
-
"x1=\"#{(x+1)*@scale}\" " +
|
|
2717
|
-
"y1=\"#{(y+0.5)*@scale}\" " +
|
|
2718
|
-
"x2=\"#{(x+0.5)*@scale}\" " +
|
|
2719
|
-
"y2=\"#{(y+1)*@scale}\" />\n"
|
|
3022
|
+
"x1=\"#{((x+1)*@scale).round(3)}\" " +
|
|
3023
|
+
"y1=\"#{((y+0.5)*@scale).round(3)}\" " +
|
|
3024
|
+
"x2=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3025
|
+
"y2=\"#{((y+1)*@scale).round(3)}\" />\n"
|
|
2720
3026
|
when LEFT|DOWN
|
|
2721
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3027
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2722
3028
|
"stroke-linecap=\"round\" " +
|
|
2723
|
-
"x1=\"#{(x+0.5)*@scale}\" " +
|
|
2724
|
-
"y1=\"#{(y)*@scale}\" " +
|
|
2725
|
-
"x2=\"#{(x)*@scale}\" " +
|
|
2726
|
-
"y2=\"#{(y+0.5)*@scale}\" />\n"
|
|
3029
|
+
"x1=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3030
|
+
"y1=\"#{((y)*@scale).round(3)}\" " +
|
|
3031
|
+
"x2=\"#{((x)*@scale).round(3)}\" " +
|
|
3032
|
+
"y2=\"#{((y+0.5)*@scale).round(3)}\" />\n"
|
|
2727
3033
|
when LEFT|UP
|
|
2728
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3034
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2729
3035
|
"stroke-linecap=\"round\" " +
|
|
2730
|
-
"x1=\"#{(x+0.5)*@scale}\" " +
|
|
2731
|
-
"y1=\"#{(y+1)*@scale}\" " +
|
|
2732
|
-
"x2=\"#{(x)*@scale}\" " +
|
|
2733
|
-
"y2=\"#{(y+0.5)*@scale}\" />\n"
|
|
3036
|
+
"x1=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3037
|
+
"y1=\"#{((y+1)*@scale).round(3)}\" " +
|
|
3038
|
+
"x2=\"#{((x)*@scale).round(3)}\" " +
|
|
3039
|
+
"y2=\"#{((y+0.5)*@scale).round(3)}\" />\n"
|
|
2734
3040
|
when UP|DOWN
|
|
2735
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
|
|
3041
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
|
|
2736
3042
|
"stroke-linecap=\"round\" " +
|
|
2737
|
-
"x1=\"#{(x+0.5)*@scale}\" " +
|
|
2738
|
-
"y1=\"#{(y)*@scale}\" " +
|
|
2739
|
-
"x2=\"#{(x+0.5)*@scale}\" " +
|
|
2740
|
-
"y2=\"#{(y+1)*@scale}\" />\n"
|
|
3043
|
+
"x1=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3044
|
+
"y1=\"#{((y)*@scale).round(3)}\" " +
|
|
3045
|
+
"x2=\"#{((x+0.5)*@scale).round(3)}\" " +
|
|
3046
|
+
"y2=\"#{((y+1)*@scale).round(3)}\" />\n"
|
|
2741
3047
|
end
|
|
2742
3048
|
end
|
|
2743
3049
|
|
|
2744
3050
|
# Draw the connection points.
|
|
2745
3051
|
tile.dots.each do |dot_pos|
|
|
2746
3052
|
res += "<rect fill=\"#000\" stroke=\"#000\" " +
|
|
2747
|
-
|
|
3053
|
+
"stroke-width=\"#{wT.round(3)}\" "
|
|
2748
3054
|
case dot_pos
|
|
2749
3055
|
when LEFT
|
|
2750
|
-
res += "x=\"#{(x+0.0)*@scale-wT*2}\" " +
|
|
2751
|
-
"y=\"#{(y+0.5)*@scale-wT*2}\" "
|
|
3056
|
+
res += "x=\"#{((x+0.0)*@scale-wT*2).round(3)}\" " +
|
|
3057
|
+
"y=\"#{((y+0.5)*@scale-wT*2).round(3)}\" "
|
|
2752
3058
|
when UP
|
|
2753
|
-
res += "x=\"#{(x+0.5)*@scale-wT*2}\" " +
|
|
2754
|
-
"y=\"#{(y+1.0)*@scale-wT*2}\" "
|
|
3059
|
+
res += "x=\"#{((x+0.5)*@scale-wT*2).round(3)}\" " +
|
|
3060
|
+
"y=\"#{((y+1.0)*@scale-wT*2).round(3)}\" "
|
|
2755
3061
|
when RIGHT
|
|
2756
|
-
res += "x=\"#{(x+1.0)*@scale-wT*2}\" " +
|
|
2757
|
-
"y=\"#{(y+0.5)*@scale-wT*2}\" "
|
|
3062
|
+
res += "x=\"#{((x+1.0)*@scale-wT*2).round(3)}\" " +
|
|
3063
|
+
"y=\"#{((y+0.5)*@scale-wT*2).round(3)}\" "
|
|
2758
3064
|
when DOWN
|
|
2759
|
-
res += "x=\"#{(x+0.5)*@scale-wT*2}\" " +
|
|
2760
|
-
"y=\"#{(y+0.0)*@scale-wT*2}\" "
|
|
3065
|
+
res += "x=\"#{((x+0.5)*@scale-wT*2).round(3)}\" " +
|
|
3066
|
+
"y=\"#{((y+0.0)*@scale-wT*2).round(3)}\" "
|
|
2761
3067
|
end
|
|
2762
|
-
res += "width=\"#{wT*4}\" height=\"#{wT*4}\"/>\n"
|
|
3068
|
+
res += "width=\"#{(wT*4).round(3)}\" height=\"#{(wT*4).round(3)}\"/>\n"
|
|
2763
3069
|
end
|
|
2764
3070
|
end
|
|
2765
3071
|
end
|
|
@@ -2817,12 +3123,20 @@ module HDLRuby::Viz
|
|
|
2817
3123
|
port.direction != :none) or child.sub_port?(port) then
|
|
2818
3124
|
if child == self then
|
|
2819
3125
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
|
|
2820
|
-
"x=\"#{(port.xpos)*@scale-pT}\" "+
|
|
2821
|
-
"y=\"#{(port.ypos+0.5)*@scale+sF/2.5}\">" +
|
|
3126
|
+
"x=\"#{((port.xpos)*@scale-pT).round(3)}\" "+
|
|
3127
|
+
"y=\"#{((port.ypos+0.5)*@scale+sF/2.5).round(3)}\">" +
|
|
3128
|
+
self.port_str(port) + "</text>\n"
|
|
3129
|
+
elsif (child.type == :assign and port.direction == :input and
|
|
3130
|
+
child.ports.size.even? and child.ports.index(port) == child.ports.size/2) then
|
|
3131
|
+
# Middle input of an alu, slide it bellow to avoid collision
|
|
3132
|
+
# with the output port.
|
|
3133
|
+
res += "<text class=\"small#{self.idC}\" x=\"#{((port.xpos)*@scale+pT).round(3)}\" "+
|
|
3134
|
+
"y=\"#{((port.ypos+0.8)*@scale+sF/2.5).round(3)}\">" +
|
|
2822
3135
|
self.port_str(port) + "</text>\n"
|
|
2823
3136
|
else
|
|
2824
|
-
|
|
2825
|
-
|
|
3137
|
+
# General case.
|
|
3138
|
+
res += "<text class=\"small#{self.idC}\" x=\"#{((port.xpos)*@scale+pT).round(3)}\" "+
|
|
3139
|
+
"y=\"#{((port.ypos+0.45)*@scale+sF/2.5).round(3)}\">" +
|
|
2826
3140
|
self.port_str(port) + "</text>\n"
|
|
2827
3141
|
end
|
|
2828
3142
|
end
|
|
@@ -2850,13 +3164,13 @@ module HDLRuby::Viz
|
|
|
2850
3164
|
port.direction != :none) or child.sub_port?(port) then
|
|
2851
3165
|
if child == self then
|
|
2852
3166
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
|
|
2853
|
-
"x=\"#{(port.xpos+0.5)*@scale}\" "+
|
|
2854
|
-
"y=\"#{(port.ypos+1.0)*@scale+pT+sF/2}\">" + # port.name +
|
|
3167
|
+
"x=\"#{((port.xpos+0.5)*@scale).round(3)}\" "+
|
|
3168
|
+
"y=\"#{((port.ypos+1.0)*@scale+pT+sF/2).round(3)}\">" + # port.name +
|
|
2855
3169
|
self.port_str(port) + "</text>\n"
|
|
2856
3170
|
else
|
|
2857
3171
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
|
|
2858
|
-
"x=\"#{(port.xpos+0.5)*@scale}\" "+
|
|
2859
|
-
"y=\"#{(port.ypos+1.0)*@scale-pT}\">" + # port.name +
|
|
3172
|
+
"x=\"#{((port.xpos+0.5)*@scale).round(3)}\" "+
|
|
3173
|
+
"y=\"#{((port.ypos+1.0)*@scale-pT).round(3)}\">" + # port.name +
|
|
2860
3174
|
self.port_str(port) + "</text>\n"
|
|
2861
3175
|
end
|
|
2862
3176
|
end
|
|
@@ -2883,13 +3197,21 @@ module HDLRuby::Viz
|
|
|
2883
3197
|
port.direction != :none) or child.sub_port?(port) then
|
|
2884
3198
|
if child == self then
|
|
2885
3199
|
res += "<text class=\"small#{self.idC}\" " +
|
|
2886
|
-
"x=\"#{(port.xpos+1)*@scale+pT}\" " +
|
|
2887
|
-
"y=\"#{(port.ypos+0.5)*@scale+sF/2.5}\">" + # port.name +
|
|
3200
|
+
"x=\"#{((port.xpos+1)*@scale+pT).round(3)}\" " +
|
|
3201
|
+
"y=\"#{((port.ypos+0.5)*@scale+sF/2.5).round(3)}\">" + # port.name +
|
|
3202
|
+
self.port_str(port) + "</text>\n"
|
|
3203
|
+
elsif (child.type == :assign and port.direction == :input and
|
|
3204
|
+
child.ports.size.even? and child.ports.index(port) == child.ports.size/2) then
|
|
3205
|
+
# Middle input of an alu, slide it bellow to avoid collision
|
|
3206
|
+
# with the output port.
|
|
3207
|
+
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
|
|
3208
|
+
"x=\"#{((port.xpos+1)*@scale-pT).round(3)}\" "+
|
|
3209
|
+
"y=\"#{((port.ypos+0.8)*@scale+sF/2.5).round(3)}\">" + # port.name +
|
|
2888
3210
|
self.port_str(port) + "</text>\n"
|
|
2889
3211
|
else
|
|
2890
3212
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
|
|
2891
|
-
"x=\"#{(port.xpos+1)*@scale-pT}\" "+
|
|
2892
|
-
"y=\"#{(port.ypos+0.
|
|
3213
|
+
"x=\"#{((port.xpos+1)*@scale-pT).round(3)}\" "+
|
|
3214
|
+
"y=\"#{((port.ypos+0.45)*@scale+sF/2.5).round(3)}\">" + # port.name +
|
|
2893
3215
|
self.port_str(port) + "</text>\n"
|
|
2894
3216
|
end
|
|
2895
3217
|
end
|
|
@@ -2916,14 +3238,13 @@ module HDLRuby::Viz
|
|
|
2916
3238
|
port.direction != :none) or child.sub_port?(port) then
|
|
2917
3239
|
if child == self then
|
|
2918
3240
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
|
|
2919
|
-
"x=\"#{(port.xpos+0.5)*@scale}\" "+
|
|
2920
|
-
"y=\"#{(port.ypos)*@scale-pT}\">" + # port.name +
|
|
3241
|
+
"x=\"#{((port.xpos+0.5)*@scale).round(3)}\" "+
|
|
3242
|
+
"y=\"#{((port.ypos)*@scale-pT).round(3)}\">" + # port.name +
|
|
2921
3243
|
self.port_str(port) + "</text>\n"
|
|
2922
3244
|
else
|
|
2923
3245
|
res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
|
|
2924
|
-
"x=\"#{(port.xpos+0.5)*@scale}\" "+
|
|
2925
|
-
|
|
2926
|
-
"y=\"#{(port.ypos)*@scale+pT+sF/2.0}\">" + # port.name +
|
|
3246
|
+
"x=\"#{((port.xpos+0.5)*@scale).round(3)}\" "+
|
|
3247
|
+
"y=\"#{((port.ypos)*@scale+pT+sF/2.0).round(3)}\">" + # port.name +
|
|
2927
3248
|
self.port_str(port) + "</text>\n"
|
|
2928
3249
|
end
|
|
2929
3250
|
end
|
|
@@ -2973,14 +3294,15 @@ module HDLRuby::Viz
|
|
|
2973
3294
|
cty += 1
|
|
2974
3295
|
end
|
|
2975
3296
|
end
|
|
2976
|
-
# Leave a space for left or right ports if any.
|
|
2977
|
-
sl = child.ports.any? {|p| p.side == LEFT } ? 1.0 : 0.0
|
|
2978
|
-
sr = child.ports.any? {|p| p.side == RIGHT } ? 1.0 : 0.0
|
|
3297
|
+
# # Leave a space for left or right ports if any.
|
|
3298
|
+
# sl = (child.ports.any? {|p| p.side == LEFT }) ? 1.0 : 0.0
|
|
3299
|
+
# sr = (child.ports.any? {|p| p.side == RIGHT }) ? 1.0 : 0.0
|
|
2979
3300
|
# Recompute the scale.
|
|
2980
3301
|
fit = [
|
|
2981
|
-
(target.width+sl+sr+(bT/@scale)) / (cwidth),
|
|
2982
|
-
(target.
|
|
2983
|
-
|
|
3302
|
+
# (target.width+sl+sr+(bT/@scale/2.0)) / (cwidth),
|
|
3303
|
+
(target.width+(bT/@scale/2.0)) / (cwidth),
|
|
3304
|
+
(target.height+(bT/@scale/2.0)) / (cheight),
|
|
3305
|
+
1.0# 3.0
|
|
2984
3306
|
].max
|
|
2985
3307
|
target.scale = @scale / fit
|
|
2986
3308
|
puts "fit=#{fit} target.scale=#{target.scale}"
|
|
@@ -2988,7 +3310,8 @@ module HDLRuby::Viz
|
|
|
2988
3310
|
res += target.to_svg(false,ctx*@scale,cty*@scale,
|
|
2989
3311
|
cwidth*scale,cheight*scale)
|
|
2990
3312
|
# Generate the closing button element.
|
|
2991
|
-
res += Viz.closing_svg(target.name + '_close',pT,(ctx+cwidth)*@scale-pT,cty*@scale)
|
|
3313
|
+
# res += Viz.closing_svg(target.name + '_close',pT,(ctx+cwidth)*@scale-pT,cty*@scale)
|
|
3314
|
+
res += Viz.closing_svg(target.__id__.to_s + '_close',pT,(ctx+cwidth)*@scale-pT,cty*@scale)
|
|
2992
3315
|
end
|
|
2993
3316
|
|
|
2994
3317
|
# Close the group containing the top system and its content.
|
|
@@ -3012,20 +3335,20 @@ module HDLRuby::Viz
|
|
|
3012
3335
|
next unless target # No target? Skip.
|
|
3013
3336
|
res += <<~SCRIPT
|
|
3014
3337
|
<script>
|
|
3015
|
-
diagram.getElementById('#{child.
|
|
3338
|
+
diagram.getElementById('#{child.__id__}').addEventListener("click", (e) => {
|
|
3016
3339
|
// For the element.
|
|
3017
|
-
let elem = diagram.getElementById('#{target.
|
|
3340
|
+
let elem = diagram.getElementById('#{target.__id__}');
|
|
3018
3341
|
elem.setAttribute('visibility','visible');
|
|
3019
3342
|
// And its closing button.
|
|
3020
|
-
elem = diagram.getElementById('#{target.
|
|
3343
|
+
elem = diagram.getElementById('#{target.__id__}_close');
|
|
3021
3344
|
elem.setAttribute('visibility','visible');
|
|
3022
3345
|
});
|
|
3023
|
-
diagram.getElementById('#{target.
|
|
3346
|
+
diagram.getElementById('#{target.__id__}_close').addEventListener("click", (e) => {
|
|
3024
3347
|
// For the element.
|
|
3025
|
-
let elem = diagram.getElementById('#{target.
|
|
3348
|
+
let elem = diagram.getElementById('#{target.__id__}');
|
|
3026
3349
|
elem.setAttribute('visibility','hidden');
|
|
3027
3350
|
// And its closing button.
|
|
3028
|
-
elem = diagram.getElementById('#{target.
|
|
3351
|
+
elem = diagram.getElementById('#{target.__id__}_close');
|
|
3029
3352
|
elem.setAttribute('visibility','hidden');
|
|
3030
3353
|
});
|
|
3031
3354
|
|
|
@@ -3550,27 +3873,22 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3550
3873
|
def assign_svg(n)
|
|
3551
3874
|
# The shape representing the instance.
|
|
3552
3875
|
res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
|
|
3553
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
# "#{(n.xpos + n.width-n.height/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3559
|
-
# "L #{(n.xpos + 1.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3560
|
-
"d=\"M #{n.xpos*@scale} #{(n.ypos + n.height)*@scale} " +
|
|
3561
|
-
"L #{(n.xpos + 1.0)*@scale} #{n.ypos*@scale} " +
|
|
3562
|
-
"L #{(n.xpos + n.width)*@scale} #{n.ypos*@scale} " +
|
|
3563
|
-
"L #{(n.xpos + n.width-1.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3876
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
3877
|
+
"d=\"M #{(n.xpos*@scale).round(3)} #{((n.ypos + n.height)*@scale).round(3)} " +
|
|
3878
|
+
"L #{((n.xpos + 1.0)*@scale).round(3)} #{(n.ypos*@scale).round(3)} " +
|
|
3879
|
+
"L #{((n.xpos + n.width)*@scale).round(3)} #{(n.ypos*@scale).round(3)} " +
|
|
3880
|
+
"L #{((n.xpos + n.width-1.0)*@scale).round(3)} #{((n.ypos+n.height)*@scale).round(3)} " +
|
|
3564
3881
|
"Z \" />\n"
|
|
3565
3882
|
# Its text.
|
|
3566
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
3883
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
3884
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3567
3885
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3568
3886
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3569
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
|
|
3570
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
3887
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" "+
|
|
3888
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3571
3889
|
n.to_s + "</text>\n"
|
|
3572
3890
|
# Its text resizing.
|
|
3573
|
-
res += Viz.svg_text_fit("text#{n.
|
|
3891
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-2)*@scale,
|
|
3574
3892
|
0.6*@scale)
|
|
3575
3893
|
return res
|
|
3576
3894
|
end
|
|
@@ -3578,35 +3896,12 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3578
3896
|
# Generate a block description SVG text for node +n+
|
|
3579
3897
|
def block_svg(n)
|
|
3580
3898
|
res = "<rect fill=\"#fff\" fill-opacity=\"0.4\" stroke=\"#000\" " +
|
|
3581
|
-
"stroke-width=\"#{@scale/10.0}\" " +
|
|
3582
|
-
"stroke-dasharray=\"#{@scale/10.0},#{@scale/10.0}\" " +
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
"x=\"#{(n.xpos-0.3)*@scale}\" y=\"#{(n.ypos-0.3)*@scale}\" " +
|
|
3588
|
-
"rx=\"#{@scale*0.6}\" " +
|
|
3589
|
-
"width=\"#{(n.width+0.6)*@scale}\" "+
|
|
3590
|
-
"height=\"#{(n.height+0.6)*@scale}\"/>\n"
|
|
3591
|
-
return res
|
|
3592
|
-
end
|
|
3593
|
-
|
|
3594
|
-
# Generate an operator description SVG text for node +n+
|
|
3595
|
-
def operator_svg(n)
|
|
3596
|
-
ICIICI
|
|
3597
|
-
res = "<rect fill=\"#eee\" stroke=\"#000\" " +
|
|
3598
|
-
"stroke-width=\"#{@scale/16.0}\" " +
|
|
3599
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
3600
|
-
"rx=\"#{@scale}\" " +
|
|
3601
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
3602
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
3603
|
-
# Its name.
|
|
3604
|
-
res += "<text class=\"medium#{self.idC}\" " +
|
|
3605
|
-
"style=\"inline-size=#{ic.width*@scale}px; text-anchor: middle; " +
|
|
3606
|
-
"dominant-baseline: middle;\" " +
|
|
3607
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
3608
|
-
"y=\"#{(ic.ypos + ic.height/2.0)*@scale}\">" +
|
|
3609
|
-
ic.name + "</text>\n"
|
|
3899
|
+
"stroke-width=\"#{(@scale/10.0).round(3)}\" " +
|
|
3900
|
+
"stroke-dasharray=\"#{(@scale/10.0).round(3)},#{(@scale/10.0).round(3)}\" " +
|
|
3901
|
+
"x=\"#{((n.xpos-0.3)*@scale).round(3)}\" y=\"#{((n.ypos-0.3)*@scale).round(3)}\" " +
|
|
3902
|
+
"rx=\"#{(@scale*0.6).round(3)}\" " +
|
|
3903
|
+
"width=\"#{((n.width+0.6)*@scale).round(3)}\" "+
|
|
3904
|
+
"height=\"#{((n.height+0.6)*@scale).round(3)}\"/>\n"
|
|
3610
3905
|
return res
|
|
3611
3906
|
end
|
|
3612
3907
|
|
|
@@ -3614,23 +3909,23 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3614
3909
|
def terminal_svg(n)
|
|
3615
3910
|
ICIICI
|
|
3616
3911
|
res = "<rect fill=\"#ddd\" stroke=\"#000\" " +
|
|
3617
|
-
"stroke-width=\"#{@scale/32.0}\" " +
|
|
3618
|
-
"x=\"#{(ic.xpos-1/16.0)*@scale}\" y=\"#{(ic.ypos-1/16.0)*@scale}\" " +
|
|
3619
|
-
"rx=\"#{(1+1/16.0)*@scale}\" " +
|
|
3620
|
-
"width=\"#{(ic.width+1/8.0)*@scale}\" "+
|
|
3621
|
-
"height=\"#{(ic.height+1/8.0)*@scale}\"/>\n"
|
|
3912
|
+
"stroke-width=\"#{(@scale/32.0).round(3)}\" " +
|
|
3913
|
+
"x=\"#{((ic.xpos-1/16.0)*@scale).round(3)}\" y=\"#{((ic.ypos-1/16.0)*@scale).round(3)}\" " +
|
|
3914
|
+
"rx=\"#{((1+1/16.0)*@scale).round(3)}\" " +
|
|
3915
|
+
"width=\"#{((ic.width+1/8.0)*@scale).round(3)}\" "+
|
|
3916
|
+
"height=\"#{((ic.height+1/8.0)*@scale).round(3)}\"/>\n"
|
|
3622
3917
|
res += "<rect fill=\"#ddd\" stroke=\"#000\" " +
|
|
3623
|
-
"stroke-width=\"#{@scale/32.0}\" " +
|
|
3624
|
-
"x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
|
|
3625
|
-
"rx=\"#{@scale}\" " +
|
|
3626
|
-
"width=\"#{ic.width*@scale}\" "+
|
|
3627
|
-
"height=\"#{ic.height*@scale}\"/>\n"
|
|
3918
|
+
"stroke-width=\"#{(@scale/32.0).round(3)}\" " +
|
|
3919
|
+
"x=\"#{(ic.xpos*@scale).round(3)}\" y=\"#{(ic.ypos*@scale).round(3)}\" " +
|
|
3920
|
+
"rx=\"#{@scale.round(3)}\" " +
|
|
3921
|
+
"width=\"#{(ic.width*@scale).round(3)}\" "+
|
|
3922
|
+
"height=\"#{(ic.height*@scale).round(3)}\"/>\n"
|
|
3628
3923
|
# Its name.
|
|
3629
3924
|
res += "<text class=\"medium#{self.idC}\" " +
|
|
3630
3925
|
"style=\"inline-size=#{ic.width*@scale}px; text-anchor: middle; " +
|
|
3631
3926
|
"dominant-baseline: middle;\" " +
|
|
3632
|
-
"x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
|
|
3633
|
-
"y=\"#{(ic.ypos + ic.height/2.0)*@scale}\">" +
|
|
3927
|
+
"x=\"#{((ic.xpos + ic.width/2.0)*@scale).round(3)}\" "+
|
|
3928
|
+
"y=\"#{((ic.ypos + ic.height/2.0)*@scale).round(3)}\">" +
|
|
3634
3929
|
ic.name + "</text>\n"
|
|
3635
3930
|
return res
|
|
3636
3931
|
end
|
|
@@ -3640,36 +3935,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3640
3935
|
def if_svg(n,no=false)
|
|
3641
3936
|
# The shape representing the instance.
|
|
3642
3937
|
res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
|
|
3643
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3644
|
-
"d=\"M #{(n.xpos)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
|
|
3645
|
-
"L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3646
|
-
"L #{(n.xpos+n.width)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
|
|
3647
|
-
"L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos)*@scale} " +
|
|
3938
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
3939
|
+
"d=\"M #{((n.xpos)*@scale).round(3)} #{((n.ypos+n.height/2.0)*@scale).round(3)} " +
|
|
3940
|
+
"L #{((n.xpos+n.width/2.0)*@scale).round(3)} #{((n.ypos+n.height)*@scale).round(3)} " +
|
|
3941
|
+
"L #{((n.xpos+n.width)*@scale).round(3)} #{((n.ypos+n.height/2.0)*@scale).round(3)} " +
|
|
3942
|
+
"L #{((n.xpos+n.width/2.0)*@scale).round(3)} #{((n.ypos)*@scale).round(3)} " +
|
|
3648
3943
|
"Z \" />\n"
|
|
3649
3944
|
# Its text.
|
|
3650
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
3945
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
3946
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3651
3947
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3652
3948
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3653
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
|
|
3654
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
3949
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" "+
|
|
3950
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3655
3951
|
n.to_s + "</text>\n"
|
|
3656
3952
|
# Its text resizing.
|
|
3657
|
-
res += Viz.svg_text_fit("text#{n.name}",(n.width-3)*@scale,
|
|
3953
|
+
# res += Viz.svg_text_fit("text#{n.name}",(n.width-3)*@scale,
|
|
3954
|
+
# 0.6*@scale)
|
|
3955
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-3)*@scale,
|
|
3658
3956
|
0.6*@scale)
|
|
3659
3957
|
# The yes text.
|
|
3660
3958
|
res += "<text " +
|
|
3661
3959
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3662
|
-
"font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
|
|
3663
|
-
"x=\"#{(n.xpos + n.width+0.1)*@scale}\" "+
|
|
3664
|
-
"y=\"#{(n.ypos + n.height/2.0+0.5)*@scale}\">" +
|
|
3960
|
+
"font-family=\"monospace\" font-size=\"#{(@scale/2.0).round(3)}px\" " +
|
|
3961
|
+
"x=\"#{((n.xpos + n.width+0.1)*@scale).round(3)}\" "+
|
|
3962
|
+
"y=\"#{((n.ypos + n.height/2.0+0.5)*@scale).round(3)}\">" +
|
|
3665
3963
|
"Yes" + "</text>\n"
|
|
3666
3964
|
# The no text if any.
|
|
3667
3965
|
if no then
|
|
3668
3966
|
res += "<text " +
|
|
3669
3967
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3670
|
-
"font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
|
|
3671
|
-
"x=\"#{(n.xpos + n.width/2.0+0.7)*@scale}\" "+
|
|
3672
|
-
"y=\"#{(n.ypos + n.height+0.3)*@scale}\">" +
|
|
3968
|
+
"font-family=\"monospace\" font-size=\"#{(@scale/2.0).round(3)}px\" " +
|
|
3969
|
+
"x=\"#{((n.xpos + n.width/2.0+0.7)*@scale).round(3)}\" "+
|
|
3970
|
+
"y=\"#{((n.ypos + n.height+0.3)*@scale).round(3)}\">" +
|
|
3673
3971
|
"No" + "</text>\n"
|
|
3674
3972
|
end
|
|
3675
3973
|
return res
|
|
@@ -3680,36 +3978,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3680
3978
|
def case_svg(n,no=false)
|
|
3681
3979
|
# The shape representing the instance.
|
|
3682
3980
|
res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
|
|
3683
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3684
|
-
"d=\"M #{(n.xpos)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
|
|
3685
|
-
"L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3686
|
-
"L #{(n.xpos+n.width)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
|
|
3687
|
-
"L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos)*@scale} " +
|
|
3981
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
3982
|
+
"d=\"M #{((n.xpos)*@scale).round(3)} #{((n.ypos+n.height/2.0)*@scale).round(3)} " +
|
|
3983
|
+
"L #{((n.xpos+n.width/2.0)*@scale).round(3)} #{((n.ypos+n.height)*@scale).round(3)} " +
|
|
3984
|
+
"L #{((n.xpos+n.width)*@scale).round(3)} #{((n.ypos+n.height/2.0)*@scale).round(3)} " +
|
|
3985
|
+
"L #{((n.xpos+n.width/2.0)*@scale).round(3)} #{((n.ypos)*@scale).round(3)} " +
|
|
3688
3986
|
"Z \" />\n"
|
|
3689
3987
|
# Its text.
|
|
3690
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
3988
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
3989
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3691
3990
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3692
3991
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3693
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
|
|
3694
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
3992
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" "+
|
|
3993
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3695
3994
|
n.to_s + "</text>\n"
|
|
3696
3995
|
# Its text resizing.
|
|
3697
|
-
res += Viz.svg_text_fit("text#{n.name}",(n.width-3)*@scale,
|
|
3996
|
+
# res += Viz.svg_text_fit("text#{n.name}",(n.width-3)*@scale,
|
|
3997
|
+
# 0.6*@scale)
|
|
3998
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-3)*@scale,
|
|
3698
3999
|
0.6*@scale)
|
|
3699
4000
|
# The yes text.
|
|
3700
4001
|
res += "<text " +
|
|
3701
4002
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3702
|
-
"font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
|
|
3703
|
-
"x=\"#{(n.xpos + n.width+0.1)*@scale}\" "+
|
|
3704
|
-
"y=\"#{(n.ypos + n.height/2.0+0.5)*@scale}\">" +
|
|
4003
|
+
"font-family=\"monospace\" font-size=\"#{(@scale/2.0).round(3)}px\" " +
|
|
4004
|
+
"x=\"#{((n.xpos + n.width+0.1)*@scale).round(3)}\" "+
|
|
4005
|
+
"y=\"#{((n.ypos + n.height/2.0+0.5)*@scale).round(3)}\">" +
|
|
3705
4006
|
"Yes" + "</text>\n"
|
|
3706
4007
|
# The no text if any.
|
|
3707
4008
|
if no then
|
|
3708
4009
|
res += "<text " +
|
|
3709
4010
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3710
|
-
"font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
|
|
3711
|
-
"x=\"#{(n.xpos + n.width/2.0+0.7)*@scale}\" "+
|
|
3712
|
-
"y=\"#{(n.ypos + n.height+0.3)*@scale}\">" +
|
|
4011
|
+
"font-family=\"monospace\" font-size=\"#{(@scale/2.0).round(3)}px\" " +
|
|
4012
|
+
"x=\"#{((n.xpos + n.width/2.0+0.7)*@scale).round(3)}\" "+
|
|
4013
|
+
"y=\"#{((n.ypos + n.height+0.3)*@scale).round(3)}\">" +
|
|
3713
4014
|
"No" + "</text>\n"
|
|
3714
4015
|
end
|
|
3715
4016
|
return res
|
|
@@ -3719,22 +4020,25 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3719
4020
|
def wait_svg(n)
|
|
3720
4021
|
# The shape representing the instance.
|
|
3721
4022
|
res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
|
|
3722
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3723
|
-
"d=\"M #{n.xpos*@scale} #{(n.ypos)*@scale} " +
|
|
3724
|
-
"L #{(n.xpos + n.width-n.height/2.0)*@scale} #{n.ypos*@scale} " +
|
|
3725
|
-
"A #{n.height/2.0*@scale} #{n.height/2.0*@scale} 0 0 1 " +
|
|
3726
|
-
"#{(n.xpos + n.width-n.height/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
3727
|
-
"L #{(n.xpos)*@scale} #{(n.ypos+n.height)*@scale} " +
|
|
4023
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
4024
|
+
"d=\"M #{(n.xpos*@scale).round(3)} #{((n.ypos)*@scale).round(3)} " +
|
|
4025
|
+
"L #{((n.xpos + n.width-n.height/2.0)*@scale).round(3)} #{(n.ypos*@scale).round(3)} " +
|
|
4026
|
+
"A #{(n.height/2.0*@scale).round(3)} #{(n.height/2.0*@scale).round(3)} 0 0 1 " +
|
|
4027
|
+
"#{((n.xpos + n.width-n.height/2.0)*@scale).round(3)} #{((n.ypos+n.height)*@scale).round(3)} " +
|
|
4028
|
+
"L #{((n.xpos)*@scale).round(3)} #{((n.ypos+n.height)*@scale).round(3)} " +
|
|
3728
4029
|
"Z \" />\n"
|
|
3729
4030
|
# Its text.
|
|
3730
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
4031
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
4032
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3731
4033
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3732
4034
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3733
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
|
|
3734
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
4035
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" "+
|
|
4036
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3735
4037
|
n.to_s + "</text>\n"
|
|
3736
4038
|
# Its text resizing.
|
|
3737
|
-
res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4039
|
+
# res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4040
|
+
# 0.6*@scale)
|
|
4041
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-1)*@scale,
|
|
3738
4042
|
0.6*@scale)
|
|
3739
4043
|
return res
|
|
3740
4044
|
end
|
|
@@ -3749,21 +4053,24 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3749
4053
|
def terminate_svg(n)
|
|
3750
4054
|
# The shape representing the instance.
|
|
3751
4055
|
res = "<ellipse fill=\"#CC0202\" stroke=\"#000\" " +
|
|
3752
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3753
|
-
"cx=\"#{n.xpos*@scale+n.width*@scale/2.0}\" " +
|
|
3754
|
-
"cy=\"#{(n.ypos)*@scale+n.height*@scale/2.0}\" " +
|
|
3755
|
-
"rx=\"#{n.width*@scale/2.0}\" ry=\"#{n.height*@scale/2.0}\" " +
|
|
4056
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
4057
|
+
"cx=\"#{(n.xpos*@scale+n.width*@scale/2.0).round(3)}\" " +
|
|
4058
|
+
"cy=\"#{((n.ypos)*@scale+n.height*@scale/2.0).round(3)}\" " +
|
|
4059
|
+
"rx=\"#{(n.width*@scale/2.0).round(3)}\" ry=\"#{(n.height*@scale/2.0).round(3)}\" " +
|
|
3756
4060
|
"/>\n"
|
|
3757
4061
|
# Its text.
|
|
3758
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
4062
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
4063
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3759
4064
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3760
4065
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3761
4066
|
"fill=\"white\" " +
|
|
3762
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" " +
|
|
3763
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
4067
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" " +
|
|
4068
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3764
4069
|
"Terminate" + "</text>\n"
|
|
3765
4070
|
# Its text resizing.
|
|
3766
|
-
res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4071
|
+
# res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4072
|
+
# 0.6*@scale)
|
|
4073
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-1)*@scale,
|
|
3767
4074
|
0.6*@scale)
|
|
3768
4075
|
return res
|
|
3769
4076
|
end
|
|
@@ -3772,19 +4079,22 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3772
4079
|
def print_svg(n)
|
|
3773
4080
|
# The shape representing the instance.
|
|
3774
4081
|
res = "<rect fill=\"#B0E2FF\" stroke=\"#000\" " +
|
|
3775
|
-
"stroke-width=\"#{@scale/12.0}\" " +
|
|
3776
|
-
"x=\"#{n.xpos*@scale}\" y=\"#{(n.ypos)*@scale}\" " +
|
|
3777
|
-
"width=\"#{n.width*@scale}\" height=\"#{n.height*@scale}\" " +
|
|
4082
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" " +
|
|
4083
|
+
"x=\"#{(n.xpos*@scale).round(3)}\" y=\"#{((n.ypos)*@scale).round(3)}\" " +
|
|
4084
|
+
"width=\"#{(n.width*@scale).round(3)}\" height=\"#{(n.height*@scale).round(3)}\" " +
|
|
3778
4085
|
"/>\n"
|
|
3779
4086
|
# Its text.
|
|
3780
|
-
res += "<text id=\"text#{n.name}\" " +
|
|
4087
|
+
# res += "<text id=\"text#{n.name}\" " +
|
|
4088
|
+
res += "<text id=\"text#{n.__id__}\" " +
|
|
3781
4089
|
"style=\"text-anchor: middle; dominant-baseline: middle;\" " +
|
|
3782
4090
|
"font-family=\"monospace\" font-size=\"1px\" " +
|
|
3783
|
-
"x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
|
|
3784
|
-
"y=\"#{(n.ypos + n.height/2.0)*@scale}\">" +
|
|
4091
|
+
"x=\"#{((n.xpos + n.width/2.0)*@scale).round(3)}\" "+
|
|
4092
|
+
"y=\"#{((n.ypos + n.height/2.0)*@scale).round(3)}\">" +
|
|
3785
4093
|
n.to_s + "</text>\n"
|
|
3786
4094
|
# Its text resizing.
|
|
3787
|
-
res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4095
|
+
# res += Viz.svg_text_fit("text#{n.name}",(n.width-1)*@scale,
|
|
4096
|
+
# 0.6*@scale)
|
|
4097
|
+
res += Viz.svg_text_fit("text#{n.__id__}",(n.width-1)*@scale,
|
|
3788
4098
|
0.6*@scale)
|
|
3789
4099
|
return res
|
|
3790
4100
|
end
|
|
@@ -3795,39 +4105,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3795
4105
|
# Draw the line.
|
|
3796
4106
|
# Vertical part
|
|
3797
4107
|
res = "<line stroke=\"#000\" " +
|
|
3798
|
-
"stroke-width=\"#{@scale/12.0}\" stroke-linecap=\"round\" " +
|
|
3799
|
-
"x1=\"#{x0*@scale}\" " +
|
|
3800
|
-
"y1=\"#{y0*@scale}\" " +
|
|
3801
|
-
"x2=\"#{x0*@scale}\" " +
|
|
3802
|
-
"y2=\"#{y1*@scale}\" " +
|
|
4108
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" stroke-linecap=\"round\" " +
|
|
4109
|
+
"x1=\"#{(x0*@scale).round(3)}\" " +
|
|
4110
|
+
"y1=\"#{(y0*@scale).round(3)}\" " +
|
|
4111
|
+
"x2=\"#{(x0*@scale).round(3)}\" " +
|
|
4112
|
+
"y2=\"#{(y1*@scale).round(3)}\" " +
|
|
3803
4113
|
"/>\n"
|
|
3804
4114
|
# Horizontal part
|
|
3805
4115
|
res += "<line stroke=\"#000\" " +
|
|
3806
|
-
"stroke-width=\"#{@scale/12.0}\" stroke-linecap=\"round\" " +
|
|
3807
|
-
"x1=\"#{x0*@scale}\" " +
|
|
3808
|
-
"y1=\"#{y1*@scale}\" " +
|
|
3809
|
-
"x2=\"#{x1*@scale}\" " +
|
|
3810
|
-
"y2=\"#{y1*@scale}\" " +
|
|
4116
|
+
"stroke-width=\"#{(@scale/12.0).round(3)}\" stroke-linecap=\"round\" " +
|
|
4117
|
+
"x1=\"#{(x0*@scale).round(3)}\" " +
|
|
4118
|
+
"y1=\"#{(y1*@scale).round(3)}\" " +
|
|
4119
|
+
"x2=\"#{(x1*@scale).round(3)}\" " +
|
|
4120
|
+
"y2=\"#{(y1*@scale).round(3)}\" " +
|
|
3811
4121
|
"/>\n"
|
|
3812
4122
|
# The head.
|
|
3813
4123
|
if x0 == x1 then
|
|
3814
4124
|
# Vertical case
|
|
3815
4125
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
3816
|
-
"points=\"#{(x1-1/4.0)*@scale},#{(y1-1/2.0-1/8.0)*@scale} " +
|
|
3817
|
-
"#{(x1+1/4.0)*@scale},#{(y1-1/2.0-1/8.0)*@scale} " +
|
|
3818
|
-
"#{(x1)*@scale},#{(y1)*@scale}\"/>\n"
|
|
4126
|
+
"points=\"#{((x1-1/4.0)*@scale).round(3)},#{((y1-1/2.0-1/8.0)*@scale).round(3)} " +
|
|
4127
|
+
"#{((x1+1/4.0)*@scale).round(3)},#{((y1-1/2.0-1/8.0)*@scale).round(3)} " +
|
|
4128
|
+
"#{((x1)*@scale).round(3)},#{((y1)*@scale).round(3)}\"/>\n"
|
|
3819
4129
|
elsif x0 < x1 then
|
|
3820
4130
|
# Horizontal left case: always end horizontally.
|
|
3821
4131
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
3822
|
-
"points=\"#{(x1-1/2.0)*@scale},#{(y1-1/4.0)*@scale} " +
|
|
3823
|
-
"#{(x1-1/2.0)*@scale},#{(y1+1/4.0)*@scale} " +
|
|
3824
|
-
"#{(x1+1/8.0)*@scale},#{(y1)*@scale}\"/>\n"
|
|
4132
|
+
"points=\"#{((x1-1/2.0)*@scale).round(3)},#{((y1-1/4.0)*@scale).round(3)} " +
|
|
4133
|
+
"#{((x1-1/2.0)*@scale).round(3)},#{((y1+1/4.0)*@scale).round(3)} " +
|
|
4134
|
+
"#{((x1+1/8.0)*@scale).round(3)},#{((y1)*@scale).round(3)}\"/>\n"
|
|
3825
4135
|
else
|
|
3826
4136
|
# Horizontal right case: always end horizontally.
|
|
3827
4137
|
res += "<polygon fill=\"#000\" stroke=\"none\" " +
|
|
3828
|
-
"points=\"#{(x1)*@scale},#{(y1+1/4.0)*@scale} " +
|
|
3829
|
-
"#{(x1)*@scale},#{(y1-1/4.0)*@scale} " +
|
|
3830
|
-
"#{(x1-1/8.0-1/2.0)*@scale},#{(y1)*@scale}\"/>\n"
|
|
4138
|
+
"points=\"#{((x1)*@scale).round(3)},#{((y1+1/4.0)*@scale).round(3)} " +
|
|
4139
|
+
"#{((x1)*@scale).round(3)},#{((y1-1/4.0)*@scale).round(3)} " +
|
|
4140
|
+
"#{((x1-1/8.0-1/2.0)*@scale).round(3)},#{((y1)*@scale).round(3)}\"/>\n"
|
|
3831
4141
|
end
|
|
3832
4142
|
return res
|
|
3833
4143
|
end
|
|
@@ -3920,17 +4230,18 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
|
|
|
3920
4230
|
# res += "</style>\n"
|
|
3921
4231
|
|
|
3922
4232
|
# Generate the group containing all the flow description.
|
|
3923
|
-
res += "<g id=\"#{self.name}\" visibility=\"#{visibility}\" " +
|
|
3924
|
-
|
|
4233
|
+
# res += "<g id=\"#{self.name}\" visibility=\"#{visibility}\" " +
|
|
4234
|
+
# "transform=\"translate(#{tx},#{ty})\">\n"
|
|
4235
|
+
res += "<g id=\"#{self.__id__}\" visibility=\"#{visibility}\" " +
|
|
4236
|
+
"transform=\"translate(#{tx.round(3)},#{ty.round(3)})\">\n"
|
|
3925
4237
|
# Generate the rectangle of the bounding box.
|
|
3926
4238
|
res += "<rect fill=\"#4682B4\" stroke=\"#007\" " +
|
|
3927
|
-
"stroke-width=\"#{@scale/4.0}\" " +
|
|
3928
|
-
|
|
3929
|
-
"
|
|
3930
|
-
"width=\"#{width}\" height=\"#{height}\"/>\n"
|
|
4239
|
+
"stroke-width=\"#{(@scale/4.0).round(3)}\" " +
|
|
4240
|
+
"x=\"#{x0.round(3)}\" y=\"#{y0.round(3)}\" "+
|
|
4241
|
+
"width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
|
|
3931
4242
|
|
|
3932
4243
|
# Generate the group containing the top system and its contents.
|
|
3933
|
-
res += "<g transform=\"translate(#{stx},#{sty})\">\n"
|
|
4244
|
+
res += "<g transform=\"translate(#{stx.round(3)},#{sty.round(3)})\">\n"
|
|
3934
4245
|
|
|
3935
4246
|
# Generate the node boxes.
|
|
3936
4247
|
puts "Generate node box for self.type=#{self.type}"
|
|
@@ -4087,19 +4398,19 @@ SVG
|
|
|
4087
4398
|
res = "<g id=\"#{name}\" visibility=\"#{visibility}\">\n"
|
|
4088
4399
|
end
|
|
4089
4400
|
res += "<rect fill=\"#cd5c5c\" "+
|
|
4090
|
-
"stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
|
|
4091
|
-
"x=\"#{xpos}\" y=\"#{ypos}\" " +
|
|
4092
|
-
"width=\"#{side}\" height=\"#{side}\" />\n"
|
|
4401
|
+
"stroke=\"#000\" stroke-width=\"#{(side/8.0).round(3)}\" " +
|
|
4402
|
+
"x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
|
|
4403
|
+
"width=\"#{side.round(3)}\" height=\"#{side.round(3)}\" />\n"
|
|
4093
4404
|
# The cross lines.
|
|
4094
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
|
|
4405
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{(side/8.0).round(3)}\" " +
|
|
4095
4406
|
"stroke-linecap=\"butt\" " +
|
|
4096
|
-
"x1=\"#{xpos}\" y1=\"#{ypos}\" " +
|
|
4097
|
-
"x2=\"#{xpos+side}\" y2=\"#{ypos+side}\" " +
|
|
4407
|
+
"x1=\"#{xpos.round(3)}\" y1=\"#{ypos.round(3)}\" " +
|
|
4408
|
+
"x2=\"#{(xpos+side).round(3)}\" y2=\"#{(ypos+side).round(3)}\" " +
|
|
4098
4409
|
" />\n"
|
|
4099
|
-
res += "<line stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
|
|
4410
|
+
res += "<line stroke=\"#000\" stroke-width=\"#{(side/8.0).round(3)}\" " +
|
|
4100
4411
|
"stroke-linecap=\"butt\" " +
|
|
4101
|
-
"x1=\"#{xpos+side}\" y1=\"#{ypos}\" " +
|
|
4102
|
-
"x2=\"#{xpos}\" y2=\"#{ypos+side}\" " +
|
|
4412
|
+
"x1=\"#{(xpos+side).round(3)}\" y1=\"#{ypos.round(3)}\" " +
|
|
4413
|
+
"x2=\"#{xpos.round(3)}\" y2=\"#{(ypos+side).round(3)}\" " +
|
|
4103
4414
|
" />\n"
|
|
4104
4415
|
res += "</g>"
|
|
4105
4416
|
end
|
|
@@ -4112,10 +4423,10 @@ SVG
|
|
|
4112
4423
|
// Helping button.
|
|
4113
4424
|
<g id="$help$_open">
|
|
4114
4425
|
<rect fill="yellow" stroke="#000" stroke-width="3"
|
|
4115
|
-
x="#{x0+width-62/fit}" y="#{y0+2/fit}" width="#{60/fit}" height="#{30/fit}" />
|
|
4426
|
+
x="#{(x0+width-62/fit).round(3)}" y="#{(y0+2/fit).round(3)}" width="#{(60/fit).round(3)}" height="#{(30/fit).round(3)}" />
|
|
4116
4427
|
<text style="text-anchor: middle; dominant-baseline: middle;"
|
|
4117
|
-
font-family="monospace" font-size="#{20/fit}px"
|
|
4118
|
-
x="#{x0+width-32/fit}" y="#{y0+17/fit}" >
|
|
4428
|
+
font-family="monospace" font-size="#{(20/fit).round(3)}px"
|
|
4429
|
+
x="#{(x0+width-32/fit).round(3)}" y="#{(y0+17/fit).round(3)}" >
|
|
4119
4430
|
Help
|
|
4120
4431
|
</text>
|
|
4121
4432
|
</g>
|
|
@@ -4123,53 +4434,46 @@ SVG
|
|
|
4123
4434
|
// Helping panel.
|
|
4124
4435
|
<g id="$help$" visibility="hidden">
|
|
4125
4436
|
<rect fill="#ffffd7" stroke="#000" stroke-width="6"
|
|
4126
|
-
x="#{x0}" y="#{y0}" width="#{width}" height="#{height}" />
|
|
4127
|
-
<text font-size="#{40/fit}px" font-family="serif" font-weight="bold"
|
|
4128
|
-
x="#{x0+width/2}" y="#{y0+40/fit}" >
|
|
4437
|
+
x="#{x0.round(3)}" y="#{y0.round(3)}" width="#{width.round(3)}" height="#{height.round(3)}" />
|
|
4438
|
+
<text font-size="#{(40/fit).round(3)}px" font-family="serif" font-weight="bold"
|
|
4439
|
+
x="#{(x0+width/2).round(3)}" y="#{(y0+40/fit).round(3)}" >
|
|
4129
4440
|
Help
|
|
4130
4441
|
</text>
|
|
4131
4442
|
|
|
4132
|
-
<text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
|
|
4133
|
-
x="#{x0+15/fit}" y="#{y0+100/fit}" >
|
|
4443
|
+
<text font-size="#{(30/fit).round(3)}px" font-family="serif" font-weight="bold"
|
|
4444
|
+
x="#{(x0+15/fit).round(3)}" y="#{(y0+100/fit).round(3)}" >
|
|
4134
4445
|
Navigation:
|
|
4135
4446
|
</text>
|
|
4136
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+25/fit}" y="#{y0+140/fit}" >
|
|
4447
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+25/fit).round(3)}" y="#{(y0+140/fit).round(3)}" >
|
|
4137
4448
|
Zoom in/out:
|
|
4138
4449
|
</text>
|
|
4139
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+190/fit}" y="#{y0+140/fit}" >
|
|
4450
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+190/fit).round(3)}" y="#{(y0+140/fit).round(3)}" >
|
|
4140
4451
|
mouse wheel.
|
|
4141
4452
|
</text>
|
|
4142
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+25/fit}" y="#{y0+170/fit}" >
|
|
4453
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+25/fit).round(3)}" y="#{(y0+170/fit).round(3)}" >
|
|
4143
4454
|
Move diagram:
|
|
4144
4455
|
</text>
|
|
4145
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+190/fit}" y="#{y0+170/fit}" >
|
|
4456
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+190/fit).round(3)}" y="#{(y0+170/fit).round(3)}" >
|
|
4146
4457
|
left click and drag, or arrow keys.
|
|
4147
4458
|
</text>
|
|
4148
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+25/fit}" y="#{y0+200/fit}" >
|
|
4459
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+25/fit).round(3)}" y="#{(y0+200/fit).round(3)}" >
|
|
4149
4460
|
Open element:
|
|
4150
4461
|
</text>
|
|
4151
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+190/fit}" y="#{y0+200/fit}" >
|
|
4462
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+190/fit).round(3)}" y="#{(y0+200/fit).round(3)}" >
|
|
4152
4463
|
left click on element.
|
|
4153
4464
|
</text>
|
|
4154
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+25/fit}" y="#{y0+230/fit}" >
|
|
4465
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+25/fit).round(3)}" y="#{(y0+230/fit).round(3)}" >
|
|
4155
4466
|
Close element:
|
|
4156
4467
|
</text>
|
|
4157
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+190/fit}" y="#{y0+230/fit}" >
|
|
4468
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+190/fit).round(3)}" y="#{(y0+230/fit).round(3)}" >
|
|
4158
4469
|
left click on the close button at the top right of the element.
|
|
4159
4470
|
</text>
|
|
4160
4471
|
|
|
4161
|
-
<text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
|
|
4162
|
-
x="#{x0+15/fit}" y="#{y0+300/fit}" >
|
|
4472
|
+
<text font-size="#{(30/fit).round(3)}px" font-family="serif" font-weight="bold"
|
|
4473
|
+
x="#{(x0+15/fit).round(3)}" y="#{(y0+300/fit).round(3)}" >
|
|
4163
4474
|
Types of elements:
|
|
4164
4475
|
</text>
|
|
4165
4476
|
#{
|
|
4166
|
-
# ic = IC.new("Instance",:instance)
|
|
4167
|
-
# ic.scale = 35.0
|
|
4168
|
-
# ic.xpos = (x0+15/fit) / ic.scale
|
|
4169
|
-
# ic.ypos = 330/fit / ic.scale
|
|
4170
|
-
# ic.width = 300/fit / ic.scale
|
|
4171
|
-
# ic.height = 100/fit / ic.scale
|
|
4172
|
-
# ic.instance_svg(ic)
|
|
4173
4477
|
ic = IC.new("Instance",:instance)
|
|
4174
4478
|
ic.scale = 35.0/fit
|
|
4175
4479
|
ic.xpos = (x0+15)/fit / ic.scale
|
|
@@ -4179,23 +4483,6 @@ SVG
|
|
|
4179
4483
|
ic.instance_svg(ic)
|
|
4180
4484
|
}
|
|
4181
4485
|
#{
|
|
4182
|
-
# ic = IC.new("Continuous assignment",:alu)
|
|
4183
|
-
# ic.scale = 35.0
|
|
4184
|
-
# ic.xpos = (x0+(15+300+15)/fit) / ic.scale
|
|
4185
|
-
# ic.ypos = 305/fit / ic.scale
|
|
4186
|
-
# ic.width = 300/fit / ic.scale
|
|
4187
|
-
# ic.height = 150/fit / ic.scale
|
|
4188
|
-
# p0 = Port.new("in0",ic,:input)
|
|
4189
|
-
# p0.side = LEFT
|
|
4190
|
-
# ic.ports << p0
|
|
4191
|
-
# p1 = Port.new("in1",ic,:input)
|
|
4192
|
-
# p1.side = LEFT
|
|
4193
|
-
# ic.ports << p1
|
|
4194
|
-
# p2 = Port.new("out",ic,:output)
|
|
4195
|
-
# p2.side = RIGHT
|
|
4196
|
-
# ic.alu_svg(ic)
|
|
4197
|
-
# ic.ports << p2
|
|
4198
|
-
# ic.alu_svg(ic)
|
|
4199
4486
|
ic = IC.new("Continuous assignment",:alu)
|
|
4200
4487
|
ic.scale = 35.0/fit
|
|
4201
4488
|
ic.xpos = (x0+(15+300+15))/fit / ic.scale
|
|
@@ -4215,13 +4502,6 @@ SVG
|
|
|
4215
4502
|
ic.alu_svg(ic)
|
|
4216
4503
|
}
|
|
4217
4504
|
#{
|
|
4218
|
-
# ic = IC.new("Combinatorial process",:process)
|
|
4219
|
-
# ic.scale = 35.0
|
|
4220
|
-
# ic.xpos = (x0+15/fit) / ic.scale
|
|
4221
|
-
# ic.ypos = 480/fit / ic.scale
|
|
4222
|
-
# ic.width = 300/fit / ic.scale
|
|
4223
|
-
# ic.height = 100/fit / ic.scale
|
|
4224
|
-
# ic.process_svg(ic)
|
|
4225
4505
|
ic = IC.new("Combinatorial process",:process)
|
|
4226
4506
|
ic.scale = 35.0/fit
|
|
4227
4507
|
ic.xpos = (x0+15)/fit / ic.scale
|
|
@@ -4231,13 +4511,6 @@ SVG
|
|
|
4231
4511
|
ic.process_svg(ic)
|
|
4232
4512
|
}
|
|
4233
4513
|
#{
|
|
4234
|
-
# ic = IC.new("Clocked process",:clocked_process)
|
|
4235
|
-
# ic.scale = 35.0
|
|
4236
|
-
# ic.xpos = (x0+(15+300+15)/fit) / ic.scale
|
|
4237
|
-
# ic.ypos = 480/fit / ic.scale
|
|
4238
|
-
# ic.width = 300/fit / ic.scale
|
|
4239
|
-
# ic.height = 100/fit / ic.scale
|
|
4240
|
-
# ic.clocked_process_svg(ic)
|
|
4241
4514
|
ic = IC.new("Clocked process",:clocked_process)
|
|
4242
4515
|
ic.scale = 35.0/fit
|
|
4243
4516
|
ic.xpos = (x0+(15+300+15))/fit / ic.scale
|
|
@@ -4247,13 +4520,6 @@ SVG
|
|
|
4247
4520
|
ic.clocked_process_svg(ic)
|
|
4248
4521
|
}
|
|
4249
4522
|
#{
|
|
4250
|
-
# ic = IC.new("Time process",:timed_process)
|
|
4251
|
-
# ic.scale = 35.0
|
|
4252
|
-
# ic.xpos = (x0+(15+300+15+300+15)/fit) / ic.scale
|
|
4253
|
-
# ic.ypos = 480/fit / ic.scale
|
|
4254
|
-
# ic.width = 300/fit / ic.scale
|
|
4255
|
-
# ic.height = 100/fit / ic.scale
|
|
4256
|
-
# ic.timed_process_svg(ic)
|
|
4257
4523
|
ic = IC.new("Time process",:timed_process)
|
|
4258
4524
|
ic.scale = 35.0/fit
|
|
4259
4525
|
ic.xpos = (x0+(15+300+15+300+15))/fit / ic.scale
|
|
@@ -4263,13 +4529,6 @@ SVG
|
|
|
4263
4529
|
ic.timed_process_svg(ic)
|
|
4264
4530
|
}
|
|
4265
4531
|
#{
|
|
4266
|
-
# ic = IC.new("Signal",:register)
|
|
4267
|
-
# ic.scale = 35.0
|
|
4268
|
-
# ic.xpos = (x0+15/fit) / ic.scale
|
|
4269
|
-
# ic.ypos = 600/fit / ic.scale
|
|
4270
|
-
# ic.width = 150/fit / ic.scale
|
|
4271
|
-
# ic.height = 75/fit / ic.scale
|
|
4272
|
-
# ic.register_svg(ic)
|
|
4273
4532
|
ic = IC.new("Signal",:register)
|
|
4274
4533
|
ic.scale = 35.0/fit
|
|
4275
4534
|
ic.xpos = (x0+15)/fit / ic.scale
|
|
@@ -4279,13 +4538,6 @@ SVG
|
|
|
4279
4538
|
ic.register_svg(ic)
|
|
4280
4539
|
}
|
|
4281
4540
|
#{
|
|
4282
|
-
# ic = IC.new("Memory",:memory)
|
|
4283
|
-
# ic.scale = 35.0
|
|
4284
|
-
# ic.xpos = (x0+(15+200+15)/fit) / ic.scale
|
|
4285
|
-
# ic.ypos = 600/fit / ic.scale
|
|
4286
|
-
# ic.width = 200/fit / ic.scale
|
|
4287
|
-
# ic.height = 100/fit / ic.scale
|
|
4288
|
-
# ic.memory_svg(ic)
|
|
4289
4541
|
ic = IC.new("Memory",:memory)
|
|
4290
4542
|
ic.scale = 35.0/fit
|
|
4291
4543
|
ic.xpos = (x0+(15+200+15))/fit / ic.scale
|
|
@@ -4295,11 +4547,11 @@ SVG
|
|
|
4295
4547
|
ic.memory_svg(ic)
|
|
4296
4548
|
}
|
|
4297
4549
|
|
|
4298
|
-
<text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
|
|
4299
|
-
x="#{x0+15/fit}" y="#{y0+800/fit}" >
|
|
4550
|
+
<text font-size="#{(30/fit).round(3)}px" font-family="serif" font-weight="bold"
|
|
4551
|
+
x="#{(x0+15/fit).round(3)}" y="#{(y0+800/fit).round(3)}" >
|
|
4300
4552
|
Contents of processes and assigments:
|
|
4301
4553
|
</text>
|
|
4302
|
-
<text font-size="#{25/fit}px" font-family="serif" x="#{x0+25/fit}" y="#{y0+840/fit}" >
|
|
4554
|
+
<text font-size="#{(25/fit).round(3)}px" font-family="serif" x="#{(x0+25/fit).round(3)}" y="#{(y0+840/fit).round(3)}" >
|
|
4303
4555
|
Represented as sets of parallel flow charts.
|
|
4304
4556
|
</text>
|
|
4305
4557
|
|
|
@@ -4329,11 +4581,11 @@ SVG
|
|
|
4329
4581
|
def self.svg_text_fit(name,width,max_size)
|
|
4330
4582
|
return <<~SCRIPT
|
|
4331
4583
|
<script>
|
|
4332
|
-
fitWidth=#{width};
|
|
4584
|
+
fitWidth=#{width.round(3)};
|
|
4333
4585
|
textNode = document.getElementById("#{self.to_svg_id(name)}");
|
|
4334
4586
|
textBB = textNode.getBBox();
|
|
4335
4587
|
fitSize = fitWidth / textBB.width;
|
|
4336
|
-
if (fitSize > #{max_size}) fitSize = #{max_size};
|
|
4588
|
+
if (fitSize > #{max_size.round(3)}) fitSize = #{max_size.round(3)};
|
|
4337
4589
|
textNode.setAttribute("font-size", fitSize + "px")
|
|
4338
4590
|
</script>
|
|
4339
4591
|
SCRIPT
|
|
@@ -4382,7 +4634,7 @@ class HDLRuby::Low::SystemT
|
|
|
4382
4634
|
# ports.each_value do |subs|
|
|
4383
4635
|
ports.each do |name,subs|
|
|
4384
4636
|
# Skip connection to registers, they are processed later.
|
|
4385
|
-
next if regs[name]
|
|
4637
|
+
next if regs[HDLRuby::Viz.port_base_name(name)]
|
|
4386
4638
|
# Not a register, can go on.
|
|
4387
4639
|
subs.each do |p0|
|
|
4388
4640
|
subs.each do |p1|
|
|
@@ -4400,15 +4652,17 @@ class HDLRuby::Low::SystemT
|
|
|
4400
4652
|
# Check if there is a register corresponding to the port
|
|
4401
4653
|
# (full port or sub port of the register).
|
|
4402
4654
|
next if name.include?("$") # Skip register ports which are targets.
|
|
4403
|
-
rname = name
|
|
4655
|
+
# rname = name
|
|
4656
|
+
rname = HDLRuby::Viz.port_base_name(name)
|
|
4404
4657
|
while !regs.key?(rname) do
|
|
4405
4658
|
break unless rname.include?(".")
|
|
4406
4659
|
rname = rname.gsub(/\.[^.]*$/,"")
|
|
4407
4660
|
end
|
|
4408
4661
|
reg = regs[rname]
|
|
4409
4662
|
next unless reg
|
|
4410
|
-
# Connect the register, once per ic and direction.
|
|
4411
|
-
|
|
4663
|
+
# # Connect the register, once per ic and direction.
|
|
4664
|
+
# Connect the register, once per ic, direction and type.
|
|
4665
|
+
subs.uniq {|p| [p.ic,p.direction,p.type] }.each do |p|
|
|
4412
4666
|
# puts "Connect to register port name #{name} in ic=#{world.name} with port=#{p.name}"
|
|
4413
4667
|
if p.direction == :output then
|
|
4414
4668
|
world.connect(p,ports[HDLRuby::Viz.reg2input_name(name)][0])
|
|
@@ -4444,16 +4698,48 @@ class HDLRuby::Low::SystemT
|
|
|
4444
4698
|
# NOTE: p0 or p1 may be empty if outside current module.
|
|
4445
4699
|
world.connect(p0,p1) unless (!p0 or !p1 or p0.targets.include?(p1))
|
|
4446
4700
|
end
|
|
4447
|
-
# Remove the dangling input ports in registers (they are ROMS).
|
|
4701
|
+
# # Remove the dangling input ports in registers (they are ROMS).
|
|
4702
|
+
# regs.each_value do |reg|
|
|
4703
|
+
# to_remove_input = reg.ports.select {|p| p.direction==:input }.all? do
|
|
4704
|
+
# |p|
|
|
4705
|
+
# p.targets.none?
|
|
4706
|
+
# end
|
|
4707
|
+
# if to_remove_input then
|
|
4708
|
+
# reg.ports.delete_if {|p| p.direction == :input }
|
|
4709
|
+
# end
|
|
4710
|
+
# end
|
|
4711
|
+
# Remove the dangling ports in registers (they are ROMS).
|
|
4448
4712
|
regs.each_value do |reg|
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4713
|
+
reg.ports.delete_if {|p| p.targets.none? }
|
|
4714
|
+
end
|
|
4715
|
+
|
|
4716
|
+
# Gather the bit ports by owner port.
|
|
4717
|
+
port2bits = {}
|
|
4718
|
+
ports.each do |name,subs|
|
|
4719
|
+
subs.each do |port|
|
|
4720
|
+
port2bits[port.name] = []
|
|
4721
|
+
end
|
|
4722
|
+
end
|
|
4723
|
+
ports.each do |name,subs|
|
|
4724
|
+
subs.each do |port|
|
|
4725
|
+
if HDLRuby::Viz.port_bit_name?(port.name) then
|
|
4726
|
+
port2bits[HDLRuby::Viz.port_base_name(port.name)] << port
|
|
4727
|
+
end
|
|
4452
4728
|
end
|
|
4453
|
-
|
|
4454
|
-
|
|
4729
|
+
end
|
|
4730
|
+
# Remove the dangling ports that are accessed by sub ports.
|
|
4731
|
+
ports.each do |name,subs|
|
|
4732
|
+
subs.each do |port|
|
|
4733
|
+
if port.targets.none? then
|
|
4734
|
+
# This is a dangling port, is it connected by bits.
|
|
4735
|
+
if port2bits[port.name].any? then
|
|
4736
|
+
# Yes, remove it.
|
|
4737
|
+
port.ic.ports.delete(port)
|
|
4738
|
+
end
|
|
4739
|
+
end
|
|
4455
4740
|
end
|
|
4456
4741
|
end
|
|
4742
|
+
|
|
4457
4743
|
# Return the resulting visualization.
|
|
4458
4744
|
return world
|
|
4459
4745
|
end
|
|
@@ -4482,18 +4768,23 @@ class HDLRuby::Low::Scope
|
|
|
4482
4768
|
# name = sname + inner.name.to_s
|
|
4483
4769
|
# name = inner.name.to_s
|
|
4484
4770
|
name = sname + inner.name.to_s
|
|
4485
|
-
#
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
#
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4771
|
+
# But first cut of the index if any for the register.
|
|
4772
|
+
rname = HDLRuby::Viz.port_base_name(name)
|
|
4773
|
+
reg = regs[rname]
|
|
4774
|
+
unless reg then
|
|
4775
|
+
# Create the viz for the "register"
|
|
4776
|
+
if typ.is_a?(HDLRuby::Low::TypeVector) and
|
|
4777
|
+
typ.base.width > 1 then
|
|
4778
|
+
puts "Adding scope register #{rname} to #{world.name}"
|
|
4779
|
+
# This is in fact a memory matrix.
|
|
4780
|
+
reg = HDLRuby::Viz::IC.new(rname,:memory,world)
|
|
4781
|
+
else
|
|
4782
|
+
puts "Adding plain register #{rname} to #{world.name}"
|
|
4783
|
+
# This is a plain register.
|
|
4784
|
+
reg = HDLRuby::Viz::IC.new(rname,:register,world)
|
|
4785
|
+
end
|
|
4786
|
+
regs[reg.name] = reg
|
|
4495
4787
|
end
|
|
4496
|
-
regs[reg.name] = reg
|
|
4497
4788
|
# Create the corresponding input and output ports.
|
|
4498
4789
|
iname = HDLRuby::Viz.reg2input_name(name)
|
|
4499
4790
|
puts "Adding input port #{iname} to reg #{reg.name}"
|
|
@@ -4546,21 +4837,11 @@ class HDLRuby::Low::Scope
|
|
|
4546
4837
|
# Explicit port connect case.
|
|
4547
4838
|
links << [ connection.left.to_viz_names[0],
|
|
4548
4839
|
connection.right.to_viz_names[0] ]
|
|
4549
|
-
# # Get the right refered name.
|
|
4550
|
-
# rname = connection.right.to_viz_names[0]
|
|
4551
|
-
# # If it is a register make the name its output.
|
|
4552
|
-
# rname = HDLRuby::Viz.reg2output_name(rname) if regs[rname]
|
|
4553
|
-
# # Get the left refered name.
|
|
4554
|
-
# lname = connection.left.to_viz_names[0]
|
|
4555
|
-
# # If it is a register make the name its input.
|
|
4556
|
-
# lname = HDLRuby::Viz.reg2input_name(lname) if regs[lname]
|
|
4557
|
-
# # Make the explicit port connect.
|
|
4558
|
-
# links << [ lname, rname ]
|
|
4559
4840
|
# Add the explicit port connection.
|
|
4560
4841
|
puts "added link between #{links[-1][0]} and #{links[-1][1]}"
|
|
4561
4842
|
next
|
|
4562
4843
|
end
|
|
4563
|
-
ic = HDLRuby::Viz::IC.new(HDLRuby.uniq_name("
|
|
4844
|
+
ic = HDLRuby::Viz::IC.new(HDLRuby.uniq_name("cnx"),:assign,world)
|
|
4564
4845
|
# Add its ports.
|
|
4565
4846
|
# Output.
|
|
4566
4847
|
name = connection.left.to_viz_names[0]
|
|
@@ -4595,14 +4876,15 @@ class HDLRuby::Low::Scope
|
|
|
4595
4876
|
behavior.each_event do |ev|
|
|
4596
4877
|
name = ev.ref.to_viz_names[0]
|
|
4597
4878
|
next if ic.port?(name) # The port has already been added.
|
|
4598
|
-
# Is it a clocked event?
|
|
4599
|
-
if ev.on_edge? then
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
else
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
end
|
|
4879
|
+
# # Is it a clocked event?
|
|
4880
|
+
# if ev.on_edge? then
|
|
4881
|
+
# # Yes.
|
|
4882
|
+
# ports[name] << ic.add_port(name, :input, ev.type)
|
|
4883
|
+
# else
|
|
4884
|
+
# # No, use a standard port.
|
|
4885
|
+
# ports[name] << ic.add_port(name, :input)
|
|
4886
|
+
# end
|
|
4887
|
+
ports[name] << ic.add_port(name, :input, ev.type)
|
|
4606
4888
|
end
|
|
4607
4889
|
# Recurse on its blocks.
|
|
4608
4890
|
# behavior.block.to_viz(world,ic,ports)
|
|
@@ -4664,6 +4946,9 @@ class HDLRuby::Low::Case
|
|
|
4664
4946
|
# self.default.to_viz_node(node) if self.default
|
|
4665
4947
|
# return node
|
|
4666
4948
|
node = parent
|
|
4949
|
+
# NOROM
|
|
4950
|
+
count = 0
|
|
4951
|
+
# END NOROM
|
|
4667
4952
|
# Generate one node per possible value.
|
|
4668
4953
|
self.each_when do |w|
|
|
4669
4954
|
sub = HDLRuby::Viz::Node.new(:case,node)
|
|
@@ -4671,6 +4956,12 @@ class HDLRuby::Low::Case
|
|
|
4671
4956
|
w.match.to_viz_node(sub)
|
|
4672
4957
|
w.statement.to_viz_node(sub)
|
|
4673
4958
|
node = sub if node == parent # Set the first node
|
|
4959
|
+
# NOROM
|
|
4960
|
+
count += 1
|
|
4961
|
+
if count > 16 then
|
|
4962
|
+
break
|
|
4963
|
+
end
|
|
4964
|
+
# END NOROM
|
|
4674
4965
|
end
|
|
4675
4966
|
self.default.to_viz_node(node) if self.default
|
|
4676
4967
|
return node
|
|
@@ -4691,14 +4982,19 @@ class HDLRuby::Low::Block
|
|
|
4691
4982
|
self.each_inner do |inner|
|
|
4692
4983
|
name = bname + inner.name.to_s
|
|
4693
4984
|
puts "Adding block register #{name} to #{world.name}"
|
|
4694
|
-
#
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4985
|
+
# But first cut of the index if any for the register.
|
|
4986
|
+
rname = HDLRuby::Viz.port_base_name(name)
|
|
4987
|
+
reg = regs[rname]
|
|
4988
|
+
unless reg then
|
|
4989
|
+
# Create the viz for the "register"
|
|
4990
|
+
if inner.type.base.width > 1 then
|
|
4991
|
+
# This is in fact a memory matrix.
|
|
4992
|
+
reg = HDLRuby::Viz::IC.new(rname,:memory,world)
|
|
4993
|
+
else
|
|
4994
|
+
reg = HDLRuby::Viz::IC.new(rname,:register,world)
|
|
4995
|
+
end
|
|
4996
|
+
regs[reg.name] = reg
|
|
4700
4997
|
end
|
|
4701
|
-
regs[reg.name] = reg
|
|
4702
4998
|
# Create the corresponding input and output ports.
|
|
4703
4999
|
iname = HDLRuby::Viz.reg2input_name(name)
|
|
4704
5000
|
puts "Adding input port #{iname} to #{world.name}"
|
|
@@ -4767,20 +5063,22 @@ class HDLRuby::Low::Block
|
|
|
4767
5063
|
end
|
|
4768
5064
|
|
|
4769
5065
|
next unless stmnt.is_a?(HDLRuby::Low::Transmit)
|
|
4770
|
-
|
|
5066
|
+
lnames = stmnt.left.to_viz_names
|
|
5067
|
+
name = lnames[0]
|
|
4771
5068
|
if iports.key?(name) then
|
|
4772
5069
|
# Change to inout port.
|
|
4773
5070
|
iports[name].direction = :inout
|
|
4774
|
-
next
|
|
4775
|
-
end
|
|
5071
|
+
# next
|
|
5072
|
+
# end
|
|
4776
5073
|
# Add one port by output name.
|
|
4777
|
-
unless oports.key?(name) then
|
|
5074
|
+
# unless oports.key?(name) then
|
|
5075
|
+
elsif !oports.key?(name) then
|
|
4778
5076
|
puts "Adding output port #{name} to #{ic.name}"
|
|
4779
5077
|
port = ic.add_port(name, :output)
|
|
4780
5078
|
ports[name] << port
|
|
4781
5079
|
oports[name] = port
|
|
4782
5080
|
end
|
|
4783
|
-
stmnt.right.to_viz_names.each do |name|
|
|
5081
|
+
(stmnt.right.to_viz_names+lnames[1..-1]).each do |name|
|
|
4784
5082
|
if oports.key?(name) then
|
|
4785
5083
|
# Change to inout port.
|
|
4786
5084
|
oports[name].direction = :inout
|
|
@@ -4806,10 +5104,19 @@ class HDLRuby::Low::Block
|
|
|
4806
5104
|
def to_viz_node(parent)
|
|
4807
5105
|
node = HDLRuby::Viz::Node.new(self.mode,parent)
|
|
4808
5106
|
prev = nil
|
|
5107
|
+
# NOROM
|
|
5108
|
+
count = 0
|
|
5109
|
+
# END NOROM
|
|
4809
5110
|
self.each_statement do |stmnt|
|
|
4810
5111
|
succ = stmnt.to_viz_node(node)
|
|
4811
5112
|
prev.successor = succ if prev
|
|
4812
5113
|
prev = succ
|
|
5114
|
+
# NOROM
|
|
5115
|
+
count += 1
|
|
5116
|
+
if count > 256 then
|
|
5117
|
+
break
|
|
5118
|
+
end
|
|
5119
|
+
# END NOROM
|
|
4813
5120
|
end
|
|
4814
5121
|
unless prev then
|
|
4815
5122
|
# There were no statement in the block, create a dummy one
|