rcircuit/old/kt8.rb
2018-07-08 14:09:22 -05:00

183 lines
5.0 KiB
Ruby
Executable File

require_relative "rcircuit_lib"
class ALU < Device
def initialize(init_args={},width)
#define inputs and outputs
define_port('a', width)
define_port('b', width)
define_port('op', 4)
define_port('out', width)
#connect ports in init arguments
init_assign(init_args)
#create internal components
define_device("mux", Mux.new(8, 4).sel(op)
.in0(a + b)
.in1(a - b)
.in2(a & b)
.in3(a | b)
.in4(a ^ b)
.in5(!a)
.in6(!b)
.in7(a)
.in8(b)
.in9(a << 1)
.in10(a >> 1)
.in11(a + 1)
.in12(a - 1)
.in13(0)
.in14(0)
.in15(0) )
mux.out.connect(out)
end
end
def ALU.test
puts "ALU test:"
a=Port.new(8)
b=Port.new(8)
op=Port.new(4)
alu=ALU.new({"a"=>a,"b"=>b,"op"=>op},8)
dbg=Dbg.new({"a"=>a,"b"=>b,"op"=>op,"out"=>alu.out},true)
a.value=3
b.value=10
dbg.add_trigger("op")
for i in (0..15) do
op.value=i
end
end
class KT8Decoder < Device
def initialize(init_args={})
define_port("ins",8)
init_assign(init_args)
define_port("aen")
define_port("ben")
define_port("ren")
define_port("wr")
define_port("rbsel")
define_port("den")
@ins4to7=ins.slice(4..7)
@ins0to3=ins.slice(0..3)
define_device("dec", Decoder.new(4)
.sel(@ins4to7)
.en(1)
.o0(aen)
.o1(ben)
.o2(wr)
.o3(rbsel)
.o8(ren)
.o11(den) )
define_device("dec1", Decoder.new(4).sel(@ins0to3).en(den) )
end
def on_change(new_val)
puts "ins:#{ins.value},ins[5:7]:#{@ins5to7.value},ins[4:7]:#{@ins4to7.value}"
if @ins5to7.value==0
puts "5to7=0"
aen.value=1
ben.value=0
ren.value=0
wr.value=0
rbsel.value=0
end
if @ins5to7.value==1
puts "5to7=1"
aen.value=0
ben.value=1
ren.value=0
wr.value=0
rbsel.value=0
end
if @ins5to7.value==2
puts "5to7=2"
aen.value=0
ben.value=0
ren.value=0
wr.value=1
rbsel.value=0
end
if @ins4to7.value==6
puts "4to7=6"
aen.value=0
ben.value=0
ren.value=0
wr.value=0
rbsel.value=1
end
if @ins4to7.value==7
puts "4to7=7"
aen.value=0
ben.value=0
ren.value=0
wr.value=0
rbsel.value=2
end
if @ins4to7.value==8
puts "4to7=8"
aen.value=0
ben.value=0
ren.value=1
wr.value=0
rbsel.value=0
end
end
end
#start of KT8 parts
class KT8 < Device
def initialize(init_args={})
define_port("clk")
define_port("rst")
define_port("dout",8)
define_port("ins",8)
init_assign(init_args)
define_port("wr")
define_port("paddr",8)
define_port("daddr",5)
define_port("din",8)
define_device("dec", KT8Decoder.new().ins(ins).wr(wr))
define_device("pc", Counter.new(8).clk(clk).rst(rst).load(0).out(paddr))
define_device("reg_a", Reg.new(8).clk(clk).rst(rst).en(dec.aen))
define_device("reg_b",Reg.new(8).clk(clk).rst(rst).en(dec.ben))
define_device("reg_r",Reg.new(8).clk(clk).rst(rst).en(dec.ren))
define_device("alu",ALU.new(8).a(reg_a.out).b(reg_b.out).op(ins.slice(0..3)).out(reg_r.in))
daddr.connect(ins.slice(0..4))
din.connect(reg_r.out)
#reg A input is always from data memory
reg_a.in(dout)
#reg B can be from memory or current value combined with immediate bits
low_bit_combine = reg_b.out.slice(4..7).join(ins.slice(0..3))
high_bit_combine = ins.out.slice(0..3).join(reg_b.out.slice(0..3))
reg_b_source = Mux.new(8,1).in0(dout).in1(low_bit_combine).sel(dec.rbsel)
reg_b.in(reg_b_source.out)
end
end
clk=Port.new
rst=Port.new
prog_mem=Ram.new(8,8)
data_mem=Ram.new(8,5)
kt8=KT8.new("clk"=>clk,"rst"=>rst,"dout"=>data_mem.out,"ins"=>prog_mem.out)
prog_mem.addr(kt8.paddr).clk(clk).wr(0).in(0)
data_mem.addr(kt8.daddr).clk(clk).wr(kt8.wr).in(kt8.din)
dbg=Dbg.new("paddr"=>kt8.paddr,"daddr"=>kt8.daddr,"aval"=>kt8.reg_a.out,"rval"=>kt8.reg_r.out,"ins"=>kt8.ins,"aen"=>kt8.dec.aen,"ben"=>kt8.dec.ben,"ren"=>kt8.dec.ren,"wr"=>kt8.dec.wr,"rbsel"=>kt8.dec.rbsel,"aluop"=>prog_mem.out.slice(0..3))
prog_mem[0]="00000000"
prog_mem[1]="10000111"
prog_mem[2]="01000001"
data_mem[0]="1011"
rst.value=0
clk.value=0
rst.value=1
rst.value=0
dbg.out
clk.value=1
dbg.out
clk.value=0
clk.value=1
dbg.out
clk.value=0
clk.value=1
dbg.out
puts "Putting.."
puts data_mem[1].inspect