HDLRuby 3.9.3 → 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.
@@ -86,6 +86,7 @@ module HDLRuby::Viz
86
86
  @cwidths = [] # The widths of each column in number of routes
87
87
  # @border = 2 # The IC border size for routing to external ports.
88
88
  @border = 4 # The IC border size for routing to external ports.
89
+ # @cell_border = 4 # The cell border size
89
90
  @cell_border = 4 # The cell border size
90
91
  @routes = [] # The connection routes.
91
92
  @port_width = 3 # The width in tiles for a port
@@ -172,8 +173,8 @@ module HDLRuby::Viz
172
173
 
173
174
  # Compute the distance between to IC.
174
175
  def distance(ic0,ic1)
175
- res = Math.sqrt((ic0.xpos-ic1.xpos)**2+(ic0.ypos-ic1.ypos)**2)
176
- # res = (ic0.xpos-ic1.xpos).abs+(ic0.ypos-ic1.ypos).abs
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
177
178
  return res
178
179
  end
179
180
 
@@ -360,7 +361,8 @@ module HDLRuby::Viz
360
361
 
361
362
  # Select the side of the ports of the children according to the
362
363
  # position of their targets.
363
- def side_children
364
+ # def side_children
365
+ def side_children(ic_matrix_coordinates)
364
366
  @children.each do |child|
365
367
  puts "side_children for child=#{child.name} with #{child.ports.size} ports"
366
368
  # Resets the port sides.
@@ -372,8 +374,9 @@ module HDLRuby::Viz
372
374
  # (Information used for certain types of IC).
373
375
  left_for, up_for, right_for, down_for = nil, nil, nil, nil
374
376
  # Recompute the ports sides.
375
- cx = child.xpos
376
- cy = child.ypos
377
+ # cx = child.xpos
378
+ # cy = child.ypos
379
+ cx,cy = ic_matrix_coordinates[child]
377
380
  child.ports.each do |port|
378
381
  puts "For port: #{port.name} (of #{port.ic.name})"
379
382
  unless left_for || up_for || right_for || down_for then
@@ -398,58 +401,89 @@ module HDLRuby::Viz
398
401
  # Current IC, do not use its position, but the side.
399
402
  case port.targets[0].side
400
403
  when LEFT
401
- tx = cx + 1.0
404
+ # tx = cx + 1.0
405
+ tx = cx + 1
402
406
  ty = cy
403
407
  when UP
404
408
  tx = cx
405
- ty = -cy - 1.0
409
+ # ty = -cy - 1.0
410
+ ty = -cy - 1
406
411
  when RIGHT
407
- tx = -cx - 1.0
412
+ # tx = -cx - 1.0
413
+ tx = -cx - 1
408
414
  ty = cy
409
415
  when DOWN
410
416
  tx = cx
411
- ty = cy + 1.0
417
+ # ty = cy + 1.0
418
+ ty = cy + 1
412
419
  end
413
420
  else
414
- tx = port.targets[0].ic.xpos
415
- 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]
416
424
  end
417
425
  dx = cx-tx
418
426
  dy = cy-ty
419
- if dx > 0 then
427
+ puts "cx=#{cx} cy=#{cy} tx=#{tx} ty=#{ty} dx=#{dx} dy=#{dy}"
428
+ if dx == 0 then
420
429
  if dy > 0 then
421
- if dx > dy then
422
- port.side = this_port ? RIGHT : LEFT
423
- else
424
- port.side = this_port ? UP : DOWN
425
- end
430
+ port.side = this_port ? UP : DOWN
426
431
  else
427
- if dx > -dy then
428
- port.side = this_port ? RIGHT : LEFT
429
- else
430
- port.side = this_port ? DOWN : UP
431
- end
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
456
+ if dy > 0 then
457
+ port.side = this_port ? RIGHT : LEFT
458
+ else
459
+ # port.side = this_port ? UP : DOWN
460
+ port.side = this_port ? DOWN : UP
432
461
  end
433
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
434
476
  if dy > 0 then
435
- if -dx > dy then
436
- port.side = this_port ? LEFT : RIGHT
437
- else
438
- port.side = this_port ? UP : DOWN
439
- end
477
+ port.side = this_port ? LEFT : RIGHT
440
478
  else
441
- if -dx > -dy then
442
- port.side = this_port ? LEFT : RIGHT
443
- else
444
- port.side = this_port ? DOWN : UP
445
- end
479
+ port.side = this_port ? DOWN : UP
446
480
  end
447
481
  end
448
482
  end
449
483
  end
450
484
  # Case of IC of type assign or register if a side is used for
451
485
  # output, the opposite must be used for input, and vice versa.
452
- if child.type == :assign or child.type == :register then
486
+ if child.type == :assign then # or child.type == :register then
453
487
  # puts "left_for=#{left_for} up_for=#{up_for} right_for=#{right_for} down_for=#{down_for}"
454
488
  if left_for then
455
489
  if port.direction == left_for then
@@ -869,6 +903,10 @@ module HDLRuby::Viz
869
903
  cw = @cwidths[j]
870
904
  @cwidths[j] = child.width if child.width > cw
871
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
+
872
910
  end
873
911
  end
874
912
  # Increase the space to allow placing the routes.
@@ -925,9 +963,9 @@ module HDLRuby::Viz
925
963
  elsif child.lports.any? then
926
964
  step = child.height / child.lports.size
927
965
  child.lports.each_with_index do |port,i|
928
- puts "Preplace left port=#{port.name}"
929
966
  port.xpos = xpos
930
967
  port.ypos = ypos + i*step + step/2
968
+ puts "Preplace left port=#{port.name} ypos=#{port.ypos}"
931
969
  end
932
970
  end
933
971
  # The up ports.
@@ -939,9 +977,9 @@ module HDLRuby::Viz
939
977
  elsif child.uports.any? then
940
978
  step = child.width / child.uports.size
941
979
  child.uports.each_with_index do |port,i|
942
- puts "Preplace up port=#{port.name}"
943
980
  port.xpos = xpos + i*step + step/2
944
981
  port.ypos = ypos + height - 1
982
+ puts "Preplace up port=#{port.name} xpos=#{port.xpos}"
945
983
  end
946
984
  end
947
985
  # The right ports.
@@ -953,9 +991,9 @@ module HDLRuby::Viz
953
991
  elsif child.rports.any? then
954
992
  step = child.height / child.rports.size
955
993
  child.rports.each_with_index do |port,i|
956
- puts "Preplace right port=#{port.name}"
957
994
  port.xpos = xpos + width - 1
958
995
  port.ypos = ypos + i*step + step/2
996
+ puts "Preplace right port=#{port.name} ypos=#{port.ypos}"
959
997
  end
960
998
  end
961
999
  # The down ports.
@@ -967,13 +1005,14 @@ module HDLRuby::Viz
967
1005
  elsif child.dports.any? then
968
1006
  step = child.width / child.dports.size
969
1007
  child.dports.each_with_index do |port,i|
970
- puts "Preplace down port=#{port.name}"
971
1008
  port.xpos = xpos + i*step + step/2
972
1009
  port.ypos = ypos
1010
+ puts "Preplace down port=#{port.name} xpos=#{port.xpos}"
973
1011
  end
974
1012
  end
975
1013
  end
976
1014
 
1015
+ # TRUCMUCHE
977
1016
  # Optimize the place.
978
1017
  @children.each do |child|
979
1018
  xpos = child.xpos
@@ -986,11 +1025,11 @@ module HDLRuby::Viz
986
1025
  step = child.height / child.lports.size
987
1026
  lefts = child.lports.clone
988
1027
 
989
- # Sort the ports by reverse order y difference with their
1028
+ # Sort the ports by reverse order in difference with their
990
1029
  # targets.
991
1030
  lefts.sort! do |p0,p1|
992
- p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p0.ypos } <=>
993
- 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 }
994
1033
  end
995
1034
  # Apply the order.
996
1035
  lefts.each_with_index do |port,i|
@@ -1007,8 +1046,8 @@ module HDLRuby::Viz
1007
1046
  # Sort the ports by reverse order x difference with their
1008
1047
  # targets.
1009
1048
  ups.sort! do |p0,p1|
1010
- p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p0.xpos } <=>
1011
- 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 }
1012
1051
  end
1013
1052
  # Apply the order.
1014
1053
  ups.each_with_index do |port,i|
@@ -1026,8 +1065,8 @@ module HDLRuby::Viz
1026
1065
  # targets.
1027
1066
  rights.sort! do |p0,p1|
1028
1067
  # puts "p0=#{p0.name} p1=#{p1.name}"
1029
- p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.ypos - p0.ypos } <=>
1030
- 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 }
1031
1070
  end
1032
1071
  # Apply the order.
1033
1072
  rights.each_with_index do |port,i|
@@ -1044,8 +1083,8 @@ module HDLRuby::Viz
1044
1083
  # Sort the ports by reverse order x difference with their
1045
1084
  # targets.
1046
1085
  downs.sort! do |p0,p1|
1047
- p0.targets.uniq {|t| t.ic }.reduce(0) {|sum,t| sum + t.xpos - p0.xpos } <=>
1048
- 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 }
1049
1088
  end
1050
1089
  # Apply the order.
1051
1090
  downs.each_with_index do |port,i|
@@ -1061,112 +1100,8 @@ module HDLRuby::Viz
1061
1100
  # Also fine-place the ports of the current IC to also increase the
1062
1101
  # aligment of connected ports.
1063
1102
  def place_children_port_matrix
