Method: HDLRuby::Viz::Node#place_and_route_statement_matrix

Defined in:
lib/HDLRuby/hruby_viz.rb

#place_and_route_statement_matrix(stmnt, matrix, r, c) ⇒ Object

Place statements in a matrix from statement +stmnt+ at using +matrix+ as guide for current row +r+ and column +c+. Returns the width and height to fill from current position.



3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
# File 'lib/HDLRuby/hruby_viz.rb', line 3385

def place_and_route_statement_matrix(stmnt, matrix, r, c)
  # The initial area to fill from current statement.
  fW, fH = stmnt.width + 1, stmnt.height 
  puts "Placing stmnt=#{stmnt.name} type=#{stmnt.type} at #{r},#{c}"
  # Recurse Depending of the kind of statement.
  case stmnt.type
  when :if, :case # There no repeat in parallel blocks.
    fs = stmnt.type != :case ? 1 : 2 # First statement position.
    # First set the current statement in the matrix.
    self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,3)
    # Recurse on the branches.
    stmnt.branches[fs..-1].each do |branch|
      # Update the position in the matrix
      # Depending on the type of branch.
      if branch.type == :if or branch.type == :case then
        # If branch, go down
        cur_r = self.next_row_matrix(matrix,c,r)
        cur_c = c
        # Route to it downward.
        @arrows << [c + stmnt.width/2, r-1, c + stmnt.width/2, cur_r]
      else
        if stmnt.branches[fs] != branch then
          # # Not if/case branch and secondary branch,
          # # put a placeholder to forbid placing
          # # an element between the if/case and the else.
          # self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,
          #                        # stmnt.branches[fs].height-3)
          #                        fH-3)
          # # And Route to it with a long diagonal arrow.
          # @arrows << [c + stmnt.width/2, r-1,
          #             # c + stmnt.width+1, r+stmnt.branches[fs].height-1]
          #             c + stmnt.width+1, r+fH-1]
          #             # c + stmnt.width+1, fH-1]
          # # And update the row to start with.
          # # r += stmnt.branches[fs].height-2
          # r += fH-2
          # # r = fH-2
          # Else branch, go down
          cur_r = self.next_row_matrix(matrix,c,r)
          # put a placeholder to forbid placing
          # an element between the if/case and the else.
          self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,
                                 cur_r-r-1)
          # Route to it downward.
          @arrows << [c + stmnt.width/2, r-1, 
                      c + stmnt.width + 1, cur_r + 1]
          r = cur_r
        else
          # Route it with a short left arrow.
          @arrows << [c + stmnt.width, r+1, c + stmnt.width+1, r+1]
        end
        # And go left.
        cur_r = r
        cur_c = c + stmnt.width + 1
      end
      # Place and route the branch.
      nW, nH =self.place_and_route_statement_matrix(branch,matrix,cur_r,cur_c)
      # Update the total fill size.
      fW = nW + 1 if fW < nW + 1
      fH = nH if fH < nH
      # Update the current row.
      r = cur_r + 3
      # Update the size of the matrix if required.
      while r >= matrix.size do
        matrix << ([ nil ] * matrix[0].size)
      end
    end
    # Fill again all the place used by the if/case.
    # self.fill_place_matrix(matrix,stmnt,r,c,fW,fH-3)
  when :par
    # Recurse on the branches.
    stmnt.place_and_route_par(c,r)
    # Then set the current statement in the matrix.
    self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,stmnt.height+1)
    # Update the fill size.
    fW = stmnt.width+1 if fW < stmnt.width + 1
    fH = stmnt.height if fH < stmnt.height
  when :seq
    # Recurse on the branches.
    stmnt.place_and_route_seq(c,r)
    # Then set the current statement in the matrix.
    self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,stmnt.height+1)
    # Update the fill size.
    fW = stmnt.width+1 if fW < stmnt.width + 1
    fH = stmnt.height if fH < stmnt.height
  else
    # Just set the current statement in the matrix.
    self.fill_place_matrix(matrix,stmnt,r,c,stmnt.width+1,3)
  end
  # Update the position in the matrix.
  r,c = self.next_place_matrix(matrix,0,r,c)
  # Recurse on successor if any.
  if stmnt.successor then
    self.place_and_route_statement_matrix(stmnt.successor,matrix,r,c)
  end
  puts "matrix placed for statement: #{stmnt.name}"
  return fW,fH
end