source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/plugin/ThroughPlugin.rb@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 14.9 KB
RevLine 
[352]1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2014 by TOPPERS Project
7#--
8# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13# スコード中に含まれていること.
14# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17# の無保証規定を掲載すること.
18# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20# と.
21# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22# 作権表示,この利用条件および下記の無保証規定を掲載すること.
23# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24# 報告すること.
25# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29# 免責すること.
30#
31# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35# の責任を負わない.
36#
37# $Id$
38#++
39
40# mikan through plugin: namespace が考慮されていない
41
42#== スループラグインの共通の親クラス かつ (何もせず)スルーするセルを挿入するスループラグイン
43# スループラグインは ThroughPlugin の子クラスとして定義する
44class ThroughPlugin < Plugin
45#@cell_name:: Symbol 生成するセル名(複数セルを生成する場合、受け口側のセル)
46#@plugin_arg_str:: string through で指定された引数
47#@next_cell:: Cell 呼び口を結合するセル
48#@next_cell_port_name:: Symbol 呼び口を結合する受口の名前
49#@signature:: Signature シグニチャ
50#@celltype:: Celltype 呼び先のセルのセルタイプ. through が連接する場合、最終的な呼び先のセルのセルタイプ
51#@entry_port_name::Symbol 生成するセルの受け口名 "eThroughEntry"
52#@call_port_name:: Symbol 生成するセルの呼び口名 "cCall"
53#@ct_name:: Symbol 生成するセルのセルタイプ名 "t#{self.class.name}_#{@signature.get_global_name}"
54#@plugin_arg_list:: Hash プラグイン引数をパースした結果のハッシュ変数
55#@caller_cell:: Cell 呼び元のセル.through プラグインが連接する場合では、最も呼び元のセル.($source$)
56# through プラグインが合流するケースでは、1つ目の呼び元セルのみ引数として与えられる
57# 従って TracePlugin の呼び元の判別に利用する場合は、異なる呼び元から呼ばれる可能性があることに注意しなくてはならない
58#@callee_cell:: Cell 呼び先のセル($destination$)
59#@plugin_arg_check_proc_tab:: [string => Proc] プラグイン引数名⇒チェック関数
60# 以下の変数は、initialize ではなく、後から設定される
61#@start_@region:: Region 始まりのリージョン: caller_cell のリージョンとは異なる可能性がある ($start_region$)
62#@end_region:: Region 終わりのリージョン: next_cell のリージョンとは異なる可能性がある ($end_region$)
63#@region:: Region @start_region と @end_region のいずれかで、cell を置くのが好ましいリージョン ($preferred_region$)
64#@through_type:: Symbol :THROUGH, :TO_THROUGH, :IN_THROUGH, :OUT_THROUGH のいずれか
65
66 # この Plugin が生成したセルタイプのリスト
67 @@generated_celltype = {}
68
69 #=== ThroughPlugin の初期化
70 # through が指定された時点で生成が行われる
71 # 初期化では、指定された引数を記録するに留める
72 #cell_name:: Symbol 生成すべきセル名(受口側)
73 #plugin_arg:: string through で指定された引数
74 #next_cell:: Cell 呼び口を接続するセル
75 #next_cell_port_name:: Symbol 呼び口を接続する受口の名前
76 #signature:: Signature シグニチャ
77 #celltype:: Celltype セルタイプ (呼び先のセルのセルタイプ)
78 #caller_cell:: Cell 呼び元のセル.@caller_cell の項を参照
79 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell )
80 super()
81 @cell_name = cell_name # 生成すべきセル名(受け口側のセル名)
82 # この呼び先に別セルを生成する場合、この名前を接頭辞とすべき
83 @next_cell = next_cell # 呼び先のセル
84 @next_cell_port_name = next_cell_port_name
85 @signature = signature
86 @entry_port_name = :"eThroughEntry"
87 @call_port_name = :"cCall"
88 @ct_name = :"t#{self.class.name}_#{@signature.get_global_name}"
89 @celltype = celltype
90 @plugin_arg_str = plugin_arg
91 @plugin_arg_list = {} # プラグイン引数をパースした結果のハッシュ変数
92 @caller_cell = caller_cell
93 Join.set_through_info self # 引数で渡らない(後から追加された)ものは set_through_info で設定される
94 print( "#{self.class.name}.new( '#{cell_name}', '#{plugin_arg}', '#{next_cell.get_name}', '#{next_cell_port_name}', #{celltype.get_name} )\n" )
95 end
96
97 #=== 情報を設定する
98 # 共有チャンネルの場合 caller_cell, next_cell のいずれの region でもないケースがある
99 # 後から追加したので initialize の引数ではなく、別メソッドで設定
100 # このメソッドは、オーバーライドしないでください
101 # Join と ThrougPlugin の間の連絡用で、今後とも引数が追加される可能性があるため
102 # このメソッドは V1.C.0.34 で位置が移動され、ThroughPlugin#initialize で呼び出される
103 def set_through_info( start_region, end_region, through_type, join, callee_cell, count )
104 @start_region = start_region
105 @end_region = end_region
106 @through_type = through_type
107 @join = join
108 @callee_cell = callee_cell
109 @count = count
110
111 # preferred_region の設定
112 case through_type
113 when :IN_THROUGH, :THROUGH
114 @region = end_region
115 when :OUT_THROUGH, :TO_THROUGH
116 @region = start_region
117 else
118 raise "Unknown through_type #{through_type}"
119 end
120 end
121
122 #=== セルの名前を得る
123 def get_cell_name
124 @cell_name
125 end
126
127 #=== NamespacePath を得る
128 # 生成するセルの namespace path を生成する
129 def get_cell_namespace_path
130# nsp = @region.get_namespace.get_namespace_path
131 nsp = @region.get_namespace_path
132 return nsp.append( @cell_name )
133 end
134
135 #=== 生成されたセルの受け口の名前を得る
136 def get_through_entry_port_name
137 @entry_port_name
138 end
139
140 #=== 宣言コードの生成
141 # typedef, signature, celltype など(cell 以外)のコードを生成
142 # 重複して生成してはならない(すでに生成されている場合は出力しないこと)
143 #file:: FILE 生成するファイル
144 def gen_plugin_decl_code( file )
145
146 # このセルタイプ(同じシグニチャ)は既に生成されているか?
147 if @@generated_celltype[ @ct_name ] == nil then
148 @@generated_celltype[ @ct_name ] = [ self ]
149 else
150 @@generated_celltype[ @ct_name ] << self
151 return
152 end
153
154 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
155
156 send_receive = []
157 if @signature != nil then
158 @signature.each_param{ |fd,param|
159 dir =param.get_direction
160 case dir
161 when :SEND, :RECEIVE
162 send_receive << [ dir, fd, param ]
163 end
164 }
165 end
166
167 file2.print <<EOT
168celltype #{@ct_name} {
169EOT
170
171 if send_receive.length > 0 then
172 file2.print " [ allocator(\n"
173 delim = ""
174 send_receive.each { |a|
175 file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
176 delim = ",\n"
177 }
178 file2.print "\n )]\n"
179 end
180
181 file2.print <<EOT
182 entry #{@signature.get_namespace_path} #{@entry_port_name};
183 call #{@signature.get_namespace_path} #{@call_port_name};
184};
185EOT
186 file2.close
187
188 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
189 end
190
191 #=== CDL ファイルの生成
192 #file:: FILE 生成するファイル
193 def gen_cdl_file( file )
194 gen_plugin_decl_code( file )
195 gen_through_cell_code( file )
196 end
197
198 #=== セルコードの生成
199 # through 指定により生じるセルコード(CDL)を生成する
200 #file:: FILE 生成するファイル
201 def gen_through_cell_code( file )
202
203 nest = @region.gen_region_str_pre file
204 nest_str = " " * nest
205
206 file.print <<EOT
207#{nest_str}cell #{@ct_name} #{@cell_name} {
208#{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
209#{nest_str}};
210EOT
211 @region.gen_region_str_post file
212
213 end
214
215 #=== 後ろのコードを生成
216 #プラグインの後ろのコード (CDL) を生成
217 #file:: File:
218 def self.gen_post_code( file )
219 # 複数のプラグインの post_code が一つのファイルに含まれるため、以下のような見出しをつけること
220 # file.print "/* '#{self.class.name}' post code */\n"
221 end
222
223 #=== 受け口関数の本体(C言語)を生成する
224 # 通常であれば、ジェネレータは受け口関数のテンプレートを生成する
225 # プラグインの場合、変更する必要のないセルタイプコードを生成する
226 #file:: FILE 出力先ファイル
227 #b_singleton:: bool true if singleton
228 #ct_name:: Symbol
229 #global_ct_name:: string
230 #sig_name:: string
231 #ep_name:: string
232 #func_name:: string
233 #func_global_name:: string
234 #func_type:: class derived from Type
235 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 )
236
237 ret_type = func_type.get_type
238 b_ret_void = ret_type.is_void?
239
240 if ! b_ret_void then
241 file.print( " #{ret_type.get_type_str} retval;\n" )
242 end
243
244 if ! b_singleton then
245
246 file.print <<EOT
247 #{ct_name}_CB *p_cellcb;
248 if( VALID_IDX( idx ) ){
249 p_cellcb = #{global_ct_name}_GET_CELLCB(idx);
250 }else{
251 /* エラー処理コードをここに記述 */
252 }
253
254EOT
255 end
256
257 # p "celltype_name, sig_name, func_name, func_global_name"
258 # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
259
260 delim = ""
261 if ! b_ret_void then
262 file.print( " retval = " )
263 end
264
265 file.print( "#{@call_port_name}_#{func_name}(" )
266
267# if ( ! b_singleton ) then
268# file.print( " tecs_this" )
269# delim = ","
270# end
271
272 params.each{ |param|
273 file.printf( "#{delim} #{param.get_name}" )
274 delim = ","
275 }
276
277 file.print( " );\n" )
278
279 if ! b_ret_void then
280 file.print( " return retval;\n" )
281 end
282 end
283
284 #=== Through プラグインの引数の名前を置換する
285 def check_plugin_arg( ident, rhs )
286 rhs = subst_name rhs
287 super( ident, rhs )
288 end
289
290 #=== ThroughPlugin#名前の置換
291 # プラグインオプション引数内の文字列を置換する
292 # $source$ … 呼び元のセル名
293 # $destination$ … 呼び先のセル名
294 # $SOURCE$ … 呼び元のセル名 (リージョン名を '_' で連結した global_name)
295 # $DESTINATION$ … 呼び先のセル名 (リージョン名を '_' で連結した global_name)
296 # $next$ … 次のセル名
297 # 複数の through がつながっている場合、すぐ後ろに来るもの
298 # $NEXT$ … 次のセル名 (リージョン名を '_' で連結した global_name)
299 # 複数の through がつながっている場合、すぐ後ろに来るもの
300 # $start_region$ … $source$ のセルの存在する region (global_name)
301 # $end_region$ … $destination$ のセルの存在する region (global_name)
302 # $preferred_region$ … 適切な region (global_name), start_region または end_region
303 # $count$ … region 間の through の適用数
304 # $$ … $ に置換
305 def subst_name( str )
306 # セル名の置換
307 str = str.gsub( /(^|[^\$])\$source\$/, "\\1#{@caller_cell.get_name}" )
308 str = str.gsub( /(^|[^\$])\$destination\$/, "\\1#{@callee_cell.get_name}" )
309 str = str.gsub( /(^|[^\$])\$SOURCE\$/, "\\1#{@caller_cell.get_global_name}" )
310 str = str.gsub( /(^|[^\$])\$DESTINATION\$/, "\\1#{@callee_cell.get_global_name}" )
311 str = str.gsub( /(^|[^\$])\$next\$/, "\\1#{@next_cell.get_name}" )
312 str = str.gsub( /(^|[^\$])\$NEXT\$/, "\\1#{@next_cell.get_global_name}" )
313 # region 名の置換
314 str = str.gsub( /(^|[^\$])\$start_region\$/, "\\1#{@start_region.get_global_name}" )
315 str = str.gsub( /(^|[^\$])\$end_region\$/, "\\1#{@end_region.get_global_name}" )
316 str = str.gsub( /(^|[^\$])\$preferred_region\$/, "\\1#{@region.get_global_name}" )
317 str = str.gsub( /(^|[^\$])\$count\$/, "\\1#{@count}" )
318
319 str = str.gsub( /\$\$/, "\$" ) # $$ を $ に置換
320
321 return str
322 end
323
324 def show_tree( indent )
325 indent.times { print " " }
326 puts "Plugin: celltype: #{@ct_name} cell: #{@cell_name}"
327 (indent+1).times { print " " }
328 puts "next: signature: #{@signature.get_namespace_path} call = #{@next_cell.get_name}.#{@next_cell_port_name}"
329 end
330end
331
Note: See TracBrowser for help on using the repository browser.