1064
- # xpos, ypos = 0, 0
1065
- # @matrix.each_with_index do |row,i|
1066
- # xpos = 0
1067
- # mypos = ypos + @rheights[i]
1068
- # row.each_with_index do |child,j|
1069
- # mxpos = xpos + @cwidths[j]
1070
- # if child then
1071
- # # Tune x position.
1072
- # # Find the best delta.
1073
- # bdx = 0 # Best y delta
1074
- # bcost = 1/0.0 # Best score
1075
- # xpos_in_cell = child.xpos - xpos # Initial position in cell
1076
- # xpos_in_cell -= @border if j == 0 # Do not go inside the border
1077
- # (@cwidths[j]-child.width).times do |dx|
1078
- # dx = dx - xpos_in_cell # Adjust delta x to the initial position
1079
- # cost = child.ports.reduce(0) do |sum,port|
1080
- # pxpos = port.xpos + dx
1081
- # sum + port.targets.reduce(0) do |subsum,tport|
1082
- # # There is cost when the port is not align with the target.
1083
- # if (port.side == LEFT and tport.side == RIGHT) or
1084
- # (port.side == UP and tport.side == UP) then
1085
- # # For left to right or up yo up connections,
1086
- # # the first side should be 2 tiles on the left for
1087
- # # straight wire or avoiding routing conjestion.
1088
- # subsum + (pxpos-tport.xpos-2) != 0 ? 1 : 0
1089
- # elsif (port.side == RIGHT and tport.side == LEFT) or
1090
- # (port.side == DOWN and tport.side == DOWN) then
1091
- # # For right to left or down to down connections,
1092
- # # the first side should be 2 tiles on the right for
1093
- # # straight wire or avoiding routing conjestion.
1094
- # subsum + (pxpos-tport.xpos+2) != 0 ? 1 : 0
1095
- # else
1096
- # # Otherwise, perfect aligment is the best.
1097
- # subsum + (pxpos-tport.xpos) != 0 ? 1 : 0
1098
- # end
1099
- # end
1100
- # end
1101
- # if cost < bcost then
1102
- # bcost = cost
1103
- # bdx = dx
1104
- # end
1105
- # end
1106
- # # Ensure the child does not goes out of its cell.
1107
- # if child.xpos + bdx < xpos then
1108
- # bdx = xpos - child.xpos
1109
- # elsif child.xpos + child.width + bdx >= mxpos then
1110
- # bdx = mxpos - child.xpos - child.width - 1
1111
- # end
1112
- # # Apply the best delta.
1113
- # child.xpos += bdx
1114
- # # Update the ports position.
1115
- # child.ports.each {|port| port.xpos += bdx }
1116
-
1117
- # # Tune y position.
1118
- # puts "for child=#{child.name}"
1119
- # # Find the best delta.
1120
- # bdy = 0 # Best x delta
1121
- # bcost = 1/0.0 # Best score
1122
- # ypos_in_cell = child.ypos - ypos # Initial position in cell
1123
- # ypos_in_cell -= @border if i == 0 # Do not go to the outer border
1124
- # (@rheights[i]-child.height).times do |dy|
1125
- # dy = dy - ypos_in_cell # Adjust dela y with initial position
1126
- # cost = child.ports.reduce(0) do |sum,port|
1127
- # pypos = port.ypos + dy
1128
- # sum + port.targets.reduce(0) do |subsum,tport|
1129
- # # There is cost when the port is not align with the target.
1130
- # if (port.side == UP and tport.side == DOWN) or
1131
- # (port.side == RIGHT and tport.side == RIGHT) then
1132
- # # For up to down or right to right connections,
1133
- # # the first side should be 2 tiles on the right for
1134
- # # straight wire or avoiding routing conjestion.
1135
- # subsum + (pypos-tport.ypos+2) != 0 ? 1 : 0
1136
- # elsif (port.side == DOWN and tport.side == UP) or
1137
- # (port.side == LEFT and tport.side == LEFT) then
1138
- # # For down to up or left to left connections,
1139
- # # the forst side should be 2 tiles on the down for
1140
- # # straight wire or avoiding routing conjestion.
1141
- # subsum + (pypos-tport.ypos-2) != 0 ? 1 : 0
1142
- # else
1143
- # subsum + (pypos-tport.ypos) != 0 ? 1 : 0
1144
- # end
1145
- # end
1146
- # end
1147
- # if cost < bcost then
1148
- # bcost = cost
1149
- # bdy = dy
1150
- # end
1151
- # end
1152
- # # puts "mypos=#{mypos} child.ypos=#{child.ypos} bdy=#{bdy}"
1153
- # # Ensure the child does not goes out of its cell.
1154
- # if child.ypos + bdy < ypos then
1155
- # bdy = ypos - child.ypos
1156
- # elsif child.ypos + child.height + bdy >= mypos then
1157
- # bdy = mypos - child.ypos - child.height - 1
1158
- # end
1159
- # # Apply the best delta.
1160
- # child.ypos += bdy
1161
- # # Update the ports position.
1162
- # child.ports.each {|port| port.ypos += bdy }
1163
- # end
1164
- # xpos += @cwidths[j]
1165
- # end
1166
- # ypos += @rheights[i]
1167
- # end
1168
1103
 
1169
- # First prepare the algorthims: sort the children for
1104
+ # First prepare the algorthms: sort the children for
1170
1105
  # vertical and horizontal processing and locate their
1171
1106
  # respective row and column intervals.
1172
1107
  # Sort the children by decreasing number of left and right ports,
@@ -1547,152 +1482,342 @@ module HDLRuby::Viz
1547
1482
  return (pos0[0] - pos1[0]).abs + (pos0[1] - pos1[1]).abs
1548
1483
  end
1549
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
+
1550
1512
  # Check if there is a port at location +pos+ in +side+ that conflict
1551
1513
  # with both +port0+ and +port1+.
1552
- def ic_port_conflict(port0,port1,pos,side)
1553
- return false unless @route_matrix[pos[1]]
1554
- return false unless @route_matrix[pos[1]][pos[0]]
1555
- ic = @route_matrix[pos[1]][pos[0]].ic
1556
- return false unless ic # No IC here, so not possible port to conflict
1557
- # There is an IC get the port at pos from side if any.
1558
- p = nil
1559
- case side
1560
- when LEFT
1561
- port = ic.lports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
1562
- when UP
1563
- port = ic.uports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
1564
- when RIGHT
1565
- port = ic.rports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
1566
- when DOWN
1567
- port = ic.dports.find {|p| p.xpos==pos[0] && p.ypos==pos[1] }
1568
- end
1569
- if port and port != port0 and port != port1 then
1570
- return true
1571
- else
1572
- return false
1573
- end
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
1574
1541
  end
1575
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
1576
1684
  # Get the neighbor free positions for port.
1685
+ res = p0 = p1 = nil
1577
1686
  def free_neighbors(port0,port1,cpos)
1578
1687
  res = []
1579
1688
  # For cosmetic reasons of the wires, the order of processing depends
1580
1689
  # on the relative position of the ports.
1581
1690
  if port0.xpos < port1.xpos and port0.ypos < port1.ypos then
1582
1691
  # 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)
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)
1588
1698
  end
1589
1699
  # Up neighbor.
1590
- upos = [cpos[0],cpos[1]+1]
1591
- if upos[1] < @route_height then
1592
- elem = @route_matrix[upos[1]][upos[0]]
1593
- res << upos if elem.free_from_down?(port0,port1) and
1594
- !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
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)
1595
1706
  end
1596
1707
  # Right neighbor.
1597
- rpos = [cpos[0]+1,cpos[1]]
1598
- if rpos[0] < @route_width then
1599
- elem = @route_matrix[rpos[1]][rpos[0]]
1600
- res << rpos if elem.free_from_left?(port0,port1) and
1601
- !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
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)
1602
1714
  end
1603
1715
  # Down neighbor.
1604
- dpos = [cpos[0],cpos[1]-1]
1605
- if dpos[1] >= 0 then
1606
- elem = @route_matrix[dpos[1]][dpos[0]]
1607
- res << dpos if elem.free_from_up?(port0,port1) and
1608
- !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
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)
1609
1722
  end
1610
1723
  elsif port0.xpos < port1.xpos and port0.ypos > port1.ypos then
1611
1724
  # Left neighbor.
1612
- lpos = [cpos[0]-1,cpos[1]]
1613
- if lpos[0] >= 0 then
1614
- elem = @route_matrix[lpos[1]][lpos[0]]
1615
- res << lpos if elem.free_from_right?(port0,port1) and
1616
- !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
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)
1617
1731
  end
1618
1732
  # Down neighbor.
1619
- dpos = [cpos[0],cpos[1]-1]
1620
- if dpos[1] >= 0 then
1621
- elem = @route_matrix[dpos[1]][dpos[0]]
1622
- res << dpos if elem.free_from_up?(port0,port1) and
1623
- !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
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)
1624
1739
  end
1625
1740
  # Right neighbor.
1626
- rpos = [cpos[0]+1,cpos[1]]
1627
- if rpos[0] < @route_width then
1628
- elem = @route_matrix[rpos[1]][rpos[0]]
1629
- res << rpos if elem.free_from_left?(port0,port1) and
1630
- !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
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)
1631
1747
  end
1632
1748
  # Up neighbor.
1633
- upos = [cpos[0],cpos[1]+1]
1634
- if upos[1] < @route_height then
1635
- elem = @route_matrix[upos[1]][upos[0]]
1636
- res << upos if elem.free_from_down?(port0,port1) and
1637
- !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
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)
1638
1755
  end
1639
1756
  elsif port0.xpos > port1.xpos and port0.ypos > port1.ypos then
1640
1757
  # Right neighbor.
1641
- rpos = [cpos[0]+1,cpos[1]]
1642
- if rpos[0] < @route_width then
1643
- elem = @route_matrix[rpos[1]][rpos[0]]
1644
- res << rpos if elem.free_from_left?(port0,port1) and
1645
- !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
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)
1646
1764
  end
1647
1765
  # Down neighbor.
1648
- dpos = [cpos[0],cpos[1]-1]
1649
- if dpos[1] >= 0 then
1650
- elem = @route_matrix[dpos[1]][dpos[0]]
1651
- res << dpos if elem.free_from_up?(port0,port1) and
1652
- !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
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)
1653
1772
  end
1654
1773
  # Left neighbor.
1655
- lpos = [cpos[0]-1,cpos[1]]
1656
- if lpos[0] >= 0 then
1657
- elem = @route_matrix[lpos[1]][lpos[0]]
1658
- res << lpos if elem.free_from_right?(port0,port1) and
1659
- !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
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)
1660
1780
  end
1661
1781
  # Up neighbor.
1662
- upos = [cpos[0],cpos[1]+1]
1663
- if upos[1] < @route_height then
1664
- elem = @route_matrix[upos[1]][upos[0]]
1665
- res << upos if elem.free_from_down?(port0,port1) and
1666
- !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
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)
1667
1788
  end
1668
1789
  else
1669
1790
  # Right neighbor.
1670
- rpos = [cpos[0]+1,cpos[1]]
1671
- if rpos[0] < @route_width then
1672
- elem = @route_matrix[rpos[1]][rpos[0]]
1673
- res << rpos if elem.free_from_left?(port0,port1) and
1674
- !ic_port_conflict(port0,port1,[rpos[0]+1,rpos[1]],LEFT)
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)
1675
1797
  end
1676
1798
  # Up neighbor.
1677
- upos = [cpos[0],cpos[1]+1]
1678
- if upos[1] < @route_height then
1679
- elem = @route_matrix[upos[1]][upos[0]]
1680
- res << upos if elem.free_from_down?(port0,port1) and
1681
- !ic_port_conflict(port0,port1,[upos[0],upos[1]+1],DOWN)
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)
1682
1805
  end
1683
1806
  # Left neighbor.
