Line 93... |
Line 93... |
yield( name.to_s, type, value, is_last )
|
yield( name.to_s, type, value, is_last )
|
end
|
end
|
end
|
end
|
|
|
|
|
def get_len( ifc_name, port_spec_name )
|
|
|
|
# get the port name, which we are using
|
def get_len( ifc_name, port_spec_name, inst = nil )
|
|
|
|
if inst == nil
|
tmp = @defn.interfaces[ ifc_name.to_sym ].
|
tmp = @defn.interfaces[ ifc_name.to_sym ].
|
ports.select{ |key,hash| hash.defn == port_spec_name.to_s }.
|
ports.select{ |key,hash| hash.defn == port_spec_name.to_s }.
|
keys.first.to_s
|
keys.first.to_s
|
|
|
return tmp.size == 0 ? 0 : @ports[ tmp.to_sym ][ :len ]
|
return tmp.size == 0 ? 0 : @ports[ tmp.to_sym ][ :len ]
|
|
else
|
|
if inst == @name
|
|
return get_len( ifc_name, port_spec_name )
|
|
else
|
|
return @defn.get_len( ifc_name, port_spec_name, inst )
|
|
end
|
end
|
end
|
|
end
|
|
|
|
|
|
|
|
|
def implements_port?( ifc_name, port_spec_name )
|
def implements_port?( ifc_name, port_spec_name )
|
@defn.implements_port?( ifc_name, port_spec_name )
|
@defn.implements_port?( ifc_name, port_spec_name )
|
end
|
end
|
Line 189... |
Line 198... |
field: 'cores' )
|
field: 'cores' )
|
|
|
end
|
end
|
|
|
|
|
|
|
|
def get_core_def( inst )
|
|
tmp = @defn.get_core_def( inst )
|
|
if tmp != nil
|
|
return tmp
|
|
elsif inst == @name
|
|
return self
|
|
else
|
|
return nil
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def gen_toplevel( coder = VHDLCoder.new() )
|
|
|
|
|
|
#
|
|
# create filename
|
|
#
|
|
file_name = @defn.name.dup
|
|
if coder.is_a?( VHDLCoder )
|
|
file_name << ".vhd"
|
|
elsif coder.is_a?( VerilogCoder )
|
|
file_name << ".v"
|
|
else
|
|
perr_if( true,
|
|
"No valid coder" )
|
|
end
|
|
|
|
|
|
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 every core to your implementation.
|
|
# Even if there are multiple instances of a core,
|
|
# we need to decalre it only once
|
|
#
|
|
@defn.cores.values.uniq{|x| x.type }.each do |inst; spec|
|
|
|
|
spec = SOCMaker::lib.get_core( inst.type )
|
|
SOCMaker::lib.check_nil( spec, "Can't find #{ inst.type } in SOC library" )
|
|
|
|
coder.add_core_declaration( inst.type, spec )
|
|
end
|
|
|
|
#core_instances = {}
|
|
#@cores.each do |inst_name, _core_inst|
|
|
# # the corresponding core from SOC lib
|
|
# core_def = SOCMaker::lib.get_core( _core_inst[ :type ] )
|
|
# core_instances[ inst_name ] = SOCMaker::CoreInst.new( core_def, _core_inst[ :params ] )
|
|
#end
|
|
|
|
|
|
@defn.cores.each do |inst_name, inst|
|
|
coder.add_core_inst( inst_name.to_s, inst )
|
|
end
|
|
|
|
|
|
|
|
# Iterate over all connections:
|
|
# - create signal instances
|
|
# - add assignments
|
|
#
|
|
@defn.cons.each do |con_name, con_def|
|
|
gen_toplevel_con( con_name.to_s,
|
|
con_def[ :rule ],
|
|
con_def[ :mapping ][0],
|
|
con_def[ :mapping ][1],
|
|
coder )
|
|
|
|
end
|
|
|
|
SOCMaker::logger.proc( "writing top-level" )
|
|
|
|
file_dir = File.join( SOCMaker::conf[ :build_dir ],
|
|
SOCMaker::conf[ :hdl_dir ] )
|
|
::FileUtils.mkdir_p file_dir
|
|
file_path = File.join( file_dir, file_name )
|
|
File.open( file_path, 'w' ) do |f|
|
|
f.write( coder.get_entity( self, "test" ) )
|
|
end
|
|
SOCMaker::logger.proc( "END of creating top-level" )
|
|
|
|
end
|
|
|
|
|
|
def gen_toplevel_con( name, rule, src, dst, coder )
|
|
|
|
src_inst = {};
|
|
dst_inst = {};
|
|
|
|
# fetch somehow the spec
|
|
ifc_spec = SOCMaker::lib.get_ifc(
|
|
get_core_def( src.keys.first.to_s ).interfaces[ src.values.first ].name,
|
|
get_core_def( src.keys.first.to_s ).interfaces[ src.values.first ].version )
|
|
|
|
#port_used = {};
|
|
length_tmp = {};
|
|
|
|
|
|
ifc_spec.ports.keys.each do |_name|
|
|
# TODO: bis dahin konnte angenommen werden, dass self auch eine Art instanz ist,
|
|
# aber hier geht das nicht mehr, weil get_len nur für CoreInst definiert ist.
|
|
#
|
|
|
|
|
|
# create a length table
|
|
#port_used[ _name ] = false
|
|
#dst.each do |inst_name, ifc_name|
|
|
# port_used[ _name ] ||= get_core_def( inst_name ).implements_port?( ifc_name, _name )
|
|
#end
|
|
#src.each do |inst_name, ifc_name|
|
|
# port_used[ _name ] ||= get_core_def( inst_name ).implements_port?( ifc_name, _name )
|
|
#end
|
|
|
|
|
|
|
|
length_tmp[ _name ] = []
|
|
dst.each do |inst_name, ifc_name|
|
|
length_tmp[ _name ] << get_len( ifc_name, _name, inst_name )
|
|
end
|
|
src.each do |inst_name, ifc_name|
|
|
length_tmp[ _name ] << get_len( ifc_name, _name, inst_name )
|
|
end
|
|
|
|
end
|
|
|
|
# getting the maximum length for each signal
|
|
max_length = Hash[ length_tmp.map{ |key, arr| [ key, arr.max ] } ]
|
|
|
|
|
|
p max_length
|
|
coder.ifc_declaration( ifc_spec, name, max_length )
|
|
|
|
src.keys.each do |inst_name|
|
|
src_inst[ inst_name ] = @defn.cores[ inst_name ]
|
|
end
|
|
dst.keys.each do |inst_name|
|
|
dst_inst[ inst_name ] = @defn.cores[ inst_name ]
|
|
end
|
|
|
|
coder.ifc_assignment( ifc_spec, name, max_length, src_inst, dst_inst, src, dst )
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def to_s
|
def to_s
|
"type: #{type}\n" +
|
"type: #{type}\n" +
|
"params: #{params}\n"
|
"params: #{params}\n"
|
end
|
end
|
|
|