class SOCMaker::CoreDef

This class represents a core definition. It is one of the central classes and holds data, which is used to describe and instanciate a IP core. In general, instances of this class desribe a core, it's interface and parameters as well as the files, which are required for synthesis/simulation.

In addition to this core, there exist SOCMaker::CoreInst, which represents a concret instanciation of a definition.

Attributes

author[RW]

author of this core

authormail[RW]

author-mail of this core

date[RW]

creation date

description[RW]

description of this core

functions[RW]

reserved and not implemented

hdlfiles[RW]
id[RW]

ID of the core (mandatory, stored as hash key)

id_clean[RW]

the ID, but withou commata and as string, can be used for creating paths and so on

inst_parameters[RW]

hash of instantiation parameters see SOCMaker::Parameter

interfaces[RW]

interfaces which are implemented see SOCMaker::IfcSpc

license[RW]

license of this core

licensefile[RW]

location of the license file

name[RW]

name of the core (mandatory)

static_parameters[RW]

hash of static parameters see SOCMaker::SParameter

toplevel[RW]

toplevel name (mandatory)

vccmd[RW]

a version control command, which is used to download the files

Public Class Methods

core_cnt( core_id_array ) click to toggle source

Method, which counts the core occurence:

core_id_array

An array with id's, for example [ 'id1', 'id1', 'id2', 'id3' ]

return

A Hash with id => ofOccurence mapping, for example { 'id1' => 2, 'id2' => 1, 'id3' => 1 }

# File lib/soc_maker/core_def.rb, line 487
def self.core_cnt( core_id_array )
  cnt_hash = Hash.new( 0 )
  core_id_array.each do |v|
    cnt_hash[v] += 1
  end
  return cnt_hash
end
get_and_ensure_dst_dir!( dir_name ) click to toggle source

Creates a core directory, if it doesn't exist. The path of the target directoy depends on SOCMaker::conf[ :build_dir ] and on SOCMaker::conf[ :hdl_dir ]. The resulting path is

./build_dir/hdl_dir/dir_name
dir_name

Name of the target directory

# File lib/soc_maker/core_def.rb, line 507
def self.get_and_ensure_dst_dir!( dir_name )
    dst_dir =  File.expand_path(
          File.join( 
            SOCMaker::conf[ :build_dir ], 
            SOCMaker::conf[ :hdl_dir   ],
            dir_name ) )
    FileUtils.mkdir_p dst_dir
    return dst_dir
end
new( name, id, toplevel, optional = {} ) click to toggle source

Constructor: the three attributes name, id and toplevel are required. All other attributes can be given as a optinal hash.

name

Name of this core (string)

id

Id of this core (string)

toplevel

Toplevel name of this core (string)

optional

Non-mandatory values, which can be set during initialization.

# File lib/soc_maker/core_def.rb, line 116
def initialize( name, id, toplevel, optional = {} )
  init_with( { 'name'      => name, 
               'id'        => id, 
               'toplevel'  => toplevel }.merge( optional ) )
end

Public Instance Methods

==(o) click to toggle source

Equality operator

# File lib/soc_maker/core_def.rb, line 446
def ==(o)

  tmp    = ( o.class   == self.class )
  return tmp if !tmp

  %w[ name id description date license licensefile 
      author authormail vccmd toplevel interfaces 
      functions inst_parameters static_parameters hdlfiles ].
        each do |v| 
    return false if instance_variable_get( "@#{v}" ) != o.instance_variable_get( "@#{v}" )
  end
  return true
end
add_interface( ifc_name, ifc_id, dir, ports ) click to toggle source
# File lib/soc_maker/core_def.rb, line 428
def add_interface( ifc_name, ifc_id, dir, ports )
  processing_error_if( @interfaces.has_key?( ifc_name.to_sym ),
      "Interface name #{ifc_name} already exist",
      name: ifc_name,
      id_to_add: ifc_id )
  @interfaces[ ifc_name.to_sym ] = SOCMaker::IfcDef.new( ifc_name, ifc_id, dir, ports );