1684
- lpos = [cpos[0]-1,cpos[1]]
1685
- if lpos[0] >= 0 then
1686
- elem = @route_matrix[lpos[1]][lpos[0]]
1687
- res << lpos if elem.free_from_right?(port0,port1) and
1688
- !ic_port_conflict(port0,port1,[lpos[0]-1,lpos[1]],RIGHT)
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)
1689
1813
  end
1690
1814
  # Down neighbor.
1691
- dpos = [cpos[0],cpos[1]-1]
1692
- if dpos[1] >= 0 then
1693
- elem = @route_matrix[dpos[1]][dpos[0]]
1694
- res << dpos if elem.free_from_up?(port0,port1) and
1695
- !ic_port_conflict(port0,port1,[dpos[0],dpos[1]-1],UP)
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)
1696
1821
  end
1697
1822
  end
1698
1823
  # Return the free neigbor positions.
@@ -1772,6 +1897,20 @@ module HDLRuby::Viz
1772
1897
  ((pos0[1]-pos1[1]).abs < 2 and pos0[0] == pos1[0]))
1773
1898
  end
1774
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
+
1775
1914
  # Route from +port0+ to +port1.
1776
1915
  # NOTE: uses the A* algorithm with taxi cab distance.
1777
1916
  def connection_route(port0,port1)
@@ -1780,18 +1919,22 @@ module HDLRuby::Viz
1780
1919
  pos0 = [port0.xpos,port0.ypos]
1781
1920
  pos1 = [port1.xpos,port1.ypos]
1782
1921
  oset = [pos0]
1783
- oset << pos0
1784
1922
  from = { }
1785
1923
  gscore = Array.new(@route_matrix.size) { Array.new(@route_matrix[0].size) { 1/0.0 } }
1786
1924
  gscore[pos0[1]][pos0[0]] = 0
1787
- 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 } }
1788
1927
  fscore[pos0[1]][pos0[0]] = taxi_distance(pos0,pos1)
1928
+
1929
+ closed = { } # Closed set
1789
1930
  while oset.any? do
1790
1931
  # Pick the position from oset with the minimum fscore.
1791
- cpos = nil # Current position
1792
- mscore = 1/0.0 # Minimum score
1932
+ # cpos = nil # Current position
1933
+ # mscore = 1/0.0 # Minimum score
1793
1934
  # The best score is necessily at the end of oset.
1794
1935
  cpos = oset.pop
1936
+ next if closed[cpos] # Skip already teated position
1937
+ closed[cpos] = true
1795
1938
  # puts "cpos=#{cpos}"
1796
1939
  if touch?(cpos,pos1) then
1797
1940
  # The goal is reached.
@@ -1800,20 +1943,31 @@ module HDLRuby::Viz
1800
1943
  end
1801
1944
  # Get the neighbor positions for port.
1802
1945
  poses = free_neighbors(port0,port1,cpos)
1946
+ #BENDCOST
1947
+ ppos = poses.first
1948
+ pdir = nil
1803
1949
  poses.each do |pos|
1804
1950
  # Try it.
1805
- tscore = gscore[cpos[1]][cpos[0]] + cost_position(port0,pos)
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)
1806
1956
  if tscore < gscore[pos[1]][pos[0]] then
1807
1957
  # This path to neigbor is better than any previous one, keep it.
1808
1958
  from[pos] = cpos
1809
1959
  gscore[pos[1]][pos[0]] = tscore
1810
1960
  fscore[pos[1]][pos[0]] = tscore + taxi_distance(pos,pos1)
1811
- idx = oset.bsearch_index {|p| fscore[p[1]][p[0]] <= fscore[pos[1]][pos[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]] }
1812
1963
  if idx then
1813
1964
  oset.insert(idx,pos)
1814
1965
  else
1815
1966
  oset << pos
1816
1967
  end
1968
+ #BENDCOST
1969
+ ppos = pos
1970
+ pdir = dir
1817
1971
  end
1818
1972
  end
1819
1973
  end
@@ -1856,6 +2010,7 @@ module HDLRuby::Viz
1856
2010
  (to_route.size/2).times do |epoch|
1857
2011
  puts "Routing epoch=#{epoch}..."
1858
2012
  self.init_route # Reinitialize the route matrix.
2013
+ build_port_conflict_cache
1859
2014
  routed_pairs = [] # The list of already routed pair of ports.
1860
2015
  @routes = [] # The list of created routes.
1861
2016
  # Do the routing.
@@ -1947,6 +2102,7 @@ module HDLRuby::Viz
1947
2102
  route.path.append([eport.xpos,eport.ypos-1])
1948
2103
  end
1949
2104
  end
2105
+ # Add the wires to the tiles.
1950
2106
  route.path.each_cons(3).with_index do |((x0,y0),(x1,y1),(x2,y2)),i|
1951
2107
  # puts "x0,y0=#{x0},#{y0} x1,y1=#{x1},#{y1} x2,y2=#{x2},#{y2}"
1952
2108
  # puts "i=#{i} dir=#{dir}"
@@ -2185,6 +2341,14 @@ module HDLRuby::Viz
2185
2341
  puts "matrix:"
2186
2342
  matrix.each { |row| puts "#{row.map{|ic| ic ? ic.name : " " }}" }
2187
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
+
2188
2352
  # Compute the side of the ports.
2189
2353
  self.bounding_children
2190
2354
 
@@ -2201,7 +2365,8 @@ module HDLRuby::Viz
2201
2365
  end
2202
2366
 
2203
2367
  # For the children.
2204
- self.side_children
2368
+ # self.side_children
2369
+ self.side_children(ic_matrix_coordinates)
2205
2370
 
2206
2371
  puts "Children ports side results: "
2207
2372
  self.children.each_with_index do |child|
@@ -2314,51 +2479,54 @@ module HDLRuby::Viz
2314
2479
  # Generate a system description SVG text for +ic+
2315
2480
  def system_svg(ic)
2316
2481
  return "<rect fill=\"#fff\" stroke=\"#000\" " +
2317
- "stroke-width=\"#{@scale/8.0}\" " +
2318
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2319
- "width=\"#{ic.width*@scale}\" "+
2320
- "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"
2321
2486
  end
2322
2487
 
2323
2488
  # Generate an instance description SVG text for +ic+
2324
2489
  def instance_svg(ic)
2325
- id = Viz.to_svg_id(ic.name)
2490
+ # id = Viz.to_svg_id(ic.name)
2491
+ id = ic.__id__.to_s
2326
2492
  # The rectangle representing the instance.
2327
2493
  res = "<rect id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
2328
- "stroke-width=\"#{@scale/12.0}\" " +
2329
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2330
- "width=\"#{ic.width*@scale}\" "+
2331
- "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"
2332
2498
  # Its name.
2333
2499
  sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
2334
2500
  res += "<text id=\"text#{id}\" " +
2335
2501
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2336
2502
  "font-family=\"monospace\" font-size=\"1px\" " +
2337
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2338
- "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)}\">" +
2339
2505
  ic.name + "</text>\n"
2340
2506
  # Its text resizing.
2341
- res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
2342
- 0.6*@scale)
2507
+ res += Viz.svg_text_fit("text#{id}",
2508
+ ((ic.width-0.6)*@scale).round(3),
2509
+ (0.6*@scale).round(3))
2343
2510
  return res
2344
2511
  end
2345
2512
 
2346
2513
  # Generate a process description SVG text for +ic+
2347
2514
  def process_svg(ic)
2348
- id = Viz.to_svg_id(ic.name)
2515
+ # id = Viz.to_svg_id(ic.name)
2516
+ id = ic.__id__.to_s
2349
2517
  res = "<rect id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
2350
- "stroke-width=\"#{@scale/16.0}\" " +
2351
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2352
- "rx=\"#{@scale}\" " +
2353
- "width=\"#{ic.width*@scale}\" "+
2354
- "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"
2355
2523
  # Its name.
2356
2524
  sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
2357
2525
  res += "<text id=\"text#{id}\" " +
2358
2526
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2359
2527
  "font-family=\"monospace\" font-size=\"1px\" " +
2360
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2361
- "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)}\">" +
2362
2530
  ic.name + "</text>\n"
2363
2531
  # Its text resizing.
2364
2532
  res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
@@ -2368,26 +2536,27 @@ module HDLRuby::Viz
2368
2536
 
2369
2537
  # Generate a clocked process description SVG text for +ic+
2370
2538
  def clocked_process_svg(ic)
2371
- id = Viz.to_svg_id(ic.name)
2539
+ # id = Viz.to_svg_id(ic.name)
2540
+ id = ic.__id__.to_s
2372
2541
  res = "<rect fill=\"#ddd\" stroke=\"#000\" " +
2373
- "stroke-width=\"#{@scale/32.0}\" " +
2374
- "x=\"#{(ic.xpos-1/16.0)*@scale}\" y=\"#{(ic.ypos-1/16.0)*@scale}\" " +
2375
- "rx=\"#{(1+1/16.0)*@scale}\" " +
2376
- "width=\"#{(ic.width+1/8.0)*@scale}\" "+
2377
- "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"
2378
2547
  res += "<rect id=\"#{id}\" fill=\"#ddd\" stroke=\"#000\" " +
2379
- "stroke-width=\"#{@scale/32.0}\" " +
2380
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2381
- "rx=\"#{@scale}\" " +
2382
- "width=\"#{ic.width*@scale}\" "+
2383
- "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"
2384
2553
  # Its name.
2385
2554
  sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
2386
2555
  res += "<text id=\"text#{id}\" " +
2387
2556
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2388
2557
  "font-family=\"monospace\" font-size=\"1px\" " +
2389
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2390
- "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)}\">" +
2391
2560
  ic.name + "</text>\n"
2392
2561
  # Its text resizing.
2393
2562
  res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
@@ -2397,20 +2566,21 @@ module HDLRuby::Viz
2397
2566
 
2398
2567
  # Generate a timed process description SVG text for +ic+
2399
2568
  def timed_process_svg(ic)
2400
- id = Viz.to_svg_id(ic.name)
2569
+ # id = Viz.to_svg_id(ic.name)
2570
+ id = ic.__id__.to_s
2401
2571
  res = "<rect id=\"#{id}\" fill=\"#bbb\" stroke=\"#000\" " +
2402
- "stroke-width=\"#{@scale/8.0}\" " +
2403
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2404
- "rx=\"#{@scale}\" " +
2405
- "width=\"#{ic.width*@scale}\" "+
2406
- "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"
2407
2577
  # Its name.
2408
2578
  sy = (ic.lports.size.even? and ic.rports.size.even? ) ? 0 : -0.5 # Shift to avoid ports
2409
2579
  res += "<text id=\"text#{id}\" " +
2410
2580
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2411
2581
  "font-family=\"monospace\" font-size=\"1px\" " +
2412
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2413
- "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)}\">" +
2414
2584
  ic.name + "</text>\n"
