Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ハードウェアシミュレータ6/17
HLHASH = {true=>"H", false=>"L", nil=>"nil"}
H = true
L = false
QUEUE = []
# 出力ピン
class OutputPin
attr_accessor :output_objects
def initialize(v=nil)
@value = v
@output_objects = []
end
# 出力をセットする
def set(v)
tmp = @value
@value = v
# 出力が変わったら通知先をキューに格納する
if tmp != v
@output_objects.each do |i|
QUEUE.push i
end
end
self
end
# 出力の取得
def get
@value
end
# &演算子
def &(dst)
tmp = AND.new
tmp.a = self
tmp.b = dst
tmp.o
end
# |演算子
def |(dst)
tmp = OR.new
tmp.a = self
tmp.b = dst
tmp.o
end
# ~演算子
def ~
tmp = NOT.new
tmp.a = self
tmp.o
end
# ^演算子
def ^(dst)
tmp = XOR.new
tmp.a = self
tmp.b = dst
tmp.o
end
end
# 外部からの入力用配線
class Line
attr_accessor :output_objects
def initialize
@o = OutputPin.new
@output_objects = []
end
def d=(v)
@d = OutputPin.new(v)
QUEUE.push(self)
# キューが無くなるまでシミュレーション実行
while QUEUE.size > 0
QUEUE.shift.update
end
end
def o
@o
end
def update
@o.set(@d.get)
end
end
class Bus1
def initialize
@o = OutputPin.new
end
def o
@o
end
def add(v)
v.connect_bus(self)
end
end
class Bus
def initialize(bit_width)
@bus = Array.new(bit_width){Bus1.new}
end
def o
@bus.map{|b|b.o}
end
def add(v)
v.connect_bus(@bus)
end
def bus
@bus
end
end
class ThreeStateBuffer1
def d=(v)
v.output_objects << self
@d = v
end
def g=(v)
v.output_objects << self
@g = v
end
def update
@bus.o.set(@d.get) if @g and @g.get
end
def connect_bus(b)
@bus = b
end
end
class ThreeStateBuffer
def initialize(bit_width)
@tsb = Array.new(bit_width){ThreeStateBuffer1.new}
end
def d=(v)
@tsb.zip(v) do |tsb, o|
tsb.d = o
end
end
def g=(v)
@tsb.each do |tsb|
tsb.g = v
end
end
def connect_bus(b)
@tsb.zip(b).each do |t, bus|
t.connect_bus bus
end
end
end
class ThreeStateBufferB1
def d=(v)
v.output_objects << self
@d = v
end
def g=(v)
v.output_objects << self
@g = v
end
def update
@bus.o.set(@d.get) if @g and !@g.get
end
def connect_bus(b)
@bus = b
end
end
class ThreeStateBufferB
def initialize(bit_width)
@tsb = Array.new(bit_width){ThreeStateBufferB1.new}
end
def d=(v)
@tsb.zip(v) do |tsb, o|
tsb.d = o
end
end
def g=(v)
@tsb.each do |tsb|
tsb.g = v
end
end
end
# NANDゲート試作
class NAND
def initialize
@o = OutputPin.new
@a = @b = OutputPin.new
end
def a=(v)
v.output_objects << self
@a = v
end
def b=(v)
v.output_objects << self
@b = v
end
def o
@o
end
def update
if @a.get != nil or @b.get != nil
@o.set(!(@a.get and @b.get))
end
end
def inspect
"#{HLHASH[o.get]}"
end
end
# NOTゲート試作
class NOT
def initialize
@nand = NAND.new
end
def a=(v)
@nand.a = v
@nand.b = v
end
def o
@nand.o
end
def inspect
"#{HLHASH[o.get]}"
end
end
class AND
def initialize
@nand = NAND.new
@not = NOT.new
@not.a = @nand.o
end
def a=(v)
@nand.a = v
end
def b=(v)
@nand.b = v
end
def o
@not.o
end
def inspect
"#{HLHASH[o.get]}"
end
end
class OR
def initialize
@nand = NAND.new
@not1 = NOT.new
@not2 = NOT.new
@nand.a = @not1.o
@nand.b = @not2.o
end
def a=(v)
@not1.a = v
end
def b=(v)
@not2.a = v
end
def o
@nand.o
end
def inspect
"#{HLHASH[o.get]}"
end
end
class XOR
def initialize
@and1 = AND.new
@and2 = AND.new
@not1 = NOT.new
@not2 = NOT.new
@or = OR.new
@and1.a = @not1.o
@and2.b = @not2.o
@or.a = @and1.o
@or.b = @and2.o
end
def a=(v)
@not1.a = v
@and2.a = v
end
def b=(v)
@not2.a = v
@and1.b = v
end
def o
@or.o
end
def inspect
"#{HLHASH[o.get]}"
end
end
class HarfAdder
def initialize
@and = AND.new
@xor = XOR.new
end
def a=(v)
@and.a = v
@xor.a = v
end
def b=(v)
@and.b = v
@xor.b = v
end
def s
@xor.o
end
def c
@and.o
end
def inspect
"#{HLHASH[c.get]}#{HLHASH[s.get]}"
end
end
class FullAdder
def initialize
@hadr1 = HarfAdder.new
@hadr2 = HarfAdder.new
@or = OR.new
@hadr2.a = @hadr1.s
@or.a = @hadr1.c
@or.b = @hadr2.c
end
def a=(v)
@hadr1.a = v
end
def b=(v)
@hadr1.b = v
end
def x=(v)
@hadr2.b = v
end
def s
@hadr2.s
end
def c
@or.o
end
def inspect
"#{HLHASH[c.get]}#{HLHASH[s.get]}"
end
end
class RSFF
def initialize
@not1 = NOT.new
@not2 = NOT.new
@nand1 = NAND.new
@nand2 = NAND.new
@nand1.a = @not1.o
@nand1.b = @nand2.o
@nand2.a = @not2.o
@nand2.b = @nand1.o
end
def s=(v)
@not1.a = v
end
def r=(v)
@not2.a = v
end
def q
@nand1.o
end
def qb
@nand2.o
end
def inspect
"q=#{HLHASH[q.get]}, qb=#{HLHASH[qb.get]}"
end
end
class DFF1
def initialize
@not1 = NOT.new
@not2 = NOT.new
@nand1 = NAND.new
@nand2 = NAND.new
@nand3 = NAND.new
@nand4 = NAND.new
@nand5 = NAND.new
@nand6 = NAND.new
@nand7 = NAND.new
@nand8 = NAND.new
@reset1_and = AND.new
@reset1_not = NOT.new
@reset1_nand = NAND.new
@reset1_and.a = @nand2.o
@reset1_not.a = @nand1.o
@reset1_nand.a = @reset1_not.o
@reset2_and = AND.new
@reset2_not = NOT.new
@reset2_nand = NAND.new
@reset2_and.a = @nand6.o
@reset2_not.a = @nand5.o
@reset2_nand.a = @reset2_not.o
@not2.a = @not1.o
@nand1.b = @not1.o
@nand2.a = @nand1.o
@nand2.b = @not1.o
@nand3.a = @reset1_nand.o
@nand3.b = @nand4.o
@nand4.a = @nand3.o
@nand4.b = @reset1_and.o
@nand5.a = @nand3.o
@nand5.b = @not2.o
@nand6.a = @nand5.o
@nand6.b = @not2.o
@nand7.a = @reset2_nand.o
@nand7.b = @nand8.o
@nand8.a = @nand7.o
@nand8.b = @reset2_and.o
end
def d=(v)
@nand1.a = v
end
def clk=(v)
@not1.a = v
end
def clrb=(v)
@reset1_and.b = @reset1_nand.b = v
@reset2_and.b = @reset2_nand.b = v
end
def q
@nand7.o
end
def qb
@nand8.o
end
def inspect
"q=#{HLHASH[q.get]}, qb=#{HLHASH[qb.get]}"
end
end
class DFF
def initialize(bit_width)
@dff = Array.new(bit_width){DFF1.new}
end
def d=(v)
@dff.zip(v) do |dff, o|
dff.d = o
end
end
def clk=(v)
@dff.each do |dff|
dff.clk = v
end
end
def clrb=(v)
@dff.each do |dff|
dff.clrb = v
end
end
def q
@dff.map{|dff|dff.q}
end
def qb
@dff.map{|dff|dff.qb}
end
end
class JKFF
def initialize
@nand1 = NAND.new
@nand2 = NAND.new
@nand3 = NAND.new
@nand4 = NAND3.new
@nand5 = NAND3.new
@nand6 = NAND.new
@nand7 = NAND.new
@nand8 = NAND.new
@reset_and = AND.new
@reset_not = NOT.new
@reset_nand = NAND.new
@reset_and.a = @nand5.o
@reset_not.a = @nand4.o
@reset_nand.a = @reset_not.o
@nand1.a = @nand8.o
@nand2.b = @nand7.o
@nand3.a = @nand1.o
@nand3.b = @nand4.o
@nand4.a = @nand3.o
@nand4.c = @nand5.o
@nand5.a = @nand4.o
@nand5.c = @nand6.o
@nand6.a = @nand5.o
@nand6.b = @nand2.o
@nand7.a = @reset_nand.o # @nand.o
@nand7.b = @nand8.o
@nand8.a = @nand7.o
@nand8.b = @reset_and.o #@nand5.o
end
def j=(v)
@nand1.b = v
end
def k=(v)
@nand2.a = v
end
def clk=(v)
@nand4.b = v
@nand5.b = v
end
def clrb=(v)
@reset_and.b = @reset_nand.b = v
end
def q
@nand7.o
end
def qb
@nand8.o
end
def inspect
"#{HLHASH[q.get]}#{HLHASH[qb.get]}"
end
end
class TFF
def initialize
@jkff = JKFF.new
@jkff.j = @jkff.k = OutputPin.new(H)
end
def t=(v)
@jkff.clk = v
end
def clrb=(v)
@jkff.clrb = v
end
def q
@jkff.q
end
def qb
@jkff.qb
end
def inspect
"#{HLHASH[q.get]}#{HLHASH[qb.get]}"
end
end
class Incrementer
def initialize(bit_width)
@ha = Array.new(bit_width){HarfAdder.new}
@ha.last.b = OutputPin.new(H)
if bit_width > 1
(bit_width-1).times do |i|
@ha[i].b = @ha[i+1].c
end
end
end
def d=(v)
@ha.zip(v).each do |ha, o|
ha.a = o
end
end
def o
@ha.map{|ha|ha.s}
end
end
class Counter
def initialize(bit_width)
@dff = Array.new(bit_width){
tmp = DFF1.new
tmp.d = tmp.qb
tmp
}
if bit_width > 1
(bit_width-1).times do |i|
@dff[i].clk = @dff[i+1].qb
end
end
end
def clk=(v)
@dff.last.clk = v
end
def clrb=(v)
@dff.each do |dff|
dff.clrb = v
end
end
def o
@dff.map{|dff|dff.q}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment