Class: TECSCDE::TECSModel::TmCell

Inherits:
TECSCDE::TmObject show all
Includes:
TmUneditable
Defined in:
lib/tecscde/tecs_model/tm_cell.rb

Instance Attribute Summary collapse

Attributes inherited from TECSCDE::TmObject

#owner

Instance Method Summary collapse

Methods included from TmUneditable

#editable?, #set_editable

Methods inherited from TECSCDE::TmObject

#copy_from, #model, #modified

Constructor Details

#initialize(name, celltype, x, y, region, tecsgen_cell = nil) ⇒ TmCell

Returns a new instance of TmCell.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 74

def initialize(name, celltype, x, y, region, tecsgen_cell = nil)
  TECSCDE.logger.debug("TmCell.new")
  @name = name
  @celltype = celltype
  @owner = region
  @attr_list = {}

  @x = x
  @y = y
  @width  = 25
  @height = 15

  @cports = {}
  @eports = {}
  @n_cport = 0
  @n_eport = 0

  @celltype.get_port_list.each do |port_def|
    # p "celltype:#{@celltype.get_name} port:#{port_def.get_name}"
    if port_def.get_port_type == :ENTRY
      # if ! port_def.is_reverse_required? then
      if port_def.get_array_size.nil?
        @eports[port_def.get_name] = TECSCDE::TECSModel::TmEPort.new(self, port_def)
      else
        @eports[port_def.get_name] = TECSCDE::TECSModel::TmEPortArray.new(self, port_def)
      end
      # end
    else
      unless port_def.is_require?
        if port_def.get_array_size.nil?
          @cports[port_def.get_name] = TECSCDE::TECSModel::TmCPort.new(self, port_def)
        else
          @cports[port_def.get_name] = TECSCDE::TECSModel::TmCPortArray.new(self, port_def)
        end
      end
    end
  end

  @tecsgen_cell = tecsgen_cell
  @editable = true
  modified {}
end

Instance Attribute Details

#cportsObject (readonly)

Returns the value of attribute cports.



72
73
74
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 72

def cports
  @cports
end

#eportsObject (readonly)

Returns the value of attribute eports.



72
73
74
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 72

def eports
  @eports
end

Instance Method Details

#adjust_port_position_after_port(port, move_offs) ⇒ Object

TmCell#adjust_port_position_after_port port, offs

this method is part of adjust_port_position_to_insert



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 331

def adjust_port_position_after_port(port, move_offs)
  # p "adjust_port_position_after_port"
  edge_side = port.get_edge_side
  offs = port.offset
  proc_adjust = proc do |port, offs, edge_side, move_offs|
    if port.get_edge_side == edge_side
      dist = port.offset - offs
      if dist > 0
        port.move(move_offs, move_offs) # move same value for x, y (only x or y applied in the method)
      end
    end
  end
  (@eports.values + @cports.values).each do |port|
    if port.is_a?(TECSCDE::TECSModel::TmPortArray)
      port.ports.each do |pt|
        proc_adjust.call(pt, offs, edge_side, move_offs)
      end
    else
      proc_adjust.call(port, offs, edge_side, move_offs)
    end
  end
end

#adjust_port_position_to_insert(port) ⇒ Object

TmCell#adjust_port_position_to_insert port::TmPort : insert after the port



295
296
297
298
299
300
301
302
303
304
305
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 295

def adjust_port_position_to_insert(port)
  # p "adjust_port_position_to_insert"
  nearest_port = find_nearest_next_port(port)
  if nearest_port
    dist = (nearest_port.offset - port.offset)
    if dist < (DIST_PORT * 2)
      offs = (DIST_PORT * 2) - dist
      adjust_port_position_after_port(port, offs)
    end
  end
end

#change_name(name) ⇒ Object

TmCell#change_name ***

name::Symbol : new name return::Bool: true if succeed if cell of new_name already exists, results false



169
170
171
172
173
174
175
176
177
178
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 169

def change_name(name)
  if @owner.rename_cell(self, name)
    modified do
      @name = name
      return true
    end
  else
    false
  end
end

#clone_for_undoObject

TmCell#clone_for_undo



471
472
473
474
475
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 471

def clone_for_undo
  bu = clone
  bu.copy_from(self)
  bu
end

#complete?Boolean

TmCell#complete?

Returns:

  • (Boolean)


420
421
422
423
424
425
426
427
428
429
430
431
432
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 420

def complete?
  @celltype.get_attribute_list.each do |attr|
    if attr.get_initializer.nil? && @attr_list[attr.get_name].nil?
      return false
    end
  end
  @cports.each do |_name, cport|
    if !cport.complete? && !cport.optional?
      return false
    end
  end
  true
