OpenCores
URL https://opencores.org/ocsvn/soc_maker/soc_maker/trunk

Subversion Repositories soc_maker

[/] [soc_maker/] [trunk/] [lib/] [soc_maker/] [soc_def.rb] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 feddischso
###############################################################
2
#
3
#  File:      soc_def.rb
4
#
5
#  Author:    Christian Hättich
6
#
7
#  Project:   System-On-Chip Maker
8
#
9
#  Target:    Linux / Windows / Mac
10
#
11
#  Language:  ruby
12
#
13
#
14
###############################################################
15
#
16
#
17
#   Copyright (C) 2014  Christian Hättich  - feddischson [ at ] opencores.org
18
#
19
#   This program is free software: you can redistribute it and/or modify
20
#   it under the terms of the GNU General Public License as published by
21
#   the Free Software Foundation, either version 3 of the License, or
22
#   (at your option) any later version.
23
#
24
#   This program is distributed in the hope that it will be useful,
25
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
#   GNU General Public License for more details.
28
#
29
#   You should have received a copy of the GNU General Public License
30
#   along with this program.  If not, see .
31
#
32
#
33
###############################################################
34
#
35
#   Description:
36
#     This class represents a System-on-chip and derives
37
#     the functionallity from Component.
38
#     The two important fields are
39
#       - @cores: holds all core-instances
40
#       - cons:   holds all connections
41
#     In addition, the field @static is used to store
42
#     static parameters, which are set for cores used in this SOC.
43
#
44
###############################################################
45
 
46
module SOCMaker
47
class SOCDef < Component
48
  include ERR
49
  include YAML_EXT
50
 
51
  attr_accessor :cores
52
  attr_accessor :cons
53
  attr_accessor :static
54
  def initialize( name, version, toplevel, options = {} )
55
 
56
    init_with( { 'name'     => name,
57
                 'version'  => version,
58
                 'toplevel' => toplevel }.merge( options ) )
59
 
60
  end
61
 
62
  def encode_with( coder )
63
    super coder
64
    %w[ cores cons static ].
65
      each { |v| coder[ v ] = instance_variable_get "@#{v}" }
66
  end
67
 
68
  def init_with( coder )
69
    super coder
70
    @cores  = coder[ 'cores'  ] || {}
71
    @static = coder[ 'static' ] || {}
72
    @cons   = coder[ 'cons'   ] || {}
73
  end
74
 
75
  def verify
76
    super( true )
77
 
78
    @cores.each do |core_name, core_inst|
79
      core_inst.verify
80
    end
81
 
82
  end
83
 
84
 
85
 
86
 
87
 
88
 
89
  # SOCMaker::logger.error( "instantiation #{inst_name} is already in use" )
90
  def inst_in_use?( inst_name )
91
       @cores[ inst_name.to_sym ] != nil or
92
       @cons[ inst_name.to_sym ]  != nil
93
  end
94
 
95
  def rm( inst_name )
96
 
97
    if @cores[ inst_name.to_sym ] != nil
98
      # TODO: remove also all related connections
99
      @cores.delete( inst_name.to_sym )
100
    elsif @cons[ inst_name.to_sym ]  != nil
101
      @cons.delete( inst_name.to_sym )
102
    else
103
      return false
104
    end
105
    return true
106
  end
107
 
108
 
109
  def add_core( name, version, inst_name )
110
 
111
    return false if inst_in_use?( inst_name )
112
 
113
    # check, if the core exits in our library
114
    #  if not: an error will be raised
115
    SOCMaker::lib.get_core( name, version )
116
 
117
    @cores[ inst_name.to_sym ] = SOCMaker::CoreInst.new( name+version )
118
  end
119
 
120
 
121
  def ifc_in_use?( inst_name, ifc_name )
122
 
123
    # go through all connections and check,
124
    # that non of the interfaces we want to connect is used
125
    @cons.each do |_con_name, con_def|
126
      return true if con_def[ :mapping ][ 0 ][ inst_name.to_sym] == ifc_name.to_sym
127
      return true if con_def[ :mapping ][ 1 ][ inst_name.to_sym] == ifc_name.to_sym
128
    end
129
    return false
130
 
131
  end
132
 
133
 
134 6 feddischso
  def get_len( ifc_name, port_name, inst )
135
    if @cores[ inst.to_sym ] != nil
136
      return @cores[ inst ].get_len( ifc_name, port_name )
