rcircuit/gate.rb
2018-07-09 14:56:30 -05:00

48 lines
1.2 KiB
Ruby

require_relative "port.rb"
# @abstract Subclass and override {#inputs_changed} to implement a gate
## Base class for gates
class Gate
# @!attribute [r] out
# @return [Port] the output port of the gate
attr_reader :out
# @param args [Array<Port>] These are the ports to be added to the gate.
# @note The first argument determines the width of the gate.
def initialize(*args)
@inputs=[]
@width=args[0].width
@out=Port.new(@width)
args.each do |input|
add_input(input)
end
end
# Add a port to the gate.
# @param port [Port] The port to be added. It must match the width of the gate.
# @return [void]
def add_input(port)
if port.width != @width then
raise ArgumentError, "Incorrect width #{port.width}, expected #{@width}"
end
@inputs.push(port)
port.add_callback do |value|
vals=[]
@inputs.each do |port|
vals.push port.val
end
inputs_changed(vals)
end
vals=[]
@inputs.each do |port|
vals.push port.val
end
inputs_changed(vals)
end
# @abstract Override this to implement a gate.
# @param vals [Array<Integer>] List of values for connected ports.
def inputs_changed(vals); raise NotImplementedError; end
end