Class: ThroughPlugin

Inherits:
Plugin show all
Defined in:
lib/tecsgen/plugin/ThroughPlugin.rb

Overview

スループラグインの共通の親クラス かつ (何もせず)スルーするセルを挿入するスループラグイン

スループラグインは ThroughPlugin の子クラスとして定義する

Constant Summary collapse

@@generated_celltype =

この Plugin が生成したセルタイプのリスト

{}

Constants inherited from Plugin

Plugin::PluginArgProc

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Plugin

#cdl_error, #gen_ep_func?, #gen_postamble, #gen_preamble, #new_cell, #parse_plugin_arg, #print_msg, #set_locale, #set_silent

Methods inherited from Node

#cdl_error, #cdl_error2, #cdl_error3, #cdl_info, #cdl_info2, #cdl_warning, #cdl_warning2, #get_locale, #locale_str, #set_locale

Constructor Details

#initialize(cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell) ⇒ ThroughPlugin

ThroughPlugin の初期化

through が指定された時点で生成が行われる
    初期化では、指定された引数を記録するに留める
cell_name

Symbol 生成すべきセル名(受口側)

plugin_arg

string through で指定された引数

next_cell

Cell 呼び口を接続するセル

next_cell_port_name

Symbol 呼び口を接続する受口の名前

next_cell_port_subscript

Nil|Integer 呼び口を接続する受口配列添数

signature

Signature シグニチャ

celltype

Celltype セルタイプ (呼び先のセルのセルタイプ)

caller_cell

Cell 呼び元のセル.@caller_cell の項を参照



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 80

def initialize(cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell)
  super()
  @cell_name = cell_name                      # 生成すべきセル名(受け口側のセル名)
                                              # この呼び先に別セルを生成する場合、この名前を接頭辞とすべき
  @next_cell = next_cell                      # 呼び先のセル
  @next_cell_port_name = next_cell_port_name
  @next_cell_port_subscript = next_cell_port_subscript
  @signature = signature
  @entry_port_name = :eThroughEntry
  @call_port_name = :cCall
  @ct_name = :"t#{self.class.name}_#{@signature.get_global_name}"
  @celltype = celltype
  @plugin_arg_str = plugin_arg
  @plugin_arg_list = {}                       # プラグイン引数をパースした結果のハッシュ変数
  @caller_cell     = caller_cell
  Join.set_through_info self                  # 引数で渡らない(後から追加された)ものは set_through_info で設定される
  print("#{self.class.name}.new( '#{cell_name}', '#{plugin_arg}', '#{next_cell.get_name}', '#{next_cell_port_name}', #{celltype.get_name} )\n")
end

Class Method Details

.gen_post_code(file) ⇒ Object

後ろのコードを生成

プラグインの後ろのコード (CDL) を生成

file

File:



222
223
224
225
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 222

def self.gen_post_code(file)
  # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
  # file.print "/* '#{self.class.name}' post code */\n"
end

Instance Method Details

#check_plugin_arg(ident, rhs) ⇒ Object

Through プラグインの引数の名前を置換する



288
289
290
291
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 288

def check_plugin_arg(ident, rhs)
  rhs = subst_name rhs
  super(ident, rhs)
end

#gen_cdl_file(file) ⇒ Object

CDL ファイルの生成

file

FILE 生成するファイル



199
200
201
202
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 199

def gen_cdl_file(file)
  gen_plugin_decl_code(file)
  gen_through_cell_code(file)
end

#gen_ep_func_body(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params) ⇒ Object

受け口関数の本体(C言語)を生成する

通常であれば、ジェネレータは受け口関数のテンプレートを生成する
プラグインの場合、変更する必要のないセルタイプコードを生成する
file

FILE 出力先ファイル

b_singleton

bool true if singleton

ct_name

Symbol

global_ct_name

string

sig_name

string

ep_name

string

func_name

string

func_global_name

string

func_type

class derived from Type



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 239

def gen_ep_func_body(file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params)
  ret_type = func_type.get_type
  b_ret_void = ret_type.is_void?

  if !b_ret_void
    file.print("  #{ret_type.get_type_str}  retval;\n")
  end

  if !b_singleton

    file.print <<EOT
#{ct_name}_CB    *p_cellcb;
if( VALID_IDX( idx ) ){
  p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
}else{
   /* エラー処理コードをここに記述 */
}

EOT
  end

  # p "celltype_name, sig_name, func_name, func_global_name"
  # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"

  delim = ""
  if !b_ret_void
    file.print("  retval = ")
  end

  file.print("#{@call_port_name}_#{func_name}(")

#    if ( ! b_singleton ) then
#      file.print( " tecs_this" )
#      delim = ","
#    end

  params.each{|param|
    file.printf("#{delim} #{param.get_name}")
    delim = ","
  }

  file.print(" );\n")

  if !b_ret_void
    file.print("  return retval;\n")
  end
end

#gen_plugin_decl_code(file) ⇒ Object

宣言コードの生成

typedef, signature, celltype など(cell 以外)のコードを生成
    重複して生成してはならない(すでに生成されている場合は出力しないこと)
file

FILE 生成するファイル



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 151

def gen_plugin_decl_code(file)
  # このセルタイプ(同じシグニチャ)は既に生成されているか?
  if @@generated_celltype[@ct_name].nil?
    @@generated_celltype[@ct_name] = [self]
  else
    @@generated_celltype[@ct_name] << self
    return
  end

  file2 = CFile.open("#{$gen}/#{@ct_name}.cdl", "w")

  send_receive = []
  if !@signature.nil?
    @signature.each_param{|fd, param|
      dir = param.get_direction
      case dir
      when :SEND, :RECEIVE
        send_receive << [dir, fd, param]
      end
    }
  end

  file2.print <<EOT