2415
2585
  # Its text resizing.
2416
2586
  res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
@@ -2420,20 +2590,21 @@ module HDLRuby::Viz
2420
2590
 
2421
2591
  # Generate a register description SVG text for +ic+
2422
2592
  def register_svg(ic)
2423
- id = Viz.to_svg_id(ic.name)
2593
+ # id = Viz.to_svg_id(ic.name)
2594
+ id = ic.__id__.to_s
2424
2595
  res = "<rect id=\"#{id}\" fill=\"#fff\" stroke=\"#000\" " +
2425
- "stroke-width=\"#{@scale/16.0}\" " +
2426
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2427
- "rx=\"#{@scale/4}\" " +
2428
- "width=\"#{ic.width*@scale}\" "+
2429
- "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"
2430
2601
  # Its name.
2431
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).
2432
2603
  res += "<text id=\"text#{id}\" " +
2433
2604
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2434
2605
  "font-family=\"monospace\" font-size=\"1px\" " +
2435
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2436
- "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)}\">" +
2437
2608
  ic.name + "</text>\n"
2438
2609
  # Its text resizing.
2439
2610
  res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
@@ -2443,37 +2614,38 @@ module HDLRuby::Viz
2443
2614
 
2444
2615
  # Generate a memory description SVG text for +ic+
2445
2616
  def memory_svg(ic)
2446
- id = Viz.to_svg_id(ic.name)
2617
+ # id = Viz.to_svg_id(ic.name)
2618
+ id = ic.__id__.to_s
2447
2619
  res = "<rect id=\"#{id}\" fill=\"#fff\" stroke=\"#000\" " +
2448
- "stroke-width=\"#{@scale/16.0}\" " +
2449
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
2450
- "rx=\"#{@scale/4}\" " +
2451
- "width=\"#{ic.width*@scale}\" "+
2452
- "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"
2453
2625
  res += "<rect fill=\"#fff\" stroke=\"#333\" " +
2454
- "stroke-width=\"#{@scale/16.0}\" " +
2455
- "x=\"#{(ic.xpos+1/4.0)*@scale}\" "+
2456
- "y=\"#{(ic.ypos+1/4.0)*@scale}\" " +
2457
- "width=\"#{(ic.width-1/2.0)*@scale}\" "+
2458
- "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"
2459
2631
  res += "<line stroke=\"#333\" " +
2460
- "stroke-width=\"#{@scale/16.0}\" " +
2461
- "x1=\"#{(ic.xpos+1/4.0+1/8.0)*@scale}\" "+
2462
- "y1=\"#{(ic.ypos+1/4.0)*@scale}\" " +
2463
- "x2=\"#{(ic.xpos+1/4.0+1/8.0)*@scale}\" "+
2464
- "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"
2465
2637
  res += "<line stroke=\"#333\" " +
2466
- "stroke-width=\"#{@scale/16.0}\" " +
2467
- "x1=\"#{(ic.xpos+1/4.0)*@scale}\" "+
2468
- "y1=\"#{(ic.ypos+1/4.0+1/8.0)*@scale}\" " +
2469
- "x2=\"#{(ic.xpos+ic.width-1/4.0)*@scale}\" "+
2470
- "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"
2471
2643
  # Its name.
2472
2644
  res += "<text id=\"text#{id}\" " +
2473
2645
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2474
2646
  "font-family=\"monospace\" font-size=\"1px\" " +
2475
- "x=\"#{(ic.xpos + ic.width/2.0 + 1/10.0)*@scale}\" "+
2476
- "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)}\">" +
2477
2649
  ic.name + "</text>\n"
2478
2650
  # Its text resizing.
2479
2651
  res += Viz.svg_text_fit("text#{id}",(ic.width-1.0)*@scale,
@@ -2483,7 +2655,8 @@ module HDLRuby::Viz
2483
2655
 
2484
2656
  # Generate an ALU description SVG text for +ic+
2485
2657
  def alu_svg(ic)
2486
- id = Viz.to_svg_id(ic.name)
2658
+ # id = Viz.to_svg_id(ic.name)
2659
+ id = ic.__id__.to_s
2487
2660
  # Determine the side of the inputs (and consequently of the outputs),
2488
2661
  # and the number of inputs.
2489
2662
  iside = nil
@@ -2516,80 +2689,72 @@ module HDLRuby::Viz
2516
2689
  end
2517
2690
  # Generate the resulting polygon.
2518
2691
  res = "<polygon id=\"#{id}\" fill=\"#eee\" stroke=\"#000\" " +
2519
- "stroke-width=\"#{@scale/16.0}\" " +
2692
+ "stroke-width=\"#{(@scale/16.0).round(3)}\" " +
2520
2693
  "points=\""
2521
2694
  # The result depends on the size of the input.
2522
2695
  case(iside)
2523
2696
  when LEFT
2524
2697
  # The left side
2525
- res += "#{ic.xpos*@scale} #{(ic.ypos)*@scale} "
2698
+ res += "#{(ic.xpos*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
2526
2699
  (inum-1).times do |i|
2527
- res += "#{(ic.xpos)*@scale} #{(ic.ypos+i*leg+0.25)*@scale} "
2528
- res += "#{(ic.xpos)*@scale} #{(ic.ypos+(i+1)*leg-0.25)*@scale} "
2529
- res += "#{(ic.xpos+0.25)*@scale} #{(ic.ypos+(i+1)*leg)*@scale} "
2530
- 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)} "
2531
2704
  end
2532
- res += "#{(ic.xpos)*@scale} #{(ic.ypos+inum*leg)*@scale} "
2705
+ res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+inum*leg)*@scale).round(3)} "
2533
2706
  # The up side
2534
- # res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+inum*leg-1)*@scale} "
2535
- 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)} "
2536
2708
  # The right side.
2537
- # res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+1)*@scale}"
2538
- 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)}"
2539
2710
  # The down side is not necessary, close the shape.
2540
2711
  res += "\"/>"
2541
2712
  when UP
2542
2713
  # The right side
2543
- res += "#{(ic.xpos)*@scale} #{(ic.ypos+ic.height)*@scale} "
2714
+ res += "#{((ic.xpos)*@scale).round(3)} #{((ic.ypos+ic.height)*@scale).round(3)} "
2544
2715
  (inum-1).times do |i|
2545
- res += "#{(ic.xpos+i*leg+0.25)*@scale} #{(ic.ypos+ic.height)*@scale} "
2546
- res += "#{(ic.xpos+(i+1)*leg-0.25)*@scale} #{(ic.ypos+ic.height)*@scale} "
2547
- res += "#{(ic.xpos+(i+1)*leg)*@scale} #{(ic.ypos-0.25+ic.height)*@scale} "
2548
- 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)} "
2549
2720
  end
2550
- 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)} "
2551
2722
  # The up side
2552
- # res += "#{(ic.xpos+inum*leg-1)*@scale} #{(ic.ypos)*@scale} "
2553
- 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)} "
2554
2724
  # The right side.
2555
- # res += "#{(ic.xpos+1)*@scale} #{(ic.ypos)*@scale}"
2556
- 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)}"
2557
2726
  # The down side is not necessary, close the shape.
2558
2727
  res += "\"/>"
2559
2728
  when RIGHT
2560
2729
  # The right side
2561
- res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos)*@scale} "
2730
+ res += "#{((ic.xpos+ic.width)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
2562
2731
  (inum-1).times do |i|
2563
- res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+i*leg+0.25)*@scale} "
2564
- res += "#{(ic.xpos+ic.width)*@scale} #{(ic.ypos+(i+1)*leg-0.25)*@scale} "
2565
- res += "#{(ic.xpos-0.25+ic.width)*@scale} #{(ic.ypos+(i+1)*leg)*@scale} "
2566
- 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)} "
2567
2736
  end
2568
- 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)} "
2569
2738
  # The up side
2570
- # res += "#{(ic.xpos)*@scale} #{(ic.ypos+inum*leg-1)*@scale} "
2571
- 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)} "
2572
2740
  # The right side.
2573
- # res += "#{(ic.xpos)*@scale} #{(ic.ypos+1)*@scale}"
2574
- 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)}"
2575
2742
  # The down side is not necessary, close the shape.
2576
2743
  res += "\"/>"
2577
2744
  when DOWN
2578
2745
  # The down side
2579
- res += "#{ic.xpos*@scale} #{(ic.ypos)*@scale} "
2746
+ res += "#{(ic.xpos*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
2580
2747
  (inum-1).times do |i|
2581
- res += "#{(ic.xpos+i*leg+0.25)*@scale} #{(ic.ypos)*@scale} "
2582
- res += "#{(ic.xpos+(i+1)*leg-0.25)*@scale} #{(ic.ypos)*@scale} "
2583
- res += "#{(ic.xpos+(i+1)*leg)*@scale} #{(ic.ypos+0.25)*@scale} "
2584
- 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)} "
2585
2752
  end
2586
- res += "#{(ic.xpos+inum*leg)*@scale} #{(ic.ypos)*@scale} "
2753
+ res += "#{((ic.xpos+inum*leg)*@scale).round(3)} #{((ic.ypos)*@scale).round(3)} "
2587
2754
  # The up side
2588
- # res += "#{(ic.xpos+inum*leg-1)*@scale} #{(ic.ypos+ic.height)*@scale} "
2589
- 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)} "
2590
2756
  # The right side.
2591
- # res += "#{(ic.xpos+1)*@scale} #{(ic.ypos+ic.height)*@scale}"
2592
- 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)}"
2593
2758
  # The down side is not necessary, close the shape.
2594
2759
  res += "\"/>"
2595
2760
  else
@@ -2601,8 +2766,8 @@ module HDLRuby::Viz
2601
2766
  res += "<text id=\"text#{id}\" " +
2602
2767
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
2603
2768
  "font-family=\"monospace\" font-size=\"1px\" " +
2604
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
2605
- "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)}\">" +
2606
2771
  ic.name + "</text>\n"
2607
2772
  # Its text resizing.