end
all_core_id() click to toggle source

This method is required to allow recursive search of all IDs and returns only it's ID (because there are no sub-cores).

# File lib/soc_maker/core_def.rb, line 568
def all_core_id
  [ @id ]
end
all_static_parameters() click to toggle source

This method is required to allow recursive static parameter collection. Because this is a sigle core and doesn't have sub-cores (which might have some static parameters), an empty hash is returned.

# File lib/soc_maker/core_def.rb, line 525
def all_static_parameters
  Hash.new()
end
consistence_check() click to toggle source

Runs a consistence check: Iterate over all interfaces and check, if the interface is in the SOCMaker::Lib. The method also checks also, if the ports defined by this core is also defined in the interface.

# File lib/soc_maker/core_def.rb, line 307
def consistence_check
  @interfaces.values.each_with_index do | ifc, i_ifc; ifc_spc|

    # get interface definition
    ifc_spc = SOCMaker::lib.get_ifc( ifc.id )



    # check if all refereces (to the ports) exist
    ifc.ports.each_with_index do |(port_name, port_def), i_port |
      spc_ref      = port_def.spc_ref.to_sym
      consistence_error_if( 
          !ifc_spc.ports.has_key?( spc_ref ), 
          "Can't find #{port_def} in" + 
          "interface definition #{ifc_spc.name} ",
          id: ifc_spc.id,
          portname: port_name )
    end


    # check, if all mandatory ports are implemented by this interface
    ifc_spc.ports.each do | port_name, port |
      consistence_error_if( 
          port[ :mandatory ] == true &&  
          ifc.ports.select{ |key,port_def| port_def.spc_ref.to_sym == port_name }.size == 0,  
        "Mandatory port #{port_name} is not implemented in interface #{ifc.name}",
        port: port_name,
        interface: ifc.name )
    end

  end

end
core_definition( inst ) click to toggle source
# File lib/soc_maker/core_def.rb, line 438
def core_definition( inst )
  return nil;
end
deploy( options={} ) click to toggle source

Method to deploy this core: all files are copied and deployed:

  • all hdl-files

  • all files with static-parameters

options

Optinal arguments: usually the static parameters are passed via options[ :static ]

# File lib/soc_maker/core_def.rb, line 539
def deploy( options={} )
  options = { static: {} }.merge( options )

  # create destination directory name and ensure, that it is exist
  dst_dir  = CoreDef::get_and_ensure_dst_dir!( dir_name )



  # copy each file into destination dir
  @hdlfiles.each do |file, val|
    file_path = File.join( @src_dir, val.path )
    dst_path = File.join( dst_dir, val.path )
    SOCMaker::logger.proc( "copy #{file_path} to #{ dst_path} " )
    FileUtils.mkdir_p(File.dirname(dst_path))
    FileUtils.cp( file_path, dst_path )
  end

  # deploy all static-parameter files
  @static_parameters.each do |file, sparam|
    sparam.deploy( options[ :static ][ @id ], @src_dir, dst_dir )
  end

end
dir_name() click to toggle source

The directory name of this core (returns @id_clean)

# File lib/soc_maker/core_def.rb, line 268
def dir_name
  @id_clean
end
encode_with( coder ) click to toggle source

Encoder method (to yaml)

coder

An instance of the Psych::Coder to encode this class to a YAML file

# File lib/soc_maker/core_def.rb, line 127
def encode_with( coder )
  init_error_if !coder.is_a?( Psych::Coder ), 
              'coder is not given as Psych::Coder'
  %w[ name description date license licensefile 
      author authormail vccmd toplevel interfaces 
      functions inst_parameters static_parameters hdlfiles ].
        each { |v| coder[ v ] = instance_variable_get "@#{v}" }

  coder[ "id" ] = @id.to_s
end
generics() { |_generic_name , _generic_type , _generic_default, _is_last| ... } click to toggle source

Iterates over all generic values of this core and yield the call block with

  • generic name

  • generic type

  • generic default

  • is-last value