celltype #{@ct_name} {
EOT

  if send_receive.length > 0
    file2.print "  [ allocator(\n"
    delim = ""
    send_receive.each {|a|
      file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
      delim = ",\n"
    }
    file2.print "\n  )]\n"
  end

  file2.print <<EOT
entry #{@signature.get_namespace_path} #{@entry_port_name};
call  #{@signature.get_namespace_path} #{@call_port_name};
};
EOT
  file2.close

  file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
end

#gen_through_cell_code(file) ⇒ Object

セルコードの生成

through 指定により生じるセルコード(CDL)を生成する
file

FILE 生成するファイル



207
208
209
210
211
212
213
214
215
216
217
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 207

def gen_through_cell_code(file)
  nest = @region.gen_region_str_pre file
  nest_str = "  " * nest

  file.print <<EOT
#{nest_str}cell #{@ct_name} #{@cell_name} {
#{nest_str}  #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
#{nest_str}};
EOT
  @region.gen_region_str_post file
end

#get_cell_nameObject

セルの名前を得る



125
126
127
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 125

def get_cell_name
  @cell_name
end

#get_cell_namespace_pathObject

NamespacePath を得る

生成するセルの namespace path を生成する



131
132
133
134
135
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 131

def get_cell_namespace_path
#    nsp = @region.get_namespace.get_namespace_path
  nsp = @region.get_namespace_path
  return nsp.append(@cell_name)
end

#get_through_entry_port_nameObject

生成されたセルの受け口の名前を得る



138
139
140
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 138

def get_through_entry_port_name
  @entry_port_name
end

#get_through_entry_port_subscriptObject

生成されたセルの受け口配列添数を得る



143
144
145
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 143

def get_through_entry_port_subscript
  @entry_port_subscript
end

#set_through_info(start_region, end_region, through_type, join, callee_cell, count) ⇒ Object

情報を設定する

共有チャンネルの場合 caller_cell, next_cell のいずれの region でもないケースがある後から追加したので initialize の引数ではなく、別メソッドで設定このメソッドは、オーバーライドしないでくださいJoin と ThrougPlugin の間の連絡用で、今後とも引数が追加される可能性があるためこのメソッドは V1.C.0.34 で位置が移動され、ThroughPlugin#initialize で呼び出される



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 105

def set_through_info(start_region, end_region, through_type, join, callee_cell, count)
  @start_region = start_region
  @end_region = end_region
  @through_type = through_type
  @join = join
  @callee_cell = callee_cell
  @count = count

  # preferred_region の設定
  case through_type
  when :IN_THROUGH, :THROUGH
    @region = end_region
  when :OUT_THROUGH, :TO_THROUGH
    @region = start_region
  else
    raise "Unknown through_type #{through_type}"
  end
end

#show_tree(indent) ⇒ Object



327
328
329
330
331
332
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 327

def show_tree(indent)
  indent.times { print "  " }
  puts "Plugin: celltype: #{@ct_name} cell: #{@cell_name}"
  (indent + 1).times { print "  " }
  puts "next: signature: #{@signature.get_namespace_path} call = #{@next_cell.get_name}.#{@next_cell_port_name}"
end

#subst_name(str) ⇒ Object

ThroughPlugin#名前の置換

プラグインオプション引数内の文字列を置換する

$source$       … 呼び元のセル名
$destination$  … 呼び先のセル名
$SOURCE$       … 呼び元のセル名 (リージョン名を '_' で連結した global_name)
$DESTINATION$  … 呼び先のセル名 (リージョン名を '_' で連結した global_name)
$next$         … 次のセル名
                  複数の through がつながっている場合、すぐ後ろに来るもの
$NEXT$         … 次のセル名 (リージョン名を '_' で連結した global_name)
                  複数の through がつながっている場合、すぐ後ろに来るもの
$start_region$ … $source$ のセルの存在する region (global_name)
$end_region$   … $destination$ のセルの存在する region (global_name)
$preferred_region$  … 適切な region (global_name), start_region または end_region
$count$        … region 間の through の適用数
$$             … $ に置換


308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/tecsgen/plugin/ThroughPlugin.rb', line 308

def subst_name(str)
  # セル名の置換
  str = str.gsub(/(^|[^\$])\$source\$/, "\\1#{@caller_cell.get_name}")
  str = str.gsub(/(^|[^\$])\$destination\$/, "\\1#{@callee_cell.get_name}")
  str = str.gsub(/(^|[^\$])\$SOURCE\$/, "\\1#{@caller_cell.get_global_name}")
  str = str.gsub(/(^|[^\$])\$DESTINATION\$/, "\\1#{@callee_cell.get_global_name}")
  str = str.gsub(/(^|[^\$])\$next\$/, "\\1#{@next_cell.get_name}")
  str = str.gsub(/(^|[^\$])\$NEXT\$/, "\\1#{@next_cell.get_global_name}")
  # region 名の置換
  str = str.gsub(/(^|[^\$])\$start_region\$/, "\\1#{@start_region.get_global_name}")
  str = str.gsub(/(^|[^\$])\$end_region\$/, "\\1#{@end_region.get_global_name}")
  str = str.gsub(/(^|[^\$])\$preferred_region\$/, "\\1#{@region.get_global_name}")
  str = str.gsub(/(^|[^\$])\$count\$/, "\\1#{@count}")

  str = str.gsub(/\$\$/, "\$") # $$ を $ に置換

  return str
end