2608
2773
  res += Viz.svg_text_fit("text#{id}",(ic.width-0.6)*@scale,
@@ -2624,12 +2789,12 @@ module HDLRuby::Viz
2624
2789
  else
2625
2790
  res = "<rect fill=\"#ff0\" stroke=\"#000\" "
2626
2791
  end
2627
- res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
2628
- "stroke-width=\"#{@scale/16.0}\" " +
2629
- "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"
2630
2795
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2631
- "points=\"#{xpos},#{ypos+height/2.0} #{xpos+width},#{ypos} " +
2632
- "#{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"
2633
2798
  return res
2634
2799
  end
2635
2800
 
@@ -2645,27 +2810,27 @@ module HDLRuby::Viz
2645
2810
  else
2646
2811
  res = "<rect fill=\"#ff0\" stroke=\"#000\" "
2647
2812
  end
2648
- res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
2649
- "stroke-width=\"#{@scale/16.0}\" " +
2650
- "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"
2651
2816
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2652
- "points=\"#{xpos},#{ypos} #{xpos+width},#{ypos+height/2.0} " +
2653
- "#{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"
2654
2819
  return res
2655
2820
  end
2656
2821
 
2657
2822
  # Generate a left-right port description SVG text.
2658
2823
  def left_right_port_svg(name,type,xpos,ypos,width,height)
2659
2824
  res = "<rect fill=\"#FF0\" stroke=\"#000\" " +
2660
- "x=\"#{xpos}\" y=\"#{ypos}\" " +
2825
+ "x=\"#{xpos.round(3)}\" y=\"#{ypos.round(3)}\" " +
2661
2826
  "stroke-width=\"#{@scale/16.0}\" " +
2662
- "width=\"#{width}\" height=\"#{height}\"/>\n"
2827
+ "width=\"#{width.round(3)}\" height=\"#{height.round(3)}\"/>\n"
2663
2828
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2664
- "points=\"#{xpos},#{ypos+height/2} #{xpos+width},#{ypos} " +
2665
- "#{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"
2666
2831
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2667
- "points=\"#{xpos},#{ypos} #{xpos+width},#{ypos+height/2.0} " +
2668
- "#{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"
2669
2834
  return res
2670
2835
  end
2671
2836
 
@@ -2681,12 +2846,12 @@ module HDLRuby::Viz
2681
2846
  else
2682
2847
  res = "<rect fill=\"#ff0\" stroke=\"#000\" "
2683
2848
  end
2684
- res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
2685
- "stroke-width=\"#{@scale/16.0}\" " +
2686
- "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"
2687
2852
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2688
- "points=\"#{xpos},#{ypos} #{xpos+width/2.0},#{ypos+height} " +
2689
- "#{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"
2690
2855
  return res
2691
2856
  end
2692
2857
 
@@ -2702,27 +2867,27 @@ module HDLRuby::Viz
2702
2867
  else
2703
2868
  res = "<rect fill=\"#ff0\" stroke=\"#000\" "
2704
2869
  end
2705
- res += "x=\"#{xpos}\" y=\"#{ypos}\" " +
2706
- "stroke-width=\"#{@scale/16.0}\" " +
2707
- "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"
2708
2873
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2709
- "points=\"#{xpos+width/2.0},#{ypos} #{xpos},#{ypos+height} " +
2710
- "#{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"
2711
2876
  return res
2712
2877
  end
2713
2878
 
2714
2879
  # Generate an up-down port description SVG text.
2715
2880
  def up_down_port_svg(name,type,xpos,ypos,width,height)
2716
2881
  res = "<rect fill=\"#FF0\" stroke=\"#000\" " +
2717
- "x=\"#{xpos}\" y=\"#{ypos}\" " +
2718
- "stroke-width=\"#{@scale/16.0}\" " +
2719
- "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"
2720
2885
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2721
- "points=\"#{xpos},#{ypos} #{xpos+width/2},#{ypos+height} " +
2722
- "#{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"
2723
2888
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
2724
- "points=\"#{xpos+width/2.0},#{ypos} #{xpos},#{ypos+height} " +
2725
- "#{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"
2726
2891
  return res
2727
2892
  end
2728
2893
 
@@ -2805,17 +2970,19 @@ module HDLRuby::Viz
2805
2970
  res += "</style>\n"
2806
2971
 
2807
2972
  # Generate the group containing all the IC description.
2808
- 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}\" " +
2809
2976
  "transform=\"translate(#{tx},#{ty})\">\n"
2810
2977
  # Generate the rectangle of the bounding box.
2811
2978
  res += "<rect fill=\"#bbb\" stroke=\"#555\" " +
2812
- "stroke-width=\"#{@scale/4.0}\" " +
2979
+ "stroke-width=\"#{(@scale/4.0).round(3)}\" " +
2813
2980
  # "x=\"#{x0-bT*2.5}\" y=\"#{y0-bT*2.5}\" "+
2814
- "x=\"#{x0}\" y=\"#{y0}\" "+
2981
+ "x=\"#{x0.round(3)}\" y=\"#{y0.round(3)}\" "+
2815
2982
  "width=\"#{width}\" height=\"#{height}\"/>\n"
2816
2983
 
2817
2984
  # Generate the group containing the top system and its contents.
2818
- res += "<g transform=\"translate(#{stx},#{sty})\">\n"
2985
+ res += "<g transform=\"translate(#{stx.round(3)},#{sty.round(3)})\">\n"
2819
2986
 
2820
2987
  # Generate current IC's box.
2821
2988
  # The SVG object representing a system.
@@ -2826,9 +2993,9 @@ module HDLRuby::Viz
2826
2993
  row.each_with_index do |tile,x|
2827
2994
  # # Draw the tiles contour for debug.
2828
2995
  # res += "<rect fill=\"none\" stroke=\"#00F\" " +
2829
- # "x=\"#{x*@scale}\" " +
2830
- # "y=\"#{y*@scale}\" " +
2831
- # "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"
2832
2999
  #
2833
3000
  # Draw the wires.
2834
3001
  tile.wires.each do |wire_dir|
@@ -2836,69 +3003,69 @@ module HDLRuby::Viz
2836
3003
  # Draw the wire (as a thin rectangle).
2837
3004
  case wire_dir
2838
3005
  when LEFT|RIGHT
2839
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3006
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2840
3007
  "stroke-linecap=\"round\" " +
2841
- "x1=\"#{(x)*@scale}\" " +
2842
- "y1=\"#{(y+0.5)*@scale}\" " +
2843
- "x2=\"#{(x+1)*@scale}\" " +
2844
- "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"
2845
3012
  when RIGHT|DOWN
2846
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3013
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2847
3014
  "stroke-linecap=\"round\" " +
2848
- "x1=\"#{(x+1)*@scale}\" " +
2849
- "y1=\"#{(y+0.5)*@scale}\" " +
2850
- "x2=\"#{(x+0.5)*@scale}\" " +
2851
- "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"
2852
3019
  when RIGHT|UP
2853
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3020
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2854
3021
  "stroke-linecap=\"round\" " +
2855
- "x1=\"#{(x+1)*@scale}\" " +
2856
- "y1=\"#{(y+0.5)*@scale}\" " +
2857
- "x2=\"#{(x+0.5)*@scale}\" " +
2858
- "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"
2859
3026
  when LEFT|DOWN
2860
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3027
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2861
3028
  "stroke-linecap=\"round\" " +
2862
- "x1=\"#{(x+0.5)*@scale}\" " +
2863
- "y1=\"#{(y)*@scale}\" " +
2864
- "x2=\"#{(x)*@scale}\" " +
2865
- "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"
2866
3033
  when LEFT|UP
2867
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3034
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2868
3035
  "stroke-linecap=\"round\" " +
2869
- "x1=\"#{(x+0.5)*@scale}\" " +
2870
- "y1=\"#{(y+1)*@scale}\" " +
2871
- "x2=\"#{(x)*@scale}\" " +
2872
- "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"
2873
3040
  when UP|DOWN
2874
- res += "<line stroke=\"#000\" stroke-width=\"#{wT}\" " +
3041
+ res += "<line stroke=\"#000\" stroke-width=\"#{wT.round(3)}\" " +
2875
3042
  "stroke-linecap=\"round\" " +
2876
- "x1=\"#{(x+0.5)*@scale}\" " +
2877
- "y1=\"#{(y)*@scale}\" " +
2878
- "x2=\"#{(x+0.5)*@scale}\" " +
2879
- "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"
2880
3047
  end
2881
3048
  end
2882
3049
 
2883
3050
  # Draw the connection points.
2884
3051
  tile.dots.each do |dot_pos|
2885
3052
  res += "<rect fill=\"#000\" stroke=\"#000\" " +
2886
- "stroke-width=\"#{wT}\" "
3053
+ "stroke-width=\"#{wT.round(3)}\" "
2887
3054
  case dot_pos
2888
3055
  when LEFT
2889
- res += "x=\"#{(x+0.0)*@scale-wT*2}\" " +
2890
- "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)}\" "
2891
3058
  when UP
2892
- res += "x=\"#{(x+0.5)*@scale-wT*2}\" " +
2893
- "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)}\" "
2894
3061
  when RIGHT
2895
- res += "x=\"#{(x+1.0)*@scale-wT*2}\" " +
2896
- "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)}\" "
2897
3064
  when DOWN
2898
- res += "x=\"#{(x+0.5)*@scale-wT*2}\" " +
2899
- "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)}\" "
2900
3067
  end
2901
- res += "width=\"#{wT*4}\" height=\"#{wT*4}\"/>\n"
3068
+ res += "width=\"#{(wT*4).round(3)}\" height=\"#{(wT*4).round(3)}\"/>\n"
2902
3069
  end
2903
3070
  end
2904
3071
  end
@@ -2956,20 +3123,20 @@ module HDLRuby::Viz
2956
3123
  port.direction != :none) or child.sub_port?(port) then
2957
3124
  if child == self then
2958
3125
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
2959
- "x=\"#{(port.xpos)*@scale-pT}\" "+
2960
- "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)}\">" +
2961
3128
  self.port_str(port) + "</text>\n"
2962
3129
  elsif (child.type == :assign and port.direction == :input and
2963
3130
  child.ports.size.even? and child.ports.index(port) == child.ports.size/2) then
2964
3131
  # Middle input of an alu, slide it bellow to avoid collision
2965
3132
  # with the output port.
2966
- res += "<text class=\"small#{self.idC}\" x=\"#{(port.xpos)*@scale+pT}\" "+
2967
- "y=\"#{(port.ypos+0.8)*@scale+sF/2.5}\">" +
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)}\">" +
2968
3135
  self.port_str(port) + "</text>\n"
2969
3136
  else
2970
3137
  # General case.
2971
- res += "<text class=\"small#{self.idC}\" x=\"#{(port.xpos)*@scale+pT}\" "+
2972
- "y=\"#{(port.ypos+0.45)*@scale+sF/2.5}\">" +
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)}\">" +
2973
3140
  self.port_str(port) + "</text>\n"
2974
3141
  end
2975
3142
  end
@@ -2997,13 +3164,13 @@ module HDLRuby::Viz
2997
3164
  port.direction != :none) or child.sub_port?(port) then
2998
3165
  if child == self then
2999
3166
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
3000
- "x=\"#{(port.xpos+0.5)*@scale}\" "+
3001
- "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 +
3002
3169
  self.port_str(port) + "</text>\n"
3003
3170
  else
