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)
|
inputs_changed(vals)
|
||||||
end
|
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.
|
# @abstract Override this to implement a gate.
|
||||||
# @param vals [Array<Integer>] List of values for connected ports.
|
# @param vals [Array<Integer>] List of values for connected ports.
|
||||||
def inputs_changed(vals); raise NotImplementedError; end
|
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 "../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
|
describe Gate do
|
||||||
let(:klass) do
|
let(:klass) do
|
||||||
Class.new(Gate) do
|
Class.new(Gate) do
|
||||||
@ -31,4 +34,54 @@ describe Gate do
|
|||||||
b.setval(10)
|
b.setval(10)
|
||||||
expect(gate.out.val).to eq(18)
|
expect(gate.out.val).to eq(18)
|
||||||
end
|
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
|
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