end

#deleteObject

TmCell#delete ***



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 142

def delete
  return unless editable?
  modified do
    @cports.each do |_name, cport|
      cport.delete
    end
    @eports.each do |_name, eport|
      eport.delete
    end
    @owner.delete_cell(self)
  end
end

#find_nearest_next_port(port) ⇒ Object

TmCell#find_nearest_next_port this method is part of adjust_port_position_to_insert



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 309

def find_nearest_next_port(port)
  # p "find_nearest_next_port #{port.get_name} #{port.get_subscript}"
  edge_side = port.get_edge_side
  offs = port.offset
  nearest_port = nil
  (@eports.values + @cports.values).each do |_port|
    if _port.is_a?(TECSCDE::TECSModel::TmPortArray)
      _port.ports.each do |pt|
        nearest_port = judge_near(pt, offs, edge_side, nearest_port)
        # p "nearest=#{nearest_port}"
      end
    else
      nearest_port = judge_near(_port, offs, edge_side, nearest_port)
      # p "nearest=#{nearest_port}"
    end
  end
  # p "find_nearest=#{nearest_port}"
  nearest_port
end

#get_attr_listObject



415
416
417
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 415

def get_attr_list
  @attr_list
end

#get_celltypeObject

TmCell#get_celltype ***



181
182
183
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 181

def get_celltype
  @celltype
end

#get_cport_for_new_join(cport_name, cport_subscript) ⇒ Object

TmCell#get_cport_for_new_join



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 355

def get_cport_for_new_join(cport_name, cport_subscript)
  cp = @cports[cport_name]
  if cp.nil?
    TECSCDE.logger.error("TM9999 cell #{@name} not have call port #{cport_name}")
  end

  if cport_subscript.nil?
    if !cp.array?
      return cp
    else
      TECSCDE.logger.error("TM9999 cell #{@name}.#{cport_name} is call port array")
      return nil
    end
  else
    if cp.array?
      return cp.get_port_for_new_join(cport_subscript)
    else
      TECSCDE.logger.error("TM9999 cell #{@name}.#{cport_name} is not call port array")
      return nil
    end
  end
end

#get_edge_position_in_normal_dir(edge_side) ⇒ Object

TmCell#get_edge_position_in_normal_dir



239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 239

def get_edge_position_in_normal_dir(edge_side)
  case edge_side
  when  EDGE_TOP
    @y
  when  EDGE_BOTTOM
    @y + @height
  when  EDGE_LEFT
    @x
  when  EDGE_RIGHT
    @x + @width
  end
end

#get_eport_for_new_join(eport_name, eport_subscript) ⇒ Object

TmCell#get_eport_for_new_join



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 379

def get_eport_for_new_join(eport_name, eport_subscript)
  ep = @eports[eport_name]
  if ep.nil?
    TECSCDE.logger.error("TM9999 cell #{@name} not have entry port #{eport_name}")
  end

  if eport_subscript.nil?
    if !ep.array?
      return ep
    else
      TECSCDE.logger.error("TM9999 cell #{@name}.#{eport_name} is entry port array")
      return nil
    end
  else
    if ep.array?
      return ep.get_port_for_new_join(eport_subscript)
    else
      TECSCDE.logger.error("TM9999 cell #{@name}.#{eport_name} is not entry port array")
      return nil
    end
  end
end

#get_geometryObject

TmCell#get_geometry ***



156
157
158
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 156

def get_geometry
  [@x, @y, @width, @height]
end

#get_min_whObject

TmCell#get_min_wh

minimum width & height of the cell. these values are calculated from ports’ offset. name length is not considered.



438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 438

def get_min_wh
  h_min = 0
  w_min = 0
  (@cports.values + @eports.values).each do |port|
    if port.is_a?(TECSCDE::TECSModel::TmPortArray)
      port.ports.each do |pt|
        offs = pt.offset
        case pt.get_edge_side
        when EDGE_TOP, EDGE_BOTTOM
          w_min = offs if offs > w_min
        else
          h_min = offs if offs > h_min
        end
      end
    else
      offs = port.offset
      case port.get_edge_side
      when EDGE_TOP, EDGE_BOTTOM
        w_min = offs if offs > w_min
      else
        h_min = offs if offs > h_min
      end
    end
  end
  [w_min + DIST_PORT, h_min + DIST_PORT]
end

#get_nameObject

TmCell#get_name ***



161
162
163
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 161

def get_name
  @name
end

#get_near_port(x, y) ⇒ Object

TmCell::get_near_port ***



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 218

