from soc.experiment.alu_hier import ALU, DummyALU
from soc.experiment.compalu_multi import MultiCompUnit
from soc.decoder.power_enums import MicrOp
+from nmutil.gtkw import write_gtkw
from nmigen import Module
from nmigen.cli import rtlil
-cxxsim = False
-if cxxsim:
- from nmigen.sim.cxxsim import Simulator, Settle
-else:
- from nmigen.back.pysim import Simulator, Settle
+
+# NOTE: to use cxxsim, export NMIGEN_SIM_MODE=cxxsim from the shell
+# Also, check out the cxxsim nmigen branch, and latest yosys from git
+from nmutil.sim_tmp_alternative import Simulator, Settle, is_engine_pysim
def wrap(process):
yield dut.issue_i.eq(0)
yield
- yield dut.rd.go.eq(0b11)
+ yield dut.rd.go_i.eq(0b11)
while True:
yield
- rd_rel_o = yield dut.rd.rel
+ rd_rel_o = yield dut.rd.rel_o
print("rd_rel", rd_rel_o)
if rd_rel_o:
break
- yield dut.rd.go.eq(0)
+ yield dut.rd.go_i.eq(0)
- req_rel_o = yield dut.wr.rel
+ req_rel_o = yield dut.wr.rel_o
result = yield dut.data_o
print("req_rel", req_rel_o, result)
while True:
- req_rel_o = yield dut.wr.rel
+ req_rel_o = yield dut.wr.rel_o
result = yield dut.data_o
print("req_rel", req_rel_o, result)
if req_rel_o:
break
yield
- yield dut.wr.go[0].eq(1)
+ yield dut.wr.go_i[0].eq(1)
yield Settle()
result = yield dut.data_o
yield
print("result", result)
- yield dut.wr.go[0].eq(0)
+ yield dut.wr.go_i[0].eq(0)
yield
return result
yield dut.src_i[0].eq(a)
yield dut.src_i[1].eq(b)
yield dut.oper_i.insn_type.eq(op)
- yield dut.oper_i.invert_a.eq(inv_a)
- yield dut.oper_i.imm_data.imm.eq(imm)
- yield dut.oper_i.imm_data.imm_ok.eq(imm_ok)
+ yield dut.oper_i.invert_in.eq(inv_a)
+ yield dut.oper_i.imm_data.data.eq(imm)
+ yield dut.oper_i.imm_data.ok.eq(imm_ok)
yield dut.oper_i.zero_a.eq(zero_a)
yield dut.issue_i.eq(1)
yield
yield dut.issue_i.eq(0)
yield
if not imm_ok or not zero_a:
- yield dut.rd.go.eq(0b11)
+ yield dut.rd.go_i.eq(0b11)
while True:
yield
- rd_rel_o = yield dut.rd.rel
+ rd_rel_o = yield dut.rd.rel_o
print("rd_rel", rd_rel_o)
if rd_rel_o:
break
- yield dut.rd.go.eq(0)
+ yield dut.rd.go_i.eq(0)
else:
print("no go rd")
if len(dut.src_i) == 3:
- yield dut.rd.go.eq(0b100)
+ yield dut.rd.go_i.eq(0b100)
while True:
yield
- rd_rel_o = yield dut.rd.rel
+ rd_rel_o = yield dut.rd.rel_o
print("rd_rel", rd_rel_o)
if rd_rel_o:
break
- yield dut.rd.go.eq(0)
+ yield dut.rd.go_i.eq(0)
else:
print("no 3rd rd")
- req_rel_o = yield dut.wr.rel
+ req_rel_o = yield dut.wr.rel_o
result = yield dut.data_o
print("req_rel", req_rel_o, result)
while True:
- req_rel_o = yield dut.wr.rel
+ req_rel_o = yield dut.wr.rel_o
result = yield dut.data_o
print("req_rel", req_rel_o, result)
if req_rel_o:
break
yield
- yield dut.wr.go[0].eq(1)
+ yield dut.wr.go_i[0].eq(1)
yield Settle()
result = yield dut.data_o
yield
print("result", result)
- yield dut.wr.go[0].eq(0)
+ yield dut.wr.go_i[0].eq(0)
yield
return result
def test_compunit_fsm():
-
+ top = "top.cu" if is_engine_pysim() else "cu"
+ traces = [
+ 'clk', 'src1_i[7:0]', 'src2_i[7:0]', 'oper_i_None__sdir', 'cu_issue_i',
+ 'cu_busy_o', 'cu_rd__rel_o[1:0]', 'cu_rd__go_i[1:0]',
+ 'cu_wr__rel_o', 'cu_wr__go_i', 'dest1_o[7:0]',
+ ('alu', {'module': top+'.alu'}, [
+ 'p_data_i[7:0]', 'p_shift_i[7:0]', 'op__sdir',
+ 'p_valid_i', 'p_ready_o', 'n_valid_o', 'n_ready_i',
+ 'n_data_o[7:0]'
+ ])
+
+ ]
+ write_gtkw(
+ "test_compunit_fsm1.gtkw",
+ "test_compunit_fsm1.vcd",
+ traces,
+ module=top
+ )
m = Module()
alu = Shifter(8)
dut = MultiCompUnit(8, alu, CompFSMOpSubset)
# at the same time, present the operation
yield self.dut.oper_i.insn_type.eq(self.op)
- yield self.dut.oper_i.invert_a.eq(self.inv_a)
- yield self.dut.oper_i.imm_data.imm.eq(self.imm)
- yield self.dut.oper_i.imm_data.imm_ok.eq(self.imm_ok)
+ yield self.dut.oper_i.invert_in.eq(self.inv_a)
+ yield self.dut.oper_i.imm_data.data.eq(self.imm)
+ yield self.dut.oper_i.imm_data.ok.eq(self.imm_ok)
yield self.dut.oper_i.zero_a.eq(self.zero_a)
rdmaskn = self.rdmaskn[0] | (self.rdmaskn[1] << 1)
yield self.dut.rdmaskn.eq(rdmaskn)
# note: rdmaskn must be held, while busy_o is active
# TODO: deactivate rdmaskn when the busy_o cycle ends
yield self.dut.oper_i.insn_type.eq(0)
- yield self.dut.oper_i.invert_a.eq(0)
- yield self.dut.oper_i.imm_data.imm.eq(0)
- yield self.dut.oper_i.imm_data.imm_ok.eq(0)
+ yield self.dut.oper_i.invert_in.eq(0)
+ yield self.dut.oper_i.imm_data.data.eq(0)
+ yield self.dut.oper_i.imm_data.ok.eq(0)
yield self.dut.oper_i.zero_a.eq(0)
yield
if issue_i:
break
# issue_i has not risen yet, so rd must keep low
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert not rel
yield
return
# issue_i has risen. rel must rise on the next cycle
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert not rel
# stall for additional cycles. Check that rel doesn't fall on its own
for n in range(self.RD_GO_DELAY[rd_idx]):
yield
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert rel
# Before asserting "go", make sure "rel" has risen.
# The use of Settle allows "go" to be set combinatorially,
# rising on the same cycle as "rel".
yield Settle()
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert rel
# assert go for one cycle, passing along the operand value
- yield self.dut.rd.go[rd_idx].eq(1)
+ yield self.dut.rd.go_i[rd_idx].eq(1)
yield self.dut.src_i[rd_idx].eq(self.operands[rd_idx])
# check that the operand was sent to the alu
# TODO: Properly check the alu protocol
yield
# rel must keep high, since go was inactive in the last cycle
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert rel
# finish the go one-clock pulse
- yield self.dut.rd.go[rd_idx].eq(0)
+ yield self.dut.rd.go_i[rd_idx].eq(0)
yield self.dut.src_i[rd_idx].eq(0)
yield
# rel must have gone low in response to go being high
# on the previous cycle
- rel = yield self.dut.rd.rel[rd_idx]
+ rel = yield self.dut.rd.rel_o[rd_idx]
assert not rel
self.rd_complete[rd_idx] = True