137
    else
138
      return nil
139
    end
140
  end
141 5 feddischso
 
142
  def get_core_def( inst )
143
      if @cores[ inst.to_sym ] != nil
144
        return @cores[ inst.to_sym ].defn
145
      elsif inst == @name
146
        return self
147
      else
148 6 feddischso
        return nil
149 5 feddischso
      end
150
  end
151
 
152
 
153
 
154 3 feddischso
  def add_connection( inst1, ifc1_name, inst2, ifc2_name, con_name )
155
 
156
    return nil if inst_in_use?( con_name )
157
 
158
 
159
   [ [ inst1, ifc1_name ],
160
     [ inst2, ifc2_name ] ].each do |sub_arr|
161
      perr_if( ifc_in_use?( sub_arr[ 0 ], sub_arr[ 1 ] ),
162
          "Interface #{sub_arr[ 1 ]} of instance '#{sub_arr[ 0 ]}' is already in use " )
163
    end
164
 
165
 
166 5 feddischso
    core_spec_1 = get_core_def( inst1 )
167
    core_spec_2 = get_core_def( inst2 )
168 3 feddischso
 
169 5 feddischso
 
170 3 feddischso
    [ [ core_spec_1, ifc1_name ],
171
      [ core_spec_2, ifc2_name ] ].each do |sub_arr|
172
        perr_if( sub_arr[ 0 ].interfaces[ sub_arr[ 1 ].to_sym ] == nil,
173
          "Interface '#{sub_arr[ 1 ]}' dosn't exist in core '#{sub_arr[0].name}' " )
174
    end
175
 
176
    # check name and version of the ifcs which will be connected
177
    perr_if( core_spec_1.interfaces[ ifc1_name.to_sym ].name     !=
178
             core_spec_2.interfaces[ ifc2_name.to_sym ].name     ||
179
             core_spec_1.interfaces[ ifc1_name.to_sym ].version  !=
180
             core_spec_2.interfaces[ ifc2_name.to_sym ].version,
181
          "Can't connect #{
182
            core_spec_1.interfaces[ ifc1_name.to_sym ].name } - #{
183
            core_spec_2.interfaces[ ifc2_name.to_sym ].name } : #{
184
            core_spec_1.interfaces[ ifc1_name.to_sym ].version } - #{
185
            core_spec_2.interfaces[ ifc2_name.to_sym ].version }" )
186
 
187
 
188
    @cons[ con_name.to_sym ] = {
189
          :rule    => "or",
190
          :mapping => [ { inst1.to_sym => ifc1_name.to_sym },
191
                        { inst2.to_sym => ifc2_name.to_sym } ] }
192 5 feddischso
    return false
193 3 feddischso
  end
194
 
195
  def set_param( instance, param, value )
196
 
197
    # get instance
198
    core_inst = @cores[ instance.to_sym ]
199
    perr_if( core_inst == nil,
200
      "Can't find '#{instance}' in SOC" )
201
 
202
    # get the core-definition
203
    core_def = SOCMaker::lib.get_core( core_inst.type  )
204
 
205
    # check if parameter exist
206
    if core_def.inst_parameters[ param.to_sym ] != nil
207
      core_inst.params[ param.to_sym ] = value
208
    else
209
      perr_if( true,
210
        "Parameter '#{param}' not found in '#{core_def.name}'" )
211
    end
212
 
213
  end
214
 
215
  def get_param( instance, param )
216
 
217
    # get instance
218
    core_inst = @cores[ instance.to_sym ]
219
    perr_if( core_inst == nil,
220
      "Can't find '#{instance}' in SOC" )
221
    param_val = core_inst.params[ param.to_sym ]
222
    perr_if( param_val == nil,
223
      "Can't find parameter '#{param}' in '#{instance}'" )
224
    return param_val
225
  end
226
 
227
 
228
  def set_sparam( core, param, value )
229
 
230
    #get instance
231
 
232
    # check, if we are instantiating this core
233
    perr_if( @cores.select{ |name,inst| inst.type == core }.size == 0,
234
      "Core '#{core}' is not instantiated in this SOC" )
235
 
236
    # get the core-definition
237
    core_def = SOCMaker::lib.get_core( core )
238
 
239
    # check if parameter exist
240
    perr_if( core_def.static_parameters.select{ |f,p| p.parameters[ param.to_sym ] != nil }.size == 0,
241
        "Parameter '#{param}' not found in '#{core_def.name}'" )