3004
3171
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
3005
- "x=\"#{(port.xpos+0.5)*@scale}\" "+
3006
- "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 +
3007
3174
  self.port_str(port) + "</text>\n"
3008
3175
  end
3009
3176
  end
@@ -3030,21 +3197,21 @@ module HDLRuby::Viz
3030
3197
  port.direction != :none) or child.sub_port?(port) then
3031
3198
  if child == self then
3032
3199
  res += "<text class=\"small#{self.idC}\" " +
3033
- "x=\"#{(port.xpos+1)*@scale+pT}\" " +
3034
- "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 +
3035
3202
  self.port_str(port) + "</text>\n"
3036
3203
  elsif (child.type == :assign and port.direction == :input and
3037
3204
  child.ports.size.even? and child.ports.index(port) == child.ports.size/2) then
3038
3205
  # Middle input of an alu, slide it bellow to avoid collision
3039
3206
  # with the output port.
3040
3207
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
3041
- "x=\"#{(port.xpos+1)*@scale-pT}\" "+
3042
- "y=\"#{(port.ypos+0.8)*@scale+sF/2.5}\">" + # port.name +
3208
+ "x=\"#{((port.xpos+1)*@scale-pT).round(3)}\" "+
3209
+ "y=\"#{((port.ypos+0.8)*@scale+sF/2.5).round(3)}\">" + # port.name +
3043
3210
  self.port_str(port) + "</text>\n"
3044
3211
  else
3045
3212
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: end\" " +
3046
- "x=\"#{(port.xpos+1)*@scale-pT}\" "+
3047
- "y=\"#{(port.ypos+0.45)*@scale+sF/2.5}\">" + # port.name +
3213
+ "x=\"#{((port.xpos+1)*@scale-pT).round(3)}\" "+
3214
+ "y=\"#{((port.ypos+0.45)*@scale+sF/2.5).round(3)}\">" + # port.name +
3048
3215
  self.port_str(port) + "</text>\n"
3049
3216
  end
3050
3217
  end
@@ -3071,14 +3238,13 @@ module HDLRuby::Viz
3071
3238
  port.direction != :none) or child.sub_port?(port) then
3072
3239
  if child == self then
3073
3240
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
3074
- "x=\"#{(port.xpos+0.5)*@scale}\" "+
3075
- "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 +
3076
3243
  self.port_str(port) + "</text>\n"
3077
3244
  else
3078
3245
  res += "<text class=\"small#{self.idC}\" style=\"text-anchor: middle\" " +
3079
- "x=\"#{(port.xpos+0.5)*@scale}\" "+
3080
- # "y=\"#{(port.ypos)*@scale+pT+sF}\">" + # port.name +
3081
- "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 +
3082
3248
  self.port_str(port) + "</text>\n"
3083
3249
  end
3084
3250
  end
@@ -3144,7 +3310,8 @@ module HDLRuby::Viz
3144
3310
  res += target.to_svg(false,ctx*@scale,cty*@scale,
3145
3311
  cwidth*scale,cheight*scale)
3146
3312
  # Generate the closing button element.
3147
- 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)
3148
3315
  end
3149
3316
 
3150
3317
  # Close the group containing the top system and its content.
@@ -3168,20 +3335,20 @@ module HDLRuby::Viz
3168
3335
  next unless target # No target? Skip.
3169
3336
  res += <<~SCRIPT
3170
3337
  <script>
3171
- diagram.getElementById('#{child.name}').addEventListener("click", (e) => {
3338
+ diagram.getElementById('#{child.__id__}').addEventListener("click", (e) => {
3172
3339
  // For the element.
3173
- let elem = diagram.getElementById('#{target.name}');
3340
+ let elem = diagram.getElementById('#{target.__id__}');
3174
3341
  elem.setAttribute('visibility','visible');
3175
3342
  // And its closing button.
3176
- elem = diagram.getElementById('#{target.name}_close');
3343
+ elem = diagram.getElementById('#{target.__id__}_close');
3177
3344
  elem.setAttribute('visibility','visible');
3178
3345
  });
3179
- diagram.getElementById('#{target.name}_close').addEventListener("click", (e) => {
3346
+ diagram.getElementById('#{target.__id__}_close').addEventListener("click", (e) => {
3180
3347
  // For the element.
3181
- let elem = diagram.getElementById('#{target.name}');
3348
+ let elem = diagram.getElementById('#{target.__id__}');
3182
3349
  elem.setAttribute('visibility','hidden');
3183
3350
  // And its closing button.
3184
- elem = diagram.getElementById('#{target.name}_close');
3351
+ elem = diagram.getElementById('#{target.__id__}_close');
3185
3352
  elem.setAttribute('visibility','hidden');
3186
3353
  });
3187
3354
 
@@ -3706,27 +3873,22 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3706
3873
  def assign_svg(n)
3707
3874
  # The shape representing the instance.
3708
3875
  res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
3709
- "stroke-width=\"#{@scale/12.0}\" " +
3710
- # "d=\"M #{n.xpos*@scale} #{(n.ypos + n.height/2.0)*@scale} " +
3711
- # "L #{(n.xpos + 1.0)*@scale} #{n.ypos*@scale} " +
3712
- # "L #{(n.xpos + n.width-n.height/2.0)*@scale} #{n.ypos*@scale} " +
3713
- # "A #{n.height/2.0*@scale} #{n.height/2.0*@scale} 0 0 1 " +
3714
- # "#{(n.xpos + n.width-n.height/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
3715
- # "L #{(n.xpos + 1.0)*@scale} #{(n.ypos+n.height)*@scale} " +
3716
- "d=\"M #{n.xpos*@scale} #{(n.ypos + n.height)*@scale} " +
3717
- "L #{(n.xpos + 1.0)*@scale} #{n.ypos*@scale} " +
3718
- "L #{(n.xpos + n.width)*@scale} #{n.ypos*@scale} " +
3719
- "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)} " +
3720
3881
  "Z \" />\n"
3721
3882
  # Its text.
3722
- res += "<text id=\"text#{n.name}\" " +
3883
+ # res += "<text id=\"text#{n.name}\" " +
3884
+ res += "<text id=\"text#{n.__id__}\" " +
3723
3885
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3724
3886
  "font-family=\"monospace\" font-size=\"1px\" " +
3725
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
3726
- "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)}\">" +
3727
3889
  n.to_s + "</text>\n"
3728
3890
  # Its text resizing.
3729
- res += Viz.svg_text_fit("text#{n.name}",(n.width-2)*@scale,
3891
+ res += Viz.svg_text_fit("text#{n.__id__}",(n.width-2)*@scale,
3730
3892
  0.6*@scale)
3731
3893
  return res
3732
3894
  end
@@ -3734,35 +3896,12 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3734
3896
  # Generate a block description SVG text for node +n+
3735
3897
  def block_svg(n)
3736
3898
  res = "<rect fill=\"#fff\" fill-opacity=\"0.4\" stroke=\"#000\" " +
3737
- "stroke-width=\"#{@scale/10.0}\" " +
3738
- "stroke-dasharray=\"#{@scale/10.0},#{@scale/10.0}\" " +
3739
- # "x=\"#{n.xpos*@scale}\" y=\"#{n.ypos*@scale}\" " +
3740
- # "rx=\"#{@scale*2.0}\" " +
3741
- # "width=\"#{n.width*@scale}\" "+
3742
- # "height=\"#{n.height*@scale}\"/>\n"
3743
- "x=\"#{(n.xpos-0.3)*@scale}\" y=\"#{(n.ypos-0.3)*@scale}\" " +
3744
- "rx=\"#{@scale*0.6}\" " +
3745
- "width=\"#{(n.width+0.6)*@scale}\" "+
3746
- "height=\"#{(n.height+0.6)*@scale}\"/>\n"
3747
- return res
3748
- end
3749
-
3750
- # Generate an operator description SVG text for node +n+
3751
- def operator_svg(n)
3752
- ICIICI
3753
- res = "<rect fill=\"#eee\" stroke=\"#000\" " +
3754
- "stroke-width=\"#{@scale/16.0}\" " +
3755
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
3756
- "rx=\"#{@scale}\" " +
3757
- "width=\"#{ic.width*@scale}\" "+
3758
- "height=\"#{ic.height*@scale}\"/>\n"
3759
- # Its name.
3760
- res += "<text class=\"medium#{self.idC}\" " +
3761
- "style=\"inline-size=#{ic.width*@scale}px; text-anchor: middle; " +
3762
- "dominant-baseline: middle;\" " +
3763
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
3764
- "y=\"#{(ic.ypos + ic.height/2.0)*@scale}\">" +
3765
- 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"
3766
3905
  return res
3767
3906
  end
3768
3907
 
@@ -3770,23 +3909,23 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3770
3909
  def terminal_svg(n)
3771
3910
  ICIICI
3772
3911
  res = "<rect fill=\"#ddd\" stroke=\"#000\" " +
3773
- "stroke-width=\"#{@scale/32.0}\" " +
3774
- "x=\"#{(ic.xpos-1/16.0)*@scale}\" y=\"#{(ic.ypos-1/16.0)*@scale}\" " +
3775
- "rx=\"#{(1+1/16.0)*@scale}\" " +
3776
- "width=\"#{(ic.width+1/8.0)*@scale}\" "+
3777
- "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"
3778
3917
  res += "<rect fill=\"#ddd\" stroke=\"#000\" " +
3779
- "stroke-width=\"#{@scale/32.0}\" " +
3780
- "x=\"#{ic.xpos*@scale}\" y=\"#{ic.ypos*@scale}\" " +
3781
- "rx=\"#{@scale}\" " +
3782
- "width=\"#{ic.width*@scale}\" "+
3783
- "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"
3784
3923
  # Its name.
3785
3924
  res += "<text class=\"medium#{self.idC}\" " +
3786
3925
  "style=\"inline-size=#{ic.width*@scale}px; text-anchor: middle; " +
3787
3926
  "dominant-baseline: middle;\" " +
3788
- "x=\"#{(ic.xpos + ic.width/2.0)*@scale}\" "+
3789
- "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)}\">" +
3790
3929
  ic.name + "</text>\n"
3791
3930
  return res
3792
3931
  end
@@ -3796,36 +3935,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3796
3935
  def if_svg(n,no=false)
3797
3936
  # The shape representing the instance.
3798
3937
  res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
3799
- "stroke-width=\"#{@scale/12.0}\" " +
3800
- "d=\"M #{(n.xpos)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
3801
- "L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
3802
- "L #{(n.xpos+n.width)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
3803
- "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)} " +
3804
3943
  "Z \" />\n"
3805
3944
  # Its text.
3806
- res += "<text id=\"text#{n.name}\" " +
3945
+ # res += "<text id=\"text#{n.name}\" " +
3946
+ res += "<text id=\"text#{n.__id__}\" " +
3807
3947
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3808
3948
  "font-family=\"monospace\" font-size=\"1px\" " +
3809
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
3810
- "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)}\">" +
3811
3951
  n.to_s + "</text>\n"
3812
3952
  # Its text resizing.
3813
- 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,
3814
3956
  0.6*@scale)
3815
3957
  # The yes text.
3816
3958
  res += "<text " +
3817
3959
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3818
- "font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
3819
- "x=\"#{(n.xpos + n.width+0.1)*@scale}\" "+
3820
- "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)}\">" +
3821
3963
  "Yes" + "</text>\n"
3822
3964
  # The no text if any.
3823
3965
  if no then
3824
3966
  res += "<text " +
3825
3967
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3826
- "font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
3827
- "x=\"#{(n.xpos + n.width/2.0+0.7)*@scale}\" "+
3828
- "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)}\">" +
3829
3971
  "No" + "</text>\n"
3830
3972
  end
3831
3973
  return res
@@ -3836,36 +3978,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3836
3978
  def case_svg(n,no=false)
3837
3979
  # The shape representing the instance.
3838
3980
  res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
3839
- "stroke-width=\"#{@scale/12.0}\" " +
3840
- "d=\"M #{(n.xpos)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
3841
- "L #{(n.xpos+n.width/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
3842
- "L #{(n.xpos+n.width)*@scale} #{(n.ypos+n.height/2.0)*@scale} " +
3843
- "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)} " +
3844
3986
  "Z \" />\n"
3845
3987
  # Its text.
3846
- res += "<text id=\"text#{n.name}\" " +
3988
+ # res += "<text id=\"text#{n.name}\" " +
3989
+ res += "<text id=\"text#{n.__id__}\" " +
3847
3990
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3848
3991
  "font-family=\"monospace\" font-size=\"1px\" " +
3849
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
3850
- "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)}\">" +
3851
3994
  n.to_s + "</text>\n"
3852
3995
  # Its text resizing.
3853
- 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,
3854
3999
  0.6*@scale)
3855
4000
  # The yes text.
3856
4001
  res += "<text " +
3857
4002
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3858
- "font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
3859
- "x=\"#{(n.xpos + n.width+0.1)*@scale}\" "+
3860
- "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)}\">" +
3861
4006
  "Yes" + "</text>\n"
3862
4007
  # The no text if any.
3863
4008
  if no then
3864
4009
  res += "<text " +
3865
4010
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3866
- "font-family=\"monospace\" font-size=\"#{@scale/2.0}px\" " +
3867
- "x=\"#{(n.xpos + n.width/2.0+0.7)*@scale}\" "+
3868
- "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)}\">" +
3869
4014
  "No" + "</text>\n"
3870
4015
  end
3871
4016
  return res
@@ -3875,22 +4020,25 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3875
4020
  def wait_svg(n)
3876
4021
  # The shape representing the instance.
3877
4022
  res = "<path fill=\"#B0E2FF\" stroke=\"#000\" " +
3878
- "stroke-width=\"#{@scale/12.0}\" " +
3879
- "d=\"M #{n.xpos*@scale} #{(n.ypos)*@scale} " +
3880
- "L #{(n.xpos + n.width-n.height/2.0)*@scale} #{n.ypos*@scale} " +
3881
- "A #{n.height/2.0*@scale} #{n.height/2.0*@scale} 0 0 1 " +
3882
- "#{(n.xpos + n.width-n.height/2.0)*@scale} #{(n.ypos+n.height)*@scale} " +
3883
- "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)} " +
3884
4029
  "Z \" />\n"
3885
4030
  # Its text.
3886
- res += "<text id=\"text#{n.name}\" " +
4031
+ # res += "<text id=\"text#{n.name}\" " +
4032
+ res += "<text id=\"text#{n.__id__}\" " +
3887
4033
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3888
4034
  "font-family=\"monospace\" font-size=\"1px\" " +
3889
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
3890
- "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)}\">" +
3891
4037
  n.to_s + "</text>\n"
3892
4038
  # Its text resizing.
3893
- 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,
3894
4042
  0.6*@scale)
3895
4043
  return res
3896
4044
  end
@@ -3905,21 +4053,24 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3905
4053
  def terminate_svg(n)
3906
4054
  # The shape representing the instance.
3907
4055
  res = "<ellipse fill=\"#CC0202\" stroke=\"#000\" " +
3908
- "stroke-width=\"#{@scale/12.0}\" " +
3909
- "cx=\"#{n.xpos*@scale+n.width*@scale/2.0}\" " +
3910
- "cy=\"#{(n.ypos)*@scale+n.height*@scale/2.0}\" " +
3911
- "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)}\" " +
3912
4060
  "/>\n"
3913
4061
  # Its text.
3914
- res += "<text id=\"text#{n.name}\" " +
4062
+ # res += "<text id=\"text#{n.name}\" " +
4063
+ res += "<text id=\"text#{n.__id__}\" " +
3915
4064
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3916
4065
  "font-family=\"monospace\" font-size=\"1px\" " +
3917
4066
  "fill=\"white\" " +
3918
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" " +
3919
- "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)}\">" +
3920
4069
  "Terminate" + "</text>\n"
3921
4070
  # Its text resizing.
3922
- 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,
3923
4074
  0.6*@scale)
3924
4075
  return res
3925
4076
  end
@@ -3928,19 +4079,22 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3928
4079
  def print_svg(n)
3929
4080
  # The shape representing the instance.
3930
4081
  res = "<rect fill=\"#B0E2FF\" stroke=\"#000\" " +
3931
- "stroke-width=\"#{@scale/12.0}\" " +
3932
- "x=\"#{n.xpos*@scale}\" y=\"#{(n.ypos)*@scale}\" " +
3933
- "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)}\" " +
3934
4085
  "/>\n"
3935
4086
  # Its text.
3936
- res += "<text id=\"text#{n.name}\" " +
4087
+ # res += "<text id=\"text#{n.name}\" " +
4088
+ res += "<text id=\"text#{n.__id__}\" " +
3937
4089
  "style=\"text-anchor: middle; dominant-baseline: middle;\" " +
3938
4090
  "font-family=\"monospace\" font-size=\"1px\" " +
3939
- "x=\"#{(n.xpos + n.width/2.0)*@scale}\" "+
3940
- "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)}\">" +
3941
4093
  n.to_s + "</text>\n"
3942
4094
  # Its text resizing.
3943
- 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,
3944
4098
  0.6*@scale)
