class HDLRuby::High::Std::ChannelI
Describes a high-level channel instance.
Attributes
The name of the channel instance.
The namespace associated with the current execution when building a channel.
The read port if any.
The scope the channel has been created in.
The write port if any.
Public Class Methods
Creates a new channel instance with name
built from ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 432 def initialize(name,&ruby_block) # Check and set the name of the channel. @name = name.to_sym # puts "my name is #{self.name}" # Generate a name for the scope containing the signals of # the channel. # @scope_name = HDLRuby.uniq_name @scope_name = HDLRuby.uniq_name(name) # # Sets the scope. # @scope = HDLRuby::High.cur_scope # Keep access to self. obj = self # At first there no read nor write port. @read_port = nil @write_port = nil # The reader input ports by name. @reader_inputs = {} # The reader output ports by name. @reader_outputs = {} # The reader inout ports by name. @reader_inouts = {} # The writer input ports by name. @writer_inputs = {} # The writer output ports by name. @writer_outputs = {} # The writer inout ports by name. @writer_inouts = {} # The accesser input ports by name. @accesser_inputs = {} # The accesser output ports by name. @accesser_outputs = {} # The accesser inout ports by name. @accesser_inouts = {} # The branch channels @branches = {} # Create the namespaces for building the channel, its readers # its writers and its accessers. # Creates the namespace of the channel. @namespace = Namespace.new(self) # Make it give access to the internal of the class. @namespace.add_method(:reader_input, &method(:reader_input)) @namespace.add_method(:reader_output, &method(:reader_output)) @namespace.add_method(:reader_inout, &method(:reader_inout)) @namespace.add_method(:writer_input, &method(:writer_input)) @namespace.add_method(:writer_output, &method(:writer_output)) @namespace.add_method(:writer_inout, &method(:writer_inout)) @namespace.add_method(:accesser_input, &method(:accesser_input)) @namespace.add_method(:accesser_output,&method(:accesser_output)) @namespace.add_method(:accesser_inout, &method(:accesser_inout)) @namespace.add_method(:reader, &method(:reader)) @namespace.add_method(:writer, &method(:writer)) @namespace.add_method(:brancher, &method(:brancher)) # Creates the namespace of the reader. @reader_namespace = Namespace.new(self) # Creates the namespace of the writer. @writer_namespace = Namespace.new(self) # Creates the namespace of the accesser. @accesser_namespace = Namespace.new(self) # Builds the channel within a new scope. HDLRuby::High.space_push(@namespace) # puts "top_user=#{HDLRuby::High.top_user}" scope_name = @scope_name scope = nil HDLRuby::High.top_user.instance_eval do sub(scope_name) do # Generate the channel code. ruby_block.call end end HDLRuby::High.space_pop # Keep access to the scope containing the code of the channel. @scope = @namespace.send(scope_name) # puts "@scope=#{@scope}" # Adds the name space of the scope to the namespace of the # channel @namespace.concat_namespace(@scope.namespace) # Gives access to the channel by registering its name. obj = self # HDLRuby::High.space_reg(@name) { self } HDLRuby::High.space_reg(@name) { obj } end
Public Instance Methods
Sets the signals accessible through key
to be accesser inout port.
# File lib/HDLRuby/std/channel.rb, line 652 def accesser_inout(*keys) # Registers each signal as accesser port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @accesser_inouts[name] = send(key) end end
Sets the signals accessible through key
to be accesser input port.
# File lib/HDLRuby/std/channel.rb, line 628 def accesser_input(*keys) # Registers each signal as accesser port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @accesser_inputs[name] = send(key) end end
Sets the signals accessible through key
to be accesser output port.
# File lib/HDLRuby/std/channel.rb, line 640 def accesser_output(*keys) # Registers each signal as accesser port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @accesser_outputs[name] = send(key) end end
Gets branch channel name
. NOTE: name
can be of any type on purpose.
# File lib/HDLRuby/std/channel.rb, line 744 def branch(name,*args) # Ensure name is a symbol. name = name.to_s unless name.respond_to?(:to_sym) name = name.to_sym # Get the branch. channelI = @branches[name] return @branches[name] end
Defines a branch in the channel named name
built executing ruby_block
. Alternatively, a ready channel instance can be passed as argument as channelI
.
# File lib/HDLRuby/std/channel.rb, line 721 def brancher(name,channelI = nil,&ruby_block) # puts "self.name=#{self.name} and name=#{name}" # Ensure name is a symbol. name = name.to_s unless name.respond_to?(:to_sym) name = name.to_sym # Is there a ready channel instance. if channelI then # Yes, use it directly. @branches[name] = channelI return self end # Now, create the branch. channelI = HDLRuby::High::Std.channel_instance(name, &ruby_block) # channelI = HDLRuby::High::Std.channel_instance("#{self.name}::#{name}", &ruby_block) @branches[name] = channelI return self end
Declares the accesser port and assigned them to name
.
# File lib/HDLRuby/std/channel.rb, line 981 def inout(name = nil) # Ensure name is a symbol. name = HDLRuby.uniq_name unless name name = name.to_sym # Ensure the port is not already existing. if @read_port then raise "Read port already declared for channel instance: " + self.name.to_s end if @write_port then raise "Write port already declared for channel instance: " + self.name.to_s end # Access the ports loc_inputs = @accesser_inputs.merge(@reader_inputs). merge(@writer_inputs) loc_outputs = @accesser_outputs.merge(@reader_outputs). merge(@writer_outputs) loc_inouts = @accesser_inouts.merge(@reader_inouts). merge(@writer_inouts) locs = loc_inputs.merge(loc_outputs).merge(loc_inouts) # The generated port with corresponding channel port pairs. port_pairs = [] if HDLRuby::High.cur_system == self.parent_system then # Port in same system as the channel case. # Add them to the current system. HDLRuby::High.cur_system.open do locs.each do |name,sig| port_pairs << [sig, sig.type.inner(name)] end end obj = self # Make the inner connection port_pairs.each do |sig, port| sig.parent.open do port.to_ref <= sig end end else # Port in different system as the channel case. # Add them to the current system. HDLRuby::High.cur_system.open do # The inputs loc_inputs.each do |name,sig| # puts "name=#{name} sig.name=#{sig.name}" port_pairs << [sig, sig.type.input(name)] end # The outputs loc_outputs.each do |name,sig| port_pairs << [sig, sig.type.output(name)] end # The inouts loc_inouts.each do |name,sig| port_pairs << [sig, sig.type.inout(name)] end end obj = self # Make the connection of the instance. HDLRuby::High.cur_system.on_instance do |inst| obj.scope.open do port_pairs.each do |sig, port| RefObject.new(inst,port.to_ref) <= sig end end end end # Fill the reader namespace with the access to the reader signals. loc_inputs.each do |name,sig| @accesser_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_outputs.each do |name,sig| @accesser_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_inouts.each do |name,sig| @accesser_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end # Give access to the ports through name. # NOTE: for now, simply associate the channel to name. chp = ChannelPortA.new(@accesser_namespace,@reader_proc,@writer_proc,@inout_reseter_proc) HDLRuby::High.space_reg(name) { chp } # Save the port in the channe to avoid conflicting declaration. @read_port = chp @write_port = chp return chp end
Tells if the channel support inout port.
# File lib/HDLRuby/std/channel.rb, line 712 def inout? return @accesser_inputs.any? || @accesser_outputs.any? || @accesser_inouts.any? end
Sets the inout port reset to be ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 690 def inout_reseter(&ruby_block) @inout_reseter_proc = ruby_block end
Declares the reader port as and assigned them to name
.
# File lib/HDLRuby/std/channel.rb, line 757 def input(name = nil) # Ensure name is a symbol. name = HDLRuby.uniq_name unless name name = name.to_sym # Ensure the port is not already existing. if @read_port then raise "Read port already declared for channel instance: " + self.name end # Access the ports # loc_inputs = @reader_inputs # loc_outputs = @reader_outputs # loc_inouts = @reader_inouts loc_inputs = @reader_inputs.merge(@accesser_inputs) loc_outputs = @reader_outputs.merge(@accesser_outputs) loc_inouts = @reader_inouts.merge(@accesser_inouts) locs = loc_inputs.merge(loc_outputs).merge(loc_inouts) # The generated port with corresponding channel port pairs. port_pairs = [] if HDLRuby::High.cur_system == self.parent_system then # Port in same system as the channel case. # Add them to the current system. HDLRuby::High.cur_system.open do # locs.each do |name,sig| # port_pairs << [sig, sig.type.inner(name)] # end loc_inputs.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:input] end loc_outputs.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:output] end loc_inouts.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:inout] end end obj = self # Make the inner connection # port_pairs.each do |sig, port| port_pairs.each do |sig, port, dir| sig.parent.open do # port.to_ref <= sig if dir == :input then port.to_ref <= sig else sig <= port.to_ref end end end else # Port in different system as the channel case. # Add them to the current system. HDLRuby::High.cur_system.open do # The inputs loc_inputs.each do |name,sig| # puts "name=#{name} sig.name=#{sig.name}" port_pairs << [sig, sig.type.input(name),:input] end # The outputs loc_outputs.each do |name,sig| port_pairs << [sig, sig.type.output(name),:output] end # The inouts loc_inouts.each do |name,sig| port_pairs << [sig, sig.type.inout(name),:inout] end end obj = self # Make the connection of the instance. HDLRuby::High.cur_system.on_instance do |inst| obj.scope.open do port_pairs.each do |sig, port, dir| # RefObject.new(inst,port.to_ref) <= sig if dir == :input then RefObject.new(inst,port.to_ref) <= sig else sig <= RefObject.new(inst,port.to_ref) end end end end end # Fill the reader namespace with the access to the reader signals. loc_inputs.each do |name,sig| @reader_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_outputs.each do |name,sig| @reader_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_inouts.each do |name,sig| @reader_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end # Give access to the ports through name. # NOTE: for now, simply associate the channel to name. chp = ChannelPortR.new(@reader_namespace,@reader_proc,@input_reseter_proc) HDLRuby::High.space_reg(name) { chp } # Save the port in the channe to avoid conflicting declaration. @read_port = chp return chp end
Sets the input port reset to be ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 680 def input_reseter(&ruby_block) @input_reseter_proc = ruby_block end
Declares the ports for the writer and assigned them to name
.
# File lib/HDLRuby/std/channel.rb, line 868 def output(name = nil) # Ensure name is a symbol. name = HDLRuby.uniq_name unless name name = name.to_sym # Ensure the port is not already existing. if @write_port then raise "Write port already declared for channel instance: " + self.name end # Access the ports # loc_inputs = @writer_inputs # loc_outputs = @writer_outputs # loc_inouts = @writer_inouts loc_inputs = @writer_inputs.merge(@accesser_inputs) loc_outputs = @writer_outputs.merge(@accesser_outputs) loc_inouts = @writer_inouts.merge(@accesser_inouts) locs = loc_inputs.merge(loc_outputs).merge(loc_inouts) # The generated port with corresponding channel port pairs. port_pairs = [] # puts "cur_system=#{HDLRuby::High.cur_system} self.parent_system=#{self.parent_system}" if HDLRuby::High.cur_system == self.parent_system then # puts "Inner found!" # Port in same system as the channel case. # Add them to the current system. HDLRuby::High.cur_system.open do # locs.each do |name,sig| # port_pairs << [sig, sig.type.inner(name)] # end loc_inputs.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:input] end loc_outputs.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:output] end loc_inouts.each do |name,sig| port_pairs << [sig, sig.type.inner(name),:inout] end end obj = self # Make the inner connection # port_pairs.each do |sig, port| port_pairs.each do |sig, port, dir| sig.parent.open do # port.to_ref <= sig if dir == :input then port.to_ref <= sig else sig <= port.to_ref end end end else # Portds in different system as the channel's case. # Add them to the current system. HDLRuby::High.cur_system.open do # The inputs loc_inputs.each do |name,sig| port_pairs << [sig, sig.type.input(name),:input] end # The outputs loc_outputs.each do |name,sig| port_pairs << [sig, sig.type.output(name),:output] end # The inouts loc_inouts.each do |name,sig| port_pairs << [sig, sig.type.inout(name),:inout] end end obj = self # Make the connection of the instance. HDLRuby::High.cur_system.on_instance do |inst| obj.scope.open do port_pairs.each do |sig, port, dir| # RefObject.new(inst,port.to_ref) <= sig # RefObject.new(inst,port.to_ref) <= sig if dir == :input then RefObject.new(inst,port.to_ref) <= sig else sig <= RefObject.new(inst,port.to_ref) end end end end end # Fill the writer namespace with the access to the writer signals. loc_inputs.each do |name,sig| @writer_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_outputs.each do |name,sig| @writer_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end loc_inouts.each do |name,sig| @writer_namespace.add_method(sig.name) do HDLRuby::High.top_user.send(name) end end # Give access to the ports through name. # NOTE: for now, simply associate the channel to name. chp = ChannelPortW.new(@writer_namespace,@writer_proc,@output_reseter_proc) HDLRuby::High.space_reg(name) { chp } # Save the port in the channe to avoid conflicting declaration. @write_port = chp return chp end
Sets the output port reset to be ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 685 def output_reseter(&ruby_block) @output_reseter_proc = ruby_block end
Get the parent system.
# File lib/HDLRuby/std/channel.rb, line 528 def parent_system return self.scope.parent_system end
Sets the read procedure to be ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 665 def reader(&ruby_block) @reader_proc = ruby_block end
Sets the signals accessible through key
to be reader inout port.
# File lib/HDLRuby/std/channel.rb, line 580 def reader_inout(*keys) # Registers each signal as reader port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @reader_inouts[name] = send(key) end end
Sets the signals accessible through key
to be reader input port.
# File lib/HDLRuby/std/channel.rb, line 556 def reader_input(*keys) # Registers each signal as reader port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @reader_inputs[name] = send(key) end end
Sets the signals accessible through key
to be reader output port.
# File lib/HDLRuby/std/channel.rb, line 568 def reader_output(*keys) # Registers each signal as reader port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @reader_outputs[name] = send(key) end end
Gets the list of the signals of the channel to be connected to the reader.
# File lib/HDLRuby/std/channel.rb, line 699 def reader_signals return @reader_inputs.values + @reader_outputs.values + @reader_inouts.values end
Sets the writer procedure to be ruby_block
.
# File lib/HDLRuby/std/channel.rb, line 670 def writer(&ruby_block) @writer_proc = ruby_block end
Sets the signals accessible through key
to be writer inout port.
# File lib/HDLRuby/std/channel.rb, line 616 def writer_inout(*keys) # Registers each signal as writer port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @writer_inouts[name] = send(key) end end
Sets the signals accessible through key
to be writer input port.
# File lib/HDLRuby/std/channel.rb, line 592 def writer_input(*keys) # Registers each signal as writer port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @writer_inputs[name] = send(key) end end
Sets the signals accessible through key
to be writer output port.
# File lib/HDLRuby/std/channel.rb, line 604 def writer_output(*keys) # Registers each signal as writer port keys.each do |key| # Ensure the key is a symbol. key = key.to_sym # Register it with the corresponding signal. name = HDLRuby.uniq_name # The name of the signal is uniq. @writer_outputs[name] = send(key) end end
Gets the list of the signals of the channel to be connected to the writer.
# File lib/HDLRuby/std/channel.rb, line 706 def writer_signals return @writer_inputs.values + @writer_outputs.values + @writer_inouts.values end