def get_near_port(x, y)
  @cports.merge(@eports).each do |_name, port|
    if port.is_a?(TECSCDE::TECSModel::TmPort)
      xp, yp = port.get_position
    else
      pt = port.get_near_port(x, y)
      if pt
        return pt
      end
      next
    end
    # p "get_near_port x=#{x} y=#{y} xp=#{xp} yp=#{yp}"
    if ((xp - x).abs < NEAR_DIST) && ((yp - y).abs < NEAR_DIST)
      # p "near port: found"
      return port
    end
  end
  nil
end

#get_new_cport_position(port_def) ⇒ Object



277
278
279
280
281
282
283
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 277

def get_new_cport_position(port_def)
  if $b_tate
    [EDGE_BOTTOM, DIST_PORT * (inc_n_cport + 1)]
  else
    [EDGE_RIGHT, DIST_PORT * (inc_n_cport + 1)]
  end
end

#get_new_eport_position(port_def) ⇒ Object



285
286
287
288
289
290
291
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 285

def get_new_eport_position(port_def)
  if $b_tate
    [EDGE_TOP, DIST_PORT * (inc_n_eport + 1)]
  else
    [EDGE_LEFT, DIST_PORT * (inc_n_eport + 1)]
  end
end

#get_regionObject

TmCell#get_region

return::TmRegion



187
188
189
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 187

def get_region
  @owner
end

#get_right_angle_edges_position(edge_side) ⇒ Object

TmCell#get_right_angle_edges_position



253
254
255
256
257
258
259
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 253

def get_right_angle_edges_position(edge_side)
  if TECSCDE::TECSModel.vertical?(edge_side)
    [@y, @y + @height]
  else
    [@x, @x + @width]
  end
end

#get_tecsgen_cellObject

TmCell#get_tecsgen_cell



466
467
468
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 466

def get_tecsgen_cell
  @tecsgen_cell
end

#inc_n_cportObject

TmCell#inc_n_cport

total call port count



263
264
265
266
267
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 263

def inc_n_cport
  n = @n_cport
  @n_cport += 1
  n
end

#inc_n_eportObject

TmCell#inc_n_eport

total entry port count



271
272
273
274
275
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 271

def inc_n_eport
  n = @n_eport
  @n_eport += 1
  n
end

#move(x_inc, y_inc) ⇒ Object

TmCell#move ***



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 192

def move(x_inc, y_inc)
  modified do
    TECSCDE.logger.debug("cell move #{@name}")
    x0 = @x
    y0 = @y
    @x = model.clip_x(TECSCDE::TECSModel.round_length_val(@x + x_inc))
    @y = model.clip_y(TECSCDE::TECSModel.round_length_val(@y + y_inc))
    x_inc2 = @x - x0
    y_inc2 = @y - y0

    @cports.each do |_name, cport|
      cport.moved(x_inc2, y_inc2)
    end
    @eports.each do |_name, eport|
      eport.moved(x_inc2, y_inc2)
    end
  end
end

#near?(x, y) ⇒ Boolean

TmCell::near?( x, y ) ***

Returns:

  • (Boolean)


212
213
214
215
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 212

def near?(x, y)
  # p "near? @x=#{@x} @width=#{@width} @y=#{@y} @height=#{@height} x=#{x} y=#{y}"
  @x < x && x < @x + @width && @y < y && y < @y + @height
end

#set_attr(name, init) ⇒ Object

TmCell#set_attr

name::Symbol init::String|Nil (from Expression)



405
406
407
408
409
410
411
412
413
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 405

def set_attr(name, init)
  modified do
    if init.nil?
      @attr_list.delete(name)
    else
      @attr_list[name] = init
    end
  end
end

#set_geometry(x, y, w, h) ⇒ Object

TmCell#set_geometry



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/tecscde/tecs_model/tm_cell.rb', line 118

def set_geometry(x, y, w, h)
  x_inc = x - @x
  y_inc = y - @y
  x_inc_r = x + w - (@x + @width)
  y_inc_b = y + h - (@y + @height)

  @cports.each do |_name, cport|
    cport.moved_edge(x_inc, x_inc_r, y_inc, y_inc_b)
  end
  @eports.each do |_name, eport|
    eport.moved_edge(x_inc, x_inc_r, y_inc, y_inc_b)
  end

  w_min, h_min = get_min_wh
  w = w_min if w < w_min
  h = h_min if h < h_min

  @x = TECSCDE::TECSModel.round_length_val(x)
  @y = TECSCDE::TECSModel.round_length_val(y)
  @width = TECSCDE::TECSModel.round_length_val(w)
  @height = TECSCDE::TECSModel.round_length_val(h)
end