3945
4099
  return res
3946
4100
  end
@@ -3951,39 +4105,39 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
3951
4105
  # Draw the line.
3952
4106
  # Vertical part
3953
4107
  res = "<line stroke=\"#000\" " +
3954
- "stroke-width=\"#{@scale/12.0}\" stroke-linecap=\"round\" " +
3955
- "x1=\"#{x0*@scale}\" " +
3956
- "y1=\"#{y0*@scale}\" " +
3957
- "x2=\"#{x0*@scale}\" " +
3958
- "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)}\" " +
3959
4113
  "/>\n"
3960
4114
  # Horizontal part
3961
4115
  res += "<line stroke=\"#000\" " +
3962
- "stroke-width=\"#{@scale/12.0}\" stroke-linecap=\"round\" " +
3963
- "x1=\"#{x0*@scale}\" " +
3964
- "y1=\"#{y1*@scale}\" " +
3965
- "x2=\"#{x1*@scale}\" " +
3966
- "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)}\" " +
3967
4121
  "/>\n"
3968
4122
  # The head.
3969
4123
  if x0 == x1 then
3970
4124
  # Vertical case
3971
4125
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
3972
- "points=\"#{(x1-1/4.0)*@scale},#{(y1-1/2.0-1/8.0)*@scale} " +
3973
- "#{(x1+1/4.0)*@scale},#{(y1-1/2.0-1/8.0)*@scale} " +
3974
- "#{(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"
3975
4129
  elsif x0 < x1 then
3976
4130
  # Horizontal left case: always end horizontally.
3977
4131
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
3978
- "points=\"#{(x1-1/2.0)*@scale},#{(y1-1/4.0)*@scale} " +
3979
- "#{(x1-1/2.0)*@scale},#{(y1+1/4.0)*@scale} " +
3980
- "#{(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"
3981
4135
  else
3982
4136
  # Horizontal right case: always end horizontally.
3983
4137
  res += "<polygon fill=\"#000\" stroke=\"none\" " +
3984
- "points=\"#{(x1)*@scale},#{(y1+1/4.0)*@scale} " +
3985
- "#{(x1)*@scale},#{(y1-1/4.0)*@scale} " +
3986
- "#{(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"
3987
4141
  end
3988
4142
  return res
3989
4143
  end
@@ -4076,17 +4230,18 @@ diagram.getElementById('#{target.name}_close').addEventListener("click", (e) =>
4076
4230
  # res += "</style>\n"
4077
4231
 
4078
4232
  # Generate the group containing all the flow description.
4079
- res += "<g id=\"#{self.name}\" visibility=\"#{visibility}\" " +
4080
- "transform=\"translate(#{tx},#{ty})\">\n"
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"
4081
4237
  # Generate the rectangle of the bounding box.
4082
4238
  res += "<rect fill=\"#4682B4\" stroke=\"#007\" " +
4083
- "stroke-width=\"#{@scale/4.0}\" " +
4084
- # "x=\"#{x0-bT*2.5}\" y=\"#{y0-bT*2.5}\" "+
4085
- "x=\"#{x0}\" y=\"#{y0}\" "+
4086
- "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"
4087
4242
 
4088
4243
  # Generate the group containing the top system and its contents.
4089
- res += "<g transform=\"translate(#{stx},#{sty})\">\n"
4244
+ res += "<g transform=\"translate(#{stx.round(3)},#{sty.round(3)})\">\n"
4090
4245
 
4091
4246
  # Generate the node boxes.
4092
4247
  puts "Generate node box for self.type=#{self.type}"
@@ -4243,19 +4398,19 @@ SVG
4243
4398
  res = "<g id=\"#{name}\" visibility=\"#{visibility}\">\n"
4244
4399
  end
4245
4400
  res += "<rect fill=\"#cd5c5c\" "+
4246
- "stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
4247
- "x=\"#{xpos}\" y=\"#{ypos}\" " +
4248
- "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"
4249
4404
  # The cross lines.
4250
- res += "<line stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
4405
+ res += "<line stroke=\"#000\" stroke-width=\"#{(side/8.0).round(3)}\" " +
4251
4406
  "stroke-linecap=\"butt\" " +
4252
- "x1=\"#{xpos}\" y1=\"#{ypos}\" " +
4253
- "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)}\" " +
4254
4409
  " />\n"
4255
- res += "<line stroke=\"#000\" stroke-width=\"#{side/8.0}\" " +
4410
+ res += "<line stroke=\"#000\" stroke-width=\"#{(side/8.0).round(3)}\" " +
4256
4411
  "stroke-linecap=\"butt\" " +
4257
- "x1=\"#{xpos+side}\" y1=\"#{ypos}\" " +
4258
- "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)}\" " +
4259
4414
  " />\n"
4260
4415
  res += "</g>"
4261
4416
  end
@@ -4268,10 +4423,10 @@ SVG
4268
4423
  // Helping button.
4269
4424
  <g id="$help$_open">
4270
4425
  <rect fill="yellow" stroke="#000" stroke-width="3"
4271
- 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)}" />
4272
4427
  <text style="text-anchor: middle; dominant-baseline: middle;"
