###############################################################
|
###############################################################
|
#
|
#
|
# File: spc_lib.rb
|
# File: spc_lib.rb
|
#
|
#
|
# Author: Christian Hättich
|
# Author: Christian Hättich
|
#
|
#
|
# Project: System-On-Chip Maker
|
# Project: System-On-Chip Maker
|
#
|
#
|
# Target: Linux / Windows / Mac
|
# Target: Linux / Windows / Mac
|
#
|
#
|
# Language: ruby
|
# Language: ruby
|
#
|
#
|
#
|
#
|
###############################################################
|
###############################################################
|
#
|
#
|
#
|
#
|
# Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
|
# Copyright (C) 2014 Christian Hättich - feddischson [ at ] opencores.org
|
#
|
#
|
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
# the Free Software Foundation, either version 3 of the License, or
|
# the Free Software Foundation, either version 3 of the License, or
|
# (at your option) any later version.
|
# (at your option) any later version.
|
#
|
#
|
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
#
|
#
|
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
# along with this program. If not, see .
|
# along with this program. If not, see .
|
#
|
#
|
#
|
#
|
###############################################################
|
###############################################################
|
#
|
#
|
# Description:
|
# Description:
|
# This class represents the library, which holds all
|
# This class represents the library, which holds all
|
# - cores (core-definitions)
|
# - cores (core-definitions)
|
# - interfaces (interface-specifications)
|
# - interfaces (interface-specifications)
|
#
|
#
|
#
|
#
|
####
|
####
|
#
|
#
|
#
|
#
|
#
|
#
|
###############################################################
|
###############################################################
|
|
|
module SOCMaker
|
module SOCMaker
|
class Lib
|
class Lib
|
|
include ERR
|
|
|
def initialize
|
def initialize
|
|
|
# will store all cores
|
# will store all cores
|
@cores_lib = {}
|
@cores_lib = {}
|
|
|
# will store the versions of all cores { name => { ver1, ver2, ver3 } }
|
# will store the versions of all cores { name => { ver1, ver2, ver3 } }
|
@cores_ver = {}
|
@cores_ver = {}
|
|
|
# will store all interfaces
|
# will store all interfaces
|
@ifc_lib = {}
|
@ifc_lib = {}
|
|
|
# will store the versions of all interfaces { name => { ver1, ver2, ver3 } }
|
# will store the versions of all interfaces { name => { ver1, ver2, ver3 } }
|
@ifc_ver = {}
|
@ifc_ver = {}
|
|
|
|
|
# we remember paths, which we've already processed
|
# we remember paths, which we've already processed
|
@path_lut = []
|
@path_lut = []
|
|
|
end
|
end
|
|
|
|
|
def clear
|
def clear
|
@cores_lib.clear
|
@cores_lib.clear
|
@cores_ver.clear
|
@cores_ver.clear
|
@ifc_lib.clear
|
@ifc_lib.clear
|
@ifc_ver.clear
|
@ifc_ver.clear
|
@path_lut.clear
|
@path_lut.clear
|
end
|
end
|
|
|
|
|
# refreshes the core library:
|
# refreshes the core library:
|
# it useses the global configuration entry cores_search_path,
|
# it useses the global configuration entry cores_search_path,
|
# which defines, where to search for inc_fname (defined in soc_maker_conf.rb) files.
|
# which defines, where to search for inc_fname (defined in soc_maker_conf.rb) files.
|
# For each directory, we call process_include
|
# For each directory, we call process_include
|
def refresh( paths = nil )
|
def refresh( paths = nil )
|
|
|
paths = [ paths ] if paths.is_a?( String )
|
paths = [ paths ] if paths.is_a?( String )
|
|
|
|
|
SOCMaker::logger.info "START REFRESHING CORE LIBRARY"
|
SOCMaker::logger.info "START REFRESHING CORE LIBRARY"
|
|
|
# clear the libs
|
# clear the libs
|
clear
|
clear
|
|
|
# use argument if given, otherwise config paths
|
# use argument if given, otherwise config paths
|
paths ||= SOCMaker::conf[ :cores_search_path ]
|
paths ||= SOCMaker::conf[ :cores_search_path ]
|
|
|
|
|
paths.each do |dir|
|
paths.each do |dir|
|
process_include dir
|
process_include dir
|
end
|
end
|
SOCMaker::logger.info "DONE REFRESHING CORE LIBRARY"
|
SOCMaker::logger.info "DONE REFRESHING CORE LIBRARY"
|
|
|
end
|
end
|
|
|
|
|
|
|
def process_include( dir )
|
def process_include( dir )
|
|
|
#
|
#
|
# this prevents the revursive call
|
# this prevents the revursive call
|
# from an infinite call
|
# from an infinite call
|
#
|
#
|
folder_sym = File.expand_path( dir ).to_sym
|
folder_sym = File.expand_path( dir ).to_sym
|
if @path_lut.include?( folder_sym )
|
lerr_if( @path_lut.include?( folder_sym ),
|
SOCMaker::logger.warn( "double-include: infinite resursive search?" )
|
"double-include: infinite resursive search?" )
|
raise SOCMaker::ERR::LibError.new( "", "double-include" )
|
|
else
|
|
@path_lut << folder_sym
|
@path_lut << folder_sym
|
end
|
|
|
|
# get all yaml files in the directory
|
# get all yaml files in the directory
|
SOCMaker::logger.info "search for include in: " + dir
|
SOCMaker::logger.info "search for include in: " + dir
|
|
|
|
|
SOCMaker::from_s( get_all_yaml_in_str( dir ) ) do |o|
|
SOCMaker::from_s( get_all_yaml_in_str( dir ) ) do |o|
|
o.dir = dir
|
o.dir = dir
|
case o
|
case o
|
when SOCMaker::LibInc
|
when SOCMaker::LibInc
|
add_include( o, dir )
|
add_include( o, dir )
|
when SOCMaker::CoreDef
|
when SOCMaker::CoreDef
|
add_core( o )
|
add_core( o )
|
when SOCMaker::SOCDef
|
when SOCMaker::SOCDef
|
add_core( o )
|
add_core( o )
|
when SOCMaker::IfcSpc
|
when SOCMaker::IfcSpc
|
add_ifc( o )
|
add_ifc( o )
|
else
|
else
|
#TODO add error
|
#TODO add error
|
end
|
end
|
end
|
end
|
|
|
end
|
end
|
|
|
|
|
|
|
def get_all_yaml_in_str( dir )
|
def get_all_yaml_in_str( dir )
|
yaml_str = ""
|
yaml_str = ""
|
Dir[ File.join( dir, "*.yaml" ) ].sort.each do |yaml_file|
|
Dir[ File.join( dir, "*.yaml" ) ].sort.each do |yaml_file|
|
SOCMaker::logger.info "reading:" + yaml_file
|
SOCMaker::logger.info "reading:" + yaml_file
|
yaml_str << File.read( yaml_file )
|
yaml_str << File.read( yaml_file )
|
end
|
end
|
return yaml_str
|
return yaml_str
|
end
|
end
|
|
|
|
|
|
|
# gets an SOCMaker::LibInc object and iterates
|
# gets an SOCMaker::LibInc object and iterates
|
# over all folders.
|
# over all folders.
|
# Note: this is moved from process_include to this extra function
|
# Note: this is moved from process_include to this extra function
|
# to support test capability
|
# to support test capability
|
def add_include( soc_inc_object, dir )
|
def add_include( soc_inc_object, dir )
|
soc_inc_object.dirs.each { |d| process_include( File.expand_path( File.join( dir, d ) ) ) }
|
soc_inc_object.dirs.each { |d| process_include( File.expand_path( File.join( dir, d ) ) ) }
|
end
|
end
|
|
|
def add_core( core )
|
def add_core( core )
|
# generate key-string from name and vesion
|
# generate key-string from name and vesion
|
core_key = core.name + core.version
|
core_key = core.name + core.version
|
|
|
# save core
|
# save core
|
@cores_lib[ core_key ] = core
|
@cores_lib[ core_key ] = core
|
@cores_ver[ core.name.to_sym ] = [] unless @cores_ver.has_key?(core.name.to_sym)
|
@cores_ver[ core.name.to_sym ] = [] unless @cores_ver.has_key?(core.name.to_sym)
|
@cores_ver[ core.name.to_sym ] << core.version
|
@cores_ver[ core.name.to_sym ] << core.version
|
|
|
SOCMaker::logger.info "loaded " +
|
SOCMaker::logger.info "loaded " +
|
core.name +
|
core.name +
|
" version " +
|
" version " +
|
core.version
|
core.version
|
end
|
end
|
def get_core( name, version = "" )
|
def get_core( name, version = "" )
|
core_key = name + version
|
core_key = name + version
|
tmp = @cores_lib[ core_key ]
|
tmp = @cores_lib[ core_key ]
|
check_nil( tmp, "Core '#{name}' version '#{version}' does not exist" )
|
check_nil( tmp, "Core '#{name}' version '#{version}' does not exist" )
|
return tmp
|
return tmp
|
end
|
end
|
def rm_core( core )
|
def rm_core( core )
|
core_key = core.name + core.version
|
core_key = core.name + core.version
|
@cores_lib.delete( core_key )
|
@cores_lib.delete( core_key )
|
end
|
end
|
|
|
|
|
def add_ifc( ifc )
|
def add_ifc( ifc )
|
ifc_key = ifc.name + ifc.version
|
ifc_key = ifc.name + ifc.version
|
@ifc_lib[ ifc_key ] = ifc
|
@ifc_lib[ ifc_key ] = ifc
|
@ifc_ver[ ifc.name.to_sym ] = [] unless @ifc_ver.has_key?(ifc.name.to_sym)
|
@ifc_ver[ ifc.name.to_sym ] = [] unless @ifc_ver.has_key?(ifc.name.to_sym)
|
@ifc_ver[ ifc.name.to_sym ] << ifc.version
|
@ifc_ver[ ifc.name.to_sym ] << ifc.version
|
end
|
end
|
def get_ifc( name, version = "" )
|
def get_ifc( name, version = "" )
|
ifc_key = name + version
|
ifc_key = name + version
|
tmp = @ifc_lib[ ifc_key ]
|
tmp = @ifc_lib[ ifc_key ]
|
check_nil( tmp, "Interface '#{name}' version '#{version}' does not exist" )
|
check_nil( tmp, "Interface '#{name}' version '#{version}' does not exist" )
|
return tmp
|
return tmp
|
end
|
end
|
def rm_ifc( ifc )
|
def rm_ifc( ifc )
|
ifc_key = ifc.name + ifc.version
|
ifc_key = ifc.name + ifc.version
|
@ifc_lib.delete( ifc_key )
|
@ifc_lib.delete( ifc_key )
|
end
|
end
|
|
|
def to_s
|
def to_s
|
"IP-Core - lib: \n" +
|
"IP-Core - lib: \n" +
|
@cores_lib.keys.to_s +
|
@cores_lib.keys.to_s +
|
"\n\nIP-Core - versions: \n" +
|
"\n\nIP-Core - versions: \n" +
|
@cores_ver.to_s +
|
@cores_ver.to_s +
|
"\n\nInterface - lib: \n" +
|
"\n\nInterface - lib: \n" +
|
@ifc_lib.keys.to_s +
|
@ifc_lib.keys.to_s +
|
"\n\nInterface - versions: \n" +
|
"\n\nInterface - versions: \n" +
|
@ifc_ver.to_s + "\n"
|
@ifc_ver.to_s + "\n"
|
end
|
end
|
|
|
|
|
|
|
def check_nil( var, error_msg = "")
|
def check_nil( var, error_msg = "")
|
if var == nil
|
if var == nil
|
SOCMaker::logger.error error_msg
|
SOCMaker::logger.error error_msg
|
raise SOCMaker::ERR::LibError.new( "", error_msg )
|
raise SOCMaker::ERR::LibError.new( "", error_msg )
|
end
|
end
|
end
|
end
|
|
|
|
|
|
|
#
|
#
|
# get all interfaces in a list
|
# get all interfaces in a list
|
#
|
#
|
# TODO untested: do we need this?
|
# TODO untested: do we need this?
|
def get_ifcs( core )
|
def get_ifcs( core )
|
ifc_list = [];
|
ifc_list = [];
|
core.interfaces.values.each do |ifc; ifc_tmp|
|
core.interfaces.values.each do |ifc; ifc_tmp|
|
ifc_tmp = get_ifc( ifc[ :name ], ifc[ :version ] )
|
ifc_tmp = get_ifc( ifc[ :name ], ifc[ :version ] )
|
|
|
# error handling
|
# error handling
|
if ifc_tmp == nil
|
if ifc_tmp == nil
|
SOCMaker::logger.error "Can't find #{ifc[ :name ]} version #{ifc[ :version ]} in SOC library"
|
SOCMaker::logger.error "Can't find #{ifc[ :name ]} version #{ifc[ :version ]} in SOC library"
|
raise NameError, "Can't find #{ifc[ :name ]} version #{ifc[ :version ]} in SOC library"
|
raise NameError, "Can't find #{ifc[ :name ]} version #{ifc[ :version ]} in SOC library"
|
end
|
end
|
|
|
# add interface to list
|
# add interface to list
|
ifc_list << ifc_tmp
|
ifc_list << ifc_tmp
|
end
|
end
|
return ifc_list
|
return ifc_list
|
end
|
end
|
|
|
|
|
#
|
#
|
# TODO add test code
|
# TODO add test code
|
#
|
#
|
def cores
|
def cores
|
@cores_lib.each do |nameversion,core|
|
@cores_lib.each do |nameversion,core|
|
yield( nameversion.to_s, core )
|
yield( nameversion.to_s, core )
|
end
|
end
|
end
|
end
|
|
|
|
|
end #class Lib
|
end #class Lib
|
end #Module SOCMaker
|
end #Module SOCMaker
|
|
|
#
|
#
|
# vim: noai:ts=2:sw=2
|
# vim: noai:ts=2:sw=2
|
|
|