def setUp(self): self.s = Status() plat = ["", None, None] pscanner = PlatformScanner() platform_dict = pscanner.get_platforms() platform_names = platform_dict.keys() if "sim" in platform_names: #If sim is in the platforms, move it to the end platform_names.remove("sim") platform_names.append("sim") urn = None for platform_name in platform_names: if plat[1] is not None: break self.s.Debug("Platform: %s" % str(platform_name)) platform_instance = platform_dict[platform_name](self.s) #self.s.Verbose("Platform Instance: %s" % str(platform_instance)) instances_dict = platform_instance.scan() for name in instances_dict: #s.Verbose("Found Platform Item: %s" % str(platform_item)) n = instances_dict[name] plat = ["", None, None] if n is not None: self.s.Important("Found a nysa instance: %s" % name) n.read_sdb() #import pdb; pdb.set_trace() if n.is_device_in_platform(DRIVER): plat = [platform_name, name, n] break continue #self.s.Verbose("\t%s" % psi) if plat[1] is None: self.sata_drv = None return n = plat[2] self.n = n sata_urn = n.find_device(DRIVER)[0] dma_urn = n.find_device(DMA)[0] self.memory_urn = self.n.find_device(Memory)[0] self.sata_drv = DRIVER(n, sata_urn) self.dma = DMA(n, dma_urn) self.s.set_level("verbose") self.s.Info("Using Platform: %s" % plat[0]) self.s.Info("Instantiated a SATA Device: %s" % sata_urn) self.s.Info("Instantiated a DMA Device: %s" % dma_urn)
def dma_first_test(dut): """ Description: Very Basic Functionality Startup Nysa Startup DMA Controller Test ID: 4 Expected Results: Write to all registers """ dut.test_id = 4 #nysa = NysaSim(dut) nysa = NysaSim(dut, SIM_CONFIG, CLK_PERIOD, user_paths=[MODULE_PATH]) yield (nysa.reset()) nysa.read_sdb() dma = DMA(nysa, nysa.find_device(DMA)[0]) sata = SATADriver(nysa, nysa.find_device(SATADriver)[0]) yield cocotb.external(dma.setup)() setup_sata(dut) yield cocotb.external(sata.enable_sata_reset)(False) count = yield cocotb.external(dma.get_channel_count)() dut.log.info("DMA Channel Count: %d" % count) dut.log.info("SATA Opened!") dut.log.info("DMA Opened!") dut.log.info("Ready") yield nysa.wait_clocks(100)
def first_test(dut): """ Description: Very Basic Functionality Startup Nysa Startup DMA Controller Test ID: 0 Expected Results: Write to all registers """ dut.test_id = 0 nysa = NysaSim(dut) yield (nysa.reset()) nysa.read_sdb() nysa.pretty_print_sdb() dma = DMA(nysa, nysa.find_device(DMA)[0]) yield cocotb.external(dma.setup)() yield cocotb.external(dma.get_channel_count)() dut.log.info("DMA Opened!") dut.log.info("Ready")
def test_dma_read_write_transfer(dut): """ Description: Simple DMA Transfer Test ID: 3 Expected Results: """ dut.test_id = 3 nysa = NysaSim(dut, SIM_CONFIG, CLK_PERIOD, user_paths = [MODULE_PATH]) setup_dut(dut) yield(nysa.reset()) nysa.read_sdb() yield(nysa.wait_clocks(10)) driver = wb_hs_demoDriver(nysa, nysa.find_device(wb_hs_demoDriver)[0]) dma = DMA(nysa, nysa.find_device(DMA)[0]) yield cocotb.external(dma.setup)() yield cocotb.external(dma.enable_dma)(True) yield(nysa.wait_clocks(10)) count = yield cocotb.external(dma.get_channel_count)() dut.log.info("DMA Channel Count: %d" % count) #WORD_COUNT = 0x880 #WORD_COUNT = 0x1000 #WORD_COUNT = 0x0800 #WORD_COUNT = 0x400 WORD_COUNT = 0x400 #WORD_COUNT = 0x800000 CHANNEL_ADDR = 1 SINK_ADDR = 3 INST_ADDR = 7 SOURCE_ADDRESS = 0x0000000000000000 DEST_ADDRESS = 0x0000000000000000 yield cocotb.external(dma.set_channel_sink_addr) (CHANNEL_ADDR, SINK_ADDR ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer) (CHANNEL_ADDR, INST_ADDR ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_source_address_increment) (CHANNEL_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_address_increment) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, False ) #yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_source_address) (INST_ADDR, SOURCE_ADDRESS ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_dest_address) (INST_ADDR, DEST_ADDRESS ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_data_count) (INST_ADDR, WORD_COUNT ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer) (CHANNEL_ADDR, INST_ADDR ) yield nysa.wait_clocks(10) #Start yield cocotb.external(dma.enable_channel) (CHANNEL_ADDR, True ) yield nysa.wait_clocks(10000) yield cocotb.external(dma.enable_channel) (CHANNEL_ADDR, False ) yield cocotb.external(dma.enable_dma)(False) yield nysa.wait_clocks(10) WORD_COUNT = 0x400 CHANNEL_ADDR = 3 SINK_ADDR = 0 INST_ADDR = 0 SOURCE_ADDRESS = 0x0000000000000000 DEST_ADDRESS = 0x0000000000000000 yield cocotb.external(dma.set_channel_sink_addr) (CHANNEL_ADDR, SINK_ADDR ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer) (CHANNEL_ADDR, INST_ADDR ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_source_address_increment) (CHANNEL_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_address_increment) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, False ) #yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_source_address) (INST_ADDR, SOURCE_ADDRESS ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_dest_address) (INST_ADDR, DEST_ADDRESS ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_data_count) (INST_ADDR, WORD_COUNT ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer) (CHANNEL_ADDR, INST_ADDR ) yield nysa.wait_clocks(10) #Start yield cocotb.external(dma.enable_channel) (CHANNEL_ADDR, True ) yield nysa.wait_clocks(10000) yield cocotb.external(dma.enable_channel) (CHANNEL_ADDR, False ) yield cocotb.external(dma.enable_dma)(False) yield nysa.wait_clocks(10) ''' data = Array('B') SIZE =1024 for i in range(SIZE): data.append(i % 256) yield cocotb.external(driver.write_data)(0x00, data) yield (nysa.wait_clocks(100)) v = yield cocotb.external(driver.read_data)(0x00, (SIZE / 4)) if len(v) != len(data): raise cocotb.result.TestFailure("Test %d: Length of incomming data and outgoing data is equal %d = %d" % (dut.test_id, len(v), len(data))) for i in range(len(data)): if v[i] != data[i]: raise cocotb.result.TestFailure("Test %d: Address 0x%02X 0x%02X != 0x%02X" % (dut.test_id, i, v[i], data[i])) ''' dut.log.info("Success")
def test_setup_dma(dut): """ Description: Set Values Within Simulation and make sure they stimulate The correct places Read Number of Sources Read Number of Sinks Read Number of Instructions Source Testing: Enable DMA Source Address Address Increment Address Decrement Address No Change Set Sink Address Set Instruction Address Sink Testing: Sink Address Address Increment Address Decrement Address No Change Quantum Instruction Continue Testing Next Address Source Reset Address on Command Sink Reset Address on Command Egress Enable and Egress Bond Address Ingress Enable and Ingress Bond Address Test ID: 1 Expected Results: Write to all registers """ dut.test_id = 1 nysa = NysaSim(dut) yield(nysa.reset()) nysa.read_sdb() dma = DMA(nysa, nysa.find_device(DMA)[0]) yield nysa.wait_clocks(10) yield cocotb.external(dma.setup)() yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dma)(True) yield nysa.wait_clocks(10) #print "Enable dma" SINK_ADDR = 2 INST_ADDR = 7 NEXT_INST_ADDR =3 INGRESS_ADDR = 2 EGRESS_ADDR = 4 level = logging.INFO l = logging.getLogger("cocotb.gpi") #print "dma.channel_count: %d" % dma.channel_count #Source for i in range (0, dma.channel_count): #Set Channel Address Increment yield cocotb.external(dma.enable_source_address_increment)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr increment is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_source_address_increment)(i) if r != True: raise cocotb.result.TestFailure("Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) yield cocotb.external(dma.enable_source_address_increment)(i, False) r = yield cocotb.external(dma.is_source_address_increment)(i) if r != False: raise cocotb.result.TestFailure("Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr increment is false when it should be false" % i) l.setLevel(level) #Set Channel Address Decrement yield cocotb.external(dma.enable_source_address_decrement)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr decrement is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_source_address_decrement)(i) if r != True: raise cocotb.result.TestFailure("Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) yield cocotb.external(dma.enable_source_address_decrement)(i, False) r = yield cocotb.external(dma.is_source_address_decrement)(i) if r != False: raise cocotb.result.TestFailure("Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr decrement is true when it should be false" % i) l.setLevel(level) #Channel Enable yield cocotb.external(dma.enable_channel)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.dma_enable[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr enable is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_channel_enable)(i) if r == False: raise cocotb.result.TestFailure("Channel [%d] DMA Enable should be true but it is not" % (i)) yield cocotb.external(dma.enable_channel)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.dma_enable[i].value.get_value(): raise cocotb.result.TestFailure("Channel [%d] source addr enable is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_channel_enable)(i) if r: raise cocotb.result.TestFailure("Channel [%d] DMA Enable should be false but it is not" % (i)) #Set Channel Sink Address yield cocotb.external(dma.set_channel_sink_addr)(i, SINK_ADDR) l.setLevel(logging.ERROR) addr = get_register_range(dut.s1.dmacntrl.src_control[i], dmam.BIT_SINK_ADDR_TOP, dmam.BIT_SINK_ADDR_BOT) l.setLevel(level) if addr != SINK_ADDR: cocotb.result.TestFailure("Channel [%d] Sink Address should be [%d] but is [%d]" % (i, SINK_ADDR, addr)) r = yield cocotb.external(dma.get_channel_sink_addr)(i) if SINK_ADDR != r: raise cocotb.result.TestFailure("Channel [%d] Sink Addr should be [%d] but is [%d]" % (i, SINK_ADDR, r)) #Set Channel Instruction Address yield cocotb.external(dma.set_channel_instruction_pointer)(i, INST_ADDR) l.setLevel(logging.ERROR) inst_addr = get_register_range(dut.s1.dmacntrl.src_control[i], dmam.BIT_INST_PTR_TOP, dmam.BIT_INST_PTR_BOT) l.setLevel(level) if inst_addr != INST_ADDR: raise cocotb.result.TestFailure("Channel [%d] Insruction Addr should be [%d] but is [%d]" % (i, INST_ADDR, inst_addr)) r = yield cocotb.external(dma.get_channel_instruction_pointer)(i) if INST_ADDR != r: raise cocotb.result.TestFailure("Channel [%d] Insruction Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) #Sink for i in range (0, dma.sink_count): #Enable and Disable the dest incrementing yield cocotb.external(dma.enable_dest_address_increment)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Increment not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_increment)(i) if r != True: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Increment not enabled" % (i)) yield cocotb.external(dma.enable_dest_address_increment)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_dest_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Increment not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_increment)(i) if r: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Increment enabled" % (i)) #Enable and Disable the dest decrementing yield cocotb.external(dma.enable_dest_address_decrement)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Decrement not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_decrement)(i) if r != True: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Decrement not enabled" % (i)) yield cocotb.external(dma.enable_dest_address_decrement)(i, False) if dut.s1.dmacntrl.flag_dest_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Decrement not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_decrement)(i) if r: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Decrement enabled" % (i)) #Enable and Disable the sink respect quantum yield cocotb.external(dma.enable_dest_respect_quantum)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_data_quantum[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Respect Quantum not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_respect_quantum)(i) if r != True: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Respect Quantum not enabled" % (i)) yield cocotb.external(dma.enable_dest_respect_quantum)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_dest_data_quantum[i].value.get_value(): raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Respect Quantum enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_respect_quantum)(i) if r: raise cocotb.result.TestFailure("Sink [%d] DMA Sink Address Respect Quantum enabled" % (i)) #Instruction for i in range(dma.get_instruction_count()): #Continue Testing yield cocotb.external(dma.enable_instruction_continue)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_instruction_continue[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Instruction Continue Not Enabled When it shouldn't be" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_continue)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_instruction_continue[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Instruction Continue Enabled When it shouldn't be" % (i)) l.setLevel(level) #Next Address yield cocotb.external(dma.set_instruction_next_instruction)(i, NEXT_INST_ADDR) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.cmd_next[i].value.get_value() l.setLevel(level) if addr != NEXT_INST_ADDR: raise cocotb.result.TestFailure("Instruction [%d] Next Address Should be [%d] but is [%d]" % (i, NEXT_INST_ADDR, addr)) yield cocotb.external(dma.set_instruction_next_instruction)(i, 0) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.cmd_next[i].value.get_value() l.setLevel(level) if addr != 0: raise cocotb.result.TestFailure("Instruction [%d] Next Address Should be [%d] but is [%d]" % (i, 0, addr)) #Source Reset Address on Command yield cocotb.external(dma.enable_instruction_src_addr_reset_on_cmd)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Reset Source Address on command is not set" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_src_addr_reset_on_cmd)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Reset Source Address on command is set" % (i)) l.setLevel(level) #Sink Reset Address on Command yield cocotb.external(dma.enable_instruction_dest_addr_reset_on_cmd)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Reset Destination Address on command is not set" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_dest_addr_reset_on_cmd)(i, False) if dut.s1.dmacntrl.flag_dest_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Reset Destination Address on command is set" % (i)) l.setLevel(level) #Egress Enable and Egress Bond Address yield cocotb.external(dma.set_instruction_egress)(i, EGRESS_ADDR) yield cocotb.external(dma.enable_egress_bond)(i, True) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.egress_bond_ip[i].value.get_value() if not dut.s1.dmacntrl.flag_egress_bond[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Egress is not Enabled when it should be" % (i)) l.setLevel(level) if addr != EGRESS_ADDR: raise cocotb.result.TestFailure("Instruction [%d] Egress Address Should be [%d] but is [%d]" % (i, EGRESS_ADDR, addr)) yield cocotb.external(dma.enable_egress_bond)(i, False) if dut.s1.dmacntrl.flag_egress_bond[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Egress is Enabled when it shouldn't be" % (i)) #Ingress Enable and Ingress Bond Address yield cocotb.external(dma.set_instruction_ingress)(i, INGRESS_ADDR) yield cocotb.external(dma.enable_ingress_bond)(i, True) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.ingress_bond_ip[i].value.get_value() if not dut.s1.dmacntrl.flag_ingress_bond[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Ingress is not Enabled when it should be" % (i)) l.setLevel(level) if addr != INGRESS_ADDR: raise cocotb.result.TestFailure("Instruction [%d] Ingress Address Should be [%d] but is [%d]" % (i, EGRESS_ADDR, addr)) yield cocotb.external(dma.enable_ingress_bond)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_ingress_bond[i].value.get_value(): raise cocotb.result.TestFailure("Instruction [%d] Ingress is Enabled when it shouldn't be" % (i)) l.setLevel(level) print "Finished" yield nysa.wait_clocks(10)
class Test (unittest.TestCase): def setUp(self): self.s = Status() plat = ["", None, None] pscanner = PlatformScanner() platform_dict = pscanner.get_platforms() platform_names = platform_dict.keys() if "sim" in platform_names: #If sim is in the platforms, move it to the end platform_names.remove("sim") platform_names.append("sim") urn = None for platform_name in platform_names: if plat[1] is not None: break self.s.Debug("Platform: %s" % str(platform_name)) platform_instance = platform_dict[platform_name](self.s) #self.s.Verbose("Platform Instance: %s" % str(platform_instance)) instances_dict = platform_instance.scan() for name in instances_dict: #s.Verbose("Found Platform Item: %s" % str(platform_item)) n = instances_dict[name] plat = ["", None, None] if n is not None: self.s.Important("Found a nysa instance: %s" % name) n.read_sdb() #import pdb; pdb.set_trace() if n.is_device_in_platform(DRIVER): plat = [platform_name, name, n] break continue #self.s.Verbose("\t%s" % psi) if plat[1] is None: self.sata_drv = None return n = plat[2] self.n = n sata_urn = n.find_device(DRIVER)[0] dma_urn = n.find_device(DMA)[0] self.memory_urn = self.n.find_device(Memory)[0] self.sata_drv = DRIVER(n, sata_urn) self.dma = DMA(n, dma_urn) self.s.set_level("verbose") self.s.Info("Using Platform: %s" % plat[0]) self.s.Info("Instantiated a SATA Device: %s" % sata_urn) self.s.Info("Instantiated a DMA Device: %s" % dma_urn) def test_dma_sata(self): if self.sata_drv is None: self.s.Fatal("Cannot Run Test when no device is found!") return self.s.Info("Reseting Hard Drive...") self.sata_drv.enable_sata_reset(True) time.sleep(0.5) self.sata_drv.enable_sata_reset(False) time.sleep(0.75) self.s.Info("Reset Complete") if self.sata_drv.is_linkup(): self.s.Important("Linked up with Hard Drive!") self.s.Info("\tInitial Status of hard drive (Status): 0x%02X" % self.sata_drv.get_d2h_status()) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("\tReceived 0 for status of hard drive, sending reset!") self.s.Warning ("Sending reset command to hard drive") self.sata_drv.send_hard_drive_command(0x08) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("Still Received 0x00 after reset, send a sequence of identify commands to get hard drive into known state") for i in range (32): self.sata_drv.send_hard_drive_command(0xEC) if (self.sata_drv.get_d2h_status() & 0x040) > 0: print "Found!" break if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning("Did not get a normal status response from the hard drive attempting soft reset") time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(True) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(False) self.sata_drv.send_hard_drive_command(0x00) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Error("After Soft Reset Still Did not get a good response") sys.exit(1) self.sata_drv.identify_hard_drive() config = self.sata_drv.get_config() self.s.Verbose("Hard Drive Serial Number: %s" % config.serial_number()) max_user_lba = config.max_user_sectors() self.s.Verbose("Max User Sectors: %d" % config.max_user_sectors()) self.s.Verbose("Max User Size (GB): %f" % ((config.max_user_sectors() * 512.0) * 0.000000001)) #Clear out a block of memory values = Array('B') clear_values = Array('B') for i in range (2048 * 4): values.append(i % 256) clear_values.append(0) self.sata_drv.set_local_buffer_write_size(128) self.sata_drv.write_local_buffer(clear_values) self.sata_drv.load_local_buffer() self.sata_drv.hard_drive_write(0x0000, 1) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() #self.s.Verbose("Data from Hard Drive Before DMA Transfer (Should be all zeros):") #print str(data[0:128]) self.sata_drv.enable_dma_control(True) self.s.Info("Setup DMA") self.dma.setup() self.dma.enable_dma(True) #DMA Configuration CHANNEL_ADDR = 2 SINK_ADDR = 0 INST_ADDR = 0 DDR3_ADDRESS = 0x0000000000000000 SATA_ADDRESS = 0x0000000000000000 #WORD_TRANSFER_COUNT = 0x1000 #WORD_TRANSFER_COUNT = 0x800 #WORD_TRANSFER_COUNT = 2048 #Rarely Failed: #WORD_TRANSFER_COUNT = 0x2000 #WORD_TRANSFER_COUNT = 0x16000 WORD_TRANSFER_COUNT = 0x0A00000 #WORD_TRANSFER_COUNT = 0x100000 #WORD_TRANSFER_COUNT = 0xF00000 #WORD_TRANSFER_COUNT = 0x800000 #WORD_TRANSFER_COUNT = 0x900000 #WORD_TRANSFER_COUNT = 0xB00000 MEGABYTES = (WORD_TRANSFER_COUNT * 4.0) / 1000000.0 self.s.Info ("Transfer Size: 0x%08X" % WORD_TRANSFER_COUNT) #Clear SATA self.clear_memory() #Fill Memory With Data self.s.Important("Fill memory with zeros") self.s.Important("Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) #self.fill_memory_with_pattern() self.dma.enable_channel (CHANNEL_ADDR, False ) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.set_instruction_source_address (INST_ADDR, DDR3_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose("Data from first sector of hard drive (Should be all zeros):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) print ("") #Fill Memory With Data self.s.Important("Fill memory with pattern") self.s.Important("Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) self.fill_memory_with_pattern() self.dma.enable_channel (CHANNEL_ADDR, False ) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.set_instruction_source_address (INST_ADDR, DDR3_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT ''' self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() status = self.dma.get_channel_status(CHANNEL_ADDR) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tStatus: 0x%08X" % status ''' while not self.dma.is_channel_finished(CHANNEL_ADDR): #while (self.dma.get_current_sink_address(SINK_ADDR) - SATA_ADDRESS) >= WORD_TRANSFER_COUNT: print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info ("Transaction Finished!") print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() #self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) self.dma.enable_channel (CHANNEL_ADDR, False ) self.sata_drv.enable_dma_control (False) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose("Data from first sector of the hard drive (Should be incrementing number patter):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) #Clear DDR3 Memory self.s.Important("Clear DDR3 Memory") self.clear_memory() data = self.n.read_memory(0x00, 128) self.s.Verbose("Data read from memory after clear (Should be all zeros):") print str(data[0:128]) #Configure DMA to transfer 100MB of data from hard drive to DDR3 CHANNEL_ADDR = 0 SINK_ADDR = 2 self.s.Important("Configure DMA to transfer %f MB from Hard Drive to DDR3" % MEGABYTES) self.dma.set_channel_sink_addr (CHANNEL_ADDR, SINK_ADDR ) self.dma.set_channel_instruction_pointer (CHANNEL_ADDR, INST_ADDR ) self.dma.enable_source_address_increment (CHANNEL_ADDR, True ) self.dma.enable_dest_address_increment (SINK_ADDR, True ) #self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum (SINK_ADDR, False ) self.dma.set_instruction_source_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_dest_address (INST_ADDR, SATA_ADDRESS ) self.dma.set_instruction_data_count (INST_ADDR, WORD_TRANSFER_COUNT ) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction (INST_ADDR, INST_ADDR ) self.dma.enable_instruction_continue (INST_ADDR, False ) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel (CHANNEL_ADDR, True ) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info ("Wait for transaction to finish (Timeout: %d)" % TIMEOUT) timeout = time.time() + TIMEOUT fail = False while not self.dma.is_channel_finished(CHANNEL_ADDR): print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info ("Transaction Finished!") print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() #Transaction Complete self.s.Important("DMA Transaction is complete") #Verify values of memory are correct self.s.Important("Verify values of DDR3 are correct") data = self.n.read_memory(0x00, 128) self.s.Verbose("Data read from memory after clear (Should be all incrementing number pattern):") print str(data[0:128]) #self.verify_memory_pattern() self.s.Verbose("Put Hard Drive to Sleep") self.sata_drv.hard_drive_sleep() def fail_analysis(self, channel, sink, instruction_addr): status = self.dma.get_channel_status(channel) source_ready = ((status & 0x200) >> 9) source_activate = ((status & 0x100) >> 8) sink_ready = ((status & 0xC0) >> 6) sink_activate = ((status & 0x30) >> 4) if channel == 0: self.s.Warning("Hard Drive -> DDR3") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("***DMA STALL! *****") elif channel == 2: self.s.Warning("DDR3 -> Hard Drive") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("***DMA STALL! *****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") print "Channel Status: 0x%08X" % status print "\tDMA Enabled: %s" % str(((status & 0x01) > 0)) print "\tBusy: %s" % str(((status & 0x02) > 0)) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tSink Error Conflict: %s" % str(((status & 0x08) > 0)) print "\tSink Activate: 0x%02X" % sink_activate print "\tSink Ready: 0x%02X" % sink_ready print "\tSource Activate: 0x%02X" % source_activate print "\tSource Ready: 0x%02X" % source_ready print "\tInstruction Count: 0x%08X" % self.dma.get_instruction_data_count(instruction_addr) print "\tInstruction Dest Addr 0x%016X" % self.dma.get_instruction_dest_address(instruction_addr) print "\tInstruction Source Addr0x%016X" % self.dma.get_instruction_source_address(instruction_addr) print"" print "\tDMA Request Ingress Address: 0x%08X" % self.dma.get_channel_sink_addr(channel) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() print "\tDMA Request Egress Address: 0x%08X" % self.dma.get_instruction_dest_address(instruction_addr) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(sink) print "" print "\tSATA Command Layer Write State: %d" % self.sata_drv.get_cmd_wr_state() print "\tSATA Transport State: %d" % self.sata_drv.get_transport_state() print "\tSATA Link Layer State: %d" % self.sata_drv.get_link_layer_write_state() print "" print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() print "\tDMA Channel State: %s" % self.dma.get_debug_channel_state(channel) def fill_memory_with_pattern(self): position = 0 #self.clear_memory() total_size = self.n.get_device_size(self.memory_urn) size = 0 if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size #Write Data Out data_out = Array('B') for i in range (0, size): data_out.append((i % 0x100)) while position < total_size: self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Wrote: 0x%08X - 0x%08X" % (prev_pos, position)) def verify_memory_pattern(self): #Read status = "Passed" fail = False fail_count = 0 total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 data_out = Array('B') for i in range (0, size): data_out.append((i % 0x100)) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while (position < total_size) and fail_count < 257: data_in = self.n.read_memory(position, size / 4) if size != len(data_in): self.s.Error("Data in length not equal to data_out length") self.s.Error("\toutgoing: %d" % size) self.s.Error("\tincomming: %d" % len(data_in)) dout = data_out.tolist() din = data_in.tolist() for i in range(len(data_out)): out_val = dout[i] in_val = din[i] if out_val != in_val: fail = True status = "Failed" self.s.Error("Mismatch @ 0x%08X: Write: (Hex): 0x%08X Read (Hex): 0x%08X" % (position + i, data_out[i], data_in[i])) if fail_count >= 16: break fail_count += 1 prev_pos = position if (position + size) > total_size: size = total_size - position position += size self.s.Verbose("Read: 0x%08X - 0x%08X" % (prev_pos, position)) return status def clear_memory(self): total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 self.s.Verbose("Clearing Memory") self.s.Verbose("Memory Size: 0x%08X" % size) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than read/write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while position < total_size: data_out = Array('B') for i in range(0, ((size / 4) - 1)): num = 0x00 data_out.append(num) self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose ("Cleared: 0x%08X - 0x%08X" % (prev_pos, position))
class Test(unittest.TestCase): def setUp(self): self.s = Status() plat = ["", None, None] pscanner = PlatformScanner() platform_dict = pscanner.get_platforms() platform_names = platform_dict.keys() if "sim" in platform_names: #If sim is in the platforms, move it to the end platform_names.remove("sim") platform_names.append("sim") urn = None for platform_name in platform_names: if plat[1] is not None: break self.s.Debug("Platform: %s" % str(platform_name)) platform_instance = platform_dict[platform_name](self.s) #self.s.Verbose("Platform Instance: %s" % str(platform_instance)) instances_dict = platform_instance.scan() for name in instances_dict: #s.Verbose("Found Platform Item: %s" % str(platform_item)) n = instances_dict[name] plat = ["", None, None] if n is not None: self.s.Important("Found a nysa instance: %s" % name) n.read_sdb() #import pdb; pdb.set_trace() if n.is_device_in_platform(DRIVER): plat = [platform_name, name, n] break continue #self.s.Verbose("\t%s" % psi) if plat[1] is None: self.sata_drv = None return n = plat[2] self.n = n sata_urn = n.find_device(DRIVER)[0] dma_urn = n.find_device(DMA)[0] self.memory_urn = self.n.find_device(Memory)[0] self.sata_drv = DRIVER(n, sata_urn) self.dma = DMA(n, dma_urn) self.s.set_level("verbose") self.s.Info("Using Platform: %s" % plat[0]) self.s.Info("Instantiated a SATA Device: %s" % sata_urn) self.s.Info("Instantiated a DMA Device: %s" % dma_urn) def test_dma_sata(self): if self.sata_drv is None: self.s.Fatal("Cannot Run Test when no device is found!") return self.s.Info("Reseting Hard Drive...") self.sata_drv.enable_sata_reset(True) time.sleep(0.5) self.sata_drv.enable_sata_reset(False) time.sleep(0.75) self.s.Info("Reset Complete") if self.sata_drv.is_linkup(): self.s.Important("Linked up with Hard Drive!") self.s.Info("\tInitial Status of hard drive (Status): 0x%02X" % self.sata_drv.get_d2h_status()) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "\tReceived 0 for status of hard drive, sending reset!") self.s.Warning("Sending reset command to hard drive") self.sata_drv.send_hard_drive_command(0x08) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "Still Received 0x00 after reset, send a sequence of identify commands to get hard drive into known state" ) for i in range(32): self.sata_drv.send_hard_drive_command(0xEC) if (self.sata_drv.get_d2h_status() & 0x040) > 0: print "Found!" break if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Warning( "Did not get a normal status response from the hard drive attempting soft reset" ) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(True) time.sleep(0.1) self.sata_drv.enable_sata_command_layer_reset(False) self.sata_drv.send_hard_drive_command(0x00) if (self.sata_drv.get_d2h_status() & 0x040) == 0: self.s.Error( "After Soft Reset Still Did not get a good response" ) sys.exit(1) self.sata_drv.identify_hard_drive() config = self.sata_drv.get_config() self.s.Verbose("Hard Drive Serial Number: %s" % config.serial_number()) max_user_lba = config.max_user_sectors() self.s.Verbose("Max User Sectors: %d" % config.max_user_sectors()) self.s.Verbose("Max User Size (GB): %f" % ((config.max_user_sectors() * 512.0) * 0.000000001)) #Clear out a block of memory values = Array('B') clear_values = Array('B') for i in range(2048 * 4): values.append(i % 256) clear_values.append(0) self.sata_drv.set_local_buffer_write_size(128) self.sata_drv.write_local_buffer(clear_values) self.sata_drv.load_local_buffer() self.sata_drv.hard_drive_write(0x0000, 1) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() #self.s.Verbose("Data from Hard Drive Before DMA Transfer (Should be all zeros):") #print str(data[0:128]) self.sata_drv.enable_dma_control(True) self.s.Info("Setup DMA") self.dma.setup() self.dma.enable_dma(True) #DMA Configuration CHANNEL_ADDR = 2 SINK_ADDR = 0 INST_ADDR = 0 DDR3_ADDRESS = 0x0000000000000000 SATA_ADDRESS = 0x0000000000000000 #WORD_TRANSFER_COUNT = 0x1000 #WORD_TRANSFER_COUNT = 0x800 #WORD_TRANSFER_COUNT = 2048 #Rarely Failed: #WORD_TRANSFER_COUNT = 0x2000 #WORD_TRANSFER_COUNT = 0x16000 WORD_TRANSFER_COUNT = 0x0A00000 #WORD_TRANSFER_COUNT = 0x100000 #WORD_TRANSFER_COUNT = 0xF00000 #WORD_TRANSFER_COUNT = 0x800000 #WORD_TRANSFER_COUNT = 0x900000 #WORD_TRANSFER_COUNT = 0xB00000 MEGABYTES = (WORD_TRANSFER_COUNT * 4.0) / 1000000.0 self.s.Info("Transfer Size: 0x%08X" % WORD_TRANSFER_COUNT) #Clear SATA self.clear_memory() #Fill Memory With Data self.s.Important("Fill memory with zeros") self.s.Important( "Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) #self.fill_memory_with_pattern() self.dma.enable_channel(CHANNEL_ADDR, False) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) self.dma.enable_dest_respect_quantum(SINK_ADDR, True) self.dma.set_instruction_source_address(INST_ADDR, DDR3_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose( "Data from first sector of hard drive (Should be all zeros):") print str(data[0:128]) self.sata_drv.enable_dma_control(True) print("") #Fill Memory With Data self.s.Important("Fill memory with pattern") self.s.Important( "Configure DMA to transfer %f MB from DDR3 to Hard Drive" % MEGABYTES) self.fill_memory_with_pattern() self.dma.enable_channel(CHANNEL_ADDR, False) #Configure DMA to transfer 100MB of data from DDR3 to hard drive self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) self.dma.enable_dest_respect_quantum(SINK_ADDR, True) self.dma.set_instruction_source_address(INST_ADDR, DDR3_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish") fail = False timeout = time.time() + TIMEOUT ''' self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address(SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status() print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count() status = self.dma.get_channel_status(CHANNEL_ADDR) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tStatus: 0x%08X" % status ''' while not self.dma.is_channel_finished(CHANNEL_ADDR): #while (self.dma.get_current_sink_address(SINK_ADDR) - SATA_ADDRESS) >= WORD_TRANSFER_COUNT: print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info("Transaction Finished!") print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address( SINK_ADDR) print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) #self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) self.dma.enable_channel(CHANNEL_ADDR, False) self.sata_drv.enable_dma_control(False) self.sata_drv.hard_drive_read(0x0000, 1) data = self.sata_drv.read_local_buffer() self.s.Verbose( "Data from first sector of the hard drive (Should be incrementing number patter):" ) print str(data[0:128]) self.sata_drv.enable_dma_control(True) #Clear DDR3 Memory self.s.Important("Clear DDR3 Memory") self.clear_memory() data = self.n.read_memory(0x00, 128) self.s.Verbose( "Data read from memory after clear (Should be all zeros):") print str(data[0:128]) #Configure DMA to transfer 100MB of data from hard drive to DDR3 CHANNEL_ADDR = 0 SINK_ADDR = 2 self.s.Important( "Configure DMA to transfer %f MB from Hard Drive to DDR3" % MEGABYTES) self.dma.set_channel_sink_addr(CHANNEL_ADDR, SINK_ADDR) self.dma.set_channel_instruction_pointer(CHANNEL_ADDR, INST_ADDR) self.dma.enable_source_address_increment(CHANNEL_ADDR, True) self.dma.enable_dest_address_increment(SINK_ADDR, True) #self.dma.enable_dest_respect_quantum (SINK_ADDR, True ) self.dma.enable_dest_respect_quantum(SINK_ADDR, False) self.dma.set_instruction_source_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_dest_address(INST_ADDR, SATA_ADDRESS) self.dma.set_instruction_data_count(INST_ADDR, WORD_TRANSFER_COUNT) #This is only needed if we are going to another instruction after this self.dma.set_instruction_next_instruction(INST_ADDR, INST_ADDR) self.dma.enable_instruction_continue(INST_ADDR, False) #Initate DMA Transaction self.s.Important("Intiate a DMA Transaction") self.dma.enable_interrupt_when_command_finished(True) self.dma.enable_channel(CHANNEL_ADDR, True) #Transaction Complete self.s.Important("DMA Transaction is complete") #self.dma.wait_for_interrupts(wait_time = 10) self.s.Info("Wait for transaction to finish (Timeout: %d)" % TIMEOUT) timeout = time.time() + TIMEOUT fail = False while not self.dma.is_channel_finished(CHANNEL_ADDR): print ".", if time.time() > timeout: print "" self.s.Error("Timeout Occured!") fail = True break if fail: self.fail_analysis(CHANNEL_ADDR, SINK_ADDR, INST_ADDR) return self.s.Info("Transaction Finished!") print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) #Transaction Complete self.s.Important("DMA Transaction is complete") #Verify values of memory are correct self.s.Important("Verify values of DDR3 are correct") data = self.n.read_memory(0x00, 128) self.s.Verbose( "Data read from memory after clear (Should be all incrementing number pattern):" ) print str(data[0:128]) #self.verify_memory_pattern() self.s.Verbose("Put Hard Drive to Sleep") self.sata_drv.hard_drive_sleep() def fail_analysis(self, channel, sink, instruction_addr): status = self.dma.get_channel_status(channel) source_ready = ((status & 0x200) >> 9) source_activate = ((status & 0x100) >> 8) sink_ready = ((status & 0xC0) >> 6) sink_activate = ((status & 0x30) >> 4) if channel == 0: self.s.Warning("Hard Drive -> DDR3") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("***DMA STALL! *****") elif channel == 2: self.s.Warning("DDR3 -> Hard Drive") if ((source_ready == 0) and (source_activate == 0)): self.s.Error("***DMA STALL! *****") elif ((sink_ready == 0) and (sink_activate == 0)): self.s.Error("*** HARD DRIVE STALL! ****") print "Channel Status: 0x%08X" % status print "\tDMA Enabled: %s" % str(((status & 0x01) > 0)) print "\tBusy: %s" % str(((status & 0x02) > 0)) print "\tFinished: %s" % str(((status & 0x04) > 0)) print "\tSink Error Conflict: %s" % str(((status & 0x08) > 0)) print "\tSink Activate: 0x%02X" % sink_activate print "\tSink Ready: 0x%02X" % sink_ready print "\tSource Activate: 0x%02X" % source_activate print "\tSource Ready: 0x%02X" % source_ready print "\tInstruction Count: 0x%08X" % self.dma.get_instruction_data_count( instruction_addr) print "\tInstruction Dest Addr 0x%016X" % self.dma.get_instruction_dest_address( instruction_addr) print "\tInstruction Source Addr0x%016X" % self.dma.get_instruction_source_address( instruction_addr) print "" print "\tDMA Request Ingress Address: 0x%08X" % self.dma.get_channel_sink_addr( channel) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) print "\tDMA Request Egress Address: 0x%08X" % self.dma.get_instruction_dest_address( instruction_addr) print "\tCurrent SATA DMA Address: 0x%08X" % self.dma.get_current_sink_address( sink) print "" print "\tSATA Command Layer Write State: %d" % self.sata_drv.get_cmd_wr_state( ) print "\tSATA Transport State: %d" % self.sata_drv.get_transport_state( ) print "\tSATA Link Layer State: %d" % self.sata_drv.get_link_layer_write_state( ) print "" print "\tSATA Status: 0x%08X" % self.sata_drv.get_d2h_status( ) print "\tSATA Current Address: 0x%08X" % self.sata_drv.get_hard_drive_lba( ) print "\tSATA Sector Count: 0x%08X" % self.sata_drv.get_sector_count( ) print "\tDMA Channel State: %s" % self.dma.get_debug_channel_state( channel) def fill_memory_with_pattern(self): position = 0 #self.clear_memory() total_size = self.n.get_device_size(self.memory_urn) size = 0 if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size #Write Data Out data_out = Array('B') for i in range(0, size): data_out.append((i % 0x100)) while position < total_size: self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Wrote: 0x%08X - 0x%08X" % (prev_pos, position)) def verify_memory_pattern(self): #Read status = "Passed" fail = False fail_count = 0 total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 data_out = Array('B') for i in range(0, size): data_out.append((i % 0x100)) if total_size > MAX_LONG_SIZE: self.s.Verbose("Memory Size: 0x%08X is larger than write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while (position < total_size) and fail_count < 257: data_in = self.n.read_memory(position, size / 4) if size != len(data_in): self.s.Error("Data in length not equal to data_out length") self.s.Error("\toutgoing: %d" % size) self.s.Error("\tincomming: %d" % len(data_in)) dout = data_out.tolist() din = data_in.tolist() for i in range(len(data_out)): out_val = dout[i] in_val = din[i] if out_val != in_val: fail = True status = "Failed" self.s.Error( "Mismatch @ 0x%08X: Write: (Hex): 0x%08X Read (Hex): 0x%08X" % (position + i, data_out[i], data_in[i])) if fail_count >= 16: break fail_count += 1 prev_pos = position if (position + size) > total_size: size = total_size - position position += size self.s.Verbose("Read: 0x%08X - 0x%08X" % (prev_pos, position)) return status def clear_memory(self): total_size = self.n.get_device_size(self.memory_urn) position = 0 size = 0 self.s.Verbose("Clearing Memory") self.s.Verbose("Memory Size: 0x%08X" % size) if total_size > MAX_LONG_SIZE: self.s.Verbose( "Memory Size: 0x%08X is larger than read/write size" % total_size) self.s.Verbose("\tBreaking transaction into 0x%08X chunks" % MAX_LONG_SIZE) size = MAX_LONG_SIZE else: size = total_size while position < total_size: data_out = Array('B') for i in range(0, ((size / 4) - 1)): num = 0x00 data_out.append(num) self.n.write_memory(position, data_out) #Increment the position prev_pos = position if position + size > total_size: size = total_size - position position += size self.s.Verbose("Cleared: 0x%08X - 0x%08X" % (prev_pos, position))
def test_double_buffer(dut): """ Description: Setup a channel to transfer data Test ID: 7 Expected Results: Data is all transferred from one memory device to the next """ dut.test_id = 7 #nysa = NysaSim(dut) nysa = NysaSim(dut, SIM_CONFIG, CLK_PERIOD, user_paths=[MODULE_PATH]) yield (nysa.reset()) nysa.read_sdb() yield nysa.wait_clocks(10) dma = DMA(nysa, nysa.find_device(DMA)[0]) sata = SATADriver(nysa, nysa.find_device(SATADriver)[0]) setup_sata(dut) yield cocotb.external(sata.enable_sata_reset)(False) yield cocotb.external(dma.setup)() yield cocotb.external(dma.enable_dma)(True) #yield nysa.wait_clocks(10) #Enable the hard drive data generator dut.h2u_read_enable = 1 #Instructions INST_START_ADDR = 0 #Channels SOURCE_CHANNEL = 0 MEM_SINK_CHANNEL = 2 MEM_SOURCE_CHANNEL = 2 SINK_CHANNEL = 1 #Addresses SOURCE_ADDR = 0x0000 MEM_ADDR0 = 0x0000 MEM_ADDR1 = 0x0000 SINK_ADDR = 0x0000 #Count COUNT = 0x0080 print "Setup double buffer" source_error = get_source_error_signal(dut, SOURCE_CHANNEL) sink_error = get_sink_error_signal(dut, SINK_CHANNEL) source_error_monitor = ErrorMonitor(dut, source_error) sink_error_monitor = ErrorMonitor(dut, sink_error) #Setup Address Increments for all sinks and sources yield cocotb.external(dma.enable_source_address_increment)(SOURCE_CHANNEL, True) yield cocotb.external(dma.enable_dest_address_increment)(SINK_CHANNEL, True) yield cocotb.external(dma.enable_dest_respect_quantum)(MEM_SINK_CHANNEL, True) yield cocotb.external(dma.enable_source_address_increment)( MEM_SOURCE_CHANNEL, True) yield cocotb.external(dma.enable_dest_respect_quantum)(MEM_SINK_CHANNEL, False) yield cocotb.external(dma.enable_dest_address_increment)(MEM_SINK_CHANNEL, True) yield cocotb.external(dma.set_channel_sink_addr)(SOURCE_CHANNEL, MEM_SINK_CHANNEL) yield cocotb.external(dma.set_channel_sink_addr)(MEM_SOURCE_CHANNEL, SINK_CHANNEL) yield cocotb.external(dma.setup_double_buffer) \ ( start_inst_addr = INST_START_ADDR, \ source = SOURCE_CHANNEL, \ sink = SINK_CHANNEL, \ mem_sink = MEM_SINK_CHANNEL, \ mem_source = MEM_SOURCE_CHANNEL, \ source_addr = SOURCE_ADDR, \ sink_addr = SINK_ADDR, \ mem_addr0 = MEM_ADDR0, \ mem_addr1 = MEM_ADDR1, \ count = COUNT ) yield cocotb.external(dma.enable_channel)(SOURCE_CHANNEL, True) yield cocotb.external(dma.enable_channel)(MEM_SOURCE_CHANNEL, True) yield nysa.wait_clocks(4000) yield cocotb.external(dma.enable_channel)(SOURCE_CHANNEL, False) yield cocotb.external(dma.enable_channel)(MEM_SOURCE_CHANNEL, False) if len(source_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d read detected %d errors" % (dut.test_id, SOURCE_CHANNEL, len(source_error_monitor))) if len(sink_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on sink %d read detected %d errors" % (dut.test_id, SINK_CHANNEL, len(sink_error_monitor))) source_error_monitor.kill() sink_error_monitor.kill() yield nysa.wait_clocks(100) dut.h2u_read_enable = 0
def test_continuous_transfer(dut): """ Description: Setup a channel to transfer data Test ID: 6 Expected Results: Data is all transferred from one memory device to the next """ dut.test_id = 6 #nysa = NysaSim(dut) nysa = NysaSim(dut, SIM_CONFIG, CLK_PERIOD, user_paths=[MODULE_PATH]) yield (nysa.reset()) nysa.read_sdb() yield nysa.wait_clocks(2000) dma = DMA(nysa, nysa.find_device(DMA)[0]) sata = SATADriver(nysa, nysa.find_device(SATADriver)[0]) setup_sata(dut) yield cocotb.external(sata.enable_sata_reset)(False) yield cocotb.external(dma.setup)() yield cocotb.external(dma.enable_dma)(True) #yield nysa.wait_clocks(10) CHANNEL_ADDR = 0 SINK_ADDR = 2 INST_ADDR = 2 source_error = get_source_error_signal(dut, CHANNEL_ADDR) sink_error = get_sink_error_signal(dut, SINK_ADDR) source_error_monitor = ErrorMonitor(dut, source_error) sink_error_monitor = ErrorMonitor(dut, sink_error) #yield cocotb.external(dma.enable_channel) (CHANNEL_ADDR, False ) yield cocotb.external(dma.set_channel_sink_addr)(CHANNEL_ADDR, SINK_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_source_address_increment)(CHANNEL_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_address_increment)(SINK_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_respect_quantum)(SINK_ADDR, False) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_instruction_continue)(INST_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_source_address)( INST_ADDR, 0x0000000000000000) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_dest_address)(INST_ADDR, 0x0000000000000010) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_data_count)(INST_ADDR, 0x0100) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_next_instruction)(INST_ADDR, INST_ADDR) yield nysa.wait_clocks(10) #Start yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, True) yield nysa.wait_clocks(2000) yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, False) yield cocotb.external(dma.enable_dma)(False) yield nysa.wait_clocks(10) if len(source_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d read detected %d errors" % (dut.test_id, CHANNEL_ADDR, len(source_error_monitor))) if len(sink_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on sink %d write detected %d errors" % (dut.test_id, SINK_ADDR, len(sink_error_monitor))) source_error_monitor.kill() sink_error_monitor.kill()
def test_single_instruction_from_sata(dut): """ Description: -Setup source and sink for 0x200 word transaction -Setup the source address to increment -Setup the sink address to increment -setup instruction Test ID: 5 Expected Results: Data is all transferred from one memory device to the next """ dut.test_id = 8 #nysa = NysaSim(dut) nysa = NysaSim(dut, SIM_CONFIG, CLK_PERIOD, user_paths=[MODULE_PATH]) yield (nysa.reset()) nysa.read_sdb() yield nysa.wait_clocks(2000) dma = DMA(nysa, nysa.find_device(DMA)[0]) sata = SATADriver(nysa, nysa.find_device(SATADriver)[0]) setup_sata(dut) yield cocotb.external(sata.enable_sata_reset)(False) yield cocotb.external(dma.setup)() yield cocotb.external(dma.enable_dma)(True) yield nysa.wait_clocks(10) yield cocotb.external(sata.enable_dma_control)(True) dut.h2u_read_enable = 1 #WORD_COUNT = 0x880 WORD_COUNT = 0x800 CHANNEL_ADDR = 3 SINK_ADDR = 0 INST_ADDR = 0 SOURCE_ADDRESS = 0x0000000000000000 DEST_ADDRESS = 0x0000000000000200 source_error = get_source_error_signal(dut, CHANNEL_ADDR) sink_error = get_sink_error_signal(dut, SINK_ADDR) source_error_monitor = ErrorMonitor(dut, source_error) sink_error_monitor = ErrorMonitor(dut, sink_error) yield cocotb.external(dma.set_channel_sink_addr)(CHANNEL_ADDR, SINK_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_source_address_increment)(CHANNEL_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_address_increment)(SINK_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_respect_quantum)(SINK_ADDR, False) #yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_source_address)(INST_ADDR, SOURCE_ADDRESS) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_dest_address)(INST_ADDR, DEST_ADDRESS) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_data_count)(INST_ADDR, WORD_COUNT) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield nysa.wait_clocks(10) #Start yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, True) yield nysa.wait_clocks(10000) yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, False) yield cocotb.external(dma.enable_dma)(False) yield nysa.wait_clocks(10) #dut.tdm0.m2f_data_error <= 1 #yield nysa.wait_clocks(10) if len(source_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d write detected %d errors" % (dut.test_id, CHANNEL_ADDR, len(source_error_monitor))) if len(sink_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d read detected %d errors" % (dut.test_id, SINK_ADDR, len(sink_error_monitor))) source_error_monitor.kill() sink_error_monitor.kill()
def test_setup_dma(dut): """ Description: Set Values Within Simulation and make sure they stimulate The correct places Read Number of Sources Read Number of Sinks Read Number of Instructions Source Testing: Enable DMA Source Address Address Increment Address Decrement Address No Change Set Sink Address Set Instruction Address Sink Testing: Sink Address Address Increment Address Decrement Address No Change Quantum Instruction Continue Testing Next Address Source Reset Address on Command Sink Reset Address on Command Egress Enable and Egress Bond Address Ingress Enable and Ingress Bond Address Test ID: 1 Expected Results: Write to all registers """ dut.test_id = 1 nysa = NysaSim(dut) yield (nysa.reset()) nysa.read_sdb() dma = DMA(nysa, nysa.find_device(DMA)[0]) yield nysa.wait_clocks(10) yield cocotb.external(dma.setup)() yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dma)(True) yield nysa.wait_clocks(10) #print "Enable dma" SINK_ADDR = 2 INST_ADDR = 7 NEXT_INST_ADDR = 3 INGRESS_ADDR = 2 EGRESS_ADDR = 4 level = logging.INFO l = logging.getLogger("cocotb.gpi") #print "dma.channel_count: %d" % dma.channel_count #Source for i in range(0, dma.channel_count): #Set Channel Address Increment yield cocotb.external(dma.enable_source_address_increment)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr increment is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_source_address_increment)(i) if r != True: raise cocotb.result.TestFailure( "Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) yield cocotb.external(dma.enable_source_address_increment)(i, False) r = yield cocotb.external(dma.is_source_address_increment)(i) if r != False: raise cocotb.result.TestFailure( "Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr increment is false when it should be false" % i) l.setLevel(level) #Set Channel Address Decrement yield cocotb.external(dma.enable_source_address_decrement)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr decrement is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_source_address_decrement)(i) if r != True: raise cocotb.result.TestFailure( "Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) yield cocotb.external(dma.enable_source_address_decrement)(i, False) r = yield cocotb.external(dma.is_source_address_decrement)(i) if r != False: raise cocotb.result.TestFailure( "Channel [%d] source Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr decrement is true when it should be false" % i) l.setLevel(level) #Channel Enable yield cocotb.external(dma.enable_channel)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.dma_enable[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr enable is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_channel_enable)(i) if r == False: raise cocotb.result.TestFailure( "Channel [%d] DMA Enable should be true but it is not" % (i)) yield cocotb.external(dma.enable_channel)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.dma_enable[i].value.get_value(): raise cocotb.result.TestFailure( "Channel [%d] source addr enable is false when it should be true" % i) l.setLevel(level) r = yield cocotb.external(dma.is_channel_enable)(i) if r: raise cocotb.result.TestFailure( "Channel [%d] DMA Enable should be false but it is not" % (i)) #Set Channel Sink Address yield cocotb.external(dma.set_channel_sink_addr)(i, SINK_ADDR) l.setLevel(logging.ERROR) addr = get_register_range(dut.s1.dmacntrl.src_control[i], dmam.BIT_SINK_ADDR_TOP, dmam.BIT_SINK_ADDR_BOT) l.setLevel(level) if addr != SINK_ADDR: cocotb.result.TestFailure( "Channel [%d] Sink Address should be [%d] but is [%d]" % (i, SINK_ADDR, addr)) r = yield cocotb.external(dma.get_channel_sink_addr)(i) if SINK_ADDR != r: raise cocotb.result.TestFailure( "Channel [%d] Sink Addr should be [%d] but is [%d]" % (i, SINK_ADDR, r)) #Set Channel Instruction Address yield cocotb.external(dma.set_channel_instruction_pointer)(i, INST_ADDR) l.setLevel(logging.ERROR) inst_addr = get_register_range(dut.s1.dmacntrl.src_control[i], dmam.BIT_INST_PTR_TOP, dmam.BIT_INST_PTR_BOT) l.setLevel(level) if inst_addr != INST_ADDR: raise cocotb.result.TestFailure( "Channel [%d] Insruction Addr should be [%d] but is [%d]" % (i, INST_ADDR, inst_addr)) r = yield cocotb.external(dma.get_channel_instruction_pointer)(i) if INST_ADDR != r: raise cocotb.result.TestFailure( "Channel [%d] Insruction Addr should be [%d] but is [%d]" % (i, INST_ADDR, r)) #Sink for i in range(0, dma.sink_count): #Enable and Disable the dest incrementing yield cocotb.external(dma.enable_dest_address_increment)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Increment not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_increment)(i) if r != True: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Increment not enabled" % (i)) yield cocotb.external(dma.enable_dest_address_increment)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_dest_addr_inc[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Increment not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_increment)(i) if r: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Increment enabled" % (i)) #Enable and Disable the dest decrementing yield cocotb.external(dma.enable_dest_address_decrement)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Decrement not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_decrement)(i) if r != True: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Decrement not enabled" % (i)) yield cocotb.external(dma.enable_dest_address_decrement)(i, False) if dut.s1.dmacntrl.flag_dest_addr_dec[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Decrement not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_address_decrement)(i) if r: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Decrement enabled" % (i)) #Enable and Disable the sink respect quantum yield cocotb.external(dma.enable_dest_respect_quantum)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_data_quantum[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Respect Quantum not enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_respect_quantum)(i) if r != True: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Respect Quantum not enabled" % (i)) yield cocotb.external(dma.enable_dest_respect_quantum)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_dest_data_quantum[i].value.get_value(): raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Respect Quantum enabled" % (i)) l.setLevel(level) r = yield cocotb.external(dma.is_dest_respect_quantum)(i) if r: raise cocotb.result.TestFailure( "Sink [%d] DMA Sink Address Respect Quantum enabled" % (i)) #Instruction for i in range(dma.get_instruction_count()): #Continue Testing yield cocotb.external(dma.enable_instruction_continue)(i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_instruction_continue[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Instruction Continue Not Enabled When it shouldn't be" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_continue)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_instruction_continue[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Instruction Continue Enabled When it shouldn't be" % (i)) l.setLevel(level) #Next Address yield cocotb.external(dma.set_instruction_next_instruction)( i, NEXT_INST_ADDR) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.cmd_next[i].value.get_value() l.setLevel(level) if addr != NEXT_INST_ADDR: raise cocotb.result.TestFailure( "Instruction [%d] Next Address Should be [%d] but is [%d]" % (i, NEXT_INST_ADDR, addr)) yield cocotb.external(dma.set_instruction_next_instruction)(i, 0) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.cmd_next[i].value.get_value() l.setLevel(level) if addr != 0: raise cocotb.result.TestFailure( "Instruction [%d] Next Address Should be [%d] but is [%d]" % (i, 0, addr)) #Source Reset Address on Command yield cocotb.external(dma.enable_instruction_src_addr_reset_on_cmd)( i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_src_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Reset Source Address on command is not set" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_src_addr_reset_on_cmd)( i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_src_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Reset Source Address on command is set" % (i)) l.setLevel(level) #Sink Reset Address on Command yield cocotb.external(dma.enable_instruction_dest_addr_reset_on_cmd)( i, True) l.setLevel(logging.ERROR) if not dut.s1.dmacntrl.flag_dest_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Reset Destination Address on command is not set" % (i)) l.setLevel(level) yield cocotb.external(dma.enable_instruction_dest_addr_reset_on_cmd)( i, False) if dut.s1.dmacntrl.flag_dest_addr_rst_on_cmd[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Reset Destination Address on command is set" % (i)) l.setLevel(level) #Egress Enable and Egress Bond Address yield cocotb.external(dma.set_instruction_egress)(i, EGRESS_ADDR) yield cocotb.external(dma.enable_egress_bond)(i, True) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.egress_bond_ip[i].value.get_value() if not dut.s1.dmacntrl.flag_egress_bond[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Egress is not Enabled when it should be" % (i)) l.setLevel(level) if addr != EGRESS_ADDR: raise cocotb.result.TestFailure( "Instruction [%d] Egress Address Should be [%d] but is [%d]" % (i, EGRESS_ADDR, addr)) yield cocotb.external(dma.enable_egress_bond)(i, False) if dut.s1.dmacntrl.flag_egress_bond[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Egress is Enabled when it shouldn't be" % (i)) #Ingress Enable and Ingress Bond Address yield cocotb.external(dma.set_instruction_ingress)(i, INGRESS_ADDR) yield cocotb.external(dma.enable_ingress_bond)(i, True) l.setLevel(logging.ERROR) addr = dut.s1.dmacntrl.ingress_bond_ip[i].value.get_value() if not dut.s1.dmacntrl.flag_ingress_bond[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Ingress is not Enabled when it should be" % (i)) l.setLevel(level) if addr != INGRESS_ADDR: raise cocotb.result.TestFailure( "Instruction [%d] Ingress Address Should be [%d] but is [%d]" % (i, EGRESS_ADDR, addr)) yield cocotb.external(dma.enable_ingress_bond)(i, False) l.setLevel(logging.ERROR) if dut.s1.dmacntrl.flag_ingress_bond[i].value.get_value(): raise cocotb.result.TestFailure( "Instruction [%d] Ingress is Enabled when it shouldn't be" % (i)) l.setLevel(level) print "Finished" yield nysa.wait_clocks(10)
def test_execute_single_instruction(dut): """ Description: -Setup source and sink for 256 word transaction -Setup the source address to increment -Setup the sink address to increment -setup instruction Test ID: 2 Expected Results: Data is all transferred from one memory device to the next """ dut.test_id = 2 nysa = NysaSim(dut) yield (nysa.reset()) nysa.read_sdb() yield nysa.wait_clocks(2000) dma = DMA(nysa, nysa.find_device(DMA)[0]) yield cocotb.external(dma.setup)() yield cocotb.external(dma.enable_dma)(True) #yield nysa.wait_clocks(10) CHANNEL_ADDR = 1 SINK_ADDR = 0 INST_ADDR = 7 source_error = get_source_error_signal(dut, CHANNEL_ADDR) sink_error = get_sink_error_signal(dut, SINK_ADDR) source_error_monitor = ErrorMonitor(dut, source_error) sink_error_monitor = ErrorMonitor(dut, sink_error) yield cocotb.external(dma.set_channel_sink_addr)(CHANNEL_ADDR, SINK_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_source_address_increment)(CHANNEL_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_address_increment)(SINK_ADDR, True) yield nysa.wait_clocks(10) yield cocotb.external(dma.enable_dest_respect_quantum)(SINK_ADDR, False) #yield cocotb.external(dma.enable_dest_respect_quantum) (SINK_ADDR, True ) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_source_address)( INST_ADDR, 0x0000000000000000) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_dest_address)(INST_ADDR, 0x0000000000000010) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_instruction_data_count)(INST_ADDR, 1000) yield nysa.wait_clocks(10) yield cocotb.external(dma.set_channel_instruction_pointer)(CHANNEL_ADDR, INST_ADDR) yield nysa.wait_clocks(10) #Start yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, True) yield nysa.wait_clocks(2000) yield cocotb.external(dma.enable_channel)(CHANNEL_ADDR, False) yield cocotb.external(dma.enable_dma)(False) yield nysa.wait_clocks(10) #dut.tdm0.m2f_data_error <= 1 #yield nysa.wait_clocks(10) if len(source_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d write detected %d errors" % (dut.test_id, CHANNEL_ADDR, len(source_error_monitor))) if len(sink_error_monitor) > 0: raise cocotb.result.TestFailure( "Test %d Error on source %d read detected %d errors" % (dut.test_id, SINK_ADDR, len(sink_error_monitor))) source_error_monitor.kill() sink_error_monitor.kill()