4273
- font-family="monospace" font-size="#{20/fit}px"
4274
- 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)}" >
4275
4430
  Help
4276
4431
  </text>
4277
4432
  </g>
@@ -4279,53 +4434,46 @@ SVG
4279
4434
  // Helping panel.
4280
4435
  <g id="$help$" visibility="hidden">
4281
4436
  <rect fill="#ffffd7" stroke="#000" stroke-width="6"
4282
- x="#{x0}" y="#{y0}" width="#{width}" height="#{height}" />
4283
- <text font-size="#{40/fit}px" font-family="serif" font-weight="bold"
4284
- 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)}" >
4285
4440
  Help
4286
4441
  </text>
4287
4442
 
4288
- <text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
4289
- 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)}" >
4290
4445
  Navigation:
4291
4446
  </text>
4292
- <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)}" >
4293
4448
  Zoom in/out:
4294
4449
  </text>
4295
- <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)}" >
4296
4451
  mouse wheel.
4297
4452
  </text>
4298
- <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)}" >
4299
4454
  Move diagram:
4300
4455
  </text>
4301
- <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)}" >
4302
4457
  left click and drag, or arrow keys.
4303
4458
  </text>
4304
- <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)}" >
4305
4460
  Open element:
4306
4461
  </text>
4307
- <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)}" >
4308
4463
  left click on element.
4309
4464
  </text>
4310
- <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)}" >
4311
4466
  Close element:
4312
4467
  </text>
4313
- <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)}" >
4314
4469
  left click on the close button at the top right of the element.
4315
4470
  </text>
4316
4471
 
4317
- <text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
4318
- 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)}" >
4319
4474
  Types of elements:
4320
4475
  </text>
4321
4476
  #{
4322
- # ic = IC.new("Instance",:instance)
4323
- # ic.scale = 35.0
4324
- # ic.xpos = (x0+15/fit) / ic.scale
4325
- # ic.ypos = 330/fit / ic.scale
4326
- # ic.width = 300/fit / ic.scale
4327
- # ic.height = 100/fit / ic.scale
4328
- # ic.instance_svg(ic)
4329
4477
  ic = IC.new("Instance",:instance)
4330
4478
  ic.scale = 35.0/fit
4331
4479
  ic.xpos = (x0+15)/fit / ic.scale
@@ -4335,23 +4483,6 @@ SVG
4335
4483
  ic.instance_svg(ic)
4336
4484
  }
4337
4485
  #{
4338
- # ic = IC.new("Continuous assignment",:alu)
4339
- # ic.scale = 35.0
4340
- # ic.xpos = (x0+(15+300+15)/fit) / ic.scale
4341
- # ic.ypos = 305/fit / ic.scale
4342
- # ic.width = 300/fit / ic.scale
4343
- # ic.height = 150/fit / ic.scale
4344
- # p0 = Port.new("in0",ic,:input)
4345
- # p0.side = LEFT
4346
- # ic.ports << p0
4347
- # p1 = Port.new("in1",ic,:input)
4348
- # p1.side = LEFT
4349
- # ic.ports << p1
4350
- # p2 = Port.new("out",ic,:output)
4351
- # p2.side = RIGHT
4352
- # ic.alu_svg(ic)
4353
- # ic.ports << p2
4354
- # ic.alu_svg(ic)
4355
4486
  ic = IC.new("Continuous assignment",:alu)
4356
4487
  ic.scale = 35.0/fit
4357
4488
  ic.xpos = (x0+(15+300+15))/fit / ic.scale
@@ -4371,13 +4502,6 @@ SVG
4371
4502
  ic.alu_svg(ic)
4372
4503
  }
4373
4504
  #{
4374
- # ic = IC.new("Combinatorial process",:process)
4375
- # ic.scale = 35.0
4376
- # ic.xpos = (x0+15/fit) / ic.scale
4377
- # ic.ypos = 480/fit / ic.scale
4378
- # ic.width = 300/fit / ic.scale
4379
- # ic.height = 100/fit / ic.scale
4380
- # ic.process_svg(ic)
4381
4505
  ic = IC.new("Combinatorial process",:process)
4382
4506
  ic.scale = 35.0/fit
4383
4507
  ic.xpos = (x0+15)/fit / ic.scale
@@ -4387,13 +4511,6 @@ SVG
4387
4511
  ic.process_svg(ic)
4388
4512
  }
4389
4513
  #{
4390
- # ic = IC.new("Clocked process",:clocked_process)
4391
- # ic.scale = 35.0
4392
- # ic.xpos = (x0+(15+300+15)/fit) / ic.scale
4393
- # ic.ypos = 480/fit / ic.scale
4394
- # ic.width = 300/fit / ic.scale
4395
- # ic.height = 100/fit / ic.scale
4396
- # ic.clocked_process_svg(ic)
4397
4514
  ic = IC.new("Clocked process",:clocked_process)
4398
4515
  ic.scale = 35.0/fit
4399
4516
  ic.xpos = (x0+(15+300+15))/fit / ic.scale
@@ -4403,13 +4520,6 @@ SVG
4403
4520
  ic.clocked_process_svg(ic)
4404
4521
  }
4405
4522
  #{
4406
- # ic = IC.new("Time process",:timed_process)
4407
- # ic.scale = 35.0
4408
- # ic.xpos = (x0+(15+300+15+300+15)/fit) / ic.scale
4409
- # ic.ypos = 480/fit / ic.scale
4410
- # ic.width = 300/fit / ic.scale
4411
- # ic.height = 100/fit / ic.scale
4412
- # ic.timed_process_svg(ic)
4413
4523
  ic = IC.new("Time process",:timed_process)
4414
4524
  ic.scale = 35.0/fit
4415
4525
  ic.xpos = (x0+(15+300+15+300+15))/fit / ic.scale
@@ -4419,13 +4529,6 @@ SVG
4419
4529
  ic.timed_process_svg(ic)
4420
4530
  }
4421
4531
  #{
4422
- # ic = IC.new("Signal",:register)
4423
- # ic.scale = 35.0
4424
- # ic.xpos = (x0+15/fit) / ic.scale
4425
- # ic.ypos = 600/fit / ic.scale
4426
- # ic.width = 150/fit / ic.scale
4427
- # ic.height = 75/fit / ic.scale
4428
- # ic.register_svg(ic)
4429
4532
  ic = IC.new("Signal",:register)
4430
4533
  ic.scale = 35.0/fit
4431
4534
  ic.xpos = (x0+15)/fit / ic.scale
@@ -4435,13 +4538,6 @@ SVG
4435
4538
  ic.register_svg(ic)
4436
4539
  }
4437
4540
  #{
4438
- # ic = IC.new("Memory",:memory)
4439
- # ic.scale = 35.0
4440
- # ic.xpos = (x0+(15+200+15)/fit) / ic.scale
4441
- # ic.ypos = 600/fit / ic.scale
4442
- # ic.width = 200/fit / ic.scale
4443
- # ic.height = 100/fit / ic.scale
4444
- # ic.memory_svg(ic)
4445
4541
  ic = IC.new("Memory",:memory)
4446
4542
  ic.scale = 35.0/fit
4447
4543
  ic.xpos = (x0+(15+200+15))/fit / ic.scale
@@ -4451,11 +4547,11 @@ SVG
4451
4547
  ic.memory_svg(ic)
4452
4548
  }
4453
4549
 
4454
- <text font-size="#{30/fit}px" font-family="serif" font-weight="bold"
4455
- 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)}" >
4456
4552
  Contents of processes and assigments:
4457
4553
  </text>
4458
- <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)}" >
4459
4555
  Represented as sets of parallel flow charts.
4460
4556
  </text>
4461
4557
 
@@ -4485,11 +4581,11 @@ SVG
4485
4581
  def self.svg_text_fit(name,width,max_size)
4486
4582
  return <<~SCRIPT
4487
4583
  <script>
4488
- fitWidth=#{width};
4584
+ fitWidth=#{width.round(3)};
4489
4585
  textNode = document.getElementById("#{self.to_svg_id(name)}");
4490
4586
  textBB = textNode.getBBox();
4491
4587
  fitSize = fitWidth / textBB.width;
4492
- if (fitSize > #{max_size}) fitSize = #{max_size};
4588
+ if (fitSize > #{max_size.round(3)}) fitSize = #{max_size.round(3)};
4493
4589
  textNode.setAttribute("font-size", fitSize + "px")
4494
4590
  </script>
4495
4591
  SCRIPT
@@ -4850,6 +4946,9 @@ class HDLRuby::Low::Case
4850
4946
  # self.default.to_viz_node(node) if self.default
4851
4947
  # return node
4852
4948
  node = parent
4949
+ # NOROM
4950
+ count = 0
4951
+ # END NOROM
4853
4952
  # Generate one node per possible value.
4854
4953
  self.each_when do |w|
4855
4954
  sub = HDLRuby::Viz::Node.new(:case,node)
@@ -4857,6 +4956,12 @@ class HDLRuby::Low::Case
4857
4956
  w.match.to_viz_node(sub)
4858
4957
  w.statement.to_viz_node(sub)
4859
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
4860
4965
  end
4861
4966
  self.default.to_viz_node(node) if self.default
4862
4967
  return node
@@ -4999,10 +5104,19 @@ class HDLRuby::Low::Block
4999
5104
  def to_viz_node(parent)
5000
5105
  node = HDLRuby::Viz::Node.new(self.mode,parent)
5001
5106
  prev = nil
5107
+ # NOROM
5108
+ count = 0
5109
+ # END NOROM
5002
5110
  self.each_statement do |stmnt|
5003
5111
  succ = stmnt.to_viz_node(node)
5004
5112
  prev.successor = succ if prev
5005
5113
  prev = succ
5114
+ # NOROM
5115
+ count += 1
5116
+ if count > 256 then
5117
+ break
5118
+ end
5119
+ # END NOROM
5006
5120
  end
5007
5121
  unless prev then
5008
5122
  # There were no statement in the block, create a dummy one