URL
https://opencores.org/ocsvn/soc_maker/soc_maker/trunk
Subversion Repositories soc_maker
Compare Revisions
- This comparison shows the changes necessary to convert path
/soc_maker/trunk/lib/soc_maker
- from Rev 7 to Rev 8
- ↔ Reverse comparison
Rev 7 → Rev 8
/parameter.rb
61,7 → 61,8
attr_accessor :visible |
attr_accessor :editable |
attr_accessor :description |
|
attr_accessor :choice |
|
def initialize( type, options = {} ) |
init_with( { 'type' => type }.merge( options ) ) |
end |
90,7 → 91,7
@visible = coder[ 'visible' ] || true |
@editable = coder[ 'editable' ] || false |
@description = coder[ 'description' ] || '' |
|
@choice = coder[ 'choice' ] || [] |
end |
|
|
102,7 → 103,8
o.max == self.max && |
o.visible == self.visible && |
o.editable == self.editable && |
o.description == self.description |
o.description == self.description && |
o.choice == self.choice |
end |
|
|
/hdl_coder.rb
135,7 → 135,7
def entity_port_str( core ) |
port_string = "" |
|
core.ports do |port_name, port_dir, port_len, is_last | |
core.ports do |port_name, port_dir, port_len, port_default, is_last | |
|
# The string we are add in every iteration looks for example like |
# myportname1 : out std_logic_vector( 6-1 downto 0 ) |
144,7 → 144,6
# |
port_string << port_name.to_s << " : " |
|
puts port_name.to_s + ": dir: " + port_dir.to_s + ", len: " + port_len.to_s |
|
|
# port direction |
186,7 → 185,7
end |
@inst_part << "generic map( \n#{generic_str} )\n" if generic_str.size > 0 |
port_str = "" |
inst.ports do |port_name, dir, length, is_last| |
inst.ports do |port_name, dir, length, default, is_last| |
port_str << "#{port_name} => #{inst_name}_#{port_name}" |
port_str << "," unless is_last |
port_str << "\n" |
200,7 → 199,22
|
end |
|
def add_ifc_default_assignment( inst, inst_name, ifc_name, default ) |
|
|
tmp = "" |
inst.ports( ifc_name.to_s ) do |port_name, dir, length, default, is_last| |
if dir == 1 # assign default value only if it is an input |
if length > 1 |
tmp << "#{inst_name}_#{port_name} <= ( others => '#{default}' );\n" |
else |
tmp << "#{inst_name}_#{port_name} <= '#{default}';\n" |
end |
end |
end |
@asgn_part << tmp |
|
end |
|
def add_ifc_connection( ifc_spec, ifc_name, length, src_inst, dst_inst, src_ifc, dst_ifc ) |
|
226,8 → 240,10
# assignment |
# |
# |
ifc_spec.ports.each do |port_name, port_dir| |
if port_dir == 0 |
ifc_spec.ports.each do |port_name, port_setup| |
|
|
if port_setup[ :dir ] == 0 |
src_inst_sel = src_inst |
dst_inst_sel = dst_inst |
src_ifc_sel = src_ifc |
249,26 → 265,27
|
# combine all sources |
tmp = "#{port_tmp_name} <= " |
assigned = false |
|
# loop over instances |
src_inst_sel.each_with_index do |(inst_name, inst), i| |
( tmp_name, port) = inst.get_port( src_ifc_sel[ inst_name ], port_name ) |
if port != nil |
tmp << "\"" + "0" * ( length[ port_name ] - port[ :len ] ) + "\" & " if port[ :len ] < length[ port_name ] |
if port[ :len ] < length[ port_name ] |
tmp << "\"" + "0" * ( length[ port_name ] - port[ :len ] ) + "\" & " |
end |
tmp << "#{inst_name}_#{tmp_name}" |
tmp << " and \n" unless i == src_inst_sel.size-1 |
assigned = true |
else |
puts "#{port_tmp_name}: #{length[port_name] > 1}" |
if length[ port_name ] > 1 |
tmp << "( others => '0' )" |
else |
tmp << "'0'" |
end |
end |
end |
tmp << ";\n" |
@asgn_part << tmp if assigned |
@asgn_part << tmp |
|
|
puts src_inst_sel.size |
puts tmp |
|
|
tmp = "" |
assigned = false |
# assign to destination |
284,6 → 301,19
end |
end |
@asgn_part << tmp if assigned |
puts "NOT ASSIGNED DST" if not assigned |
else |
# puts "ifc #{ifc_name} port #{port_name.to_s} is not assigned" |
# p src_ifc |
# p dst_ifc |
# tmp = "" |
# dst_inst_sel.each_with_index do |(inst_name, inst), i| |
# p inst_name |
# p port_name |
# ( tmp_name, port) = inst.get_port( dst_ifc_sel[ inst_name ], port_name ) |
# tmp << "#{inst_name}_#{tmp_name} <= ( others => 'X' );\n" |
# end |
# @asgn_part << tmp; |
end |
|
end |
/core_inst.rb
78,11 → 78,15
|
end |
|
def ports |
puts "HELP" + @defn.name |
p @ports |
@ports.each_with_index do |(name, port_def), i| |
yield( name.to_s, port_def[ :dir ], port_def[ :len ], i==@ports.size-1 ) |
def ports( *args ) |
if args.size == 0 |
@ports.each_with_index do |(name, port_def), i| |
yield( name.to_s, port_def[ :dir ], port_def[ :len ], port_def[ :default ], i==@ports.size-1 ) |
end |
elsif args.size == 1 |
@ifcs[ args.first.to_sym ].each do |name, port_def, i| |
yield( name.to_s, port_def[ :dir ], port_def[ :len ], port_def[ :default ], i==@ports.size-1 ) |
end |
end |
end |
|
116,6 → 120,8
|
|
# TODO do we need this? |
# |
# |
# def implements_port?( ifc_name, port_spec_name ) |
# @defn.implements_port?( ifc_name, port_spec_name ) |
# end |
161,9 → 167,16
# end |
# end |
# end |
|
|
# |
# TODO merge these two loops and create one hash |
### |
# |
# create our own ports hash |
# |
@ports ||= {} |
@defn.ports do |port_name, port_dir, port_len, is_last | |
@defn.ports do |port_name, port_dir, port_len, default, is_last | |
if port_len.is_a?( String ) |
param_match = SOCMaker::conf[ :length_regex ].match( port_len ) |
|
170,17 → 183,41
if param_match and @params[ port_len.to_sym ] != nil |
tmp =@params[ port_len.to_sym ] |
tmp = tmp.to_i if tmp.is_a?( String ) |
@ports[ port_name.to_sym ] = { len: tmp, dir: port_dir } |
@ports[ port_name.to_sym ] = { len: tmp, dir: port_dir, default: default } |
else |
SOCMaker::logger.error( "Failed to evaluate #{port_len} for port #{port_name}" ) |
end |
else |
@ports[ port_name.to_sym ] = { len: port_len, dir: port_dir } |
@ports[ port_name.to_sym ] = { len: port_len, dir: port_dir, default: default } |
end |
end |
|
|
lerr_if( @defn == nil, 'Core not found in lib', |
field: 'cores' ) |
@ifcs ||= {} |
@defn.interfaces.keys.each do |ifc_name| |
@ifcs[ ifc_name ] = {} |
@defn.ports( ifc_name ) do |port_name, port_dir, port_len, default, is_last | |
|
if port_len.is_a?( String ) |
param_match = SOCMaker::conf[ :length_regex ].match( port_len ) |
|
if param_match and @params[ port_len.to_sym ] != nil |
tmp =@params[ port_len.to_sym ] |
tmp = tmp.to_i if tmp.is_a?( String ) |
@ifcs[ ifc_name ][ port_name.to_sym ] = { len: tmp, dir: port_dir, default: default } |
else |
SOCMaker::logger.error( "Failed to evaluate #{port_len} for port #{port_name}" ) |
end |
else |
@ifcs[ ifc_name ][ port_name.to_sym ] = { len: port_len, dir: port_dir, default: default } |
end |
# |
#puts "#{port_def_ref}, #{port_name}, #{port_dir}, #{port_default}" |
end |
end |
|
# lerr_if( @defn == nil, 'Core not found in lib', |
# field: 'cores' ) |
|
|
@defn.consistency_check |
271,17 → 308,6
SOCMaker::logger.proc( "START of creating top-level '" + file_name + "'" ) |
|
|
|
# SOCMaker::logger.proc( "verifying first ..." ) |
# |
# # TODO: this is a fix, that the parameters in core_inst.ports are updated. |
# # A good approach for verifying, which checks the whole consistency, needs |
# # to be done |
# @defn.cores.each do |inst_name, inst| |
# inst.verify |
# end |
|
|
# |
# Create a unique list of cores and |
# add for each core a component statement (vhdl only). |
317,7 → 343,9
coder ) |
|
end |
|
|
assign_unused_to_default( coder ) |
|
|
# |
# Write content to the file |
337,6 → 365,43
|
|
# |
# Assign default values for unused interfaces. |
# This is just a helper function and is used by gen_toplevel |
# |
# +coder+:: A HDL coder, which is used to create the auto-generated HDL. |
# |
def assign_unused_to_default( coder ) |
|
|
|
# iterate over all instances |
# and check all interfaces |
@defn.cores.each do |inst_name, inst| |
|
inst.defn.interfaces.each do |ifc_name, ifc| |
|
# |
# Get the interface specification by using the 1st source entry |
# and searching for the core-definition. |
# |
ifc_spec = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
|
if !@defn.ifc_in_use?( inst_name, ifc_name ) |
|
default_tmp = {}; |
ifc_spec.ports.each do |_name,_port| |
default_tmp[ _name ] = _port[ :default ] |
end |
|
coder.add_ifc_default_assignment( inst, inst_name, ifc_name, default_tmp ) |
end |
end |
end |
end |
|
|
|
# |
# This function is called during the toplevel generation |
# for each connection. |
# |
419,6 → 484,8
o.params == self.params |
end |
|
# TODO |
# private: assign_unused_to_default, :gen_toplevel_con |
|
end # CoreInst |
end # SOCMaker |
/err.rb
64,7 → 64,7
SOCMaker::logger.error( "StructureError raised: " + message + " (#{name},#{field})" ) |
end |
def to_s |
"->#{@name}:#{@field}" |
"#{super} -> #{@name}:#{@field}" |
end |
end |
|
76,7 → 76,7
SOCMaker::logger.error( "LibError raised: " + message + " (#{requested})" ) |
end |
def to_s |
"->#{@name}" |
"#{super} -> #{@name}:#{@field}" |
end |
end |
|
97,7 → 97,7
SOCMaker::logger.error( "ValueError raised: " + message + " (#{name},#{field})" ) |
end |
def to_s |
"->#{@name}:#{@field}" |
"#{super} -> #{@name}:#{@field}" |
end |
end |
|
/component.rb
219,7 → 219,20
|
|
def consistency_check |
@interfaces.values.each_with_index do | ifc, i_ifc; ifc_def| |
|
# get interface definition |
ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
|
|
# check, if all mandatory ports are implemented by this interface |
ifc_def.ports.each do | port_name, port | |
perr_if( port[ :mandatory ] == true && |
ifc.ports.select{ |key,port_def| port_def.defn.to_sym == port_name }.size == 0, |
"Mandatory port #{port_name} is not implemented in interface #{ifc.name}" ) |
end |
end |
|
end |
|
|
232,7 → 245,6
|
|
|
|
def generics |
@inst_parameters.each_with_index do |(name, val), i| |
yield( name.to_s, val.type, val.default, i == @inst_parameters.size-1 ) |
259,6 → 271,14
# - info if last |
# 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. |
# |
# |
def ports( *args ) |
273,26 → 293,15
ifc.ports.each_with_index do |(port_name, port_def), i_port; port_dir| |
|
# the reference to the port in the definition |
defn_ref = port_def.defn |
port_dir = ifc_def.ports[ defn_ref.to_sym ] |
perr_if( port_dir == nil, |
"Can't find #{defn_ref} in interface " + |
"definition #{ifc_def.name} version " + |
ifc_def.version + "==>>" + ifc_def.to_yaml ) |
|
# 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. |
|
# (name, direction, length, is_last) |
defn_ref = port_def.defn.to_sym |
perr_if( !ifc_def.ports.has_key?( defn_ref ), |
"Can't find #{port_def} in" + |
"interface definition #{ifc_def.name} " + |
"version #{ifc_def.version}" ) |
yield( port_name.to_s, |
port_dir ^ ifc.dir, |
ifc_def.ports[ defn_ref ][:dir] ^ ifc.dir, |
port_def.len, |
ifc_def.ports[ defn_ref ][ :default ], |
( (i_port == ifc.ports.size-1 ) and (i_ifc == @interfaces.size-1 ) ) ) |
end |
end |
301,24 → 310,29
|
# get interface (input is the name as string ) |
ifc = @interfaces[ args.first.to_sym ] |
ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
|
ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
ifc.ports.each do |port_name, port_def; port_dir| |
port_def = port_def.defn |
port_dir = ifc_def.ports[ port_def.to_sym ] |
if port_dir == nil |
perr_if( port_dir==nil, |
"Can't find #{port_def} in" + |
"interface definition #{ifc_def.name} " + |
"version #{ifc_def.version}" ) |
end |
yield( port_def.to_s, |
port_name.to_s, |
port_dir ^ ifc.dir ) |
# loop over all ports of this interface |
ifc.ports.each_with_index do |(port_name, port_def),i_port; port_dir| |
defn_ref = port_def.defn.to_sym |
perr_if( !ifc_def.ports.has_key?( defn_ref ), |
"Can't find #{defn_ref} in" + |
"interface definition #{ifc_def.name} " + |
"version #{ifc_def.version}" ) |
yield( port_name.to_s, |
ifc_def.ports[ defn_ref ][:dir] ^ ifc.dir, |
port_def.len, |
ifc_def.ports[ defn_ref ][ :default ], |
( (i_port == ifc.ports.size-1 ) ) |
) |
#yield( port_def.to_s, |
#port_name.to_s, |
#port_dir ^ ifc.dir, |
#port_default ) |
end |
|
else |
|
# TODO |
end |
|
end |
381,3 → 395,4
|
# vim: noai:ts=2:sw=2 |
|
# vim: noai:ts=2:sw=2 |
/soc_def.rb
273,6 → 273,7
|
SOCMaker::logger.proc( "START of copying all HDL files" ) |
|
|
# |
# Create a unique list of cores and |
# for every core, create a directory and copy files |
293,32 → 294,43
FileUtils.cp( file_path, dst_path ) |
end |
|
|
|
# |
# handle the static parameters |
# (search and replace in pakckage/include files) |
core_def.static_parameters.each do |file, param| |
core_def.static_parameters.each do |file, sparam| |
|
token_val_map = {} |
param.parameters.each do |n,p| |
sparam.parameters.each do |n,sparam_entry| |
|
if @static[ core_inst.type.to_sym ] != nil and |
@static[ core_inst.type.to_sym ][ n ] != nil |
|
# use value defined in soc-spec |
token_val_map[ p.token ] = @static[ core_inst.type.to_sym ][ n ] |
tmp = @static[ core_inst.type.to_sym ][ n ] |
else |
# use default value from core-spec |
token_val_map[ p.token ] = p.default |
tmp = sparam_entry.default |
end |
|
if sparam_entry.type == "enum" |
token_val_map[ sparam_entry.token ] = sparam_entry.choice[ tmp ] |
elsif sparam_entry.type == "bool" |
if tmp == true |
token_val_map[ sparam_entry.token ] = sparam_entry.choice |
else |
token_val_map[ sparam_entry.token ] = "" |
end |
else |
token_val_map[ sparam_entry.token ] = tmp |
end |
|
|
end |
|
|
# create file paths |
src_path = File.join( core_def.dir, param.path ) |
src_path = File.join( core_def.dir, sparam.path ) |
dst_dir = get_and_ensure_dst_dir!( core_def.name ) |
dst_path = File.join( dst_dir, param.file_dst ) |
dst_path = File.join( dst_dir, sparam.file_dst ) |
|
|
# process each line of input file |
328,7 → 340,7
File.open( src_path ) do |src_f| |
SOCMaker::logger.proc( "create #{dst_path} from #{ src_path} " ) |
while line = src_f.gets |
token_val_map.each { |token, val| line = line.sub( Regexp.new( token.to_s ), val.to_s ) } |
token_val_map.each { |token, val| line = line.sub( Regexp.new( '\b' + token.to_s + '\b' ), val.to_s ) } |
dst_f.puts line |
end |
end |
/core_def.rb
74,19 → 74,23
def init_with( coder ) |
super( coder ) |
|
serr_if( coder[ 'hdlfiles' ] == nil, |
'No hdlfiles field found', |
instance: @name, |
fiel: 'hdlfiles' ) |
@hdlfiles = coder[ 'hdlfiles' ] |
# TODO: this was removed because we want to |
# support cores, which have a config-file only |
# (where config and implementation is in one file) |
|
# serr_if( coder[ 'hdlfiles' ] == nil, |
# 'No hdlfiles field found', |
# instance: @name, |
# fiel: 'hdlfiles' ) |
@hdlfiles = coder[ 'hdlfiles' ] || {} |
serr_if( !@hdlfiles.is_a?( Hash ), |
'HDL file def. != Hash', |
instance: @name, |
field: 'hdlfiles' ) |
serr_if( @hdlfiles.size == 0, |
'No HDL files are given', |
instance: @name, |
field: 'hdlfiles' ) |
# serr_if( @hdlfiles.size == 0, |
# 'No HDL files are given', |
# instance: @name, |
# field: 'hdlfiles' ) |
|
@hdlfiles.each do |file_name, defn | |
serr_if( defn == nil, |
112,6 → 116,11
|
|
# |
# TODO this also exists in component.rb |
# might this be removed? |
# If yes, make sure, that the 'default' stuff |
# is also done in component.rb!!! |
# |
# Iterates over interface list. |
# For each interface, all ports are processed. |
# For each port within each interface, we lookup the port defn |
123,68 → 132,70
# |
# |
# |
def ports( *args ) |
#def ports( *args ) |
|
|
if args.size == 0 |
@interfaces.values.each_with_index do | ifc, i_ifc; ifc_def| |
#if args.size == 0 |
#@interfaces.values.each_with_index do | ifc, i_ifc; ifc_def| |
|
# get interface definition |
ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
## get interface definition |
#ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
|
# loop over ports in this interface |
ifc.ports.each_with_index do |(port_name, port_def), i_port; port_dir| |
## loop over ports in this interface |
#ifc.ports.each_with_index do |(port_name, port_def), i_port; port_dir| |
|
# the reference to the port in the definition |
defn_ref = port_def.defn |
port_dir = ifc_def.ports[ defn_ref.to_sym ] |
perr_if( port_dir == nil, |
"Can't find #{defn_ref} in interface " + |
"definition #{ifc_def.name} version " + |
ifc_def.version + "==>>" + ifc_def.to_yaml ) |
## the reference to the port in the definition |
#defn_ref = port_def.defn |
#port_dir = ifc_def.ports[ defn_ref.to_sym ][ :dir ] |
#port_default = ifc_def.ports[ defn_ref.to_sym ][ :default ] |
#perr_if( port_dir == nil, |
#"Can't find #{defn_ref} in interface " + |
#"definition #{ifc_def.name} version " + |
#ifc_def.version + "==>>" + ifc_def.to_yaml ) |
|
# 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. |
## 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. |
|
# (name, direction, length, is_last) |
yield( port_name.to_s, |
port_dir ^ ifc.dir, |
port_def.len, |
( (i_port == ifc.ports.size-1 ) and (i_ifc == @interfaces.size-1 ) ) ) |
end |
end |
## (name, direction, length, is_last) |
#yield( port_name.to_s, |
#port_dir ^ ifc.dir, |
#port_def.len, |
#port_default, |
#( (i_port == ifc.ports.size-1 ) and (i_ifc == @interfaces.size-1 ) ) ) |
#end |
#end |
|
# elsif args.size == 1 |
## elsif args.size == 1 |
|
# # get interface (input is the name as string ) |
# ifc = @interfaces[ args.first.to_sym ] |
## # get interface (input is the name as string ) |
## ifc = @interfaces[ args.first.to_sym ] |
|
# ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
# ifc.ports.each do |port_name, port_def; port_dir| |
# port_def = port_def.defn |
# port_dir = ifc_def.ports[ port_def.to_sym ] |
# if port_dir == nil |
# perr_if( port_dir==nil, |
# "Can't find #{port_def} in" + |
# "interface definition #{ifc_def.name} " + |
# "version #{ifc_def.version}" ) |
# end |
# yield( port_def.to_s, |
# port_name.to_s, |
# port_dir ^ ifc.dir ) |
# end |
## ifc_def = SOCMaker::lib.get_ifc( ifc.name, ifc.version ) |
## ifc.ports.each do |port_name, port_def; port_dir| |
## port_def = port_def.defn |
## port_dir = ifc_def.ports[ port_def.to_sym ] |
## if port_dir == nil |
## perr_if( port_dir==nil, |
## "Can't find #{port_def} in" + |
## "interface definition #{ifc_def.name} " + |
## "version #{ifc_def.version}" ) |
## end |
## yield( port_def.to_s, |
## port_name.to_s, |
## port_dir ^ ifc.dir ) |
## end |
|
else |
#else |
|
end |
#end |
|
end |
#end |
|
|
# this is a core_def and doesn't have |
194,7 → 205,7
end |
|
def consistency_check |
|
super |
end |
|
|
/ifc_spc.rb
82,12 → 82,27
field: "name" ) |
|
@ports = coder[ 'ports' ] || {} |
@ports.each do |pname, port_dir| |
verr_if( !port_dir.is_a?( Fixnum ) || |
( port_dir != 0 && port_dir != 1 ), |
"Port direction value is neither 0 nor 1", |
@ports.each do |pname, port| |
|
verr_if( !port.is_a?( Hash ), |
"Port field must be organized as a hash", |
instance: @name, |
field: "ports" ) |
|
verr_if( !port.has_key?( :dir ), |
"No port direction specified for #{pname}", |
instance: @name, |
field: "ports" ) |
field: "ports" ) |
|
verr_if( !port[ :dir ].is_a?( Fixnum ) || |
( port[ :dir ] != 0 && port[ :dir ] != 1 ), |
"Port direction value for #{pname} is neither 0 nor 1", |
instance: @name, |
field: "ports" ) |
|
port[ :mandatory ] = true if !port.has_key?( :mandatory ) |
port[ :default ] ||= '0' |
|
end |
|
end |