242
 
243
    @static[ core.to_sym ] ||= {}
244
    @static[ core.to_sym ][ param.to_sym ] = value
245
  end
246
 
247
  def get_sparam( core, param )
248
    perr_if( @static[ core.to_sym ] == nil,
249
      "Core '#{core}' does not exist in this SOC" )
250
 
251
    perr_if( @static[ core.to_sym ][ param.to_sym ] == nil,
252
      "Parameter '#{param}' does not exist for core '#{core}'" )
253
 
254
    return @static[ core.to_sym ][ param.to_sym ]
255
  end
256
 
257
 
258
  def copy_files
259
 
260
    SOCMaker::logger.proc( "START of copying all HDL files" )
261
 
262
    #
263
    # Create a unique list of cores and
264
    # for every core, create a directory and copy files
265
    #
266
    @cores.values.uniq{|x| x.type }.each do |core_inst; core_def, dst_dir|
267
 
268
      core_def = SOCMaker::lib.get_core( core_inst.type )
269
 
270
      # create destination directory name and ensure, that it is exist
271
      dst_dir  = get_and_ensure_dst_dir!( core_def.name )
272
 
273
      # copy each file into destination dir
274
      core_def.hdlfiles.each do |file, val|
275
        file_path = File.join( core_def.dir, val.path )
276 5 feddischso
        dst_path = File.join( dst_dir, val.path )
277 3 feddischso
        SOCMaker::logger.proc( "copy #{file_path} to #{ dst_path} " )
278 5 feddischso
        FileUtils.mkdir_p(File.dirname(dst_path))
279 3 feddischso
        FileUtils.cp( file_path, dst_path )
280
      end
281
 
282
 
283
 
284
      #
285
      # handle the static parameters
286
      #   (search and replace in pakckage/include files)
287
      core_def.static_parameters.each do |file, param|
288
 
289
        token_val_map = {}
290
        param.parameters.each do |n,p|
291
 
292
          if  @static[ core_inst.type.to_sym ]      != nil and
293
              @static[ core_inst.type.to_sym ][ n ] != nil
294
 
295
            # use value defined in soc-spec
296
            token_val_map[ p.token ] = @static[ core_inst.type.to_sym ][ n ]
297
          else
298
            # use default value from core-spec
299
            token_val_map[ p.token ] =  p.default
300
          end
301
 
302
        end
303
 
304
        # create file paths
305
        src_path = File.join( core_def.dir, param.path )
306
        dst_dir  = get_and_ensure_dst_dir!( core_def.name )
307
        dst_path = File.join( dst_dir, param.file_dst )
308
 
309
 
310
        # process each line of input file
311
        # and replace tokens by value via
312
        # regular expression
313
        File.open( dst_path, 'w' ) do |dst_f|
314
          File.open( src_path ) do |src_f|
315
            SOCMaker::logger.proc( "create #{dst_path} from #{ src_path} " )
316
            while line = src_f.gets
317
              token_val_map.each { |token, val| line = line.sub( Regexp.new( token.to_s ), val.to_s ) }
318
              dst_f.puts line
319
            end
320
          end
321
        end
322
 
323
 
324
 
325
      end
326
 
327
    end
328
 
329
 
330
    SOCMaker::logger.proc( "END of copying all HDL files" )
331
  end
332
 
333
 
334 6 feddischso
 
335 3 feddischso
  def ==(o)
336
    o.class   == self.class   &&
337
    o.cores   == self.cores   &&
338
    o.cons    == self.cons    &&
339
    o.static  == self.static  &&
340
    super( o )
341
  end
342
 
343
 
344 5 feddischso
  def to_s
345
 
346
    tmp = "_________ SOC #{@name}: _______\n"     +
347
          super                                   +
348
          "\n__connections__\n"
349
 
350
    @cons.each do |_con_name, con_def|
351
      tmp += "#{_con_name}: #{con_def}\n"
352
    end
353
 
354
    tmp += "\n__cores__\n"
355
    @cores.each do |inst_name, inst|
356
      tmp += "#{inst_name}:\n#{inst}\n"
357
    end
358
    tmp += "'''''''''''''''''''''''''''''''''''\n"
359
    return tmp
360
  end
361
 
362
 
363 3 feddischso
end # class SOCSpec
364
end # module SOCMaker
365
 
366
 
367
# vim: noai:ts=2:sw=2

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.