# File lib/soc_maker/core_def.rb, line 352
def generics
  @inst_parameters.each_with_index do |(name, val), i|

    _generic_name     = name.to_s
    _generic_type     = val.type
    _generic_default  = val.default
    _is_last          = i == @inst_parameters.size-1
    yield( _generic_name   , 
           _generic_type   , 
           _generic_default, 
           _is_last         )

  end
end
ifc_specification( ifc_name ) click to toggle source

Method to get an interface specification, used by this core. The interface is identified by it's name (within this core)

ifc_name

Interface name (within this core, not the ID)

# File lib/soc_maker/core_def.rb, line 280
def ifc_specification( ifc_name )
  SOCMaker::lib.get_ifc( @interfaces[ ifc_name ].id )
end
init_with( coder ) click to toggle source

Initialization method (from yaml)

coder

An instance of the Psych::Coder to init this class from a YAML file

# File lib/soc_maker/core_def.rb, line 144
def init_with( coder )
  init_error_if !( coder.is_a?( Hash ) || coder.is_a?( Psych::Coder ) ), 
              'coder is not given as Hash neither as Psych::Coder'

  @name     = coder[ 'name'     ]
  @toplevel = coder[ 'toplevel' ]

  # check name
  init_error 'Name must be of type string',     field: 'name' if !@name.is_a?( String )
  init_error 'Name is not defined (size == 0)', field: 'name' if @name.size  == 0

  # check id
  init_error 'Id must be of type string', 
                field: 'id' if !coder[ 'id' ].is_a?( String )

  @id       = coder[ 'id'       ].to_sym

  init_error 'Id not defined (size == 0)', 
      instance: @name, 
      field:    'id'        if @id.size == 0
  @id_clean = coder[ 'id' ].split(',').join("_")





  init_error "toplevel must be of type string",
    instance: @name, 
    field:    "toplevel"    if !@toplevel.is_a?( String )

  init_error 'Toplevel not defined (size == 0 )',
    instance: @name, 
    field:    'toplevel'    if @toplevel.size  == 0




  # set non-nil values
  #  -> we don't need to check for nil in the rest of the
  #     processing
  @description       = coder[ 'description'       ] || ""
  @date              = coder[ 'date'              ] || ""
  @license           = coder[ 'license'           ] || ""
  @licensefile       = coder[ 'licensefile'       ] || ""
  @author            = coder[ 'author'            ] || ""
  @authormail        = coder[ 'authormail'        ] || ""
  @vccmd             = coder[ 'vccmd'             ] || ""
  @interfaces        = coder[ 'interfaces'        ] || {}
  @functions         = coder[ 'functions'         ] || {}
  @inst_parameters   = coder[ 'inst_parameters'   ] || {}
  @static_parameters = coder[ 'static_parameters' ] || {}
  @hdlfiles          = coder[ 'hdlfiles'          ] || {}


  # ensure, that these fields are of type String
  %w[ description date license licensefile 
      author authormail vccmd ].each do |n|

    init_error "#{n} must be of type String", 
      instance: @name, 
      field:    n               if !instance_variable_get( '@'+n ).is_a?( String )
  end

  # ensure, that these fields are of type Hash
  %w[ interfaces inst_parameters
      functions  static_parameters ].each do |n|
    init_error "#{n} must be of type Hash", 
        instance: @name, 
        field:    n             if  !instance_variable_get( '@'+n ).is_a?( Hash )

  end



  # check interfaces
  @interfaces.each do |ifc_name, ifc|
    init_error 'Interface not defined', 
          instance: @name,
          interface: ifc_name   if ifc == nil

    init_error 'Interface definition is not SOCMaker::IfcDef (please use SOCM_IFC)', 
          instance:  @name,
          interface: ifc_name   if  !ifc.is_a?( SOCMaker::IfcDef )
  end

  # check instance parameters
  @inst_parameters.each do |name, param |

    init_error  'Instance parameter not SOCMaker::Parameter (please use SOCM_PARAM)', 
          instance: @name, 
          parameter: name       if !param.is_a?( SOCMaker::Parameter )
  end

  # check instance parameters
  @static_parameters.each do |name, sparam |

    init_error 'Static parameter not SOCMaker::Parameter (please use SOCM_SPARAM)', 
          instance: @name,
          parameter: name       if !sparam.is_a?( SOCMaker::SParameter )
  end


  init_error  'HDL files argument is not of type Hash',
    instance: @name, 
    field:    'hdlfiles' if !@hdlfiles.is_a?( Hash )


  # check hdl files
  @hdlfiles.each do |file_name, file_info |

    init_error 'HDL file not defined', 
          instance:   @name,
          filename:   file_name if file_info == nil

    init_error 'HDL file is not of type SOCMaker::HDLFile (use SOCM_HDL_FILE)', 
          instance: @name,
          filename: file_name if !file_info.is_a?( SOCMaker::HDLFile )
  end

