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

Subversion Repositories soc_maker

[/] [soc_maker/] [trunk/] [lib/] [soc_maker/] [core_inst.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:      core_inst.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 core instantiation within
37
#     a SOC. It contains a params (parameters) hash,
38
#     which defines, which parameters are set to which values.
39
#     The type field is used to identify the SOCMaker::CoreDef
40
#     and the field @defn is initialized as reference to
41
#     the corresponding CoreDef instance.
42
#
43
#
44
###############################################################
45
 
46
 
47
module SOCMaker
48
class CoreInst
49
  include ERR
50
 
51
 
52
 
53
  attr_accessor :defn
54
  attr_accessor :type
55
  attr_accessor :params
56
 
57
  def initialize(  type, params = {} )
58
    init_with(  'type'   => type,
59
                'params' => params  )
60
    verify
61
  end
62
  def encode_with( coder )
63
    %w[ type params ].
64
      each { |v| coder[ v ] = instance_variable_get "@#{v}" }
65
  end
66
 
67
  def init_with( coder )
68
 
69
    serr_if( coder[ 'type' ] == nil,
70
      "no type is provided for a core instance",
71
      field: "type" )
72
 
73
    @type = coder[ 'type' ]
74
 
75
    @params = coder[ 'params' ] || {}
76
    serr_if( !@params.is_a?( Hash ), 'Parameters are not given as hash',
77
      field: 'params' )
78
 
79
  end
80
 
81
  def ports
82
    @ports.each_with_index do |(name, port_def), i|
83
      yield( name.to_s, port_def[ :len ], port_def[ :dir ], i==@ports.size-1 )
84
    end
85
  end
86
 
87
 
88
  def generics
89
    @defn.generics do |name, type, default_value, is_last|
90
      value = @params[ name.to_sym ];
91
      value = value
92
      value = default_value if value == nil
93
      yield( name.to_s, type, value, is_last )
94
    end
95
  end
96
 
97
 
98
 
99 6 feddischso
  def get_len( ifc_name, port_spec_name, inst = nil )
100 3 feddischso
 
101 6 feddischso
    if inst == nil
102
      tmp = @defn.interfaces[ ifc_name.to_sym ].
103
          ports.select{ |key,hash| hash.defn == port_spec_name.to_s }.
104
          keys.first.to_s
105 5 feddischso
 
106 6 feddischso
      return tmp.size == 0 ? 0 : @ports[ tmp.to_sym ][ :len ]
107
    else
108
      if inst == @name
109
        return get_len( ifc_name, port_spec_name )
110
      else
111
        return @defn.get_len( ifc_name, port_spec_name, inst )
112
      end
113
    end
114 3 feddischso
  end
115
 
116 5 feddischso
 
117 6 feddischso
 
118
 
119 5 feddischso
  def implements_port?( ifc_name, port_spec_name )
120
    @defn.implements_port?( ifc_name, port_spec_name )
121
  end
122
 
123 3 feddischso
  def get_port( ifc_name, port_spec_name )
124
    tmp = @defn.interfaces[ ifc_name.to_sym ].
125
        ports.select{ |key,hash| hash.defn == port_spec_name.to_s }.
126
        keys.first.to_s
127
    return [ tmp, @ports[ tmp.to_sym ] ]
128
  end
129
 
130
 
131
 
132
  def verify
133
 
134
    @defn = SOCMaker::lib.get_core( @type )
135
 
136
 
137
    # check, if the instance parameters in the core definition
138
    @params.each do |param_name, value|
139
      verr_if(  @defn.inst_parameters[ param_name ] == nil,
140
                "Parameter not found: " + param_name.to_s,
141
        field: 'params' )
142
    end
143
 
144
    ## auto-complete parameters with default values
145
    @defn.inst_parameters.each do |param_name, param|
146
 
147
      # auto-complete to default values
148
      @params[ param_name ] ||= param.default
149
    end
150
 
151
 
152
 
153
 
154
 
155
 
156
 
157
 
158
 
159
#   @_params ||= {}
160
#   if @params != nil
161
#     @params.each do |name, val|
162
#
163
#       param_type = defn.inst_parameters[ name ].type
164
#
165
#       if val.is_a? String
166
#         eval_match = SOCMaker::conf[ :eval_regex ].match( val )
167
#         #TODO error handling
168
#         if eval_match
169
#           #eval_func = eval_match.captures[0]
170
#           @_params[ name ] = { value: eval( eval_str ).to_s, type: param_type }
171
#         else
172
#           @_params[ name ] = { value: val, type: param_type }
173
#         end
174
#       else
175
#         @_params[ name ] = { value: val, type: param_type }
176
#       end
177
#     end
178
#   end
179
 
180
    @ports ||= {}
181
    @defn.ports do |port_name, port_dir, port_len, is_last |
182
      if port_len.is_a?( String )
183
        param_match = SOCMaker::conf[ :length_regex ].match( port_len )
184
 
185
        if param_match and @params[ port_len.to_sym ] != nil
186
          tmp =@params[ port_len.to_sym ]
187
          tmp = tmp.to_i if tmp.is_a?( String )
188
          @ports[ port_name.to_sym ] = { len: tmp, dir: port_dir }
189
        else
190
          SOCMaker::logger.error( "Failed to evaluate #{port_len} for port #{port_name}" )
191
        end
192
      else
193
        @ports[ port_name.to_sym ] = { len: port_len, dir: port_dir }
194
      end
195
    end
196
 
197
    lerr_if( @defn == nil, 'Core not found in lib',
198
      field:    'cores'    )
199
 
200
  end
201
 
202
 
203 6 feddischso
 
204
  def get_core_def( inst )
205
      tmp = @defn.get_core_def( inst )
206
      if tmp != nil
207
        return tmp
208
      elsif inst == @name
209
        return self
210
      else
211
        return nil
212
      end
213
  end
214
 
215
 
216
 
217
 
218
 
219
  def gen_toplevel( coder = VHDLCoder.new() )
220
 
221
 
222
    #
223
    # create filename
224
    #
225
    file_name = @defn.name.dup
226
    if coder.is_a?( VHDLCoder )
227
      file_name << ".vhd"
228
    elsif coder.is_a?( VerilogCoder )
229
      file_name << ".v"
230
    else
231
      perr_if( true,
232
        "No valid coder" )
233
    end
234
 
235
 
236
    SOCMaker::logger.proc( "START of creating top-level '" + file_name + "'" )
237
 
238
    SOCMaker::logger.proc( "verifying first ..." )
239
 
240
 
241
    # TODO: this is a fix, that the parameters in core_inst.ports are updated.
242
    #       A good approach for verifying, which checks the whole consistency, needs
243
    #       to be done
244
    @defn.cores.each do |inst_name, inst|
245
      inst.verify
246
    end
247
 
248
 
249
    #
250
    # Create a unique list of cores and
251
    # add every core to your implementation.
252
    # Even if there are multiple instances of a core,
253
    # we need to decalre it only once
254
    #
255
    @defn.cores.values.uniq{|x| x.type }.each do |inst; spec|
256
 
257
      spec = SOCMaker::lib.get_core( inst.type  )
258
      SOCMaker::lib.check_nil( spec, "Can't find #{ inst.type } in SOC library" )
259
 
260
      coder.add_core_declaration( inst.type, spec )
261
    end
262
 
263
   #core_instances = {}
264
   #@cores.each do |inst_name, _core_inst|
265
   #  # the corresponding core from SOC lib
266
   #  core_def = SOCMaker::lib.get_core( _core_inst[ :type ] )
267
   #  core_instances[ inst_name ] = SOCMaker::CoreInst.new( core_def, _core_inst[ :params ] )
268
   #end
269
 
270
 
271
    @defn.cores.each do |inst_name, inst|
272
      coder.add_core_inst( inst_name.to_s, inst )
273
    end
274
 
275
 
276
 
277
    # Iterate over all connections:
278
    #  - create signal instances
279
    #  - add assignments
280
    #
281
    @defn.cons.each do |con_name, con_def|
282
      gen_toplevel_con(   con_name.to_s,
283
                          con_def[ :rule ],
284
                          con_def[ :mapping ][0],
285
                          con_def[ :mapping ][1],
286
      coder  )
287
 
288
    end
289
 
290
    SOCMaker::logger.proc( "writing top-level" )
291
 
292
    file_dir  = File.join( SOCMaker::conf[ :build_dir ],
293
                           SOCMaker::conf[ :hdl_dir   ] )
294
    ::FileUtils.mkdir_p file_dir
295
    file_path = File.join( file_dir, file_name )
296
    File.open( file_path, 'w' ) do |f|
297
      f.write( coder.get_entity( self, "test" ) )
298
    end
299
    SOCMaker::logger.proc( "END of creating top-level" )
300
 
301
  end
302
 
303
 
304
  def gen_toplevel_con( name, rule, src, dst, coder )
305
 
306
    src_inst            = {};
307
    dst_inst            = {};
308
 
309
    # fetch somehow the spec
310
    ifc_spec = SOCMaker::lib.get_ifc(
311
      get_core_def( src.keys.first.to_s ).interfaces[ src.values.first ].name,
312
      get_core_def( src.keys.first.to_s ).interfaces[ src.values.first ].version )
313
 
314
    #port_used   = {};
315
    length_tmp  = {};
316
 
317
 
318
    ifc_spec.ports.keys.each do |_name|
319
      # TODO: bis dahin konnte angenommen werden, dass self auch eine Art instanz ist,
320
      #       aber hier geht das nicht mehr, weil get_len nur für CoreInst definiert ist.
321
      #
322
 
323
 
324
      # create a length table
325
     #port_used[ _name ] = false
326
     #dst.each do |inst_name, ifc_name|
327
     #  port_used[ _name ] ||= get_core_def( inst_name ).implements_port?( ifc_name, _name )
328
     #end
329
     #src.each do |inst_name, ifc_name|
330
     #  port_used[ _name ] ||= get_core_def( inst_name ).implements_port?( ifc_name, _name )
331
     #end
332
 
333
 
334
 
335
      length_tmp[ _name ] = []
336
      dst.each do |inst_name, ifc_name|
337
        length_tmp[ _name ] << get_len( ifc_name, _name, inst_name )
338
      end
339
      src.each do |inst_name, ifc_name|
340
        length_tmp[ _name ] << get_len( ifc_name, _name, inst_name )
341
      end
342
 
343
    end
344
 
345
    # getting the maximum length for each signal
346
    max_length = Hash[ length_tmp.map{ |key, arr| [ key, arr.max ] } ]
347
 
348
 
349
    p max_length
350
    coder.ifc_declaration( ifc_spec, name, max_length )
351
 
352
    src.keys.each do |inst_name|
353
      src_inst[ inst_name ]            = @defn.cores[ inst_name ]
354
    end
355
    dst.keys.each do |inst_name|
356
      dst_inst[ inst_name ]            = @defn.cores[ inst_name ]
357
    end
358
 
359
    coder.ifc_assignment( ifc_spec, name, max_length, src_inst, dst_inst, src, dst )
360
 
361
  end
362
 
363
 
364
 
365
 
366
 
367
 
368
 
369 5 feddischso
  def to_s
370
    "type:     #{type}\n"   +
371
    "params:   #{params}\n"
372
  end
373 3 feddischso
 
374
  def ==(o)
375
    o.class     == self.class   &&
376
    o.type      == self.type    &&
377
    o.params    == self.params
378
  end
379
 
380
 
381
end # CoreInst
382
end # SOCMaker
383
 
384
 
385
 
386
# 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.