Add gates
This commit is contained in:
parent
c0b1776d20
commit
1760655308
21
and.rb
Normal file
21
and.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require_relative "gate.rb"
|
||||
require_relative "port.rb"
|
||||
|
||||
# Represents an AND gate
|
||||
class AndGate < Gate
|
||||
|
||||
# Called when inputs change.
|
||||
# Calculates AND of all inputs and sets output port to that value.
|
||||
# @param vals [Array<Integer>] List of values for connected ports.
|
||||
def inputs_changed(vals)
|
||||
andval=nil
|
||||
vals.each do |val|
|
||||
if andval==nil
|
||||
andval=val
|
||||
else
|
||||
andval=andval&val
|
||||
end
|
||||
end
|
||||
out.setval(andval)
|
||||
end
|
||||
end
|
22
gate.rb
22
gate.rb
@ -41,6 +41,28 @@ class Gate
|
||||
inputs_changed(vals)
|
||||
end
|
||||
|
||||
# Test a truth table for a gate.
|
||||
# @param table [Array<Array<Integer>>] The truth table,
|
||||
# which is an array of entries. The last value in the entry is the expected output,
|
||||
# the rest are the inputs to the ports.
|
||||
def self.test_table(table)
|
||||
ports=[]
|
||||
(table[0].length-1).times do
|
||||
ports.push Port.new(1)
|
||||
end
|
||||
gate=self.new(*ports)
|
||||
table.each do |entry|
|
||||
i=0
|
||||
ports.each do |port|
|
||||
port.setval(entry[i])
|
||||
i+=1
|
||||
end
|
||||
return false if gate.out!=entry.last
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
# Called when inputs change.
|
||||
# @abstract Override this to implement a gate.
|
||||
# @param vals [Array<Integer>] List of values for connected ports.
|
||||
def inputs_changed(vals); raise NotImplementedError; end
|
||||
|
30
not.rb
Normal file
30
not.rb
Normal file
@ -0,0 +1,30 @@
|
||||
require_relative "gate.rb"
|
||||
require_relative "port.rb"
|
||||
|
||||
# Represents a NOT gate
|
||||
class NotGate < Gate
|
||||
|
||||
# (see Gate#initialize)
|
||||
def initialize(*args)
|
||||
@outmask=0
|
||||
super
|
||||
@outmask=(2**@width)-1
|
||||
end
|
||||
|
||||
# Add a port to the gate. As this is a NOT gate, there may only be one port.
|
||||
# @param (see Gate#add_input)
|
||||
# @return [void]
|
||||
def add_input(input_port)
|
||||
if @inputs.length > 0 then
|
||||
raise ArgumentError, "Cannot add multiple inputs to a NOT gate"
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
# Called when inputs change.
|
||||
# Calculates NOT of input and sets output port to that value.
|
||||
# @param vals [Array<Integer>] List of values for connected ports.
|
||||
def inputs_changed(vals)
|
||||
out.setval((~vals[0]) & @outmask)
|
||||
end
|
||||
end
|
20
or.rb
Normal file
20
or.rb
Normal file
@ -0,0 +1,20 @@
|
||||
require_relative "gate.rb"
|
||||
require_relative "port.rb"
|
||||
|
||||
# Represents an OR gate
|
||||
class OrGate < Gate
|
||||
|
||||
# Called when inputs change.
|
||||
# Calculates OR of all inputs and sets output port to that value.
|
||||
def inputs_changed(vals)
|
||||
orval=nil
|
||||
vals.each do |val|
|
||||
if orval==nil
|
||||
orval=val
|
||||
else
|
||||
orval=orval|val
|
||||
end
|
||||
end
|
||||
out.setval(orval)
|
||||
end
|
||||
end
|
@ -1,6 +1,9 @@
|
||||
require_relative "../gate.rb"
|
||||
require_relative "../port.rb"
|
||||
|
||||
require_relative "../gate.rb"
|
||||
require_relative "../not.rb"
|
||||
require_relative "../and.rb"
|
||||
require_relative "../or.rb"
|
||||
require_relative "../xor.rb"
|
||||
describe Gate do
|
||||
let(:klass) do
|
||||
Class.new(Gate) do
|
||||
@ -31,4 +34,54 @@ describe Gate do
|
||||
b.setval(10)
|
||||
expect(gate.out.val).to eq(18)
|
||||
end
|
||||
|
||||
context "NotGate" do
|
||||
it "should NOT the input" do
|
||||
table=[
|
||||
[0,1],
|
||||
[1,0]
|
||||
]
|
||||
ok=NotGate.test_table(table)
|
||||
expect(ok).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context "AndGate" do
|
||||
it "should AND together all inputs" do
|
||||
table=[
|
||||
[0,0,0],
|
||||
[0,1,0],
|
||||
[1,0,0],
|
||||
[1,1,1],
|
||||
]
|
||||
ok=AndGate.test_table(table)
|
||||
expect(ok).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context "OrGate" do
|
||||
it "should OR together all inputs" do
|
||||
table=[
|
||||
[0,0,0],
|
||||
[0,1,1],
|
||||
[1,0,1],
|
||||
[1,1,1],
|
||||
]
|
||||
ok=OrGate.test_table(table)
|
||||
expect(ok).to eq true
|
||||
end
|
||||
end
|
||||
|
||||
context "XorGate" do
|
||||
it "should XOR together all inputs" do
|
||||
table=[
|
||||
[0,0,0],
|
||||
[0,1,1],
|
||||
[1,0,1],
|
||||
[1,1,0],
|
||||
]
|
||||
ok=XorGate.test_table(table)
|
||||
expect(ok).to eq true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
20
xor.rb
Normal file
20
xor.rb
Normal file
@ -0,0 +1,20 @@
|
||||
require_relative "gate.rb"
|
||||
require_relative "port.rb"
|
||||
|
||||
# Represents an XOR gate
|
||||
class XorGate < Gate
|
||||
|
||||
# Called when inputs change.
|
||||
# Calculates XOR of all inputs and sets output port to that value.
|
||||
def inputs_changed(vals)
|
||||
xorval=nil
|
||||
vals.each do |val|
|
||||
if xorval==nil
|
||||
xorval=val
|
||||
else
|
||||
xorval=xorval^val
|
||||
end
|
||||
end
|
||||
out.setval(xorval)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user