end
ports( *args ) { |_port_name, _port_dir, _port_length, _port_default, spc_ref, _is_last| ... } click to toggle source

Iterates over interface list (if no argument is given) or all specified interfaces. For each interface, all ports are processed. For each port within each interface, we lookup the port spc_ref and yield the call block with

  • port-name

  • port length

  • default value

  • the spec-reference

  • is-last value

as argument

An xor mechanism between port_dir and ifc=>dir is used to determine the direction of a port, for example: If the interface is declared as input (1) and a port is declared as input (1) the resulting direction will be an output 1^1 = 0. But if the overall interface direction is an output (0) and a port is declared as input, the resulting direction will an input 0^1 = 1. This allows to define a port-direction in the interface definition, and toggle the directions on core-definition level.

args

An optional list of interface names

# File lib/soc_maker/core_def.rb, line 393
def ports( *args )

  if args.size == 0
    ifc_sel = @interfaces
  else
    ifc_sel = @interfaces.select{ |k,v| args.include?( k.to_s ) }
  end



  ifc_sel.values.each_with_index do | ifc, i_ifc; ifc_spc|

    # get interface specification
    ifc_spc = SOCMaker::lib.get_ifc( ifc.id )

    # loop over ports in this interface
    ifc.ports.each_with_index do |(port_name, port_def), i_port |

      # the reference to the port in the definition
      spc_ref      = port_def.spc_ref.to_sym

      _port_name    = port_name.to_s
      if ifc_spc.ports[ spc_ref ][:dir] != 2
        _port_dir     = ifc_spc.ports[ spc_ref ][:dir] ^ ifc.dir
      else
        _port_dir     = 2
      end
      _port_length  = port_def.len
      _port_default = ifc_spc.ports[ spc_ref ][ :default  ]
      _is_last      = ( (i_port == ifc.ports.size-1 ) and (i_ifc == ifc_sel.size-1 ) )
      yield(  _port_name, _port_dir, _port_length, _port_default, port_def.spc_ref, _is_last )
    end
  end
end
to_s() click to toggle source

Returns a string describing this instance

# File lib/soc_maker/core_def.rb, line 463
def to_s
  "id:                #{@id}\n"              +
  "toplevel:          #{@toplevel}\n"             +
  "description:       #{@description}\n"          +
  "date:              #{@date}\n"                 +
  "license:           #{@license}\n"              +
  "licensefile:       #{@licensefile}\n"          +
  "author:            #{@author}\n"               +
  "authormail:        #{@authormail}\n"           +
  "vccmd:             #{@vccmd}\n"                +
  "interfaces:        #{@interfaces}\n"           +
  "functions:         #{@functions}\n"            +
  "inst_parameters:   #{@inst_parameters}\n"      +
  "static_parameters: #{@static_parameters}\n"
end
update_vcs() click to toggle source

Runs the Version Control System command via system(.…)

# File lib/soc_maker/core_def.rb, line 288
def update_vcs
  unless self.vccmd.nil? or @vccmd.size == 0
    #puts"cd #{@dir} && #{@vccmd}"
    system( "cd #{@src_dir} && #{vccmd}" )
  end
end