From 765420c81d144bb08021a7aa09a9a0692f5d6322 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Fri, 16 Jul 2021 13:22:51 -0700 Subject: Add counter module and simplify board design for shift instructions. --- insts.rb | 65 ++++++++++++++++++++++++++++++++++++++++++++-- modules.rb | 81 ++++++++++++++++++++++++++++++---------------------------- sim/alu.sv | 4 +-- sim/control.sv | 3 ++- sim/counter.sv | 38 +++++++++++++++++++++++++++ sim/top.sv | 1 + 6 files changed, 148 insertions(+), 44 deletions(-) create mode 100644 sim/counter.sv diff --git a/insts.rb b/insts.rb index bc9c156..d24a31d 100644 --- a/insts.rb +++ b/insts.rb @@ -105,8 +105,69 @@ alu :xor alu :add alu :sub alu :cmp -alu :lshift -alu :rshift + +inst "lshift $ #" do + uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @counter.decrement; @alu.outdata; @alu.lshift; constaddr(0) } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end + +inst "lshift $ $" do + uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @counter.decrement; @alu.outdata; @alu.lshift; constaddr(0) } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end + +inst "rshift $ #" do + uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @counter.decrement; @alu.outdata; @alu.rshift; constaddr(0) } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end + +inst "rshift $ $" do + uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @counter.decrement; @alu.outdata; @alu.rshift; constaddr(0) } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end + +inst "rshiftsign $ #" do + uop { @decode.outdata_b; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @tmp0.outaddr; @counter.decrement; @alu.outdata; @alu.rshift } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end + +inst "rshiftsign $ $" do + uop { @decode.outaddr_b; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @counter.load; @control.set_uip_if_zero; constaddr($eom) } + uop { @decode.outaddr_a; @rf.outdata; @tmp0.loaddata } + uop { @tmp0.outdata; @alu.xor; constaddr(0) } + shiftloop = uip() + uop { @tmp0.outaddr; @counter.decrement; @alu.outdata; @alu.rshift } + uop { @counter.outdata; @control.set_uip_if_nonzero; constaddr(shiftloop) } + uop { @decode.outaddr_a; @alu.outdata; @rf.store } +end def cmpbit(name, bit) inst "#{name} $ #" do diff --git a/modules.rb b/modules.rb index 752413e..83bfdbd 100644 --- a/modules.rb +++ b/modules.rb @@ -1,39 +1,42 @@ -urom :alu, :op, :op_sel0, :op_sel1, :op_sel2, :outaddr, :outdata -urom_alias :alu, :and, :op -urom_alias :alu, :or, :op, :op_sel0 -urom_alias :alu, :xor, :op, :op_sel1 -urom_alias :alu, :add, :op, :op_sel0, :op_sel1 -urom_alias :alu, :sub, :op, :op_sel2 -urom_alias :alu, :cmp, :op, :op_sel0, :op_sel2 -urom_alias :alu, :lshift, :op, :op_sel1, :op_sel2 -urom_alias :alu, :rshift, :op, :op_sel0, :op_sel1, :op_sel2 - -urom :control, :halt, :set_uip_cond, :nocond, :outaddr, :outdata -urom_alias :control, :set_uip, :set_uip_cond, :nocond -urom_alias :control, :set_uip_if_nonzero, :set_uip_cond - -urom :decode, :clear, :decode, :outaddr, :outaddr_sel0, :outaddr_sel1, :outdata, :outdata_sel0, :outdata_sel1 -urom_alias :decode, :outaddr_a, :outaddr -urom_alias :decode, :outaddr_b, :outaddr, :outaddr_sel0 -urom_alias :decode, :outaddr_uip, :outaddr, :outaddr_sel1 -urom_alias :decode, :outdata_a, :outdata -urom_alias :decode, :outdata_b, :outdata, :outdata_sel0 -urom_alias :decode, :outdata_needmore, :outdata, :outdata_sel1 - -urom :memory, :store, :outdata - -urom :pc, :load, :increment, :outaddr - -urom :rf, :store, :reset, :outdata - -urom :tmp0, :load, :load_sel0, :outaddr, :outdata -urom_alias :tmp0, :loaddata, :load -urom_alias :tmp0, :loadaddr, :load, :load_sel0 - -urom :tmp1, :load, :load_sel0, :outaddr, :outdata -urom_alias :tmp1, :loaddata, :load -urom_alias :tmp1, :loadaddr, :load, :load_sel0 - -urom :uart, :tx, :rx, :outdata, :outdata_sel0 -urom_alias :uart, :outdata_txfull, :outdata -urom_alias :uart, :outdata_rxempty, :outdata, :outdata_sel0 +urom :alu, :op, :op_sel0, :op_sel1, :op_sel2, :outaddr, :outdata +urom_alias :alu, :and, :op +urom_alias :alu, :or, :op, :op_sel0 +urom_alias :alu, :xor, :op, :op_sel1 +urom_alias :alu, :add, :op, :op_sel0, :op_sel1 +urom_alias :alu, :sub, :op, :op_sel2 +urom_alias :alu, :cmp, :op, :op_sel0, :op_sel2 +urom_alias :alu, :lshift, :op, :op_sel1, :op_sel2 +urom_alias :alu, :rshift, :op, :op_sel0, :op_sel1, :op_sel2 + +urom :control, :halt, :set_uip_cond, :nocond, :icond, :outaddr, :outdata +urom_alias :control, :set_uip, :set_uip_cond, :nocond +urom_alias :control, :set_uip_if_nonzero, :set_uip_cond +urom_alias :control, :set_uip_if_zero, :set_uip_cond, :icond + +urom :counter, :load, :increment, :decrement, :outdata + +urom :decode, :clear, :decode, :outaddr, :outaddr_sel0, :outaddr_sel1, :outdata, :outdata_sel0, :outdata_sel1 +urom_alias :decode, :outaddr_a, :outaddr +urom_alias :decode, :outaddr_b, :outaddr, :outaddr_sel0 +urom_alias :decode, :outaddr_uip, :outaddr, :outaddr_sel1 +urom_alias :decode, :outdata_a, :outdata +urom_alias :decode, :outdata_b, :outdata, :outdata_sel0 +urom_alias :decode, :outdata_needmore, :outdata, :outdata_sel1 + +urom :memory, :store, :outdata + +urom :pc, :load, :increment, :outaddr + +urom :rf, :store, :reset, :outdata + +urom :tmp0, :load, :load_sel0, :outaddr, :outdata +urom_alias :tmp0, :loaddata, :load +urom_alias :tmp0, :loadaddr, :load, :load_sel0 + +urom :tmp1, :load, :load_sel0, :outaddr, :outdata +urom_alias :tmp1, :loaddata, :load +urom_alias :tmp1, :loadaddr, :load, :load_sel0 + +urom :uart, :tx, :rx, :outdata, :outdata_sel0 +urom_alias :uart, :outdata_txfull, :outdata +urom_alias :uart, :outdata_rxempty, :outdata, :outdata_sel0 diff --git a/sim/alu.sv b/sim/alu.sv index 407b083..5583492 100644 --- a/sim/alu.sv +++ b/sim/alu.sv @@ -49,8 +49,8 @@ assign cmp_result = {{(BUS_BITS-6){1'b0}}, abus > dbus, abus == dbus, abus < dbus}; -assign lshift_result = (dbus >= BUS_BITS) ? 0 : (abus << dbus); -assign rshift_result = (dbus >= BUS_BITS) ? 0 : (abus >> dbus); +assign lshift_result = {dbus[BUS_BITS-2:0], abus[0]}; +assign rshift_result = {abus[BUS_BITS-1], dbus[BUS_BITS-1:1]}; bit [BUS_BITS-1:0] newx; assign newx = diff --git a/sim/control.sv b/sim/control.sv index 7808f61..ddd6401 100644 --- a/sim/control.sv +++ b/sim/control.sv @@ -18,6 +18,7 @@ typedef enum { HALT , SET_UIP_COND , NOCOND + , ICOND , OUTADDR , OUTDATA } CtrlBit; @@ -33,7 +34,7 @@ assign abus = ctrl[OUTADDR] ? constant : {(BUS_BITS){1'bZ}}; assign dbus = ctrl[OUTDATA] ? constant : {(BUS_BITS){1'bZ}}; bit cond; -assign cond = (dbus != 0) || ctrl[NOCOND]; +assign cond = ((dbus != 0) || ctrl[NOCOND]) ^ ctrl[ICOND]; always @(posedge clk) begin if (reset) begin diff --git a/sim/counter.sv b/sim/counter.sv new file mode 100644 index 0000000..1316783 --- /dev/null +++ b/sim/counter.sv @@ -0,0 +1,38 @@ +module counter + #( parameter UROM = "" + , parameter UIP_BITS = 15 + , parameter UROM_BITS = 8 + , parameter BUS_BITS = 16 + ) + ( input bit clk + , input bit reset + , input bit [UIP_BITS-1:0] uip + , inout bit [BUS_BITS-1:0] abus + , inout bit [BUS_BITS-1:0] dbus + ); + +bit [BUS_BITS-1:0] x; + +typedef enum + { LOAD + , INCREMENT + , DECREMENT + , OUTDATA + } CtrlBit; + +bit [UROM_BITS-1:0] ctrl; +urom#(UROM, UIP_BITS, UROM_BITS) urom(uip, ctrl); + +assign dbus = ctrl[OUTDATA] ? x : {(BUS_BITS){1'bZ}}; + +always @(posedge clk) begin + if (ctrl[LOAD]) begin + x <= dbus; + end else if (ctrl[INCREMENT]) begin + x <= x + 1; + end else if (ctrl[DECREMENT]) begin + x <= x - 1; + end +end + +endmodule diff --git a/sim/top.sv b/sim/top.sv index 6773739..464b93d 100644 --- a/sim/top.sv +++ b/sim/top.sv @@ -14,6 +14,7 @@ bit [BUS_BITS-1:0] dbus; alu #("../out/alu.bin", UIP_BITS, UROM_BITS, BUS_BITS) alu(clk, reset, uip, abus, dbus); control #("../out/control.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/consts.0.bin", "../out/consts.1.bin", 'h7ff8) control(clk, reset, uip, abus, dbus); +counter #("../out/counter.bin", UIP_BITS, UROM_BITS, BUS_BITS) counter(clk, reset, uip, abus, dbus); decode #("../out/decode.bin", UIP_BITS, UROM_BITS, BUS_BITS, 12) decode(clk, reset, uip, abus, dbus); memory #("../out/memory.bin", UIP_BITS, UROM_BITS, BUS_BITS, "../out/image.hex", MEM_BITS) memory(clk, reset, uip, abus, dbus); pc #("../out/pc.bin", UIP_BITS, UROM_BITS, BUS_BITS, 0) pc(clk, reset, uip, abus, dbus); -- cgit v1.2.3