--- /dev/null
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.utils import get_sim_steps
+from cocotb.binary import BinaryValue
+
+from c4m.cocotb.jtag.c4m_jtag import JTAG_Master
+from c4m.cocotb.jtag.c4m_jtag_svfcocotb import SVF_Executor
+
+from itertools import chain
+
+import cocotb
+from cocotb.clock import Clock
+from cocotb.triggers import Timer
+from cocotb.utils import get_sim_steps
+from cocotb.binary import BinaryValue
+
+from c4m.nmigen.jtag.tap import IOType
+from c4m.cocotb.jtag.c4m_jtag import JTAG_Master
+from c4m.cocotb.jtag.c4m_jtag_svfcocotb import SVF_Executor
+
+from soc.config.pinouts import get_pinspecs
+from soc.debug.jtag import Pins
+
+#
+# Helper functions
+#
+
+def setup_sim(dut, *, clk_period, run):
+ """Initialize CPU and setup clock"""
+
+ clk_steps = get_sim_steps(clk_period, "ns")
+ cocotb.fork(Clock(dut.sys_clk, clk_steps).start())
+
+ dut.vdd <= 1
+ dut.vss <= 0
+ dut.iovdd <= 1
+ dut.iovss <= 0
+ dut.sys_rst <= 1
+ dut.sys_clk <= 0
+ # adder test (ignore this)
+ #dut.a <= 3
+ #dut.b <= 2
+
+ if run:
+ yield Timer(int(10.5*clk_steps))
+ dut.sys_rst <= 0
+ yield Timer(int(5*clk_steps))
+
+def setup_jtag(dut, *, tck_period):
+ # Make this a generator
+ if False:
+ yield Timer(0)
+ clk_steps = get_sim_steps(tck_period, "ns")
+ return JTAG_Master(dut.jtag_tck, dut.jtag_tms,
+ dut.jtag_tdi, dut.jtag_tdo,
+ clk_period=clk_steps,
+ ir_width=4)
+
+def execute_svf(dut, *, jtag, svf_filename):
+ jtag_svf = SVF_Executor(jtag)
+ with open(svf_filename, "r") as f:
+ svf_deck = f.read()
+ yield jtag_svf.run(svf_deck, p=dut._log.info)
+
+#
+# IDCODE using JTAG_master
+#
+
+def idcode(dut, *, jtag):
+ #jtag.IDCODE = [0, 0, 0, 1]
+ yield jtag.idcode()
+ result1 = jtag.result
+ dut._log.info("IDCODE1: {}".format(result1))
+ assert(result1 == BinaryValue("00000000000000000001100011111111"))
+
+ yield jtag.idcode()
+ result2 = jtag.result
+ dut._log.info("IDCODE2: {}".format(result2))
+
+ assert(result1 == result2)
+
+@cocotb.test()
+def idcode_reset(dut):
+ dut._log.info("Running IDCODE test; cpu in reset...")
+
+ clk_period = 100 # 10MHz
+ tck_period = 300 # 3MHz
+
+ yield from setup_sim(dut, clk_period=clk_period, run=False)
+ jtag = yield from setup_jtag(dut, tck_period = tck_period)
+
+ yield from idcode(dut, jtag=jtag)
+
+ dut._log.info("IDCODE test completed")
+
+@cocotb.test()
+def idcode_run(dut):
+ dut._log.info("Running IDCODE test; cpu running...")
+
+ clk_period = 100 # 10MHz
+ tck_period = 300 # 3MHz
+
+ yield from setup_sim(dut, clk_period=clk_period, run=True)
+ jtag = yield from setup_jtag(dut, tck_period = tck_period)
+
+ yield from idcode(dut, jtag=jtag)
+
+ dut._log.info("IDCODE test completed")
+
+#
+# Read IDCODE from SVF file
+#
+
+@cocotb.test()
+def idcodesvf_reset(dut):
+ dut._log.info("Running IDCODE through SVF test; cpu in reset...")
+
+ clk_period = 100 # 10MHz
+ tck_period = 300 # 3MHz
+
+ yield from setup_sim(dut, clk_period=clk_period, run=False)
+ jtag = yield from setup_jtag(dut, tck_period = tck_period)
+
+ yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
+
+ dut._log.info("IDCODE test completed")
+
+@cocotb.test()
+def idcode_run_svf(dut):
+ dut._log.info("Running IDCODE through test; cpu running...")
+
+ clk_period = 100 # 10MHz
+ tck_period = 300 # 3MHz
+
+ yield from setup_sim(dut, clk_period=clk_period, run=True)
+ jtag = yield from setup_jtag(dut, tck_period = tck_period)
+
+ yield from execute_svf(dut, jtag=jtag, svf_filename="idcode.svf")
+
+ dut._log.info("IDCODE test completed")
+
+
+@cocotb.test()
+def wishbone_basic(dut):
+ """
+ Test of an added Wishbone interface
+ """
+ clk_period = 100 # 100MHz
+ tck_period = 3000 # 0.3MHz
+
+ data_in = BinaryValue()
+ # these have to match with soc.debug.jtag.JTAG ircodes
+ cmd_MEMADDRESS = BinaryValue("0101") # 5
+ cmd_MEMREAD = BinaryValue("0110") # 6
+ cmd_MEMREADWRITE = BinaryValue("0111") # 7
+
+ info = "Running Wishbone basic test"
+ yield from setup_sim(dut, clk_period=clk_period, run=True)
+ master = yield from setup_jtag(dut, tck_period = tck_period)
+
+ # Load the memory address
+ yield master.load_ir(cmd_MEMADDRESS)
+ dut._log.info("Loading address")
+
+ data_in.binstr = "000000000000000000000000000001"
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+
+ # Do write
+ yield master.load_ir(cmd_MEMREADWRITE)
+ dut._log.info("Writing memory")
+
+ data_in.binstr = "01010101" * 4
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+
+ data_in.binstr = "10101010" * 4
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+
+ # Load the memory address
+ yield master.load_ir(cmd_MEMADDRESS)
+ dut._log.info("Loading address")
+
+ data_in.binstr = "000000000000000000000000000001"
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "000000000000000000000000000011"
+
+ # Do read and write
+ yield master.load_ir(cmd_MEMREADWRITE)
+ dut._log.info("Reading and writing memory")
+
+ data_in.binstr = "10101010" * 4
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "01010101" * 4
+
+ data_in.binstr = "01010101" * 4
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "10101010" * 4
+
+ # Load the memory address
+ yield master.load_ir(cmd_MEMADDRESS)
+ dut._log.info("Loading address")
+
+ data_in.binstr = "000000000000000000000000000001"
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "000000000000000000000000000011"
+
+ # Do read
+ yield master.load_ir(cmd_MEMREAD)
+ dut._log.info("Reading memory")
+ data_in.binstr = "00000000" * 4
+
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "10101010" * 4
+
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "01010101" * 4
+
+ # Load the memory address
+ yield master.load_ir(cmd_MEMADDRESS) # MEMADDR
+ dut._log.info("Loading address")
+
+ data_in.binstr = "000000000000000000000000000001"
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "000000000000000000000000000011"
+
+ # Do read
+ yield master.load_ir(cmd_MEMREAD) # MEMREAD
+ dut._log.info("Reading memory")
+ data_in.binstr = "00000000" * 4
+
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "10101010" * 4
+
+ dut._log.info(" input: {}".format(data_in.binstr))
+ yield master.shift_data(data_in)
+ dut._log.info(" output: {}".format(master.result.binstr))
+ assert master.result.binstr == "01010101" * 4
+
+ #dut._log.info("{!r}".format(wbmem))
+
+
+# demo / debug how to get boundary scan names. run "python3 test.py"
+if __name__ == '__main__':
+ pinouts = get_jtag_boundary()
+ for pin in pinouts:
+ # example: ('eint', '2', <IOType.In: 1>, 'eint_2', 125)
+ print (pin)