diff options
192 files changed, 19539 insertions, 1962 deletions
diff --git a/firmware/microblaze/Makefile.am b/firmware/microblaze/Makefile.am index 6316b31a2..52fa649c2 100644 --- a/firmware/microblaze/Makefile.am +++ b/firmware/microblaze/Makefile.am @@ -23,4 +23,7 @@ EXTRA_DIST = \ u2_flash_tool SUBDIRS = \ - usrp2 + usrp2 \ + usrp2p \ + usrp2p/bootloader + diff --git a/firmware/microblaze/Makefile.common b/firmware/microblaze/Makefile.common index ceb6a553a..4e726edab 100644 --- a/firmware/microblaze/Makefile.common +++ b/firmware/microblaze/Makefile.common @@ -59,8 +59,13 @@ COMMON_LFLAGS = \ ######################################################################## # Common stuff for building top level microblaze images ######################################################################## +#we use COMMON_IHX_ARGS to relocate the reset and interrupt vectors to +#just below the start of code. upon creating the BIN, any leading padding +#is thrown out, so the .bin file is valid for uploading to USRP2P. this +#does not affect USRP2 because the USRP2 already starts at 0x0000, and +#because the relocate_args are not defined for USRP2's Makefile.am. .elf.bin: - $(MB_OBJCOPY) -O binary $< $@ + $(MB_OBJCOPY) -O binary $(RELOCATE_ARGS) $< $@ .elf.dump: $(MB_OBJDUMP) -DSC $< > $@ @@ -69,7 +74,7 @@ COMMON_LFLAGS = \ $(HEXDUMP) -v -e'1/1 "%.2X\n"' $< > $@ .elf.ihx: - $(MB_OBJCOPY) -O ihex $(COMMON_IHX_ARGS) $< $@ + $(MB_OBJCOPY) -O ihex $(RELOCATE_ARGS) $< $@ _generated_from_elf = \ $(noinst_PROGRAMS:.elf=.map) \ diff --git a/firmware/microblaze/apps/blinkenlights.c b/firmware/microblaze/apps/blinkenlights.c new file mode 100644 index 000000000..4cebe5c9d --- /dev/null +++ b/firmware/microblaze/apps/blinkenlights.c @@ -0,0 +1,26 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include "memory_map.h" +#include <nonstdio.h> + +int main(int argc, char *argv[]) { + + uint32_t c = 0; + uint8_t i = 0; + + while(1) { + //delay(5000000); + for(c=0;c<5000000;c++) asm("NOP"); + output_regs->leds = (i++ % 2) ? 0xFF : 0x00; //blink everything on that register + } + + return 0; +} + +//void delay(uint32_t t) { +// while(t-- != 0) asm("NOP"); +//} diff --git a/firmware/microblaze/apps/flash_test.c b/firmware/microblaze/apps/flash_test.c new file mode 100644 index 000000000..5b4569030 --- /dev/null +++ b/firmware/microblaze/apps/flash_test.c @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <memory_map.h> +#include <hal_io.h> +#include <hal_uart.h> +#include <xilinx_s3_icap.h> +#include <nonstdio.h> +#include <spi_flash.h> +#include <spi.h> +#include <clocks.h> +#include <string.h> + +//just a test to write to SPI flash and retrieve the same values. +//uses the MOBFLEET SPI flash library + +void delay(uint32_t t) { + while(t-- != 0) asm("NOP"); +} + +int main(int argc, char *argv[]) { + uint16_t i, t; + uint8_t buf[260]; + const uint8_t testdata[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C}; + + hal_disable_ints(); // In case we got here via jmp 0x0 +// spi_init(); + hal_uart_init(); +// clocks_init(); //set up AD9510, enable FPGA clock @ 1x divisor + + puts("SPI Flash test\n"); + puts("Initializing SPI\n"); + + spif_init(); + delay(800000); + puts("Erasing sector 1\n"); + spi_flash_erase(0x00010000, 256); + delay(800000); + puts("Reading back data\n"); + spi_flash_read(0x00010000, 256, buf); + delay(800000); + + t=1; + for(i=4; i<250; i++) { + if(buf[i] != 0xFF) t=0; + } + + if(!t) puts("Data was not initialized to 0xFF. Unsuccessful erase or read\n"); + else puts("Data initialized to 0xFF, erase confirmed\n"); + + puts("Writing test buffer\n"); + spi_flash_program(0x00010000, 16, testdata); + //memset(buf, 0, 256); + + delay(800000); + puts("Wrote data, reading back\n"); + + spi_flash_read(0x00010000, 16, buf); + + if(memcmp(testdata, buf, 16)) puts("Data is not the same between read and write. Unsuccessful write or read\n"); + else puts("Successful write! Flash write correct\n"); + + return 0; +} diff --git a/firmware/microblaze/apps/hardware_testbed.c b/firmware/microblaze/apps/hardware_testbed.c new file mode 100644 index 000000000..e68e68ff7 --- /dev/null +++ b/firmware/microblaze/apps/hardware_testbed.c @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <memory_map.h> +#include <nonstdio.h> +#include <hal_io.h> +#include <xilinx_s3_icap.h> +#include <spi_flash.h> +//#include <spi_flash_private.h> +#include <clocks.h> +#include <ihex.h> +#include <bootloader_utils.h> +#include <string.h> +#include <hal_uart.h> +#include <spi.h> + +//so this is just an evolving file used to set up and test different bits of hardware (EEPROM, clock chip, A/D, D/A, PHY) +void delay(uint32_t t) { + while(t-- != 0) asm("NOP"); +} + +int main(int argc, char *argv[]) { + + hal_disable_ints(); + hal_uart_init(); + spi_init(); + + puts("Hardware testbed. Init clocks..."); + + clocks_init(); + + //now, hopefully, we should be running at 100MHz instead of 50MHz, meaning our UART is twice as fast and we're talking at 230400. + + while(1) { + delay(500000); + puts("Eat at Joe's."); + } + + + + + + return 0; +} diff --git a/firmware/microblaze/apps/txrx_uhd.c b/firmware/microblaze/apps/txrx_uhd.c index b7837f207..9c1873e1c 100644 --- a/firmware/microblaze/apps/txrx_uhd.c +++ b/firmware/microblaze/apps/txrx_uhd.c @@ -42,9 +42,11 @@ #include <string.h> #include "clocks.h" #include "usrp2/fw_common.h" +#include <i2c_async.h> #include <i2c.h> #include <ethertype.h> #include <arp_cache.h> +#include "udp_fw_update.h" /* * Full duplex Tx and Rx between ethernet and DSP pipelines @@ -346,6 +348,28 @@ void handle_udp_ctrl_packet( send_udp_pkt(USRP2_UDP_CTRL_PORT, src, &ctrl_data_out, sizeof(ctrl_data_out)); break; + case USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO:{ + //executes a readline()-style read, up to num_bytes long, up to and including newline + int num_bytes = ctrl_data_in->data.uart_args.bytes; + if(num_bytes > 20) num_bytes = 20; + num_bytes = fngets_timeout(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_out.data.uart_args.data, num_bytes); + ctrl_data_out.id = USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE; + ctrl_data_out.data.uart_args.bytes = num_bytes; + break; + } + + case USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO:{ + int num_bytes = ctrl_data_in->data.uart_args.bytes; + if(num_bytes > 20) num_bytes = 20; + //before we write to the UART, we flush the receive buffer + //this assumes that we're interested in the reply + hal_uart_rx_flush(ctrl_data_in->data.uart_args.dev); + fnputstr(ctrl_data_in->data.uart_args.dev, (char *) ctrl_data_in->data.uart_args.data, num_bytes); + ctrl_data_out.id = USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE; + ctrl_data_out.data.uart_args.bytes = num_bytes; + break; + } + default: ctrl_data_out.id = USRP2_CTRL_ID_HUH_WHAT; send_udp_pkt(USRP2_UDP_CTRL_PORT, src, &ctrl_data_out, sizeof(ctrl_data_out)); @@ -372,7 +396,7 @@ eth_pkt_inspector(dbsm_t *sm, int bufno) // In the future, a hardware state machine will do this... if ( //warning! magic numbers approaching.... (((buff + ((2 + 14 + 20)/sizeof(uint32_t)))[0] & 0xffff) == USRP2_UDP_DATA_PORT) && - ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[0] != USRP2_INVALID_VRT_HEADER) + ((buff + ((2 + 14 + 20 + 8)/sizeof(uint32_t)))[1] != USRP2_INVALID_VRT_HEADER) ) return false; //test if its an ip recovery packet @@ -473,6 +497,16 @@ main(void) { u2_init(); +//we do this to see if we should set a default ip addr or not +#ifdef USRP2P + bool safe_fw = find_safe_booted_flag(); + set_safe_booted_flag(0); + if(safe_fw) { + set_default_ip_addr(); + set_default_mac_addr(); + } +#endif + putstr("\nTxRx-NEWETH\n"); print_mac_addr(ethernet_mac_addr()->addr); newline(); @@ -483,10 +517,11 @@ main(void) //1) register the addresses into the network stack register_mac_addr(ethernet_mac_addr()); register_ip_addr(get_ip_addr()); - + //2) register callbacks for udp ports we service register_udp_listener(USRP2_UDP_CTRL_PORT, handle_udp_ctrl_packet); register_udp_listener(USRP2_UDP_DATA_PORT, handle_udp_data_packet); + register_udp_listener(USRP2_UDP_UPDATE_PORT, handle_udp_fw_update_packet); //3) setup ethernet hardware to bring the link up ethernet_register_link_changed_callback(link_changed_callback); diff --git a/firmware/microblaze/apps/uart_flash_loader.c b/firmware/microblaze/apps/uart_flash_loader.c new file mode 100644 index 000000000..d67b84677 --- /dev/null +++ b/firmware/microblaze/apps/uart_flash_loader.c @@ -0,0 +1,169 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +//#include <stdio.h> +#include <stdlib.h> +#include <memory_map.h> +#include <nonstdio.h> +#include <hal_io.h> +#include <hal_uart.h> +#include <xilinx_s3_icap.h> +#include <spi_flash.h> +#include <spi_flash_private.h> +//#include <clocks.h> +#include <ihex.h> +#include <bootloader_utils.h> + +//uses UART to load files to Flash in Intel HEX 16-bit format. +//this is one example of a "safe" firmware image to be loaded by a bootloader into main RAM. +//this CANNOT write to main RAM, since it is resident there. + +//Sector 0-31: Safe FPGA bootloader image +//Sector 32-63: Production bootloader image +//Sector 64: Production firmware image +//Sector 127: Safe firmware image + + +void uart_flash_loader(void) { + + char buf[256]; //input data buffer + uint8_t ihx[32]; //ihex data buffer + uint32_t slot_offset = PROD_FW_IMAGE_LOCATION_ADDR; //initial slot offset to program to. + uint32_t extended_addr = 0x00000000; //extended Intel hex segment address + + size_t sector_size = spi_flash_log2_sector_size(); + ihex_record_t ihex_record; + ihex_record.data = ihx; + int i; + + + //not gonna win a turing prize for my C text parsing + while(1) { + gets(buf); + if(!strncmp(buf, "!SECTORSIZE", 7)) { //return the sector size in log format + putstr("OK "); + puthex8((uint32_t) sector_size); //err, this should probably be decimal for human readability. we do have itoa now... + putstr("\n"); + } + else if(!strncmp(buf, "!SETADDR", 7)) { //set start address for programming + slot_offset = atol(&buf[8]); + puts("OK"); +// puthex32(slot_offset); +// putstr("\n"); + } + else if(!strncmp(buf, "!ERASE", 6)) { //erase a sector + uint32_t sector = atol(&buf[6]); + uint32_t size = 2 << (sector_size-1); + uint32_t addr = sector << sector_size; + + spi_flash_erase(addr, size); //we DO NOT implement write protection here. it is up to the HOST PROGRAM to not issue an ERASE unless it means it. + //unfortunately the Flash cannot write-protect the segments that really matter, so we only use global write-protect + //as a means of avoiding accidental writes from runaway code / garbage on the SPI bus. + puts("OK"); + } +//can't exactly run firmware if you're already executing out of main RAM +/* else if(!strncmp(buf, "!RUNSFW", 7)) { + if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) { + puts("OK"); + spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE); + start_program(RAM_BASE); + } else { + puts("NOK"); + } + } + else if(!strncmp(buf, "!RUNPFW", 7)) { + if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) { + puts("OK"); + spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES-1, (void *)RAM_BASE); + start_program(RAM_BASE); + } else { + puts("NOK"); + } + } +*/ + else if(!strncmp(buf, "!RUNPFPGA", 8)) { + if(is_valid_fpga_image(PROD_FPGA_IMAGE_LOCATION_ADDR)) { + puts("OK"); + //icap_reload_fpga(PROD_FPGA_IMAGE_LOCATION_ADDR); + } else { + puts("NOK"); + } + } + else if(!strncmp(buf, "!RUNSFPGA", 8)) { + if(is_valid_fpga_image(SAFE_FPGA_IMAGE_LOCATION_ADDR)) { + puts("OK"); + //icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR); + } else { + puts("NOK"); + } + } + else if(!strncmp(buf, "!READ", 5)) { + uint32_t addr = atol(&buf[5]); + spi_flash_read(addr, 16, ihx); + for(i=0; i < 16; i++) { + puthex8(ihx[i]); + } + putstr("\n"); + } + + else if(!ihex_parse(buf, &ihex_record)) { //last, try to see if the input was a valid IHEX line + switch (ihex_record.type) { + case 0: + spi_flash_program(ihex_record.addr + slot_offset + extended_addr, ihex_record.length, ihex_record.data); + puts("OK"); + break; + case 1: + //here we would expect a CRC checking or something else to take place. for now we do nothing. + //well, we set the extended segment addr back to 0 + extended_addr = 0; + puts("DONE"); + break; + case 4: + //set the upper 16 bits of the address + extended_addr = ((ihex_record.data[0] << 8) + ihex_record.data[1]) << 16; + puts("OK"); + break; + default: + puts("NOK"); + } + } + else puts("NOK"); + } //while(1) +} + +void delay(uint32_t t) { + while(t-- != 0) asm("NOP"); +} + +int main(int argc, char *argv[]) { + uint8_t buf[32]; + int i = 0; + + hal_disable_ints(); // In case we got here via jmp 0x0 + +// delay(10000000); + + //before anything else you might want to blinkenlights just to indicate code startup to the user. + + hal_uart_init(); + spif_init(); +// i2c_init(); //for EEPROM + puts("USRP2+ UART firmware loader"); + +// puts("Debug: loading production image, 10 bytes."); + +// spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, 10, buf); +// for(i=0; i < 10; i++) { +// puthex8(buf[i]); +// } + + uart_flash_loader(); + + //shouldn't get here. should reboot. + puts("shit happened.\n"); + + return 0; +} diff --git a/firmware/microblaze/bin/bin_to_mif.py b/firmware/microblaze/bin/bin_to_mif.py new file mode 100755 index 000000000..cefce4e92 --- /dev/null +++ b/firmware/microblaze/bin/bin_to_mif.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +import struct +import sys + +hextab = ('0000', '0001', '0010', '0011', + '0100', '0101', '0110', '0111', + '1000', '1001', '1010', '1011', + '1100', '1101', '1110', '1111') + +def w_to_binary_ascii(w): + return ''.join([hextab[(w >> 4*i) & 0xf] for i in range(7,-1,-1)]) + +def bin_to_mif(bin_input_file, mif_output_file): + ifile = open(bin_input_file, 'rb') + ofile = open(mif_output_file, 'w') + idata = ifile.read() + fmt = ">%dI" % ((len(idata) / 4),) + words = struct.unpack(fmt, idata) + for w in words: + ofile.write(w_to_binary_ascii(w)) + ofile.write('\n') + +if __name__ == '__main__': + if len(sys.argv) != 3: + sys.stderr.write("usage: bin_to_mif bin_input_file mif_output_file\n") + raise SystemExit, 1 + + bin_to_mif(sys.argv[1], sys.argv[2]) diff --git a/firmware/microblaze/bin/bin_to_ram_macro_init.py b/firmware/microblaze/bin/bin_to_ram_macro_init.py new file mode 100755 index 000000000..65cf2dbdf --- /dev/null +++ b/firmware/microblaze/bin/bin_to_ram_macro_init.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python + +import struct +import sys + +def do_8_words(ofile, which_ram, row, words): + ofile.write("defparam bootram.RAM%d.INIT_%02X=256'h" % (which_ram, row)) + ofile.write("%08x_%08x_%08x_%08x_%08x_%08x_%08x_%08x;\n" % ( + words[7], words[6], words[5], words[4], words[3], words[2], words[1], words[0])) + +def bin_to_ram_macro_init(bin_input_file, ram_init_output_file): + ifile = open(bin_input_file, 'rb') + ofile = open(ram_init_output_file, 'w') + idata = ifile.read() + fmt = ">%dI" % ((len(idata) / 4),) + words = struct.unpack(fmt, idata) + + # pad to a multiple of 8 words + r = len(words) % 8 + if r != 0: + words += (8 - r) * (0,) + + if len(words) > 2048: + sys.stderr.write("bin_to_macro_init: error: input file %s is > 8KiB\n" % (bin_input_file,)) + sys.exit(1) + + # first 2KB + for i in range(0, min(512, len(words)), 8): + do_8_words(ofile, 0, i/8, words[i:i+8]) + + # second 2KB + for i in range(512, min(1024, len(words)), 8): + do_8_words(ofile, 1, (i/8) % 64, words[i:i+8]) + + # third 2KB + for i in range(1024, min(1536, len(words)), 8): + do_8_words(ofile, 2, (i/8) % 64, words[i:i+8]) + + # last 2KB + for i in range(1536, len(words), 8): + do_8_words(ofile, 3, (i/8) % 64, words[i:i+8]) + +if __name__ == '__main__': + if len(sys.argv) != 3: + sys.stderr.write("usage: bin_to_ram_macro_init bin_input_file ram_init_output_file\n") + sys.exit(1) + + bin_to_ram_macro_init(sys.argv[1], sys.argv[2]) diff --git a/firmware/microblaze/bin/elf_to_sbf b/firmware/microblaze/bin/elf_to_sbf new file mode 100755 index 000000000..d1be10c0d --- /dev/null +++ b/firmware/microblaze/bin/elf_to_sbf @@ -0,0 +1,142 @@ +#!/usr/bin/env python +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import sys +import struct +from optparse import OptionParser +from pprint import pprint + +import sbf + +# see /usr/include/elf.h for the various magic values + + +_ehdr_fmt = ">16sHH5I6H" +_ehdr_fmt_size = struct.calcsize(_ehdr_fmt) +_phdr_fmt = ">8I" +_phdr_fmt_size = struct.calcsize(_phdr_fmt) + +class elf32_ehdr(object): + def __init__(self, s): + (self.ident, self.type, self.machine, self.version, self.entry, + self.phoff, self.shoff, self.flags, self.ehsize, + self.phentsize, self.phnum, self.shentsize, self.shnum, + self.shstrndx) = struct.unpack(_ehdr_fmt, s) + +class elf32_phdr(object): + def __init__(self, s): + (self.type, self.offset, self.vaddr, self.paddr, + self.filesz, self.memsz, + self.flags, self.align) = struct.unpack(_phdr_fmt, s) + + def __repr__(self): + return "<elf32_phdr %s offset=%d paddr=0x%x, filesz=%d>" % ( + p_type_str(self.type), self.offset, self.paddr, self.filesz) + + +def p_type_str(t): + if t <= 8: + return ('NULL', 'LOAD', 'DYNAMIC', 'INTERP', 'NOTE', 'SHLIB', 'PHDR', 'TLS', 'NUM')[t] + return "0x%x" % (t,) + + + +def _get_ehdr(f): + if len(f) < _ehdr_fmt_size: + return False + ehdr = elf32_ehdr(f[0:_ehdr_fmt_size]) + return ehdr + + +def elf32_big_endian_exec_p(f): + ehdr = _get_ehdr(f) + if not ehdr: + return False + + #pprint(ehdr, sys.stderr) + e_ident = ehdr.ident + if not e_ident.startswith('\177ELF'): + return False + if (ord(e_ident[4]) != 1 # EI_CLASS == CLASS32 + or ord(e_ident[5]) != 2 # EI_DATA == DATA2MSB + or ord(e_ident[6]) != 1 # EI_VERSION == EV_CURRENT + ): + return False + + if ehdr.type != 2: # e_type == ET_EXEC + return False + + return True + + + +# return (entry, (phdr, ...)) + +def get_elf32_prog_headers(f): + ehdr = _get_ehdr(f) + entry = ehdr.entry + phoff = ehdr.phoff + phentsize = ehdr.phentsize + phnum = ehdr.phnum + + def extract(i): + start = phoff + i * phentsize + end = start + phentsize + return f[start:end] + + return (entry, [elf32_phdr(extract(i)) for i in range(phnum)]) + + +def main(): + usage = "%prog: [options] elf_file" + parser = OptionParser() + parser.add_option("-o", "--output", default=None, + help="specify output filename [default=stdout]") + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + sys.exit(1) + + elf_file = open(args[0], 'rb') + + elf_contents = elf_file.read() + if not elf32_big_endian_exec_p(elf_contents): + sys.stderr.write("%s: not a big-endian 32-bit ELF executable\n" % (args[0],)) + sys.exit(1) + + if options.output is None: + sbf_file = sys.stdout + else: + sbf_file = open(options.output, 'wb') + + (entry, phdrs) = get_elf32_prog_headers(elf_contents) + #pprint(phdrs, sys.stderr) + + def phdr_to_sec_desc(phdr): + target_addr = phdr.paddr + data = elf_contents[phdr.offset:phdr.offset+phdr.filesz] + #print >>sys.stderr, "pdhr_to_sec_desc:", (target_addr, data) + return sbf.sec_desc(target_addr, data) + + sections = map(phdr_to_sec_desc, phdrs) + # pprint(sections, sys.stderr) + sbf.write_sbf(sbf_file, sbf.header(entry, sections)) + + +if __name__ == '__main__': + main() diff --git a/firmware/microblaze/bin/sbf.py b/firmware/microblaze/bin/sbf.py new file mode 100644 index 000000000..8e2c868a5 --- /dev/null +++ b/firmware/microblaze/bin/sbf.py @@ -0,0 +1,134 @@ +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +_SBF_MAGIC = 'SBF!' +_SBF_DONT_EXECUTE = 0x1 +_SBF_MAX_SECTIONS = 14 +_SBF_HEADER_LEN = 128 + +import struct +import sys +from pprint import pprint + +def dump_data(f, offset, data): + L = len(data) // 4 + for i in range(L): + f.write('%08x: %08x\n' % (offset + 4 * i, struct.unpack('>I', data[4*i:4*(i+1)])[0])) + remainder = len(data) - L * 4 + if remainder != 0: + f.write('%08x: ' % (offset + L*4,)) + i = 0 + while i < remainder: + f.write('%02x' % ((ord(data[L*4 + i]),))) + i += 1 + f.write('\n') + + + +class sec_desc(object): + def __init__(self, target_addr, data): + self.target_addr = target_addr + self.data = data + + def __repr__(self): + #print >>sys.stderr, "target_addr:", self.target_addr + #print >>sys.stderr, "data:", self.data + return "<sec_desc target_addr=0x%x len=%d>" % ( + self.target_addr, len(self.data)) + + +class header(object): + def __init__(self, entry, sections): + self.entry = entry + self.section = sections + + def dump(self, f): + if self.entry == _SBF_DONT_EXECUTE: + f.write("Entry: DONT_EXECUTE\n") + else: + f.write("Entry: 0x%x\n" % (self.entry,)) + for i in range(len(self.section)): + s = self.section[i] + f.write("Section[%d]: target_addr = 0x%x length = %d\n" % (i, + s.target_addr, + len(s.data))) + dump_data(f, s.target_addr, s.data) + + # + # Returns an iterator. Each yield returns (target_addr, data) + # + def iterator(self, max_piece=512): + for s in self.section: + offset = 0 + L = len(s.data) + while offset < L: + n = min(max_piece, L - offset) + yield (s.target_addr + offset, + s.data[offset:offset+n]) + offset += n + + + +def read_sbf(input_file): + """Parse an SBF file""" + + f = input_file.read(_SBF_HEADER_LEN) + #if len(f) < _SBF_HEADER_LEN or not f.startswith(_SBF_MAGIC): + #raise ValueError, '%s: not an SBF file' % (input_file.name,) + + def extract(i): + start = 16+8*i + stop = start+8 + return struct.unpack('>2I', f[start:stop]) + + def get_data(ss): + L = ss[1] + s = input_file.read(L) + #if len(s) != L: + #raise ValueError, '%s: file is too short' % (input_file.name(),) + return s + + (magic, entry, nsections, reserved) = struct.unpack('>4s3I', f[0:16]) + assert nsections <= _SBF_MAX_SECTIONS + descs = [extract(i) for i in range(nsections)] + #pprint(descs, sys.stderr) + data = map(get_data, descs) + secs = map(lambda ss, data: sec_desc(ss[0], data), descs, data) + return header(entry, secs) + + +def write_sbf(output_file, sbf_header): + assert(len(sbf_header.section) <= _SBF_MAX_SECTIONS) + sbf_header.nsections = len(sbf_header.section) + f = output_file + + # write the file header + f.write(struct.pack('>4s3I', _SBF_MAGIC, sbf_header.entry, sbf_header.nsections, 0)) + + # write the section headers + for i in range(sbf_header.nsections): + f.write(struct.pack('>2I', + sbf_header.section[i].target_addr, + len(sbf_header.section[i].data))) + for i in range(_SBF_MAX_SECTIONS - sbf_header.nsections): + f.write(struct.pack('>2I', 0, 0)) + + # write the section data + for i in range(sbf_header.nsections): + f.write(sbf_header.section[i].data) + + return True diff --git a/firmware/microblaze/bin/serial_loader b/firmware/microblaze/bin/serial_loader new file mode 100755 index 000000000..9bd5aada7 --- /dev/null +++ b/firmware/microblaze/bin/serial_loader @@ -0,0 +1,363 @@ +#!/usr/bin/env python +# +# Copyright 2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import termios +import tty +import os +import sys +import threading +import Queue +from optparse import OptionParser +import time + +import sbf + +GDB_ESCAPE = chr(0x7d) + +# Indexes for termios list. +IFLAG = 0 +OFLAG = 1 +CFLAG = 2 +LFLAG = 3 +ISPEED = 4 +OSPEED = 5 +CC = 6 + +class terminal(object): + def __init__(self, device, speed_bits): + fd = os.open(device, os.O_RDWR) + if not os.isatty(fd): + raise ValueError(device + " is not a tty") + + self.read_file = os.fdopen(fd, "rb", 0) + self.write_file = os.fdopen(os.dup(fd), "wb", 0) + self.old_attrs = termios.tcgetattr(self.write_file.fileno()) + #print "old_attrs: ", self.old_attrs + attrs = list(self.old_attrs) # copy of attributes + attrs[ISPEED] = speed_bits # set input and output speed + attrs[OSPEED] = speed_bits + termios.tcsetattr(self.write_file.fileno(), termios.TCSAFLUSH, attrs) + tty.setraw(self.write_file.fileno()) # enable raw mode + attrs = termios.tcgetattr(self.write_file.fileno()) + attrs[CC][termios.VMIN] = 1 # minimim of 1 char + attrs[CC][termios.VTIME] = 1 # wait no longer than 1/10 + termios.tcsetattr(self.write_file.fileno(), termios.TCSAFLUSH, attrs) + + def __del__(self): + termios.tcsetattr(self.write_file.fileno(), termios.TCSAFLUSH, self.old_attrs) + self.read_file.close() + self.write_file.close() + + def read(self, n): + """Read at most n bytes from tty""" + return self.read_file.read(n) + + def write(self, str): + """Write str to tty.""" + return self.write_file.write(str) + + +def hexnibble(i): + return "0123456789abcdef"[i & 0xf] + +def build_pkt(payload): + s = ['$'] + checksum = 0 + + for p in payload: + if p in ('$', '#', GDB_ESCAPE): + s.append(GDB_ESCAPE) + s.append(p) + checksum += ord(p) + + checksum &= 0xff + s.append('#') + s.append(hexnibble(checksum >> 4)) + s.append(hexnibble(checksum)) + + return ''.join(s) + + +def build_memory_read_pkt(addr, len): + return build_pkt(('m%x,%x' % (addr, len))) + +def build_memory_write_hex_pkt(addr, s): + hexdata = ''.join(["%02x" % (ord(c),) for c in s]) + return build_pkt(('M%x,%x:' % (addr, len(s))) + hexdata) + +def build_memory_write_pkt(addr, s): + return build_pkt(('X%x,%x:' % (addr, len(s))) + s) + +def build_goto_pkt(addr): + return build_pkt(('c%x' % (addr,))) + + +def get_packet(f): + """Return a valid packet, or None on EOF or timeout""" + LOOKING_FOR_DOLLAR = 0 + LOOKING_FOR_HASH = 1 + CSUM1 = 2 + CSUM2 = 3 + + fd = f.fileno() + + state = LOOKING_FOR_DOLLAR + buf = [] + + while True: + ch = os.read(fd, 1) + sys.stdout.write(ch) + if len(ch) == 0: + print("Returning None") + return(None) + + if state == LOOKING_FOR_DOLLAR: + if ch == '$': + buf = [] + state = LOOKING_FOR_HASH + elif ch == '#': + state = LOOKING_FOR_DOLLAR + + elif state == LOOKING_FOR_HASH: + if ch == '$': + state = LOOKING_FOR_DOLLAR + elif ch == '#': + state = CSUM1 + else: + if ch == GDB_ESCAPE: + ch = getc() + buf.append(ch) + + elif state == CSUM1: + chksum1 = ch + state = CSUM2 + + elif state == CSUM2: + chksum2 = ch + r = ''.join(buf) + if chksum1 == '.' and chksum2 == '.': + return r + + expected_checksum = int(chksum1 + chksum2, 16) + checksum = 0 + for c in buf: + checksum += ord(c) + + checksum &= 0xff + if checksum == expected_checksum: + return r + + state = LOOKING_FOR_DOLLAR + + else: + raise ValueError( "Invalid state") + + +class packet_reader_thread(threading.Thread): + def __init__(self, tty_in, q): + threading.Thread.__init__(self) + self.setDaemon(1) + self.tty_in = tty_in + self.q = q + self._keep_running = True + self.start() + + def run(self): + while self._keep_running == True: + p = get_packet(self.tty_in) + if p is not None: + self.q.put(('pkt', p)) + + +def _make_tr_table(): + table = [] + for c in range(256): + if c < ord(' ') or c > ord('~'): + table.append('.') + else: + table.append(chr(c)) + return ''.join(table) + + +class controller(object): + def __init__(self, tty): + self.tty = tty + self.q = Queue.Queue(0) + self.timers = {} + self.next_tid = 1 + self.current_tid = 0 + self.ntimeouts = 0 + self.packet_reader = packet_reader_thread(tty.read_file, self.q) + self.state = None + self.debug = False + self.tt = _make_tr_table() + + self.done = False + self.addr = None + self.bits = None + + def shutdown(self): + self.packet_reader._keep_running = False + + def start_timeout(self, timeout_in_secs): + def callback(tid): + if self.timers.has_key(tid): + del self.timers[tid] + self.q.put(('timeout', tid)) + self.next_tid += 1 + tid = self.next_tid + timer = threading.Timer(timeout_in_secs, callback, (tid,)) + self.timers[tid] = timer + timer.start() + return tid + + def cancel_timeout(self, tid): + if self.timers.has_key(tid): + self.timers[tid].cancel() + del self.timers[tid] + + def send_packet(self, pkt): + if self.debug: + if len(pkt) > 64: + s = pkt[0:64] + '...' + else: + s = pkt + sys.stdout.write('-> ' + s.translate(self.tt) + '\n') + self.tty.write(pkt); + + def send_packet_start_timeout(self, pkt, secs): + self.send_packet(pkt) + self.current_tid = self.start_timeout(secs) + + def upload_code(self, sbf): + MAX_PIECE = 512 # biggest piece to send + MWRITE_TIMEOUT = 0.1 + + IDLE = 0 + WAIT_FOR_ACK = 1 + UPLOAD_DONE = 2 + DONE = 3 + FAILED = 4 + + self.done = False + it = sbf.iterator(MAX_PIECE) + entry_addr = sbf.entry + + def get_next_bits(): + try: + (self.addr, self.bits) = it.next() + except StopIteration: + self.done = True + + def is_done(): + return self.done + + def send_piece(): + pkt = build_memory_write_pkt(self.addr, self.bits) + #pkt = build_memory_write_hex_pkt(self.addr, self.bits) + self.send_packet_start_timeout(pkt, MWRITE_TIMEOUT) + state = WAIT_FOR_ACK + + def advance(): + get_next_bits() + if is_done(): + self.state = DONE + self.send_packet(build_goto_pkt(entry_addr)) + + else: + self.ntimeouts = 0 + send_piece() + + get_next_bits() + if is_done(): # empty file + return True + + send_piece() # initial transition + + while 1: + (event, value) = self.q.get() + + if event == 'timeout' and value == self.current_tid: + self.ntimeouts += 1 + if self.ntimeouts >= 5: + return False # say we failed + send_piece() # resend + + + elif event == 'pkt': + if value == 'OK': + self.cancel_timeout(self.current_tid) + advance() + if self.state == DONE: + return True + else: + print("Error returned from firmware: " + value) + return False + + else: + print("Unknown event:", (event, value)) + +def main(): + usage="%prog: [options] filename" + parser = OptionParser(usage=usage) + parser.add_option("-t", "--tty", type="string", default="/dev/ttyS0", + help="select serial port [default=%default]") + + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + raise SystemExit(1) + + + filename = args[0] + f = open(filename, "rb") + try: + # Try to open the file as an SBF file + sbf_header = sbf.read_sbf(f) + except: + # If that fails, build an SBF from the binary, assuming default + # load address and entry point + f.seek(0) + t = f.read() + if t.startswith('\177ELF'): + sys.stderr.write("Can't load an ELF file. Please use an SBF file instead.\n") + raise SystemExit( 1) + sbf_header = sbf.header(0x8000, [sbf.sec_desc(0x8000, t)]) + + + tty = terminal(options.tty, termios.B115200) + ctrl = controller(tty) + ok = ctrl.upload_code(sbf_header) + + if ok: + print("OK") + try: + raw_input("Press Enter to exit: ") + except KeyboardInterrupt: + pass + ctrl.shutdown() + time.sleep(0.2) + + else: + print("Upload failed") + ctrl.shutdown() + + + +if __name__ == "__main__": + main() diff --git a/firmware/microblaze/bin/uart_ihex_flash_loader.py b/firmware/microblaze/bin/uart_ihex_flash_loader.py new file mode 100755 index 000000000..5a3300f34 --- /dev/null +++ b/firmware/microblaze/bin/uart_ihex_flash_loader.py @@ -0,0 +1,138 @@ +#!/usr/bin/python + +import serial +from optparse import OptionParser +import os, sys + +#TODO: pull everything but parser out of main() and put it in a separate function we can call from another script. lets us automate loading RAM+FLASH to produce a fully-loaded image. +#TODO: make it fail gracefully -- if it gets a NOK or times out, do at least one retry. +#TODO: put hooks in (eventually) to allow verifying a firmware image so the user can more safely update the "safe" image +#TODO: how about a progress indicator? FPGA images take FOREVER. you can use wc -l to get the number of lines, or do it with file i/o. + +def main(): + usage="%prog: [options] filename" + parser = OptionParser(usage=usage) + parser.add_option("-t", "--tty", type="string", default="/dev/ttyUSB0", + help="select serial port [default=%default]") + parser.add_option("-b", "--baudrate", type=int, default=115200, + help="set baudrate [default=%default]") + parser.add_option("-F", "--write-safe-firmware", action="store_const", const=1, dest="image", + help="write to safe firmware image") + parser.add_option("-f", "--write-production-firmware", action="store_const", const=2, dest="image", + help="write to production firmware image") + parser.add_option("-P", "--write-safe-fpga", action="store_const", const=3, dest="image", + help="write to safe FPGA image") + parser.add_option("-p", "--write-production-fpga", action="store_const", const=4, dest="image", + help="write to production FPGA image") + + (options, args) = parser.parse_args() + + if(options.image is None): + print("At least one of -f, -F, -p, -P must be specified.\n") + parser.print_help() + raise SystemExit(1) + + if len(args) != 1: + parser.print_help() + raise SystemExit(1) + + if(options.image == 3): + print "Are you *really* sure you want to write to the failsafe FPGA image? If you mess this up your USRP2+ will become a brick. Press 'y' to continue, any other key to abort." + if(raw_input().rstrip() is not "y"): + print "Good choice." + raise SystemExit(0) + + elif(options.image == 1): + print "Are you *really* sure you want to write to the failsafe firmware image? If you mess this up your USRP2+ will only be able to be reprogrammed via the UART RAM loader.\nPress 'y' to continue, any other key to abort." + if(raw_input().rstrip() is not "y"): + print "Good choice." + raise SystemExit(0) + + filename = args[0] + f = open(filename, "r") + + #now we start doing things... + if(os.path.exists(options.tty) is False): + sys.stderr.write("No serial port found at %s\n" % options.tty) + raise SystemExit(1) + + try: + ser = serial.Serial(port=options.tty, timeout=1, baudrate=options.baudrate, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, rtscts=0, xonxoff=0) + except serial.SerialException: + sys.stderr.write("Unable to open serial port\n") + raise SystemExit(1) + + ser.open() + +#test to see if a valid USRP2+ in flash load mode is connected + ser.write("garbage\n") + ser.readline() + ser.write("!SECTORSIZE\n") + reply = ser.readline().rstrip() + if("NOK" in reply): + sys.stderr.write("Error writing to USRP2+. Try again.\n") + raise SystemExit(1) + elif("OK" in reply): + sectorsize = int(reply[3:5], 16) + print("USRP2+ found with sector size %i. Erasing old image." % 2**sectorsize) + else: + sys.stderr.write("Invalid response or no USRP2+ connected.\n") + raise SystemExit(1) + + if(options.image == 1): + sectors = range(127, 128) + runcmd = "!RUNSFD\n" + elif(options.image == 2): + sectors = range(64, 65) + runcmd = "!RUNPFD\n" + elif(options.image == 3): + sectors = range(0,32) + runcmd = "!RUNSFPGA\n" + elif(options.image == 4): + sectors = range(32,64) + runcmd = "!RUNPFPGA\n" + + writeaddr = sectors[0] << sectorsize + if(options.image < 3): + writeaddr -= 0x8000 #i know this is awkward, but we subtract 0x8000 from the address for firmware loads. the reason we do this is that the IHX files are located at 0x8000 (RAM_BASE), and + #doing this here allows us to use the same IHX files for RAM load as for Flash load, without relocating in objcopy or relinking with another ld script. + #this limits us to writing above 32K for our firmware images. since the safe FPGA image located at 0x00000000 takes up 2MB of space this isn't really a worry. + #FPGA images (.mcs) always start at 0x00000000 so they don't need this relocation. + + for sector in sectors: + print "Erasing sector %i" % sector + ser.write("!ERASE %i\n" % sector) + reply = ser.readline() + if("NOK" in reply): + sys.stderr.write("Error erasing sector %i" % sector) + raise SystemExit(1) + + print "Setting start address to %i" % writeaddr + ser.write("!SETADDR %i\n" % writeaddr) + if("NOK" in reply): + sys.stderr.write("Error setting address\n") + raise SystemExit(1) + else: + print reply + + + for line in f: + ser.write(line.rstrip()+'\n') + reply = ser.readline() + if("NOK" in reply): #TODO: simplify this logic, use (reply.rstrip() is "NOK") + print("Received NOK reply during data write") + raise SystemExit(1) + elif("DONE" in reply): + print("Finished writing program. Loading...\n") + ser.write(runcmd) + elif("OK" not in reply): + print("Received invalid reply %s during data write" % reply) + raise SystemExit(1) + else: + print reply.rstrip() + '\t' + line.rstrip() + + print ser.readline() + + +if __name__ == '__main__': + main() diff --git a/firmware/microblaze/bin/uart_ihex_ram_loader.py b/firmware/microblaze/bin/uart_ihex_ram_loader.py new file mode 100755 index 000000000..c90fbe1d8 --- /dev/null +++ b/firmware/microblaze/bin/uart_ihex_ram_loader.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +import serial +from optparse import OptionParser +import os, sys + +def main(): + usage="%prog: [options] filename" + parser = OptionParser(usage=usage) + parser.add_option("-t", "--tty", type="string", default="/dev/ttyUSB0", + help="select serial port [default=%default]") + parser.add_option("-b", "--baudrate", type=int, default=115200, + help="set baudrate [default=%default]") + + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + raise SystemExit(1) + + filename = args[0] + f = open(filename, "r") + + #all we have to do is load the IHX file and attempt to spit it out to the serial port. + if(os.path.exists(options.tty) is False): + sys.stderr.write("No serial port found at %s\n" % options.tty) + raise SystemExit(1) + + try: + ser = serial.Serial(port=options.tty, timeout=1, baudrate=options.baudrate, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, rtscts=0, xonxoff=0) + except serial.SerialException: + sys.stderr.write("Unable to open serial port\n") + raise SystemExit(1) + + ser.open() + +#test to see if a valid USRP2+ in RAM load mode is connected + + ser.write("WOOOOO\n"); + reply = ser.readline() + if("NOK" not in reply): + sys.stderr.write("Valid USRP2+ not connected or no response received\n") + raise SystemExit(1) + else: + print("USRP2+ found.") + + for line in f: + ser.write(line.rstrip() + '\n') + reply = ser.readline() + if("NOK" in reply): #blocks to wait for response + print("Received NOK reply from USRP2+") + raise SystemExit(1) + elif("OK" not in reply): + print("Received invalid reply!") + raise SystemExit(1) +# else: +# print("OK received") + + print "USRP2+ RAM programmed.\nLoading program." + + #at this point it should have sent the end line of the file, which starts the program! + #we'll just act like a dumb terminal now +# ser.timeout = 0 +# try: +# while 1: +# print ser.readline() +# except KeyboardInterrupt: +# raise SystemExit(0) + +if __name__ == '__main__': + main() diff --git a/firmware/microblaze/bootstrap b/firmware/microblaze/bootstrap index 5786c1624..26987b0ec 100755 --- a/firmware/microblaze/bootstrap +++ b/firmware/microblaze/bootstrap @@ -18,6 +18,7 @@ rm -rf *.cache rm -rf libusrp2/.deps +rm -rf libusrp2p/.deps aclocal autoconf diff --git a/firmware/microblaze/configure.ac b/firmware/microblaze/configure.ac index e27bcb557..f6986f2dd 100644 --- a/firmware/microblaze/configure.ac +++ b/firmware/microblaze/configure.ac @@ -47,6 +47,8 @@ AC_PATH_PROG([HEXDUMP], [hexdump]) ################################################## AC_CONFIG_FILES([ \ Makefile \ + usrp2p/bootloader/Makefile \ usrp2/Makefile \ + usrp2p/Makefile \ ]) AC_OUTPUT diff --git a/firmware/microblaze/lib/Makefile.inc b/firmware/microblaze/lib/Makefile.inc index 2b5685d3f..38c630df4 100644 --- a/firmware/microblaze/lib/Makefile.inc +++ b/firmware/microblaze/lib/Makefile.inc @@ -33,6 +33,7 @@ COMMON_SRCS = \ $(top_srcdir)/lib/hal_io.c \ $(top_srcdir)/lib/hal_uart.c \ $(top_srcdir)/lib/i2c.c \ + $(top_srcdir)/lib/i2c_async.c \ $(top_srcdir)/lib/mdelay.c \ $(top_srcdir)/lib/memcpy_wa.c \ $(top_srcdir)/lib/memset_wa.c \ @@ -42,6 +43,7 @@ COMMON_SRCS = \ $(top_srcdir)/lib/print_rmon_regs.c \ $(top_srcdir)/lib/print_buffer.c \ $(top_srcdir)/lib/printf.c \ + $(top_srcdir)/lib/ihex.c \ $(top_srcdir)/lib/spi.c \ $(top_srcdir)/lib/net_common.c \ $(top_srcdir)/lib/arp_cache.c \ diff --git a/firmware/microblaze/lib/bootconfig.c b/firmware/microblaze/lib/bootconfig.c new file mode 100644 index 000000000..93adc05c2 --- /dev/null +++ b/firmware/microblaze/lib/bootconfig.c @@ -0,0 +1,101 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "bootconfig.h" +#include "bootconfig_private.h" +#include <stdint.h> +#include <stddef.h> +#include <i2c.h> +#include <quadradio/i2c_addr.h> +#include <mdelay.h> +#include <xilinx_v5_icap.h> +#include <nonstdio.h> + +eeprom_boot_info_t eeprom_shadow; + +static eeprom_boot_info_t eeprom_default = { + .magic = EEPROM_BOOT_INFO_MAGIC, + .nattempts = 1, + .next_boot.fpga_image_number = 0, + .next_boot.firmware_image_number = 0, + .default_boot.fpga_image_number = 0, + .default_boot.firmware_image_number = 0 +}; + +eeprom_boot_info_t * +_bc_get_eeprom_shadow(void) +{ + return &eeprom_shadow; +} + + +bool +_bc_write_eeprom_shadow(void) +{ + return eeprom_write(I2C_ADDR_MBOARD, BOOT_INFO_OFFSET, &eeprom_shadow, sizeof(eeprom_shadow)); +} + +void +bootconfig_init(void) +{ + if (!eeprom_read(I2C_ADDR_MBOARD, BOOT_INFO_OFFSET, &eeprom_shadow, sizeof(eeprom_shadow)) + || eeprom_shadow.magic != EEPROM_BOOT_INFO_MAGIC){ + eeprom_shadow = eeprom_default; + _bc_write_eeprom_shadow(); + } +} + +bootconfig_t +bootconfig_get_default(void) +{ + return eeprom_shadow.default_boot; +} + +bool +bootconfig_set_default(bootconfig_t bc) +{ + if (!validate_bootconfig(bc)) + return false; + + eeprom_shadow.default_boot = bc; + eeprom_shadow.next_boot = bc; + return _bc_write_eeprom_shadow(); +} + +void +bootconfig_boot(bootconfig_t bc) +{ + if (!validate_bootconfig(bc)) + return; + + eeprom_shadow.next_boot = bc; + eeprom_shadow.nattempts = 1; + _bc_write_eeprom_shadow(); + + if (1){ + puts("\nbootconfig: chaining to FPGA slot 0 bootloader"); + mdelay(100); + } + + while (1){ + // Reload fpga with code from SPI flash address 0x0. + icap_reload_fpga(0x00000000); + } +} diff --git a/firmware/microblaze/lib/eeprom.c b/firmware/microblaze/lib/eeprom.c index b12ffe082..d4e170046 100644 --- a/firmware/microblaze/lib/eeprom.c +++ b/firmware/microblaze/lib/eeprom.c @@ -17,9 +17,21 @@ #include "i2c.h" #include "mdelay.h" +#include "usrp2/fw_common.h" static const int EEPROM_PAGESIZE = 16; +bool find_safe_booted_flag(void) { + unsigned char flag_byte; + eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_BOOTLOADER_FLAGS, &flag_byte, 1); + return (flag_byte == 0x5E); +} + +void set_safe_booted_flag(bool flag) { + unsigned char flag_byte = flag ? 0x5E : 0xDC; + eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_BOOTLOADER_FLAGS, &flag_byte, 1); +} + bool eeprom_write (int i2c_addr, int eeprom_offset, const void *buf, int len) { diff --git a/firmware/microblaze/lib/eth_addrs.c b/firmware/microblaze/lib/eth_addrs.c index c6320e4fa..ff5d04f4d 100644 --- a/firmware/microblaze/lib/eth_addrs.c +++ b/firmware/microblaze/lib/eth_addrs.c @@ -46,9 +46,20 @@ unprogrammed(const void *t, size_t len) //////////////////// MAC Addr Stuff /////////////////////// static int8_t src_mac_addr_initialized = false; + +static const eth_mac_addr_t default_mac_addr = {{ + 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff + }}; + static eth_mac_addr_t src_mac_addr = {{ 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff }}; + +void set_default_mac_addr(void) +{ + src_mac_addr_initialized = true; + src_mac_addr = default_mac_addr; +} const eth_mac_addr_t * ethernet_mac_addr(void) @@ -88,10 +99,20 @@ ethernet_set_mac_addr(const eth_mac_addr_t *t) //////////////////// IP Addr Stuff /////////////////////// static int8_t src_ip_addr_initialized = false; + +static const struct ip_addr default_ip_addr = { + (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0) +}; + static struct ip_addr src_ip_addr = { (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0) }; +void set_default_ip_addr(void) +{ + src_ip_addr_initialized = true; + src_ip_addr = default_ip_addr; +} const struct ip_addr *get_ip_addr(void) { diff --git a/firmware/microblaze/lib/ethernet.h b/firmware/microblaze/lib/ethernet.h index 8c6d8b567..52b297349 100644 --- a/firmware/microblaze/lib/ethernet.h +++ b/firmware/microblaze/lib/ethernet.h @@ -44,6 +44,9 @@ void ethernet_register_link_changed_callback(ethernet_link_changed_callback_t cb */ const eth_mac_addr_t *ethernet_mac_addr(void); +/*!set mac addr to default*/ +void set_default_mac_addr(void); + /*! * \brief write mac address to eeprom and begin using it */ @@ -54,6 +57,9 @@ bool ethernet_set_mac_addr(const eth_mac_addr_t *t); */ const struct ip_addr *get_ip_addr(void); +/*!set ip addr to default*/ +void set_default_ip_addr(void); + /*! * \brief write ip address to eeprom and begin using it */ diff --git a/firmware/microblaze/lib/gdbstub2.c b/firmware/microblaze/lib/gdbstub2.c new file mode 100644 index 000000000..4c63dfce2 --- /dev/null +++ b/firmware/microblaze/lib/gdbstub2.c @@ -0,0 +1,506 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Implement a eensy weensy part of the GDB Remote Serial Protocol + * + * See Appendix D of the GDB manual + * + * m<addr>,<length> -- read <length> bytes of memory starting at <addr> + * Reply: + * XX... XX... is memory contents in hex + * ENN ENN NN is a hex error number + * + * M<addr>,<length>:XX... -- write memory, data in hex + * Reply: + * OK for success + * ENN for an error. NN is a hex error number + * + * X<addr>,<length>:XX... -- write memory, data in binary + * Reply: + * OK for success + * ENN for an error. NN is a hex error number + * + * c<addr> -- continue. <addr> is the address to resume (goto). + * Reply: <none> + * + * \x80 New Format... + */ + +#include "gdbstub2.h" +#include "loader_parser.h" +#include "hal_uart.h" +#include <stdbool.h> +#include <stddef.h> + +#define MAX_PACKET 1024 + +/* + * Get raw character from serial port, no echo. + */ +static inline int +gdb_getc(void) +{ + return hal_uart_getc(); +} + +/* + * Put character to serial port. Raw output. + */ +static inline void +gdb_putc(int ch) +{ + hal_uart_putc(ch); +} + +// ------------------------------------------------------------------------ + +#define GDB_ESCAPE 0x7d + +static unsigned char hex_table[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + +static int +put_hex8_checksum(int ch, int checksum) +{ + unsigned char t = hex_table[(ch >> 4) & 0xf]; + checksum += t; + gdb_putc(t); + + t = hex_table[ch & 0xf]; + checksum += t; + gdb_putc(t); + return checksum; +} + +static void +put_hex8(int ch) +{ + put_hex8_checksum(ch, 0); +} + +static bool +hex4_to_bin(int ch, int *value) +{ + if ('0' <= ch && ch <= '9'){ + *value = ch - '0'; + return true; + } + if ('a' <= ch && ch <= 'f'){ + *value = ch - 'a' + 10; + return true; + } + if ('A' <= ch && ch <= 'F'){ + *value = ch - 'A' + 10; + return true; + } + *value = 0; + return false; +} + +static bool +hex8_to_bin(const unsigned char *s, int *value) +{ + int v0, v1; + if (hex4_to_bin(s[0], &v0) && hex4_to_bin(s[1], &v1)){ + *value = (v0 << 4) | v1; + return true; + } + return false; +} + +static bool +hex_to_bin_array(unsigned char *binary_data, const unsigned char *hex_data, size_t nbytes) +{ + for (size_t i = 0; i < nbytes; i++){ + int t; + if (!hex8_to_bin(&hex_data[2*i], &t)) + return false; + binary_data[i] = t; + } + return true; +} + +static bool +needs_escaping(int ch) +{ + return ch == '$' || ch == '#' || ch == GDB_ESCAPE; +} + +/* + * \brief Wait for a packet. + * \param[out] pkt_buf gets the received packet payload. + * \param[in] max_size is the maximum number of bytes to write into \p pkt_buf. + * \param[out] actual_size is the number of bytes written to \p pkt_buf. + * + * \returns true iff the payload fits and the checksum is OK. + * + * Packets have this format: + * + * $<packet-data>#<checksum> + * + * Where <packet-data> is anything and <checksum> is a two byte hex + * checksum. In <packet-data> '$', '#' and 0x7d are escaped with 0x7d. + * The checksum is computed as the modulo 256 sum of all characters + * btween the leading '$' and the trailing '#' (an 8-bit unsigned + * checksum). + */ +static bool +get_packet(unsigned char *pkt_buf, size_t max_size, size_t *actual_size) +{ + typedef enum states { + LOOKING_FOR_DOLLAR, + LOOKING_FOR_HASH, + CSUM1, + CSUM2, + } state_t; + + *actual_size = 0; + unsigned char csum[2] = {0, 0}; + state_t state = LOOKING_FOR_DOLLAR; + size_t pi = 0; + + while (1){ + int ch = gdb_getc(); + + switch (state){ + case LOOKING_FOR_DOLLAR: + if (ch == '$'){ + pi = 0; + state = LOOKING_FOR_HASH; + } + else if (ch == '#'){ // most likely missed the $ + return false; + } + break; + + case LOOKING_FOR_HASH: + if (ch == '$'){ + return false; + } + else if (ch == '#'){ + state = CSUM1; + } + else { + if (pi >= max_size) // payload too big + return false; + + if (ch == GDB_ESCAPE) + ch = gdb_getc(); + + pkt_buf[pi++] = ch; + } + break; + + case CSUM1: + csum[0] = ch; + state = CSUM2; + break; + + case CSUM2: + csum[1] = ch; + *actual_size = pi; + + // accept .. as a correct checksum + if (csum[0] == '.' && csum[1] == '.') + return true; + + int expected_checksum; + if (!hex8_to_bin(csum, &expected_checksum)) + return false; + + int checksum = 0; + for (size_t i = 0; i < pi; i++) + checksum += pkt_buf[i]; + + checksum &= 0xff; + return checksum == expected_checksum; + } + } +} + +static void +put_packet_trailer(int checksum) +{ + gdb_putc('#'); + put_hex8(checksum & 0xff); + gdb_putc('\r'); + gdb_putc('\n'); +} + +static void +put_packet(const unsigned char *pkt_buf, size_t size) +{ + gdb_putc('$'); + + int checksum = 0; + for (size_t i = 0; i < size; i++){ + int ch = pkt_buf[i]; + if (needs_escaping(ch)) + gdb_putc(GDB_ESCAPE); + gdb_putc(ch); + checksum += ch; + } + put_packet_trailer(checksum); +} + +/*! + * Read a hex number + * + * \param[inout] bufptr - pointer to pointer to buffer (updated on return) + * \param[in] end - one past end of valid data in buf + * \param[out] value - the parsed value + * + * \returns true iff a valid hex number was read from bufptr + */ +static bool +parse_number(const unsigned char **bufptr, const unsigned char *end, unsigned int *value) +{ + const unsigned char *buf = *bufptr; + unsigned int v = 0; + bool valid = false; + int nibble; + + while (buf < end && hex4_to_bin(*buf, &nibble)){ + valid = true; + v = (v << 4) | nibble; + buf++; + } + + *value = v; + *bufptr = buf; + return valid; +} + +static bool +parse_char(const unsigned char **bufptr, const unsigned char *end, unsigned char *ch) +{ + const unsigned char *buf = *bufptr; + if (buf < end){ + *ch = *buf++; + *bufptr = buf; + return true; + } + return false; +} + +static bool +expect_char(const unsigned char **bufptr, const unsigned char *end, unsigned char expected) +{ + unsigned char ch; + return parse_char(bufptr, end, &ch) && ch == expected; +} + +static bool +expect_end(const unsigned char **bufptr, const unsigned char *end) +{ + return *bufptr == end; +} + +static bool +parse_addr_length(const unsigned char **bufptr, const unsigned char *end, + unsigned int *addr, unsigned int *length) +{ + return (parse_number(bufptr, end, addr) + && expect_char(bufptr, end, ',') + && parse_number(bufptr, end, length)); +} + +static void +put_error(int error) +{ + unsigned char buf[3]; + buf[0] = 'E'; + buf[1] = hex_table[(error >> 4) & 0xf]; + buf[2] = hex_table[error & 0xf]; + + put_packet(buf, sizeof(buf)); +} + +static void +put_ok(void) +{ + const unsigned char buf[2] = "OK"; + put_packet(buf, sizeof(buf)); +} + +/* + * Read memory and send the reply. + * We do it on the fly so that our packet size is effectively unlimited + */ +static void +read_memory(unsigned int addr, unsigned int nbytes) +{ + int checksum = 0; + gdb_putc('$'); + + if ((addr & 0x3) == 0 && (nbytes & 0x3) == 0){ // word aligned + union { + unsigned int i; + unsigned char c[4]; + } u; + + unsigned int *p = (unsigned int *) addr; + unsigned int length = nbytes / 4; + + for (unsigned int i = 0; i < length; i++){ + u.i = p[i]; // do a word read + checksum = put_hex8_checksum(u.c[0], checksum); + checksum = put_hex8_checksum(u.c[1], checksum); + checksum = put_hex8_checksum(u.c[2], checksum); + checksum = put_hex8_checksum(u.c[3], checksum); + } + } + else { // byte aligned + unsigned char *p = (unsigned char *) addr; + for (unsigned int i = 0; i < nbytes; i++) + checksum = put_hex8_checksum(p[i], checksum); + } + + put_packet_trailer(checksum); +} + +static unsigned int +get_unaligned_int(const unsigned char *p) +{ + // we're bigendian + return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]); +} + +static bool +write_memory(unsigned int addr, size_t nbytes, + const unsigned char *data) +{ + if ((addr & 0x3) == 0 && (nbytes & 0x3) == 0){ // word-aligned dst + unsigned int *dst = (unsigned int *) addr; + size_t length = nbytes / 4; + for (size_t i = 0; i < length; i++){ + unsigned int t = get_unaligned_int(&data[4*i]); + dst[i] = t; // word writes + } + } + else { // non-word-aligned dst + unsigned char *dst = (unsigned char *) addr; + for (size_t i = 0; i < nbytes; i++){ + dst[i] = data[i]; + } + } + return true; +} + +void +gdbstub2_main_loop(void) +{ + unsigned char inpkt[MAX_PACKET + 24]; + unsigned char binary_data[MAX_PACKET/2] __attribute__((aligned (4))); + + hal_uart_set_mode(UART_MODE_RAW); //tell UART HAL not to map \n to \r\n + + while (1){ + size_t inpkt_len; + bool ok = get_packet(inpkt, sizeof(inpkt), &inpkt_len); + if (!ok){ + gdb_putc('-'); + continue; + } + gdb_putc('+'); + + const unsigned char *buf = inpkt; + const unsigned char *end = inpkt + inpkt_len; + unsigned char ch; + + if (!parse_char(&buf, end, &ch)){ // empty packet + put_packet(0, 0); + continue; + } + + unsigned int addr; + unsigned int length; + + switch(ch){ + case 'm': // m<addr>,<length> -- read <length> bytes starting at <addr> + if (!(parse_addr_length(&buf, end, &addr, &length) && expect_end(&buf, end))){ + put_error(1); + } + else { + read_memory(addr, length); + } + break; + + case 'M': // M<addr>,<length>:XX... -- write <length> bytes starting at <addr> + // XX... is the data in hex + if (!(parse_addr_length(&buf, end, &addr, &length) + && expect_char(&buf, end, ':') + && (end - buf) == 2 * length)){ + put_error(1); + } + else { + if (!hex_to_bin_array(binary_data, buf, length)) + put_error(2); + else if (!write_memory(addr, length, binary_data)) + put_error(3); + else + put_ok(); + } + break; + + case 'X': // X<addr>,<length>:XX... -- write <length> bytes starting at <addr> + // XX... is the data in binary + if (!(parse_addr_length(&buf, end, &addr, &length) + && expect_char(&buf, end, ':') + && (end - buf) == length)){ + put_error(1); + } + else { + if (!write_memory(addr, length, buf)) + put_error(3); + else + put_ok(); + } + break; + + case 'c': // c<addr> -- continue. <addr> is the address to resume (goto). + if (!(parse_number(&buf, end, &addr) + && expect_end(&buf, end))){ + put_error(1); + } + else { + typedef void (*fptr_t)(void); + (*(fptr_t) addr)(); // most likely no return + } + break; +/* + case 0x80: + { + unsigned char *output = binary_data; // reuse + size_t sizeof_output = sizeof(binary_data); + size_t actual_olen; + loader_parser(buf, end-buf, + output, sizeof_output, &actual_olen); + put_packet(output, actual_olen); + } + break; +*/ + default: // unknown packet type + put_packet(0, 0); + break; + } + } +} diff --git a/firmware/microblaze/lib/gdbstub2.h b/firmware/microblaze/lib/gdbstub2.h new file mode 100644 index 000000000..15cdde939 --- /dev/null +++ b/firmware/microblaze/lib/gdbstub2.h @@ -0,0 +1,25 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INCLUDED_GDBSTUB_H +#define INCLUDED_GDBSTUB_H + +void gdbstub2_main_loop(void); + +#endif /* INCLUDED_GDBSTUB_H */ + diff --git a/firmware/microblaze/lib/hal_io.c b/firmware/microblaze/lib/hal_io.c index 58b1e681e..be4c570c7 100644 --- a/firmware/microblaze/lib/hal_io.c +++ b/firmware/microblaze/lib/hal_io.c @@ -18,9 +18,9 @@ // conditionalized on HAL_IO_USES_DBOARD_PINS && HAL_IO_USES_UART -#include "hal_io.h" #include "memory_map.h" #include "hal_uart.h" +#include "hal_io.h" #include <stdbool.h> #include <stdio.h> #include <string.h> @@ -124,16 +124,29 @@ hal_finish(void) // %c inline int +fputchar(hal_uart_name_t u, int ch) +{ + hal_uart_putc(u, ch); + return ch; +} + +inline int putchar(int ch) { - hal_uart_putc(ch); + hal_uart_putc(DEFAULT_UART, ch); return ch; } int +fgetchar(hal_uart_name_t u) +{ + return hal_uart_getc(u); +} + +int getchar(void) { - return hal_uart_getc(); + return fgetchar(DEFAULT_UART); } #else // nop all i/o @@ -172,34 +185,87 @@ getchar(void) // \n inline void +fnewline(hal_uart_name_t u) +{ + fputchar(u, '\n'); +} + +inline void newline(void) { - putchar('\n'); + fnewline(DEFAULT_UART); } int -putstr(const char *s) +fputstr(hal_uart_name_t u, const char *s) { while (*s) - putchar(*s++); + fputchar(u, *s++); return 0; } int -puts(const char *s) +fnputstr(hal_uart_name_t u, const char *s, int len) +{ + int x = 0; + while (*s && (len > x++)) + fputchar(u, *s++); + + return x; +} + +int +putstr(const char *s) { - putstr(s); - putchar('\n'); + return fputstr(DEFAULT_UART, s); +} + +int +fputs(hal_uart_name_t u, const char *s) +{ + fputstr(u, s); + fputchar(u, '\n'); return 0; } +int puts(const char *s) +{ + return fputs(DEFAULT_UART, s); +} + +char * +fgets(hal_uart_name_t u, char * const s) +{ + char *x = s; + while((*x=(char)hal_uart_getc(u)) != '\n') x++; + *x = 0; + return s; +} + +int +fngets(hal_uart_name_t u, char * const s, int len) +{ + char *x = s; + while(((*x=(char)hal_uart_getc(u)) != '\n') && ((x-s) < len)) x++; + *x = 0; + return (x-s); +} + +int +fngets_timeout(hal_uart_name_t u, char * const s, int len) +{ + char *x = s; + + while(((*x=(char)hal_uart_getc_timeout(u)) != '\n') && (*x != -1) && ((x-s) < len)) x++; + *x = 0; + //printf("Returning from fngets() with string %d of length %d\n", s[0], x-s); + return (x-s); +} + char * gets(char * const s) { - char *x = s; - while((*x=(char)hal_uart_getc()) != '\n') x++; - *x = 0; - return s; + return fgets(DEFAULT_UART, s); } diff --git a/firmware/microblaze/lib/hal_io.h b/firmware/microblaze/lib/hal_io.h index c67d96c62..950f8d591 100644 --- a/firmware/microblaze/lib/hal_io.h +++ b/firmware/microblaze/lib/hal_io.h @@ -20,10 +20,15 @@ #define INCLUDED_HAL_IO_H #include "memory_map.h" +#include "hal_uart.h" void hal_io_init(void); void hal_finish(); char *gets(char * const s); +int fputstr(hal_uart_name_t u, const char *s); +int fnputstr(hal_uart_name_t u, const char *s, int len); +int fngets(hal_uart_name_t u, char * const s, int len); +int fngets_timeout(hal_uart_name_t u, char * const s, int len); /* * ------------------------------------------------------------------------ diff --git a/firmware/microblaze/lib/hal_uart.c b/firmware/microblaze/lib/hal_uart.c index fe3b7515a..7836240fe 100644 --- a/firmware/microblaze/lib/hal_uart.c +++ b/firmware/microblaze/lib/hal_uart.c @@ -16,71 +16,105 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "memory_map.h" #include "hal_uart.h" #include "hal_io.h" -#include "memory_map.h" +#include "mdelay.h" -// First pass, no interrupts - -// Replaced with divisors.py which generates best divisor -//#define CALC_DIVISOR(rate) (WISHBONE_CLK_RATE / ((rate) * 16)) +//just to save you from going insane, note that firmware/FPGA UARTs [0-2] correspond to serial ports [1-3]. +//so in software, we refer to UART_DEBUG as UART0, but it transmits on pin TXD<1>. see the UART assignments in hal_uart.h. #define NSPEEDS 6 #define MAX_WB_DIV 4 +//if you're going to recalculate the divisors, it's just uart_clock_rate / baud_rate. +//uart_clock_rate is 50MHz for USRP2. static const uint16_t -divisor_table[MAX_WB_DIV+1][NSPEEDS] = { - { 2, 2, 2, 2, 2, 2}, // 0: can't happen - { 651, 326, 163, 109, 54, 27 }, // 1: 100 MHz - { 326, 163, 81, 54, 27, 14 }, // 2: 50 MHz - { 217, 109, 54, 36, 18, 9 }, // 3: 33.3333 MHz - { 163, 81, 41, 27, 14, 7 }, // 4: 25 MHz +divisor_table[NSPEEDS] = { + 5208, // 9600 + 2604, // 19200 + 1302, // 38400 + 868, // 57600 + 434, // 115200 + 217 // 230400 }; -#define u uart_regs +static char uart_mode[4] = { + [UART_DEBUG] = UART_MODE_ONLCR, + [UART_EXP] = UART_MODE_ONLCR, + [UART_GPS] = UART_MODE_ONLCR +}; -static char uart_mode = UART_MODE_ONLCR; +static char uart_speeds[4] = { + [UART_DEBUG] = US_230400, + [UART_EXP] = US_230400, + [UART_GPS] = US_115200 +}; void -hal_uart_set_mode(int mode) +hal_uart_set_mode(hal_uart_name_t uart, int mode) +{ + uart_mode[uart] = mode; +} + +void hal_uart_set_speed(hal_uart_name_t uart, hal_uart_speed_t speed) { - uart_mode = mode; + uart_regs[uart].clkdiv = divisor_table[speed]; } void hal_uart_init(void) { - hal_uart_set_mode(UART_MODE_ONLCR); - u->clkdiv = 217; // 230400 bps + for(int i = 0; i < 3; i++) { + hal_uart_set_mode(i, uart_mode[i]); + hal_uart_set_speed(i, uart_speeds[i]); + } } void -hal_uart_putc(int ch) +hal_uart_putc(hal_uart_name_t u, int ch) { - if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary - hal_uart_putc('\r'); + if ((ch == '\n') && (uart_mode[u] == UART_MODE_ONLCR)) //map \n->\r\n if necessary + hal_uart_putc(u, '\r'); - while (u->txlevel == 0) // wait for fifo to have space + while (uart_regs[u].txlevel == 0) // wait for fifo to have space ; - u->txchar = ch; + uart_regs[u].txchar = ch; } void -hal_uart_putc_nowait(int ch) +hal_uart_putc_nowait(hal_uart_name_t u, int ch) { - if (ch == '\n')// && (uart_mode == UART_MODE_ONLCR)) //map \n->\r\n if necessary - hal_uart_putc('\r'); + if ((ch == '\n') && (uart_mode[u] == UART_MODE_ONLCR)) //map \n->\r\n if necessary + hal_uart_putc(u, '\r'); - if(u->txlevel) // If fifo has space - u->txchar = ch; + if(uart_regs[u].txlevel) // If fifo has space + uart_regs[u].txchar = ch; } int -hal_uart_getc(void) +hal_uart_getc(hal_uart_name_t u) { - while ((u->rxlevel) == 0) // wait for data to be ready + while ((uart_regs[u].rxlevel) == 0) // wait for data to be ready ; - return u->rxchar; + return uart_regs[u].rxchar; } + +int +hal_uart_getc_timeout(hal_uart_name_t u) +{ + int timeout = 0; + while (((uart_regs[u].rxlevel) == 0) && (timeout++ < HAL_UART_TIMEOUT_MS)) + mdelay(1); + return (timeout >= HAL_UART_TIMEOUT_MS) ? -1 : uart_regs[u].rxchar; //return -1 if nothing there, cause fngets to quit +} + +int hal_uart_rx_flush(hal_uart_name_t u) +{ + char x; + while(uart_regs[u].rxlevel) x = uart_regs[u].rxchar; + return x; +} + diff --git a/firmware/microblaze/lib/hal_uart.h b/firmware/microblaze/lib/hal_uart.h index dfd73c323..758c8cb5e 100644 --- a/firmware/microblaze/lib/hal_uart.h +++ b/firmware/microblaze/lib/hal_uart.h @@ -25,29 +25,39 @@ #define UART_MODE_RAW 0x0000 // no mapping on input or output #define UART_MODE_ONLCR 0x0001 // map \n to \r\n on output (default) -/* - * \brief Set uart mode - */ -void hal_uart_set_mode(int flags); +#define DEFAULT_UART UART_DEBUG //which UART printf, gets, etc. use -/*! - * \brief one-time call to init - */ -void hal_uart_init(void); +#define HAL_UART_TIMEOUT_MS 300 typedef enum { - US_9600, - US_19200, - US_38400, - US_57600, - US_115200, - US_230400, + US_9600 = 0, + US_19200 = 1, + US_38400 = 2, + US_57600 = 3, + US_115200 = 4, + US_230400 = 5 } hal_uart_speed_t; typedef struct { hal_uart_speed_t speed; } hal_uart_config_t; +typedef enum { + UART_DEBUG = 0, + UART_EXP = 1, + UART_GPS = 2 +} hal_uart_name_t; + +/* + * \brief Set uart mode + */ +void hal_uart_set_mode(hal_uart_name_t uart, int flags); + +/*! + * \brief one-time call to init + */ +void hal_uart_init(void); + /*! * \brief Set uart parameters * Default is 115,200 bps, 8N1. @@ -62,17 +72,23 @@ void hal_uart_get_config(hal_uart_config_t *c); /*! * \brief Enqueue \p ch for output over serial port */ -void hal_uart_putc(int ch); +void hal_uart_putc(hal_uart_name_t u, int ch); /*! * \brief Enqueue \p ch for output over serial port, silent fail if queue is full */ -void hal_uart_putc_nowait(int ch); +void hal_uart_putc_nowait(hal_uart_name_t u, int ch); /* * \brief Blocking read of next char from serial port */ -int hal_uart_getc(void); +int hal_uart_getc(hal_uart_name_t u); + +/* + * \brief Blocking read of next char from serial port with timeout + */ +int hal_uart_getc_timeout(hal_uart_name_t u); +int hal_uart_rx_flush(hal_uart_name_t u); #endif /* INCLUDED_HAL_UART_H */ diff --git a/firmware/microblaze/lib/i2c.c b/firmware/microblaze/lib/i2c.c index 177341267..d230f462c 100644 --- a/firmware/microblaze/lib/i2c.c +++ b/firmware/microblaze/lib/i2c.c @@ -20,7 +20,6 @@ #include "memory_map.h" #include "stdint.h" #include <string.h> -#include "pic.h" #include "nonstdio.h" #define MAX_WB_DIV 4 // maximum wishbone divisor (from 100 MHz MASTER_CLK) @@ -37,18 +36,6 @@ static uint16_t prescaler_values[MAX_WB_DIV+1] = { PRESCALER(4), // 4: 25 MHz }; -//asynchronous (interrupt-driven) i2c state variables -volatile uint8_t i2c_buf[17]; //tx/rx data transfer buffer -volatile uint8_t *volatile i2c_bufptr = i2c_buf; //ptr to current position -volatile uint8_t i2c_len = 0; //length remaining in current transfer -volatile i2c_state_t i2c_state = I2C_STATE_IDLE; //current I2C transfer state -i2c_dir_t i2c_dir; //I2C transfer direction - -void (*volatile i2c_callback)(void); //function pointer to i2c callback to be called when transaction is complete - -static void i2c_irq_handler(unsigned irq); -inline void i2c_async_err(void); - void i2c_init(void) { @@ -64,8 +51,8 @@ i2c_init(void) i2c_regs->ctrl = I2C_CTRL_EN; //| I2C_CTRL_IE; // enable core - // FIXME interrupt driven? - pic_register_handler(IRQ_I2C, i2c_irq_handler); + //now this is done separately to maintain common code for async and sync + //pic_register_handler(IRQ_I2C, i2c_irq_handler); } static inline void @@ -140,163 +127,3 @@ i2c_write(unsigned char i2c_addr, const unsigned char *buf, unsigned int len) return false; } -static void i2c_irq_handler(unsigned irq) { -//i2c state machine. - - //printf("I2C irq handler\n"); - //first let's make sure nothing is f'ed up - //TODO: uncomment this error checking when we have some way to handle errors -// if(((i2c_regs->cmd_status & I2C_ST_RXACK) != 0) && i2c_dir == I2C_DIR_WRITE) { //we got a NACK and we didn't send it -// printf("\tNACK received\n"); -// i2c_async_err(); -// return; -// }// else printf("\tACK received, proceeding\n"); - - if(i2c_regs->cmd_status & I2C_ST_AL) { - printf("\tArbitration lost!\n"); - i2c_async_err(); - return; - } - - if(i2c_regs->cmd_status & I2C_ST_TIP) { - //printf("\tI2C still busy in interrupt\n"); - return; - } - - //now decide what to do - switch(i2c_state) { - - case I2C_STATE_IDLE: - //this is an error. in idle state, we shouldn't be transferring data, and the fact that the IRQ fired is terrible bad. - printf("AAAAAHHHHH INTERRUPT IN THE IDLE STATE AAAHHHHHHHHH\n"); - i2c_async_err(); - break; - - case I2C_STATE_CONTROL_BYTE_SENT: //here we've sent the control byte, and we're either clocking data in or out now, but we haven't received a byte yet. - case I2C_STATE_DATA: //here we're sending/receiving data and if we're receiving there's data in the data reg - - //if(i2c_state == I2C_STATE_DATA) printf("\tI2C in state DATA with dir=%d and len=%d\n", i2c_dir, i2c_len); - //else printf("\tI2C in state CONTROL_BYTE_SENT with dir=%d and len=%d\n", i2c_dir, i2c_len); - - if(i2c_dir == I2C_DIR_READ) { - if(i2c_state == I2C_STATE_DATA) *(i2c_bufptr++) = i2c_regs->data; - //printf("\tRead %x\n", *(i2c_bufptr-1)); - //set up another data byte - if(i2c_len > 1) //only one more byte to transfer - i2c_regs->cmd_status = I2C_CMD_RD; - else - i2c_regs->cmd_status = I2C_CMD_RD | I2C_CMD_NACK | I2C_CMD_STOP; - } - else if(i2c_dir == I2C_DIR_WRITE) { - //write a byte - //printf("\tWriting %x\n", *i2c_bufptr); - i2c_regs->data = *(i2c_bufptr++); - if(i2c_len > 1) - i2c_regs->cmd_status = I2C_CMD_WR; - else { - //printf("\tGenerating STOP\n"); - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_STOP; - } - }; - i2c_len--; - if(i2c_len == 0) i2c_state = I2C_STATE_LAST_BYTE; - else i2c_state = I2C_STATE_DATA; //takes care of the addr_sent->data transition - break; - - - case I2C_STATE_LAST_BYTE: //here we've already sent the last read request and the last data is waiting for us. - //printf("\tI2C in state LAST BYTE\n"); - - if(i2c_dir == I2C_DIR_READ) { - *(i2c_bufptr++) = i2c_regs->data; - //printf("\tRead %x\n", *(i2c_bufptr-1)); - i2c_state = I2C_STATE_DATA_READY; - } else { - i2c_state = I2C_STATE_IDLE; - } - i2c_regs->ctrl &= ~I2C_CTRL_IE; //disable interrupts until next time - - if(i2c_callback) { - i2c_callback(); //if we registered a callback, call it! - } - - break; - - - default: //terrible things have happened. - break; - } - -} - -void i2c_register_callback(void (*volatile callback)(void)) { - i2c_callback = callback; -} - -inline void i2c_async_err(void) { - i2c_state = I2C_STATE_IDLE; - i2c_regs->ctrl &= ~I2C_CTRL_IE; - printf("I2C error\n"); -//TODO: set an error flag instead of just dropping things on the floor - i2c_regs->cmd_status = I2C_CMD_STOP; -} - -bool i2c_async_read(uint8_t addr, unsigned int len) { - //printf("Starting async read\n"); - if(i2c_state != I2C_STATE_IDLE) return false; //sorry mario but your i2c is in another castle - if(len == 0) return true; //just idiot-proofing - if(len > sizeof(i2c_buf)) return false; - - //disable I2C interrupts and clear pending interrupts on the I2C device - i2c_regs->ctrl &= ~I2C_CTRL_IE; - i2c_regs->cmd_status |= I2C_CMD_IACK; - - i2c_len = len; - i2c_dir = I2C_DIR_READ; - i2c_bufptr = i2c_buf; - //then set up the transfer by issuing the control byte - i2c_regs->ctrl |= I2C_CTRL_IE; - i2c_regs->data = (addr << 1) | 0x01; //7 bit addr and read bit - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; //generate start & start writing addr - //update the state so the irq handler knows what's going on - i2c_state = I2C_STATE_CONTROL_BYTE_SENT; - return true; -} - -bool i2c_async_write(uint8_t addr, const uint8_t *buf, unsigned int len) { - //printf("Starting async write\n"); - if(i2c_state != I2C_STATE_IDLE) return false; //sorry mario but your i2c is in another castle - if(len > sizeof(i2c_buf)) return false; - - //disable I2C interrupts and clear pending interrupts on the I2C device - i2c_regs->ctrl &= ~I2C_CTRL_IE; - i2c_regs->cmd_status |= I2C_CMD_IACK; - - //copy the buffer into our own if writing - memcpy((void *)i2c_buf, buf, len); - - i2c_len = len; - i2c_dir = I2C_DIR_WRITE; - i2c_bufptr = i2c_buf; - //then set up the transfer by issuing the control byte - i2c_regs->ctrl |= I2C_CTRL_IE; - i2c_regs->data = (addr << 1) | 0x00; //7 bit addr and read bit - i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; //generate start & start writing addr - //update the state so the irq handler knows what's going on - i2c_state = I2C_STATE_CONTROL_BYTE_SENT; - - return true; -} - -//TODO: determine if it's better to read sequentially into the user's buffer, copy on transfer complete, or copy on request (shown below). probably best to copy on request. -bool i2c_async_data_ready(void *buf) { - if(i2c_state == I2C_STATE_DATA_READY) { - i2c_state = I2C_STATE_IDLE; - memcpy(buf, (void *)i2c_buf, (i2c_bufptr - i2c_buf)); //TODO: not really comfortable with this - //printf("Copying %d bytes to user buffer\n", i2c_bufptr-i2c_buf); - return true; - } - return false; -} - - diff --git a/firmware/microblaze/lib/i2c.h b/firmware/microblaze/lib/i2c.h index 77129e922..1af4d72df 100644 --- a/firmware/microblaze/lib/i2c.h +++ b/firmware/microblaze/lib/i2c.h @@ -22,36 +22,18 @@ #include <stdbool.h> #include "stdint.h" -typedef enum { I2C_STATE_IDLE, - I2C_STATE_CONTROL_BYTE_SENT, - I2C_STATE_DATA, - I2C_STATE_LAST_BYTE, - I2C_STATE_DATA_READY, - I2C_STATE_ERROR - } i2c_state_t; - -typedef enum { I2C_DIR_WRITE=0, I2C_DIR_READ=1 } i2c_dir_t; - void i2c_init(void); bool i2c_read (unsigned char i2c_addr, unsigned char *buf, unsigned int len); bool i2c_write(unsigned char i2c_addr, const unsigned char *buf, unsigned int len); -bool i2c_async_read(uint8_t addr, unsigned int len); -bool i2c_async_write(uint8_t addr, const uint8_t *buf, unsigned int len); -bool i2c_async_data_ready(void *); -//static void i2c_irq_handler(unsigned irq); -void i2c_register_callback(void (*callback)(void)); - -// Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard. -// Which EEPROM is determined by i2c_addr. See i2c_addr.h - bool eeprom_write (int i2c_addr, int eeprom_offset, const void *buf, int len); -bool eeprom_write_async (int i2c_addr, int eeprom_offset, const void *buf, int len, void (*callback)(void)); // Read 24LC024 / 24LC025 EEPROM on motherboard or daughterboard. // Which EEPROM is determined by i2c_addr. See i2c_addr.h bool eeprom_read (int i2c_addr, int eeprom_offset, void *buf, int len); -bool eeprom_read_async(int i2c_addr, int eeprom_offset, void *buf, int len, void (*callback)(void)); + +bool find_safe_booted_flag(void); +void set_safe_booted_flag(bool flag); #endif /* INCLUDED_I2C_H */ diff --git a/firmware/microblaze/lib/i2c_async.c b/firmware/microblaze/lib/i2c_async.c new file mode 100644 index 000000000..05c4c3a09 --- /dev/null +++ b/firmware/microblaze/lib/i2c_async.c @@ -0,0 +1,206 @@ +// +// Copyright 2010 Ettus Research LLC +// +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + //i2c_async.c: asynchronous (interrupt-driven) routines for I2C. + //separated out here so we can have a small I2C lib for bootloader and + //retain interrupt-driven I2C for the main app. + +#include "memory_map.h" +#include "stdint.h" +#include <string.h> +#include "pic.h" +#include "nonstdio.h" +#include "i2c_async.h" + + //asynchronous (interrupt-driven) i2c state variables +volatile uint8_t i2c_buf[17]; //tx/rx data transfer buffer +volatile uint8_t *volatile i2c_bufptr = i2c_buf; //ptr to current position +volatile uint8_t i2c_len = 0; //length remaining in current transfer +volatile i2c_state_t i2c_state = I2C_STATE_IDLE; //current I2C transfer state +i2c_dir_t i2c_dir; //I2C transfer direction + +void (*volatile i2c_callback)(void); //function pointer to i2c callback to be called when transaction is complete +static void i2c_irq_handler(unsigned irq); +inline void i2c_async_err(void); + +void i2c_register_handler(void) { + pic_register_handler(IRQ_I2C, i2c_irq_handler); +} + + +static void i2c_irq_handler(unsigned irq) { +//i2c state machine. + + //printf("I2C irq handler\n"); + //first let's make sure nothing is f'ed up + //TODO: uncomment this error checking when we have some way to handle errors +// if(((i2c_regs->cmd_status & I2C_ST_RXACK) != 0) && i2c_dir == I2C_DIR_WRITE) { //we got a NACK and we didn't send it +// printf("\tNACK received\n"); +// i2c_async_err(); +// return; +// }// else printf("\tACK received, proceeding\n"); + + if(i2c_regs->cmd_status & I2C_ST_AL) { + printf("\tArbitration lost!\n"); + i2c_async_err(); + return; + } + + if(i2c_regs->cmd_status & I2C_ST_TIP) { + //printf("\tI2C still busy in interrupt\n"); + return; + } + + //now decide what to do + switch(i2c_state) { + + case I2C_STATE_IDLE: + //this is an error. in idle state, we shouldn't be transferring data, and the fact that the IRQ fired is terrible bad. + printf("AAAAAHHHHH INTERRUPT IN THE IDLE STATE AAAHHHHHHHHH\n"); + i2c_async_err(); + break; + + case I2C_STATE_CONTROL_BYTE_SENT: //here we've sent the control byte, and we're either clocking data in or out now, but we haven't received a byte yet. + case I2C_STATE_DATA: //here we're sending/receiving data and if we're receiving there's data in the data reg + + //if(i2c_state == I2C_STATE_DATA) printf("\tI2C in state DATA with dir=%d and len=%d\n", i2c_dir, i2c_len); + //else printf("\tI2C in state CONTROL_BYTE_SENT with dir=%d and len=%d\n", i2c_dir, i2c_len); + + if(i2c_dir == I2C_DIR_READ) { + if(i2c_state == I2C_STATE_DATA) *(i2c_bufptr++) = i2c_regs->data; + //printf("\tRead %x\n", *(i2c_bufptr-1)); + //set up another data byte + if(i2c_len > 1) //only one more byte to transfer + i2c_regs->cmd_status = I2C_CMD_RD; + else + i2c_regs->cmd_status = I2C_CMD_RD | I2C_CMD_NACK | I2C_CMD_STOP; + } + else if(i2c_dir == I2C_DIR_WRITE) { + //write a byte + //printf("\tWriting %x\n", *i2c_bufptr); + i2c_regs->data = *(i2c_bufptr++); + if(i2c_len > 1) + i2c_regs->cmd_status = I2C_CMD_WR; + else { + //printf("\tGenerating STOP\n"); + i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_STOP; + } + }; + i2c_len--; + if(i2c_len == 0) i2c_state = I2C_STATE_LAST_BYTE; + else i2c_state = I2C_STATE_DATA; //takes care of the addr_sent->data transition + break; + + + case I2C_STATE_LAST_BYTE: //here we've already sent the last read request and the last data is waiting for us. + //printf("\tI2C in state LAST BYTE\n"); + + if(i2c_dir == I2C_DIR_READ) { + *(i2c_bufptr++) = i2c_regs->data; + //printf("\tRead %x\n", *(i2c_bufptr-1)); + i2c_state = I2C_STATE_DATA_READY; + } else { + i2c_state = I2C_STATE_IDLE; + } + i2c_regs->ctrl &= ~I2C_CTRL_IE; //disable interrupts until next time + + if(i2c_callback) { + i2c_callback(); //if we registered a callback, call it! + } + + break; + + + default: //terrible things have happened. + break; + } + +} + +void i2c_register_callback(void (*volatile callback)(void)) { + i2c_callback = callback; +} + +inline void i2c_async_err(void) { + i2c_state = I2C_STATE_IDLE; + i2c_regs->ctrl &= ~I2C_CTRL_IE; + printf("I2C error\n"); +//TODO: set an error flag instead of just dropping things on the floor + i2c_regs->cmd_status = I2C_CMD_STOP; +} + +bool i2c_async_read(uint8_t addr, unsigned int len) { + //printf("Starting async read\n"); + if(i2c_state != I2C_STATE_IDLE) return false; //sorry mario but your i2c is in another castle + if(len == 0) return true; //just idiot-proofing + if(len > sizeof(i2c_buf)) return false; + + //disable I2C interrupts and clear pending interrupts on the I2C device + i2c_regs->ctrl &= ~I2C_CTRL_IE; + i2c_regs->cmd_status |= I2C_CMD_IACK; + + i2c_len = len; + i2c_dir = I2C_DIR_READ; + i2c_bufptr = i2c_buf; + //then set up the transfer by issuing the control byte + i2c_regs->ctrl |= I2C_CTRL_IE; + i2c_regs->data = (addr << 1) | 0x01; //7 bit addr and read bit + i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; //generate start & start writing addr + //update the state so the irq handler knows what's going on + i2c_state = I2C_STATE_CONTROL_BYTE_SENT; + return true; +} + +bool i2c_async_write(uint8_t addr, const uint8_t *buf, unsigned int len) { + //printf("Starting async write\n"); + if(i2c_state != I2C_STATE_IDLE) return false; //sorry mario but your i2c is in another castle + if(len > sizeof(i2c_buf)) return false; + + //disable I2C interrupts and clear pending interrupts on the I2C device + i2c_regs->ctrl &= ~I2C_CTRL_IE; + i2c_regs->cmd_status |= I2C_CMD_IACK; + + //copy the buffer into our own if writing + memcpy((void *)i2c_buf, buf, len); + + i2c_len = len; + i2c_dir = I2C_DIR_WRITE; + i2c_bufptr = i2c_buf; + //then set up the transfer by issuing the control byte + i2c_regs->ctrl |= I2C_CTRL_IE; + i2c_regs->data = (addr << 1) | 0x00; //7 bit addr and read bit + i2c_regs->cmd_status = I2C_CMD_WR | I2C_CMD_START; //generate start & start writing addr + //update the state so the irq handler knows what's going on + i2c_state = I2C_STATE_CONTROL_BYTE_SENT; + + return true; +} + +//TODO: determine if it's better to read sequentially into the user's buffer, copy on transfer complete, or copy on request (shown below). probably best to copy on request. +bool i2c_async_data_ready(void *buf) { + if(i2c_state == I2C_STATE_DATA_READY) { + i2c_state = I2C_STATE_IDLE; + memcpy(buf, (void *)i2c_buf, (i2c_bufptr - i2c_buf)); //TODO: not really comfortable with this + //printf("Copying %d bytes to user buffer\n", i2c_bufptr-i2c_buf); + return true; + } + return false; +} + diff --git a/firmware/microblaze/lib/i2c_async.h b/firmware/microblaze/lib/i2c_async.h new file mode 100644 index 000000000..e6095fca6 --- /dev/null +++ b/firmware/microblaze/lib/i2c_async.h @@ -0,0 +1,50 @@ +// +// Copyright 2010 Ettus Research LLC +// +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INCLUDED_I2C_ASYNC_H +#define INCLUDED_I2C_ASYNC_H + +#include <stdbool.h> +#include "stdint.h" + +typedef enum { I2C_STATE_IDLE, + I2C_STATE_CONTROL_BYTE_SENT, + I2C_STATE_DATA, + I2C_STATE_LAST_BYTE, + I2C_STATE_DATA_READY, + I2C_STATE_ERROR + } i2c_state_t; + +typedef enum { I2C_DIR_WRITE=0, I2C_DIR_READ=1 } i2c_dir_t; + +bool i2c_async_read(uint8_t addr, unsigned int len); +bool i2c_async_write(uint8_t addr, const uint8_t *buf, unsigned int len); +bool i2c_async_data_ready(void *); +//static void i2c_irq_handler(unsigned irq); +void i2c_register_callback(void (*callback)(void)); +void i2c_register_handler(void); + +// Write 24LC024 / 24LC025 EEPROM on motherboard or daughterboard. +// Which EEPROM is determined by i2c_addr. See i2c_addr.h + +bool eeprom_write_async (int i2c_addr, int eeprom_offset, const void *buf, int len, void (*callback)(void)); +bool eeprom_read_async(int i2c_addr, int eeprom_offset, void *buf, int len, void (*callback)(void)); + +#endif /* INCLUDED_I2C_ASYNC_H */ diff --git a/firmware/microblaze/lib/ihex.c b/firmware/microblaze/lib/ihex.c new file mode 100644 index 000000000..97ecf73b6 --- /dev/null +++ b/firmware/microblaze/lib/ihex.c @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include "ihex.h" +#include <ctype.h> //man that pulls in a lot of shit + +//this is not safe and you should run isxdigit beforehand +uint8_t asc2nibble(char input) { + if(input > 'Z') return input - 'W'; + else if(input > '9') return input - '7'; + else return input - '0'; +} + +int ihex_parse(char input[], ihex_record_t *record) { + //given a NULL-TERMINATED input string (use gets()) in I16HEX format, write the binary record in record. return 0 on success. + + uint8_t inputlen; + uint8_t t, i, checksum_calc=0, checksum_read; + + //first check for ":" leading character + if(input[0] != ':') return -1; + + //then check the string for only valid ASCII ['0'-'F'] + inputlen=1; + while(input[inputlen]) { + if( !isxdigit(input[inputlen++]) ) return -2; + } + + //then read the length. + record->length = (asc2nibble(input[1]) << 4) + asc2nibble(input[2]); + if(input[(record->length<<1) + 11] != 0) return -3; //if we're missing a null terminator in the right place + + //then read the address. + record->addr = (asc2nibble(input[3]) << 12) + (asc2nibble(input[4]) << 8) + (asc2nibble(input[5]) << 4) + asc2nibble(input[6]); + + //then read the record type. + record->type = (asc2nibble(input[7]) << 4) + asc2nibble(input[8]); +// if(record->type > 4) return -4; + + //then read the data, which goes from input[9] to input[9+length*2]. + for(i=0; i < record->length; i++) { + t = 9 + (i<<1); + record->data[i] = (asc2nibble(input[t]) << 4) + (asc2nibble(input[t + 1])); + checksum_calc += record->data[i]; //might as well keep a running checksum as we read + } + checksum_calc += record->length + record->type + (record->addr >> 8) + (record->addr & 0xFF); //get the rest of the data into that checksum + checksum_calc = ~checksum_calc + 1; //checksum is 2's complement + + //now read the checksum of the record + checksum_read = (asc2nibble(input[9 + (record->length<<1)]) << 4) + asc2nibble(input[10 + (record->length<<1)]); + if(checksum_calc != checksum_read) return -5; //compare 'em + + return 0; +} diff --git a/firmware/microblaze/lib/ihex.h b/firmware/microblaze/lib/ihex.h new file mode 100644 index 000000000..9f471fbe2 --- /dev/null +++ b/firmware/microblaze/lib/ihex.h @@ -0,0 +1,18 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <stdint.h> +#include <stddef.h> + +typedef struct { + uint8_t type; + size_t length; + uint32_t addr; + uint8_t *data; +} ihex_record_t; + + +int ihex_parse(char input[], ihex_record_t *record); diff --git a/firmware/microblaze/lib/net_common.c b/firmware/microblaze/lib/net_common.c index beaaa5948..6305408d6 100644 --- a/firmware/microblaze/lib/net_common.c +++ b/firmware/microblaze/lib/net_common.c @@ -291,8 +291,17 @@ handle_icmp_packet(struct ip_addr src, struct ip_addr dst, { switch (icmp->type){ case ICMP_DUR: // Destinatino Unreachable - //stop_streaming(); //FIXME if (icmp->code == ICMP_DUR_PORT){ // port unreachable + //handle destination port unreachable (the host ctrl+c'd the app): + + //end async update packets per second + sr_tx_ctrl->cyc_per_up = 0; + + //the end continuous streaming command + sr_rx_ctrl->cmd = 1 << 31; //no samples now + sr_rx_ctrl->time_secs = 0; + sr_rx_ctrl->time_ticks = 0; //latch the command + //struct udp_hdr *udp = (struct udp_hdr *)((char *)icmp + 28); //printf("icmp port unr %d\n", udp->dest); putchar('i'); diff --git a/firmware/microblaze/lib/pic.c b/firmware/microblaze/lib/pic.c index e89d2b755..226da5f85 100644 --- a/firmware/microblaze/lib/pic.c +++ b/firmware/microblaze/lib/pic.c @@ -44,7 +44,7 @@ pic_init(void) // uP is level triggered pic_regs->mask = ~0; // mask all interrupts - pic_regs->edge_enable = PIC_ONETIME_INT; + pic_regs->edge_enable = PIC_ONETIME_INT | PIC_UNDERRUN_INT | PIC_OVERRUN_INT | PIC_PPS_INT; pic_regs->polarity = ~0 & ~PIC_PHY_INT; // rising edge pic_regs->pending = ~0; // clear all pending ints } diff --git a/firmware/microblaze/lib/u2_init.c b/firmware/microblaze/lib/u2_init.c index c9b4beb2b..4a553a713 100644 --- a/firmware/microblaze/lib/u2_init.c +++ b/firmware/microblaze/lib/u2_init.c @@ -23,11 +23,22 @@ #include "buffer_pool.h" #include "hal_uart.h" #include "i2c.h" +#include "i2c_async.h" #include "mdelay.h" #include "clocks.h" #include "usrp2/fw_common.h" #include "nonstdio.h" +unsigned char u2_hw_rev_major; +unsigned char u2_hw_rev_minor; + +static inline void +get_hw_rev(void) +{ + bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV, &u2_hw_rev_minor, 1); + ok &= eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_REV+1, &u2_hw_rev_major, 1); +} + /* * We ought to arrange for this to be called before main, but for now, * we require that the user's main call u2_init as the first thing... @@ -49,6 +60,7 @@ u2_init(void) // init i2c so we can read our rev pic_init(); // progammable interrupt controller i2c_init(); + i2c_register_handler(); //for using async I2C hal_enable_ints(); bp_init(); // buffer pool diff --git a/firmware/microblaze/lib/udp_fw_update.h b/firmware/microblaze/lib/udp_fw_update.h new file mode 100644 index 000000000..d25525bd2 --- /dev/null +++ b/firmware/microblaze/lib/udp_fw_update.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "net_common.h" + +#define USRP2_UDP_UPDATE_PORT 49154 + +typedef enum { + USRP2_FW_UPDATE_ID_WAT = ' ', + + USRP2_FW_UPDATE_ID_OHAI_LOL = 'a', + USRP2_FW_UPDATE_ID_OHAI_OMG = 'A', + + USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL = 'f', + USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG = 'F', + + USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL = 'e', + USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG = 'E', + + USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL = 'd', + USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG = 'D', + USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG = 'B', + + USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL = 'w', + USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG = 'W', + + USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL = 'r', + USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG = 'R', + + USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL = 's', + USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG = 'S', + + USRP2_FW_UPDATE_ID_KTHXBAI = '~' + +} usrp2_fw_update_id_t; + +typedef struct { + uint32_t proto_ver; + uint32_t id; + uint32_t seq; + union { + uint32_t ip_addr; + struct { + uint32_t flash_addr; + uint32_t length; + uint8_t data[256]; + } flash_args; + struct { + uint32_t sector_size_bytes; + uint32_t memory_size_bytes; + } flash_info_args; + } data; +} usrp2_fw_update_data_t; + +void handle_udp_fw_update_packet(struct socket_address src, struct socket_address dst, + unsigned char *payload, int payload_len); diff --git a/firmware/microblaze/usrp2/Makefile.am b/firmware/microblaze/usrp2/Makefile.am index ba426b75c..7a58e7253 100644 --- a/firmware/microblaze/usrp2/Makefile.am +++ b/firmware/microblaze/usrp2/Makefile.am @@ -24,6 +24,8 @@ AM_LDFLAGS = \ $(COMMON_LFLAGS) \ -Wl,-defsym -Wl,_TEXT_START_ADDR=0x0050 \ -Wl,-defsym -Wl,_STACK_SIZE=3072 + +LDADD = libusrp2.a LDADD = libusrp2.a @@ -35,7 +37,8 @@ noinst_LIBRARIES = libusrp2.a libusrp2_a_SOURCES = \ $(COMMON_SRCS) \ sd.c \ - ethernet.c + ethernet.c \ + udp_fw_update.c noinst_PROGRAMS = \ usrp2_txrx_uhd.elf diff --git a/firmware/microblaze/usrp2/memory_map.h b/firmware/microblaze/usrp2/memory_map.h index 41a2820bc..eac0c217f 100644 --- a/firmware/microblaze/usrp2/memory_map.h +++ b/firmware/microblaze/usrp2/memory_map.h @@ -463,6 +463,10 @@ typedef struct { typedef struct { volatile uint32_t num_chan; volatile uint32_t clear_state; // clears out state machine, fifos, + volatile uint32_t report_sid; + volatile uint32_t policy; + volatile uint32_t cyc_per_up; + volatile uint32_t packets_per_up; } sr_tx_ctrl_t; #define sr_tx_ctrl ((sr_tx_ctrl_t *) _SR_ADDR(SR_TX_CTRL)) diff --git a/firmware/microblaze/usrp2/udp_fw_update.c b/firmware/microblaze/usrp2/udp_fw_update.c new file mode 100644 index 000000000..14eb0b1ee --- /dev/null +++ b/firmware/microblaze/usrp2/udp_fw_update.c @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +//Routines to handle updating the SPI Flash firmware via UDP + +#include "net_common.h" +#include "usrp2/fw_common.h" +#include <nonstdio.h> +#include "udp_fw_update.h" + +//Firmware update packet handler +void handle_udp_fw_update_packet(struct socket_address src, struct socket_address dst, + unsigned char *payload, int payload_len) { + + usrp2_fw_update_data_t update_data_out; + update_data_out.id = USRP2_FW_UPDATE_ID_WAT; + + send_udp_pkt(USRP2_UDP_UPDATE_PORT, src, &update_data_out, sizeof(update_data_out)); +} diff --git a/firmware/microblaze/usrp2p/.gitignore b/firmware/microblaze/usrp2p/.gitignore new file mode 100644 index 000000000..18f715618 --- /dev/null +++ b/firmware/microblaze/usrp2p/.gitignore @@ -0,0 +1,9 @@ +/Makefile +/Makefile.in +/*.a +/*.bin +/*.dump +/*.ihx +/*.elf +/*.rom +/*.map diff --git a/firmware/microblaze/usrp2p/Makefile.am b/firmware/microblaze/usrp2p/Makefile.am new file mode 100644 index 000000000..40766b406 --- /dev/null +++ b/firmware/microblaze/usrp2p/Makefile.am @@ -0,0 +1,71 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +include $(top_srcdir)/Makefile.common + +AM_CFLAGS = \ + $(COMMON_CFLAGS) \ + -DUSRP2P + +AM_LDFLAGS = \ + $(COMMON_LFLAGS) \ + -Wl,-defsym -Wl,_TEXT_START_ADDR=0x8050 \ + -Wl,-defsym -Wl,_STACK_SIZE=3072 + +LDADD = libusrp2p.a + +#all of this here is to relocate the hardware vectors to somewhere normal. +RELOCATE_ARGS = \ + --change-section-address .vectors.sw_exception+0x8000 \ + --change-section-address .vectors.hw_exception+0x8000 \ + --change-section-address .vectors.interrupt+0x8000 \ + --change-section-address .vectors.reset+0x8000 + +# $(MB_OBJCOPY) -O ihex $< $@ +# the below would work if objcopy weren't written by apes +# $(MB_OBJCOPY) -O ihex -w --change-section-address .vectors*+0x8000 $< $@ +# using the below will throw away the interrupt vectors when they get relocated below 0x0000. +# $(MB_OBJCOPY) -O ihex --change-addresses -0x8000 $< $@ + +######################################################################## +# USRP2P specific library and programs +######################################################################## +noinst_LIBRARIES = libusrp2p.a + +libusrp2p_a_SOURCES = \ + $(COMMON_SRCS) \ + spif.c \ + spi_flash.c \ + spi_flash_read.c \ + bootloader_utils.c \ + ethernet.c \ + xilinx_s3_icap.c \ + udp_fw_update.c + +noinst_PROGRAMS = \ + usrp2p_txrx_uhd.elf \ + usrp2p_blinkenlights.elf \ + usrp2p_uart_flash_loader.elf + +usrp2p_txrx_uhd_elf_SOURCES = \ + $(top_srcdir)/apps/txrx_uhd.c + +usrp2p_blinkenlights_elf_SOURCES = \ + $(top_srcdir)/apps/blinkenlights.c + +usrp2p_uart_flash_loader_elf_SOURCES = \ + $(top_srcdir)/apps/uart_flash_loader.c diff --git a/firmware/microblaze/usrp2p/bootconfig.h b/firmware/microblaze/usrp2p/bootconfig.h new file mode 100644 index 000000000..35c2726ed --- /dev/null +++ b/firmware/microblaze/usrp2p/bootconfig.h @@ -0,0 +1,61 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_BOOTCONFIG_H +#define INCLUDED_BOOTCONFIG_H + +#include <stdbool.h> + +typedef struct { + unsigned char fpga_image_number; + unsigned char firmware_image_number; +} bootconfig_t; + +static inline bootconfig_t +make_bootconfig(unsigned char fpga_image_number, unsigned char firmware_image_number) +{ + bootconfig_t r; + r.fpga_image_number = fpga_image_number; + r.firmware_image_number = firmware_image_number; + return r; +} + +void bootconfig_init(void); /* One time call to initialize */ + +/*! + * \return default boot configuration + */ +bootconfig_t bootconfig_get_default(void); + +/*! + * \brief Set the default boot configuration. + */ +bool bootconfig_set_default(bootconfig_t bc); + +/*! + * \brief attempt to boot the given fpga and software image. + * + * If successful, this routine does not return. + * If it fail for some reason, it returns. + */ +void bootconfig_boot(bootconfig_t bc); + +#endif /* INCLUDED_BOOTCONFIG_H */ diff --git a/firmware/microblaze/usrp2p/bootloader/.gitignore b/firmware/microblaze/usrp2p/bootloader/.gitignore new file mode 100644 index 000000000..17b0f82f3 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/.gitignore @@ -0,0 +1,11 @@ +/*.ihx +/*.rmi +/*_rom +/*.elf +/*.bin +/*.dump +/*.log +/*.rom +/*.map +/Makefile +/Makefile.in diff --git a/firmware/microblaze/usrp2p/bootloader/Makefile.am b/firmware/microblaze/usrp2p/bootloader/Makefile.am new file mode 100644 index 000000000..1fc5daf9c --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/Makefile.am @@ -0,0 +1,39 @@ +# +# Copyright 2007,2008,2009 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +include $(top_srcdir)/Makefile.common + +ROM_LINKER_SCRIPT = u2p2-rom.ld + +# loads into 8K boot ram located at 0x0000_0000 +AM_CFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir)/usrp2p +AM_LDFLAGS = -Wl,-T,$(ROM_LINKER_SCRIPT) $(COMMON_LFLAGS) -Wl,-defsym -Wl,_STACK_SIZE=1024 + +EXTRA_DIST = $(ROM_LINKER_SCRIPT) + +LDADD = $(top_srcdir)/usrp2p/libusrp2p.a + +noinst_PROGRAMS = \ + init_bootloader.elf + +init_bootloader_elf_SOURCES = init_bootloader.c + +.bin.rmi: + $(top_srcdir)/bin/bin_to_ram_macro_init.py $< $@ + +_generated_from_elf += \ + $(noinst_PROGRAMS:.elf=.rmi) diff --git a/firmware/microblaze/usrp2p/bootloader/fpga_bootloader.c b/firmware/microblaze/usrp2p/bootloader/fpga_bootloader.c new file mode 100644 index 000000000..9feff6ecd --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/fpga_bootloader.c @@ -0,0 +1,202 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * This code is bootloader f/w for the slot 0 fpga image. It's job is + * to figure out which fpga image should be loaded, and then to load + * that image from the SPI flash. (FIXME handle retries, errors, + * etc.) + * + * If the center button is down during boot, it loads firwmare + * from 0:0 instead of its normal action. + */ + +#include <stdlib.h> +#include <hal_io.h> +#include <nonstdio.h> +#include <mdelay.h> +#include <quadradio/flashdir.h> +#include <xilinx_v5_icap.h> +#include <bootconfig.h> +#include <bootconfig_private.h> +#include <spi_flash.h> +#include <string.h> +#include <bootloader_utils.h> +#include <hal_interrupts.h> + +#define VERBOSE 1 + +#define OUR_FPGA_IMAGE_NUMBER 0 // this code only runs in slot 0 + +void hal_uart_init(void); +void spif_init(void); +void i2c_init(void); +void bootconfig_init(void); + +void pic_interrupt_handler() __attribute__ ((interrupt_handler)); + +void pic_interrupt_handler() +{ + // nop stub +} + +static int +flash_addr_of_fpga_slot(unsigned int fpga_slot) +{ + const struct flashdir *fd = get_flashdir(); + return fd->slot[fpga_slot + fd->fpga_slot0].start << spi_flash_log2_sector_size(); +} + + +/* + * If the first 256 bytes of the image contain the string of bytes, + * ff ff ff ff aa 99 55 66, we consider it a likely bitstream. + */ +static bool +looks_like_a_bitstream(unsigned int fpga_slot) +{ + unsigned char buf[256]; + static const unsigned char pattern[] = { + 0xff, 0xff, 0xff, 0xff, 0xaa, 0x99, 0x55, 0x66 + }; + + // Read the first 256 bytes of the bitstream + spi_flash_read(flash_addr_of_fpga_slot(fpga_slot), sizeof(buf), buf); + + for (int i = 0; i <= sizeof(buf) - sizeof(pattern); i++) + if (memcmp(pattern, &buf[i], sizeof(pattern)) == 0) + return true; + + return false; +} + +static bool +plausible_bootconfig(bootconfig_t bc) +{ + // Are the fields in range? + if (!validate_bootconfig(bc)) + return false; + + if (!looks_like_a_bitstream(map_fpga_image_number_to_fpga_slot(bc.fpga_image_number))) + return false; + + return true; +} + +// Attempt to boot the fpga image specified in next_boot +static void +initial_boot_attempt(eeprom_boot_info_t *ee) +{ + if (ee->next_boot.fpga_image_number == OUR_FPGA_IMAGE_NUMBER){ + load_firmware(); + return; + } + + ee->nattempts = 1; + _bc_write_eeprom_shadow(); + + unsigned int target_slot = + map_fpga_image_number_to_fpga_slot(ee->next_boot.fpga_image_number); + int flash_addr = flash_addr_of_fpga_slot(target_slot); + + putstr("fpga_bootloader: chaining to "); + puthex4(ee->next_boot.fpga_image_number); + putchar(':'); + puthex4(ee->next_boot.firmware_image_number); + newline(); + mdelay(100); + + while (1){ + icap_reload_fpga(flash_addr); + } +} + +int +main(int argc, char **argv) +{ + hal_disable_ints(); // In case we got here via jmp 0x0 + hal_uart_init(); + i2c_init(); + bootconfig_init(); // Must come after i2c_init. + spif_init(); // Needed for get_flashdir. + + sr_leds->leds = 0xAAAA; + + putstr("\n\n>>> fpga_bootloader <<<\n"); + + putstr("\nBOOTSTS "); + int bootsts = icap_read_config_reg(rBOOTSTS); + puthex32_nl(bootsts); + putstr("STAT "); + int stat = icap_read_config_reg(rSTAT); + puthex32_nl(stat); + + bool fallback = + ((bootsts & (BOOTSTS_VALID_0 | BOOTSTS_FALLBACK_0)) + == (BOOTSTS_VALID_0 | BOOTSTS_FALLBACK_0)); + + if (fallback){ + puts("FALLBACK_0 is set"); + // FIXME handle fallback condition. + } + + const struct flashdir *fd = get_flashdir(); + if (fd == 0) + abort(); + + eeprom_boot_info_t *ee = _bc_get_eeprom_shadow(); + + if (VERBOSE){ + putstr("nattempts: "); + puthex8_nl(ee->nattempts); + } + + mdelay(500); // wait for low-pass on switches + putstr("switches: "); puthex32_nl(readback->switches); + + bool center_btn_down = (readback->switches & BTN_CENTER) != 0; + if (center_btn_down){ + putstr("Center button is down!\n"); + // Force boot of image 0:0 + ee->next_boot = make_bootconfig(0, 0); + } + + // if next_boot is valid, try it + if (plausible_bootconfig(ee->next_boot)) + initial_boot_attempt(ee); // no return + + // if default_boot is valid, try it + if (plausible_bootconfig(ee->default_boot)){ + ee->next_boot = ee->default_boot; + initial_boot_attempt(ee); // no return + } + + // If we're here, we're in trouble. Try all of them... + for (int i = 0; i < 4; i++){ + bootconfig_t bc = make_bootconfig(i, 0); + if (plausible_bootconfig(bc)){ + ee->next_boot = bc; + initial_boot_attempt(ee); // no return + } + } + + // FIXME, try to find something we can load + puts("\n!!! Failed to find a valid FPGA bitstream!\n\n"); + + return 0; +} diff --git a/firmware/microblaze/usrp2p/bootloader/fw_bootloader.c b/firmware/microblaze/usrp2p/bootloader/fw_bootloader.c new file mode 100644 index 000000000..a2c32bf8e --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/fw_bootloader.c @@ -0,0 +1,50 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <memory_map.h> +#include <nonstdio.h> +#include <stdlib.h> +#include <bootconfig.h> +#include <bootconfig_private.h> +#include <bootloader_utils.h> +#include <hal_interrupts.h> + + +void hal_uart_init(void); +void spif_init(void); +void i2c_init(void); +void bootconfig_init(void); + +void pic_interrupt_handler() __attribute__ ((interrupt_handler)); + +void pic_interrupt_handler() +{ + // nop stub +} + +int +main(int argc, char **argv) +{ + hal_disable_ints(); // In case we got here via jmp 0x0 + hal_uart_init(); + i2c_init(); + bootconfig_init(); // Must come after i2c_init. + spif_init(); // Needed for get_flashdir. + + load_firmware(); +} diff --git a/firmware/microblaze/usrp2p/bootloader/icap_test.c b/firmware/microblaze/usrp2p/bootloader/icap_test.c new file mode 100644 index 000000000..5feb9d014 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/icap_test.c @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <memory_map.h> +#include <hal_io.h> +#include <xilinx_s3_icap.h> +#include <nonstdio.h> + +void delay(uint32_t t) { + while(t-- != 0) asm("NOP"); +} + + +int main(int argc, char *argv[]) { + pic_init(); + hal_uart_init(); + puts("\nStarting delay...\n"); + + output_regs->leds = 0xFF; + delay(4000000); + output_regs->leds = 0x00; + delay(4000000); + + puts("Rebooting FPGA to 0x00000000\n"); + icap_reload_fpga((uint32_t)0x00000000); + + return 0; +} diff --git a/firmware/microblaze/usrp2p/bootloader/init_bootloader.c b/firmware/microblaze/usrp2p/bootloader/init_bootloader.c new file mode 100644 index 000000000..1d9d681d7 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/init_bootloader.c @@ -0,0 +1,114 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <memory_map.h> +#include <nonstdio.h> +#include <hal_io.h> +#include <xilinx_s3_icap.h> +#include <spi_flash.h> +#include <spi_flash_private.h> +//#include <clocks.h> +#include <ihex.h> +#include <bootloader_utils.h> +#include <string.h> +#include <hal_uart.h> +#include <i2c.h> +#include "usrp2/fw_common.h" + +void pic_interrupt_handler() __attribute__ ((interrupt_handler)); + +void pic_interrupt_handler() +{ + // nop stub +} + +void load_ihex(void) { //simple IHEX parser to load proper records into RAM. loads program when it receives end of record. + char buf[128]; //input data buffer + uint8_t ihx[32]; //ihex data buffer + + ihex_record_t ihex_record; + ihex_record.data = ihx; + + while(1) { + gets(buf); + + if(!ihex_parse(buf, &ihex_record)) { //RAM data record is valid + if(ihex_record.addr >= RAM_BASE) { //it's expecting to see FULLY RELOCATED IHX RECORDS. every address referenced to 0x8000, including vectors. + memcpy((void *) (ihex_record.addr), ihex_record.data, ihex_record.length); + puts("OK"); + } else if(ihex_record.type == 1) { //end of record + puts("OK"); + //load main firmware + start_program(RAM_BASE); + puts("ERROR: main image returned! Back in IHEX load mode."); + } else puts("NOK"); //RAM loads do not support extended segment address records (04) -- upper 16 bits are always "0". + } else puts("NOK"); + } +} + +void delay(uint32_t t) { + while(t-- != 0) asm("NOP"); +} + +int main(int argc, char *argv[]) { + hal_disable_ints(); // In case we got here via jmp 0x0 + output_regs->leds = 0xFF; + delay(500000); + output_regs->leds = 0x00; + hal_uart_init(); + spif_init(); + i2c_init(); //for EEPROM + puts("USRP2+ bootloader\n"); + + bool production_image = find_safe_booted_flag(); + set_safe_booted_flag(0); //haven't booted yet + + if(BUTTON_PUSHED) { //see memory_map.h + puts("Starting USRP2+ in safe mode."); + if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) { + set_safe_booted_flag(1); //let the firmware know it's the safe image + spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE); + start_program(RAM_BASE); + puts("ERROR: return from main program! This should never happen!"); + icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR); + } else { + puts("ERROR: no safe firmware image available. I am a brick. Feel free to load IHEX to RAM."); + load_ihex(); + } + } + + if(!production_image) { + puts("Checking for valid production FPGA image..."); + if(is_valid_fpga_image(PROD_FPGA_IMAGE_LOCATION_ADDR)) { + puts("Valid production FPGA image found. Attempting to boot."); + set_safe_booted_flag(1); + delay(30000); //so serial output can finish + icap_reload_fpga(PROD_FPGA_IMAGE_LOCATION_ADDR); + } + puts("No valid production FPGA image found.\nAttempting to load production firmware..."); + } + if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) { + puts("Valid production firmware found. Loading..."); + spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE); + start_program(RAM_BASE); + puts("ERROR: Return from main program! This should never happen!"); + //if this happens, though, the safest thing to do is reboot the whole FPGA and start over. + icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR); + return 1; + } + puts("No valid production firmware found. Trying safe firmware..."); + if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) { + spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE); + start_program(RAM_BASE); + puts("ERROR: return from main program! This should never happen!"); + icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR); + return 1; + } + puts("ERROR: no safe firmware image available. I am a brick. Feel free to load IHEX to RAM."); + load_ihex(); + + return 0; +} diff --git a/firmware/microblaze/usrp2p/bootloader/serial_loader_burner.c b/firmware/microblaze/usrp2p/bootloader/serial_loader_burner.c new file mode 100644 index 000000000..4ac4df454 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/serial_loader_burner.c @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <hal_io.h> +#include <nonstdio.h> +#include <mdelay.h> +#include <gdbstub2.h> + +void hal_uart_init(void); +void spif_init(void); + +void pic_interrupt_handler() __attribute__ ((interrupt_handler)); + +void pic_interrupt_handler() +{ + // nop stub +} + +int +main(int argc, char **argv) +{ + hal_uart_init(); + spif_init(); + + sr_leds->leds = 0; + mdelay(100); + sr_leds->leds = ~0; + mdelay(100); + sr_leds->leds = 0; + + puts("\n\n>>> stage1: serial_loader_burner <<<"); + + gdbstub2_main_loop(); +} diff --git a/firmware/microblaze/usrp2p/bootloader/spi_bootloader.c b/firmware/microblaze/usrp2p/bootloader/spi_bootloader.c new file mode 100644 index 000000000..678e66cf7 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/spi_bootloader.c @@ -0,0 +1,134 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <hal_io.h> +#include <nonstdio.h> +#include <mdelay.h> +#include <spi_flash.h> +#include <quadradio/flashdir.h> +#include <quadradio/simple_binary_format.h> +#include <stdlib.h> + + +void hal_uart_init(void); +void spif_init(void); + +void pic_interrupt_handler() __attribute__ ((interrupt_handler)); + +void pic_interrupt_handler() +{ + // nop stub +} + +static void +error(int e) +{ + putstr("ERR"); + puthex8(e); + newline(); +} + +static void +load(uint32_t flash_addr, uint32_t ram_addr, uint32_t size) +{ + spi_flash_read(flash_addr, size, (void *) ram_addr); +} + +static bool +load_from_slot(const struct flashdir *fd, int fw_slot) +{ + putstr("Loading f/w image "); + putchar('0' + fw_slot); + putstr("... "); + + if (fw_slot >= fd->fw_nslots){ + error(1); + return false; + } + + int slot = fw_slot + fd->fw_slot0; + if (fd->slot[slot].start == 0 || fd->slot[slot].start == 0xffff + || fd->slot[slot].len == 0 || fd->slot[slot].len == 0xffff){ + error(2); + return false; + } + + uint32_t sbf_base = fd->slot[slot].start << spi_flash_log2_sector_size(); + uint32_t sbf_len = fd->slot[slot].len << spi_flash_log2_sector_size(); + uint32_t sbf_offset = 0; + + struct sbf_header sbf; + spi_flash_read(sbf_base, sizeof(struct sbf_header), &sbf); + if (sbf.magic != SBF_MAGIC || sbf.nsections > SBF_MAX_SECTIONS){ + error(3); + return false; + } + sbf_offset += sizeof(struct sbf_header); + + unsigned int i; + for (i = 0; i < sbf.nsections; i++){ + if (sbf_offset + sbf.sec_desc[i].length > sbf_len){ + error(4); + return false; + } + load(sbf_offset + sbf_base, + sbf.sec_desc[i].target_addr, + sbf.sec_desc[i].length); + sbf_offset += sbf.sec_desc[i].length; + } + putstr("Done!"); + + typedef void (*fptr_t)(void); + (*(fptr_t) sbf.entry)(); // almost certainly no return + + return true; +} + +int +main(int argc, char **argv) +{ + hal_uart_init(); + spif_init(); + + sr_leds->leds = 0; + mdelay(100); + sr_leds->leds = ~0; + mdelay(100); + sr_leds->leds = 0; + + putstr("\n>>> spi_bootloader <<<\n"); + + const struct flashdir *fd = get_flashdir(); + if (fd == 0) + abort(); + + while(1){ + int sw; + int fw_slot; + + sw = readback->switches; + fw_slot = sw & 0x7; + + if (!load_from_slot(fd, fw_slot)){ + if (fw_slot != 0){ + putstr("Falling back to slot 0\n"); + load_from_slot(fd, 0); + } + } + } +} diff --git a/firmware/microblaze/usrp2p/bootloader/u2p2-rom.ld b/firmware/microblaze/usrp2p/bootloader/u2p2-rom.ld new file mode 100644 index 000000000..4c9eaa8e5 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader/u2p2-rom.ld @@ -0,0 +1,190 @@ +/* + * Same as default, but with bss and stack moved to top 2K of main ram + * Copied from qr-rom.ld + */ + +/* Default linker script, for normal executables */ +OUTPUT_FORMAT("elf32-microblaze", "", "") +/*SEARCH_DIR("/home/eb/build/Xilinx_EDK_GNU_10.1i/mb/release/lin/mb/microblaze-xilinx-elf/lib");*/ + + +ENTRY(_start) +_TEXT_START_ADDR = DEFINED(_TEXT_START_ADDR) ? _TEXT_START_ADDR : 0x50; +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x0; +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400; +_BSS_START_ADDR = DEFINED(_BSS_START_ADDR) ? _BSS_START_ADDR : 0xF800; +SECTIONS +{ + .vectors.reset 0x0 : { KEEP (*(.vectors.reset)) } = 0 + .vectors.sw_exception 0x8 : { KEEP (*(.vectors.sw_exception)) } = 0 + .vectors.interrupt 0x10 : { KEEP (*(.vectors.interrupt)) } = 0 + .vectors.debug_sw_break 0x18 : { KEEP (*(.vectors.debug_sw_break)) } = 0 + .vectors.hw_exception 0x20 : { KEEP (*(.vectors.hw_exception)) } = 0 + . = _TEXT_START_ADDR; + _ftext = .; + .text : { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + _etext = .; + .init : { KEEP (*(.init)) } =0 + .fini : { KEEP (*(.fini)) } =0 + PROVIDE (__CTOR_LIST__ = .); + PROVIDE (___CTOR_LIST__ = .); + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + PROVIDE (__CTOR_END__ = .); + PROVIDE (___CTOR_END__ = .); + PROVIDE (__DTOR_LIST__ = .); + PROVIDE (___DTOR_LIST__ = .); + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + PROVIDE (__DTOR_END__ = .); + PROVIDE (___DTOR_END__ = .); + . = ALIGN(4); + _frodata = . ; + .rodata : { + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + CONSTRUCTORS; /* Is this needed? */ + } + _erodata = .; + /* Alignments by 8 to ensure that _SDA2_BASE_ on a word boundary */ + /* Note that .sdata2 and .sbss2 must be contiguous */ + . = ALIGN(8); + _ssrw = .; + .sdata2 : { + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + } + . = ALIGN(4); + .sbss2 : { + PROVIDE (__sbss2_start = .); + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + PROVIDE (__sbss2_end = .); + } + . = ALIGN(8); + _essrw = .; + _ssrw_size = _essrw - _ssrw; + PROVIDE (_SDA2_BASE_ = _ssrw + (_ssrw_size / 2 )); + . = ALIGN(4); + _fdata = .; + .data : { + *(.data) + *(.gnu.linkonce.d.*) + CONSTRUCTORS; /* Is this needed? */ + } + _edata = . ; + /* Added to handle pic code */ + .got : { + *(.got) + } + .got1 : { + *(.got1) + } + .got2 : { + *(.got2) + } + /* Added by Sathya to handle C++ exceptions */ + .eh_frame : { + *(.eh_frame) + } + .jcr : { + *(.jcr) + } + .gcc_except_table : { + *(.gcc_except_table) + } + /* Alignments by 8 to ensure that _SDA_BASE_ on a word boundary */ + /* Note that .sdata and .sbss must be contiguous */ + . = ALIGN(8); + _ssro = .; + .sdata : { + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + } + . = ALIGN(4); + .sbss : { + PROVIDE (__sbss_start = .); + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + PROVIDE (__sbss_end = .); + } + . = ALIGN(8); + _essro = .; + _ssro_size = _essro - _ssro; + PROVIDE (_SDA_BASE_ = _ssro + (_ssro_size / 2 )); + . = _BSS_START_ADDR; + . = ALIGN(4); + _fbss = .; + .bss : { + PROVIDE (__bss_start = .); + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + PROVIDE (__bss_end = .); + } + . = ALIGN(4); + .heap : { + _heap = .; + _heap_start = .; + . += _HEAP_SIZE; + _heap_end = .; + } + _end = .; + . = ALIGN(4); + . = 0xFFF0; + .stack : { + /* + _stack_end = .; + . += _STACK_SIZE; + . = ALIGN(8); + _stack = .; + _end = .; + */ + _stack_end = .; + _stack = .; + } + .tdata : { + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + } + .tbss : { + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + } +} diff --git a/firmware/microblaze/usrp2p/bootloader_utils.c b/firmware/microblaze/usrp2p/bootloader_utils.c new file mode 100644 index 000000000..fadd225bb --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader_utils.c @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +//contains routines for loading programs from Flash. depends on Flash libraries. +//also contains routines for reading / writing EEPROM flags for the bootloader +#include <stdbool.h> +#include <string.h> +#include <bootloader_utils.h> +#include <spi_flash.h> + +int is_valid_fpga_image(uint32_t addr) { + uint8_t imgbuf[64]; + spi_flash_read(addr, 64, imgbuf); + //we're just looking for leading 0xFF padding, followed by the sync bytes 0xAA 0x99 + int i = 0; + for(i; i<63; i++) { + if(imgbuf[i] == 0xFF) continue; + if(imgbuf[i] == 0xAA && imgbuf[i+1] == 0x99) return 1; + } + + return 0; +} + +int is_valid_fw_image(uint32_t addr) { + static const uint8_t fwheader[] = {0xB0, 0x00, 0x00, 0x00, 0xB8, 0x08}; //just lookin for a jump to anywhere located at the reset vector + uint8_t buf[12]; + spi_flash_read(addr, 6, buf); + return memcmp(buf, fwheader, 6) == 0; +} + +void start_program(uint32_t addr) +{ + memcpy(0x00000000, addr+0x00000000, 36); //copy the whole vector table, with the reset vector, into boot RAM + typedef void (*fptr_t)(void); + (*(fptr_t) 0x00000000)(); // most likely no return +} diff --git a/firmware/microblaze/usrp2p/bootloader_utils.h b/firmware/microblaze/usrp2p/bootloader_utils.h new file mode 100644 index 000000000..f597c0113 --- /dev/null +++ b/firmware/microblaze/usrp2p/bootloader_utils.h @@ -0,0 +1,22 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + */ + +#include <stdint.h> + +//we're working in bytes and byte addresses so we can run the same code with Flash chips of different sector sizes. +//it's really 1463736, but rounded up to 1.5MB +#define FPGA_IMAGE_SIZE_BYTES 1572864 +//instead of 32K, we write 31K because we're using the top 1K for stack space! +#define FW_IMAGE_SIZE_BYTES 31744 + +#define SAFE_FPGA_IMAGE_LOCATION_ADDR 0x00000000 +#define SAFE_FW_IMAGE_LOCATION_ADDR 0x003F0000 +#define PROD_FPGA_IMAGE_LOCATION_ADDR 0x00180000 +#define PROD_FW_IMAGE_LOCATION_ADDR 0x00300000 + +int is_valid_fpga_image(uint32_t addr); +int is_valid_fw_image(uint32_t addr); +void start_program(uint32_t addr); diff --git a/firmware/microblaze/usrp2p/eth_phy.h b/firmware/microblaze/usrp2p/eth_phy.h new file mode 100644 index 000000000..d233e96e8 --- /dev/null +++ b/firmware/microblaze/usrp2p/eth_phy.h @@ -0,0 +1,235 @@ +/* -*- c -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Much of this was extracted from the Linux e1000_hw.h file */ + +#ifndef INCLUDED_ETH_PHY_H +#define INCLUDED_ETH_PHY_H + +/* PHY 1000 MII Register/Bit Definitions */ +/* PHY Registers defined by IEEE */ + +#define PHY_CTRL 0x00 /* Control Register */ +#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ +#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ + +/* PHY 1000 MII Register additions in ET1011C */ +#define PHY_INT_MASK 24 +#define PHY_INT_STATUS 25 +#define PHY_PHY_STATUS 26 +#define PHY_LED2 28 + +/* Bit definitions for some of the registers above */ + +/* PHY Control Register (PHY_CTRL) */ +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ + +/* PHY Status Register (PHY_STATUS) */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +/* Autoneg Advertisement Register (PHY_AUTONEG_ADV) */ +#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ +#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ +#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ +#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ +#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ +#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ +#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ +#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ +#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ +#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ + +/* Link Partner Ability Register (Base Page) (PHY_LP_ABILITY) */ +#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */ +#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */ +#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */ +#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */ +#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */ +#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */ +#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */ +#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */ +#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */ +#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */ +#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */ + +/* Autoneg Expansion Register (PHY_AUTONEG_EXP) */ +#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */ +#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */ +#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */ +#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */ +#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */ + +/* Next Page TX Register (PHY_NEXT_PAGE_TX) */ +#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */ +#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges + * of different NP + */ +#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg + * 0 = cannot comply with msg + */ +#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */ +#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow + * 0 = sending last NP + */ + +/* Link Partner Next Page Register (PHY_LP_NEXT_PAGE) */ +#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */ +#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges + * of different NP + */ +#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg + * 0 = cannot comply with msg + */ +#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */ +#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */ +#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow + * 0 = sending last NP + */ + +/* 1000BASE-T Control Register (PHY_1000T_CTRL) */ +#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */ +#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ +#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ +#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */ + /* 0=DTE device */ +#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ + /* 0=Configure PHY as Slave */ +#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ + /* 0=Automatic Master/Slave config */ +#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ +#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ + +/* 1000BASE-T Status Register (PHY_1000T_STATUS) */ +#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */ +#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */ +#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ +#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ +#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ +#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ +#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ +#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ +#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13 +#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100 + +/* Extended Status Register (PHY_EXT_STATUS) */ +#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ +#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ +#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ +#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ + +#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */ +#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */ + +#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */ + /* (0=enable, 1=disable) */ + +/* PHY Status Register (PHY_PHY_STATUS) */ +#define PHYSTAT_ASYMMETRIC (1 << 0) +#define PHYSTAT_PAUSE (1 << 1) +#define PHYSTAT_AUTONEG_EN (1 << 2) +#define PHYSTAT_COLLISION (1 << 3) +#define PHYSTAT_RXSTAT (1 << 4) +#define PHYSTAT_TXSTAT (1 << 5) +#define PHYSTAT_LINK (1 << 6) +#define PHYSTAT_DUPLEX (1 << 7) +#define PHYSTAT_SPEED_MASK ((1 << 8) | (1 << 9)) +#define PHYSTAT_SPEED_1000 (1 << 9) +#define PHYSTAT_SPEED_100 (1 << 8) +#define PHYSTAT_SPEED_10 0 +#define PHYSTAT_POLARITY (1 << 10) +#define PHYSTAT_MDIX (1 << 11) +#define PHYSTAT_AUTONEG_STAT (1 << 12) +#define PHYSTAT_STANDBY (1 << 13) + +/* Interrupt status, mask and clear regs (PHY_INT_{STATUS,MASK,CLEAR}) */ +#define PHY_INT_ENABLE (1 << 0) +#define PHY_INT_DOWNSHIFT (1 << 1) +#define PHY_INT_LINK_STATUS_CHANGE (1 << 2) +#define PHY_INT_RX_STATUS_CHANGE (1 << 3) +#define PHY_INT_FIFO_ERROR (1 << 4) +#define PHY_INT_ERR_CTR_FULL (1 << 5) +#define PHY_INT_NEXT_PAGE_RX (1 << 6) +#define PHY_INT_CRC_ERROR (1 << 7) +#define PHY_INT_AUTONEG_STATUS_CHANGE (1 << 8) +#define PHY_INT_MDIO_SYNC_LOST (1 << 9) +#define PHY_INT_TDR_IP_PHONE (1 << 10) + +/* PHY LED status register 2 (used for controlling link LED for activity light) */ +#define PHY_LED_TXRX_LSB 12 +#define PHY_LED_LINK_LSB 8 +#define PHY_LED_100_LSB 4 +#define PHY_LED_1000_LSB 0 + +#define LED_1000 0 +#define LED_100_TX 1 +#define LED_10 2 +#define LED_1000_ON_100_BLINK 3 +#define LED_LINK 4 +#define LED_TX 5 +#define LED_RX 6 +#define LED_ACTIVITY 7 +#define LED_FULLDUPLEX 8 +#define LED_COLLISION 9 +#define LED_LINK_ON_ACTIVITY_BLINK 10 +#define LED_LINK_ON_RX_BLINK 11 +#define LED_FULL_DUPLEX_ON_COLLISION_BLINK 12 +#define LED_BLINK 13 +#define LED_ON 14 +#define LED_OFF 15 + + +#endif /* INCLUDED_ETH_PHY_H */ diff --git a/firmware/microblaze/usrp2p/ethernet.c b/firmware/microblaze/usrp2p/ethernet.c new file mode 100644 index 000000000..36d6a17ca --- /dev/null +++ b/firmware/microblaze/usrp2p/ethernet.c @@ -0,0 +1,399 @@ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +//Changes for USRP2P: status registers different (ethernet.h) + +#include "ethernet.h" +#include "memory_map.h" +#include "eth_phy.h" +#include <eth_mac.h> +#include <eth_mac_regs.h> +#include <pic.h> +#include <hal_io.h> +#include <nonstdio.h> +#include <stdbool.h> +#include <i2c.h> +#include "usrp2/fw_common.h" + +#define VERBOSE 0 + +static ethernet_t ed_state; +static ethernet_link_changed_callback_t ed_callback = 0; + +void +ethernet_register_link_changed_callback(ethernet_link_changed_callback_t new_callback) +{ + ed_callback = new_callback; +} + + +static void +ed_set_mac_speed(int speed) +{ + printf("Speed set to %d\n",speed); + /* + switch(speed){ + case 10: + eth_mac->speed = 1; + break; + case 100: + eth_mac->speed = 2; + break; + case 1000: + eth_mac->speed = 4; + break; + default: + break; + } + */ +} + +static void +ed_link_up(int speed) +{ + // putstr("ed_link_up: "); puthex16_nl(speed); + + ed_set_mac_speed(speed); + + //turn on link LED for USRP2P + hal_set_leds(LED_RJ45, LED_RJ45); + + + if (ed_callback) // fire link changed callback + (*ed_callback)(speed); +} + +static void +ed_link_down(void) +{ + // putstr("ed_link_down\n"); + + //turn off link LED for USRP2P + hal_set_leds(0, LED_RJ45); + + if (ed_callback) // fire link changed callback + (*ed_callback)(0); +} + + +static void +ed_link_speed_change(int speed) +{ + ed_link_down(); + ed_link_up(speed); +} + +static void +print_flow_control(int flow_control) +{ + static const char *flow_control_msg[4] = { + "NONE", "WE_TX", "WE_RX", "SYMMETRIC" + }; + putstr("ethernet flow control: "); + puts(flow_control_msg[flow_control & 0x3]); +} + +static void +check_flow_control_resolution(void) +{ + static const unsigned char table[16] = { + // index = {local_asm, local_pause, partner_asm, partner_pause} + FC_NONE, FC_NONE, FC_NONE, FC_NONE, + FC_NONE, FC_SYMM, FC_NONE, FC_SYMM, + FC_NONE, FC_NONE, FC_NONE, FC_WE_TX, + FC_NONE, FC_SYMM, FC_WE_RX, FC_SYMM + }; + + int us = eth_mac_miim_read(PHY_AUTONEG_ADV); + int lp = eth_mac_miim_read(PHY_LP_ABILITY); + int index = (((us >> 10) & 0x3) << 2) | ((lp >> 10) & 0x3); + ed_state.flow_control = table[index]; + + if (1) + print_flow_control(ed_state.flow_control); +} + +/* + * Read the PHY state register to determine link state and speed + */ +static void +ed_check_phy_state(void) +{ + int phystat = eth_mac_miim_read(PHY_PHY_STATUS); + eth_link_state_t new_state = LS_UNKNOWN; + int new_speed = S_UNKNOWN; + + if (VERBOSE){ + putstr("PHYSTAT: "); + puthex16_nl(phystat); + } + + if (phystat & PHYSTAT_LINK){ // link's up + if (VERBOSE) + puts(" LINK_GOOD"); + + new_state = LS_UP; + switch (phystat & PHYSTAT_SPEED_MASK){ + case PHYSTAT_SPEED_10: + new_speed = 10; + break; + + case PHYSTAT_SPEED_100: + new_speed = 100; + break; + + case PHYSTAT_SPEED_1000: + new_speed = 1000; + break; + + default: + new_speed = S_UNKNOWN; + break; + } + + check_flow_control_resolution(); + } + else { // link's down + if (VERBOSE) + puts(" NOT LINK_GOOD"); + + new_state = LS_DOWN; + new_speed = S_UNKNOWN; + } + + if (new_state != ed_state.link_state){ + ed_state.link_state = new_state; // remember new state + if (new_state == LS_UP) + ed_link_up(new_speed); + else if (new_state == LS_DOWN) + ed_link_down(); + } + else if (new_state == LS_UP && new_speed != ed_state.link_speed){ + ed_state.link_speed = new_speed; // remember new speed + ed_link_speed_change(new_speed); + } +} + +/* + * This is fired when the ethernet PHY state changes + */ +static void +eth_phy_irq_handler(unsigned irq) +{ + ed_check_phy_state(); + eth_mac_miim_read(PHY_INT_STATUS); +// eth_mac_miim_write(PHY_INT_CLEAR, ~0); // clear all ints +} + +void +ethernet_init(void) +{ + eth_mac_init(ethernet_mac_addr()); + + ed_state.link_state = LS_UNKNOWN; + ed_state.link_speed = S_UNKNOWN; + + // initialize MAC registers + // eth_mac->tx_hwmark = 0x1e; + //eth_mac->tx_lwmark = 0x19; + + //eth_mac->crc_chk_en = 1; + //eth_mac->rx_max_length = 2048; + + // configure PAUSE frame stuff + //eth_mac->tx_pause_en = 1; // pay attn to pause frames sent to us + + //eth_mac->pause_quanta_set = 38; // a bit more than 1 max frame 16kb/512 + fudge + //eth_mac->pause_frame_send_en = 1; // enable sending pause frames + + + // setup PHY to interrupt on changes + + unsigned mask = + (PHY_INT_ENABLE //master interrupt enable + | PHY_INT_LINK_STATUS_CHANGE + | PHY_INT_RX_STATUS_CHANGE + ); + + eth_mac_miim_read(PHY_INT_STATUS); //clear interrupts + eth_mac_miim_write(PHY_INT_MASK, mask); // enable the ones we want + + //set the LED behavior to activity instead of link + unsigned led = (LED_ACTIVITY << PHY_LED_LINK_LSB) | (LED_TX << PHY_LED_TXRX_LSB); + eth_mac_miim_write(PHY_LED2, led); + + pic_register_handler(IRQ_PHY, eth_phy_irq_handler); + + // Advertise our flow control configuation. + // + // We and the link partner each specify two bits in the base page + // related to autoconfiguration: NWAY_AR_PAUSE and NWAY_AR_ASM_DIR. + // The bits say what a device is "willing" to do, not what may actually + // happen as a result of the negotiation. There are 4 cases: + // + // PAUSE ASM_DIR + // + // 0 0 I have no flow control capability. + // + // 1 0 I both assert and respond to flow control. + // + // 0 1 I assert flow control, but cannot respond. That is, + // I want to be able to send PAUSE frames, but will ignore any + // you send to me. (This is our configuration.) + // + // 1 1 I can both assert and respond to flow control AND I am willing + // to operate symmetrically OR asymmetrically in EITHER direction. + // (We hope the link partner advertises this, otherwise we don't + // get what we want.) + + int t = eth_mac_miim_read(PHY_AUTONEG_ADV); + t &= ~(NWAY_AR_PAUSE | NWAY_AR_ASM_DIR); + t |= NWAY_AR_ASM_DIR; + + // Say we can't to 10BASE-T or 100BASE-TX, half or full duplex + t &= ~(NWAY_AR_10T_HD_CAPS | NWAY_AR_10T_FD_CAPS | NWAY_AR_100TX_HD_CAPS | NWAY_AR_100TX_FD_CAPS); + + eth_mac_miim_write(PHY_AUTONEG_ADV, t); + int r = eth_mac_miim_read(PHY_AUTONEG_ADV); // DEBUG, read back + if (t != r){ + printf("PHY_AUTONEG_ADV: wrote 0x%x, got 0x%x\n", t, r); + } + + // Restart autonegotation. + // We want to ensure that we're advertising our PAUSE capabilities. + t = eth_mac_miim_read(PHY_CTRL); + eth_mac_miim_write(PHY_CTRL, t | MII_CR_RESTART_AUTO_NEG); +} + +static bool +unprogrammed(const void *t, size_t len) +{ + int i; + uint8_t *p = (uint8_t *)t; + bool all_zeros = true; + bool all_ones = true; + for (i = 0; i < len; i++){ + all_zeros &= p[i] == 0x00; + all_ones &= p[i] == 0xff; + } + return all_ones | all_zeros; +} + +//////////////////// MAC Addr Stuff /////////////////////// +/* +static int8_t src_mac_addr_initialized = false; +static eth_mac_addr_t src_mac_addr = {{ + 0x00, 0x50, 0xC2, 0x85, 0x3f, 0xff + }}; + +const eth_mac_addr_t * +ethernet_mac_addr(void) +{ + if (!src_mac_addr_initialized){ // fetch from eeprom + src_mac_addr_initialized = true; + + // if we're simulating, don't read the EEPROM model, it's REALLY slow + if (hwconfig_simulation_p()) + return &src_mac_addr; + + eth_mac_addr_t tmp; + bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, &tmp, sizeof(tmp)); + if (!ok || unprogrammed(&tmp, sizeof(tmp))){ + // use the default + } + else + src_mac_addr = tmp; + } + + return &src_mac_addr; +} + +bool +ethernet_set_mac_addr(const eth_mac_addr_t *t) +{ + bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_MAC_ADDR, t, sizeof(eth_mac_addr_t)); + if (ok){ + src_mac_addr = *t; + src_mac_addr_initialized = true; + //eth_mac_set_addr(t); //this breaks the link + } + + return ok; +} + +//////////////////// IP Addr Stuff /////////////////////// + +static int8_t src_ip_addr_initialized = false; +static struct ip_addr src_ip_addr = { + (192 << 24 | 168 << 16 | 10 << 8 | 2 << 0) +}; + + +const struct ip_addr *get_ip_addr(void) +{ + if (!src_ip_addr_initialized){ // fetch from eeprom + src_ip_addr_initialized = true; + + // if we're simulating, don't read the EEPROM model, it's REALLY slow + if (hwconfig_simulation_p()) + return &src_ip_addr; + + struct ip_addr tmp; + bool ok = eeprom_read(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, &tmp, sizeof(tmp)); + if (!ok || unprogrammed(&tmp, sizeof(tmp))){ + // use the default + } + else + src_ip_addr = tmp; + } + + return &src_ip_addr; +} + +bool set_ip_addr(const struct ip_addr *t){ + bool ok = eeprom_write(USRP2_I2C_ADDR_MBOARD, USRP2_EE_MBOARD_IP_ADDR, t, sizeof(struct ip_addr)); + if (ok){ + src_ip_addr = *t; + src_ip_addr_initialized = true; + } + + return ok; +} +*/ +int +ethernet_check_errors(void) +{ + // these registers are reset when read + + int r = 0; + /* + if (eth_mac_read_rmon(0x05) != 0) + r |= RME_RX_CRC; + if (eth_mac_read_rmon(0x06) != 0) + r |= RME_RX_FIFO_FULL; + if (eth_mac_read_rmon(0x07) != 0) + r |= RME_RX_2SHORT_2LONG; + + if (eth_mac_read_rmon(0x25) != 0) + r |= RME_TX_JAM_DROP; + if (eth_mac_read_rmon(0x26) != 0) + r |= RME_TX_FIFO_UNDER; + if (eth_mac_read_rmon(0x27) != 0) + r |= RME_TX_FIFO_OVER; + */ + return r; +} diff --git a/firmware/microblaze/usrp2p/memory_map.h b/firmware/microblaze/usrp2p/memory_map.h new file mode 100644 index 000000000..3b2dc0057 --- /dev/null +++ b/firmware/microblaze/usrp2p/memory_map.h @@ -0,0 +1,847 @@ +/* -*- c -*- */ +/* + * Copyright 2007,2008,2009 Free Software Foundation, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Overall Memory Map + * 0000-FFFF 64K RAM space + * + * 0000-1FFF 8K Boot RAM + * 2000-5FFF 16K Buffer pool + * 6000-7FFF 8K Peripherals + * 8000-FFFF 32K Main System RAM + + +From u2plus_core.v: +wb_1master #(.decode_w(8), +.s0_addr(8'b0000_0000),.s0_mask(8'b1110_0000), // 0-8K, Boot RAM +.s1_addr(8'b0100_0000),.s1_mask(8'b1100_0000), // 16K-32K, Buffer Pool +.s2_addr(8'b0011_0000),.s2_mask(8'b1111_1111), // SPI 0x3000 +.s3_addr(8'b0011_0001),.s3_mask(8'b1111_1111), // I2C 0x3100 +.s4_addr(8'b0011_0010),.s4_mask(8'b1111_1111), // GPIO 0x3200 +.s5_addr(8'b0011_0011),.s5_mask(8'b1111_1111), // Readback 0x3300 +.s6_addr(8'b0011_0100),.s6_mask(8'b1111_1111), // Ethernet MAC 0x3400 +.s7_addr(8'b0010_0000),.s7_mask(8'b1111_0000), // 8-12K, Settings Bus (only uses 1K) 0x2000-0x2FFF +.s8_addr(8'b0011_0101),.s8_mask(8'b1111_1111), // PIC 0x3500 +.s9_addr(8'b0011_0110),.s9_mask(8'b1111_1111), // Unused 0x3600 +.sa_addr(8'b0011_0111),.sa_mask(8'b1111_1111), // UART 0x3700 +.sb_addr(8'b0011_1000),.sb_mask(8'b1111_1111), // ATR 0x3800 +.sc_addr(8'b0011_1001),.sc_mask(8'b1111_1111), // Unused 0x3900 +.sd_addr(8'b0011_1010),.sd_mask(8'b1111_1111), // ICAP 0x3A00 +.se_addr(8'b0011_1011),.se_mask(8'b1111_1111), // SPI Flash 0x3B00 +.sf_addr(8'b1000_0000),.sf_mask(8'b1000_0000), // 32-64K, Main RAM 0x8000-0xFFFF + .dw(dw),.aw(aw),.sw(sw)) wb_1master + + */ + + +#ifndef INCLUDED_MEMORY_MAP_H +#define INCLUDED_MEMORY_MAP_H + +#include <stdint.h> + + +#define MASTER_CLK_RATE 100000000 // 100 MHz + + +//////////////////////////////////////////////////////////////// +// +// Memory map for embedded wishbone bus +// +//////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////// +// Boot RAM, Slave 0 + +#define BOOTRAM_BASE 0x0000 + + +//////////////////////////////////////////////////////////////// +// Buffer Pool RAM, Slave 1 +// +// The buffers themselves are located in Slave 1, Buffer Pool RAM. +// The status registers are in Slave 5, Buffer Pool Status. +// The control register is in Slave 7, Settings Bus. + +#define BUFFER_POOL_RAM_BASE 0x4000 + +#define NBUFFERS 8 +#define BP_NLINES 0x0200 // number of 32-bit lines in a buffer +#define BP_LAST_LINE (BP_NLINES - 1) // last line in a buffer + +#define buffer_pool_ram \ + ((uint32_t *) BUFFER_POOL_RAM_BASE) + +#define buffer_ram(n) (&buffer_pool_ram[(n) * BP_NLINES]) + + +///////////////////////////////////////////////////// +// SPI Core, Slave 2. See core docs for more info +#define SPI_BASE 0x3000 // Base address (16-bit) is base peripheral addr + +typedef struct { + volatile uint32_t txrx0; + volatile uint32_t txrx1; + volatile uint32_t txrx2; + volatile uint32_t txrx3; + volatile uint32_t ctrl; + volatile uint32_t div; + volatile uint32_t ss; +} spi_regs_t; + +#define spi_regs ((spi_regs_t *) SPI_BASE) + + +// Masks for controlling different peripherals +#define SPI_SS_AD9510 1 +#define SPI_SS_AD9777 2 +#define SPI_SS_RX_DAC 4 +#define SPI_SS_RX_ADC 8 +#define SPI_SS_RX_DB 16 +#define SPI_SS_TX_DAC 32 +#define SPI_SS_TX_ADC 64 +#define SPI_SS_TX_DB 128 +#define SPI_SS_ADS62P44 256 + +// Masks for different parts of CTRL reg +#define SPI_CTRL_ASS (1<<13) +#define SPI_CTRL_IE (1<<12) +#define SPI_CTRL_LSB (1<<11) +#define SPI_CTRL_TXNEG (1<<10) +#define SPI_CTRL_RXNEG (1<< 9) +#define SPI_CTRL_GO_BSY (1<< 8) +#define SPI_CTRL_CHAR_LEN_MASK 0x7F + +//////////////////////////////////////////////// +// I2C, Slave 3 +// See Wishbone I2C-Master Core Specification. + +#define I2C_BASE 0x3100 + +typedef struct { + volatile uint32_t prescaler_lo; // r/w + volatile uint32_t prescaler_hi; // r/w + volatile uint32_t ctrl; // r/w + volatile uint32_t data; // wr = transmit reg; rd = receive reg + volatile uint32_t cmd_status; // wr = command reg; rd = status reg +} i2c_regs_t; + +#define i2c_regs ((i2c_regs_t *) I2C_BASE) + +#define I2C_CTRL_EN (1 << 7) // core enable +#define I2C_CTRL_IE (1 << 6) // interrupt enable + +// +// STA, STO, RD, WR, and IACK bits are cleared automatically +// +#define I2C_CMD_START (1 << 7) // generate (repeated) start condition +#define I2C_CMD_STOP (1 << 6) // generate stop condition +#define I2C_CMD_RD (1 << 5) // read from slave +#define I2C_CMD_WR (1 << 4) // write to slave +#define I2C_CMD_NACK (1 << 3) // when a rcvr, send ACK (ACK=0) or NACK (ACK=1) +#define I2C_CMD_RSVD_2 (1 << 2) // reserved +#define I2C_CMD_RSVD_1 (1 << 1) // reserved +#define I2C_CMD_IACK (1 << 0) // set to clear pending interrupt + +#define I2C_ST_RXACK (1 << 7) // Received acknowledgement from slave (1 = NAK, 0 = ACK) +#define I2C_ST_BUSY (1 << 6) // 1 after START signal detected; 0 after STOP signal detected +#define I2C_ST_AL (1 << 5) // Arbitration lost. 1 when core lost arbitration +#define I2C_ST_RSVD_4 (1 << 4) // reserved +#define I2C_ST_RSVD_3 (1 << 3) // reserved +#define I2C_ST_RSVD_2 (1 << 2) // reserved +#define I2C_ST_TIP (1 << 1) // Transfer-in-progress +#define I2C_ST_IP (1 << 0) // Interrupt pending + + +//////////////////////////////////////////////// +// GPIO, Slave 4 +// +// These go to the daughterboard i/o pins + +#define GPIO_BASE 0x3200 + +typedef struct { + volatile uint32_t io; // tx data in high 16, rx in low 16 + volatile uint32_t ddr; // 32 bits, 1 means output. tx in high 16, rx in low 16 + volatile uint32_t tx_sel; // 16 2-bit fields select which source goes to TX DB + volatile uint32_t rx_sel; // 16 2-bit fields select which source goes to RX DB +} gpio_regs_t; + +// each 2-bit sel field is layed out this way +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic +#define GPIO_SEL_DEBUG_0 2 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 3 // if pin is an output, debug lines from FPGA fabric + +#define gpio_base ((gpio_regs_t *) GPIO_BASE) + +/////////////////////////////////////////////////// +// Buffer Pool Status, Slave 5 +// +// The buffers themselves are located in Slave 1, Buffer Pool RAM. +// The status registers are in Slave 5, Buffer Pool Status. +// The control register is in Slave 7, Settings Bus. + +#define BUFFER_POOL_STATUS_BASE 0x3300 + +typedef struct { + volatile uint32_t last_line[NBUFFERS]; // last line xfer'd in buffer + volatile uint32_t status; // error and done flags + volatile uint32_t hw_config; // see below + volatile uint32_t dummy[3]; + volatile uint32_t irqs; + volatile uint32_t pri_enc_bp_status; + volatile uint32_t cycle_count; +} buffer_pool_status_t; + +#define buffer_pool_status ((buffer_pool_status_t *) BUFFER_POOL_STATUS_BASE) + +#define BUTTON_PUSHED ((buffer_pool_status->irqs & PIC_BUTTON) ? 0 : 1) + +/* + * Buffer n's xfer is done. + * Clear this bit by issuing bp_clear_buf(n) + */ +#define BPS_DONE(n) (0x00000001 << (n)) +#define BPS_DONE_0 BPS_DONE(0) +#define BPS_DONE_1 BPS_DONE(1) +#define BPS_DONE_2 BPS_DONE(2) +#define BPS_DONE_3 BPS_DONE(3) +#define BPS_DONE_4 BPS_DONE(4) +#define BPS_DONE_5 BPS_DONE(5) +#define BPS_DONE_6 BPS_DONE(6) +#define BPS_DONE_7 BPS_DONE(7) + +/* + * Buffer n's xfer had an error. + * Clear this bit by issuing bp_clear_buf(n) + */ +#define BPS_ERROR(n) (0x00000100 << (n)) +#define BPS_ERROR_0 BPS_ERROR(0) +#define BPS_ERROR_1 BPS_ERROR(1) +#define BPS_ERROR_2 BPS_ERROR(2) +#define BPS_ERROR_3 BPS_ERROR(3) +#define BPS_ERROR_4 BPS_ERROR(4) +#define BPS_ERROR_5 BPS_ERROR(5) +#define BPS_ERROR_6 BPS_ERROR(6) +#define BPS_ERROR_7 BPS_ERROR(7) + +/* + * Buffer n is idle. A buffer is idle if it's not + * DONE, ERROR, or processing a transaction. If it's + * IDLE, it's safe to start a new transaction. + * + * Clear this bit by starting a xfer with + * bp_send_from_buf or bp_receive_to_buf. + */ +#define BPS_IDLE(n) (0x00010000 << (n)) +#define BPS_IDLE_0 BPS_IDLE(0) +#define BPS_IDLE_1 BPS_IDLE(1) +#define BPS_IDLE_2 BPS_IDLE(2) +#define BPS_IDLE_3 BPS_IDLE(3) +#define BPS_IDLE_4 BPS_IDLE(4) +#define BPS_IDLE_5 BPS_IDLE(5) +#define BPS_IDLE_6 BPS_IDLE(6) +#define BPS_IDLE_7 BPS_IDLE(7) + +/* + * Buffer n has a "slow path" packet in it. + * This bit is orthogonal to the bits above and indicates that + * the FPGA ethernet rx protocol engine has identified this packet + * as one requiring firmware intervention. + */ +#define BPS_SLOWPATH(n) (0x01000000 << (n)) +#define BPS_SLOWPATH_0 BPS_SLOWPATH(0) +#define BPS_SLOWPATH_1 BPS_SLOWPATH(1) +#define BPS_SLOWPATH_2 BPS_SLOWPATH(2) +#define BPS_SLOWPATH_3 BPS_SLOWPATH(3) +#define BPS_SLOWPATH_4 BPS_SLOWPATH(4) +#define BPS_SLOWPATH_5 BPS_SLOWPATH(5) +#define BPS_SLOWPATH_6 BPS_SLOWPATH(6) +#define BPS_SLOWPATH_7 BPS_SLOWPATH(7) + + +#define BPS_DONE_ALL 0x000000ff // mask of all dones +#define BPS_ERROR_ALL 0x0000ff00 // mask of all errors +#define BPS_IDLE_ALL 0x00ff0000 // mask of all idles +#define BPS_SLOWPATH_ALL 0xff000000 // mask of all slowpaths + +// The hw_config register + +#define HWC_SIMULATION 0x80000000 +#define HWC_WB_CLK_DIV_MASK 0x0000000f + +/*! + * \brief return non-zero if we're running under the simulator + */ +inline static int +hwconfig_simulation_p(void) +{ + return buffer_pool_status->hw_config & HWC_SIMULATION; +} + +/*! + * \brief Return Wishbone Clock divisor. + * The processor runs at the Wishbone Clock rate which is MASTER_CLK_RATE / divisor. + */ +inline static int +hwconfig_wishbone_divisor(void) +{ + return buffer_pool_status->hw_config & HWC_WB_CLK_DIV_MASK; +} + +/////////////////////////////////////////////////// +// Ethernet Core, Slave 6 + +#define ETH_BASE 0x3400 + +#include "eth_mac_regs.h" + +#define eth_mac ((eth_mac_regs_t *) ETH_BASE) + +//////////////////////////////////////////////////// +// Settings Bus, Slave #7, Not Byte Addressable! +// +// Output-only from processor point-of-view. +// 1KB of address space (== 256 32-bit write-only regs) + + +#define MISC_OUTPUT_BASE 0x2000 +#define TX_PROTOCOL_ENGINE_BASE 0x2080 +#define RX_PROTOCOL_ENGINE_BASE 0x20C0 +#define BUFFER_POOL_CTRL_BASE 0x2100 +#define LAST_SETTING_REG 0x23FC // last valid setting register + +#define SR_MISC 0 +#define SR_TX_PROT_ENG 32 +#define SR_RX_PROT_ENG 48 +#define SR_BUFFER_POOL_CTRL 64 +#define SR_UDP_SM 96 +#define SR_TX_DSP 208 +#define SR_TX_CTRL 224 +#define SR_RX_DSP 160 +#define SR_RX_CTRL 176 +#define SR_TIME64 192 +#define SR_SIMTIMER 198 +#define SR_LAST 255 + +#define _SR_ADDR(sr) (MISC_OUTPUT_BASE + (sr) * sizeof(uint32_t)) + +// --- buffer pool control regs --- + +typedef struct { + volatile uint32_t ctrl; +} buffer_pool_ctrl_t; + +// buffer pool ports + +#define PORT_SERDES 0 // serial/deserializer +#define PORT_DSP 1 // DSP tx or rx pipeline +#define PORT_ETH 2 // ethernet tx or rx +#define PORT_RAM 3 // RAM tx or rx + +// the buffer pool ctrl register fields + +#define BPC_BUFFER(n) (((n) & 0xf) << 28) +#define BPC_BUFFER_MASK BPC_BUFFER(~0) +#define BPC_BUFFER_0 BPC_BUFFER(0) +#define BPC_BUFFER_1 BPC_BUFFER(1) +#define BPC_BUFFER_2 BPC_BUFFER(2) +#define BPC_BUFFER_3 BPC_BUFFER(3) +#define BPC_BUFFER_4 BPC_BUFFER(4) +#define BPC_BUFFER_5 BPC_BUFFER(5) +#define BPC_BUFFER_6 BPC_BUFFER(6) +#define BPC_BUFFER_7 BPC_BUFFER(7) +#define BPC_BUFFER_NIL BPC_BUFFER(0x8) // disable + +#define BPC_PORT(n) (((n) & 0x7) << 25) +#define BPC_PORT_MASK BPC_PORT(~0) +#define BPC_PORT_SERDES BPC_PORT(PORT_SERDES) +#define BPC_PORT_DSP BPC_PORT(PORT_DSP) +#define BPC_PORT_ETH BPC_PORT(PORT_ETH) +#define BPC_PORT_RAM BPC_PORT(PORT_RAM) +#define BPC_PORT_NIL BPC_PORT(0x4) // disable + +#define BPC_CLR (1 << 24) // mutually excl commands +#define BPC_READ (1 << 23) +#define BPC_WRITE (1 << 22) + +#define BPC_STEP(step) (((step) & 0xf) << 18) +#define BPC_STEP_MASK BPC_STEP(~0) +#define BPC_LAST_LINE(line) (((line) & 0x1ff) << 9) +#define BPC_LAST_LINE_MASK BPC_LAST_LINE(~0) +#define BPC_FIRST_LINE(line) (((line) & 0x1ff) << 0) +#define BPC_FIRST_LINE_MASK BPC_FIRST_LINE(~0) + +#define buffer_pool_ctrl ((buffer_pool_ctrl_t *) BUFFER_POOL_CTRL_BASE) + +// --- misc outputs --- + +typedef struct { + volatile uint32_t clk_ctrl; + volatile uint32_t serdes_ctrl; + volatile uint32_t adc_ctrl; + volatile uint32_t leds; + volatile uint32_t phy_ctrl; // LSB is reset line to eth phy + volatile uint32_t debug_mux_ctrl; + volatile uint32_t ram_page; // FIXME should go somewhere else... + volatile uint32_t flush_icache; // Flush the icache + volatile uint32_t led_src; // HW or SW control for LEDs +} output_regs_t; + +#define CLK_RESET (1<<4) +#define CLK_ENABLE (1<<3) | (1<<2) +#define CLK_SEL (1<<1) | (1<<0) + +#define SERDES_ENABLE 8 +#define SERDES_PRBSEN 4 +#define SERDES_LOOPEN 2 +#define SERDES_RXEN 1 + +#define ADC_CTRL_ON 0x0F +#define ADC_CTRL_OFF 0x00 + +// crazy order that matches the labels on the case + +#define LED_A (1 << 2) +#define LED_B (1 << 0) +#define LED_E (1 << 3) +#define LED_D (1 << 1) +#define LED_C (1 << 4) +// LED_F // controlled by CPLD +#define LED_RJ45 (1 << 5) + +#define output_regs ((output_regs_t *) MISC_OUTPUT_BASE) + +// --- udp tx regs --- + +typedef struct { + // Bits 19:16 are control info; bits 15:0 are data (see below) + // First two words are unused. + volatile uint32_t _nope[2]; + //--- ethernet header - 14 bytes--- + volatile struct{ + uint32_t mac_dst_0_1; //word 2 + uint32_t mac_dst_2_3; + uint32_t mac_dst_4_5; + uint32_t mac_src_0_1; + uint32_t mac_src_2_3; + uint32_t mac_src_4_5; + uint32_t ether_type; //word 8 + } eth_hdr; + //--- ip header - 20 bytes --- + volatile struct{ + uint32_t ver_ihl_tos; //word 9 + uint32_t total_length; + uint32_t identification; + uint32_t flags_frag_off; + uint32_t ttl_proto; + uint32_t checksum; + uint32_t src_addr_high; + uint32_t src_addr_low; + uint32_t dst_addr_high; + uint32_t dst_addr_low; //word 18 + } ip_hdr; + //--- udp header - 8 bytes --- + volatile struct{ + uint32_t src_port; //word 19 + uint32_t dst_port; + uint32_t length; + uint32_t checksum; //word 22 + } udp_hdr; + volatile uint32_t _pad[32-23]; +} sr_udp_sm_t; + +// control bits (all expect UDP_SM_LAST_WORD are mutually exclusive) + +// This is the last word of the header +#define UDP_SM_LAST_WORD (1 << 19) + +// Insert IP header checksum here. Data is the xor of 16'hFFFF and +// the values written into regs 9-13 and 15-18. +#define UDP_SM_INS_IP_HDR_CHKSUM (1 << 18) + +// Insert IP Length here (data ignored) +#define UDP_SM_INS_IP_LEN (1 << 17) + +// Insert UDP Length here (data ignore) +#define UDP_SM_INS_UDP_LEN (1 << 16) + +#define sr_udp_sm ((sr_udp_sm_t *) _SR_ADDR(SR_UDP_SM)) + +// --- dsp tx regs --- + +#define MIN_CIC_INTERP 1 +#define MAX_CIC_INTERP 128 + +typedef struct { + volatile uint32_t num_chan; + volatile uint32_t clear_state; // clears out state machine, fifos, + volatile uint32_t report_sid; + volatile uint32_t policy; + volatile uint32_t cyc_per_up; + volatile uint32_t packets_per_up; +} sr_tx_ctrl_t; + +#define sr_tx_ctrl ((sr_tx_ctrl_t *) _SR_ADDR(SR_TX_CTRL)) + +typedef struct { + volatile int32_t freq; + volatile uint32_t scale_iq; // {scale_i,scale_q} + volatile uint32_t interp_rate; + volatile uint32_t _padding0; // padding for the tx_mux + // NOT freq, scale, interp + /*! + * \brief output mux configuration. + * + * <pre> + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-------------------------------+-------+-------+-------+-------+ + * | | DAC1 | DAC0 | + * +-------------------------------+-------+-------+-------+-------+ + * + * There are N DUCs (1 now) with complex inputs and outputs. + * There are two DACs. + * + * Each 4-bit DACx field specifies the source for the DAC + * Each subfield is coded like this: + * + * 3 2 1 0 + * +-------+ + * | N | + * +-------+ + * + * N specifies which DUC output is connected to this DAC. + * + * N which interp output + * --- ------------------- + * 0 DUC 0 I + * 1 DUC 0 Q + * 2 DUC 1 I + * 3 DUC 1 Q + * F All Zeros + * + * The default value is 0x10 + * </pre> + */ + volatile uint32_t tx_mux; + +} dsp_tx_regs_t; + +#define dsp_tx_regs ((dsp_tx_regs_t *) _SR_ADDR(SR_TX_DSP)) + +// --- VITA RX CTRL regs --- +typedef struct { + // The following 3 are logically a single command register. + // They are clocked into the underlying fifo when time_ticks is written. + volatile uint32_t cmd; // {now, chain, num_samples(30) + volatile uint32_t time_secs; + volatile uint32_t time_ticks; + + volatile uint32_t clear_overrun; // write anything to clear overrun + volatile uint32_t vrt_header; // word 0 of packet. FPGA fills in packet counter + volatile uint32_t vrt_stream_id; // word 1 of packet. + volatile uint32_t vrt_trailer; + volatile uint32_t nsamples_per_pkt; + volatile uint32_t nchannels; // 1 in basic case, up to 4 for vector sources + volatile uint32_t pad[7]; // Make each structure 16 elements long +} sr_rx_ctrl_t; + +#define sr_rx_ctrl ((sr_rx_ctrl_t *) _SR_ADDR(SR_RX_CTRL)) + +// --- dsp rx regs --- +#define MIN_CIC_DECIM 1 +#define MAX_CIC_DECIM 128 + +typedef struct { + volatile int32_t freq; + volatile uint32_t scale_iq; // {scale_i,scale_q} + volatile uint32_t decim_rate; + volatile uint32_t dcoffset_i; // Bit 31 high sets fixed offset mode, using lower 14 bits, + // otherwise it is automatic + volatile uint32_t dcoffset_q; // Bit 31 high sets fixed offset mode, using lower 14 bits + + /*! + * \brief input mux configuration. + * + * This determines which ADC (or constant zero) is connected to + * each DDC input. There are N DDCs (1 now). Each has two inputs. + * + * <pre> + * Mux value: + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | |Q0 |I0 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + * Each 2-bit I field is either 00 (A/D A), 01 (A/D B) or 1X (const zero) + * Each 2-bit Q field is either 00 (A/D A), 01 (A/D B) or 1X (const zero) + * + * The default value is 0x4 + * </pre> + */ + volatile uint32_t rx_mux; // called adc_mux in dsp_core_rx.v + + /*! + * \brief Streaming GPIO configuration + * + * This determines whether the LSBs of I and Q samples come from the DSP + * pipeline or from the io_rx GPIO pins. To stream GPIO, one must first + * set the GPIO data direction register to have io_rx[15] and/or io_rx[14] + * configured as inputs. The GPIO pins will be sampled at the time the + * remainder of the DSP sample is strobed into the RX sample FIFO. There + * will be a decimation-dependent fixed time offset between the GPIO + * sample stream and the associated RF samples. + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | MBZ |Q|I| + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + * I 0=LSB comes from DSP pipeline (default) + * 1=LSB comes from io_rx[15] + * + * Q 0=LSB comes from DSP pipeline (default) + * 1=LSB comes from io_rx[14] + */ + volatile uint32_t gpio_stream_enable; + +} dsp_rx_regs_t; + +#define dsp_rx_regs ((dsp_rx_regs_t *) _SR_ADDR(SR_RX_DSP)) + +// ---------------------------------------------------------------- +// VITA49 64 bit time (write only) + /*! + * \brief Time 64 flags + * + * <pre> + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------------------------------------------------------+-+-+ + * | |S|P| + * +-----------------------------------------------------------+-+-+ + * + * P - PPS edge selection (0=negedge, 1=posedge, default=0) + * S - Source (0=sma, 1=mimo, 0=default) + * + * </pre> + */ +typedef struct { + volatile uint32_t secs; // value to set absolute secs to on next PPS + volatile uint32_t ticks; // value to set absolute ticks to on next PPS + volatile uint32_t flags; // flags - see chart above + volatile uint32_t imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) +} sr_time64_t; + +#define sr_time64 ((sr_time64_t *) _SR_ADDR(SR_TIME64)) + + +/* + * --- ethernet tx protocol engine regs (write only) --- + * + * These registers control the transmit portion of the ethernet + * protocol engine (out of USRP2). The protocol engine handles fifo + * status and sequence number insertion in outgoing packets, and + * automagically generates status packets when required to inform the + * host of changes in fifo availability. + * + * All outgoing packets have their fifo_status field set to the number + * of 32-bit lines of fifo available in the ethernet Rx fifo (see + * usrp2_eth_packet.h). Seqno's are set if FIXME, else 0. + * + * FIXME clean this up once we know how it's supposed to behave. + */ + +typedef struct { + volatile uint32_t flags; // not yet fully defined (channel?) + volatile uint32_t mac_dst0123; // 4 bytes of destination mac addr + volatile uint32_t mac_dst45src01; // 2 bytes of dest mac addr; 2 bytes of src mac addr + volatile uint32_t mac_src2345; // 4 bytes of destination mac addr + volatile uint32_t seqno; // Write to init seqno. It autoincs on match +} tx_proto_engine_regs_t; + +#define tx_proto_engine ((tx_proto_engine_regs_t *) TX_PROTOCOL_ENGINE_BASE) + +/* + * --- ethernet rx protocol engine regs (write only) --- + * + * These registers control the receive portion of the ethernet + * protocol engine (into USRP2). The protocol engine offloads common + * packet inspection operations so that firmware has less to do on + * "fast path" packets. + * + * The registers define conditions which must be matched for a packet + * to be considered a "fast path" packet. If a received packet + * matches the src and dst mac address, ethertype, flags field, and + * expected seqno number it is considered a "fast path" packet, and + * the expected seqno is updated. If the packet fails to satisfy any + * of the above conditions it's a "slow path" packet, and the + * corresponding SLOWPATH flag will be set buffer_status register. + */ + +typedef struct { + volatile uint32_t flags; // not yet fully defined (channel?) + volatile uint32_t mac_dst0123; // 4 bytes of destination mac addr + volatile uint32_t mac_dst45src01; // 2 bytes of dest mac addr; 2 bytes of src mac addr + volatile uint32_t mac_src2345; // 4 bytes of destination mac addr + volatile uint32_t ethertype_pad; // ethertype in high 16-bits +} rx_proto_engine_regs_t; + +#define rx_proto_engine ((rx_proto_engine_regs_t *) RX_PROTOCOL_ENGINE_BASE) + + + +/////////////////////////////////////////////////// +// Simple Programmable Interrupt Controller, Slave 8 + +#define PIC_BASE 0x3500 + +// Interrupt request lines +// Bit numbers (LSB == 0) that correpond to interrupts into PIC + +#define IRQ_BUFFER 0 // buffer manager +#define IRQ_ONETIME 1 +#define IRQ_SPI 2 +#define IRQ_I2C 3 +#define IRQ_PHY 4 // ethernet PHY +#define IRQ_UNDERRUN 5 +#define IRQ_OVERRUN 6 +#define IRQ_PPS 7 // pulse per second +#define IRQ_UART_RX 8 +#define IRQ_UART_TX 9 +#define IRQ_SERDES 10 +#define IRQ_CLKSTATUS 11 +#define IRQ_PERIODIC 12 +#define IRQ_BUTTON 13 + +#define IRQ_TO_MASK(x) (1 << (x)) + +#define PIC_BUFFER_INT IRQ_TO_MASK(IRQ_BUFFER) +#define PIC_ONETIME_INT IRQ_TO_MASK(IRQ_ONETIME) +#define PIC_SPI_INT IRQ_TO_MASK(IRQ_SPI) +#define PIC_I2C_INT IRQ_TO_MASK(IRQ_I2C) +#define PIC_PHY_INT IRQ_TO_MASK(IRQ_PHY) +#define PIC_UNDERRUN_INT IRQ_TO_MASK(IRQ_UNDERRUN) +#define PIC_OVERRUN_INT IRQ_TO_MASK(IRQ_OVERRUN) +#define PIC_PPS_INT IRQ_TO_MASK(IRQ_PPS) +#define PIC_UART_RX_INT IRQ_TO_MASK(IRQ_UART_RX) +#define PIC_UART_TX_INT IRQ_TO_MASK(IRQ_UART_TX) +#define PIC_SERDES IRQ_TO_MASK(IRQ_SERDES) +#define PIC_CLKSTATUS IRQ_TO_MASK(IRQ_CLKSTATUS) +#define PIC_BUTTON IRQ_TO_MASK(IRQ_BUTTON) + +typedef struct { + volatile uint32_t edge_enable; // mask: 1 -> edge triggered, 0 -> level + volatile uint32_t polarity; // mask: 1 -> rising edge + volatile uint32_t mask; // mask: 1 -> disabled + volatile uint32_t pending; // mask: 1 -> pending; write 1's to clear pending ints +} pic_regs_t; + +#define pic_regs ((pic_regs_t *) PIC_BASE) + +// ---------------------------------------------------------------- +// WB_CLK_RATE is the time base for this +typedef struct { + volatile uint32_t onetime; // Number of wb clk cycles till the onetime interrupt + volatile uint32_t periodic; // Repeat rate of periodic interrupt +} sr_simple_timer_t; + +#define sr_simple_timer ((sr_simple_timer_t *) _SR_ADDR(SR_SIMTIMER)) + +/////////////////////////////////////////////////// +// UNUSED, Slave 9 + +/////////////////////////////////////////////////// +// UART, Slave 10 + +#define UART_BASE 0x3700 + +typedef struct { + // All elements are 8 bits except for clkdiv (16), but we use uint32 to make + // the hardware for decoding easier + volatile uint32_t clkdiv; // Set to 50e6 divided by baud rate (no x16 factor) + volatile uint32_t txlevel; // Number of spaces in the FIFO for writes + volatile uint32_t rxlevel; // Number of available elements in the FIFO for reads + volatile uint32_t txchar; // Write characters to be sent here + volatile uint32_t rxchar; // Read received characters here + volatile uint32_t x[3]; //padding to reach 32B +} uart_regs_t; + +#define uart_regs ((uart_regs_t *) UART_BASE) + +/////////////////////////////////////////////////// +// ATR Controller, Slave 11 + +#define ATR_BASE 0x3800 + +typedef struct { + volatile uint32_t v[16]; +} atr_regs_t; + +#define ATR_IDLE 0x0 // indicies into v +#define ATR_TX 0x1 +#define ATR_RX 0x2 +#define ATR_FULL 0x3 + +#define atr_regs ((atr_regs_t *) ATR_BASE) + +/////////////////////////////////////////////////// +// UNUSED, Slave 12 + +/////////////////////////////////////////////////// +// ICAP, Slave 13 + +#define ICAP_BASE 0x3A00 +typedef struct { + uint32_t icap; //only the lower 8 bits matter +} icap_regs_t; + +#define icap_regs ((icap_regs_t *) ICAP_BASE) + +/////////////////////////////////////////////////// +// SPI Flash interface, Slave 14 +// Control register definitions are the same as SPI, so use SPI_CTRL_ASS, etc. +// Peripheral mask not needed since bus is dedicated (CE held low) + +#define SPIF_BASE 0x3B00 +typedef struct { + volatile uint32_t txrx0; + volatile uint32_t txrx1; + volatile uint32_t txrx2; + volatile uint32_t txrx3; + volatile uint32_t ctrl; + volatile uint32_t div; + volatile uint32_t ss; +} spif_regs_t; + +#define spif_regs ((spif_regs_t *) SPIF_BASE) + +//////////////////////////////////////////////////////////////// +// Main RAM, Slave 15 + +#define RAM_BASE 0x8000 + + + +/////////////////////////////////////////////////// +#endif + diff --git a/firmware/microblaze/usrp2p/spi_flash.c b/firmware/microblaze/usrp2p/spi_flash.c new file mode 100644 index 000000000..09b74a513 --- /dev/null +++ b/firmware/microblaze/usrp2p/spi_flash.c @@ -0,0 +1,194 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "spi_flash_private.h" +//#include <stdlib.h> +#include <nonstdio.h> + +uint32_t +spi_flash_rdsr(void) +{ + return spif_transact(SPI_TXRX, SPI_SS_FLASH, RDSR_CMD << 8, 16, FLAGS) & 0xff; +} + +static void +spi_flash_write_enable(void) +{ +// spif_transact(SPI_TXONLY, SPI_SS_FLASH, (WRSR_CMD << 8) | 0x00, 16, FLAGS); //disable write protection bits + spif_transact(SPI_TXONLY, SPI_SS_FLASH, WREN_CMD, 8, FLAGS); +} + +bool +spi_flash_done_p(void) +{ + return (spi_flash_rdsr() & SR_WIP) == 0; +} + +void +spi_flash_wait(void) +{ + while (!spi_flash_done_p()) + ; +} + +void +spi_flash_erase_sector_start(uint32_t flash_addr) +{ + //uprintf(UART_DEBUG, "spi_flash_erase_sector_start: addr = 0x%x\n", flash_addr); + + spi_flash_wait(); + spi_flash_write_enable(); + spif_transact(SPI_TXONLY, SPI_SS_FLASH, + (SE_CMD << 24) | (flash_addr & 0x00ffffff), + 32, FLAGS); +} + +bool +spi_flash_page_program_start(uint32_t flash_addr, size_t nbytes, const void *buf) +{ + if (nbytes == 0 || nbytes > SPI_FLASH_PAGE_SIZE) + return false; + + uint32_t local_buf[SPI_FLASH_PAGE_SIZE / sizeof(uint32_t)]; + memset(local_buf, 0xff, sizeof(local_buf)); // init to 0xff (nops when programming) + memcpy(local_buf, buf, nbytes); + + spi_flash_wait(); + spi_flash_write_enable(); + + /* + * We explicitly control the slave select here (/S), so that we can + * do the entire write operation as a single transaction from + * device's point of view. (The most our SPI peripheral can transfer + * in a single shot is 16 bytes.) + */ + spif_wait(); + + spif_regs->ss = 0; + spif_regs->ctrl = FLAGS; // ASS is now clear and no chip select is enabled. + + /* write PP_CMD, ADDR2, ADDR1, ADDR0 */ + + spif_regs->txrx0 = (PP_CMD << 24) | (flash_addr & 0x00ffffff); + spif_regs->ss = SPI_SS_FLASH; // assert chip select + spif_regs->ctrl = FLAGS | LEN(4 * 8); + spif_regs->ctrl = FLAGS | LEN(4 * 8) | SPI_CTRL_GO_BSY; + spif_wait(); + + /* send 256 bytes total, 16 at a time */ + for (size_t i = 0; i < 16; i++){ + spif_regs->txrx3 = local_buf[i * 4 + 0]; + spif_regs->txrx2 = local_buf[i * 4 + 1]; + spif_regs->txrx1 = local_buf[i * 4 + 2]; + spif_regs->txrx0 = local_buf[i * 4 + 3]; + + spif_regs->ctrl = FLAGS | LEN(16 * 8); // xfer 16 bytes + spif_regs->ctrl = FLAGS | LEN(16 * 8) | SPI_CTRL_GO_BSY; + spif_wait(); + } + spif_regs->ss = 0; // desassert chip select + + return true; +} + +void +spi_flash_erase(uint32_t flash_addr, size_t nbytes) +{ + if (nbytes == 0) + return; + + uint32_t first = round_down(flash_addr, spi_flash_sector_size()); + uint32_t last = round_down(flash_addr + nbytes - 1, spi_flash_sector_size()); + + for (uint32_t s = first; s <= last; s += spi_flash_sector_size()){ + spi_flash_erase_sector_start(s); + } + spi_flash_wait(); +} + +bool +spi_flash_program(uint32_t flash_addr, size_t nbytes, const void *buf) +{ + //uprintf(UART_DEBUG, "\nspi_flash_program: addr = 0x%x, nbytes = %d\n", flash_addr, nbytes); + + const unsigned char *p = (const unsigned char *) buf; + size_t n; + + if (nbytes == 0) + return true; + + uint32_t r = flash_addr % SPI_FLASH_PAGE_SIZE; + if (r){ /* do initial non-aligned page */ + n = min(SPI_FLASH_PAGE_SIZE - r, nbytes); + spi_flash_page_program_start(flash_addr, n, p); + flash_addr += n; + p += n; + nbytes -= n; + } + + while (nbytes > 0){ + n = min(SPI_FLASH_PAGE_SIZE, nbytes); + spi_flash_page_program_start(flash_addr, n, p); + flash_addr += n; + p += n; + nbytes -= n; + } + + spi_flash_wait(); + return true; +} + +void +spi_flash_async_erase_start(spi_flash_async_state_t *s, + uint32_t flash_addr, size_t nbytes) +{ + if (nbytes == 0){ + s->first = s->last = s->current = 0; + return; + } + + uint32_t first = round_down(flash_addr, spi_flash_sector_size()); + uint32_t last = round_down(flash_addr + nbytes - 1, spi_flash_sector_size()); + + s->first = first; + s->last = last; + s->current = first; + + spi_flash_erase_sector_start(s->current); +} + +bool +spi_flash_async_erase_poll(spi_flash_async_state_t *s) +{ + if (!spi_flash_done_p()) + return false; + + //printf("%d/%d\n", s->current, s->last); + + // The current sector erase has completed. See if we're finished or + // if there's more to do. + + if (s->current == s->last) // we're done! + return true; + + s->current += spi_flash_sector_size(); + spi_flash_erase_sector_start(s->current); + return false; +} + diff --git a/firmware/microblaze/usrp2p/spi_flash.h b/firmware/microblaze/usrp2p/spi_flash.h new file mode 100644 index 000000000..bbe7b650d --- /dev/null +++ b/firmware/microblaze/usrp2p/spi_flash.h @@ -0,0 +1,119 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef INCLUDED_SPI_FLASH_H +#define INCLUDED_SPI_FLASH_H + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> + + +#define SPI_FLASH_PAGE_SIZE 256 +#define SPI_SS_FLASH 1 + + +uint32_t spi_flash_rdid(void); /* Read ID */ +uint32_t spi_flash_rdsr(void); /* Read Status Register */ +size_t spi_flash_log2_sector_size(void) __attribute__((pure)); /* either 16 or 18 */ +size_t spi_flash_log2_memory_size(void); + +static inline size_t +spi_flash_sector_size(void) +{ + return ((size_t) 1) << spi_flash_log2_sector_size(); +} + +static inline size_t +spi_flash_memory_size(void) +{ + return ((size_t) 1) << spi_flash_log2_memory_size(); +} + +void spi_flash_read(uint32_t flash_addr, size_t nbytes, void *buf); + +/* + * Erase all sectors that fall within the interval [flash_addr, flash_addr + nbytes). + * Erasing sets the memory to ones. + */ +void spi_flash_erase(uint32_t flash_addr, size_t nbytes); + +/* + * Program the flash. + * The area must have been erased prior to programming. + */ +bool spi_flash_program(uint32_t flash_addr, size_t nbytes, const void *buf); + +/* + * --- asynchronous routines --- + */ + +/* + * Is the erasing or programming done? + */ +bool spi_flash_done_p(void); + +/* + * Wait for erasing or programming to complete + */ +void spi_flash_wait(void); + +/* + * Start the erase process on a single sector. + * (It takes between 1 and 3 seconds to erase a 64KB sector) + */ +void spi_flash_erase_sector_start(uint32_t flash_addr); + +/* + * Start the programming process within a single page. + * nbytes must be between 1 and 256. + * (It takes between 1.4 and 5 ms to program a page -> 640 ms for 64KB) + */ +bool spi_flash_page_program_start(uint32_t flash_addr, size_t nbytes, const void *buf); + + +/* + * --- high-level async erase --- + */ + +typedef struct { + uint32_t first; + uint32_t last; + uint32_t current; +} spi_flash_async_state_t; + +/* + * Start to erase all sectors that fall within the interval [flash_addr, flash_addr + nbytes). + * Erasing sets the memory to ones. + * + * Initializes s and begins the process. Call spi_flash_async_erase_poll + * to test for completion and advance state machine. + */ +void spi_flash_async_erase_start(spi_flash_async_state_t *s, + uint32_t flash_addr, size_t nbytes); + +/* + * Poll for aysnc flash erase completion. + * Returns true when the erase has completed. + * (This should be called at something >= 4 Hz. It takes 1 to 3 seconds to + * erase each 64KB sector). + */ +bool spi_flash_async_erase_poll(spi_flash_async_state_t *s); + + +#endif /* INCLUDED_SPI_FLASH_H */ diff --git a/firmware/microblaze/usrp2p/spi_flash_private.h b/firmware/microblaze/usrp2p/spi_flash_private.h new file mode 100644 index 000000000..9a1b8d3e3 --- /dev/null +++ b/firmware/microblaze/usrp2p/spi_flash_private.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INCLUDED_SPI_FLASH_PRIVATE_H +#define INCLUDED_SPI_FLASH_PRIVATE_H + +#include "spi_flash.h" +#include "spi.h" +#include "memory_map.h" +#include <string.h> + + +/* M25P64 et al. */ + +#define WREN_CMD 0x06 // write enable +#define WRDI_CMD 0x04 // write disable +#define RDID_CMD 0x9f // read identification +#define RDSR_CMD 0x05 // read status register +#define WRSR_CMD 0x01 // write status register +#define READ_CMD 0x03 +#define FAST_READ_CMD 0x0b +#define PP_CMD 0x02 // page program (256 bytes) +#define SE_CMD 0xd8 // sector erase (64KB) +#define BE_CMD 0xc7 // bulk erase (all) +#define RES_CMD 0xab // read electronic sig (deprecated) + +/* Status register bits */ + +#define SR_SRWD 0x80 +#define SR_BP2 0x10 // block protect bit 2 +#define SR_BP1 0x08 // block protect bit 1 +#define SR_BP0 0x04 // block protect bit 0 +#define SR_WEL 0x02 // Write Enable Latch +#define SR_WIP 0x01 // Write in Progress. Set if busy w/ program or erase cycle. + + +#define FLAGS (SPIF_PUSH_FALL | SPIF_LATCH_RISE) + +#define LEN(x) ((x) & SPI_CTRL_CHAR_LEN_MASK) + + +static inline uint32_t +min(uint32_t a, uint32_t b) +{ + return a < b ? a : b; +} + +static inline uint32_t +round_down(uint32_t x, uint32_t power_of_2) +{ + return x & -power_of_2; +} + +#endif /* INCLUDED_SPI_FLASH_PRIVATE_H */ diff --git a/firmware/microblaze/usrp2p/spi_flash_read.c b/firmware/microblaze/usrp2p/spi_flash_read.c new file mode 100644 index 000000000..4682c5fe6 --- /dev/null +++ b/firmware/microblaze/usrp2p/spi_flash_read.c @@ -0,0 +1,119 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "spi_flash_private.h" +#include <stdlib.h> // abort + +static size_t _spi_flash_log2_memory_size; + +uint32_t +spi_flash_rdid(void) +{ + return spif_transact(SPI_TXRX, SPI_SS_FLASH, RDID_CMD << 24, 32, FLAGS) & 0xffffff; +} + +size_t +spi_flash_log2_sector_size(void) +{ + static size_t _spi_flash_log2_sector_size; + + if (_spi_flash_log2_sector_size != 0) + return _spi_flash_log2_sector_size; + + + uint32_t id = spi_flash_rdid(); + int type = (id >> 8) & 0xff; + int size = id & 0xff; + if (type != 0x20 || size < 22 || size > 24) + abort(); + + static unsigned char log2_sector_size[3] = { + 16, /* M25P32 */ + 16, /* M25P64 */ + 18, /* M25P128 */ + }; + + _spi_flash_log2_sector_size = log2_sector_size[size - 22]; + _spi_flash_log2_memory_size = size; //while we're at it + return _spi_flash_log2_sector_size; +} + +size_t +spi_flash_log2_memory_size(void) +{ + if (_spi_flash_log2_memory_size != 0) + return _spi_flash_log2_memory_size; + + uint32_t id = spi_flash_rdid(); + int type = (id >> 8) & 0xff; + int size = id & 0xff; + if (type != 0x20 || size < 22 || size > 24) + abort(); + + _spi_flash_log2_memory_size = size; + return _spi_flash_log2_memory_size; +} + +void +spi_flash_read(uint32_t flash_addr, size_t nbytes, void *buf) +{ + /* + * We explicitly control the slave select here (/S), so that we can + * do the entire read operation as a single transaction from + * device's point of view. (The most our SPI peripheral can transfer + * in a single shot is 16 bytes.) + */ + spif_wait(); + + spif_regs->ss = 0; + spif_regs->ctrl = FLAGS; // ASS is now clear and no chip select is enabled. + + /* + * Do the 5 byte instruction tranfer: + * FAST_READ_CMD, ADDR2, ADDR1, ADDR0, DUMMY + */ + spif_regs->txrx1 = FAST_READ_CMD; + spif_regs->txrx0 = ((flash_addr & 0x00ffffff) << 8); + spif_regs->ss = SPI_SS_FLASH; // assert chip select + spif_regs->ctrl = FLAGS | LEN(5 * 8); + spif_regs->ctrl = FLAGS | LEN(5 * 8) | SPI_CTRL_GO_BSY; + spif_wait(); + + /* + * Read up to 16 bytes at a time until done + */ + unsigned char *dst = (unsigned char *) buf; + size_t m; + for (size_t n = 0; n < nbytes; n += m, dst += m){ + spif_regs->ctrl = FLAGS | LEN(16 * 8); // xfer 16 bytes + spif_regs->ctrl = FLAGS | LEN(16 * 8) | SPI_CTRL_GO_BSY; + spif_wait(); + + uint32_t w[4]; + w[0] = spif_regs->txrx3; // txrx3 has first bits in it + w[1] = spif_regs->txrx2; + w[2] = spif_regs->txrx1; + w[3] = spif_regs->txrx0; + unsigned char *src = (unsigned char *) &w[0]; + m = min(nbytes - n, 16); + for (size_t i = 0; i < m; i++) + dst[i] = src[i]; + } + spif_regs->ss = 0; // deassert chip select +} diff --git a/firmware/microblaze/usrp2p/spif.c b/firmware/microblaze/usrp2p/spif.c new file mode 100644 index 000000000..1c1a348f4 --- /dev/null +++ b/firmware/microblaze/usrp2p/spif.c @@ -0,0 +1,68 @@ +/* + * Copyright 2007,2008,2009 Free Software Foundation, Inc. + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Code for the Flash SPI bus + */ + +#include "spi.h" +#include "memory_map.h" + +void +spif_init(void) +{ + /* + * f_sclk = f_wb / ((div + 1) * 2) + */ + spif_regs->div = 1; // 0 = Div by 2 (31.25 MHz); 1 = Div-by-4 (15.625 MHz) + + // run dummy transaction to work around invalid initial clock state + spif_transact(SPI_TXONLY, 0, 0, 8, SPIF_PUSH_FALL | SPIF_LATCH_RISE); +} + +inline void +spif_wait(void) +{ + while (spif_regs->ctrl & SPI_CTRL_GO_BSY) + ; +} + +uint32_t +spif_transact(bool readback_, int slave, uint32_t data, int length, uint32_t flags) +{ + flags &= (SPI_CTRL_TXNEG | SPI_CTRL_RXNEG); + int ctrl = SPI_CTRL_ASS | (SPI_CTRL_CHAR_LEN_MASK & length) | flags; + + spif_wait(); + + // Data we will send + spif_regs->txrx0 = data; + + // Run it -- write once and rewrite with GO set + spif_regs->ctrl = ctrl; + // Tell it which SPI slave device to access + spif_regs->ss = slave & 0xff; + spif_regs->ctrl = ctrl | SPI_CTRL_GO_BSY; + + if(readback_) { + spif_wait(); + return spif_regs->txrx0; + } + else + return 0; +} diff --git a/firmware/microblaze/usrp2p/udp_fw_update.c b/firmware/microblaze/usrp2p/udp_fw_update.c new file mode 100644 index 000000000..ead08ad2c --- /dev/null +++ b/firmware/microblaze/usrp2p/udp_fw_update.c @@ -0,0 +1,108 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +//Routines to handle updating the SPI Flash firmware via UDP + +#include <net_common.h> +#include "usrp2/fw_common.h" +#include "spi.h" +#include "spi_flash.h" +#include <nonstdio.h> +#include <string.h> +#include "ethernet.h" +#include "udp_fw_update.h" +#include "xilinx_s3_icap.h" + +//Firmware update packet handler +void handle_udp_fw_update_packet(struct socket_address src, struct socket_address dst, + unsigned char *payload, int payload_len) { + + const usrp2_fw_update_data_t *update_data_in = (usrp2_fw_update_data_t *) payload; + + usrp2_fw_update_data_t update_data_out; + usrp2_fw_update_id_t update_data_in_id = update_data_in->id; + + //ensure that the protocol versions match +/* if (payload_len >= sizeof(uint32_t) && update_data_in->proto_ver != USRP2_FW_COMPAT_NUM){ + printf("!Error in update packet handler: Expected compatibility number %d, but got %d\n", + USRP2_FW_COMPAT_NUM, update_data_in->proto_ver + ); + update_data_in_id = USRP2_FW_UPDATE_ID_OHAI_LOL; //so we can respond + } +*/ + //ensure that this is not a short packet + if (payload_len < sizeof(usrp2_fw_update_data_t)){ + printf("!Error in update packet handler: Expected payload length %d, but got %d\n", + (int)sizeof(usrp2_fw_update_data_t), payload_len + ); + update_data_in_id = USRP2_FW_UPDATE_ID_WAT; + } + + spi_flash_async_state_t spi_flash_async_state; + + switch(update_data_in_id) { + case USRP2_FW_UPDATE_ID_OHAI_LOL: //why hello there you handsome devil + update_data_out.id = USRP2_FW_UPDATE_ID_OHAI_OMG; + memcpy(&update_data_out.data.ip_addr, (void *)get_ip_addr(), sizeof(struct ip_addr)); + break; + + case USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL: //query sector size, memory size so the host can mind the boundaries + update_data_out.data.flash_info_args.sector_size_bytes = spi_flash_sector_size(); + update_data_out.data.flash_info_args.memory_size_bytes = spi_flash_memory_size(); + update_data_out.id = USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG; + break; + + case USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL: //out with the old + spi_flash_async_erase_start(&spi_flash_async_state, update_data_in->data.flash_args.flash_addr, update_data_in->data.flash_args.length); + update_data_out.id = USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG; + break; + + case USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL: + //poll for done, set something in the reply packet + //spi_flash_async_erase_poll() also advances the state machine, so you should call it reasonably often to get things done quicker + if(spi_flash_async_erase_poll(&spi_flash_async_state)) update_data_out.id = USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG; + else update_data_out.id = USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG; + break; + + case USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL: //and in with the new + //spi_flash_program() goes pretty quick compared to page erases, so we don't bother polling -- it'll come back in some milliseconds + //if it doesn't come back fast enough, we'll just write smaller packets at a time until it does + spi_flash_program(update_data_in->data.flash_args.flash_addr, update_data_in->data.flash_args.length, update_data_in->data.flash_args.data); + update_data_out.id = USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG; + break; + + case USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL: //for verify + spi_flash_read(update_data_in->data.flash_args.flash_addr, update_data_in->data.flash_args.length, update_data_out.data.flash_args.data); + update_data_out.id = USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG; + break; + + case USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL: //for if we ever get the ICAP working + //should reset via icap_reload_fpga(uint32_t flash_address); + update_data_out.id = USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG; + //you should note that if you get a reply packet to this the reset has obviously failed + icap_reload_fpga(0); + break; + +// case USRP2_FW_UPDATE_ID_KTHXBAI: //see ya +// break; + + default: //uhhhh + update_data_out.id = USRP2_FW_UPDATE_ID_WAT; + } + send_udp_pkt(USRP2_UDP_UPDATE_PORT, src, &update_data_out, sizeof(update_data_out)); +} diff --git a/firmware/microblaze/usrp2p/xilinx_s3_icap.c b/firmware/microblaze/usrp2p/xilinx_s3_icap.c new file mode 100644 index 000000000..50c85231c --- /dev/null +++ b/firmware/microblaze/usrp2p/xilinx_s3_icap.c @@ -0,0 +1,99 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* Changes required to work for the Spartan-3A series: + * The ICAP interface on the 3A is 8 bits wide, instead of 32. + * Everything is Xilinx standard LSBit-first. + * The operations are all different. + * Commands are 16 bits long, presented to the ICAP interface 8 bits at a time. +*/ + +#include <xilinx_s3_icap.h> +#include <memory_map.h> +#include <spi_flash_private.h> //for READ_CMD + + +/* bit swap end-for-end */ +static inline unsigned char +swap8(unsigned char x) +{ + unsigned char r = 0; + r |= (x >> 7) & 0x01; + r |= (x >> 5) & 0x02; + r |= (x >> 3) & 0x04; + r |= (x >> 1) & 0x08; + + r |= (x << 1) & 0x10; + r |= (x << 3) & 0x20; + r |= (x << 5) & 0x40; + r |= (x << 7) & 0x80; + + return r; +} + +void +wr_icap(uint8_t x) +{ + icap_regs->icap = swap8(x); +} + +uint8_t +rd_icap(void) +{ + return swap8(icap_regs->icap); +} + + +void +icap_reload_fpga(uint32_t flash_address) +{ + union { + uint32_t i; + uint8_t c[4]; + } t; + t.i = flash_address; + + //note! t.c[0] MUST contain the byte-wide read command for the flash device used. + //for the 25P64, and most other flash devices, this is 0x03. + t.c[0] = FAST_READ_CMD; + + //TODO: look up the watchdog timer, ensure it won't fire too soon + + //UG332 p279 + wr_icap(0xff); + wr_icap(0xff); //dummy word, probably unnecessary + wr_icap(0xAA); + wr_icap(0x99); //sync word + wr_icap(0x32); + wr_icap(0x61); //Type 1 write General 1 (1 word) + wr_icap(t.c[2]); //bits 15-8 + wr_icap(t.c[3]); //bits 7-0 + wr_icap(0x32); + wr_icap(0x81); //Type 1 write General 2 (1 word) + wr_icap(t.c[0]); //C0-C8, the byte-wide read command + wr_icap(t.c[1]); //Upper 8 bits of 24-bit address + wr_icap(0x30); + wr_icap(0xA1); //Type 1 write CMD (1 word) + wr_icap(0x00); + wr_icap(0x0E); //REBOOT command + wr_icap(0x20); + wr_icap(0x00); //Type 1 NOP + wr_icap(0x20); + wr_icap(0x00); +} diff --git a/firmware/microblaze/usrp2p/xilinx_s3_icap.h b/firmware/microblaze/usrp2p/xilinx_s3_icap.h new file mode 100644 index 000000000..7b7e9eccc --- /dev/null +++ b/firmware/microblaze/usrp2p/xilinx_s3_icap.h @@ -0,0 +1,37 @@ +/* -*- c -*- */ +/* + * Copyright 2009 Ettus Research LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef INCLUDED_XILINX_S3_ICAP_H +#define INCLUDED_XILINX_S3_ICAP_H + +#include <stdint.h> + + +void wr_icap(uint8_t x); +uint8_t rd_icap(void); + +//int icap_read_config_reg(int regno); + +/* + * Attempt to reload the fpga from \p flash_address. + * Shouldn't return, but might. + */ +void icap_reload_fpga(uint32_t flash_address); + + +#endif /* INCLUDED_XILINX_S3_ICAP_H */ diff --git a/fpga/usrp2/coregen/Makefile.srcs b/fpga/usrp2/coregen/Makefile.srcs index 7b29225ca..a59696d15 100644 --- a/fpga/usrp2/coregen/Makefile.srcs +++ b/fpga/usrp2/coregen/Makefile.srcs @@ -16,4 +16,8 @@ fifo_xlnx_16x19_2clk.v \ fifo_xlnx_16x19_2clk.xco \ fifo_xlnx_16x40_2clk.v \ fifo_xlnx_16x40_2clk.xco \ +fifo_xlnx_512x36_2clk_36to18.v \ +fifo_xlnx_512x36_2clk_36to18.xco \ +fifo_xlnx_512x36_2clk_18to36.v \ +fifo_xlnx_512x36_2clk_18to36.xco \ )) diff --git a/fpga/usrp2/coregen/coregen.cgp b/fpga/usrp2/coregen/coregen.cgp index 810d64dac..4c9201aff 100644 --- a/fpga/usrp2/coregen/coregen.cgp +++ b/fpga/usrp2/coregen/coregen.cgp @@ -1,20 +1,22 @@ -# Date: Thu Sep 3 17:40:48 2009 -SET addpads = False -SET asysymbol = False +# Date: Mon Jul 26 21:55:33 2010 + +SET addpads = false +SET asysymbol = false SET busformat = BusFormatAngleBracketNotRipped -SET createndf = False +SET createndf = false SET designentry = Verilog SET device = xc3s2000 SET devicefamily = spartan3 SET flowvendor = Other -SET formalverification = False -SET foundationsym = False +SET formalverification = false +SET foundationsym = false SET implementationfiletype = Ngc SET package = fg456 -SET removerpms = False +SET removerpms = false SET simulationfiles = Behavioral SET speedgrade = -5 -SET verilogsim = True -SET vhdlsim = False -SET workingdirectory = /home/matt/coregen/tmp +SET verilogsim = true +SET vhdlsim = false +SET workingdirectory = /tmp/ +# CRC: 394da717 diff --git a/fpga/usrp2/coregen/fifo_generator_ug175.pdf b/fpga/usrp2/coregen/fifo_generator_ug175.pdf Binary files differindex 2c3e3c200..5fba6029c 100644 --- a/fpga/usrp2/coregen/fifo_generator_ug175.pdf +++ b/fpga/usrp2/coregen/fifo_generator_ug175.pdf diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.gise b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.gise new file mode 100644 index 000000000..c18cf3bf0 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.gise @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
+
+ <!-- -->
+
+ <!-- For tool use only. Do not edit. -->
+
+ <!-- -->
+
+ <!-- ProjectNavigator created generated project file. -->
+
+ <!-- For use in tracking generated file and other information -->
+
+ <!-- allowing preservation of process status. -->
+
+ <!-- -->
+
+ <!-- Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. -->
+
+ <version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
+
+ <sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="fifo_xlnx_512x36_2clk_18to36.xise"/>
+
+ <files xmlns="http://www.xilinx.com/XMLSchema">
+ <file xil_pn:fileType="FILE_VEO" xil_pn:name="fifo_xlnx_512x36_2clk_18to36.veo" xil_pn:origination="imported"/>
+ </files>
+
+ <transforms xmlns="http://www.xilinx.com/XMLSchema"/>
+
+</generated_project>
diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.ngc b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.ngc new file mode 100644 index 000000000..d9277b0c3 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.6e +$45640<,[o}e~g`n;"2*726&;$:,)?40493456712:;<=>?01274>6789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123454<80;0=>5>.130?46=AGZ^X7OKDSC?=?699l1:<7GAPTV9twi`Wog`Rzgrdqk8<<76;?0==4FNQWW>uthoVl~`aQ{hsgplZgt{lx044?>37855<NFY__6}|`g^dvhiYs`{oxdR`jg`vf8<<76830==4@UURVP?bf|hUhcx`{<883:4e<990DYY^ZT;uq[agsiVidycz39;2=57=6>3CE\XZ5DHC?50<76890=;4@UURVP?BHI5;>6=0>2:3;>LHW]]0oec2>7;2=5>433;98?<?42;KMTPR=L@ZJ0<4?>0086?IR\Y__6IA_A=394;753:81EC^ZT;FJF956294:?6==:NWWTPR=LFH7?<4?>06873<H]]Z^X7j`uu>01?69l29x>=>?ff662(363=>08=HI1097>LHW]]0OE]L33;2=57=32F__\XZ5DNRA86<7681=>6864:4:=32<09:;866J8@38=1=>8939748;;845=44<13CE\XZ5AEFQF9>=87;n744FNQWW>uthoVof|ywPtipfwm:?29499675IORVP?vugnUna}zv_ujqavnXizyn~y27:1<11>?=AGZ^X7~}of]fiur~W}byi~fPndebp`:?294:n675OTVSQQ<ulVnjxlQlotlw8=<76;1J>55NDEPB858?3HNO^L2>>99B@ATF4;437LJKR@>0:==FLMXJ0907;@FGVD:2611JHI\N<7<;?DBCZH6<255NDEPB8=8f3HNO^L26:1<;?DBCZH62255NDEPA858?3HNO^O2>>99B@ATE4;437LJKRC>0:==FLMXI0907;@FGVG:2611JHI\M<7<;?DBCZK6<2l5NDEPA8=<7611JHI\M<9<0?DJK12KXUCMPRDE0?GS502H^_RGAFN38G7=DM880OEKLK^NJG@HTMV^R\H<4CH68GIMF<2IGGO=4CMP:?FIJE@^_II?;;BMQAZABFLXJXDAA_HLEK2=DZLK_II?4D39GG7=CA?1OEL2?>69GMD:687=0HDO310<4?AOF4885;6JFA=30:2=CAH6:8374DHC?50<76>1OEL2>5?48@LG;97<0HDO32?48@LG;;7<0HDO34?48@LG;=7<0HDO36?48@LG;?7<0HDO38?48@LG;17<0HDL30?58@LD;994<7IGM<03=3>BNJ5;92:5KIC>27;1<L@H7=908;EKA8439?2NBN1?9>69GMG:6?7=0HDL319<4?AOE4835:6JFB=3=3>BNJ58;2:5KIC>15;1<L@H7>?08;EKA8759?2NBN1<;>69GMG:5=7=0HDL327<4?AOE4;=5;6JFB=0;:2=CAK695384DH@?6;1<L@H7?=06;EKA867=87=0HDL330<5?AOE4:4=7IGM<5<5?AOE4<4=7IGM<7<5?AOE4>4=7IGM<9<5?AOE404<7IG_A=2==>BNXH6:6=08;EKSE979?2NB\O2?>69GMUD;97=0HD^M<3<:?AOWJ591<394DHRA86813MEJ0=08;EMB8469?2NDM1?>>69GKD:6:7=0HBO312<4?AIF48>556J@A=36>5803MEJ0<;16:FLE979>2NDM1<16:FLE959>2NDM1:16:FLE939>2NDM1816:FLE919>2NDM1616:FLE9?9?2NDMR\JG79GKG:76>1OCO2>0?58@JD;984<7IAM<00=3>BHJ5;82:5KOC>20;1<LFH7=808;EMA8409?2NDN1?8>69GKG:607=0HBL318<5?AIE484<7IAM<32=3>BHJ58:2:5KOC>16;1<LFH7>>08;EMA8729?2NDN1<:>69GKG:5>7=0HBL326<4?AIE4;25;6J@B=0::3=CGK692:5KOC>04;?<LFH7?<4?>69GKG:497<0HBL33?48@JD;<7<0HBL35?48@JD;>7<0HBL37?48@JD;07<0HBL39?58@JDXZLM<7IA_A=2==>BHXH6:6=08;EMSE979?2ND\O2?>69GKUD;97=0HB^M<3<:?AIWJ591<394DNRA86843LDJ?6KABc9FJZCDKVXNMIm4EO]FGFYPZ@^N>6H=2:D;1>@FDZO97KJ<;GF@0>@CKL90JI^;;GFSA1=AL[O?7KH7009D7>AIL81B>6G?2:K26>O5:2C846GAIUR\45><AGC_\R>>8:KMMQVX8;20ECG[P^20<>OIA]ZT<964IOKWTZ6202CEEY^P07:8MKOSXV:<56GAIUQWEQC03@DBXR>?7:KMMQY79>1BBDZP0358MKOSW99<7D@FT^273>OIA]U;9:5FNHV\431<AGC_S=98;HLJPZ6??2CEEYQ?969JJLRX8H=0ECG[_1@4?LHN\V:H;6GAIU]3@2=NF@^T<H94IOKW[5@03@DBXR??7:KMMQY69>1BBDZP1358MKOSW89<7D@FT^373>OIA]U:9:5FNHV\531<AGC_S<98;HLJPZ7??2CEEYQ>969JJLRX9H=0ECG[_0@4?LHN\V;H;6GAIU]2@2=NF@^T=H94IOKW[4@03@DBXR<?7:KMMQY59>1BBDZP2358MKOSW;9<7D@FT^073>OIA]U99:5FNHV\631<AGC_S?98;HLJPZ4??2CEEYQ=969JJLRX:H=0ECG[_3@4?LHN\V8H;6GAIU]1@2=NF@^T>H94IOKW[7@03@DBXR=?7:KMMQY49>1BBDZP3358MKOSW:9<7D@FT^173>OIA]U89:5FNHV\731<AGC_S>98;HLJPZ5??2CEEYQ<969JJLRX;H=0ECG[_2@4?LHN\V9H;6GAIU]0@2=NF@^T?H94IOKW[6@13@DBXRO9;HLJPZD43@D]>6BF2:NL2>JHIMOO;6B@GHABH1=K]];?7A[[259OQQ533E__8;5CUU6\@0=J[NEE96CZXB[`?Hgmg{\n~~g`nb9Nmkiu^lxxeb`<;O226>H6<2D:<=:4N0220>H68;>0B<><4:L2412<F8:>86@>0768J460<2D:<5:4N02:7>H69=1E=<>;;O3251=I988?7C?>359M54233G;:995A1047?K76?=1E=<6;;O32=6=I9;>0B<<?4:L2642<F88986@>2268J443<2D:>8:4N0050>H6:>>0B<<73:L271=I9:;87C?;3:L216=I9?>0B<8;3:L236=I9190B<7=;O00?K47;2D9=>5A2318J7543G8??6@=529M635<F;=87C<73:L1=7=I;:1E?=<4N408J24<F090B4?<;O;17>H>;:1E59=4N870?K?1;2D2;>5A9918J<?a3GHTNX]_IO]SVJVT?2DNXZA]K09L6>IL92Z?7]O]T`9SMKYE]ZCOTo5_IO]AQVHFEL90\_K>;P38V`=UIDH::R]>8^Q02d=UMHNTJD\\Tb9QADBX_@N_DROl;SGB@ZQNL]BTN<5\129PMHYDGEFB_DAA_BJFGN0<[F_YOH94SSTBHZG03ZX]MAQM4:QPVD2<[ZXI86ZVPD11?P6(o{l%~k!hcy,`hn~(EqeySjPpovq[beXpfx;<=>PRdqvhq74:2_;#j|i.sd,cf~)keas#@v`r^pg[uhszVmhSua}0122[Wct}e~:??5Z0.eqb+ta'nis"nbdx.O{kwYulVzexQhc^zlv567:VXnxb{1208Q5)`zo$yj"ilx/aoo})JpfxT~iQnup\cfYg{:;<>Q]erwop4553\:$kh!rg-dg}(ddbr$Aua}_sf\tkruWniTtb|?016\V`urd};8>6[?/fpe*w`(ojr%oaew/LzlvZtcWyd~Ril_ymq4562W[oxyaz>339V4*aun'xm#jmw.bnh|*Kg{UyhR~ats]dgZ~hz9:;:R\jstnw564<]9%l~k }f.e`|+ekcq%Ftb|Pre]sjqtXojUsc>?06]Qavsk|8997X> gsd-vc)`kq$h`fv Mymq[rtXxg~ySjmPxnp3456XZly~`y?<2:W3+bta&{l$knv!cmi{+H~hzV}yS}`{r^e`[}iu89::S_k|umv277=R8&myj#|i/fa{*fjlp&GscQxr^rmpwY`kVrd~=>?2^Pfwpjs9:80Y=!hrg,qb*adp'iggu!Bxnp\swYwf}xTknQwos2346YUmzgx<==;T2,cw`)zo%lou lljz,I}iuW~xT|cz}_fa\|jt789>T^h}zlu306>S7'nxm"h gbz-gim'Drd~Ry}_qlwvZadWqey<=>:_Sgpqir6;;1^<"i}f/pe+be&jf`t"Cwos]tvZvi|{UloRv`r1232ZTb{|f=><4U1-dvc(un&mht#mcky-N|jtX{U{by|Pgb]{kw678>UYi~{ct011?P6(o{l%~k!hcy,`hn~(EqeySz|Ppovq[beXpfx;<=6PRdqvhq7592_;#j|i.sd,cf~)keas#jPpovq[goi4949=6[?/fpe*w`(ojr%oaew/sf\tkruWkce0<0=1:W3+bta&{l$knv!cmi{+wbXxg~ySoga<3<15>S7'nxm"h gbz-gim'{nT|cz}_ckm868592_;#j|i.sd,cf~)keas#jPpovq[goi4=49=6[?/fpe*w`(ojr%oaew/sf\tkruWkce080=1:W3+bta&{l$knv!cmi{+wbXxg~ySoga<7<15>S7'nxm"h gbz-gim'{nT|cz}_ckm828592_;#j|i.sd,cf~)keas#jPpovq[goi4149<6[?/fpe*w`(ojr%oaew/sf\tkruWkceS=<?;T2,cw`)zo%lou lljz,vaYwf}xTnd`P1328Q5)`zo$yj"ilx/aoo})ulVzexQmio]165=R8&myj#|i/fa{*fjlp&xoS}`{r^`jjZ5582_;#j|i.sd,cf~)keas#jPpovq[goiW=8;7X> gsd-vc)`kq$h`fv re]sjqtXj`dT9?>4U1-dvc(un&mht#mcky-q`Zvi|{UiecQ9219V4*aun'xm#jmw.bnh|*tcWyd~Rlfn^514>S7'nxm"h gbz-gim'{nT|cz}_ckm[=413\:$kh!rg-dg}(ddbr$~iQnup\flhXpfx;<=>=7:W3+bta&{l$knv!cmi{+wbXxg~ySoga_ymq45679;<0Y=!hrg,qb*adp'iggu!}d^rmpwYeagUsc>?0004?P6(o{l%~k!hcy,`hn~(zmU{by|Pbhl\|jt789;:>;5Z0.eqb+ta'nis"nbdx.pg[uhszVhbbRv`r123671<]9%l~k }f.e`|+ekcq%yhR~ats]amkYg{:;<??=6:W3+bta&{l$knv!cmi{+wbXxg~ySoga_ymq4564:>1^<"i}f/pe+be&jf`t"|k_qlwvZdnfVrd~=>?3305?P6(o{l%~k!hcy,`hn~(zmU{by|Pbhl\|jt789>9;6[?/fpe*w`(ojr%oaew/sf\tkruWkceSua}0127570<]9%l~k }f.e`|+ekcq%yhR~ats]amkYg{:;<8<8;T2,cw`)zo%lou lljz,vaYwf}xTnd`Pxnp34536:?1^<"i}f/pe+be&jf`t"|k_qlwvZdnfVrd~=>?63:8Q5)`zo$yj"ilx/aoo})ulVzexQmio]{kw678?;:>:5Z0.eqb+ta'nis"nbdx.pg[uhszVhbbRv`r123274e3\:$kh!rg-dg}(ddbr$~iQnup\flhXpfx;<=8Pbef363=R8&myj#|i/fa{*fjlp&xoS}`{r^`jjZ~hz9:;;?94U1-dvc(un&mht#mcky-q`Zvi|{UiecQwos23427582_;#j|i.sd,cf~)keas#jPpovq[be;878;7X> gsd-vc)`kq$h`fv re]sjqtXoj6:2?>4U1-dvc(un&mht#mcky-q`Zvi|{Ulo1<1219V4*aun'xm#jmw.bnh|*tcWyd~Ril<2<14>S7'nxm"h gbz-gim'{nT|cz}_fa?0;473\:$kh!rg-dg}(ddbr$~iQnup\cf:26;:0Y=!hrg,qb*adp'iggu!}d^rmpwY`k5<5>=5Z0.eqb+ta'nis"nbdx.pg[uhszVmh0:0=0:W3+bta&{l$knv!cmi{+wbXxg~ySjm38?3e?P6(o{l%~k!hcy,`hn~(zmU{by|Pgb]35c=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[47a3\:$kh!rg-dg}(ddbr$~iQnup\cfY59o1^<"i}f/pe+be&jf`t"|k_qlwvZadW:;m7X> gsd-vc)`kq$h`fv re]sjqtXojU?=k5Z0.eqb+ta'nis"nbdx.pg[uhszVmhS8?i;T2,cw`)zo%lou lljz,vaYwf}xTknQ91g9V4*aun'xm#jmw.bnh|*tcWyd~Ril_63e?P6(o{l%~k!hcy,`hn~(zmU{by|Pgb];63=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumn6;2?84U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde?5;413\:$kh!rg-dg}(ddbr$~iQnup\cfYf{{ol0?0=6:W3+bta&{l$knv!cmi{+wbXxg~ySjmParpfc959:?1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyij2;>348Q5)`zo$yj"ilx/aoo})ulVzexQhc^cpv`a;=78=7X> gsd-vc)`kq$h`fv re]sjqtXojUjkh<7<12>S7'nxm"h gbz-gim'{nT|cz}_fa\evtbo5=5>;5Z0.eqb+ta'nis"nbdx.pg[uhszVmhSl}}ef>;:73<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmT<?;4U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\573<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmT>?;4U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\773<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmT8?;4U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\173<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmT:?;4U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\373<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmT4?74U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\`4:76;30Y=!hrg,qb*adp'iggu!}d^rmpwY`kVkx~hiPd0>2:7?<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmTh<2=>3;8Q5)`zo$yj"ilx/aoo})ulVzexQhc^cpv`aXl8682?74U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\`4:36;30Y=!hrg,qb*adp'iggu!}d^rmpwY`kVkx~hiPd0>6:7?<]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmTh<29>3;8Q5)`zo$yj"ilx/aoo})ulVzexQhc^cpv`aXl86<2?74U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde\`4:?6;20Y=!hrg,qb*adp'iggu!}d^rmpwY`kVkx~hiPd0]36==R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumnUo=R?=8:W3+bta&{l$knv!cmi{+wbXxg~ySjmParpfcZb6W;837X> gsd-vc)`kq$h`fv re]sjqtXojUjkh_e3\77><]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmTh<Q;299V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabYc9V?946[?/fpe*w`(ojr%oaew/sf\tkruWniTm~|jg^f2[34?3\:$kh!rg-dg}(ddbr$~iQnup\cfYf{{olSi?P73:8Q5)`zo$yj"ilx/aoo})ulVzexQhc^cpv`aXl8U3>85Z0.eqb+ta'nis"nbdx.pg[uhszVmhSua}012360=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[}iu89::>85Z0.eqb+ta'nis"nbdx.pg[uhszVmhSua}012160=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[}iu89:8>85Z0.eqb+ta'nis"nbdx.pg[uhszVmhSua}012760=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[}iu89:>>85Z0.eqb+ta'nis"nbdx.pg[uhszVmhSua}012560=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[}iu89:<><5Z0.eqb+ta'nis"nbdx.uq[uhszVhbb1?1209V4*aun'xm#jmw.bnh|*quWyd~Rlfn=0=64=R8&myj#|i/fa{*fjlp&}yS}`{r^`jj959:81^<"i}f/pe+be&jf`t"y}_qlwvZdnf5>5><5Z0.eqb+ta'nis"nbdx.uq[uhszVhbb1;1209V4*aun'xm#jmw.bnh|*quWyd~Rlfn=4=64=R8&myj#|i/fa{*fjlp&}yS}`{r^`jj919:81^<"i}f/pe+be&jf`t"y}_qlwvZdnf525><5Z0.eqb+ta'nis"nbdx.uq[uhszVhbb171219V4*aun'xm#jmw.bnh|*quWyd~Rlfn^314>S7'nxm"h gbz-gim'~xT|cz}_ckm[7473\:$kh!rg-dg}(ddbr${Qnup\flhX;;:0Y=!hrg,qb*adp'iggu!xr^rmpwYeagU?>=5Z0.eqb+ta'nis"nbdx.uq[uhszVhbbR;=0:W3+bta&{l$knv!cmi{+rtXxg~ySoga_703?P6(o{l%~k!hcy,`hn~({U{by|Pbhl\376<]9%l~k }f.e`|+ekcq%|~R~ats]amkY?:91^<"i}f/pe+be&jf`t"y}_qlwvZdnfV39:6[?/fpe*w`(ojr%oaew/vp\tkruWkceSua}012362=R8&myj#|i/fa{*fjlp&}yS}`{r^`jjZ~hz9:;<<<9;T2,cw`)zo%lou lljz,swYwf}xTnd`Pxnp34575?2_;#j|i.sd,cf~)keas#z|Ppovq[goiWqey<=>>1348Q5)`zo$yj"ilx/aoo})pzVzexQmio]{kw678;8<7X> gsd-vc)`kq$h`fv ws]sjqtXj`dTtb|?010263=R8&myj#|i/fa{*fjlp&}yS}`{r^`jjZ~hz9:;??94U1-dvc(un&mht#mcky-tvZvi|{UiecQwos234645>2_;#j|i.sd,cf~)keas#z|Ppovq[goiWqey<=>;269V4*aun'xm#jmw.bnh|*quWyd~Rlfn^zlv567<88=7X> gsd-vc)`kq$h`fv ws]sjqtXj`dTtb|?01713>S7'nxm"h gbz-gim'~xT|cz}_ckm[}iu89:>=?84U1-dvc(un&mht#mcky-tvZvi|{UiecQwos23434?3\:$kh!rg-dg}(ddbr${Qnup\flhXpfx;<=8>1358Q5)`zo$yj"ilx/aoo})pzVzexQmio]{kw678?89n6[?/fpe*w`(ojr%oaew/vp\tkruWkceSua}0125[gbc8;<0Y=!hrg,qb*adp'iggu!xr^rmpwYeagUsc>?0604?P6(o{l%~k!hcy,`hn~({U{by|Pbhl\|jt789=:>=5Z0.eqb+ta'nis"nbdx.uq[uhszVmh0=0=0:W3+bta&{l$knv!cmi{+rtXxg~ySjm31?03?P6(o{l%~k!hcy,`hn~({U{by|Pgb>1:76<]9%l~k }f.e`|+ekcq%|~R~ats]dg959:91^<"i}f/pe+be&jf`t"y}_qlwvZad4=49<6[?/fpe*w`(ojr%oaew/vp\tkruWni793<?;T2,cw`)zo%lou lljz,swYwf}xTkn29>328Q5)`zo$yj"ilx/aoo})pzVzexQhc=5=65=R8&myj#|i/fa{*fjlp&}yS}`{r^e`8=8582_;#j|i.sd,cf~)keas#z|Ppovq[be;17;m7X> gsd-vc)`kq$h`fv ws]sjqtXojU;=k5Z0.eqb+ta'nis"nbdx.uq[uhszVmhS<?i;T2,cw`)zo%lou lljz,swYwf}xTknQ=1g9V4*aun'xm#jmw.bnh|*quWyd~Ril_23e?P6(o{l%~k!hcy,`hn~({U{by|Pgb]75c=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[07a3\:$kh!rg-dg}(ddbr${Qnup\cfY19o1^<"i}f/pe+be&jf`t"y}_qlwvZadW>;m7X> gsd-vc)`kq$h`fv ws]sjqtXojU3=k5Z0.eqb+ta'nis"nbdx.uq[uhszVmhS4<9;T2,cw`)zo%lou lljz,swYwf}xTknQnssgd8585>2_;#j|i.sd,cf~)keas#z|Ppovq[beXizxnk1?1279V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqab:56;<0Y=!hrg,qb*adp'iggu!xr^rmpwY`kVkx~hi33?05?P6(o{l%~k!hcy,`hn~({U{by|Pgb]bwwc`4=49:6[?/fpe*w`(ojr%oaew/vp\tkruWniTm~|jg=7=63=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[duumn6=2?84U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde?3;413\:$kh!rg-dg}(ddbr${Qnup\cfYf{{ol050=6:W3+bta&{l$knv!cmi{+rtXxg~ySjmParpfc9?9:<1^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQ?249V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabY6:<1^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQ=249V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabY4:<1^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQ;249V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabY2:<1^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQ9249V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabY0:<1^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQ7249V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabY>:01^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQk1=3=6<=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[duumnUo=1<1289V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabYc9595>45Z0.eqb+ta'nis"nbdx.uq[uhszVmhSl}}ef]g5929:01^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQk1=7=6<=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[duumnUo=181289V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabYc95=5>45Z0.eqb+ta'nis"nbdx.uq[uhszVmhSl}}ef]g59>9:01^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQk1=;=6==R8&myj#|i/fa{*fjlp&}yS}`{r^e`[duumnUo=R?=8:W3+bta&{l$knv!cmi{+rtXxg~ySjmParpfcZb6W;837X> gsd-vc)`kq$h`fv ws]sjqtXojUjkh_e3\77><]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmTh<Q;299V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqabYc9V?946[?/fpe*w`(ojr%oaew/vp\tkruWniTm~|jg^f2[34?3\:$kh!rg-dg}(ddbr${Qnup\cfYf{{olSi?P73:8Q5)`zo$yj"ilx/aoo})pzVzexQhc^cpv`aXl8U3>55Z0.eqb+ta'nis"nbdx.uq[uhszVmhSl}}ef]g5Z?5=2_;#j|i.sd,cf~)keas#z|Ppovq[beXpfx;<=>=5:W3+bta&{l$knv!cmi{+rtXxg~ySjmPxnp34575=2_;#j|i.sd,cf~)keas#z|Ppovq[beXpfx;<=<=5:W3+bta&{l$knv!cmi{+rtXxg~ySjmPxnp34555=2_;#j|i.sd,cf~)keas#z|Ppovq[beXpfx;<=:=5:W3+bta&{l$knv!cmi{+rtXxg~ySjmPxnp34535=2_;#j|i.sd,cf~)keas#z|Ppovq[beXpfx;<=8=5:W3+bta&{l$knv!cmi{+rtXxg~ySjmPxnp34515=2_;#j|i.sd,cf~)keas#z|Ppovq[beXpfx;<=6<0:W3+bta&{l$ka>!re-dv4(un~l#@czx^PBIZTCWLDTJZH[200e?P6(o{l%~k!hl1,q`*au9'xm{kz Mlw{[WGJW[OLCXZPEO326a=R8&myj#|i/fn3*wb(o{;%~kyit.avvwYao~Tyo{e=2=6a=R8&myj#|i/fn3*wb(o{;%~kyit.avvwYao~Tyo{e=3=6f=R8&myj#|i/fn3*wb(o{;%~kyit.avvwYao~Tyo{e^21g>S7'nxm"h gm2-va)`z8$yjzh{/bwqvZ`pn}Uxxlzj_016?P6(o{l%~k!hl1,q`*au9'xm{kz ctpq[cqa|VymykPmtz3457;879=7X> gsd-vc)`d9$yh"i}1/pescr(k|xySkyit^qweqcXe|r;<=?30?301>S7'nxm"h gm2-va)`z8$yjzh{/bwqvZ`pn}Uxxlzj_lw{45664848:6[?/fpe*w`(oe:%~i!hr0,qbr`s'jy~Rhxfu]ppdrbWds<=>><0<26==R8&myj#|i/fn3*wb(o{;%~kyit.gntqXn~lSkl=7:W3+bta&{l$ka>!re-dv4(un~l#hctx]escrXa;l0Y=!hrg,qb*ak8'xo#j|>.sdtbq)bey~rSkyit^k\ip~789:8<6[?/fpe*w`(oe:%~i!hr0,qbr`s'lg{xtQiwgv\mZkrp9:;<<<6;T2,cw`)zo%l`= }d.eqev(u{}y$o=!laspzj`r;87827X> gsd-vc)`d9$yh"i}ar,qwqu(k9%hm|vndv?5;4>3\:$kh!rg-dh5(ul&mym~ }suq,g5)di{xrbhz32?0:?P6(o{l%~k!hl1,q`*auiz$yy} c1-`ewt~fl~7?3<i;T2,cw`)zo%l`= }d.eqev(u{}y$o=!hmtz-ch]7U'mf=#c>2g9V4*aun'xm#jb?.sf,cwgt&{y"m?/fov|+ajS8W%k`}!mr0e?P6(o{l%~k!hl1,q`*auiz$yy} c1-dip~)odQ9Q#ibs/op6c=R8&myj#|i/fn3*wb(o{kx"}{s.a3+bkrp'mfW>S!glq-iv4a3\:$kh!rg-dh5(ul&mym~ }suq,g5)`e|r%k`U;]/enw+kt::1^<"i}f/pe+bj7&{n$ko|.sqww*e7';7<3<<;T2,cw`)zo%l`= }d.eqev(u{}y$o=!y1=3=66=R8&myj#|i/fn3*wb(o{kx"}{s.a3+s7;:7887X> gsd-vc)`d9$yh"i}ar,qwqu(k9%}=1=1229V4*aun'xm#jb?.sf,cwgt&{y"m?/w3?0;4e3\:$kh!rg-dh5(ul&mym~ }suq,g5)q9V:Tmcj?01226g=R8&myj#|i/fn3*wb(o{kx"}{s.a3+s7X9Vkeh=>?000a?P6(o{l%~k!hl1,q`*auiz$yy} c1-u5Z4Xign;<=>>2c9V4*aun'xm#jb?.sf,cwgt&{y"m?/w3\7Zgil9:;<<<m;T2,cw`)zo%l`= }d.eqev(u{}y$o=!y1^6\jjr789::>45Z0.eqb+ta'nf;"j gscp*wus{&i:#no}rxlfp969:01^<"i}f/pe+bj7&{n$ko|.sqww*e6'jky~t`jt=3=6<=R8&myj#|i/fn3*wb(o{kx"}{s.a2+fguzpdnx1<1289V4*aun'xm#jb?.sf,cwgt&{y"m>/bcqv|hb|595>k5Z0.eqb+ta'nf;"j gscp*wus{&i:#jczx/en_5[)od;%a<<i;T2,cw`)zo%l`= }d.eqev(u{}y$o<!hmtz-ch]6U'mf#c|2g9V4*aun'xm#jb?.sf,cwgt&{y"m>/fov|+ajS;W%k`}!mr0e?P6(o{l%~k!hl1,q`*auiz$yy} c0-dip~)odQ8Q#ibs/op6c=R8&myj#|i/fn3*wb(o{kx"}{s.a2+bkrp'mfW9S!glq-iv443\:$kh!rg-dh5(ul&mym~ }suq,g4)q95:5>>5Z0.eqb+ta'nf;"j gscp*wus{&i:#{?31?00?P6(o{l%~k!hl1,q`*auiz$yy} c0-u5949::1^<"i}f/pe+bj7&{n$ko|.sqww*e6';7?3<<;T2,cw`)zo%l`= }d.eqev(u{}y$o<!y1=6=6g=R8&myj#|i/fn3*wb(o{kx"}{s.a2+s7X8Vkeh=>?000a?P6(o{l%~k!hl1,q`*auiz$yy} c0-u5Z7Xign;<=>>2c9V4*aun'xm#jb?.sf,cwgt&{y"m>/w3\6Zgil9:;<<<m;T2,cw`)zo%l`= }d.eqev(u{}y$o<!y1^1\ekb789::>o5Z0.eqb+ta'nf;"j gscp*wus{&i:#{?P4^llp567888;7X> gsd-vc)`d9$yh"i}ar,qwqu(kfg{<?>4U1-dvc(un&mg<#|k/fpbw+tt|z%hc`~>289V4*aun'xm#jb?.sf,cwgt&{y"|nm^gntqXnkUb?=5Z0.eqb+ta'nf;"j gscp*wus{&xjaRkbpu{\bgYnWfx;<=><1:W3+bta&{l$ka>!re-dvdu)zz~x#ob_dosp|YajVcTc>?01317>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|;>0Y=!hrg,qb*ak8'xo#~ats-Ngjsi|Vidycz>259V4*aun'xm#jb?.sf,vuhsz&Ghcx`{_bmvjq45<2_;#j|i.sd,ci6)zm%y|cz}/LalqkrXkfex><;;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw072<]9%l~k }f.eo4+tc'{zex!BcnwmpZeh}g~>>95Z0.eqb+ta'nf;"j rqlwv*Kdg|dSnaznu410>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|>8?7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{83;8Q5)`zo$yj"ic0/pg+wvi|{%Fob{at^alqkrXkp6;2?m4U1-dvc(un&mg<#|k/srmpw)JkfexRm`uov\g|:76Vx>45Z0.eqb+ta'nf;"j rqlwv*Kdg|dSnaznu]`}979:j1^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~byQly=3=[wr512_;#j|i.sd,ci6)zm%y|cz}/LalqkrXkfexRmv<3<1g>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|Vir0?0Pru0:?P6(o{l%~k!hl1,q`*twf}x$Anaznu]`kphsWjs7?3<l;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw[f;;7Uyx?74U1-dvc(un&mg<#|k/srmpw)JkfexRm`uov\g|:36;i0Y=!hrg,qb*ak8'xo#~ats-Ngjsi|VidyczPcx>7:Zts:01^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~byQly=7=6f=R8&myj#|i/fn3*wb(zyd~"Clotlw[firf}Uhu1;1_sv1=>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|Vir0;0=c:W3+bta&{l$ka>!re-qtkru'DidyczPcnwmpZe~4?4T~y<6;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw[f;?78h7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{_b{?3;Yu|;k0Y=!hrg,qb*ak8'xo#~ats-Ngjsi|VidyczPxnp?4;4f3\:$kh!rg-dh5(ul&x{by| MbmvjqYdg|dSua}<0<1e>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|Vrd~1<12`9V4*aun'xm#jb?.sf,vuhsz&Ghcx`{_bmvjqYg{682?o4U1-dvc(un&mg<#|k/srmpw)JkfexRm`uov\|jt;<78j7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{_ymq8085i2_;#j|i.sd,ci6)zm%y|cz}/LalqkrXkfexRv`r=4=6d=R8&myj#|i/fn3*wb(zyd~"Clotlw[firf}Usc28>3c8Q5)`zo$yj"ic0/pg+wvi|{%Fob{at^alqkrXpfx743<k;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw[}iu414T~y?i;T2,cw`)zo%l`= }d.psjqt(kfex1>11g9V4*aun'xm#jb?.sf,vuhsz&idycz31?3e?P6(o{l%~k!hl1,q`*twf}x$ob{at=0=5c=R8&myj#|i/fn3*wb(zyd~"m`uov?7;7a3\:$kh!rg-dh5(ul&x{by| cnwmp9299o1^<"i}f/pe+bj7&{n$~}`{r.alqkr;=7;m7X> gsd-vc)`d9$yh"|nup,gjsi|5<5=k5Z0.eqb+ta'nf;"j rqlwv*eh}g~7;3?i;T2,cw`)zo%l`= }d.psjqt(kfex1611d9V4*aun'xm#jb?.sf,vuhsz&idyczP00g8Q5)`zo$yj"ic0/pg+wvi|{%hcx`{_03f?P6(o{l%~k!hl1,q`*twf}x$ob{at^02a>S7'nxm"h gm2-va)uxg~y#naznu]05`=R8&myj#|i/fn3*wb(zyd~"m`uov\04c<]9%l~k }f.eo4+tc'{zex!lotlw[07b3\:$kh!rg-dh5(ul&x{by| cnwmpZ06m2_;#j|i.sd,ci6)zm%y|cz}/bmvjqY09l1^<"i}f/pe+bj7&{n$~}`{r.alqkrX0;80Y=!hrg,qb*ak8'xo#~ats-`kphsWm;7<3<=;T2,cw`)zo%l`= }d.psjqt(kfexRj><0<16>S7'nxm"h gm2-va)uxg~y#naznu]g5949:;1^<"i}f/pe+bj7&{n$~}`{r.alqkrXl8682?<4U1-dvc(un&mg<#|k/srmpw)dg|dSi?34?01?P6(o{l%~k!hl1,q`*twf}x$ob{at^f28085:2_;#j|i.sd,ci6)zm%y|cz}/bmvjqYc95<5>?5Z0.eqb+ta'nf;"j rqlwv*eh}g~Th<28>308Q5)`zo$yj"ic0/pg+wvi|{%hcx`{_e3?<;463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W98:7X> gsd-vc)`d9$yh"|nup,gjsi|Vn:S<<>;T2,cw`)zo%l`= }d.psjqt(kfexRj>_302?P6(o{l%~k!hl1,q`*twf}x$ob{at^f2[6463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W=8:7X> gsd-vc)`d9$yh"|nup,gjsi|Vn:S8<>;T2,cw`)zo%l`= }d.psjqt(kfexRj>_702?P6(o{l%~k!hl1,q`*twf}x$ob{at^f2[2463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W18?7X> gsd-vc)`d9$yh"|nup,gjsi|Vddx=>?12d8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-NeabXl`lmS}`{r^rb`Zgcl9:;<Rmv<1<0b>S7'nxm"h gm2-sw)`hy%k}h!wsre+HgclVnbjkQnup\tdbXimn;<=>Pcx>2:6`<]9%l~k }f.eo4+qu'n}j#if/uqtc)JimnThdhi_qlwvZvflVkoh=>?0^az8784n2_;#j|i.sd,ci6){%l{l}!gqd-swva'DkohRjffg]sjqtXxhnTmij?012\g|:46:l0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%FmijPdhde[uhszVzjhRokd1234Ze~4=48j6[?/fpe*w`(oe:%{!hw`q-cu`){zm#@okd^fjbcYwf}xT|ljPaef3456Xkp6>2>h4U1-dvc(un&mg<#y}/fubw+awn'}y|k!Baef\`l`aWyd~R~nd^cg`5678Vir0;0<f:W3+bta&{l$ka>!ws-dsdu)oyl%{~i/Lcg`ZbnnoU{by|Pp`f\eab789:Tot28>2d8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-NeabXl`lmS}`{r^rb`Zgcl9:;<Rmv<9<0b>S7'nxm"h gm2-sw)`hy%k}h!wsre+HgclVnbjkQnup\tdbXimn;<=>Pcx>::17<]9%l~k }f.eo4+qu'n}j#if/uqtc)JimnThdhi_qlwvZvflVkoh=>?0^nvp9776=:0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%FmijPdhde[uhszVzjhRokd1234Zjr|5;58;5Z0.eqb+ta'nf;"z| gvcp*bva&~x{j"Cnde]gmc`Xxg~yS}ok_`fg4567We0<0PIOT\416<]9%l~k }f.eo4+qu'n}j#if/uqtc)JimnThdhi_qlwvZvflVkoh=>?0^nvp949<91^<"i}f/pe+bj7&~x$kzo|.fre*rtwn&GjhiQkigd\tkruWykoSljk0123[iss4:4?<6[?/fpe*w`(oe:%{!hw`q-cu`){zm#@okd^fjbcYwf}xT|ljPaef3456Xd|~783:?;T2,cw`)zo%l`= xr.etev(`xo$|~}h M`fg[aoanVzexQae]b`a6789Ugyy2:>528Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-NeabXl`lmS}`{r^rb`Zgcl9:;<Rbzt=4=05=R8&myj#|i/fn3*rt(o~kx"j~i.vpsb*KflmUoekhPpovq[ugcWhno<=>?_mww828382_;#j|i.sd,ci6){%l{l}!gqd-swva'DkohRjffg]sjqtXxhnTmij?012\hpr;07>;7X> gsd-vc)`d9$|~"ixar,dtc(pzyl$Aljk_ekebZvi|{U{miQnde2345Yk}}6229?4U1-dvc(un&mg<#y}/fubw+awn'}y|k!Baef\`l`aWyd~R~nd^cg`5678Vrd~1??>528Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-NeabXl`lmS}`{r^rb`Zgcl9:;<Rv`r=3=05=R8&myj#|i/fn3*rt(o~kx"j~i.vpsb*KflmUoekhPpovq[ugcWhno<=>?_ymq878382_;#j|i.sd,ci6){%l{l}!gqd-swva'DkohRjffg]sjqtXxhnTmij?012\|jt;;7>;7X> gsd-vc)`d9$|~"ixar,dtc(pzyl$Aljk_ekebZvi|{U{miQnde2345Yg{6?29>4U1-dvc(un&mg<#y}/fubw+awn'}y|k!Baef\`l`aWyd~R~nd^cg`5678Vrd~1;1419V4*aun'xm#jb?.vp,crgt&nzm"z|f.Ob`aYcaolT|cz}_qcg[dbc89:;Sua}<7<74>S7'nxm"h gm2-sw)`hy%k}h!wsre+HgclVnbjkQnup\tdbXimn;<=>Pxnp?3;273\:$kh!rg-dh5(pz&m|m~ hpg,tvu`(EhnoSigif^rmpwYwimUjhi>?01]{kw:?6=:0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%FmijPdhde[uhszVzjhRokd1234Z~hz535?=5Z0.eqb+ta'nf;"z| gvcp*bva&~x{j"jffg]sjqtXxhn7==0=f:W3+bta&{l$ka>!ws-dsdu)oyl%{~i/ekebZvi|{U{mi2>>3d8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-gmc`Xxg~yS}ok<3<1b>S7'nxm"h gm2-sw)`hy%k}h!wsre+aoanVzexQae>0:7`<]9%l~k }f.eo4+qu'n}j#if/uqtc)caolT|cz}_qcg8185n2_;#j|i.sd,ci6){%l{l}!gqd-swva'mcmjR~ats]sea:26;l0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%oekhPpovq[ugc4?49j6[?/fpe*w`(oe:%{!hw`q-cu`){zm#igif^rmpwYwim6<2?h4U1-dvc(un&mg<#y}/fubw+awn'}y|k!kigd\tkruWyko050=f:W3+bta&{l$ka>!ws-dsdu)oyl%{~i/ekebZvi|{U{mi26>3g8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-gmc`Xxg~yS}ok_00e?P6(o{l%~k!hl1,tv*apiz$l|k xrqd,`l`aWyd~R~nd^336`=R8&myj#|i/fn3*rt(o~kx"j~i.vpsb*bnnoU{by|Pp`f\67c<]9%l~k }f.eo4+qu'n}j#if/uqtc)caolT|cz}_qcg[64b3\:$kh!rg-dh5(pz&m|m~ hpg,tvu`(l`lmS}`{r^rb`Z25m2_;#j|i.sd,ci6){%l{l}!gqd-swva'mcmjR~ats]seaY2:l1^<"i}f/pe+bj7&~x$kzo|.fre*rtwn&nbjkQnup\tdbX>;o0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%oekhPpovq[ugcW>8n7X> gsd-vc)`d9$|~"ixar,dtc(pzyl$hdhi_qlwvZvflV29i6[?/fpe*w`(oe:%{!hw`q-cu`){zm#igif^rmpwYwimU2?55Z0.eqb+ta'nf;"z| gvcp*bva&~x{j"jffg]sjqtXxhnTmij?012?5584?2_;#j|i.sd,ci6){%l{l}!gqd-swva'mcmjR~ats]seaYflm:;<=2>>258Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-gmc`Xxg~yS}ok_`fg45674;48;6[?/fpe*w`(oe:%{!hw`q-cu`){zm#igif^rmpwYwimUjhi>?01>0:61<]9%l~k }f.eo4+qu'n}j#if/uqtc)caolT|cz}_qcg[dbc89:;090<7:W3+bta&{l$ka>!ws-dsdu)oyl%{~i/ekebZvi|{U{miQnde2345:26:=0Y=!hrg,qb*ak8'}y#jyns/esb+quxo%oekhPpovq[ugcWhno<=>?<7<03>S7'nxm"h gm2-sw)`hy%k}h!wsre+aoanVzexQae]b`a67896<2>94U1-dvc(un&mg<#y}/fubw+awn'}y|k!kigd\tkruWykoSljk01238=84?2_;#j|i.sd,ci6){%l{l}!gqd-swva'mcmjR~ats]seaYflm:;<=26>3c8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-svjaXn|fgSd==;T2,cw`)zo%l`= xr.etev(`xo$|~}h psmd[cskdVcTaxv?01100>S7'nxm"h gm2-sw)`hy%k}h!wsre+uthoVl~`aQf_lw{4564989?7X> gsd-vc)`d9$|~"ixar,dtc(pzyl$|ah_gwohZoXe|r;<==>92:8Q5)`zo$yj"ic0/uq+bqf{'m{j#y}pg-svjaXn|fgSdQbuy23467>WZ];??5Z0.eqb+ta'nf;"z| gvcp*bva&~x{j"~}of]eqijXaVddx=>?13;8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.abvwim}6;2?74U1-dvc(un&mg<#y}/fubw+qt|z%h="mnrs{maq:66;30Y=!hrg,qb*ak8'}y#jyns/uppv)d9&ij~waeu>1:7?<]9%l~k }f.eo4+qu'n}j#y|tr-`5*efz{seiy2<>3d8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.enq}(`eR:V"jc>.l31b>S7'nxm"h gm2-sw)`hy%{~z|/b3,chs&ngP=P hmr,nw7`<]9%l~k }f.eo4+qu'n}j#y|tr-`5*aj}q$laV<R.fop*hu5n2_;#j|i.sd,ci6){%l{l}!wrvp+f7(ods"jcT3\,div(j{;l0Y=!hrg,qb*ak8'}y#jyns/uppv)d9&mfyu hmZ6^*bkt&dy9?6[?/fpe*w`(oe:%{!hw`q-svrt'j;$z<2?>318Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.t28485;2_;#j|i.sd,ci6){%l{l}!wrvp+f7(~8692?=4U1-dvc(un&mg<#y}/fubw+qt|z%h="x><2<17>S7'nxm"h gm2-sw)`hy%{~z|/b3,r4:36;h0Y=!hrg,qb*ak8'}y#jyns/uppv)d9&|:S=Qnne234575j2_;#j|i.sd,ci6){%l{l}!wrvp+f7(~8U:Sl`k012357d<]9%l~k }f.eo4+qu'n}j#y|tr-`5*p6W;Ujbi>?0131f>S7'nxm"h gm2-sw)`hy%{~z|/b3,r4Y4Whdo<=>?13`8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.t2[1Yffm:;<=?=9:W3+bta&{l$ka>!ws-dsdu)z~x#n< c`pq}kcs494956[?/fpe*w`(oe:%{!hw`q-svrt'j8$ol|}yogw848512_;#j|i.sd,ci6){%l{l}!wrvp+f4(khxyuck{<3<1=>S7'nxm"h gm2-sw)`hy%{~z|/b0,gdtuqgo0>0=f:W3+bta&{l$ka>!ws-dsdu)z~x#n< glw{*bk\8T$la< b13d8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.enq}(`eR;V"jc|.lq1b>S7'nxm"h gm2-sw)`hy%{~z|/b0,chs&ngP>P hmr,nw7`<]9%l~k }f.eo4+qu'n}j#y|tr-`6*aj}q$laV=R.fop*hu5n2_;#j|i.sd,ci6){%l{l}!wrvp+f4(ods"jcT4\,div(j{;90Y=!hrg,qb*ak8'}y#jyns/uppv)d:&|:0=0=3:W3+bta&{l$ka>!ws-dsdu)z~x#n< v0>2:75<]9%l~k }f.eo4+qu'n}j#y|tr-`6*p64;49?6[?/fpe*w`(oe:%{!hw`q-svrt'j8$z<2<>318Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.t28185j2_;#j|i.sd,ci6){%l{l}!wrvp+f4(~8U;Sl`k012357d<]9%l~k }f.eo4+qu'n}j#y|tr-`6*p6W8Ujbi>?0131f>S7'nxm"h gm2-sw)`hy%{~z|/b0,r4Y5Whdo<=>?13`8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.t2[6Yffm:;<=?=b:W3+bta&{l$ka>!ws-dsdu)z~x#n< v0]7[dhc89:;=?>4U1-dvc(un&mg<#y}/fubw+qt|z%hc`~>219V4*aun'xm#jb?.vp,crgt&~y"m`mq014>S7'nxm"h gm2-sw)`hy%{~z|/bmnt64c3\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%hm|vndv?4;4c3\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%hm|vndv?5;4c3\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%hm|vndv?6;4c3\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%hm|vndv?7;543\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%laxv!glY3Y+aj9'g:?>5Z0.eqb+ta'nf;"z| gvcp*rus{&mjj#m</fov|+ajS8W%k`}!mr10?P6(o{l%~k!hl1,tv*apiz$|y} g`d-g6)`e|r%k`U=]/enw+kt;:1^<"i}f/pe+bj7&~x$kzo|.vqww*afn'i8#jczx/en_6[)ody%a~=<;T2,cw`)zo%l`= xr.etev(p{}y$klh!c2-dip~)odQ?Q#ibs/op62=R8&myj#|i/fn3*rt(o~kx"z}{s.ebb+e4';7<3<8;T2,cw`)zo%l`= xr.etev(p{}y$klh!c2-u5979:>1^<"i}f/pe+bj7&~x$kzo|.vqww*afn'i8#{?32?04?P6(o{l%~k!hl1,tv*apiz$|y} g`d-g6)q9595>:5Z0.eqb+ta'nf;"z| gvcp*rus{&mjj#m</w3?0;4a3\:$kh!rg-dh5(pz&m|m~ xsuq,cd`)k:%}=R>Paof34566:o1^<"i}f/pe+bj7&~x$kzo|.vqww*afn'i8#{?P1^cm`567888m7X> gsd-vc)`d9$|~"ixar,twqu(ohl%o>!y1^0\ekb789::>k5Z0.eqb+ta'nf;"z| gvcp*rus{&mjj#m</w3\7Zgil9:;<<<i;T2,cw`)zo%l`= xr.etev(p{}y$klh!c2-u5Z2Xign;<=>>2b9V4*aun'xm#jb?.vp,crgt&~y"|nm^coijusWog`Rg<4:W3+bta&{l$ka>!ws-dsdu)z~x#ob_`nnkvrXn|fgSdQbuy2345523\:$kh!rg-dh5(pz&m|m~ xsuq,vdkXiegdyQiumn\mZkrp9:;<<=m;T2,cw`)zo%l`= xr.etev(p{}y$~lcPamolwqYa}efTeR``t12354YNF_U;>55Z0.eqb+ta'nf;"z| gvcp*rus{&xjaRhzlm]efZo5=2_;#j|i.sd,ci6){%l{l}!wrvp+wgjWog`Rg=d:W3+bta&{l$ka>!ws-dsdu)z~x#ob_gwohZoXe|r;<=>=e:W3+bta&{l$ka>!ws-dsdu)z~x#ob_gwohZoXe|r;<=>>1e9V4*aun'xm#jb?.vp,vdkX{UnbRg>1g9V4*aun'xm#jb?.vp,vdkX{UnbRg>_000?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphs:=1^<"i}f/pe+bj7&~x${}`{r.O`kphsWje~by?=4:W3+bta&{l$ka>!ws-ttkru'DidyczPcnwmp7433\:$kh!rg-dh5(pz&}{by| MbmvjqYdg|d??:4U1-dvc(un&mg<#y}/vrmpw)JkfexRm`uov761=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}?986[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at707?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphs?;>0Y=!hrg,qb*ak8'}y#z~ats-Ngjsi|Vidycz7259V4*aun'xm#jb?.vp,suhsz&Ghcx`{_bmvjq?512_;#j|i.sd,ci6){%||cz}/LalqkrXkfexRmv<1<1g>S7'nxm"h gm2-sw)pxg~y#@m`uov\gjsi|Vir0=0Pru0:?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphsWjs7=3<l;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw[f;97Uyx?74U1-dvc(un&mg<#y}/vrmpw)JkfexRm`uov\g|:56;i0Y=!hrg,qb*ak8'}y#z~ats-Ngjsi|VidyczPcx>1:Zts:01^<"i}f/pe+bj7&~x${}`{r.O`kphsWje~byQly=1=6f=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}Uhu1=1_sv1=>S7'nxm"h gm2-sw)pxg~y#@m`uov\gjsi|Vir090=c:W3+bta&{l$ka>!ws-ttkru'DidyczPcnwmpZe~4=4T~y<6;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw[f;=78h7X> gsd-vc)`d9$|~"ynup,Ifirf}Uhcx`{_b{?1;Yu|;30Y=!hrg,qb*ak8'}y#z~ats-Ngjsi|VidyczPcx>5:7e<]9%l~k }f.eo4+qu'~zex!BcnwmpZeh}g~Tot29>^pw6<=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}Uhu1912b9V4*aun'xm#jb?.vp,suhsz&Ghcx`{_bmvjqYdq5=5Sz=9:W3+bta&{l$ka>!ws-ttkru'DidyczPcnwmpZe~4149o6[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at^az8=8Xz}8j7X> gsd-vc)`d9$|~"ynup,Ifirf}Uhcx`{_ymq8585i2_;#j|i.sd,ci6){%||cz}/LalqkrXkfexRv`r=3=6d=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}Usc2=>3c8Q5)`zo$yj"ic0/uq+rvi|{%Fob{at^alqkrXpfx7?3<n;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw[}iu4=49m6[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at^zlv939:h1^<"i}f/pe+bj7&~x${}`{r.O`kphsWje~byQwos>5:7g<]9%l~k }f.eo4+qu'~zex!BcnwmpZeh}g~Ttb|37?0b?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphsWqey050=a:W3+bta&{l$ka>!ws-ttkru'DidyczPcnwmpZ~hz535>i5Z0.eqb+ta'nf;"z| wqlwv*Kdg|dSnaznu]{kw:>6Vx=k5Z0.eqb+ta'nf;"z| wqlwv*eh}g~7<3?i;T2,cw`)zo%l`= xr.usjqt(kfex1?11g9V4*aun'xm#jb?.vp,suhsz&idycz32?3e?P6(o{l%~k!hl1,tv*qwf}x$ob{at=1=5c=R8&myj#|i/fn3*rt(yd~"m`uov?0;7a3\:$kh!rg-dh5(pz&}{by| cnwmp9399o1^<"i}f/pe+bj7&~x${}`{r.alqkr;>7;m7X> gsd-vc)`d9$|~"ynup,gjsi|5=5=k5Z0.eqb+ta'nf;"z| wqlwv*eh}g~743?i;T2,cw`)zo%l`= xr.usjqt(kfex1711d9V4*aun'xm#jb?.vp,suhsz&idyczP00g8Q5)`zo$yj"ic0/uq+rvi|{%hcx`{_03f?P6(o{l%~k!hl1,tv*qwf}x$ob{at^02a>S7'nxm"h gm2-sw)pxg~y#naznu]05`=R8&myj#|i/fn3*rt(yd~"m`uov\04c<]9%l~k }f.eo4+qu'~zex!lotlw[07b3\:$kh!rg-dh5(pz&}{by| cnwmpZ06m2_;#j|i.sd,ci6){%||cz}/bmvjqY09l1^<"i}f/pe+bj7&~x${}`{r.alqkrX08o0Y=!hrg,qb*ak8'}y#z~ats-`kphsW0897X> gsd-vc)`d9$|~"ynup,gjsi|Vn:0=0=2:W3+bta&{l$ka>!ws-ttkru'je~byQk1=3=67=R8&myj#|i/fn3*rt(yd~"m`uov\`4:56;80Y=!hrg,qb*ak8'}y#z~ats-`kphsWm;7?3<=;T2,cw`)zo%l`= xr.usjqt(kfexRj><5<16>S7'nxm"h gm2-sw)pxg~y#naznu]g5939:;1^<"i}f/pe+bj7&~x${}`{r.alqkrXl86=2?<4U1-dvc(un&mg<#y}/vrmpw)dg|dSi?37?01?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f28=85:2_;#j|i.sd,ci6){%||cz}/bmvjqYc9535><5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th<Q?209V4*aun'xm#jb?.vp,suhsz&idyczPd0]264=R8&myj#|i/fn3*rt(yd~"m`uov\`4Y5:81^<"i}f/pe+bj7&~x${}`{r.alqkrXl8U8><5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th<Q;209V4*aun'xm#jb?.vp,suhsz&idyczPd0]664=R8&myj#|i/fn3*rt(yd~"m`uov\`4Y1:81^<"i}f/pe+bj7&~x${}`{r.alqkrXl8U<><5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th<Q7209V4*aun'xm#jb?.vp,suhsz&idyczPd0]:67=R8&myj#|i/fn3*rt(yd~"m`uov\`7:76;80Y=!hrg,qb*ak8'}y#z~ats-`kphsWm87=3<=;T2,cw`)zo%l`= xr.usjqt(kfexRj=<3<16>S7'nxm"h gm2-sw)pxg~y#naznu]g6959:;1^<"i}f/pe+bj7&~x${}`{r.alqkrXl;6?2?<4U1-dvc(un&mg<#y}/vrmpw)dg|dSi<35?01?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f18385:2_;#j|i.sd,ci6){%||cz}/bmvjqYc:5=5>?5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th?27>308Q5)`zo$yj"ic0/uq+rvi|{%hcx`{_e0?=;463\:$kh!rg-dh5(pz&}{by| cnwmpZb5W98:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn9S<<>;T2,cw`)zo%l`= xr.usjqt(kfexRj=_302?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f1[6463\:$kh!rg-dh5(pz&}{by| cnwmpZb5W=8:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn9S8<>;T2,cw`)zo%l`= xr.usjqt(kfexRj=_702?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f1[2463\:$kh!rg-dh5(pz&}{by| cnwmpZb5W18:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn9S4<=;T2,cw`)zo%l`= xr.usjqt(kfexRj<<1<16>S7'nxm"h gm2-sw)pxg~y#naznu]g7979:;1^<"i}f/pe+bj7&~x${}`{r.alqkrXl:692?<4U1-dvc(un&mg<#y}/vrmpw)dg|dSi=33?01?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f08185:2_;#j|i.sd,ci6){%||cz}/bmvjqYc;5?5>?5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th>29>308Q5)`zo$yj"ic0/uq+rvi|{%hcx`{_e1?3;453\:$kh!rg-dh5(pz&}{by| cnwmpZb44149>6[?/fpe*w`(oe:%{!xpovq+firf}Uo?171209V4*aun'xm#jb?.vp,suhsz&idyczPd2]364=R8&myj#|i/fn3*rt(yd~"m`uov\`6Y6:81^<"i}f/pe+bj7&~x${}`{r.alqkrXl:U9><5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th>Q<209V4*aun'xm#jb?.vp,suhsz&idyczPd2]764=R8&myj#|i/fn3*rt(yd~"m`uov\`6Y2:81^<"i}f/pe+bj7&~x${}`{r.alqkrXl:U=><5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th>Q8209V4*aun'xm#jb?.vp,suhsz&idyczPd2];64=R8&myj#|i/fn3*rt(yd~"m`uov\`6Y>:=1^<"i}f/pe+bj7&~x${}`{r.alqkrXff~;<=?>7:W3+bta&{l$ahc dnww[l:76820Y=!hrg,qb*kbe&ndyyQf<02=5==R8&myj#|i/lgn+air|Vc7=<0>8:W3+bta&{l$ahc dnww[l:6:7;37X> gsd-vc)jmd%ocxzPi=30:4><]9%l~k }f.ofi*bh}}Ub0<:1199V4*aun'xm#`kb/emvpZo;9<4:46[?/fpe*w`(elg$hb{{_h>22;7?3\:$kh!rg-nah)cg|~Te1?8>0:8Q5)`zo$yj"cjm.flqqYn4825=55Z0.eqb+ta'dof#iazt^k?5<86?2_;#j|i.sd,i`k(lfSd2>>0:8Q5)`zo$yj"cjm.flqqYn4;:5=55Z0.eqb+ta'dof#iazt^k?648602_;#j|i.sd,i`k(lfSd2=2?3;?P6(o{l%~k!bel-gkprXa5882<64U1-dvc(un&gna"j`uu]j8729911^<"i}f/pe+hcj'me~xRg324<2<>S7'nxm"h mdo,`jssW`69:3?7;T2,cw`)zo%fi`!kotv\m9406820Y=!hrg,qb*kbe&ndyyQf<3:=5==R8&myj#|i/lgn+air|Vc7>40>7:W3+bta&{l$ahc dnww[l:56820Y=!hrg,qb*kbe&ndyyQf<22=5==R8&myj#|i/lgn+air|Vc7?<0>8:W3+bta&{l$ahc dnww[l:4:7;37X> gsd-vc)jmd%ocxzPi=10:4><]9%l~k }f.ofi*bh}}Ub0>:1199V4*aun'xm#`kb/emvpZo;;<4:;6[?/fpe*w`(elg$hb{{_h>0:41<]9%l~k }f.ofi*bh}}Ub090>7:W3+bta&{l$ahc dnww[l:268=0Y=!hrg,qb*kbe&ndyyQf<7<23>S7'nxm"h mdo,`jssW`6<2<94U1-dvc(un&gna"j`uu]j8=86?2_;#j|i.sd,i`k(lfSd26>048Q5)`zo$yj"cjm.flqqYnW9;=7X> gsd-vc)jmd%ocxzPi^323>S7'nxm"h mdo,`jssW`U:<<94U1-dvc(un&gna"j`uu]j[476?2_;#j|i.sd,i`k(lfSdQ>2058Q5)`zo$yj"cjm.flqqYnW89:;6[?/fpe*w`(elg$hb{{_h]2041<]9%l~k }f.ofi*bh}}UbS<;>7:W3+bta&{l$ahc dnww[lY6>8=0Y=!hrg,qb*kbe&ndyyQf_0523>S7'nxm"h mdo,`jssW`U:4<94U1-dvc(un&gna"j`uu]j[4?6>2_;#j|i.sd,i`k(lfSdQ=169V4*aun'xm#`kb/emvpZoX:9;<7X> gsd-vc)jmd%ocxzPi^0252=R8&myj#|i/lgn+air|VcT>??8;T2,cw`)zo%fi`!kotv\mZ449>1^<"i}f/pe+hcj'me~xRgP2534?P6(o{l%~k!bel-gkprXaV8>=:5Z0.eqb+ta'dof#iazt^k\63703\:$kh!rg-nah)cg|~TeR<8169V4*aun'xm#`kb/emvpZoX:1;<7X> gsd-vc)jmd%ocxzPi^0:53=R8&myj#|i/lgn+air|VcT?<94U1-dvc(un&gna"j`uu]j[666?2_;#j|i.sd,i`k(lfSdQ<1058Q5)`zo$yj"cjm.flqqYnW:8:;6[?/fpe*w`(elg$hb{{_h]0741<]9%l~k }f.ofi*bh}}UbS>:>7:W3+bta&{l$ahc dnww[lY4=8<0Y=!hrg,qb*kbe&ndyyQf_535?P6(o{l%~k!bel-gkprXaV?::6[?/fpe*w`(elg$hb{{_h]553=R8&myj#|i/lgn+air|VcT;<84U1-dvc(un&gna"j`uu]j[=713\:$kh!rg-nah)cg|~TeR7>9:W3+bta&{l$ahc dnww[hcj494:m6[?/fpe*w`(elg$hb{{_lgn84699h1^<"i}f/pe+hcj'me~xRcjm=32:4g<]9%l~k }f.ofi*bh}}Ufi`2>2?3b?P6(o{l%~k!bel-gkprXelg7=>0>a:W3+bta&{l$ahc dnww[hcj48>5=l5Z0.eqb+ta'dof#iazt^ofi97268k0Y=!hrg,qb*kbe&ndyyQbel>22;7f3\:$kh!rg-nah)cg|~Tahc316<2e>S7'nxm"h mdo,`jssWdof0<611`9V4*aun'xm#`kb/emvpZkbe5;22<74U1-dvc(un&gna"j`uu]nah:668k0Y=!hrg,qb*kbe&ndyyQbel>14;7f3\:$kh!rg-nah)cg|~Tahc320<2e>S7'nxm"h mdo,`jssWdof0?<11`9V4*aun'xm#`kb/emvpZkbe5882<o4U1-dvc(un&gna"j`uu]nah:5<7;j7X> gsd-vc)jmd%ocxzPmdo?6086i2_;#j|i.sd,i`k(lfS`kb<34=5d=R8&myj#|i/lgn+air|Vgna1<8>0c8Q5)`zo$yj"cjm.flqqYjmd6943?n;T2,cw`)zo%fi`!kotv\i`k;:04:56[?/fpe*w`(elg$hb{{_lgn8786i2_;#j|i.sd,i`k(lfS`kb<22=5d=R8&myj#|i/lgn+air|Vgna1=>>0c8Q5)`zo$yj"cjm.flqqYjmd68>3?n;T2,cw`)zo%fi`!kotv\i`k;;:4:m6[?/fpe*w`(elg$hb{{_lgn86299h1^<"i}f/pe+hcj'me~xRcjm=16:4?<]9%l~k }f.ofi*bh}}Ufi`2<>0;8Q5)`zo$yj"cjm.flqqYjmd6?2<74U1-dvc(un&gna"j`uu]nah:26830Y=!hrg,qb*kbe&ndyyQbel>5:4?<]9%l~k }f.ofi*bh}}Ufi`28>0;8Q5)`zo$yj"cjm.flqqYjmd632<74U1-dvc(un&gna"j`uu]nah:>6>>0Y=!hrg,qb*kbe&mia#immf,dfhaf&gmnon mmf-ahnYjmdUlick}aumq+sgkam$hy| r`ookjv\8T$ym` }/r1\jjoia}$ym`!kpscn*av60q9="ob1c9V4*aun'xm#`kb/uos[wgjW{nTic?l;T2,cw`)zo%fi`!{mq]qehYulVoe=<94U1-dvc(un&xjaR|jgnww[`h6l2_;#j|i.sd,vvredb%yhR||t^cpv`a582_;#j|i.sd,vvredb%yhR||t^cpv`aXl88;7X> gsd-vc)u{}hgg"|k_sqw[duumnUo><m4U1-dvc(un&xxxobd/sf\vvrXkfgi=i5Z0.eqb+ta'{ynae re]qwqYdgdh:=h5Z0.eqb+ta'{ynae re]qwqYumn6;2<k4U1-dvc(un&xxxobd/sf\vvrXzlm7=3?j;T2,cw`)zo%yylck.pg[wusW{ol0?0>d:W3+bta&{l$~~zmlj-q`Ztt|VxnkR>>d:W3+bta&{l$~~zmlj-q`Ztt|VxnkR?>d:W3+bta&{l$~~zmlj-q`Ztt|VxnkR<>d:W3+bta&{l$~~zmlj-tvZtt|Vkx~hi=0:W3+bta&{l$~~zmlj-tvZtt|Vkx~hiPd003?P6(o{l%~k!}su`oo*quW{ySl}}ef]g64e<]9%l~k }f.pppgjl'~xT~~zPcnoa5a=R8&myj#|i/sqwfim({UyyQlol`25`=R8&myj#|i/sqwfim({UyyQ}ef>3:4c<]9%l~k }f.pppgjl'~xT~~zPrde?5;7c3\:$kh!rg-qwqdkc&}yS}{_sgd[57c3\:$kh!rg-qwqdkc&}yS}{_sgd[4g<]ZOYSLBFARa8QVCUW_CXEOBJ3:T@G<=QAL]TXT^J3:UFE6=PMKi0[_G[E^OL@@YFk2]YEYKPMNFF[Gb<_[C_IRYFDUJ\Ea=PZ@^NSZGKTI]A5a=_AECET VKB!2-5%US]K*;"<.NSBKJ1>^HZJS=7U][LH@4?]USWNDO;6V\T^T@Gg=_WJEYIRGAFN48\adXAml0TifPPsknR`ttafd:<6Vkm^ObnjtQm{ybcc??;Yfn[Hoig{\n~~g`nb9bhhit|Vof|ywm;`nnkvrXn|fg:6lncjws`>dfkb{S`o}kdp0?fjll2njxlQlotlw,5/c3mkmRm`uov+5,b<lh~jSnaznu*1-a=ci}kTob{at)1*`>bf|hUhcx`{(5+g?agsiVidycz'5(f8`drfWje~by&9)e9geqgXkfex%9&d:fbpdYdg|d$5'k;ecweZeh}g~#5$h4d`vb[firf}626=08;e`jp`tu>2nbb%>&6:fjj-7.?2nbb%??)69gmk.69 =0hd`'13+4?aoi 89";6jfn)37-2=cag":9$94dhl+53/03mce$<9&6:fjj-4.>2nbb%=&6:fjj-2.>2nbb%;&6:fjj-0.>2nbb%9&6:fjj->.>2nbb%7&6:fjj969?2nbb1??>69gmk:697=0hd`313<4?aoi4895;6jfn=37:2=cag6:9394dhl?538>3mce0<950?58`lh;9>4=7iga<0<5?aoi4;4=7iga<2<5?aoi4=4=7iga<4<5?aoi4?4=7iga<6<5?aoi414=7iga<8<4?air|!:";6j`uu*2-==cg|~#=='7;emvp-76!11ocxz'13+;?air|!;8%55kotv+51/?3me~x%?:)99gkpr/9?#37iazt)34-==cg|~#=5'7;emvp-7>!>1ocxz'2(:8`jss ;:"46j`uu*15,><lf$?<&8:flqq.5; 20hb{{(36*<>bh}}"99$64dnww,70.02ndyy&=7(:8`jss ;2"46j`uu*1=,1<lf$>'7;emvp-57!11ocxz'30+;?air|!99%55kotv+76/?3me~x%=;)99gkpr/;<#<7iazt)6*3>bh}}">%:5kotv+2,1<lf$:'8;emvp->.?2ndyy&6)69gkpr;8720hb{{<02=<>bh}}6:=364dnww844902ndyy2>3?:8`jss48>546j`uu>21;><lf0<818:flqq:6?720hb{{<0:=<>bh}}6:5394dnww848?3me~x1<?>99gkpr;:8437iazt=01:==cg|~7>>07;emvp943611ocxz324<;?air|58=255kotv?628?3me~x1<7>99gkpr;:04<7iazt=0=<>bh}}68<364dnww867902ndyy2<2?:8`jss4:9546j`uu>00;g<lf0>;50?:8`jss4:?5;6j`uu>0:2=cg|~78394dnww80803me~x1817:flqq:06>1ocxz38?58`jss40437hjff3ld`0=bey~r>k5iigm\c`hbzh~d~Rx9_0.#\ljnfq*HC_K/Gdlfvdrhz);9"<?l;gkekZ~kfqU>=?v<6^0`hnY60}e8:>o4fhdl[}jipV?:>u=9_3aooZ7?|f9= kgio^efj`tf|fxTz;Q>,OMMA)HHFL>;?6hffn]{hk~X=88s?;Q=cmi\5=rh;?&mekaPgdlfvdrhzV|=S<"tc^jbwZoi|Vigg0>#c^jbwZuu{}7; nQ}d^dqat;6$jUnbllce^pppZu~fj7: nQgar]q`Zbf|hUhcx`{=1.`[aoiW~coxe3>8-a\lduX{UomyoPcnwmp86+kVl~`aQil`ep[wusWkg1="l_hosh`kbf}keb`Ptxrf97*dW|ynShcmeeff`Ztbo4:'oRy}_gpfu87+kVxiRj`uu]qwq;6$jU~bik}fmmt[iip59&hSeo|_ntfvcjh4:'oR~}emmb`Zjf|ldhu0>#c^flqqYpam~c1>8#c^opcjhX~hf6=!mPre]gauro5<;9 nQjrsmq[lhmmj~bccQ{yqg>4)eX`hyTycjjrgnls86+kVbjRocmnqw[cskd4;'oRfns^ppp87+kVnjxlQlotlw[roc|a7:<!mPh`q\swYfkb7; nQzsd]fgf;7$jUhc`c`n^aokfm:8%iT{Qncj]okr;7$jUyhR~ats]tmaro50&hSx}j_guepZbf|hUhcx`{=1.`[mgtWhffc~zPelrw}86+kVxoSio{a^alqkrX`nd07#c^muaw`kg~Ugcz3?,b]tvZvi|{U|eizg=02/gZvugnUna}zv_u{sa86+kV}ySio{a^alqkrX`nd0??,b]sv`jhimUyij}21-a\`jssW{yS{oc=1.`[mgtWmkmRm`uov>4)eXx{elSk{cl^vkv`uoWgolmykPv`n>5573$jU|~Rjjpuj>5543$jU{~biPelrw}ZrozlycSckhaug\rdj:=%iT|ah_dosp|Ys`{oxdRo|sdpw[sgk5=&hSeo|_wcoma;7$jU{~biPftno[qnumzbTm~}jru]uei;688?'obcoogmpZhfel7mekaPxml{[075p:<T>nbd_0:wk60+kV|j`djPlnu>4)eXx{cfSkgio^vzt`;6cq;3 nQrne\bpjkW}s{i0?#c^ofijt~W}s{i0?#}248bl`hWqfetR;>2y15[7ekcV;3xb=9_gkekZabflxjxb|Pv7]2[}usW8>0jxbcd:kmn`eslkci|k;hliafrtj`~n~94iov\gim?3gmhnxgcd99lr`tadf}j7}|`g^gntq6<2zycjQjmqvz[qnumzb#<$?;;qplcZcjx}sTxe|jsi*2-42<x{elShctx]wlwct`!8"=95rne\ahvsqV~c~h}g(2+20>vugnUna}zv_ujqavn/< ;?7}|`g^gntqX|axne&:)068twi`Wlg{xtQ{hsgpl-0.9=1{~biPelrw}Zrozlyc$:'>4:rqkbYbey~rSyf}erj+<,713yxdkRkbpu{\pmtb{a636=0>b:rqkbYbey~rSyf}erj\evubz}";%<l4psmd[`kw|pUdk|h^cpw`ts 8#:n6~}of]fiur~W}byi~fParqfvq.5!8h0|ah_dosp|Ys`{oxdRo|sdpw,6/6j2zycjQjmqvz[qnumzbTm~}jru*7-4d<x{elShctx]wlwct`Vkxh|{(4+2f>vugnUna}zv_ujqavnXizyn~y&9)0`8twi`Wlg{xtQ{hsgplZgt{lx$:'>b:rqkbYbey~rSyf}erj\evubz}"3%<j4psmd[`kw|pUdk|h^cpw`ts410;2<l4psmd[`kw|pUdk|h^lfcdrb 9#:n6~}of]fiur~W}byi~fPndebp`.6!8h0|ah_dosp|Ys`{oxdR`jg`vf,7/6j2zycjQjmqvz[qnumzbTbhintd*0-4d<x{elShctx]wlwct`Vdnklzj(5+2f>vugnUna}zv_ujqavnXflmjxh&:)0`8twi`Wlg{xtQ{hsgplZhboh~n$;'>b:rqkbYbey~rSyf}erj\j`af|l"<%<l4psmd[`kw|pUdk|h^lfcdrb 1#:h6~}of]fiur~W}byi~fPndebp`:?29427}|`g^dvhi743yxdkRhzlm]wlwct`!:"=>5rne\bpjkW}byi~f'1(30?uthoVl~`aQ{hsgpl-4.9:1{~biPftno[qnumzb#?$?<;qplcZ`rdeUdk|h)6*56=wzfmTjxbc_ujqavn/= ;87}|`g^dvhiYs`{oxd%8&129svjaXn|fgSyf}erj+3,743yxdkRhzlm]wlwct`!2"=>5rne\bpjkW}byi~f'9(36?uthoVl~`aQ{hsgpl9?=87;j7}|`g^dvhiYs`{oxdRo|sdpw,5/6i2zycjQiumn\pmtb{aUj~k}t)3*5d=wzfmTjxbc_ujqavnXizyn~y&=)0c8twi`Wog`Rzgrdqk[dutm{~#?$?n;qplcZ`rdeUdk|h^cpw`ts =#:m6~}of]eqijX|axneQnsrgqp-3.9h1{~biPftno[qnumzbTm~}jru*5-4g<x{elSk{cl^vkv`uoWhyxiz'7(3b?uthoVl~`aQ{hsgplZgt{lx$5'>a:rqkbYa}efTxe|jsi]bwvcu|!3"=n5rne\bpjkW}byi~fParqfvq:>294:m6~}of]eqijX|axneQaefcwa-6.9h1{~biPftno[qnumzbTbhintd*2-4g<x{elSk{cl^vkv`uoWgolmyk'2(3b?uthoVl~`aQ{hsgplZhboh~n$>'>a:rqkbYa}efTxe|jsi]mabgsm!>"=l5rne\bpjkW}byi~fPndebp`.2!8k0|ah_gwohZrozlycSckhaug+2,7f3yxdkRhzlm]wlwct`Vdnklzj(6+2e>vugnUmyabPtipfwmYimnki%6&1`9svjaXn|fgSyf}erj\j`af|l"2%<m4psmd[cskdV~c~h}g_ogdeqc;13:5:6|k_bnh55=ulVnjxlQlotlw,5/682xoSio{a^alqkr/9 ;;7jPd`vb[firf}"9%<>4re]geqgXkfex%=&119q`Zbf|hUhcx`{(5+24>tcWmkmRm`uov+1,773{nThlzn_bmvjq.1!8:0~iQkauc\gjsi|!="==5}d^fbpdYdg|d$5'>0:pg[agsiVidycz30?31?wbXlh~jSnaznu>;>5823{nTic84re]qwq5<zz~<7~lftdpq0>uu{}837yc/^ad+coagVrgbuQ:13z02Z4ddbU:4ya<6/ldk1=sz|o27x`kesdokr3<~hfbh;5xr^c`o3=pzVigg<>4ws]geqgXkfex%>&119tvZbf|hUhcx`{(0+24>quWmkmRm`uov+6,773~xThlzn_bmvjq.4!8:0{Qkauc\gjsi|!>"==5xr^fbpdYdg|d$8'>0:uq[agsiVidycz'6(33?rtXlh~jSnaznu*4-46<{UomyoPcnwmp->.991|~Rjnt`]`kphs 0#:>6y}_ecweZeh}g~757>15:uq[`h13~xT~~zr@Ar``==GHq?=>7H54;3xW1c==991;7?<2c4g6?4f:k=pb96=:09m0=5=>2.?4=4;7`9~W1e==991;7?<2c4g6?4f:k=0_<<m:42f>5<6;;h=h?4=a3`;?V2d2<:n6=4>33`5`7<5i;h37i;?6;295?7|[=o19==57;306g0c:38j>o94vU3;e?6=93;1=n>tS5g9155=?3;8>o8k2;0b6g1<,==86<<l;W6;5?4|}89?6<5z12794>{#9>o1=55m51494?5a2:08jvF;709Y01<5s8=1==4r$0:e>0613-><j7;?5:k61a<722e?484?::m66c<722c>;>4?::m64d<722e><94?::k622<722c>9k4?::m7`2<72-;3<7:ia:l23c<732e?h;4?:%3;4?2ai2d:;k4>;:m7`0<72-;3<7:ia:l23c<532e?h94?:%3;4?2ai2d:;k4<;:m7`6<72-;3<7:ia:l23c<332e?h?4?:%3;4?2ai2d:;k4:;:m7`5<72-;3<7:ia:l23c<132e?ok4?:%3;4?2ai2d:;k48;:m7g`<72-;3<7:ia:l23c<?32e?oi4?:%3;4?2ai2d:;k46;:m7gf<72-;3<7:ia:l23c<f32e?oo4?:%3;4?2ai2d:;k4m;:m7gd<72-;3<7:ia:l23c<d32e?o44?:%3;4?2ai2d:;k4k;:m7g=<72-;3<7:ia:l23c<b32e?o:4?:%3;4?2ai2d:;k4i;:m7g0<72-;3<7:ia:l23c<6821d8n:50;&2<5<3nh1e=:h51098k1e4290/=5>54gc8j41a28807b:l2;29 4>72=lj7c?8f;30?>i3k80;6)?70;6ee>h6?o0:865`4b294?"6090?jl5a16d950=<g=hm6=4+19290cg<f8=m6<84;n6aa?6=,82;69hn;o34b?7032e?ni4?:%3;4?2ai2d:;k4>8:9l0ge=83.:4=4;f`9m52`=9010c9jk:18'5=6=<ok0b<9i:0c8?j2ck3:1(<6?:5db?k70n3;i76a;dc83>!7?83>mm6`>7g82g>=h<mk1<7*>8187bd=i9>l1=i54o5f:>5<#91:18ko4n05e>4c<3f>o47>5$0:3>1`f3g;<j7?i;:m7`4<72-;3<7:ia:l23c<5821d8n850;&2<5<3nh1e=:h52098k1de290/=5>54gc8j41a2;807b:ma;29 4>72=lj7c?8f;00?>o31l0;6)?70;6bb>h6?o0;76g;9e83>!7?83>jj6`>7g82?>o31j0;6)?70;6bb>h6?o0976g;9c83>!7?83>jj6`>7g80?>o31h0;6)?70;6bb>h6?o0?76g;9883>!7?83>jj6`>7g86?>o3110;6)?70;6bb>h6?o0=76g;9683>!7?83>jj6`>7g84?>o3i?0;6)?70;6bb>h6?o0376g;a483>!7?83>jj6`>7g8:?>o3i=0;6)?70;6bb>h6?o0j76g;a283>!7?83>jj6`>7g8a?>o3i;0;6)?70;6bb>h6?o0h76g;a083>!7?83>jj6`>7g8g?>o3i90;6)?70;6bb>h6?o0n76g;9g83>!7?83>jj6`>7g8e?>o31?0;6)?70;6bb>h6?o0:<65f48794?"6090?mk5a16d954=<a<?:6=44b551>5<6290;wE:81:&2<c<3?;1d=:j50;9~fa1=83;1<7>tH552?!7?n3n<7bj9:188yg24290j:7?74;3`4~N3?81Q894>6z0;>71=:00h644n:c823?772;k1h7m5d;34>7g=:10:<7l5a;;96<<5?3w/=5h551;8 11==9=0(9j551:8 41>28=h7d;=3;29 4>72<8?7c?8f;28?l35:3:1(<6?:407?k70n3;07d;=1;29 4>72<8?7c?8f;08?l3583:1(<6?:407?k70n3907d;>f;29 4>72<8?7c?8f;68?l36m3:1(<6?:407?k70n3?07d;>d;29 4>72<8?7c?8f;48?l36k3:1(<6?:407?k70n3=07d;>b;29 4>72<8?7c?8f;:8?l37k3:17d;:e;29?l3193:17b;95;29?l3613:1(<6?:43b?k70n3:07d;>8;29 4>72<;j7c?8f;38?l36?3:1(<6?:43b?k70n3807d;>6;29 4>72<;j7c?8f;18?l36=3:1(<6?:43b?k70n3>07d;>4;29 4>72<;j7c?8f;78?l36;3:1(<6?:43b?k70n3<07d;>2;29 4>72<;j7c?8f;58?l3693:1(<6?:43b?k70n3207d;:d;29?j37n3:17d;=d;29 4>72<8n7c?8f;28?l35k3:1(<6?:40f?k70n3;07d;=b;29 4>72<8n7c?8f;08?l35i3:1(<6?:40f?k70n3907d;=9;29 4>72<8n7c?8f;68?l3503:1(<6?:40f?k70n3?07d;=7;29 4>72<8n7c?8f;48?l35>3:1(<6?:40f?k70n3=07d;=5;29 4>72<8n7c?8f;:8?j2?=3:17b:62;29 4>72=387c?8f;28?j2>93:1(<6?:5;0?k70n3;07b:60;29 4>72=387c?8f;08?j2?n3:1(<6?:5;0?k70n3907b:7e;29 4>72=387c?8f;68?j2?l3:1(<6?:5;0?k70n3?07b:7c;29 4>72=387c?8f;48?j2?j3:1(<6?:5;0?k70n3=07b:7a;29 4>72=387c?8f;:8?j2?13:1(<6?:5;0?k70n3307b;=f;29?l30;3:17d;<9;29 4>72<9j7c?8f;28?l3403:1(<6?:41b?k70n3;07d;<7;29 4>72<9j7c?8f;08?l34>3:1(<6?:41b?k70n3907d;<5;29 4>72<9j7c?8f;68?l34<3:1(<6?:41b?k70n3?07d;<3;29 4>72<9j7c?8f;48?l34:3:1(<6?:41b?k70n3=07d;<1;29 4>72<9j7c?8f;:8?l3483:1(<6?:41b?k70n3307b;?a;29?j37<3:17d;97;29?l2??3:17d;;4;29 4>72<>>7c?8f;28?l33;3:1(<6?:466?k70n3;07d;;2;29 4>72<>>7c?8f;08?l3393:1(<6?:466?k70n3907d;;0;29 4>72<>>7c?8f;68?l34n3:1(<6?:466?k70n3?07d;<e;29 4>72<>>7c?8f;48?l34l3:1(<6?:466?k70n3=07d;<c;29 4>72<>>7c?8f;:8?l34j3:1(<6?:466?k70n3307d;;f;29 4>72<?;7c?8f;28?l33m3:1(<6?:473?k70n3;07d;;d;29 4>72<?;7c?8f;08?l33k3:1(<6?:473?k70n3907d;;b;29 4>72<?;7c?8f;68?l33i3:1(<6?:473?k70n3?07d;;9;29 4>72<?;7c?8f;48?l3303:1(<6?:473?k70n3=07d;;7;29 4>72<?;7c?8f;:8?l33>3:1(<6?:473?k70n3307b:74;29?l37l3:17d:78;29?l30<3:17b;90;29?j31>3:17d;:f;29?j2c?3:1(<6?:5db?k70n3:07b:k6;29 4>72=lj7c?8f;38?j2c=3:1(<6?:5db?k70n3807b:k4;29 4>72=lj7c?8f;18?j2c;3:1(<6?:5db?k70n3>07b:k2;29 4>72=lj7c?8f;78?j2c83:1(<6?:5db?k70n3<07b:lf;29 4>72=lj7c?8f;58?j2dm3:1(<6?:5db?k70n3207b:ld;29 4>72=lj7c?8f;;8?j2dk3:1(<6?:5db?k70n3k07b:lb;29 4>72=lj7c?8f;`8?j2di3:1(<6?:5db?k70n3i07b:l9;29 4>72=lj7c?8f;f8?j2d03:1(<6?:5db?k70n3o07b:l7;29 4>72=lj7c?8f;d8?j2d=3:1(<6?:5db?k70n3;;76a;c583>!7?83>mm6`>7g825>=h<j91<7*>8187bd=i9>l1=?54o5a1>5<#91:18ko4n05e>45<3f>h=7>5$0:3>1`f3g;<j7?;;:m7g5<72-;3<7:ia:l23c<6=21d8oh50;&2<5<3nh1e=:h51798k1db290/=5>54gc8j41a28=07b:md;29 4>72=lj7c?8f;3;?>i3jj0;6)?70;6ee>h6?o0:565`4ef94?"6090?jl5a16d95d=<g=nh6=4+19290cg<f8=m6<l4;n6gf?6=,82;69hn;o34b?7d32e?hl4?:%3;4?2ai2d:;k4>d:9l0a?=83.:4=4;f`9m52`=9l10c9j7:18'5=6=<ok0b<9i:0d8?j2c93:1(<6?:5db?k70n38;76a;c783>!7?83>mm6`>7g815>=h<kh1<7*>8187bd=i9>l1>?54o5`b>5<#91:18ko4n05e>75<3`>2i7>5$0:3>1ga3g;<j7>4;h6:`?6=,82;69oi;o34b?7<3`>2o7>5$0:3>1ga3g;<j7<4;h6:f?6=,82;69oi;o34b?5<3`>2m7>5$0:3>1ga3g;<j7:4;h6:=?6=,82;69oi;o34b?3<3`>247>5$0:3>1ga3g;<j784;h6:3?6=,82;69oi;o34b?1<3`>j:7>5$0:3>1ga3g;<j764;h6b1?6=,82;69oi;o34b??<3`>j87>5$0:3>1ga3g;<j7o4;h6b7?6=,82;69oi;o34b?d<3`>j>7>5$0:3>1ga3g;<j7m4;h6b5?6=,82;69oi;o34b?b<3`>j<7>5$0:3>1ga3g;<j7k4;h6:b?6=,82;69oi;o34b?`<3`>2:7>5$0:3>1ga3g;<j7??;:k7=0<72-;3<7:nf:l23c<6921b85850;9l10g=83.:4=4:5b9m52`=821d98750;&2<5<2=j1e=:h51:9l10>=83.:4=4:5b9m52`=:21d98950;&2<5<2=j1e=:h53:9l100=83.:4=4:5b9m52`=<21d98;50;&2<5<2=j1e=:h55:9l102=83.:4=4:5b9m52`=>21d98=50;&2<5<2=j1e=:h57:9l104=83.:4=4:5b9m52`=021d9:?50;&2<5<2?;1e=:h50:9l126=83.:4=4:739m52`=921d9;h50;&2<5<2?;1e=:h52:9l13c=83.:4=4:739m52`=;21d9;j50;&2<5<2?;1e=:h54:9l13e=83.:4=4:739m52`==21d9;l50;&2<5<2?;1e=:h56:9l13g=83.:4=4:739m52`=?21d9;750;&2<5<2?;1e=:h58:9l13>=83.:4=4:739m52`=121d9<>50;9j15d=831d84:50;9j107=831d9;:50;9a02b=83;1<7>t$0:e>a1<@==h7E:81:mg2?6=3th?;h4?:083>5}#91l18:<4H55`?M2092e:;i4?::a6d6=83>1<7>t$0:e>a4<@==h7E:81:&f1?0<a=?1<75f4g83>>o6080;66a>8383>>{e<<o1<7=50;2x 4>a2jl0D99l;I645>N3:2.:??4:629'a0<63`>>6=44i5d94?=h9181<75rb54:>5<4290;w)?7f;ae?M20k2B?;<5G439'564==?90(h;51:k71?6=3`>m6=44o0:1>5<<uk>>h7>53;294~"60o0hj6F;7b9K027<@=80(<==:440?!c2281b884?::k7b?6=3f;3>7>5;|`722<72<0;6=u+19d9`6=O<>i0D99>;I61?!74:3?=?6g;5;29?l212900e9h50;9j5=7=831d=5<50;9~f10?29086=4?{%3;b?ea3A><o6F;709K07=#9:819;=4$d795>o3=3:17d:i:188k4>52900qo::c;291?6=8r.:4k4k3:J73f=O<>;0D9<4$011>0043`>>6=44i5494?=n<o0;66g>8083>>i60;0;66sm47494?2=83:p(<6i:e08L11d3A><=6*j5;48m13=831b8k4?::k2<4<722e:4?4?::a033=83>1<7>t$0:e>a4<@==h7E:81:&f1?0<a=?1<75f4g83>>o6080;66a>8383>>{e<?>1<7:50;2x 4>a2m80D99l;I645>"b=3<0e9;50;9j0c<722c:4<4?::m2<7<722wi8;h50;694?6|,82m6i<4H55`?M2092.n9784i5794?=n<o0;66g>8083>>i60;0;66sm47g94?2=83:p(<6i:e08L11d3A><=6*j5;48m13=831b8k4?::k2<4<722e:4?4?::a642=83>1<7>t$0:e>a6<@==h7E:81:&f1?7<a=?1<75f4c83>>o3n3:17b?72;29?xd59:0;694?:1y'5=`=l91C8:m4H552?!c2281b884?::k7f?6=3`>m6=44o0:1>5<<uk8:>7>54;294~"60o0o<6F;7b9K027<,l?1=6g;5;29?l2e2900e9h50;9l5=4=831vn??>:187>5<7s-;3j7j?;I64g>N3?81/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm20294?2=83:p(<6i:e28L11d3A><=6*j5;38m13=831b8o4?::k7b?6=3f;3>7>5;|`14c<72=0;6=u+19d9`5=O<>i0D99>;%g6>4=n<<0;66g;b;29?l2a2900c<6=:188yg47m3:187>50z&2<c<c82B?;n5G4638 `3=92c?97>5;h6a>5<<a=l1<75`19094?=zj;:o6=4;:183!7?n3n;7E:8c:J734=#m<0:7d:::188m1d=831b8k4?::m2<7<722wi>=m50;694?6|,82m6i>4H55`?M2092.n97?4i5794?=n<k0;66g;f;29?j7?:3:17pl>b383>1<729q/=5h5d19K02e<@==:7)k::09j00<722c?n7>5;h6e>5<<g8296=44}c3a5?6=<3:1<v*>8g8g4>N3?j1C8:?4$d795>o3=3:17d:m:188m1`=831d=5<50;9~f4d7290?6=4?{%3;b?b73A><o6F;709'a0<63`>>6=44i5`94?=n<o0;66a>8383>>{e9hl1<7:50;2x 4>a2m:0D99l;I645>"b=3;0e9;50;9j0g<722c?j7>5;n3;6?6=3th:mh4?:583>5}#91l1h=5G46a8L1163-o>6<5f4483>>o3j3:17d:i:188k4>52900qo?nd;290?6=8r.:4k4k0:J73f=O<>;0(h;51:k71?6=3`>i6=44i5d94?=h9181<75rb0c`>5<3290;w)?7f;f3?M20k2B?;<5+e482?l222900e9l50;9j0c<722e:4?4?::a5dd=83>1<7>t$0:e>a6<@==h7E:81:&f1?7<a=?1<75f4c83>>o3n3:17b?72;29?xd6ih0;694?:1y'5=`=l91C8:m4H552?!c2281b884?::k7f?6=3`>m6=44o0:1>5<<uk8=<7>54;294~"60o0o<6F;7b9K027<,l?1=6g;5;29?l2e2900e9h50;9l5=4=831vn?;i:187>5<7s-;3j7j?;I64g>N3?81/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm24g94?2=83:p(<6i:e28L11d3A><=6*j5;38m13=831b8o4?::k7b?6=3f;3>7>5;|`11a<72=0;6=u+19d9`5=O<>i0D99>;%g6>4=n<<0;66g;b;29?l2a2900c<6=:188yg42k3:187>50z&2<c<c82B?;n5G4638 `3=92c?97>5;h6a>5<<a=l1<75`19094?=zj;?i6=4;:183!7?n3n;7E:8c:J734=#m<0:7d:::188m1d=831b8k4?::m2<7<722wi>8o50;694?6|,82m6i>4H55`?M2092.n97?4i5794?=n<k0;66g;f;29?j7?:3:17pl=5883>1<729q/=5h5d19K02e<@==:7)k::09j00<722c?n7>5;h6e>5<<g8296=44}c06<?6=<3:1<v*>8g8g4>N3?j1C8:?4$d795>o3=3:17d:m:188m1`=831d=5<50;9~f4`f290?6=4?{%3;b?b73A><o6F;709'a0<63`>>6=44i5`94?=n<o0;66a>8383>>{e9o31<7:50;2x 4>a2m:0D99l;I645>"b=3;0e9;50;9j0g<722c?j7>5;n3;6?6=3th:j54?:583>5}#91l1h=5G46a8L1163-o>6<5f4483>>o3j3:17d:i:188k4>52900qo?i7;290?6=8r.:4k4k0:J73f=O<>;0(h;51:k71?6=3`>i6=44i5d94?=h9181<75rb0d5>5<3290;w)?7f;f3?M20k2B?;<5+e482?l222900e9l50;9j0c<722e:4?4?::a5c3=83>1<7>t$0:e>a6<@==h7E:81:&f1?7<a=?1<75f4c83>>o3n3:17b?72;29?xd6n=0;694?:1y'5=`=l91C8:m4H552?!c2281b884?::k7f?6=3`>m6=44o0:1>5<<uk;m?7>54;294~"60o0o<6F;7b9K027<,l?1=6g;5;29?l2e2900e9h50;9l5=4=831vn<h=:187>5<7s-;3j7j?;I64g>N3?81/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25g94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25f94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25a94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25`94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25c94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25;94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25:94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25594?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25494?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm25794?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d:94?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d594?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d494?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d794?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d694?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d194?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d094?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d394?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1d294?2=83:p(<6i:e28L11d3A><=6F;2:&277<2>:1/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm1e494?2=83:p(<6i:e28L11d3A><=6*j5;38m13=831b8o4?::k7b?6=3f;3>7>5;|`2`0<72=0;6=u+19d9`5=O<>i0D99>;%g6>4=n<<0;66g;b;29?l2a2900c<6=:188yg7c<3:187>50z&2<c<c82B?;n5G4638 `3=92c?97>5;h6a>5<<a=l1<75`19094?=zj8n86=4;:183!7?n3n;7E:8c:J734=#m<0:7d:::188m1d=831b8k4?::m2<7<722wi=i<50;694?6|,82m6i>4H55`?M2092.n97?4i5794?=n<k0;66g;f;29?j7?:3:17pl>d083>1<729q/=5h5d19K02e<@==:7)k::09j00<722c?n7>5;h6e>5<<g8296=44}c3g4?6=<3:1<v*>8g8g4>N3?j1C8:?4$d795>o3=3:17d:m:188m1`=831d=5<50;9~f4ea290?6=4?{%3;b?b73A><o6F;709'a0<63`>>6=44i5`94?=n<o0;66a>8383>>{e9jo1<7:50;2x 4>a2m:0D99l;I645>"b=3;0e9;50;9j0g<722c?j7>5;n3;6?6=3th9?l4?:583>5}#91l1h=5G46a8L1163-o>6<5f4483>>o3j3:17d:i:188k4>52900qo<<9;290?6=8r.:4k4k0:J73f=O<>;0(h;51:k71?6=3`>i6=44i5d94?=h9181<75rb31;>5<3290;w)?7f;f3?M20k2B?;<5+e482?l222900e9l50;9j0c<722e:4?4?::a661=83>1<7>t$0:e>a6<@==h7E:81:&f1?7<a=?1<75f4c83>>o3n3:17b?72;29?xd5;?0;694?:1y'5=`=l91C8:m4H552?!c2281b884?::k7f?6=3`>m6=44o0:1>5<<uk8897>54;294~"60o0o<6F;7b9K027<,l?1=6g;5;29?l2e2900e9h50;9l5=4=831vn?=;:187>5<7s-;3j7j?;I64g>N3?81/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm22194?2=83:p(<6i:e28L11d3A><=6*j5;38m13=831b8o4?::k7b?6=3f;3>7>5;|`177<72=0;6=u+19d9`5=O<>i0D99>;%g6>4=n<<0;66g;b;29?l2a2900c<6=:188yg4493:187>50z&2<c<c82B?;n5G4638 `3=92c?97>5;h6a>5<<a=l1<75`19094?=zj;n<6=4::183!7?n3n:7E:8c:J734=#m<0:7d:::188m10=831b8o4?::k7b?6=3f;3>7>5;|`1`3<72<0;6=u+19d9`4=O<>i0D99>;%g6>4=n<<0;66g;6;29?l2e2900e9h50;9l5=4=831vn?j::186>5<7s-;3j7j>;I64g>N3?81/i84>;h66>5<<a=<1<75f4c83>>o3n3:17b?72;29?xd5l=0;684?:1y'5=`=l81C8:m4H552?!c2281b884?::k72?6=3`>i6=44i5d94?=h9181<75rb3f0>5<2290;w)?7f;f2?M20k2B?;<5+e482?l222900e9850;9j0g<722c?j7>5;n3;6?6=3th9h?4?:483>5}#91l1h<5G46a8L1163-o>6<5f4483>>o3>3:17d:m:188m1`=831d=5<50;9~f7b7290>6=4?{%3;b?b63A><o6F;709'a0<63`>>6=44i5494?=n<k0;66g;f;29?j7?:3:17pl=cg83>0<729q/=5h5d29K02e<@==:7)k::79j00<722c?:7>5;h6e>5<<a82:6=44o0:1>5<<uk8o=7>55;294~"60o0o=6F;7b9K027<,l?1=6g;5;29?l212900e9l50;9j0c<722e:4?4?::a6f2=8391<7>t$0:e>11e3A><o6F;709j0=<722c:>44?::m23g<722wi>n=50;194?6|,82m699m;I64g>N3?81b854?::k26<<722e:;o4?::a6gg=83>1<7>t$0:e>4543A><o6F;709j0=<722c>=7>5;h3;<?6=3f;<n7>5;|`1g7<72:0;6=u+19d902d<@==h7E:81:k7<?6=3`;957>5;n34f?6=3th9n54?:583>5}#91l1=>=4H55`?M2092c?47>5;h72>5<<a8236=44o05a>5<<uk8h=7>53;294~"60o0?;o5G46a8L1163`>36=44i00:>5<<g8=i6=44}c0a2?6=<3:1<v*>8g8276=O<>i0D99>;h6;>5<<a<;1<75f19:94?=h9>h1<75rb3a3>5<4290;w)?7f;64f>N3?j1C8:?4i5:94?=n9;31<75`16`94?=zj;h?6=4;:183!7?n3;8?6F;7b9K027<a=21<75f5083>>o6010;66a>7c83>>{e:kl1<7=50;2x 4>a2==i7E:8c:J734=n<10;66g>2883>>i6?k0;66sm2c094?2=83:p(<6i:010?M20k2B?;<5f4983>>o293:17d?78;29?j70j3:17pl=bd83>6<729q/=5h546`8L11d3A><=6g;8;29?l7513:17b?8b;29?xd5j90;694?:1y'5=`=9:90D99l;I645>o303:17d;>:188m4>?2900c<9m:188yg4el3:1?7>50z&2<c<3?k1C8:m4H552?l2?2900e<<6:188k41e2900qo<ne;290?6=8r.:4k4>329K02e<@==:7d:7:188m07=831b=5650;9l52d=831vn?ll:180>5<7s-;3j7:8b:J73f=O<>;0e9650;9j57?=831d=:l50;9~f7gd290?6=4?{%3;b?74;2B?;n5G4638m1>=831b9<4?::k2<=<722e:;o4?::a6`?=83?1<7>t$0:e>a7<@==h7E:81:&f1?7<a=?1<75f4783>>o3j3:17d:i:188k4>52900qo<j8;291?6=8r.:4k4k1:J73f=O<>;0(h;51:k71?6=3`>=6=44i5`94?=n<o0;66a>8383>>{e:l=1<7;50;2x 4>a2m;0D99l;I645>"b=3;0e9;50;9j03<722c?n7>5;h6e>5<<g8296=44}c0f2?6==3:1<v*>8g8g5>N3?j1C8:?4$d795>o3=3:17d:9:188m1d=831b8k4?::m2<7<722wi>h;50;794?6|,82m6i?4H55`?M2092.n97?4i5794?=n<?0;66g;b;29?l2a2900c<6=:188yg4b<3:197>50z&2<c<c92B?;n5G4638 `3=92c?97>5;h65>5<<a=h1<75f4g83>>i60;0;66sm2d194?3=83:p(<6i:e38L11d3A><=6*j5;38m13=831b8;4?::k7f?6=3`>m6=44o0:1>5<<uk8n>7>55;294~"60o0o=6F;7b9K027<,l?1=6g;5;29?l212900e9l50;9j0c<722e:4?4?::a6`7=83?1<7>t$0:e>a7<@==h7E:81:&f1?7<a=?1<75f4783>>o3j3:17d:i:188k4>52900qo<84;290?6=8r.:4k4k2:J73f=O<>;0(h;56:k71?6=3`>m6=44i0:2>5<<g8296=44}c041?6=<3:1<v*>8g8g6>N3?j1C8:?4$d792>o3=3:17d:i:188m4>62900c<6=:188yg41n3:187>50z&2<c<c82B?;n5G4638 `3=92c?97>5;h6a>5<<a=l1<75`19094?=zj;<n6=4;:183!7?n3n;7E:8c:J734=#m<0:7d:::188m1d=831b8k4?::m2<7<722wi?=>50;194?6|,82m699m;I64g>N3?81b854?::k26<<722e:;o4?::a75?=8391<7>t$0:e>11e3A><o6F;709j0=<722c:>44?::m23g<722wi>k:50;694?6|,82m6<=<;I64g>N3?81b854?::k65?6=3`;347>5;n34f?6=3th8<54?:283>5}#91l18:l4H55`?M2092c?47>5;h31=?6=3f;<n7>5;|`1b6<72=0;6=u+19d9565<@==h7E:81:k7<?6=3`?:6=44i0:;>5<<g8=i6=44}c133?6=;3:1<v*>8g873g=O<>i0D99>;h6;>5<<a8826=44o05a>5<<uk8m>7>54;294~"60o0:?>5G46a8L1163`>36=44i4394?=n9121<75`16`94?=zj::=6=4<:183!7?n3><n6F;7b9K027<a=21<75f13;94?=h9>h1<75rb3d2>5<3290;w)?7f;307>N3?j1C8:?4i5:94?=n=80;66g>8983>>i6?k0;66sm31794?5=83:p(<6i:55a?M20k2B?;<5f4983>>o6:00;66a>7c83>>{e:o:1<7:50;2x 4>a28987E:8c:J734=n<10;66g:1;29?l7?03:17b?8b;29?xd48=0;6>4?:1y'5=`=<>h0D99l;I645>o303:17d?=9;29?j70j3:17pl=eg83>1<729q/=5h51218L11d3A><=6g;8;29?l362900e<67:188k41e2900qo=?3;297?6=8r.:4k4;7c9K02e<@==:7d:7:188m44>2900c<9m:188yg4bm3:187>50z&2<c<6;:1C8:m4H552?l2?2900e8?50;9j5=>=831d=:l50;9~f66529086=4?{%3;b?20j2B?;n5G4638m1>=831b=?750;9l52d=831vn?kk:187>5<7s-;3j7?<3:J73f=O<>;0e9650;9j14<722c:454?::m23g<722wi?=?50;194?6|,82m699m;I64g>N3?81b854?::k26<<722e:;o4?::a6`e=83>1<7>t$0:e>4543A><o6F;709j0=<722c>=7>5;h3;<?6=3f;<n7>5;|`1ag<72=0;6=u+19d9565<@==h7E:81:k7<?6=3`?:6=44i0:;>5<<g8=i6=44}c121?6=<3:1<v*>8g8g4>N3?j1C8:?4$d795>o3=3:17d:m:188m1`=831d=5<50;9~f67c290?6=4?{%3;b?b73A><o6F;709'a0<63`>>6=44i5`94?=n<o0;66a>8383>>{e;8i1<7:50;2x 4>a2m:0D99l;I645>"b=3;0e9;50;9j0g<722c?j7>5;n3;6?6=3th8=o4?:583>5}#91l1h=5G46a8L1163-o>6<5f4483>>o3j3:17d:i:188k4>52900qo=>a;290?6=8r.:4k4k0:J73f=O<>;0(h;51:k71?6=3`>i6=44i5d94?=h9181<75rb23:>5<3290;w)?7f;f3?M20k2B?;<5+e482?l222900e9l50;9j0c<722e:4?4?::a74>=83>1<7>t$0:e>a6<@==h7E:81:&f1?7<a=?1<75f4c83>>o3n3:17b?72;29?xd49>0;694?:1y'5=`=l91C8:m4H552?!c2281b884?::k7f?6=3`>m6=44o0:1>5<<uk9::7>54;294~"60o0o<6F;7b9K027<,l?1=6g;5;29?l2e2900e9h50;9l5=4=831vn>?;:187>5<7s-;3j7j?;I64g>N3?81/i84>;h66>5<<a=h1<75f4g83>>i60;0;66sm33:94?3=83:p(<6i:e38L11d3A><=6*j5;38m13=831b8;4?::k7f?6=3`>m6=44o0:1>5<<uk82?7>54;294~"60o0:?>5G46a8L1163`>36=44i4394?=n9121<75`16`94?=zj;396=4;:183!7?n3;8?6F;7b9K027<a=21<75f5083>>o6010;66a>7c83>>{e:0;1<7:50;2x 4>a28987E:8c:J734=n<10;66g:1;29?l7?03:17b?8b;29?xd5190;694?:1y'5=`=9:90D99l;I645>o303:17d;>:188m4>?2900c<9m:188yg4?n3:187>50z&2<c<6;:1C8:m4H552?l2?2900e8?50;9j5=>=831d=:l50;9~f7>7290?6=4?{%3;b?74;2B?;n5G4638m1>=831b9<4?::k2<=<722e:;o4?::a62`=83>1<7>t$0:e>4543A><o6F;709j0=<722c>=7>5;h3;<?6=3f;<n7>5;|`13`<72=0;6=u+19d9565<@==h7E:81:k7<?6=3`?:6=44i0:;>5<<g8=i6=44}c04`?6=<3:1<v*>8g8276=O<>i0D99>;h6;>5<<a<;1<75f19:94?=h9>h1<75rb35`>5<3290;w)?7f;307>N3?j1C8:?4i5:94?=n=80;66g>8983>>i6?k0;66sm3c`94?3=83:p(<6i:e38L11d3A><=6*j5;38m13=831b8;4?::k7f?6=3`>m6=44o0:1>5<<uk9i57>55;294~"60o0o=6F;7b9K027<,l?1=6g;5;29?l212900e9l50;9j0c<722e:4?4?::a7gg=83?1<7>t$0:e>a5<@==h7E:81:&f1?0<a=?1<75f4783>>o3n3:17d?71;29?j7?:3:17pl<bb83>0<729q/=5h5d09K02e<@==:7)k::09j00<722c?:7>5;h6a>5<<a=l1<75`19094?=zj:ho6=4::183!7?n3n:7E:8c:J734=#m<0:7d:::188m10=831b8o4?::k7b?6=3f;3>7>5;|`0g5<72<0;6=u+19d9`4=O<>i0D99>;%g6>4=n<<0;66g;6;29?l2e2900e9h50;9l5=4=831vn>lj:186>5<7s-;3j7j>;I64g>N3?81/i84>;h66>5<<a=<1<75f4c83>>o3n3:17b?72;29?xd4jo0;684?:1y'5=`=l81C8:m4H552?!c2281b884?::k72?6=3`>i6=44i5d94?=h9181<75rb2a2>5<2290;w)?7f;f2?M20k2B?;<5+e482?l222900e9850;9j0g<722c?j7>5;n3;6?6=3th8o?4?:483>5}#91l1h<5G46a8L1163-o>6<5f4483>>o3>3:17d:m:188m1`=831d=5<50;9~f6ea290>6=4?{%3;b?b63A><o6F;709'a0<63`>>6=44i5494?=n<k0;66g;f;29?j7?:3:17pl<ce83>0<729q/=5h5d29K02e<@==:7)k::79j00<722c?:7>5;h6e>5<<a82:6=44o0:1>5<<uk9hi7>55;294~"60o0o=6F;7b9K027<,l?1=6g;5;29?l212900e9l50;9j0c<722e:4?4?::a7a6=83?1<7>t$0:e>a7<@==h7E:81:&f1?7<a=?1<75f4783>>o3j3:17d:i:188k4>52900qo=k1;291?6=8r.:4k4k1:J73f=O<>;0(h;51:k71?6=3`>=6=44i5`94?=n<o0;66a>8383>>{e;m>1<7;50;2x 4>a2m;0D99l;I645>"b=3;0e9;50;9j03<722c?n7>5;h6e>5<<g8296=44}c1g6?6==3:1<v*>8g8g5>N3?j1C8:?4$d795>o3=3:17d:9:188m1d=831b8k4?::m2<7<722wi?i=50;794?6|,82m6i?4H55`?M2092.n97?4i5794?=n<?0;66g;b;29?l2a2900c<6=:188yg5c=3:197>50z&2<c<c92B?;n5G4638 `3=92c?97>5;h65>5<<a=h1<75f4g83>>i60;0;66sm3e494?3=83:p(<6i:e38L11d3A><=6*j5;38m13=831b8;4?::k7f?6=3`>m6=44o0:1>5<<uk9jh7>55;294~"60o0o=6F;7b9K027<,l?1=6g;5;29?l212900e9l50;9j0c<722e:4?4?::a7de=83?1<7>t$0:e>a7<@==h7E:81:&f1?7<a=?1<75f4783>>o3j3:17d:i:188k4>52900qo=ne;291?6=8r.:4k4k1:J73f=O<>;0(h;51:k71?6=3`>=6=44i5`94?=n<o0;66a>8383>>{e;hk1<7;50;2x 4>a2m;0D99l;I645>"b=3;0e9;50;9j03<722c?n7>5;h6e>5<<g8296=44}c1b=?6==3:1<v*>8g8g5>N3?j1C8:?4$d795>o3=3:17d:9:188m1d=831b8k4?::m2<7<722wi?ll50;794?6|,82m6i?4H55`?M2092.n97?4i5794?=n<?0;66g;b;29?l2a2900c<6=:188yg5f?3:197>50z&2<c<c92B?;n5G4638 `3=92c?97>5;h65>5<<a=h1<75f4g83>>i60;0;66sm3`494?3=83:p(<6i:e18L11d3A><=6*j5;48m13=831b8;4?::k7b?6=3`;3=7>5;n3;6?6=3th8m54?:483>5}#91l1h<5G46a8L1163-o>6<5f4483>>o3>3:17d:m:188m1`=831d=5<50;9~f6g2290>6=4?{%3;b?b43A><o6F;709'a0<13`>>6=44i5494?=n<o0;66g>8083>>i60;0;66sm38;94?5=83:p(<6i:55a?M20k2B?;<5f4983>>o6:00;66a>7c83>>{e;021<7=50;2x 4>a2==i7E:8c:J734=n<10;66g>2883>>i6?k0;66sm39g94?2=83:p(<6i:010?M20k2B?;<5f4983>>o293:17d?78;29?j70j3:17pl<9683>6<729q/=5h546`8L11d3A><=6g;8;29?l7513:17b?8b;29?xd40j0;694?:1y'5=`=9:90D99l;I645>o303:17d;>:188m4>?2900c<9m:188yg5>>3:1?7>50z&2<c<3?k1C8:m4H552?l2?2900e<<6:188k41e2900qo=7a;290?6=8r.:4k4>329K02e<@==:7d:7:188m07=831b=5650;9l52d=831vn>7::180>5<7s-;3j7:8b:J73f=O<>;0e9650;9j57?=831d=:l50;9~f6>?290?6=4?{%3;b?74;2B?;n5G4638m1>=831b9<4?::k2<=<722e:;o4?::a7<2=8391<7>t$0:e>11e3A><o6F;709j0=<722c:>44?::m23g<722wi?5850;694?6|,82m6<=<;I64g>N3?81b854?::k65?6=3`;347>5;n34f?6=3th85>4?:283>5}#91l18:l4H55`?M2092c?47>5;h31=?6=3f;<n7>5;|`0<1<72=0;6=u+19d9565<@==h7E:81:k7<?6=3`?:6=44i0:;>5<<g8=i6=44}c1:6?6=;3:1<v*>8g873g=O<>i0D99>;h6;>5<<a8826=44o05a>5<<uk93>7>54;294~"60o0:?>5G46a8L1163`>36=44i4394?=n9121<75`16`94?=zj:3:6=4<:183!7?n3><n6F;7b9K027<a=21<75f13;94?=h9>h1<75rb2:3>5<3290;w)?7f;307>N3?j1C8:?4i5:94?=n=80;66g>8983>>i6?k0;66sm38294?5=83:p(<6i:55a?M20k2B?;<5f4983>>o6:00;66a>7c83>>{e;>o1<7:50;2x 4>a28987E:8c:J734=n<10;66g:1;29?l7?03:17b?8b;29?xd4mh0;684?:1y'5=`=l81C8:m4H552?!c2281b884?::k72?6=3`>i6=44i5d94?=h9181<75rb2g:>5<2290;w)?7f;f2?M20k2B?;<5+e482?l222900e9850;9j0g<722c?j7>5;n3;6?6=3th8i54?:483>5}#91l1h<5G46a8L1163-o>6<5f4483>>o3>3:17d:m:188m1`=831d=5<50;9~f6c0290>6=4?{%3;b?b63A><o6F;709'a0<63`>>6=44i5494?=n<k0;66g;f;29?j7?:3:17pl<e783>0<729q/=5h5d09K02e<@==:7)k::09j00<722c?:7>5;h6a>5<<a=l1<75`19094?=zj:o>6=4::183!7?n3n:7E:8c:J734=#m<0:7d:::188m10=831b8o4?::k7b?6=3f;3>7>5;|`0a1<72<0;6=u+19d9`4=O<>i0D99>;%g6>4=n<<0;66g;6;29?l2e2900e9h50;9l5=4=831vn>k<:186>5<7s-;3j7j>;I64g>N3?81/i84>;h66>5<<a=<1<75f4c83>>o3n3:17b?72;29?xd4m;0;684?:1y'5=`=l81C8:m4H552?!c2281b884?::k72?6=3`>i6=44i5d94?=h9181<75rb2g2>5<2290;w)?7f;f2?M20k2B?;<5+e482?l222900e9850;9j0g<722c?j7>5;n3;6?6=3th8??4?:583>5}#91l1=>=4H55`?M2092c?47>5;h72>5<<a8236=44o05a>5<<uk98?7>54;294~"60o0:?>5G46a8L1163`>36=44i4394?=n9121<75`16`94?=zj:9?6=4;:183!7?n3;8?6F;7b9K027<a=21<75f5083>>o6010;66a>7c83>>{e;:?1<7:50;2x 4>a28987E:8c:J734=n<10;66g:1;29?l7?03:17b?8b;29?xd4;?0;694?:1y'5=`=9:90D99l;I645>o303:17d;>:188m4>?2900c<9m:188yg53=3:187>50z&2<c<6;:1C8:m4H552?l2?2900e8?50;9j5=>=831d=:l50;9~f621290?6=4?{%3;b?74;2B?;n5G4638m1>=831b9<4?::k2<=<722e:;o4?::a711=83>1<7>t$0:e>4543A><o6F;709j0=<722c>=7>5;h3;<?6=3f;<n7>5;|`00=<72=0;6=u+19d9565<@==h7E:81:k7<?6=3`?:6=44i0:;>5<<g8=i6=44}c17=?6=<3:1<v*>8g8276=O<>i0D99>;h6;>5<<a<;1<75f19:94?=h9>h1<75rb27a>5<3290;w)?7f;307>N3?j1C8:?4i5:94?=n=80;66g>8983>>i6?k0;66sm34a94?2=83:p(<6i:010?M20k2B?;<5f4983>>o293:17d?78;29?j70j3:17pl<5e83>1<729q/=5h51218L11d3A><=6g;8;29?l362900e<67:188k41e2900qo=:e;290?6=8r.:4k4>329K02e<@==:7d:7:188m07=831b=5650;9l52d=831vn>;i:187>5<7s-;3j7?<3:J73f=O<>;0e9650;9j14<722c:454?::m23g<722wi?;k50;694?6|,82m6i>4H55`?M2092.n97?4i5794?=n<k0;66g;f;29?j7?:3:17pl<6g83>1<729q/=5h5d19K02e<@==:7)k::09j00<722c?n7>5;h6e>5<<g8296=44}c15e?6==3:1<v*>8g8g5>N3?j1C8:?4$d795>o3=3:17d:9:188m1d=831b8k4?::m2<7<722wi8?j50;794?6|,82m6i:4H55`?M2092.n97?4i5794?=n<?0;66g;f;29?l7?;3:17b?72;29?xd3:j0;684?:1y'5=`=l=1C8:m4H552?!c2281b884?::k72?6=3`>m6=44i0:0>5<<g8296=44}c61f?6==3:1<v*>8g8g0>N3?j1C8:?4$d795>o3=3:17d:9:188m1`=831b=5=50;9l5=4=831vn9<n:186>5<7s-;3j7j;;I64g>N3?81/i84>;h66>5<<a=<1<75f4g83>>o60:0;66a>8383>>{e<;31<7;50;2x 4>a2m>0D99l;I645>"b=3;0e9;50;9j03<722c?j7>5;h3;7?6=3f;3>7>5;|`76=<72<0;6=u+19d9`1=O<>i0D99>;%g6>4=n<<0;66g;6;29?l2a2900e<6<:188k4>52900qo:=6;291?6=8r.:4k4k4:J73f=O<>;0(h;51:k71?6=3`>=6=44i5d94?=n9191<75`19094?=zj=8>6=4::183!7?n3n?7E:8c:J734=#m<0:7d:::188m10=831b8k4?::k2<6<722e:4?4?::a072=83?1<7>t$0:e>a2<@==h7E:81:&f1?7<a=?1<75f4783>>o3n3:17d?73;29?j7?:3:17pl;2283>0<729q/=5h5d59K02e<@==:7)k::09j00<722c?:7>5;h6e>5<<a8286=44o0:1>5<<uk>9>7>55;294~"60o0o86F;7b9K027<,l?1=6g;5;29?l212900e9h50;9j5=5=831d=5<50;9~f146290>6=4?{%3;b?b33A><o6F;709'a0<63`>>6=44i5494?=n<o0;66g>8283>>i60;0;66sm43294?3=83:p(<6i:e68L11d3A><=6*j5;38m13=831b8;4?::k7b?6=3`;3?7>5;n3;6?6=3th?=k4?:483>5}#91l1h95G46a8L1163-o>6<5f4483>>o3>3:17d:i:188m4>42900c<6=:188yg26m3:197>50z&2<c<c<2B?;n5G4638 `3=92c?97>5;h65>5<<a=l1<75f19194?=h9181<75rb53g>5<2290;w)?7f;f7?M20k2B?;<5+e482?l222900e9850;9j0c<722c:4>4?::m2<7<722wi8<l50;794?6|,82m6i:4H55`?M2092.n97?4i5794?=n<?0;66g;f;29?l7?;3:17b?72;29?xd39h0;684?:1y'5=`=l=1C8:m4H552?!c2281b884?::k72?6=3`>m6=44i0:0>5<<g8296=44}c62=?6==3:1<v*>8g8g0>N3?j1C8:?4$d795>o3=3:17d:9:188m1`=831b=5=50;9l5=4=831vn9?7:186>5<7s-;3j7j;;I64g>N3?81/i84>;h66>5<<a=<1<75f4g83>>o60:0;66a>8383>>{e<8=1<7;50;2x 4>a2m>0D99l;I645>"b=3;0e9;50;9j03<722c?j7>5;h3;7?6=3f;3>7>5;|`753<72<0;6=u+19d9`1=O<>i0D99>;%g6>4=n<<0;66g;6;29?l2a2900e<6<:188k4>52900qo:>5;291?6=8r.:4k4k4:J73f=O<>;0(h;51:k71?6=3`>=6=44i5d94?=n9191<75`19094?=zj=;?6=4::183!7?n3n?7E:8c:J734=#m<0:7d:::188m10=831b8k4?::k2<6<722e:4?4?::a045=83?1<7>t$0:e>a2<@==h7E:81:&f1?7<a=?1<75f4783>>o3n3:17d?73;29?j7?:3:17pl;1383>0<729q/=5h5d59K02e<@==:7)k::09j00<722c?:7>5;h6e>5<<a8286=44o0:1>5<<uk>8?7>55;294~"60o0o86F;7b9K027<,l?1=6g;5;29?l212900e9h50;9j5=5=831d=5<50;9~f155290>6=4?{%3;b?b33A><o6F;709'a0<63`>>6=44i5494?=n<o0;66g>8283>>i60;0;66sm42394?3=83:p(<6i:e68L11d3A><=6*j5;38m13=831b8;4?::k7b?6=3`;3?7>5;n3;6?6=3th??=4?:483>5}#91l1h95G46a8L1163-o>6<5f4483>>o3>3:17d:i:188m4>42900c<6=:188yg25n3:197>50z&2<c<c<2B?;n5G4638 `3=92c?97>5;h65>5<<a=l1<75f19194?=h9181<75rb50f>5<2290;w)?7f;f7?M20k2B?;<5+e482?l222900e9850;9j0c<722c:4>4?::m2<7<722wi8?950;794?6|,82m6i:4H55`?M2092.n97?4i5794?=n<?0;66g;f;29?l7?;3:17b?72;29?xd39j0;684?:1y'5=`=l=1C8:m4H552?!c2281b884?::k72?6=3`>m6=44i0:0>5<<g8296=44}c625?6==3:1<v*>8g8g0>N3?j1C8:?4$d795>o3=3:17d:9:188m1`=831b=5=50;9l5=4=831vn9??:186>5<7s-;3j7j;;I64g>N3?81/i84>;h66>5<<a=<1<75f4g83>>o60:0;66a>8383>>{e<?h1<7=50;2x 4>a288n7E:8c:J734=#m<0:56gk9;29?lbf2900c<9m:188yg2183:1?7>50z&2<c<6:l1C8:m4H552?!c22830ei750;9j`d<722e:;o4?::a640=8391<7>t$0:e>44b3A><o6F;709'a0<6l2co57>5;hfb>5<<g8=i6=44}c3a0?6=;3:1<v*>8g826`=O<>i0D99>;%g6>4b<am31<75fd`83>>i6?k0;66sm1`294?5=83:p(<6i:00f?M20k2B?;<5+e482`>oc13:17djn:188k41e2900qo?6f;297?6=8r.:4k4>2d9K02e<@==:7)k::0f8ma?=831bhl4?::m23g<722wi=4k50;194?6|,82m6<<j;I64g>N3?81/i84>d:kg=?6=3`nj6=44o05a>5<<uk;2h7>53;294~"60o0:>h5G46a8L1163-o>6<j4ie;94?=nlh0;66a>7c83>>{e90i1<7=50;2x 4>a288n7E:8c:J734=#m<0:h6gk9;29?lbf2900c<9m:188yg7>j3:1?7>50z&2<c<6:l1C8:m4H552?!c228n0ei750;9j`d<722e:;o4?::a5<g=8391<7>t$0:e>44b3A><o6F;709'a0<6l2co57>5;hfb>5<<g8=i6=44}c3:=?6=;3:1<v*>8g826`=O<>i0D99>;%g6>4b<am31<75fd`83>>i6?k0;66sm18:94?5=83:p(<6i:00f?M20k2B?;<5+e482`>oc13:17djn:188k41e2900qo?67;297?6=8r.:4k4>2d9K02e<@==:7)k::0f8ma?=831bhl4?::m23g<722wi=4850;194?6|,82m6<<j;I64g>N3?81/i84>d:kg=?6=3`nj6=44o05a>5<<uk;297>53;294~"60o0:>h5G46a8L1163-o>6<j4ie;94?=nlh0;66a>7c83>>{e90>1<7=50;2x 4>a288n7E:8c:J734=#m<0:h6gk9;29?lbf2900c<9m:188yg7>;3:1?7>50z&2<c<6:l1C8:m4H552?!c228n0ei750;9j`d<722e:;o4?::a5<4=8391<7>t$0:e>44b3A><o6F;709'a0<6l2co57>5;hfb>5<<g8=i6=44}c3:5?6=;3:1<v*>8g826`=O<>i0D99>;%g6>4b<am31<75fd`83>>i6?k0;66sm18294?5=83:p(<6i:00f?M20k2B?;<5+e482`>oc13:17djn:188k41e2900qo<83;290?6=8r.:4k4>2g9K02e<@==:7)k::ba8ma?=831bhl4?::kgf?6=3f;<n7>5;|`15=<72=0;6=u+19d957`<@==h7E:81:&f1?433`n26=44iec94?=nlk0;66a>7c83>>{e9k<1<7:50;2x 4>a288m7E:8c:J734=#m<0986gk9;29?lbf2900eil50;9l52d=831vn?9>:186>5<7s-;3j7?<0:J73f=O<>;0(h;51`9j`<<722com7>5;hfa>5<<ami1<75`16`94?=zj;;j6=4::183!7?n3;8<6F;7b9K027<,l?1=k5fd883>>oci3:17djm:188mae=831d=:l50;9~f4d?290>6=4?{%3;b?7482B?;n5G4638 `3=9o1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb354>5<2290;w)?7f;304>N3?j1C8:?4$d7964=nl00;66gka;29?lbe2900eim50;9l52d=831vn?8m:187>5<7s-;3j7?=f:J73f=O<>;0(h;52c9j`<<722com7>5;hfa>5<<g8=i6=44}c02g?6=;3:1<v*>8g826`=O<>i0D99>;%g6>4b<am31<75fd`83>>i6?k0;66sm1cc94?5=83:p(<6i:00f?M20k2B?;<5+e482`>oc13:17djn:188k41e2900qo<>e;290?6=8r.:4k4>2g9K02e<@==:7)k::368ma?=831bhl4?::kgf?6=3f;<n7>5;|`2ff<72=0;6=u+19d957`<@==h7E:81:&f1?433`n26=44iec94?=nlk0;66a>7c83>>{e:;:1<7;50;2x 4>a289;7E:8c:J734=#m<0:j6gk9;29?lbf2900eil50;9j`f<722e:;o4?::a5gc=83?1<7>t$0:e>4573A><o6F;709'a0<6n2co57>5;hfb>5<<amh1<75fdb83>>i6?k0;66sm33c94?3=83:p(<6i:013?M20k2B?;<5+e4814>oc13:17djn:188mad=831bhn4?::m23g<722wi88o50;694?6|,82m6<<i;I64g>N3?81/i84:0:kg=?6=3`nj6=44ie`94?=h9>h1<75rb34b>5<2290;w)?7f;304>N3?j1C8:?4$d7957=nl00;66gka;29?lbe2900eim50;9l52d=831vn?7k:180>5<7s-;3j7?=e:J73f=O<>;0(h;5239j`<<722com7>5;n34f?6=3th94l4?:283>5}#91l1=?k4H55`?M2092.n97<=;hf:>5<<amk1<75`16`94?=zj:<26=4::183!7?n3;8<6F;7b9K027<,l?1>>5fd883>>oci3:17djm:188mae=831d=:l50;9~f634290>6=4?{%3;b?7482B?;n5G4638 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb263>5<2290;w)?7f;304>N3?j1C8:?4$d7966=nl00;66gka;29?lbe2900eim50;9l52d=831vn>87:186>5<7s-;3j7?<0:J73f=O<>;0(h;5229j`<<722com7>5;hfa>5<<ami1<75`16`94?=zj:?96=4::183!7?n3;8<6F;7b9K027<,l?1>>5fd883>>oci3:17djm:188mae=831d=:l50;9~f65a290>6=4?{%3;b?7482B?;n5G4638 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb3;`>5<2290;w)?7f;304>N3?j1C8:?4$d7966=nl00;66gka;29?lbe2900eim50;9l52d=831vn?66:186>5<7s-;3j7?<0:J73f=O<>;0(h;5229j`<<722com7>5;hfa>5<<ami1<75`16`94?=zj:<<6=4::183!7?n3;8<6F;7b9K027<,l?1>>5fd883>>oci3:17djm:188mae=831d=:l50;9~f636290>6=4?{%3;b?7482B?;n5G4638 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb21f>5<2290;w)?7f;304>N3?j1C8:?4$d7966=nl00;66gka;29?lbe2900eim50;9l52d=831vn?7m:186>5<7s-;3j7?<0:J73f=O<>;0(h;5229j`<<722com7>5;hfa>5<<ami1<75`16`94?=zj;236=4::183!7?n3;8<6F;7b9K027<,l?1>>5fd883>>oci3:17djm:188mae=831d=:l50;9~f601290>6=4?{%3;b?7482B?;n5G4638 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb273>5<2290;w)?7f;304>N3?j1C8:?4$d7966=nl00;66gka;29?lbe2900eim50;9l52d=831vn>=k:186>5<7s-;3j7?<0:J73f=O<>;0(h;5229j`<<722com7>5;hfa>5<<ami1<75`16`94?=zj;3j6=4::183!7?n3;8<6F;7b9K027<,l?1>>5fd883>>oci3:17djm:188mae=831d=:l50;9~f7>0290>6=4?{%3;b?7482B?;n5G4638 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9>h1<75rb252>5<3290;w)?7f;31b>N3?j1C8:?4$d79ga=nl00;66gka;29?lbe2900c<9m:188yg51k3:187>50z&2<c<6:o1C8:m4H552?!c22jn0ei750;9j`d<722con7>5;n34f?6=3th9m?4?:583>5}#91l1=?h4H55`?M2092.n97mk;hf:>5<<amk1<75fdc83>>i6?k0;66sm37794?2=83:p(<6i:00e?M20k2B?;<5+e486?lb>2900eio50;9j`g<722e:;o4?::a71`=83>1<7>t$0:e>44a3A><o6F;709'a0<23`n26=44iec94?=nlk0;66a>7c83>>{e;:i1<7:50;2x 4>a288m7E:8c:J734=#m<0>7dj6:188mag=831bho4?::m23g<722wi>4750;794?6|,82m6<=?;I64g>N3?81/i84=3:kg=?6=3`nj6=44ie`94?=nlj0;66a>7c83>>{e:1<1<7;50;2x 4>a289;7E:8c:J734=#m<09?6gk9;29?lbf2900eil50;9j`f<722e:;o4?::a675=8391<7>t$0:e>44b3A><o6F;709'a0<5:2co57>5;hfb>5<<g8=i6=44}c3`5?6=;3:1<v*>8g826`=O<>i0D99>;%g6>74<am31<75fd`83>>i6?k0;66sm23494?2=83:p(<6i:00e?M20k2B?;<5+e482a>oc13:17djn:188mad=831d=:l50;9~f4e3290?6=4?{%3;b?75n2B?;n5G4638 `3=9l1bh44?::kge?6=3`ni6=44o05a>5<<uk9<>7>53;294~"60o0:>h5G46a8L1163-o>6<?4ie;94?=nlh0;66a>7c83>>{e:kh1<7<50;2x 4>a288o7E:8c:J734=#m<0:=6gk9;29?j70j3:17pl=b883>7<729q/=5h513f8L11d3A><=6*j5;32?lb>2900c<9m:188yg4e?3:1>7>50z&2<c<6:m1C8:m4H552?!c228;0ei750;9l52d=831vn?l::181>5<7s-;3j7?=d:J73f=O<>;0(h;5109j`<<722e:;o4?::a6g5=8381<7>t$0:e>44c3A><o6F;709'a0<692co57>5;n34f?6=3th9n<4?:383>5}#91l1=?j4H55`?M2092.n97?>;hf:>5<<g8=i6=44}c0bb?6=:3:1<v*>8g826a=O<>i0D99>;%g6>47<am31<75`16`94?=zj;ko6=4=:183!7?n3;9h6F;7b9K027<,l?1=<5fd883>>i6?k0;66sm39d94?4=83:p(<6i:00g?M20k2B?;<5+e4825>oc13:17b?8b;29?xd40m0;6?4?:1y'5=`=9;n0D99l;I645>"b=3;:7dj6:188k41e2900qo=7b;296?6=8r.:4k4>2e9K02e<@==:7)k::038ma?=831d=:l50;9~f6>>29096=4?{%3;b?75l2B?;n5G4638 `3=981bh44?::m23g<722wi?5950;094?6|,82m6<<k;I64g>N3?81/i84>1:kg=?6=3f;<n7>5;|`0<0<72;0;6=u+19d957b<@==h7E:81:&f1?763`n26=44o05a>5<<uk93?7>52;294~"60o0:>i5G46a8L1163-o>6<?4ie;94?=h9>h1<75rb2:2>5<5290;w)?7f;31`>N3?j1C8:?4$d7954=nl00;66a>7c83>>{e;>l1<7<50;2x 4>a288o7E:8c:J734=#m<0:=6gk9;29?j70j3:17pl=c483>7<729q/=5h513f8L11d3A><=6*j5;32?lb>2900c<9m:188yg5>i3:1>7>50z&2<c<6:m1C8:m4H552?!c228;0ei750;9l52d=831vn?h7:180>5<7s-;3j7?=e:J73f=O<>;0(h;5239j`<<722com7>5;n34f?6=3th9j44?:283>5}#91l1=?k4H55`?M2092.n97<=;hf:>5<<amk1<75`16`94?=zj;lj6=4<:183!7?n3;9i6F;7b9K027<,l?1>?5fd883>>oci3:17b?8b;29?xd5nk0;6>4?:1y'5=`=9;o0D99l;I645>"b=3897dj6:188mag=831d=:l50;9~f7`d29086=4?{%3;b?75m2B?;n5G4638 `3=:;1bh44?::kge?6=3f;<n7>5;|`1ba<72:0;6=u+19d957c<@==h7E:81:&f1?453`n26=44iec94?=h9>h1<75rb3df>5<4290;w)?7f;31a>N3?j1C8:?4$d7967=nl00;66gka;29?j70j3:17pl=fg83>6<729q/=5h513g8L11d3A><=6*j5;01?lb>2900eio50;9l52d=831vn?h::180>5<7s-;3j7?=e:J73f=O<>;0(h;5239j`<<722com7>5;n34f?6=3th8>n4?:483>5}#91l1=>>4H55`?M2092.n97j:;hf:>5<<amk1<75fdc83>>ock3:17b?8b;29?xd4:k0;684?:1y'5=`=9::0D99l;I645>"b=38;7dj6:188mag=831bho4?::kgg?6=3f;<n7>5;|`036<72:0;6=u+19d957c<@==h7E:81:&f1?763`n26=44iec94?=h9>h1<75rb3d4>5<5290;w)?7f;31<>N3?j1C8:?4ie:94?=h9>h1<75rb24g>5<5290;w)?7f;31<>N3?j1C8:?4ie:94?=h9>h1<75rb301>5<1290;w)?7f;305>N3?j1C8:?4$d7960=nl00;66gka;29?lbe2900eim50;9l57g=831d=:l50;9~f4e7290=6=4?{%3;b?7492B?;n5G4638 `3=:<1bh44?::kge?6=3`ni6=44iea94?=h9;k1<75`16`94?=zj=?36=477;294~N3?81/=5h51968^12=ir21>;4j:07956<6j3l1=;4>4;3`>x"6:>087)jk:59'``<33-nm695+e187?!c62=1/i?4;;%g0>1=#kh0hi6*j6;68 `1=<2.n47:4$d;90>"bi3>0(hl54:&fg?2<,ln186*je;68 ``=<2.m<7:4$g390>"a:3>0(k=54:&e0?2<,o?186*i6;68 c1=<2.m47:4$g;90>"ai3>0(kl54:&eg?2<,on186*ie;68 c`=<2.:<=4;;%335?2<,8:9695+11190>"68=0?7)??5;68 4612=1/==954:&24=<33-;;57:4$02b>1=#99h186*>0b87?!77l3>0(<>j:59'55`=<2.:==4;;%325?2<,8;9695+10190>"69=0?7)?>5;68 4712=1/=<954:&25=<33-;:57:4$03b>1=#98h186*>1b87?!76l3>0(<?j:59'54`=<2.:>=4;;%315?2<,889695+13190>"6:=0?7)?=5;68 4412;1/=575409'a1<33-;3n7<4$555>4>23-><;7?75:l:`?6<fkl1<6`>87826>h60>0986`;79826>h3?00986*lb;af?!7?k390e9750;9j0d<722c?;94?::k`=?6=3`2<6=4+1929<d=i9>l1?65f19g94?=n;?0;6)?70;16?k70n3:07d=;:18'5=6=;<1e=:h51:9j76<72-;3<7=:;o34b?4<3`996=4+192970=i9>l1?65f3083>!7?839>7c?8f;68?l57290/=5>5349m52`==21b>k4?:%3;4?523g;<j784;h0f>5<#91:1?85a16d93>=n:m0;6)?70;16?k70n3207d<l:18'5=6=;<1e=:h59:9j05<72-;3<7=i;o34b?6<3`9n6=4+19297c=i9>l1=65f3e83>!7?839m7c?8f;08?l5d290/=5>53g9m52`=;21b?o4?:%3;4?5a3g;<j7:4;h1b>5<#91:1?k5a16d91>=n;00;6)?70;1e?k70n3<07d=7:18'5=6=;o1e=:h57:9j72<72-;3<7=i;o34b?><3`?26=4+19291==i9>l1<65f5683>!7?83?37c?8f;38?l31290/=5>5599m52`=:21b984?:%3;4?3?3g;<j7=4;h77>5<#91:1955a16d90>=n=:0;6)?70;7;?k70n3?07d8=:18'5=6==11e=:h56:9j24<72-;3<7;7;o34b?1<3`<;6=4+19291==i9>l1465f5g83>!7?83?37c?8f;;8?l3b290/=5>5599m52`=i21b9i4?:%3;4?3?3g;<j7l4;h7`>5<#91:1955a16d9g>=n=k0;6)?70;7;?k70n3n07d;n:18'5=6==11e=:h5e:9j17<72-;3<7;7;o34b?`<3`2=6=4+1929<0=i9>l1<65f8583>!7?832>7c?8f;38?jd0290/=5>5b79m52`=821dn84?:%3;4?d13g;<j7?4;n`0>5<#91:1n;5a16d96>=hj;0;6)?70;`5?k70n3907bl>:18'5=6=j?1e=:h54:9lf5<72-;3<7l9;o34b?3<3fkm6=4+1929f3=i9>l1:65`ad83>!7?83h=7c?8f;58?jgc290/=5>5b79m52`=021dmn4?:%3;4?d13g;<j774;nca>5<#91:1n;5a16d9e>=hih0;6)?70;`5?k70n3h07bo7:18'5=6=j?1e=:h5c:9le2<72-;3<7l9;o34b?b<3fk=6=4+1929f3=i9>l1i65`a483>!7?83h=7c?8f;d8?jg3290/=5>5b79m52`=9910cl=50;&2<5<e>2d:;k4>1:9le7<72-;3<7l9;o34b?7532ej=7>5$0:3>g0<f8=m6<=4;nc3>5<#91:1n;5a16d951=<g0l1<7*>818a2>h6?o0:965`bd83>!7?83h=7c?8f;35?>iel3:1(<6?:c48j41a28=07bll:18'5=6=j?1e=:h51998kgd=83.:4=4m6:l23c<6121dnl4?:%3;4?d13g;<j7?n;:ma=?6=,82;6o84n05e>4d<3fh36=4+1929f3=i9>l1=n54oc694?"6090i:6`>7g82`>=hi00;6)?70;`5?k70n3;n76a6e;29 4>72k<0b<9i:0d8?je0290/=5>5c79m52`=821do84?:%3;4?e13g;<j7?4;na7>5<#91:1o;5a16d96>=hk:0;6)?70;a5?k70n3907dm7:188m4>c2900e99::188m2e=83.:4=48b:l23c<732c<m7>5$0:3>2d<f8=m6<54i6:94?"6090<n6`>7g81?>o0?3:1(<6?:6`8j41a2:10e:850;&2<5<0j2d:;k4;;:k41?6=,82;6:l4n05e>0=<a>>1<7*>8184f>h6?o0=76g83;29 4>72>h0b<9i:698m24=83.:4=48b:l23c<?32c<=7>5$0:3>2d<f8=m6454i6294?"6090<n6`>7g8b?>o1n3:1(<6?:6`8j41a2k10e;j50;&2<5<0j2d:;k4l;:k5g?6=,82;6:l4n05e>a=<a?h1<7*>8184f>h6?o0n76g9a;29 4>72>h0b<9i:g98m3?=83.:4=48b:l23c<6821b:54?:%3;4?1e3g;<j7?>;:k53?6=,82;6:l4n05e>44<3`<=6=4+19293g=i9>l1=>54i7794?"6090<n6`>7g820>=n>=0;6)?70;5a?k70n3;>76g73;29 4>72>h0b<9i:048?l>5290/=5>57c9m52`=9>10e5?50;&2<5<0j2d:;k4>8:9j<5<72-;3<79m;o34b?7>32c<j7>5$0:3>2d<f8=m6<o4;h5f>5<#91:1;o5a16d95g=<a>n1<7*>8184f>h6?o0:o65f7883>!7?83=i7c?8f;3g?>o1m3:1(<6?:6`8j41a28o07d8<:18'5=6=?k1e=:h51g98m=d=83.:4=47a:l23c<732c357>5$0:3>=g<f8=m6<54i9:94?"60903m6`>7g81?>i>;3:1(<6?:808j41a2910c4?50;&2<5<>:2d:;k4>;:m:4?6=,82;64<4n05e>7=<g1l1<7*>818:6>h6?o0876a7e;29 4>72080b<9i:598k=b=83.:4=462:l23c<232e2o7>5$0:3><4<f8=m6;54o8`94?"60902>6`>7g84?>i>i3:1(<6?:808j41a2110c4750;&2<5<>:2d:;k46;:m:<?6=,82;64<4n05e>d=<g0=1<7*>818:6>h6?o0i76a66;29 4>72080b<9i:b98k<3=83.:4=462:l23c<c32e287>5$0:3><4<f8=m6h54o9a94?"60902>6`>7g8e?>id:3:1(<6?:b38j41a2910cn>50;&2<5<d92d:;k4>;:p10b=83<pR8;k;<047?bf348<=7j6;<043?bd348=n7jm;<05e?b>3ty>9o4?:6gxZ1?33W?=:6P:659]0=2<V<<;7S;?f:\620=Y=8:0R97=;_6:5>X3191U85h4^5:f?[2?l2T?4n5Q49`8Z1>f3W>356P:709]126<V<<m7S;9e:\62a=Y=?i0R88m;_75e>X2>01U9;64^47b?[3212T>955Q5458Z0313W?>96P:559]105<V<?970:8d;f5?821?3>m70::c;6e?821>3>m70:95;6e?821<3>m70:9f;6e?821m3>m70<ma;72?84e03?:70<m6;72?84e<3?:70<m2;72?84e83?:70<ne;72?84fk3?:70<jb;3;<>;51:0>=63=93865>;5180>=63=91865>;50o0>=63=81865>;5?o0>=63=7d865>;5?m0>=63=7b865>;40l0>=63<8b865>;40h0>=63<89865>;40?0>=63<85865>;40;0>=63<81865>;4?l0>=63<33865>;4;:0>=63<35865>;4;<0>=63<37865>;4<<0>=63<47865>;4<>0>=63<49865>;4<00>=63<5c865>;4=j0>=63<5e865>;4=l0>=63<5g865>;3=103;63;5982<a=:<<218:;4=57;>2e<5=?36:o4=57;>2><5=?36:94=57;>20<5=?36:;4=57;>22<5=?36:=4=57;>24<5=?36:?4=57;>26<5=?36;h4=57;>3b<5=?36;m4=57;>3d<5=?36;o4=57;>3?<5=?36;64=57;>31<5=?36;84=57;>33<5=?36;:4=57;>=5<5=?365<4=57;>=7<5=?365>4=57;>2`<5=?36:k4=57;>2b<5=?36:74=57;>3c<5=?36;=4=57;>=d<5=?36574=57;>=><uz9=m7>52z\7<0=:;?k1=5<4}r76b?6=;rT>9k5247595=7<5=?h6<6>;|q130<72;qU9=:4=356>4>53ty>;>4?:2y]125<5:=96i74=250>a?<uz?>=7>569y]107<5;k;69;4=57f>13<5=?o69;4=57`>13<5=<=69;4=546>13<5=<?69;4=337>13<5;;869;4=331>13<5;;:69;4=333>13<5;:m69;4=32f>13<5;:o69;4=32`>13<5;<;69;4=37e>13<5;?n69;4=37g>13<5;?h69;4=37a>13<5;?j69;4=37:>13<5;?369;4=36f>13<5;>o69;4=36`>13<5;>i69;4=36b>13<5;>269;4=36;>13<5;><69;4=365>13<5;>>69;4=0f5>13<58n>69;4=0f7>13<58n869;4=0f1>13<58n:69;4=0f3>13<58im69;4=0af>13<5;n<69;4=3f5>13<5;n>69;4=3f7>13<5;n869;4=3f1>13<5;n;69;4=3ae>13<5;n:69;4=3g:>13<5;o369;4=3g4>13<5;o=69;4=3g6>13<5;o?69;4=3g0>13<5;o969;4=3g2>13<5;=?69;4=356>13<5;<m69;4=34f>13<5=8o69;4=50`>13<5=8i69;4=50b>13<5=8269;4=50;>13<5=8=69;4=506>13<5=8?69;4=500>13<5=8969;4=502>13<5=8;69;4=53e>13<5=;n69;4=53g>13<5=;i69;4=53b>13<5=;269;4=53;>13<5=;<69;4=535>13<5=;>69;4=537>13<5=;869;4=531>13<5=9869;4=511>13<5=9:69;4=513>13<5=8m69;4=50f>13<5=8<69;4=53`>13<5=;:69;4=533>13<5=?369o4}r15b?6=:rT><l5237d95=4<uz?=;7>563y]131<5=<269;4=544>13<5=<369;4=54e>13<5=<n69;4=0`1>13<58h:69;4=0`3>13<58km69;4=0cf>13<58ko69;4=0c`>13<58ki69;4=0cb>13<58lj69;4=0d:>13<58l369;4=0d4>13<58l=69;4=0d6>13<58l?69;4=0d0>13<58l969;4=0g;>13<58o<69;4=0g5>13<58o>69;4=0g7>13<58o869;4=0g1>13<58o:69;4=0g3>13<5;9j69;4=31:>13<5;9369;4=314>13<5;9=69;4=316>13<5;9?69;4=310>13<5;9969;4=312>13<5:;>69;4=23g>13<5:;h69;4=23a>13<5:;j69;4=23:>13<5:;369;4=234>13<5:;=69;4=237>13<5:8369;4=2`a>13<5:h269;4=2`b>13<5:hh69;4=2`g>13<5:i;69;4=2`f>13<5:hm69;4=2a2>13<5:i969;4=2ae>13<5:io69;4=2af>13<5:n;69;4=2f2>13<5:n?69;4=2f1>13<5:n869;4=2f6>13<5:n=69;4=2cg>13<5:kh69;4=2cf>13<5:kj69;4=2c:>13<5:ki69;4=2c4>13<5:k=69;4=2c;>13<5:k>69;4=2gb>13<5:o269;4=2g;>13<5:o<69;4=2g5>13<5:o>69;4=2g7>13<5:o869;4=2g1>13<5:o:69;4=24f>13<5:<m69;4=24b>13<5=?36974}r11<?6=:rT>>k5233:95=4<uz9m87>52z\7`2=:<831=5<4}r1e7?6=:rT?h;5240:95=4<uz9m>7>52z\7`0=:<8=1=5<4}r1e5?6=:rT?h95240495=4<uz9m<7>52z\7`6=:<8?1=5<4}r1fb?6=:rT?h?5240695=4<uz9ni7>52z\7`5=:<891=5<4}r1f`?6=:rT?ok5240095=4<uz>;j7>52z\7g`=:<:91=5<4}r63a?6=:rT?oi5242095=4<uz>;h7>52z\7gf=:<:;1=5<4}r63g?6=:rT?oo5242295=4<uz>;n7>52z\7gd=:<;l1=5<4}r63e?6=:rT?o45243g95=4<uz>;57>52z\7g==:<;=1=5<4}r636?6=:rT?o:5240a95=4<uz9m;7>52z\7g0=:<8;1=5<4}r1fg?6=:rT?o95240295=4<uz>;47>52z\7g6=:<;n1=5<4}r633?6=:rT?o?5243a95=4<uz>;:7>52z\7g4=:<;h1=5<4}r631?6=:rT?o=5243c95=4<uz>;87>52z\7fc=:<;31=5<4}r637?6=:rT?nh5243:95=4<uz>;=7>52z\7fa=:<;<1=5<4}r634?6=:rT?nn5243795=4<uz9mj7>52z\7`a=:<;>1=5<4}r1ea?6=:rT?hn5243195=4<uz9mh7>52z\7`g=:<;81=5<4}r1eg?6=:rT?hl5243395=4<uz9mn7>52z\7`<=:<;:1=5<4}r1ee?6=:rT?h55240d95=4<uz9m57>52z\7`4=:<8o1=5<4}r1e<?6=:rT?o;5240f95=4<uz9m:7>52z\7fg=:<8h1=5<4}r1e1?6=:rT?nl5240c95=4<uz>i<7>52z\7=`=:<<214;5rs5cf>5<5sW>2h63;5986=>{t<hn1<7<t^5;`?82203?<7p};ab83>7}Y<0h019;7:448yv2fj3:1>vP;9`9>00>==<1v9on:181[2>127?954:4:p0d?=838pR977;<66<?343ty?m54?:3y]0<1<5=?36;<4}r6a=?6=:rT?m;5244:924=z{=h36=4={_6b1>;3=10386s|4c594?4|V=k?70::8;43?xu3j?0;6?uQ4`18913?2<l0q~:m5;296~X3i;1688655d9~w1d32909wS:n1:?71=<2l2wx8o=50;0xZ1g734>>47;l;|q7f7<72;qU84h4=57;>0d<uz>i=7>52z\7=3=:<<219l5rs5c4>5<5sW>2963;59866>{t9:=1<7mt=55f>41c348io7:7;<0bg?2?348no7;>;<0ff?2?3483j7:7;<04g?2?3492<7:7;<14a?2?3498>7:7;<171?2?349>n7:7;|q1e4<72;q6>l>54g9>6d4=9>h0q~:93;295=}::h:1=5?4=545>4>5348o;7:m;<0g2?2e348o97:m;<0g0?2e348o?7:m;<0g6?2e348o<7:m;<0`b?7?9279h<4;b:?1a<<3j279i54;b:?1a2<3j279i;4;b:?1a0<3j279i94;b:?1a6<3j279i?4;b:?1a4<3j279;94>809>623=91;01?8i:5`8970b2=h0q~<n0;290~;5i90:4?522639`f=:<<k1h45227c9`d=z{=?o6=4<{<66a?2a34>>h7?72:?71f<3>2wx88k50;0x913b282970:90;f:?xu3>10;6>u247;90c=:<?=18;5247:95=4<uz>=57>52z?72<<60;168;l5d89~w13d2908w0::d;6e?822k3;3>63;618ge>{t<?=1<7=t=544>4>534>=47:i;<65f?bf3ty?9k4?:5y>030=91;0198::0:2?821<3;3=63;61823g=z{=<96=4=6z?720<60;16><:54c9>645=<k16><<54c9>647=<k16><>54c9>65`=<k16>=k54c9>65b=<k16>=m54c9>636=<k16>8h54c9>60c=<k16>8j54c9>60e=<k16>8l54c9>60g=<k16>8754c9>60>=<k16>9k54c9>61b=<k16>9m54c9>61d=<k16>9o54c9>61?=<k16>9654c9>611=<k16>9854c9>613=<k16=i854c9>5a3=<k16=i:54c9>5a5=<k16=i<54c9>5a7=<k16=i>54c9>5f`=<k16=nk54c9~w1062909;v3;6582<7=:<;n1=5=4=50`>4>434>9n7?73:?76d<60:168?751918914?282870:=6;3;7>;3:<0:4>5243695=5<5=886<6<;<616?7?;27?><4>829>076=919019?i:0:0?826m3;3?63;1e82<6=:<8h1=5=4=53b>4>434>:57?73:?75=<60:168<9519189171282870:>5;3;7>;39=0:4>5240195=5<5=;96<6<;<607?7?;27???4>829>067=919019=?:0:0?825n3;3?63;2d82<6=:<;=1=5=4=53`>4>434>:=7?73:?755<60:1688o5d`9>00>=91o0q~:9a;297~;3>o0:4<5247g95=7<5=<i6<9m;|q72a<72:9p198i:0:1?856=3>i70=>d;6a?856k3>i70=>b;6a?856i3>i70=>9;6a?85603>i70=>7;6a?856>3>i70=>4;6a?85ej3>i70=m9;6a?85ei3;3=63<bb87f>;4jm0?n63<c187f>;4jl0?n63<bg87f>;4k80?n63<c387f>;4ko0?n63<ce82<4=:;jo18o523e290g=:;m;18o523e690g=:;m818o523e190g=:;m?18o523e490g=:;hn18o523`a90g=:;ho18o523`c90g=:;h318o523``90g=:;h=18o523`495=7<5:k369l4=2c6>4>6349nm7:m;<1f=?2e349n47:m;<1f3?2e349n:7:m;<1f1?2e349n87:m;<1f7?2e349n>7:m;<1f5?2e3ty?:n4?:3cx910b282970?m2;6a?87e93>i70?m0;6a?87fn3>i70?ne;6a?87fl3>i70?nc;6a?87fj3>i70?na;6a?87ai3>i70?i9;6a?87a03>i70?i7;6a?87a>3>i70?i5;6a?87a<3>i70?i3;6a?87a:3>i70?j8;6a?87b?3>i70?j6;6a?87b=3>i70?j4;6a?87b;3>i70?j2;6a?87b93>i70?j0;6a?844i3>i70<<9;6a?84403>i70<<7;6a?844>3>i70<<5;6a?844<3>i70<<3;6a?844:3>i70<<1;6a?85503>i70=9e;6a?851n3>i70=9a;6a?xu5=>0;68u220690c=::?:1=5<4=335>ag<5;;36i74=33b>ae<uz8;n7>53z?151<60;16>4j5d89>6=g=l01v??::181846;3>m70<>6;34f>{t:9k1<7=t=330>4>53482o7jn;<0;=?bf3ty9=:4?:3y>644=<o16><6516`8yv4713:1?v3=1382<7=::0i1hn5229;9`f=z{;;26=49{<025?2a348:m7?8b:?15f<ci279=h4k9:?165<cj279>?4kc:p65>=839p1??>:0:1?84>j3nj70<78;fb?xu59k0;6?u220290c=::8i1=:l4}r033?6=;r79==4>839>6<d=lj16>565db9~w77c2909w0<?f;6e?846m3;<n6s|21494?5|5;:m6<6=;<0:e?bf3483;7jn;|q15c<72;q6>=k54g9>676=9>h0q~<?5;297~;58l0:4?5228c9`f=::1=1hn5rs302>5<5s48;h7:i;<017?70j2wx>=:50;1x976c282970<69;fb?84?>3nj7p}=2483>7}::9i18k52234952d<uz8;?7>53z?14f<60;16>475db9>6=0=lj1v<h>:18687e:3>m70?ia;3;6>;6j=0om63>b78g=>;6j10oo6s|1`;94?3|58h96<6=;<15=?b>349>?7j6;<174?b>348m97jn;|q2f6<72;q6=o?54g9>5g2=9>h0q~?n8;291~;6j80:4?5237;9`g=:;<91ho523529`g=::ol1hl5rs0`6>5<5s4;i<7:i;<3a2?70j2wx=l950;7x94d7282970=98;f:?852:3n270=<f;f:?84am3nj7p}>b683>3}:9hl18k521c:952d<58hj6io4=0``>a?<58hn6il4=0a3>ae<uz;j:7>55z?2ec<60;16?;65dc9>704=lk16?>h5dc9>6cb=lh1v<l6:18187fm3>m70?ma;34f>{t9h?1<7;t=0cf>4>5349=;7j6;<165?b>3498i7j6;<0eg?bf3ty:no4?:3y>5db=<o16=om516`8yv7f<3:19v3>ae82<7=:;?=1ho523439`g=:;:o1ho522g`9`d=z{8ho6=4={<3bg?2a34;ii7?8b:p5d5=83?p1<ol:0:1?851>3n270=:0;f:?854l3n270<ia;fb?xu6jo0;6?u21``90c=:9j;1=:l4}r3b6?6==r7:mo4>839>730=lk16?8>5dc9>76b=lk16>k75d`9~w4e42909w0?na;6e?87d<3;<n6s|1`394?3|58kj6<6=;<151?b>349?j7j6;<10g?b>348m47jn;|q101<72;q6>;>54g9>61c=9180q~<;3;296~;5=o0?j63=4e82<7=z{;?=6=4;{<06b?7?:279=;4k9:?15=<ci279=l4kb:p614=838p1?;j:5d8972d28297p}=5483>6}::<o1=5<4=33;>ad<5;;j6io4}r075?6=:r799i4;f:?10g<60;1v?;;:181842l3;3>63=1`8g=>{t:=:1<7<t=37`>1`<5;>j6<6=;|q116<72<q6>8m51908977d2m301??j:ec897472mi01?<=:e`8yv44n3:1>v3=5c87b>;5<00:4?5rs371>5<3s48>n7?72:?15`<cj279>=4k9:?167<ci2wx>>k50;0x973f2=l01?:7:0:1?xu5=80;6>u224c95=4<5;8;6io4=301>a?<uz88h7>52z?11<<3n2798:4>839~w7372908w0<:9;3;6>;5::0o563=278ge>{t::i1<7<t=37;>1`<5;>=6<6=;|q10c<72;q6>865190897412m30q~?kf;296~;6nh0?j63>e982<7=z{8nn6=4={<3e=?2a34;n;7?72:p5c6=83>p1<h6:0:1?87e<3n270?m6;fb?87e03ni7p}>de83>7}:9o218k521d495=4<uz;nj7>53z?2b=<60;16=o85dc9>5g>=lh1v<jl:18187a?3>m70?j5;3;6>{t9lo1<7<t=0d4>4>534;i47j6;|q2`g<72;q6=k854g9>5`2=9180q~?jd;291~;6n?0:4?521cc9`<=:9ki1hl521cg9`f=:9j:1ho5rs0fb>5<5s4;m97:i;<3f7?7?:2wx=hm50;6x94`2282970?mc;fa?87em3n270?l0;fb?xu6l00;6?u21g690c=:9l81=5<4}r3ff?6=;r7:j94>839>5gc=lh16=n>5d89~w4b?2909w0?i3;6e?87b93;3>6s|1dc94?5|58l86<6=;<3`5?b>34;h87jn;|q2`2<72;q6=k<54g9>5`6=9180q~?j9;296~;6n;0:4?521b69`<=z{;9;6=4={<07a?2a3488m7?72:p67`=838p1?:k:5d8975>28297p}=2d83>7}::=i18k5222:95=4<uz89h7>52z?10g<3n279?:4>839~w74d2909w0<;a;6e?844>3;3>6s|23`94?4|5;>269h4=316>4>53ty9>l4?:3y>61>=<o16>>:51908yv4513:1>v3=4687b>;5;:0:4?5rs30;>5<5s48?:7:i;<006?7?:2wx>?950;0x97222=l01?=>:0:1?xu5;k0;6<u225795=4<uz;hh7>52z?2a=<3n27:h;4>839~w4ed2909w0?j7;6e?87c=3;3>6s|1b`94?4|58o=69h4=0f7>4>53ty:ol4?:3y>5`3=<o16=i=51908yv7d13:1>v3>e587b>;6l;0:4?5rs0a;>5<5s4;n?7:i;<3g5?7?:2wx=n950;0x94c52=l01<j?:0:1?xu6k?0;6?u21d390c=:9jl1=5<4}r3`1?6=:r7:i=4;f:?2g`<60;1v?k?:18687c>3>m70<j9;3;6>;6190o563=8`8ge>;3=10?<6s|1g`94?4|58n>69h4=0;3>41e3ty:jn4?:3y>5a2=<o16=4?516`8yv7al3:1>v3>d287b>;61;0:;o5rs0df>5<5s4;o>7:i;<3:7?70j2wx=kh50;0x94b62=l01<7;:05a?xu5890;6?u21e290c=:90?1=:l4}r035?6=:r7:ok4;f:?2=3<6?k1v?>=:18187dm3>m70?67;34f>{t;l:1<7:t=31b>1`<5:oj6<6=;<3:<?b>34>>47=9;|q124<72;q6>>754g9>5<>=9>h0q~<92;296~;5;10?j63>98823g=z{;<86=4={<003?2a34;2m7?8b:p632=838p1?=9:5d894?e28=i7p}=6483>7}:::?18k5218a952d<uz8=:7>52z?171<3n27:5i4>7c9~w7002909w0<<3;6e?87>m3;<n6s|27:94?4|5;9969h4=0;e>41e3ty9:44?:3y>667=<o16=l>516`8yv4bi3:1=8u22e5903=::m<18;522e7903=::m>18;522e1903=::m818;522e2903=::jl18;522e3903=::l318;522d:903=::l=18;522d4903=::l?18;522d6903=::l918;522d0903=::l;18;5244c9`g=::?k1=:l4=3c1>ag<uz8jn7>52z?1`2<3n279o94>7c9~w7eb290?w0<k7;3;6>;5m00?j63=9e8ge>;5k<0o56s|2`c94?4|5;n=69h4=3a0>41e3ty9oi4?:5y>6a0=91801?k7:5d897?d2m301?lm:e;8yv4f13:1>v3=d487b>;5k;0:;o5rs3a`>5<3s48o97?72:?1a2<3n2795n4kb:?1f<<c12wx>l650;0x97b32=l01?m>:05a?xu5kk0;69u22e695=4<5;o=69h4=3;a>a?<5;h<6i74}r0b3?6=:r79h>4;f:?1g5<6?k1v?mn:18784c;3;3>63=e487b>;51k0on63=b48g=>{t:h<1<7<t=3f1>1`<5;hm6<9m;|q1g<<72=q6>i<5190897c32=l01?7n:e;897d42m30q~<n4;296~;5l90?j63=be823g=z{;i<6=4;{<0g4?7?:279i?4;f:?1=<<c1279mk4k9:p6d5=838p1?mi:5d897dd28=i7p}=c783>1}::jl1=5<4=3g2>1`<5;326il4=3cg>a?<uz8j97>52z?1`4<3n279nh4>7c9~w7e?290?w0<k1;3;6>;5m:0?j63=9`8gf>;5j80o56s|2cc94?4|5;i?6964=3`b>41e3ty9o84?:3y>6f2=9;301?m::05a?xu5j10;6>u22b190==::kk185522c:952d<uz8in7>53z?1g6<6:016>oo519:897de28=i7p}=b783>6}::j8185522c:90==::k<1=:l4}r0a=?6=;r79o?4>289>6g>=91201?l6:05a?xu5j=0;6>u22b390==::k<185522c6952d<uz8i;7>53z?1g4<6:016>o8519:897d028=i7p}=b383>6}::j:185522c690==::k81=:l4}r0a1?6=;r79o=4>289>6g2=91201?l::05a?xu5j90;6>u22cd90==::k8185522c2952d<uz8i?7>53z?1fc<6:016>o<519:897d428=i7p}=ad83>6}::ko185522c290==::ho1=:l4}r0a5?6=;r79nh4>289>6g6=91201?l>:05a?xu5ij0;6>u22cf90==::ho185522`a952d<uz8jj7>53z?1fa<6:016>lk519:897ga28=i7p}=ae83>6}::ki1=?74=3c`>4>?348jh7?8b:p6a`=83?p1?k7:0:1?87>93n270?60;fb?84?13n270::8;1f?xu5ll0;68u22d595=4<58396i74=0;2>ag<5;226il4=57;>6b<uz8oh7>55z?1a3<60;16=4=5d89>5<4=lh16>565d89>00>=;j1v?jl:18684b=3;3>63>958g=>;61:0om63=898gf>;3=108n6s|2e`94?3|5;o?6<6=;<3:1?b>34;287jn;<0;3?b>34>>47=n;|q1`d<72<q6>h=5190894?12m301<7::ec897>02mh019;7:2;8yv4c13:19v3=e382<7=:90=1h4521849`d=::1<1h45244:97==z{;n36=4;{<0f5?7?:27:5:4ka:?1<3<cj27?954<7:p620=839p1?9;:5d897122=l01?98:05a?xu5?=0;6?u226695=4<5;=<6i74}r044?6=:r79:k4;f:?134<6?k1v?8k:185841n3;3>63=728gf>;5?80on63=768gf>;5>k0o563=6`8gg>{t:>81<7<t=34f>1`<5;=86<9m;|q12f<72?q6>;k5190897142m301?9>:ec897102mk01?8m:ec8970f2mh0q~<i4;296~;4890?463=f5823g=z{;l>6=4={<134?751279j84>7c9~w67b2909w0=?0;34f>;49<0?j6s|2g194?5|5::26964=3d7>1><5;l86<9m;|q1bc<72:q6?=7513;897`3282370<if;34f>{t;;=1<7<t=22:>41e349:h7:i;|q0gg<72<q6>k:5509>7a3=91801>k6:5d896272mi01?hi:e;8yv4a:3:1?v3<0987<>;5n:0?463=f3823g=z{;ln6=4<{<13<?751279j>4>899>6cc=9>h0q~==6;296~;4810:;o5230a90c=z{:ij6=4:{<0e7?36349o87?72:?0a=<3n278?k4ka:?1b`<c12wx>k?50;1x96602=201?h=:5:897`628=i7p}=fe83>6}:;9=1=?74=3d1>4>?348mh7?8b:p773=838p1>>8:05a?856j3>m7p}<c883>0}::o819<523e195=4<5:o<69h4=21e>ae<5;lo6i74}r0e4?6=;r78<;4;8:?1b4<30279j=4>7c9~w7`d2908w0=?6;31=>;5n80:45522ga952d<uz9987>52z?043<6?k16?<o54g9~w6e?290>w0<i1;72?85c:3;3>63<e787b>;4;l0om63=fb8g=>{t:ll1<7=t=226>1><5;l;6964=3ge>41e3ty9jo4?:2y>753=9;301?h?:0:;?84aj3;<n6s|33194?4|5::>6<9m;<12=?2a3ty8o:4?:4y>6c6==816?i?5190896c22=l01>=j:ea897`e2m30q~<je;297~;48=0?463=eg87<>;5ml0:;o5rs3db>5<4s49;87?=9:?1ac<60116>ko516`8yv55:3:1>v3<05823g=:;8218k5rs2a5>5<2s48nj7;>;<1g4?7?:278i94;f:?07a<ci279jl4k9:p6`b=839p1>><:5:897cb2=201?kk:05a?xu5n00;6>u2311957?<5;on6<67;<0e=?70j2wx???50;0x966428=i70=>7;6e?xu4k<0;68u22dg914=:;jl1=5<4=2g0>1`<5:9o6im4=3d:>a?<uz8no7>53z?047<30279ii4;8:?1af<6?k1v?h7:180857:3;9563=ee82<==::o21=:l4}r114?6=:r78<?4>7c9>740=<o1v>m;:18684bl3?:70=le;3;6>;4m;0?j63<3b8ge>;5n10o56s|2d`94?5|5:::6964=3g`>1><5;oi6<9m;|q1b3<72:q6?=?513;897cd282370<i7;34f>{t;8l1<7<t=222>41e349:87:i;|q037<72;kp1?km:43896de2=<01>l6:54896df2=<01>ll:54896dc2=<01>m?:54896db2=<01>li:54896e62=<01>m=:54896ea2=<01>mk:54896eb2=<01>j?:54896b62=<01>j;:54896b52=<01>j<:54896b22=<01>j9:54896gc2=<01>ol:54896gb2=<01>on:54896g>2=<01>om:54896g02=<01>o9:54896g?2=<01>o::54896cf2=<01>k6:54896c?2=<01>k8:54896c12=<01>k::54896c32=<01>k<:54896c52=<01>k>:548961428=i7p}<0`83>7}:;8?1=5<4=20b>ae<uz9:?7>52z?05a<60;16??o5dc9~w6752909w0=>c;3;6>;4:h0om6s|30394?4|5:;i6<6=;<11e?b>3ty8==4?:3y>74g=91801><m:ec8yv57n3:1>v3<1882<7=:;;h1h45rs22f>5<5s49:47?72:?06f<ck2wx?=j50;0x9670282970==c;fa?xu48j0;6?u230495=4<5:8h6io4}r13f?6=:r78=94>839>77e=l01v><k:18085503>=70=9a;65?851l3;<n6s|33;94?4|5:8369h4=20a>41e3ty94h4?:3y>6<5=<116>4<516`8yv4>03:1>v3=9282<==::0n1=:l4}r0:b?6=:r795>4>7c9>6d4=l01v?6k:18184>:3>370<61;34f>{t:0=1<7<t=3;1>4>?3482o7?8b:p6=e=838p1?7>:5:897?728=i7p}=9783>7}::0;1=564=3;a>41e3ty94o4?:3y>6<6=<116>5h516`8yv4>=3:1>v3=9182<==::0k1=:l4}r0:0?6=:r794k4>899>6<?=9>h0q~<8b;296~;5090?463=7g823g=z{;2>6=4={<0;4?7?02794l4>7c9~w7?b2909w0<70;34f>;5i;0on6s|26c94?4|5;=m6964=35f>41e3ty9494?:3y>62`=91201?66:05a?xu5?00;6?u226g90==::>n1=:l4}r0;7?6=:r79;h4>899>6=>=9>h0q~<88;296~;5?m0?463=7b823g=z{;296=4={<04`?7?02794:4>7c9~w7>62909w0<8c;3;<>;50?0:;o5rs2;g>5<3s49in7:i;<1b3?7?:278:;4kc:?0<6<c12wx?o?50;1x96de282970=lf;6e?85283nh7p}<9c83>1}:;k318k523`795=4<5:<>6il4=25e>a?<uz9jj7>53z?0f<<60;16?nj54g9>71`=lk1v>7l:18785ei3>m70=n6;3;6>;4><0om63<808g=>{t;k:1<7=t=2`b>4>5349hi7:i;<17b?bf3ty85h4?:5y>7ge=<o16?l65190896012mk01>6::e;8yv5e:3:1?v3<bb82<7=:;m:18k523429`d=z{:3m6=4;{<1a`?2a349j57?72:?022<ck2784:4k9:p7g5=839p1>lk:0:1?85c93>m70=:1;f`?xu4i;0;69u23b290c=:;hi1=5<4=24;>ag<5:2o6i74}r1a2?6=;r78o=4>839>7a2=<o16?8<5d`9~w6g7290?w0=me;6e?85fi3;3>63<668ge>;4000o56s|3c694?5|5:hn6<6=;<1g6?2a349>=7jn;|q0e4<72=q6?oh54g9>7dd=91801>87:ea896>e2m30q~=m5;297~;4jo0:4?523e190c=:;<81hn5rs2c0>5<3s49h=7:i;<1b`?7?:278:44kc:?0<c<c12wx?o950;1x96e6282970=k5;6e?852;3nh7p}<a583>1}:;j818k523`g95=4<5:<26io4=2;b>a?<uz9i47>53z?0g7<60;16?i854g9>705=lh1v>m<:18785dl3;3>63<e087b>;4;j0on63=f68g<>{t;ji1<7:t=2f5>4>5349nm7:i;<174?bf348m97j6;|q03f<72;q6?lj54g9>7<>=9>h0q~=8b;296~;4ij0?j63<96823g=z{:=o6=4={<1ba?2a349257?8b:p72?=838p1>on:5d896?228=i7p}<7983>7}:;h318k52386952d<uz9<m7>52z?0eg<3n2785;4>7c9~w6112909w0=n7;6e?85>:3;<n6s|36794?4|5:k=69h4=2;2>41e3ty8;:4?:3y>7d>=<o16?4=516`8yv50<3:1>v3<a487b>;4190:;o5rs2:f>5<5s49257:7;<1;a?70j2wx?4o50;0x96?>288270=6a;34f>{t;1i1<7=t=2;;>1><5:2n6964=2:`>41e3ty84k4?:2y>7<>=9;301>6j:0:;?85?n3;<n6s|39c94?5|5:3<6964=2:`>1><5:2j6<9m;|q0<a<72:q6?49513;896>d282370=7d;34f>{t;121<7=t=2;5>1><5:2j6964=2:;>41e3ty84o4?:2y>7<0=9;301>6n:0:;?85?j3;<n6s|39494?5|5:3>6964=2:;>1><5:2=6<9m;|q0<<<72:q6?4;513;896>?282370=79;34f>{t;1>1<7=t=2;7>1><5:2=6964=2:7>41e3ty84:4?:2y>7<2=9;301>69:0:;?85??3;<n6s|39094?5|5:386964=2:7>1><5:296<9m;|q0<0<72:q6?4=513;896>3282370=75;34f>{t;1:1<7=t=2;1>1><5:296964=2:3>41e3ty84>4?:2y>7<4=9;301>6=:0:;?85?;3;<n6s|36g94?5|5:3:6964=2:3>1><5:=n6<9m;|q0<4<72:q6?4?513;896>7282370=71;34f>{t;>l1<7=t=2;3>44>349<i7?78:?03c<6?k1v>ji:18785b13;3>63>988g=>;6110om63;59800>{t;mo1<7:t=2g;>4>534;2m7j6;<3:=?bf34>>47=<;|q0`a<72=q6?h95190894?e2m301<7n:ec8913?2:80q~=kc;290~;4m?0:4?5218a9`<=:90h1hl5244:974=z{:ni6=4;{<1f1?7?:27:5i4k9:?2=f<ci27?954<0:p7ag=83>p1>k;:0:1?87>m3n270?6d;fb?822038m7p}<d883>1}:;l91=5<4=0;e>a?<583n6io4=57;>7c<uz9o47>54z?0a7<60;16=l>5d89>5<`=lh1688652e9~w6b02908w0=j1;3;6>;6i90om63;5981g>{t;:=1<7<t=211>4>?3498o7?8b:p77c=838p1>==:05a?854;3>37p}<3983>7}:;:91=564=21g>41e3ty8>k4?:3y>765=9>h01>=;:5:8yv5413:1>v3<3582<==:;:o1=:l4}r104?6=:r78?94>7c9>763=<11v>=n:181854=3;3463<3g823g=z{:9:6=4={<101?70j278?;4;8:p76d=838p1>=9:0:;?85383;<n6s|34694?4|5:9=6<9m;<145?be3ty88l4?:3y>713=91201>:i:05a?xu4<80;6?u2357952d<5:>=6964}r17f?6=:r788;4>899>706=9>h0q~=;2;296~;4<?0:;o5235590==z{:>h6=4={<173?7?02789<4>7c9~w6242909w0=;7;34f>;4<10?46s|35f94?4|5:>36<67;<166?70j2wx?9:50;0x962?28=i70=;9;6;?xu4<l0;6?u235;95=><5:?86<9m;|q010<72:q6?97516`896162m301>8l:e`8yv5183:1>v3<5c82<==:;??1=:l4}r163?6=:r789o4>7c9>70e=<11v>8>:181852k3;3463<67823g=z{:?36=4={<16g?70j2789i4;8:p734=838p1>;k:0:;?851?3;<n6s|34;94?4|5:?o6<9m;<16a?2?3ty8:>4?:3y>70c=91201>87:05a?xu4=h0;6?u234g952d<5:?m6964}r150?6=:r789k4>899>73?=9>h0q~=:6;296~;4=o0:;o5237a9`<=z{:=;6=4<{<15a?2a349=j7:i;<145?70j2wx?;k50;6x960b282970=82;fb?850;3nj70=9d;f;?xu4>k0;6?u237c90c=:;?i1=:l4}r66f?6=:<q68?j5479>07e=<?168?l5479>07g=<?168?75479>07>=<?168?85479>073=<?168?:5479>075=<?168?<5479>077=<?168?>5479>04`=<?168<k5479>04b=<?168<l5479>04g=<?168<75479>04>=<?168<95479>040=<?168<;5479>042=<?168<=5479>044=<?168>=5479>064=<?168>?5479>066=<?168?h5479>07c=<?168?95479>04e=<?168<?5479>046=<?16>;l516`8yv2283:1>v3;2e87b>;3=10h;6s|45d94?4|5=8h69h4=57;>g1<uz>?i7>52z?76g<3n27?954m5:p01b=838p19<n:5d8913?2k90q~:;c;296~;3:00?j63;598a6>{t<=h1<7<t=50;>1`<5=?36o?4}r67=?6=:r7?>;4;f:?71=<e82wx89650;0x91422=l019;7:`d8yv23?3:1>v3;2587b>;3=10ji6s|45494?4|5=8869h4=57;>f3<uz>?97>52z?767<3n27?954nd:p012=838p19<>:5d8913?2hi0q~:;3;296~;3:90?j63;598bf>{t<=81<7<t=53e>1`<5=?36lo4}r675?6=:r7?=h4;f:?71=<f02wx89>50;0x917c2=l019;7:`58yv24m3:1>v3;1c87b>;3=10j:6s|42f94?4|5=;j69h4=57;>d3<uz>8o7>52z?75<<3n27?954l4:p06d=838p19?7:5d8913?2h>0q~:<a;296~;39>0?j63;598b7>{t<:31<7<t=535>1`<5=?36l<4}r60<?6=:r7?=84;f:?71=<f92wx8>950;0x91732=l019;7:`28yv24>3:1>v3;1287b>;3=102j6s|42794?4|5=;969h4=57;>gc<uz>>;7>52z?776<3n27?954md:p000=838p19==:5d8913?2j90q~::5;296~;3;80?j63;598ag>{t<<>1<7<t=513>1`<5=?36ol4}r667?6=:r7?>k4;f:?71=<ei2wx88<50;0x914b2=l019;7:c;8yv2293:1>v3;2687b>;3=10i46s|45c94?4|5=;h69h4=57;>g2<uz>8j7>52z?754<3n27?954n9:p062=838p19??:5d8913?20o0q~==a;296~;4:h0:;o5233`9`g=z{=?26=4={<66e?70j27?954l9:p7`d=83?p1>9>:ec8960d2mk01>9=:05a?82203><863;598`<>{t9?:1<7<t=300>ag<5;896<<n;|q22g<72;q6=n?5d`9>5f6=9;k0q~<=4;296~;5:?0on63=23823g=z{8i96=4={<3`0?be34;h<7?8b:p560=838p1><l:05a?855j3nh7ps|54d94?4|V<?m70:<:47e?!2083;=h6s|57594?4|V<<<70:<:444?!2083;=i6s|54394?4|V<?:70:<:472?!2083;=j6s|4c294?4|V=3n70:<:5;f?!2083;?>6s|4`g94?4|V=3o70:<:5;g?!2083;?h6s|4`f94?4|V=3h70:<:5;`?!2083;>;6s|4`a94?4|V=3i70:<:5;a?!2083;>56s|4``94?4|V=3j70:<:5;b?!2083;>m6s|4`c94?4|V=3270:<:5;:?!2083;>n6s|4`;94?4|V=3370:<:5;;?!2083;>h6s|4`:94?4|V=3<70:<:5;4?!2083;>i6s|4c;94?4|V=k=70:<:5c5?!2083;>j6s|4c:94?4|V=k>70:<:5c6?!2083;==6s|4c594?4|V=k?70:<:5c7?!2083;=>6s|4c494?4|V=k870:<:5c0?!2083;=?6s|4c794?4|V=k970:<:5c1?!2083;=86s|4c694?4|V=k:70:<:5c2?!2083;=96s|4c194?4|V=k;70:<:5c3?!2083;=:6s|4c094?4|V=3m70:<:5;e?!2083;=;6s|4c394?4|V=3=70:<:5;5?!2083;=46s|4`594?4|V=3>70:<:5;6?!2083;=56s|56194?4|V<=870:<:450?!2083;=m6s|54f94?4|V<?o70:<:47g?!2083;=o6s|4g`94?4|V=n<70:<:5f4?!2083;<<6s|4g;94?4|V=n=70:<:5f5?!2083;<=6s|4g:94?4|V=n>70:<:5f6?!2083;<>6s|4g594?4|V=n?70:<:5f7?!2083;<?6s|4g494?4|V=n870:<:5f0?!2083;<86s|4g794?4|V=n970:<:5f1?!2083;<96s|4g194?4|V=n;70:<:5f3?!2083;<:6s|4g094?4|V=im70:<:5ae?!2083;<;6s|4g394?4|V=in70:<:5af?!2083;<46s|4g294?4|V=io70:<:5ag?!2083;846s|4dd94?4|V=ih70:<:5a`?!2083;856s|4dg94?4|V=ii70:<:5aa?!2083;8m6s|4df94?4|V=ij70:<:5ab?!2083;8n6s|4da94?4|V=i270:<:5a:?!2083;8o6s|4d`94?4|V=i370:<:5a;?!2083;8h6s|4dc94?4|V=i<70:<:5a4?!2083;8i6s|4d:94?4|V=i>70:<:5a6?!2083;8j6s|4d594?4|V=i?70:<:5a7?!2083;?<6s|4d494?4|V=i870:<:5a0?!2083;?=6s|4d794?4|V=i970:<:5a1?!2083;??6s|4d694?4|V=i:70:<:5a2?!2083;?86s|4d194?4|V=i;70:<:5a3?!2083;?96s|4d094?4|V=hm70:<:5`e?!2083;?:6s|4d394?4|V=hn70:<:5`f?!2083;?;6s|4d294?4|V=ho70:<:5`g?!2083;?46s|4ed94?4|V=hh70:<:5``?!2083;?56s|51094?4|V=no70:<:5fg?!2083;?m6s|51394?4|V=nh70:<:5f`?!2083;?n6s|51294?4|V=ni70:<:5fa?!2083;?o6s|4gd94?4|V=nj70:<:5fb?!2083;?i6s|4gg94?4|V=n270:<:5f:?!2083;?j6s|4gf94?4|V=n370:<:5f;?!2083;><6s|4ga94?4|V=n:70:<:5f2?!2083;>=6s|4g694?4|V=i=70:<:5a5?!2083;>>6s|4d;94?4|V=hi70:<:5`a?!2083;>?6s|4eg94?4|V=hj70:<:5`b?!2083;>86s|51c94?4|V<:j70:<:42b?!2083;>96s|49794?4|V=2>70:<:5:6?!2083;>:6s|51694?4|V<:?70:<:427?!2083;>46s|53d94?4|V<8m70:<:40e?!2083;>o6srn`f:>5<5sA><=6saaec94?4|@==:7p`ndc83>7}O<>;0qcokc;296~N3?81vbljk:181M2092wemik50;0xL1163tdjhk4?:3yK027<ugkn<7>52zJ734=zfho:6=4={I645>{iil81<7<tH552?xhfm:0;6?uG4638ykgb<3:1>vF;709~jdc22909wE:81:me`0=838pD99>;|lba2<72;qC8:?4}ocf<?6=:rB?;<5rn`g:>5<5sA><=6saadc94?4|@==:7p`nec83>7}O<>;0qcojc;296~N3?81vblkk:181M2092wemhk50;0xL1163tdjik4?:3yK027<ugkm<7>52zJ734=zfhl:6=4={I645>{iio81<7<tH552?xhfn:0;6?uG4638ykga<3:1>vF;709~jd`22909wE:81:mec0=838pD99>;|lbb2<72;qC8:?4}oce<?6=:rB?;<5rn`d:>5<5sA><=6saagc94?4|@==:7p`nfc83>7}O<>;0qcoic;296~N3?81vblhk:181M2092wemkk50;0xL1163tdjjk4?:3yK027<ugh;<7>52zJ734=zfk::6=4={I645>{ij981<7<tH552?xhe8:0;6?uG4638ykd7<3:1>vF;709~jg622909wE:81:mf50=838pD99>;|la42<72;qC8:?4}o`3<?6=:rB?;<5rnc2:>5<5sA><=6sab1c94?4|@==:7p`m0c83>7}O<>;0qcl?c;296~N3?81vbo>k:181M2092wen=k50;0xL1163tdi<k4?:3yK027<ugh:<7>52zJ734=zfk;:6=4={I645>{ij881<7<tH552?xhe9:0;6?uG4638ykd6<3:1>vF;709~jg722909wE:81:mf40=838pD99>;|la52<72;qC8:?4}o;2e?6=9rB?;<5rn87:>5<6sA><=6sa94c94?7|@==:7p`65c83>4}O<>;0qc7:c;295~N3?81vb4;k:182M2092we58k50;3xL1163td29k4?:0yK027<ug3=<7>51zJ734=zf0<:6=4>{I645>{i1?81<7?tH552?xh>>:0;6<uG4638yk?1<3:1=vF;709~j<02290:wE:81:m=30=83;pD99>;|l:22<728qC8:?4}o;5<?6=9rB?;<5rn84:>5<6sA><=6sa97c94?7|@==:7p`66c83>4}O<>;0qc79c;295~N3?81vb48k:182M2092we5;k50;3xL1163td2:k4?:0yK027<ug3<<7>51zJ734=zf0=:6=4>{I645>{i1>81<7?tH552?xh>?:0;6<uG4638yk?0<3:1=vF;709~j<12290:wE:81:m=20=83;pD99>;|l:32<728qC8:?4}o;4<?6=9rB?;<5rn85:>5<6sA><=6sa96c94?7|@==:7p`67c83>4}O<>;0qc78c;295~N3?81vb49k:182M2092we5:k50;3xL1163td2;k4?:0yK027<ug33<7>51zJ734=zf02:6=4>{I645>{i1181<7?tH552?xh>0:0;6<uG4638yk??<3:1=vF;709~j<>2290:wE:81:m==0=83;pD99>;|l:<2<728qC8:?4}o;;<?6=9rB?;<5rn8::>5<6sA><=6sa99c94?7|@==:7p`68c83>4}O<>;0qc77c;295~N3?81vb46k:182M2092we55k50;3xL1163td24k4?:0yK027<ug32<7>51zJ734=zf03:6=4>{I645>{i1081<7?tH552?xh>1:0;6<uG4638yk?><3:1=vF;709~j<?2290:wE:81:m=<0=83;pD99>;|l:=2<728qC8:?4}o;:<?6=9rB?;<5rn8;:>5<6sA><=6sa98c94?7|@==:7p`69c83>4}O<>;0qc76c;295~N3?81vb47k:182M2092we54k50;3xL1163td25k4?:0yK027<ug3j<7>51zJ734=zf0k:6=4>{I645>{i1h81<7?tH552?xh>i:0;6<uG4638yk?f<3:1=vF;709~j<g2290:wE:81:m=d0=83;pD99>;|l:e2<728qC8:?4}o;b<?6=9rB?;<5rn8c:>5<6sA><=6sa9`c94?7|@==:7p`6ac83>4}O<>;0qc7nc;295~N3?81vb4ok:182M2092we5lk50;3xL1163td2mk4?:0yK027<ug3i<7>51zJ734=zf0h:6=4>{I645>{i1k81<7?tH552?xh>j:0;6<uG4638yk?e<3:1=vF;709~j<d2290:wE:81:m=g0=83;pD99>;|l:f2<728qC8:?4}o;a<?6=9rB?;<5rn8`:>5<6sA><=6sa9cc94?7|@==:7p`6bc83>4}O<>;0qc7mc;295~N3?81vb4lk:182M2092we5ok50;3xL1163td2nk4?:0yK027<ug3h<7>51zJ734=zf0i:6=4>{I645>{i1j81<7?tH552?xh>k:0;6<uG4638yk?d<3:1=vF;709~j<e2290:wE:81:m=f0=83;pD99>;|l:g2<728qC8:?4}o;`<?6=9rB?;<5rn8a:>5<6sA><=6sa9bc94?7|@==:7p`6cc83>4}O<>;0qc7lc;295~N3?81vb4mk:182M2092we5nk50;3xL1163td2ok4?:0yK027<ug3o<7>51zJ734=zf0n:6=4>{I645>{i1m81<7?tH552?xh>l:0;6<uG4638yk?c<3:1=vF;709~j<b2290:wE:81:m=a0=83;pD99>;|l:`2<728qC8:?4}o;g<?6=9rB?;<5rn8f:>5<6sA><=6sa9ec94?7|@==:7p`6dc83>4}O<>;0qc7kc;295~N3?81vb4jk:182M2092we5ik50;3xL1163td2hk4?:0yK027<ug3n<7>51zJ734=zf0o:6=4>{I645>{i1l81<7?tH552?xh>m:0;6<uG4638yk?b<3:1=vF;709~j<c2290:wE:81:m=`0=83;pD99>;|l:a2<728qC8:?4}o;f<?6=9rB?;<5rn8g:>5<6sA><=6sa9dc94?7|@==:7p`6ec83>4}O<>;0qc7jc;295~N3?81vb4kk:182M2092we5hk50;3xL1163td2ik4?:0yK027<ug3m<7>51zJ734=zf0l:6=4>{I645>{i1o81<7?tH552?xh>n:0;6<uG4638yk?a<3:1=vF;709~j<`2290:wE:81:m=c0=83;pD99>;|l:b2<728qC8:?4}o;e<?6=9rB?;<5rn8d:>5<6sA><=6sa9gc94?7|@==:7p`6fc83>4}O<>;0qc7ic;295~N3?81vb4hk:182M2092we5kk50;3xL1163td2jk4?:0yK027<ugk;<7>51zJ734=zfh::6=4>{I645>{ii981<7?tH552?xhf8:0;6<uG4638ykg7<3:1=vF;709~jd62290:wE:81:me50=83;pD99>;|lb42<728qC8:?4}oc3<?6=9rB?;<5rn`2:>5<6sA><=6saa1c94?7|@==:7p`n0c83>4}O<>;0qco?c;295~N3?81vbl>k:182M2092wem=k50;3xL1163tdj<k4?:0yK027<ugk:<7>51zJ734=zfh;:6=4>{I645>{ii881<7?tH552?xhf9:0;6<uG4638ykg6<3:1=vF;709~jd72290:wE:81:me40=83;pD99>;|lb52<728qC8:?4}oc2<?6=9rB?;<5rn`3:>5<6sA><=6saa0c94?7|@==:7p`n1c83>4}O<>;0qco>c;295~N3?81vbl?k:182M2092wem<k50;3xL1163tdj=k4?:0yK027<ugk9<7>51zJ734=zfh8:6=4>{I645>{ii;81<7?tH552?xhf::0;6<uG4638ykg5<3:1=vF;709~jd42290:wE:81:me70=83;pD99>;|lb62<728qC8:?4}oc1<?6=9rB?;<5rn`0:>5<6sA><=6saa3c94?7|@==:7p`n2c83>4}O<>;0qco=c;295~N3?81vbl<k:182M2092wem?k50;3xL1163tdj>k4?:0yK027<ugk8<7>51zJ734=zfh9:6=4>{I645>{ii:81<7?tH552?xhf;:0;6<uG4638ykg4<3:1=vF;709~jd52290:wE:81:me60=83;pD99>;|lb72<728qC8:?4}oc0<?6=9rB?;<5rn`1:>5<6sA><=6saa2c94?7|@==:7p`n3c83>4}O<>;0qco<c;295~N3?81vbl=k:182M2092wem>k50;3xL1163tdj?k4?:0yK027<ugk?<7>51zJ734=zfh>:6=4>{I645>{ii=81<7?tH552?xhf<:0;6<uG4638ykg3<3:1=vF;709~jd22290:wE:81:me10=83;pD99>;|lb02<728qC8:?4}oc7<?6=9rB?;<5rn`6:>5<6sA><=6saa5c94?7|@==:7p`n4c83>4}O<>;0qco;c;295~N3?81vbl:k:182M2092wem9k50;3xL1163tdj8k4?:0yK027<ugk><7>51zJ734=zfh?:6=4>{I645>{ii<81<7?tH552?xhf=:0;6<uG4638ykg2<3:1=vF;709~jd32290:wE:81:me00=83;pD99>;|lb12<728qC8:?4}oc6<?6=9rB?;<5rn`7:>5<6sA><=6saa4c94?7|@==:7p`n5c83>4}O<>;0qco:c;295~N3?81vbl;k:182M2092wem8k50;3xL1163tdj9k4?:0yK027<ugk=<7>51zJ734=zfh<:6=4>{I645>{ii?81<7?tH552?xhf>:0;6<uG4638ykg1<3:1=vF;709~jd02290:wE:81:me30=83;pD99>;|lb22<728qC8:?4}oc5<?6=9rB?;<5rn`4:>5<6sA><=6saa7c94?7|@==:7p`n6c83>4}O<>;0qco9c;295~N3?81vbl8k:182M2092wem;k50;3xL1163tdj:k4?:0yK027<ugk<<7>51zJ734=zfh=:6=4>{I645>{ii>81<7?tH552?xhf?:0;6<uG4638ykg0<3:1=vF;709~jd12290:wE:81:me20=83;pD99>;|lb32<728qC8:?4}oc4<?6=9rB?;<5rn`5:>5<6sA><=6saa6c94?7|@==:7p`n7c83>4}O<>;0qco8c;295~N3?81vbl9k:182M2092wem:k50;3xL1163tdj;k4?:0yK027<ugk3<7>51zJ734=zfh2:6=4>{I645>{ii181<7?tH552?xhf0:0;6<uG4638ykg?<3:1=vF;709~jd>2290:wE:81:me=0=83;pD99>;|lb<2<728qC8:?4}oc;<?6=9rB?;<5rn`::>5<6sA><=6saa9c94?7|@==:7p`n8c83>4}O<>;0qco7c;295~N3?81vbl6k:182M2092wem5k50;3xL1163tdj4k4?:0yK027<ugk2<7>51zJ734=zfh3:6=4>{I645>{ii081<7?tH552?xhf1:0;6<uG4638ykg><3:1=vF;709~jd?2290:wE:81:me<0=83;pD99>;|lb=2<728qC8:?4}oc:<?6=9rB?;<5rn`;:>5<6sA><=6saa8c94?7|@==:7p`n9c83>4}O<>;0qco6c;295~N3?81vbl7k:182M2092wem4k50;3xL1163tdj5k4?:0yK027<ugkj<7>51zJ734=zfhk:6=4>{I645>{iih81<7?tH552?xhfi:0;6<uG4638ykgf<3:1=vF;709~jdg2290:wE:81:med0=83;pD99>;|lbe2<728qC8:?4}ocb<?6=9rB?;<5rn`c:>5<6sA><=6saa`c94?7|@==:7p`nac83>4}O<>;0qconc;295~N3?81vblok:182M2092wemlk50;3xL1163tdjmk4?:0yK027<ugki<7>51zJ734=zfhh:6=4>{I645>{iik81<7?tH552?xhfj:0;6<uG4638ykge<3:1=vF;709~jdd2290:wE:81:meg0=83;pD99>;|lbf2<728qC8:?4}oca<?6=9rB?;<5rn``:>5<6sA><=6saacc94?7|@==:7p`nbc83>4}O<>;0qcomc;295~N3?81vbllk:182M2092wemok50;3xL1163tdjnk4?:0yK027<ugkh<7>51zJ734=zfhi:6=4>{I645>{iij81<7?tH552?xhfk:0;6<uG4638ykgd<3:1=vF;709~jde2290:wE:81:mef0=83;pD99>;|lbg2<728qC8:?4}oc`<?6=9rB?;<5rn`a:>5<6sA><=6saabc94?7|@==:7p`ncc83>4}O<>;0qcolc;295~N3?81vblmk:182M2092wemnk50;3xL1163tdjok4?:0yK027<ugko<7>51zJ734=zfhn:6=4>{I645>{iim81<7?tH552?xhfl:0;6<uG4638ykgc<3:1=vF;709~jdb2290:wE:81:mea0=83;pD99>;|lb`2<728qC8:?4}ocg<?6=9rB?;<5r}|CDF}dl10<jh:ke93~DED|8tJK\vsO@
\ No newline at end of file diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v new file mode 100644 index 000000000..25ac9779e --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.v @@ -0,0 +1,173 @@ +/******************************************************************************* +* This file is owned and controlled by Xilinx and must be used * +* solely for design, simulation, implementation and creation of * +* design files limited to Xilinx devices or technologies. Use * +* with non-Xilinx devices or technologies is expressly prohibited * +* and immediately terminates your license. * +* * +* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * +* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * +* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * +* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * +* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * +* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * +* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * +* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * +* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE * +* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * +* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * +* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * +* FOR A PARTICULAR PURPOSE. * +* * +* Xilinx products are not intended for use in life support * +* appliances, devices, or systems. Use in such applications are * +* expressly prohibited. * +* * +* (c) Copyright 1995-2009 Xilinx, Inc. * +* All rights reserved. * +*******************************************************************************/ +// The synthesis directives "translate_off/translate_on" specified below are +// supported by Xilinx, Mentor Graphics and Synplicity synthesis +// tools. Ensure they are correct for your synthesis tool(s). + +// You must compile the wrapper file fifo_xlnx_512x36_2clk_18to36.v when simulating +// the core, fifo_xlnx_512x36_2clk_18to36. When compiling the wrapper file, be sure to +// reference the XilinxCoreLib Verilog simulation library. For detailed +// instructions, please refer to the "CORE Generator Help". + +`timescale 1ns/1ps + +module fifo_xlnx_512x36_2clk_18to36( + rst, + wr_clk, + rd_clk, + din, + wr_en, + rd_en, + dout, + full, + almost_full, + empty, + prog_full); + + +input rst; +input wr_clk; +input rd_clk; +input [17 : 0] din; +input wr_en; +input rd_en; +output [35 : 0] dout; +output full; +output almost_full; +output empty; +output prog_full; + +// synthesis translate_off + + FIFO_GENERATOR_V6_1 #( + .C_COMMON_CLOCK(0), + .C_COUNT_TYPE(0), + .C_DATA_COUNT_WIDTH(10), + .C_DEFAULT_VALUE("BlankString"), + .C_DIN_WIDTH(18), + .C_DOUT_RST_VAL("0"), + .C_DOUT_WIDTH(36), + .C_ENABLE_RLOCS(0), + .C_ENABLE_RST_SYNC(1), + .C_ERROR_INJECTION_TYPE(0), + .C_FAMILY("spartan3"), + .C_FULL_FLAGS_RST_VAL(0), + .C_HAS_ALMOST_EMPTY(0), + .C_HAS_ALMOST_FULL(1), + .C_HAS_BACKUP(0), + .C_HAS_DATA_COUNT(0), + .C_HAS_INT_CLK(0), + .C_HAS_MEMINIT_FILE(0), + .C_HAS_OVERFLOW(0), + .C_HAS_RD_DATA_COUNT(0), + .C_HAS_RD_RST(0), + .C_HAS_RST(1), + .C_HAS_SRST(0), + .C_HAS_UNDERFLOW(0), + .C_HAS_VALID(0), + .C_HAS_WR_ACK(0), + .C_HAS_WR_DATA_COUNT(0), + .C_HAS_WR_RST(0), + .C_IMPLEMENTATION_TYPE(2), + .C_INIT_WR_PNTR_VAL(0), + .C_MEMORY_TYPE(1), + .C_MIF_FILE_NAME("BlankString"), + .C_MSGON_VAL(1), + .C_OPTIMIZATION_MODE(0), + .C_OVERFLOW_LOW(0), + .C_PRELOAD_LATENCY(0), + .C_PRELOAD_REGS(1), + .C_PRIM_FIFO_TYPE("1kx18"), + .C_PROG_EMPTY_THRESH_ASSERT_VAL(4), + .C_PROG_EMPTY_THRESH_NEGATE_VAL(5), + .C_PROG_EMPTY_TYPE(0), + .C_PROG_FULL_THRESH_ASSERT_VAL(1015), + .C_PROG_FULL_THRESH_NEGATE_VAL(1014), + .C_PROG_FULL_TYPE(1), + .C_RD_DATA_COUNT_WIDTH(9), + .C_RD_DEPTH(512), + .C_RD_FREQ(1), + .C_RD_PNTR_WIDTH(9), + .C_UNDERFLOW_LOW(0), + .C_USE_DOUT_RST(1), + .C_USE_ECC(0), + .C_USE_EMBEDDED_REG(0), + .C_USE_FIFO16_FLAGS(0), + .C_USE_FWFT_DATA_COUNT(0), + .C_VALID_LOW(0), + .C_WR_ACK_LOW(0), + .C_WR_DATA_COUNT_WIDTH(10), + .C_WR_DEPTH(1024), + .C_WR_FREQ(1), + .C_WR_PNTR_WIDTH(10), + .C_WR_RESPONSE_LATENCY(1)) + inst ( + .RST(rst), + .WR_CLK(wr_clk), + .RD_CLK(rd_clk), + .DIN(din), + .WR_EN(wr_en), + .RD_EN(rd_en), + .DOUT(dout), + .FULL(full), + .ALMOST_FULL(almost_full), + .EMPTY(empty), + .PROG_FULL(prog_full), + .BACKUP(), + .BACKUP_MARKER(), + .CLK(), + .SRST(), + .WR_RST(), + .RD_RST(), + .PROG_EMPTY_THRESH(), + .PROG_EMPTY_THRESH_ASSERT(), + .PROG_EMPTY_THRESH_NEGATE(), + .PROG_FULL_THRESH(), + .PROG_FULL_THRESH_ASSERT(), + .PROG_FULL_THRESH_NEGATE(), + .INT_CLK(), + .INJECTDBITERR(), + .INJECTSBITERR(), + .WR_ACK(), + .OVERFLOW(), + .ALMOST_EMPTY(), + .VALID(), + .UNDERFLOW(), + .DATA_COUNT(), + .RD_DATA_COUNT(), + .WR_DATA_COUNT(), + .PROG_EMPTY(), + .SBITERR(), + .DBITERR()); + + +// synthesis translate_on + +endmodule + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.veo b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.veo new file mode 100644 index 000000000..db2795098 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.veo @@ -0,0 +1,53 @@ +/******************************************************************************* +* This file is owned and controlled by Xilinx and must be used * +* solely for design, simulation, implementation and creation of * +* design files limited to Xilinx devices or technologies. Use * +* with non-Xilinx devices or technologies is expressly prohibited * +* and immediately terminates your license. * +* * +* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * +* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * +* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * +* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * +* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * +* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * +* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * +* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * +* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE * +* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * +* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * +* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * +* FOR A PARTICULAR PURPOSE. * +* * +* Xilinx products are not intended for use in life support * +* appliances, devices, or systems. Use in such applications are * +* expressly prohibited. * +* * +* (c) Copyright 1995-2009 Xilinx, Inc. * +* All rights reserved. * +*******************************************************************************/ +// The following must be inserted into your Verilog file for this +// core to be instantiated. Change the instance name and port connections +// (in parentheses) to your own signal names. + +//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG +fifo_xlnx_512x36_2clk_18to36 YourInstanceName ( + .rst(rst), + .wr_clk(wr_clk), + .rd_clk(rd_clk), + .din(din), // Bus [17 : 0] + .wr_en(wr_en), + .rd_en(rd_en), + .dout(dout), // Bus [35 : 0] + .full(full), + .almost_full(almost_full), + .empty(empty), + .prog_full(prog_full)); + +// INST_TAG_END ------ End INSTANTIATION Template --------- + +// You must compile the wrapper file fifo_xlnx_512x36_2clk_18to36.v when simulating +// the core, fifo_xlnx_512x36_2clk_18to36. When compiling the wrapper file, be sure to +// reference the XilinxCoreLib Verilog simulation library. For detailed +// instructions, please refer to the "CORE Generator Help". + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco new file mode 100644 index 000000000..f888ba5f4 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xco @@ -0,0 +1,84 @@ +############################################################## +# +# Xilinx Core Generator version 12.1 +# Date: Wed Aug 18 17:27:35 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc3s2000 +SET devicefamily = spartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = fg456 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -5 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 6.1 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=true +CSET component_name=fifo_xlnx_512x36_2clk_18to36 +CSET data_count=false +CSET data_count_width=10 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=4 +CSET empty_threshold_negate_value=5 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET enable_reset_synchronization=true +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_flags_reset_value=0 +CSET full_threshold_assert_value=1015 +CSET full_threshold_negate_value=1014 +CSET inject_dbit_error=false +CSET inject_sbit_error=false +CSET input_data_width=18 +CSET input_depth=1024 +CSET output_data_width=36 +CSET output_depth=512 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=First_Word_Fall_Through +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=Single_Programmable_Full_Threshold_Constant +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=9 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=10 +# END Parameters +GENERATE +# CRC: 77234081 diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xise b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xise new file mode 100644 index 000000000..04acaf578 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36.xise @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema"> + + <header> + <!-- ISE source project file created by Project Navigator. --> + <!-- --> + <!-- This file contains project source information including a list of --> + <!-- project source files, project and process properties. This file, --> + <!-- along with the project source files, is sufficient to open and --> + <!-- implement in ISE Project Navigator. --> + <!-- --> + <!-- Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. --> + </header> + + <version xil_pn:ise_version="12.1" xil_pn:schema_version="2"/> + + <files> + <file xil_pn:name="fifo_xlnx_512x36_2clk_18to36.ngc" xil_pn:type="FILE_NGC"> + <association xil_pn:name="BehavioralSimulation"/> + <association xil_pn:name="Implementation"/> + </file> + <file xil_pn:name="fifo_xlnx_512x36_2clk_18to36.v" xil_pn:type="FILE_VERILOG"> + <association xil_pn:name="BehavioralSimulation"/> + <association xil_pn:name="Implementation"/> + <association xil_pn:name="PostMapSimulation"/> + <association xil_pn:name="PostRouteSimulation"/> + <association xil_pn:name="PostTranslateSimulation"/> + </file> + </files> + + <properties> + <property xil_pn:name="Auto Implementation Top" xil_pn:value="false" xil_pn:valueState="non-default"/> + <property xil_pn:name="Device" xil_pn:value="xc3s2000" xil_pn:valueState="non-default"/> + <property xil_pn:name="Device Family" xil_pn:value="Spartan3" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Stop View" xil_pn:value="PreSynthesis" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top" xil_pn:value="Module|fifo_xlnx_512x36_2clk_18to36" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top File" xil_pn:value="fifo_xlnx_512x36_2clk_18to36.ngc" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/fifo_xlnx_512x36_2clk_18to36" xil_pn:valueState="non-default"/> + <property xil_pn:name="Package" xil_pn:value="fg456" xil_pn:valueState="default"/> + <property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/> + <property xil_pn:name="Project Generator" xil_pn:value="CoreGen" xil_pn:valueState="non-default"/> + <property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/> + <property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/> + <property xil_pn:name="Speed Grade" xil_pn:value="-5" xil_pn:valueState="default"/> + <property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/> + <property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/> + <property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/> + <!-- --> + <!-- The following properties are for internal use only. These should not be modified.--> + <!-- --> + <property xil_pn:name="PROP_DesignName" xil_pn:value="fifo_xlnx_512x36_2clk_18to36" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan3" xil_pn:valueState="default"/> + <property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2010-08-18T10:27:37" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="224FA43C81F32871F9E1930EA6CDD6AD" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/> + </properties> + + <bindings/> + + <libraries/> + + <autoManagedFiles> + <!-- The following files are identified by `include statements in verilog --> + <!-- source files and are automatically managed by Project Navigator. --> + <!-- --> + <!-- Do not hand-edit this section, as it will be overwritten when the --> + <!-- project is analyzed based on files automatically identified as --> + <!-- include files. --> + </autoManagedFiles> + +</project> diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_flist.txt b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_flist.txt new file mode 100644 index 000000000..2f8d522f6 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_flist.txt @@ -0,0 +1,12 @@ +# Output products list for <fifo_xlnx_512x36_2clk_18to36> +_xmsgs/pn_parser.xmsgs +fifo_generator_ug175.pdf +fifo_xlnx_512x36_2clk_18to36.gise +fifo_xlnx_512x36_2clk_18to36.ngc +fifo_xlnx_512x36_2clk_18to36.v +fifo_xlnx_512x36_2clk_18to36.veo +fifo_xlnx_512x36_2clk_18to36.xco +fifo_xlnx_512x36_2clk_18to36.xise +fifo_xlnx_512x36_2clk_18to36_flist.txt +fifo_xlnx_512x36_2clk_18to36_readme.txt +fifo_xlnx_512x36_2clk_18to36_xmdf.tcl diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_readme.txt b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_readme.txt new file mode 100644 index 000000000..03829e876 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_readme.txt @@ -0,0 +1,47 @@ +The following files were generated for 'fifo_xlnx_512x36_2clk_18to36' in directory +/home/ianb/ettus/sram_fifo/fpgapriv/usrp2/coregen/ + +fifo_generator_ug175.pdf: + Please see the core data sheet. + +fifo_xlnx_512x36_2clk_18to36.gise: + ISE Project Navigator support file. This is a generated file and should + not be edited directly. + +fifo_xlnx_512x36_2clk_18to36.ngc: + Binary Xilinx implementation netlist file containing the information + required to implement the module in a Xilinx (R) FPGA. + +fifo_xlnx_512x36_2clk_18to36.v: + Verilog wrapper file provided to support functional simulation. + This file contains simulation model customization data that is + passed to a parameterized simulation model for the core. + +fifo_xlnx_512x36_2clk_18to36.veo: + VEO template file containing code that can be used as a model for + instantiating a CORE Generator module in a Verilog design. + +fifo_xlnx_512x36_2clk_18to36.xco: + CORE Generator input file containing the parameters used to + regenerate a core. + +fifo_xlnx_512x36_2clk_18to36.xise: + ISE Project Navigator support file. This is a generated file and should + not be edited directly. + +fifo_xlnx_512x36_2clk_18to36_readme.txt: + Text file indicating the files generated and how they are used. + +fifo_xlnx_512x36_2clk_18to36_xmdf.tcl: + ISE Project Navigator interface file. ISE uses this file to determine + how the files output by CORE Generator for the core can be integrated + into your ISE project. + +fifo_xlnx_512x36_2clk_18to36_flist.txt: + Text file listing all of the output files produced when a customized + core was generated in the CORE Generator. + + +Please see the Xilinx CORE Generator online help for further details on +generated files and how to use them. + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_xmdf.tcl b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_xmdf.tcl new file mode 100644 index 000000000..9b9b1f37a --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_18to36_xmdf.tcl @@ -0,0 +1,68 @@ +# The package naming convention is <core_name>_xmdf +package provide fifo_xlnx_512x36_2clk_18to36_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::fifo_xlnx_512x36_2clk_18to36_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::fifo_xlnx_512x36_2clk_18to36_xmdf::xmdfInit { instance } { +# Variable containg name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name fifo_xlnx_512x36_2clk_18to36 +} +# ::fifo_xlnx_512x36_2clk_18to36_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::fifo_xlnx_512x36_2clk_18to36_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be magically +# available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_generator_ug175.pdf +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_18to36.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_18to36.v +utilities_xmdf::xmdfSetData $instance FileSet $fcount type verilog +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_18to36.veo +utilities_xmdf::xmdfSetData $instance FileSet $fcount type verilog_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_18to36.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_18to36_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module fifo_xlnx_512x36_2clk_18to36 +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.gise b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.gise new file mode 100644 index 000000000..d0c862319 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.gise @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
+
+ <!-- -->
+
+ <!-- For tool use only. Do not edit. -->
+
+ <!-- -->
+
+ <!-- ProjectNavigator created generated project file. -->
+
+ <!-- For use in tracking generated file and other information -->
+
+ <!-- allowing preservation of process status. -->
+
+ <!-- -->
+
+ <!-- Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. -->
+
+ <version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
+
+ <sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="fifo_xlnx_512x36_2clk_36to18.xise"/>
+
+ <files xmlns="http://www.xilinx.com/XMLSchema">
+ <file xil_pn:fileType="FILE_VEO" xil_pn:name="fifo_xlnx_512x36_2clk_36to18.veo" xil_pn:origination="imported"/>
+ </files>
+
+ <transforms xmlns="http://www.xilinx.com/XMLSchema"/>
+
+</generated_project>
diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.ngc b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.ngc new file mode 100644 index 000000000..00814f02e --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.ngc @@ -0,0 +1,3 @@ +XILINX-XDB 0.1 STUB 0.1 ASCII +XILINX-XDM V1.6e +$5a540<,[o}e~g`n;"2*726&;$:,)<6;.vnt*Ydo&lbjbQwloz\144;?U9oaeP37vl5=(iof;0<85?0123=>6789:;<=>;0:23456789:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?013856=6&9;87<>5IORVP?GCL[K757>11g924?OIX\^1|ah_dosp|Ys`{oxd1750?05?46=AGZ^X7~}of]fiur~W}byi~fParqfvq:>2949:6??:HLSQQ<wzfmTi`~{y^vkv`uoWgolmyk39;2=5f=683E^X][[:sf\`drfWje~by26:1<26>712@D[YY4KI@>21?699:1::7AZTQWW>AIF48?1<3?;;0:9KPRW]]0ocxz31683:4=5:28:86<<3232?7<NFY__6IG_A=394;753;0DYY^ZT;FLTD:6294:>6==:HLSQQ<CAK68=7>112906?IR\Y__6IAM<2394;753:<1EC^ZT;fjj952294o7>}=012ec131%<;0895;0GD25>2=AGZ^X7JFPC>0>586:2>1CXZ_UU8GKUD;;3:5=68=;7;7?3?>>=138??;;9G;E4=><23;<4<49768=30>9;126D@_UU8B@ATE410;2<j49;KMTPR=x{elSk{cl^vkv`uo410;2?:49;KMTPR=x{elSk{cl^vkv`uoWhyxiz38;2=61=>2@D[YY4rne\bpjkW}byi~fPndebp`:?294:4675OTVSQQ<ci}kTob{at=:94;7e300DYY^ZT;uq[agsiVidycz38;2=6>G502KOH_O30?:8EABUI5;546OKDSC?6;><IMNYM1=18:CG@WG;<720MIJ]A=7=<>GCL[K7:364AEFQE91902KOH_O38?c8EABUI531<364AEFQE9?902KOH_L30?:8EABUJ5;546OKDS@?6;><IMNYN1=18:CG@WD;<720MIJ]B=7=<>GCL[H7:364AEFQF919i2KOH_L38;2=<>GCL[H743=4AMN:?DU^FJUYIJ=4BT0;?GSTW@DMC<5L2:AF57=D@LI@SAGLEOQF[Q_WM;1HE95LLJC7?FJLJ:1H@_74CNONMQRBL8>0OB\J_FGMAWGSAFDTECH@7:AQADRBL81O>6JL2:FJ2>BNI5:5;6JFA=33:2=CAH6:=394DHC?57803MCJ0<=17:FJE973601OEL2>5;2=3>BNI5;>2;5KI@>2:3=CAH692;5KI@>0:3=CAH6?2;5KI@>6:3=CAH6=2;5KI@>4:3=CAH632;5KI@>::3=CAK6;2:5KIC>24;1<L@H7=<08;EKA8449?2NBN1?<>69GMG:6<7=0HDL314<4?AOE48<5;6JFB=34:2=CAK6:4394DH@?5<813MCI0<08;EKA8769?2NBN1<>>69GMG:5:7=0HDL322<4?AOE4;>5;6JFB=06:2=CAK69:394DH@?62803MCI0?617:FJF94>6?1OEO2=>69GMG:48730HDL33083:2=CAK68=384DH@?7;0<L@H78384DH@?1;0<L@H7:384DH@?3;0<L@H74384DH@?=;1<L@ZJ0=06;EKSE97=87=0HD^N<0<4?AOWJ5:5;6JFPC>2:2=CAYH7>374DHRA86<76>1OE]L33?48@JG;87=0HBO311<4?AIF48;5;6J@A=31:2=CGH6:?394DNC?518>3MEJ0<;50?58@JG;9<4=7IAN<0<5?AIF4;4=7IAN<2<5?AIF4=4=7IAN<4<5?AIF4?4=7IAN<6<5?AIF414=7IAN<8<4?AIFW[OL:6J@B=2=3>BHJ5;;2:5KOC>25;1<LFH7=?08;EMA8459?2NDN1?;>69GKG:6=7=0HBL317<4?AIE48=5;6J@B=3;:2=CGK6:5384DN@?5;1<LFH7>=08;EMA8779?2NDN1<=>69GKG:5;7=0HBL325<4?AIE4;?5;6J@B=05:2=CGK69;394DN@?6=803MEI0?716:FLF949?2NDN1=?>89GKG:493:5;6J@B=12:3=CGK682;5KOC>7:3=CGK6>2;5KOC>5:3=CGK6<2;5KOC>;:3=CGK622:5KOC]QAB1<LFZJ0=06;EMSE97=87=0HB^N<0<4?AIWJ5:5;6J@PC>2:2=CGYH7>374DNRA86<76>1OC]L33?18AKG43LDIn6KA_DA@[WCFLj1NBRKLC^UQMQC53O8?7K<I039E<0=AIEYN>6HK3:DGG1=ALJO87KJ_4:DGT@2<NMXN=6I<;FLG6>O7:2C:>6G=2:K0<>OIA]ZT<=64IOKWTZ6602CEEY^P03:8MKOSXV:846GAIUR\41><AGC_\R>:8:KMMQVX8?20ECG[P^24=>OIA]Y_MYK8;HLJPZ67?2CEEYQ?169JJLRX8;=0ECG[_114?LHN\V:?;6GAIU]312=NF@^T<;94IOKW[5103@DBXR>77:KMMQY71>1BBDZP0@58MKOSW9H<7D@FT^2@3>OIA]U;H:5FNHV\4@1<AGC_S=H8;HLJPZ77?2CEEYQ>169JJLRX9;=0ECG[_014?LHN\V;?;6GAIU]212=NF@^T=;94IOKW[4103@DBXR?77:KMMQY61>1BBDZP1@58MKOSW8H<7D@FT^3@3>OIA]U:H:5FNHV\5@1<AGC_S<H8;HLJPZ47?2CEEYQ=169JJLRX:;=0ECG[_314?LHN\V8?;6GAIU]112=NF@^T>;94IOKW[7103@DBXR<77:KMMQY51>1BBDZP2@58MKOSW;H<7D@FT^0@3>OIA]U9H:5FNHV\6@1<AGC_S?H8;HLJPZ57?2CEEYQ<169JJLRX;;=0ECG[_214?LHN\V9?;6GAIU]012=NF@^T?;94IOKW[6103@DBXR=77:KMMQY41>1BBDZP3@58MKOSW:H<7D@FT^1@3>OIA]U8H:5FNHV\7@1<AGC_S>H9;HLJPZG13@DBXRL=;MK1?II13EEJHHJ8;MMDMFGK<2F^X<:4LTV10>JR\:>0@XZ;6:NVP1YC=2GXKB@:;LW[G\e<Eh`d~[k}shmmg>Knffx]i}foo08J42<F8:2?6@>159M54633G;:=95A1007?K76;=1E=<:;;O3211=I98<?7C?>759M54>33G;:5>5A1368J447<2D:><:4N0010>H6::>0B<<;4:L2602<F88=86@>2618J4533G;8=>5A1518J4343G;=?6@>729M5=5<F8397C<<;O037>H59:1E>?=4N310?K43;2D99>5A2718J7143G83?6@=929M755<F:;87C==3:L076=I;=90B>;<;O157>H4?:1E?5=4N2;0?K27;2D?=>5A4318J1543G>??6@;529M035<F==87C:72:L66>H0:2D2j6@M_CWPTLHXX[E[_:5AEUULVN7<G;1DG<5_4:RBVQg<X@DTNX]FDY`8TLHXJ\YEM@K<;QPF5>W63[o0^LCM17]P5=YT;?k0^HOK_GKQWQe<ZLKOSZGKTI]Bg>TBIMU\EIZG_C38W45<[@GTOBBCIRKLJZEOMJA=7^AZRBG4?VTQIEUJ;6]]V@N\F1=T[[K?7^]]B59W]UC4:2_;#j|i.sd,cf~)keas#@v`r^pg[uhszVmhSua}0123[Wct}e~:??5Z0.eqb+ta'nis"nbdx.O{kwYulVzexQhc^zlv5679VXnxb{1208Q5)`zo$yj"ilx/aoo})JpfxT~iQnup\cfYg{:;<?Q]erwop4553\:$kh!rg-dg}(ddbr$Aua}_sf\tkruWniTtb|?011\V`urd};8>6[?/fpe*w`(ojr%oaew/LzlvZtcWyd~Ril_ymq4563W[oxyaz>339V4*aun'xm#jmw.bnh|*Kg{UyhR~ats]dgZ~hz9:;9R\jstnw564<]9%l~k }f.e`|+ekcq%Ftb|Pre]sjqtXojUsc>?07]Qavsk|8997X> gsd-vc)`kq$h`fv Mymq[wbXxg~ySjmPxnp3451XZly~`y?<2:W3+bta&{l$knv!cmi{+H~hzVxoS}`{r^e`[}iu89:3S_k|umv277=R8&myj#|i/fa{*fjlp&GscQxr^rmpwY`kVrd~=>?0^Pfwpjs9:80Y=!hrg,qb*adp'iggu!Bxnp\swYwf}xTknQwos2344YUmzgx<==;T2,cw`)zo%lou lljz,I}iuW~xT|cz}_fa\|jt7898T^h}zlu306>S7'nxm"h gbz-gim'Drd~Ry}_qlwvZadWqey<=><_Sgpqir6;;1^<"i}f/pe+be&jf`t"Cwos]tvZvi|{UloRv`r1230ZTb{|f=><4U1-dvc(un&mht#mcky-N|jtX{U{by|Pgb]{kw678<UYi~{ct011?P6(o{l%~k!hcy,`hn~(EqeySz|Ppovq[beXpfx;<=8PRdqvhq74:2_;#j|i.sd,cf~)keas#@v`r^uq[uhszVmhSua}0124[Wct}e~:><5Z0.eqb+ta'nis"nbdx.pg[uhszVhbb1?1209V4*aun'xm#jmw.bnh|*tcWyd~Rlfn=0=64=R8&myj#|i/fa{*fjlp&xoS}`{r^`jj959:81^<"i}f/pe+be&jf`t"|k_qlwvZdnf5>5><5Z0.eqb+ta'nis"nbdx.pg[uhszVhbb1;1209V4*aun'xm#jmw.bnh|*tcWyd~Rlfn=4=64=R8&myj#|i/fa{*fjlp&xoS}`{r^`jj919:81^<"i}f/pe+be&jf`t"|k_qlwvZdnf525><5Z0.eqb+ta'nis"nbdx.pg[uhszVhbb171219V4*aun'xm#jmw.bnh|*tcWyd~Rlfn^314>S7'nxm"h gbz-gim'{nT|cz}_ckm[7473\:$kh!rg-dg}(ddbr$~iQnup\flhX;;:0Y=!hrg,qb*adp'iggu!}d^rmpwYeagU?>=5Z0.eqb+ta'nis"nbdx.pg[uhszVhbbR;=0:W3+bta&{l$knv!cmi{+wbXxg~ySoga_703?P6(o{l%~k!hcy,`hn~(zmU{by|Pbhl\376<]9%l~k }f.e`|+ekcq%yhR~ats]amkY?:91^<"i}f/pe+be&jf`t"|k_qlwvZdnfV39:6[?/fpe*w`(ojr%oaew/sf\tkruWkceSua}012362=R8&myj#|i/fa{*fjlp&xoS}`{r^`jjZ~hz9:;<<<9;T2,cw`)zo%lou lljz,vaYwf}xTnd`Pxnp34575?2_;#j|i.sd,cf~)keas#jPpovq[goiWqey<=>>1348Q5)`zo$yj"ilx/aoo})ulVzexQmio]{kw678;8<7X> gsd-vc)`kq$h`fv re]sjqtXj`dTtb|?010263=R8&myj#|i/fa{*fjlp&xoS}`{r^`jjZ~hz9:;??94U1-dvc(un&mht#mcky-q`Zvi|{UiecQwos234645>2_;#j|i.sd,cf~)keas#jPpovq[goiWqey<=>;269V4*aun'xm#jmw.bnh|*tcWyd~Rlfn^zlv567<88=7X> gsd-vc)`kq$h`fv re]sjqtXj`dTtb|?01713>S7'nxm"h gbz-gim'{nT|cz}_ckm[}iu89:>=?84U1-dvc(un&mht#mcky-q`Zvi|{UiecQwos23434?3\:$kh!rg-dg}(ddbr$~iQnup\flhXpfx;<=8>1358Q5)`zo$yj"ilx/aoo})ulVzexQmio]{kw678?89n6[?/fpe*w`(ojr%oaew/sf\tkruWkceSua}0125[gbc8;<0Y=!hrg,qb*adp'iggu!}d^rmpwYeagUsc>?0604?P6(o{l%~k!hcy,`hn~(zmU{by|Pbhl\|jt789=:>=5Z0.eqb+ta'nis"nbdx.pg[uhszVmh0=0=0:W3+bta&{l$knv!cmi{+wbXxg~ySjm31?03?P6(o{l%~k!hcy,`hn~(zmU{by|Pgb>1:76<]9%l~k }f.e`|+ekcq%yhR~ats]dg959:91^<"i}f/pe+be&jf`t"|k_qlwvZad4=49<6[?/fpe*w`(ojr%oaew/sf\tkruWni793<?;T2,cw`)zo%lou lljz,vaYwf}xTkn29>328Q5)`zo$yj"ilx/aoo})ulVzexQhc=5=65=R8&myj#|i/fa{*fjlp&xoS}`{r^e`8=8582_;#j|i.sd,cf~)keas#jPpovq[be;17;m7X> gsd-vc)`kq$h`fv re]sjqtXojU;=k5Z0.eqb+ta'nis"nbdx.pg[uhszVmhS<?i;T2,cw`)zo%lou lljz,vaYwf}xTknQ=1g9V4*aun'xm#jmw.bnh|*tcWyd~Ril_23e?P6(o{l%~k!hcy,`hn~(zmU{by|Pgb]75c=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[07a3\:$kh!rg-dg}(ddbr$~iQnup\cfY19o1^<"i}f/pe+be&jf`t"|k_qlwvZadW>;m7X> gsd-vc)`kq$h`fv re]sjqtXojU3=k5Z0.eqb+ta'nis"nbdx.pg[uhszVmhS4<9;T2,cw`)zo%lou lljz,vaYwf}xTknQnssgd8585>2_;#j|i.sd,cf~)keas#jPpovq[beXizxnk1?1279V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqab:56;<0Y=!hrg,qb*adp'iggu!}d^rmpwY`kVkx~hi33?05?P6(o{l%~k!hcy,`hn~(zmU{by|Pgb]bwwc`4=49:6[?/fpe*w`(ojr%oaew/sf\tkruWniTm~|jg=7=63=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumn6=2?84U1-dvc(un&mht#mcky-q`Zvi|{UloRo|rde?3;413\:$kh!rg-dg}(ddbr$~iQnup\cfYf{{ol050=6:W3+bta&{l$knv!cmi{+wbXxg~ySjmParpfc9?9:<1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQ?249V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabY6:<1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQ=249V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabY4:<1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQ;249V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabY2:<1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQ9249V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabY0:<1^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQ7249V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabY>:01^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQk1=3=6<=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumnUo=1<1289V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabYc9595>45Z0.eqb+ta'nis"nbdx.pg[uhszVmhSl}}ef]g5929:01^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQk1=7=6<=R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumnUo=181289V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabYc95=5>45Z0.eqb+ta'nis"nbdx.pg[uhszVmhSl}}ef]g59>9:01^<"i}f/pe+be&jf`t"|k_qlwvZadWhyyijQk1=;=6==R8&myj#|i/fa{*fjlp&xoS}`{r^e`[duumnUo=R?=8:W3+bta&{l$knv!cmi{+wbXxg~ySjmParpfcZb6W;837X> gsd-vc)`kq$h`fv re]sjqtXojUjkh_e3\77><]9%l~k }f.e`|+ekcq%yhR~ats]dgZgtzlmTh<Q;299V4*aun'xm#jmw.bnh|*tcWyd~Ril_`qqabYc9V?946[?/fpe*w`(ojr%oaew/sf\tkruWniTm~|jg^f2[34?3\:$kh!rg-dg}(ddbr$~iQnup\cfYf{{olSi?P73:8Q5)`zo$yj"ilx/aoo})ulVzexQhc^cpv`aXl8U3>55Z0.eqb+ta'nis"nbdx.pg[uhszVmhSl}}ef]g5Z?5=2_;#j|i.sd,cf~)keas#jPpovq[beXpfx;<=>=5:W3+bta&{l$knv!cmi{+wbXxg~ySjmPxnp34575=2_;#j|i.sd,cf~)keas#jPpovq[beXpfx;<=<=5:W3+bta&{l$knv!cmi{+wbXxg~ySjmPxnp34555=2_;#j|i.sd,cf~)keas#jPpovq[beXpfx;<=:=5:W3+bta&{l$knv!cmi{+wbXxg~ySjmPxnp34535=2_;#j|i.sd,cf~)keas#jPpovq[beXpfx;<=8=5:W3+bta&{l$knv!cmi{+wbXxg~ySjmPxnp34515=2_;#j|i.sd,cf~)keas#jPpovq[beXpfx;<=6=1:W3+bta&{l$knv!cmi{+rtXxg~ySoga<1<15>S7'nxm"h gbz-gim'~xT|cz}_ckm848592_;#j|i.sd,cf~)keas#z|Ppovq[goi4;49=6[?/fpe*w`(ojr%oaew/vp\tkruWkce0>0=1:W3+bta&{l$knv!cmi{+rtXxg~ySoga<5<15>S7'nxm"h gbz-gim'~xT|cz}_ckm808592_;#j|i.sd,cf~)keas#z|Ppovq[goi4?49=6[?/fpe*w`(ojr%oaew/vp\tkruWkce0:0=1:W3+bta&{l$knv!cmi{+rtXxg~ySoga<9<14>S7'nxm"h gbz-gim'~xT|cz}_ckm[5473\:$kh!rg-dg}(ddbr${Qnup\flhX9;:0Y=!hrg,qb*adp'iggu!xr^rmpwYeagU9>=5Z0.eqb+ta'nis"nbdx.uq[uhszVhbbR==0:W3+bta&{l$knv!cmi{+rtXxg~ySoga_503?P6(o{l%~k!hcy,`hn~({U{by|Pbhl\176<]9%l~k }f.e`|+ekcq%|~R~ats]amkY1:91^<"i}f/pe+be&jf`t"y}_qlwvZdnfV=9<6[?/fpe*w`(ojr%oaew/vp\tkruWkceS5<9;T2,cw`)zo%lou lljz,swYwf}xTnd`Pxnp34565?2_;#j|i.sd,cf~)keas#z|Ppovq[goiWqey<=>?1348Q5)`zo$yj"ilx/aoo})pzVzexQmio]{kw67888<7X> gsd-vc)`kq$h`fv ws]sjqtXj`dTtb|?013263=R8&myj#|i/fa{*fjlp&}yS}`{r^`jjZ~hz9:;>?94U1-dvc(un&mht#mcky-tvZvi|{UiecQwos234775>2_;#j|i.sd,cf~)keas#z|Ppovq[goiWqey<=><269V4*aun'xm#jmw.bnh|*quWyd~Rlfn^zlv567;;8=7X> gsd-vc)`kq$h`fv ws]sjqtXj`dTtb|?01613>S7'nxm"h gbz-gim'~xT|cz}_ckm[}iu89:?=?84U1-dvc(un&mht#mcky-tvZvi|{UiecQwos2340403\:$kh!rg-dg}(ddbr${Qnup\flhXpfx;<=;>279V4*aun'xm#jmw.bnh|*quWyd~Rlfn^zlv567>;20Y=!hrg,qb*adp'iggu!xr^rmpwYeagUsc>?073262=R8&myj#|i/fa{*fjlp&}yS}`{r^`jjZ~hz9:;:?<m;T2,cw`)zo%lou lljz,swYwf}xTnd`Pxnp3450Xjmn;>;5Z0.eqb+ta'nis"nbdx.uq[uhszVhbbRv`r123371<]9%l~k }f.e`|+ekcq%|~R~ats]amkYg{:;<:?=0:W3+bta&{l$knv!cmi{+rtXxg~ySjm30?03?P6(o{l%~k!hcy,`hn~({U{by|Pgb>2:76<]9%l~k }f.e`|+ekcq%|~R~ats]dg949:91^<"i}f/pe+be&jf`t"y}_qlwvZad4:49<6[?/fpe*w`(ojr%oaew/vp\tkruWni783<?;T2,cw`)zo%lou lljz,swYwf}xTkn2:>328Q5)`zo$yj"ilx/aoo})pzVzexQhc=4=65=R8&myj#|i/fa{*fjlp&}yS}`{r^e`828582_;#j|i.sd,cf~)keas#z|Ppovq[be;07;m7X> gsd-vc)`kq$h`fv ws]sjqtXojU;=k5Z0.eqb+ta'nis"nbdx.uq[uhszVmhS<?i;T2,cw`)zo%lou lljz,swYwf}xTknQ=1g9V4*aun'xm#jmw.bnh|*quWyd~Ril_23e?P6(o{l%~k!hcy,`hn~({U{by|Pgb]75c=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[07a3\:$kh!rg-dg}(ddbr${Qnup\cfY19o1^<"i}f/pe+be&jf`t"y}_qlwvZadW>;m7X> gsd-vc)`kq$h`fv ws]sjqtXojU3>;5Z0.eqb+ta'nis"nbdx.uq[uhszVmhSl}}ef>3:70<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlm7=3<9;T2,cw`)zo%lou lljz,swYwf}xTknQnssgd8785>2_;#j|i.sd,cf~)keas#z|Ppovq[beXizxnk1=1279V4*aun'xm#jmw.bnh|*quWyd~Ril_`qqab:36;<0Y=!hrg,qb*adp'iggu!xr^rmpwY`kVkx~hi35?05?P6(o{l%~k!hcy,`hn~({U{by|Pgb]bwwc`4?49:6[?/fpe*w`(ojr%oaew/vp\tkruWniTm~|jg=5=63=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[duumn632?;4U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\473<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmT=?;4U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\673<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmT??;4U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\073<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmT9?;4U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\273<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmT;?;4U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\<7?<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmTh<2?>3;8Q5)`zo$yj"ilx/aoo})pzVzexQhc^cpv`aXl86:2?74U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\`4:56;30Y=!hrg,qb*adp'iggu!xr^rmpwY`kVkx~hiPd0>0:7?<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmTh<2;>3;8Q5)`zo$yj"ilx/aoo})pzVzexQhc^cpv`aXl86>2?74U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\`4:16;30Y=!hrg,qb*adp'iggu!xr^rmpwY`kVkx~hiPd0>4:7?<]9%l~k }f.e`|+ekcq%|~R~ats]dgZgtzlmTh<27>3:8Q5)`zo$yj"ilx/aoo})pzVzexQhc^cpv`aXl8U;>55Z0.eqb+ta'nis"nbdx.uq[uhszVmhSl}}ef]g5Z7502_;#j|i.sd,cf~)keas#z|Ppovq[beXizxnkRj>_30;?P6(o{l%~k!hcy,`hn~({U{by|Pgb]bwwc`Wm;T??64U1-dvc(un&mht#mcky-tvZvi|{UloRo|rde\`4Y3:11^<"i}f/pe+be&jf`t"y}_qlwvZadWhyyijQk1^71<>S7'nxm"h gbz-gim'~xT|cz}_fa\evtboVn:S;<7;T2,cw`)zo%lou lljz,swYwf}xTknQnssgd[a7X?;20Y=!hrg,qb*adp'iggu!xr^rmpwY`kVkx~hiPd0];60=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[}iu89:;>85Z0.eqb+ta'nis"nbdx.uq[uhszVmhSua}012260=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[}iu89:9>85Z0.eqb+ta'nis"nbdx.uq[uhszVmhSua}012060=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[}iu89:?>85Z0.eqb+ta'nis"nbdx.uq[uhszVmhSua}012660=R8&myj#|i/fa{*fjlp&}yS}`{r^e`[}iu89:=>85Z0.eqb+ta'nis"nbdx.uq[uhszVmhSua}012475=R8&myj#|i/fn3*wb(o{;%~kyit.Onq}YUIDUYHRKA_GUEP775n2_;#j|i.sd,ci6)zm%l~< }fvdw+HkrpVXJAR\JGNWW[@H69;n0Y=!hrg,qb*ak8'xo#j|>.sdtbq)d}{xTjzh{_rvbp`:76;n0Y=!hrg,qb*ak8'xo#j|>.sdtbq)d}{xTjzh{_rvbp`:66;i0Y=!hrg,qb*ak8'xo#j|>.sdtbq)d}{xTjzh{_rvbp`Y7:j1^<"i}f/pe+bj7&{n$k?!rguep*erz{Um{kzPsucwaZ74=2_;#j|i.sd,ci6)zm%l~< }fvdw+fsuzVl|jyQ|t`vf[hs89::0=0<6:W3+bta&{l$ka>!re-dv4(un~l#n{}r^dtbqYt|h~nS`{w01228586;<1^<"i}f/pe+bj7&{n$k?!rguep*erz{Um{kzPsucwaZkrp9:;=1?1379V4*aun'xm#jb?.sf,cw7)zo}mx"mzrs]escrX{}kiRczx12359799;20Y=!hrg,qb*ak8'xo#j|>.sdtbq)bey~rSkyit^da62=R8&myj#|i/fn3*wb(o{;%~kyit.gntqXn~lSd<i;T2,cw`)zo%l`= }d.eq5+tao~$i`~{y^dtbqYnWds<=>?319V4*aun'xm#jb?.sf,cw7)zo}mx"kbpu{\br`sW`Ufyu>?0131=>S7'nxm"h gm2-va)`zhy%~~z|/b2,gdtuqgo0=0=9:W3+bta&{l$ka>!re-dvdu)zz~x#n> c`pq}kcs484956[?/fpe*w`(oe:%~i!hr`q-vvrt'j:$ol|}yogw878512_;#j|i.sd,ci6)zm%l~l}!rrvp+f6(khxyuck{<2<1b>S7'nxm"h gm2-va)`zhy%~~z|/b2,chs&ngP<P hm0,n57`<]9%l~k }f.eo4+tc'nxj#||tr-`4*aj}q$laV?R.fop*hu5n2_;#j|i.sd,ci6)zm%l~l}!rrvp+f6(ods"jcT2\,div(j{;l0Y=!hrg,qb*ak8'xo#j|ns/pppv)d8&mfyu hmZ1^*bkt&dy9j6[?/fpe*w`(oe:%~i!hr`q-vvrt'j:$k`{w.foX0X(`ez$f?=4U1-dvc(un&mg<#|k/fpbw+tt|z%h<"x><1<17>S7'nxm"h gm2-va)`zhy%~~z|/b2,r4:66;90Y=!hrg,qb*ak8'xo#j|ns/pppv)d8&|:0?0=3:W3+bta&{l$ka>!re-dvdu)zz~x#n> v0>0:75<]9%l~k }f.eo4+tc'nxj#||tr-`4*p64=49n6[?/fpe*w`(oe:%~i!hr`q-vvrt'j:$z<Q?_`lg45679;h0Y=!hrg,qb*ak8'xo#j|ns/pppv)d8&|:S<Qnne234575j2_;#j|i.sd,ci6)zm%l~l}!rrvp+f6(~8U9Sl`k012357d<]9%l~k }f.eo4+tc'nxj#||tr-`4*p6W:Ujbi>?0131f>S7'nxm"h gm2-va)`zhy%~~z|/b2,r4Y3Whdo<=>?13;8Q5)`zo$yj"ic0/pg+btf{'xxx~!l1.abvwim}6;2?74U1-dvc(un&mg<#|k/fpbw+tt|z%h="mnrs{maq:66;30Y=!hrg,qb*ak8'xo#j|ns/pppv)d9&ij~waeu>1:7?<]9%l~k }f.eo4+tc'nxj#||tr-`5*efz{seiy2<>3d8Q5)`zo$yj"ic0/pg+btf{'xxx~!l1.enq}(`eR:V"jc>.l31b>S7'nxm"h gm2-va)`zhy%~~z|/b3,chs&ngP=P hmr,nw7`<]9%l~k }f.eo4+tc'nxj#||tr-`5*aj}q$laV<R.fop*hu5n2_;#j|i.sd,ci6)zm%l~l}!rrvp+f7(ods"jcT3\,div(j{;l0Y=!hrg,qb*ak8'xo#j|ns/pppv)d9&mfyu hmZ6^*bkt&dy9?6[?/fpe*w`(oe:%~i!hr`q-vvrt'j;$z<2?>318Q5)`zo$yj"ic0/pg+btf{'xxx~!l1.t28485;2_;#j|i.sd,ci6)zm%l~l}!rrvp+f7(~8692?=4U1-dvc(un&mg<#|k/fpbw+tt|z%h="x><2<17>S7'nxm"h gm2-va)`zhy%~~z|/b3,r4:36;h0Y=!hrg,qb*ak8'xo#j|ns/pppv)d9&|:S=Qnne234575j2_;#j|i.sd,ci6)zm%l~l}!rrvp+f7(~8U:Sl`k012357d<]9%l~k }f.eo4+tc'nxj#||tr-`5*p6W;Ujbi>?0131f>S7'nxm"h gm2-va)`zhy%~~z|/b3,r4Y4Whdo<=>?13`8Q5)`zo$yj"ic0/pg+btf{'xxx~!l1.t2[1Yffm:;<=?=0:W3+bta&{l$ka>!re-dvdu)zz~x#nabp103?P6(o{l%~k!hl1,q`*auiz$yy} cnos57?<]9%l~k }f.eo4+tc'nxj#||tr-qehYbey~rSklPi228Q5)`zo$yj"ic0/pg+btf{'xxx~!}al]fiur~WohTeRa}012374=R8&myj#|i/fn3*wb(o{kx"}{s.pbiZcjx}sTjoQf_np34566::1^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~by<;;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw572<]9%l~k }f.eo4+tc'{zex!BcnwmpZeh}g~9>95Z0.eqb+ta'nf;"j rqlwv*Kdg|dSnaznu110>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|=8?7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{5368Q5)`zo$yj"ic0/pg+wvi|{%Fob{at^alqkr1:=1^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~by9=4:W3+bta&{l$ka>!re-qtkru'DidyczPcnwmp=433\:$kh!rg-dh5(ul&x{by| MbmvjqYdg|d5?74U1-dvc(un&mg<#|k/srmpw)JkfexRm`uov\g|:76;i0Y=!hrg,qb*ak8'xo#~ats-Ngjsi|VidyczPcx>3:Zts:01^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~byQly=3=6f=R8&myj#|i/fn3*wb(zyd~"Clotlw[firf}Uhu1?1_sv1=>S7'nxm"h gm2-va)uxg~y#@m`uov\gjsi|Vir0?0=c:W3+bta&{l$ka>!re-qtkru'DidyczPcnwmpZe~4;4T~y<6;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw[f;;78h7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{_b{?7;Yu|;30Y=!hrg,qb*ak8'xo#~ats-Ngjsi|VidyczPcx>7:7e<]9%l~k }f.eo4+tc'{zex!BcnwmpZeh}g~Tot2;>^pw6<=R8&myj#|i/fn3*wb(zyd~"Clotlw[firf}Uhu1;12b9V4*aun'xm#jb?.sf,vuhsz&Ghcx`{_bmvjqYdq5?5Sz=9:W3+bta&{l$ka>!re-qtkru'DidyczPcnwmpZe~4?49o6[?/fpe*w`(oe:%~i!}povq+Heh}g~Tob{at^az838Xz}827X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{_b{?3;4d3\:$kh!rg-dh5(ul&x{by| MbmvjqYdg|dSnw37?]qp7?<]9%l~k }f.eo4+tc'{zex!BcnwmpZeh}g~Tot27>3a8Q5)`zo$yj"ic0/pg+wvi|{%Fob{at^alqkrXkp632R|{2`9V4*aun'xm#jb?.sf,vuhsz&Ghcx`{_bmvjqYg{6;2?o4U1-dvc(un&mg<#|k/srmpw)JkfexRm`uov\|jt;978j7X> gsd-vc)`d9$yh"|nup,Ifirf}Uhcx`{_ymq8785i2_;#j|i.sd,ci6)zm%y|cz}/LalqkrXkfexRv`r=1=6d=R8&myj#|i/fn3*wb(zyd~"Clotlw[firf}Usc2;>3c8Q5)`zo$yj"ic0/pg+wvi|{%Fob{at^alqkrXpfx793<n;T2,cw`)zo%l`= }d.psjqt(Eje~byQlotlw[}iu4?49m6[?/fpe*w`(oe:%~i!}povq+Heh}g~Tob{at^zlv919:h1^<"i}f/pe+bj7&{n$~}`{r.O`kphsWje~byQwos>;:7g<]9%l~k }f.eo4+tc'{zex!BcnwmpZeh}g~Ttb|39?0g?P6(o{l%~k!hl1,q`*twf}x$Anaznu]`kphsWqey040Pru3e?P6(o{l%~k!hl1,q`*twf}x$ob{at=2=5c=R8&myj#|i/fn3*wb(zyd~"m`uov?5;7a3\:$kh!rg-dh5(ul&x{by| cnwmp9499o1^<"i}f/pe+bj7&{n$~}`{r.alqkr;;7;m7X> gsd-vc)`d9$yh"|nup,gjsi|5>5=k5Z0.eqb+ta'nf;"j rqlwv*eh}g~793?i;T2,cw`)zo%l`= }d.psjqt(kfex1811g9V4*aun'xm#jb?.sf,vuhsz&idycz37?3e?P6(o{l%~k!hl1,q`*twf}x$ob{at=:=5c=R8&myj#|i/fn3*wb(zyd~"m`uov?=;7b3\:$kh!rg-dh5(ul&x{by| cnwmpZ66m2_;#j|i.sd,ci6)zm%y|cz}/bmvjqY69l1^<"i}f/pe+bj7&{n$~}`{r.alqkrX:8o0Y=!hrg,qb*ak8'xo#~ats-`kphsW:;n7X> gsd-vc)`d9$yh"|nup,gjsi|V>:i6[?/fpe*w`(oe:%~i!}povq+firf}U>=h5Z0.eqb+ta'nf;"j rqlwv*eh}g~T:<k4U1-dvc(un&mg<#|k/srmpw)dg|dS:?j;T2,cw`)zo%l`= }d.psjqt(kfexR6>e:W3+bta&{l$ka>!re-qtkru'je~byQ6239V4*aun'xm#jb?.sf,vuhsz&idyczPd0>3:74<]9%l~k }f.eo4+tc'{zex!lotlw[a7;97897X> gsd-vc)`d9$yh"|nup,gjsi|Vn:0?0=2:W3+bta&{l$ka>!re-qtkru'je~byQk1=1=67=R8&myj#|i/fn3*wb(zyd~"m`uov\`4:36;80Y=!hrg,qb*ak8'xo#~ats-`kphsWm;793<=;T2,cw`)zo%l`= }d.psjqt(kfexRj><7<16>S7'nxm"h gm2-va)uxg~y#naznu]g5919:;1^<"i}f/pe+bj7&{n$~}`{r.alqkrXl8632?<4U1-dvc(un&mg<#|k/srmpw)dg|dSi?39?02?P6(o{l%~k!hl1,q`*twf}x$ob{at^f2[5463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W88:7X> gsd-vc)`d9$yh"|nup,gjsi|Vn:S?<>;T2,cw`)zo%l`= }d.psjqt(kfexRj>_202?P6(o{l%~k!hl1,q`*twf}x$ob{at^f2[1463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W<8:7X> gsd-vc)`d9$yh"|nup,gjsi|Vn:S;<>;T2,cw`)zo%l`= }d.psjqt(kfexRj>_602?P6(o{l%~k!hl1,q`*twf}x$ob{at^f2[=463\:$kh!rg-dh5(ul&x{by| cnwmpZb6W08?7X> gsd-vc)`d9$yh"|nup,gjsi|Vddx=>?13;8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.abvwim}6;2?74U1-dvc(un&mg<#y}/fubw+qt|z%h="mnrs{maq:66;30Y=!hrg,qb*ak8'}y#jyns/uppv)d9&ij~waeu>1:7?<]9%l~k }f.eo4+qu'n}j#y|tr-`5*efz{seiy2<>3d8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.enq}(`eR:V"jc>.l31b>S7'nxm"h gm2-sw)`hy%{~z|/b3,chs&ngP=P hmr,nw7`<]9%l~k }f.eo4+qu'n}j#y|tr-`5*aj}q$laV<R.fop*hu5n2_;#j|i.sd,ci6){%l{l}!wrvp+f7(ods"jcT3\,div(j{;l0Y=!hrg,qb*ak8'}y#jyns/uppv)d9&mfyu hmZ6^*bkt&dy9?6[?/fpe*w`(oe:%{!hw`q-svrt'j;$z<2?>318Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.t28485;2_;#j|i.sd,ci6){%l{l}!wrvp+f7(~8692?=4U1-dvc(un&mg<#y}/fubw+qt|z%h="x><2<17>S7'nxm"h gm2-sw)`hy%{~z|/b3,r4:36;h0Y=!hrg,qb*ak8'}y#jyns/uppv)d9&|:S=Qnne234575j2_;#j|i.sd,ci6){%l{l}!wrvp+f7(~8U:Sl`k012357d<]9%l~k }f.eo4+qu'n}j#y|tr-`5*p6W;Ujbi>?0131f>S7'nxm"h gm2-sw)`hy%{~z|/b3,r4Y4Whdo<=>?13`8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l1.t2[1Yig}:;<=?=9:W3+bta&{l$ka>!ws-dsdu)z~x#n< c`pq}kcs494956[?/fpe*w`(oe:%{!hw`q-svrt'j8$ol|}yogw848512_;#j|i.sd,ci6){%l{l}!wrvp+f4(khxyuck{<3<1=>S7'nxm"h gm2-sw)`hy%{~z|/b0,gdtuqgo0>0=f:W3+bta&{l$ka>!ws-dsdu)z~x#n< glw{*bk\8T$la< b13d8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.enq}(`eR;V"jc|.lq1b>S7'nxm"h gm2-sw)`hy%{~z|/b0,chs&ngP>P hmr,nw7`<]9%l~k }f.eo4+qu'n}j#y|tr-`6*aj}q$laV=R.fop*hu5n2_;#j|i.sd,ci6){%l{l}!wrvp+f4(ods"jcT4\,div(j{;90Y=!hrg,qb*ak8'}y#jyns/uppv)d:&|:0=0=3:W3+bta&{l$ka>!ws-dsdu)z~x#n< v0>2:75<]9%l~k }f.eo4+qu'n}j#y|tr-`6*p64;49?6[?/fpe*w`(oe:%{!hw`q-svrt'j8$z<2<>318Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.t28185j2_;#j|i.sd,ci6){%l{l}!wrvp+f4(~8U;Sl`k012357d<]9%l~k }f.eo4+qu'n}j#y|tr-`6*p6W8Ujbi>?0131f>S7'nxm"h gm2-sw)`hy%{~z|/b0,r4Y5Whdo<=>?13`8Q5)`zo$yj"ic0/uq+bqf{'}xx~!l2.t2[6Yffm:;<=?=b:W3+bta&{l$ka>!ws-dsdu)z~x#n< v0]7[kis89:;=?>4U1-dvc(un&mg<#y}/fubw+qt|z%hc`~>219V4*aun'xm#jb?.vp,crgt&~y"m`mq01<>S7'nxm"h gm2-sw)`hy%{~z|/scn[cskdVliSd<:;T2,cw`)zo%l`= xr.etev(p{}y$~lcPftno[l4c3\:$kh!rg-dh5(pz&m|m~ xsuq,vdkXn|fgSdQbuy23454b3\:$kh!rg-dh5(pz&m|m~ xsuq,vdkXn|fgSdQbuy234576l2_;#j|i.sd,ci6){%ym`Qxr^gm[l75;2_;#j|i.sd,ci6){%||cz}/LalqkrXkfex?:4U1-dvc(un&mg<#y}/vrmpw)JkfexRm`uov261=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}8986[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at207?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphs<;>0Y=!hrg,qb*ak8'}y#z~ats-Ngjsi|Vidycz:259V4*aun'xm#jb?.vp,suhsz&Ghcx`{_bmvjq05<2_;#j|i.sd,ci6){%||cz}/LalqkrXkfex:<;;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw<7?<]9%l~k }f.eo4+qu'~zex!BcnwmpZeh}g~Tot2?>3a8Q5)`zo$yj"ic0/uq+rvi|{%Fob{at^alqkrXkp6;2R|{289V4*aun'xm#jb?.vp,suhsz&Ghcx`{_bmvjqYdq5;5>n5Z0.eqb+ta'nf;"z| wqlwv*Kdg|dSnaznu]`}979W{~956[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at^az8785k2_;#j|i.sd,ci6){%||cz}/LalqkrXkfexRmv<3<\vq4>3\:$kh!rg-dh5(pz&}{by| MbmvjqYdg|dSnw33?0`?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphsWjs7?3Q}t3;8Q5)`zo$yj"ic0/uq+rvi|{%Fob{at^alqkrXkp6?2?m4U1-dvc(un&mg<#y}/vrmpw)JkfexRm`uov\g|:36Vx>45Z0.eqb+ta'nf;"z| wqlwv*Kdg|dSnaznu]`}939:j1^<"i}f/pe+bj7&~x${}`{r.O`kphsWje~byQly=7=[wr512_;#j|i.sd,ci6){%||cz}/LalqkrXkfexRmv<7<1g>S7'nxm"h gm2-sw)pxg~y#@m`uov\gjsi|Vir0;0Pru0:?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphsWjs7;3<l;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw[f;?7Uyx?o4U1-dvc(un&mg<#y}/vrmpw)JkfexRm`uov\|jt;878j7X> gsd-vc)`d9$|~"ynup,Ifirf}Uhcx`{_ymq8485i2_;#j|i.sd,ci6){%||cz}/LalqkrXkfexRv`r=0=6d=R8&myj#|i/fn3*rt(yd~"Clotlw[firf}Usc2<>3c8Q5)`zo$yj"ic0/uq+rvi|{%Fob{at^alqkrXpfx783<n;T2,cw`)zo%l`= xr.usjqt(Eje~byQlotlw[}iu4<49m6[?/fpe*w`(oe:%{!xpovq+Heh}g~Tob{at^zlv909:h1^<"i}f/pe+bj7&~x${}`{r.O`kphsWje~byQwos>4:7g<]9%l~k }f.eo4+qu'~zex!BcnwmpZeh}g~Ttb|38?0g?P6(o{l%~k!hl1,tv*qwf}x$Anaznu]`kphsWqey050Pru3e?P6(o{l%~k!hl1,tv*qwf}x$ob{at=2=5c=R8&myj#|i/fn3*rt(yd~"m`uov?5;7a3\:$kh!rg-dh5(pz&}{by| cnwmp9499o1^<"i}f/pe+bj7&~x${}`{r.alqkr;;7;m7X> gsd-vc)`d9$|~"ynup,gjsi|5>5=k5Z0.eqb+ta'nf;"z| wqlwv*eh}g~793?i;T2,cw`)zo%l`= xr.usjqt(kfex1811g9V4*aun'xm#jb?.vp,suhsz&idycz37?3e?P6(o{l%~k!hl1,tv*qwf}x$ob{at=:=5`=R8&myj#|i/fn3*rt(yd~"m`uov\44c<]9%l~k }f.eo4+qu'~zex!lotlw[47b3\:$kh!rg-dh5(pz&}{by| cnwmpZ46m2_;#j|i.sd,ci6){%||cz}/bmvjqY49l1^<"i}f/pe+bj7&~x${}`{r.alqkrX<8o0Y=!hrg,qb*ak8'}y#z~ats-`kphsW<;n7X> gsd-vc)`d9$|~"ynup,gjsi|V<:i6[?/fpe*w`(oe:%{!xpovq+firf}U<=h5Z0.eqb+ta'nf;"z| wqlwv*eh}g~T4?<4U1-dvc(un&mg<#y}/vrmpw)dg|dSi?30?01?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f28485:2_;#j|i.sd,ci6){%||cz}/bmvjqYc9585>?5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th<2<>308Q5)`zo$yj"ic0/uq+rvi|{%hcx`{_e3?0;453\:$kh!rg-dh5(pz&}{by| cnwmpZb64<49>6[?/fpe*w`(oe:%{!xpovq+firf}Uo=181239V4*aun'xm#jb?.vp,suhsz&idyczPd0>4:74<]9%l~k }f.eo4+qu'~zex!lotlw[a7;078:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn:S=<>;T2,cw`)zo%l`= xr.usjqt(kfexRj>_002?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f2[7463\:$kh!rg-dh5(pz&}{by| cnwmpZb6W:8:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn:S9<>;T2,cw`)zo%l`= xr.usjqt(kfexRj>_402?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f2[3463\:$kh!rg-dh5(pz&}{by| cnwmpZb6W>8:7X> gsd-vc)`d9$|~"ynup,gjsi|Vn:S5<=;T2,cw`)zo%l`= xr.usjqt(kfexRj=<1<16>S7'nxm"h gm2-sw)pxg~y#naznu]g6979:;1^<"i}f/pe+bj7&~x${}`{r.alqkrXl;692?<4U1-dvc(un&mg<#y}/vrmpw)dg|dSi<33?01?P6(o{l%~k!hl1,tv*qwf}x$ob{at^f18185:2_;#j|i.sd,ci6){%||cz}/bmvjqYc:5?5>?5Z0.eqb+ta'nf;"z| wqlwv*eh}g~Th?29>308Q5)`zo$yj"ic0/uq+rvi|{%hcx`{_e0?3;453\:$kh!rg-dh5(pz&}{by| cnwmpZb54149=6[?/fpe*w`(oe:%{!xpovq+firf}Uo>R>=1:W3+bta&{l$ka>!ws-ttkru'je~byQk2^315>S7'nxm"h gm2-sw)pxg~y#naznu]g6Z4592_;#j|i.sd,ci6){%||cz}/bmvjqYc:V99=6[?/fpe*w`(oe:%{!xpovq+firf}Uo>R:=1:W3+bta&{l$ka>!ws-ttkru'je~byQk2^715>S7'nxm"h gm2-sw)pxg~y#naznu]g6Z0592_;#j|i.sd,ci6){%||cz}/bmvjqYc:V=9=6[?/fpe*w`(oe:%{!xpovq+firf}Uo>R6=4:W3+bta&{l$ka>!ws-ttkru'je~byQaou2344703\:$kh!rg-nah)cg|~Te1>1199V4*aun'xm#`kb/emvpZo;994:46[?/fpe*w`(elg$hb{{_h>25;7?3\:$kh!rg-nah)cg|~Te1?=>0:8Q5)`zo$yj"cjm.flqqYn4895=55Z0.eqb+ta'dof#iazt^k?518602_;#j|i.sd,i`k(lfSd2>5?3;?P6(o{l%~k!bel-gkprXa5;=2<64U1-dvc(un&gna"j`uu]j84199>1^<"i}f/pe+hcj'me~xRg31?34?P6(o{l%~k!bel-gkprXa585=:5Z0.eqb+ta'dof#iazt^k?7;703\:$kh!rg-nah)cg|~Te1:1169V4*aun'xm#`kb/emvpZo;=7;<7X> gsd-vc)jmd%ocxzPi=4=52=R8&myj#|i/lgn+air|Vc7;3?8;T2,cw`)zo%fi`!kotv\m9>99>1^<"i}f/pe+hcj'me~xRg39?35?P6(o{l%~k!bel-gkprXaV:::6[?/fpe*w`(elg$hb{{_h]252=R8&myj#|i/lgn+air|VcT==?8;T2,cw`)zo%fi`!kotv\mZ769>1^<"i}f/pe+hcj'me~xRgP1334?P6(o{l%~k!bel-gkprXaV;8=:5Z0.eqb+ta'dof#iazt^k\51703\:$kh!rg-nah)cg|~TeR?:169V4*aun'xm#`kb/emvpZoX9?;<7X> gsd-vc)jmd%ocxzPi^3453=R8&myj#|i/lgn+air|VcT><84U1-dvc(un&gna"j`uu]j[6713\:$kh!rg-nah)cg|~TeR:>6:W3+bta&{l$ahc dnww[lY29?1^<"i}f/pe+hcj'me~xRgP6048Q5)`zo$yj"cjm.flqqYnW>;=7X> gsd-vc)jmd%ocxzPi^:22>S7'nxm"h mdo,`jssW`U2=45Z0.eqb+ta'dof#iazt^ofi9699h1^<"i}f/pe+hcj'me~xRcjm=33:4g<]9%l~k }f.ofi*bh}}Ufi`2>1?3b?P6(o{l%~k!bel-gkprXelg7=?0>a:W3+bta&{l$ahc dnww[hcj4895=l5Z0.eqb+ta'dof#iazt^ofi97368k0Y=!hrg,qb*kbe&ndyyQbel>21;7f3\:$kh!rg-nah)cg|~Tahc317<2e>S7'nxm"h mdo,`jssWdof0<91189V4*aun'xm#`kb/emvpZkbe5;5=45Z0.eqb+ta'dof#iazt^ofi949901^<"i}f/pe+hcj'me~xRcjm=1=5<=R8&myj#|i/lgn+air|Vgna1:1189V4*aun'xm#`kb/emvpZkbe5?5=45Z0.eqb+ta'dof#iazt^ofi909901^<"i}f/pe+hcj'me~xRcjm=5=5<=R8&myj#|i/lgn+air|Vgna161189V4*aun'xm#`kb/emvpZkbe535;95Z0.eqb+ta'dof#jlb.f`nc+aeenk%bjklc/`nc*dkcVgnaRijndpbpjt(~hfbh#m|ts-qehjhgyQ;Q#|nm/p,w6Yig`dbx#|nm.fsvdk)ly9=t<6!r`o2f>S7'nxm"h mdo,phvXzhgT~iQjn0a8Q5)`zo$yj"cjm.vntZtfeVxoSh`>169V4*aun'xm#ob_sgdkprXmg;o7X> gsd-vc)u{}hgg"|k_sqw[duumn8;7X> gsd-vc)u{}hgg"|k_sqw[duumnUo=?>4U1-dvc(un&xxxobd/sf\vvrXizxnkRj=1b9V4*aun'xm#}{bmi,vaYu{}Uhc`l>d:W3+bta&{l$~~zmlj-q`Ztt|Vidao?>e:W3+bta&{l$~~zmlj-q`Ztt|Vxnk1>11d9V4*aun'xm#}{bmi,vaYu{}Uyij2>>0g8Q5)`zo$yj"||tcnh+wbXzz~T~hi32?3g?P6(o{l%~k!}su`oo*tcW{ySkh_13g?P6(o{l%~k!}su`oo*tcW{ySkh_03g?P6(o{l%~k!}su`oo*tcW{ySkh_33g?P6(o{l%~k!}su`oo*quW{ySl}}ef03?P6(o{l%~k!}su`oo*quW{ySl}}ef]g576<]9%l~k }f.pppgjl'~xT~~zParpfcZb59j1^<"i}f/pe+wusjea${Q}su]`khd6l2_;#j|i.sd,vvredb%|~R||t^alig76m2_;#j|i.sd,vvredb%|~R||t^pfc9699l1^<"i}f/pe+wusjea${Q}su]qab:668n0Y=!hrg,qb*tt|kf`#z|Prrv\v`aX88n0Y=!hrg,qb*tt|kf`#z|Prrv\v`aX9h1^_H\PAMKBWf=R[LXTZD]FBMG0?SED12\BIZQ[YQG0?RCF;2]NNn5XRHVF[HICMVKh7Z\FTD]NKACXJm1\^DZJ_VKGPMYFl2]YEYKPWHFWLZD6l2RB@D@W-YFA$5(6(Z^^N->!1!CPGLO23QEYOT84XRVOMG1<PZ^TKCJ8;YQW[SEDj2RTOB\J_HLEK3=_lkUBhk5Wdi]SvlkQm{ybcc??;Yfn[Hgmg{\n~~g`n028\akXE`dd~[k}shmmg>gkefyShctx`8eikh{}Umyab9;cc`opvc3kkhgx~Pm`phaw5<keao7io{a^alqkr/8 n0hlzn_bmvjq.6!m1omyoPcnwmp-4.l2njxlQlotlw,6/c3mkmRm`uov+0,b<lh~jSnaznu*6-a=ci}kTob{at)4*`>bf|hUhcx`{(6+g?agsiVidycz'8(d8`drfWje~by27:1<4?adn|lxy:6jfn)2*2>bnf!;";6jfn)33-2=cag":=$94dhl+57/03mce$<=&7:fjj-73!>1oec&>5(58`lh/9?#<7iga(05*3>bnf!;3%:5kio*2=,0<l`d#>$94dhl+65/03mce$??&7:fjj-45!>1oec&=3(58`lh/:=#<7iga(37*3>bnf!8=%:5kio*13,1<l`d#>5'8;ekm,7?.>2nbb%=&7:fjj-57!>1oec&<1(58`lh/;;#<7iga(21*3>bnf!9?%:5kio*01,0<l`d#8$84dhl+1,0<l`d#:$84dhl+3,0<l`d#4$84dhl+=,0<l`d7<394dhl?55803mce0<?17:fjj9756>1oec2>3?58`lh;9=4<7iga<07=3>bnf5;=2:5kio>23;1<l`d7=508;ekm84?9>2nbb1?17:fjj9476>1oec2=1?58`lh;:;4<7iga<31=3>bnf58?2:5kio>11;1<l`d7>;08;ekm8719?2nbb1<7>69gmk:517<0hd`32?58`lh;;94<7iga<23=3>bnf5992:5kio>07;1<l`d7?906;ekm863=87=0hd`334<5?aoi4:4=7iga<5<5?aoi4<4=7iga<7<5?aoi4>4=7iga<9<5?aoi404<7iazt)2*3>bh}}":%55kotv+55/?3me~x%?>)99gkpr/9;#37iazt)30-==cg|~#=9'7;emvp-72!11ocxz'17+;?air|!;<%:5kotv+6,1<lf$>'8;emvp-2.?2ndyy&:)69gkpr/> =0hb{{(6+4?air|!2";6j`uu*:-2=cg|~7<364dnww846902ndyy2>1?:8`jss488546j`uu>27;><lf0<:18:flqq:6=720hb{{<04=e>bh}}6:;7>18:flqq:6?7=0hb{{<0<4?air|585;6j`uu>0:2=cg|~78394dnww80803me~x1817:flqq:06>1ocxz38?58`jss40437hjff3ld`0=bey~r>k5iigm\c`hbzh~d~Rx9_0.#\ljnfq*HC_K/Gdlfvdrhz);9"<?l;gkekZ~kfqU>=?v<6^0`hnY4>}e:4>o4fhdl[}jipV?:>u=9_3aooZ51|f;3 kgio^efj`tf|fxTz;Q>,OMMA)HHFL>;=6hffn]{hk~X=88s?;Q=cmi\73rh91&mekaPgdlfvdrhzV|=S<"tc^jbwZoi|Vigg0>#c^jbwZuu{}7; nQ}d^dqat;6$jUnbllce^pppZu~fj7: nQgar]q`Zbf|hUhcx`{=1.`[aoiW~coxe3<6-a\lduX{UomyoPcnwmp86+kVl~`aQil`ep[wusWkg1="l_hosh`kbf}keb`Ptxrf97*dW|ynShcmeeff`Ztbo4:'oRy}_gpfu87+kVxiRj`uu]qwq;6$jU~bik}fmmt[iip59&hSeo|_ntfvcjh4:'oR~}emmb`Zjf|ldhu0>#c^flqqYpam~c1<6#c^opcjhX~hf6=!mPre]gauro58:98!mPesplvZoiblieb`Ptxrf95*dWakxSx`kesdokr;7$jUcm~QnllmppZ`rde7; nQgar]qwq;6$jUomyoPcnwmpZqnl}b65!mPh`q\swYfkb7; nQzsd]fgf;7$jUhc`c`n^aokfm:8%iT{Qncj]okr;7$jUyhR~ats]tmaro58:'oR{|e^dtbqYci}kTob{at<2/gZnf{Vkgab}{_dosp|;7$jUyhRjnt`]`kphsW~coxe3>0-a\kscunee|Saax=1.`[rtXxg~ySzgkti?:(fYwzfmTi`~{y^vzt`;7$jU|~Rjnt`]`kphsW~coxe36,b]sv`jhimUyij}21-a\`jssW{yS{oc=1.`[mgtWmkmRm`uov>4)eXx{elSk{cl^vkv`uoWgolmykPv`n>15>+kV}ySikti?657*dWyxdkRkbpu{\pmtb{aUeijo{e^tbh83+kVzycjQjmqvz[qnumzbTm~}jru]uei;3$jUcm~Qyamkg95*dWyxdkRhzlm]wlwct`Vkxh|{_wco906>$jef|b`jnu]mehc:n`ldSubax^726}51W;iggR=9tn3;(fYqiecoSaax=1.`[utneVlbjbQ{yqg>144;?&hS}|`g^dvhiYsqyo6<!mPmdolv|Ysqyo6=!s<6:djbjYdgrT9<<w37]1gimX;?~d=5Qiigm\c`hbzh~d~Rx9_0]{wqY6<2l~`aj4iohfgqbea}oy~i5fnkg`pvdn|lxy;6gat^aoo==iojh~eaj7;ntfvcjhh1{~biPelrw}42<x{elShctx]wlwct`!:"=95rne\ahvsqV~c~h}g(0+20>vugnUna}zv_ujqavn/: ;?7}|`g^gntqX|axne&<)068twi`Wlg{xtQ{hsgpl-2.9=1{~biPelrw}Zrozlyc$8'>4:rqkbYbey~rSyf}erj+2,733yxdkRkbpu{\pmtb{a"<%<:4psmd[`kw|pUdk|h):*51=wzfmTi`~{y^vkv`uo 0#::6~}of]fiur~W}byi~f39;2=5g=wzfmTi`~{y^vkv`uoWhyxiz'0(3a?uthoVof|ywPtipfwmYf{zoyx%?&1c9svjaXmdzuRzgrdqk[dutm{~#>$?m;qplcZcjx}sTxe|jsi]bwvcu|!9"=o5rne\ahvsqV~c~h}g_`qpawr/< ;i7}|`g^gntqX|axneQnsrgqp-3.9k1{~biPelrw}ZrozlycSl}|esv+2,7e3yxdkRkbpu{\pmtb{aUj~k}t)5*5g=wzfmTi`~{y^vkv`uoWhyxiz'8(3a?uthoVof|ywPtipfwmYf{zoyx%7&1e9svjaXmdzuRzgrdqk[dutm{~757>11c9svjaXmdzuRzgrdqk[kc`i}o#<$?m;qplcZcjx}sTxe|jsi]mabgsm!;"=o5rne\ahvsqV~c~h}g_ogdeqc/: ;i7}|`g^gntqX|axneQaefcwa-5.9k1{~biPelrw}ZrozlycSckhaug+0,7e3yxdkRkbpu{\pmtb{aUeijo{e)7*5g=wzfmTi`~{y^vkv`uoWgolmyk'6(3a?uthoVof|ywPtipfwmYimnki%9&1c9svjaXmdzuRzgrdqk[kc`i}o#4$?m;qplcZcjx}sTxe|jsi]mabgsm!3"=i5rne\ahvsqV~c~h}g_ogdeqc;13:556~}of]eqij6;2zycjQiumn\pmtb{a";%<=4psmd[cskdV~c~h}g(0+27>vugnUmyabPtipfwm.5!890|ah_gwohZrozlyc$>'>3:rqkbYa}efTxe|jsi*7-45<x{elSk{cl^vkv`uo <#:?6~}of]eqijX|axne&9)018twi`Wog`Rzgrdqk,2/6;2zycjQiumn\pmtb{a"3%<;4psmd[cskdV~c~h}g<983:4g<x{elSk{cl^vkv`uoWhyxiz'0(3b?uthoVl~`aQ{hsgplZgt{lx$<'>a:rqkbYa}efTxe|jsi]bwvcu|!8"=l5rne\bpjkW}byi~fParqfvq.4!8k0|ah_gwohZrozlycSl}|esv+0,7f3yxdkRhzlm]wlwct`Vkxh|{(4+2e>vugnUmyabPtipfwmYf{zoyx%8&1`9svjaXn|fgSyf}erj\evubz}"<%<o4psmd[cskdV~c~h}g_`qpawr/0 ;h7}|`g^dvhiYs`{oxdRo|sdpw8=<768k0|ah_gwohZrozlycSckhaug+4,7f3yxdkRhzlm]wlwct`Vdnklzj(0+2e>vugnUmyabPtipfwmYimnki%<&1`9svjaXn|fgSyf}erj\j`af|l"8%<o4psmd[cskdV~c~h}g_ogdeqc/< ;j7}|`g^dvhiYs`{oxdR`jg`vf,0/6i2zycjQiumn\pmtb{aUeijo{e)4*5d=wzfmTjxbc_ujqavnXflmjxh&8)0c8twi`Wog`Rzgrdqk[kc`i}o#4$?l;qplcZ`rdeUdk|h^lfcdrb410;2;5}d^aoo46<zmUomyoPcnwmp-6.991yhRjnt`]`kphs 8#:<6|k_ecweZeh}g~#>$??;sf\`drfWje~by&<)028vaYci}kTob{at)6*55=ulVnjxlQlotlw,0/682xoSio{a^alqkr/> ;;7jPd`vb[firf}"<%<>4re]geqgXkfex%6&119q`Zbf|hUhcx`{(8+24>tcWmkmRm`uov?4;753{nThlzn_bmvjq:>294>7jPeo48vaYu{}90~~z8;r`jp`tu<2yyy:4tswf=>sillxm`by:;wcoma0<{Ujof84ws]`hn773~xThlzn_bmvjq.7!8:0{Qkauc\gjsi|!;"==5xr^fbpdYdg|d$?'>0:uq[agsiVidycz'3(33?rtXlh~jSnaznu*7-46<{UomyoPcnwmp-3.991|~Rjnt`]`kphs ?#:<6y}_ecweZeh}g~#;$??;vp\`drfWje~by&7)008swYci}kTob{at=:94;3<{Unb;5xr^pppxFGxh<>7MNw1;D90?7|[=l188;57;306g0dk398:ljtn2f6>4=i;m<1:6*<d280ga=z[=n188;57;306g0dk398:lj4S00b>107290:??l9cb8073gb3Z>o698?:18277d1kj08?;oi;e66<?6=93;p_9h544793?74:k<ho7=<6`f8rQ7?=3:1=7?517;xW1`=<<?1;7?<2c4`g?54>hn0(>m9:00a?S5c<38py<=<:09v562=82w/=:75199a00>=839o6>4<dzJ0g1=]<<09wk4>7;'5=g=<<20(>j=:574?l2e83:17d:l4;29?j22k3:17b::6;29?l2e13:17d:m2;29?j2413:1(<9m:56b?k70i3:07b:<8;29 41e2=>j7c?8a;38?j24?3:1(<9m:56b?k70i3807b:<6;29 41e2=>j7c?8a;18?j24=3:1(<9m:56b?k70i3>07b:<4;29 41e2=>j7c?8a;78?j24;3:1(<9m:56b?k70i3<07b:<2;29 41e2=>j7c?8a;58?j2393:1(<9m:56b?k70i3207b:;0;29 41e2=>j7c?8a;;8?j24n3:1(<9m:56b?k70i3k07b:<e;29 41e2=>j7c?8a;`8?j24l3:1(<9m:56b?k70i3i07b:<c;29 41e2=>j7c?8a;f8?j24j3:1(<9m:56b?k70i3o07b:<a;29 41e2=>j7c?8a;d8?j2493:1(<9m:56b?k70i3;;76a;3183>!70j3>?m6`>7`825>=n<9>1<7*>7c8762=i9>k1<65f41194?"6?k0?>:5a16c95>=n<981<7*>7c8762=i9>k1>65f41394?"6?k0?>:5a16c97>=n<9:1<7*>7c8762=i9>k1865f3gd94?"6?k0?>:5a16c91>=n;on1<7*>7c8762=i9>k1:65f3ga94?"6?k0?>:5a16c93>=n;oh1<7*>7c8762=i9>k1465f3gc94?"6?k0?>:5a16c9=>=n;o31<7*>7c8762=i9>k1m65f3g:94?"6?k0?>:5a16c9f>=n;o=1<7*>7c8762=i9>k1o65f3g494?"6?k0?>:5a16c9`>=n;o?1<7*>7c8762=i9>k1i65f3g694?"6?k0?>:5a16c9b>=n;o81<7*>7c8762=i9>k1==54i2d2>5<#9>h18?94n05b>47<3`9m<7>5$05a>1403g;<m7?=;:k0ac<72-;<n7:=7:l23d<6;21b?hk50;&23g<3:>1e=:o51598m6cc290/=:l54358j41f28?07d=jc;29 41e2=8<7c?8a;35?>o4mk0;6)?8b;613>h6?h0:;65f3dc94?"6?k0?>:5a16c95==<a:o26=4+16`9071<f8=j6<74;h63e?6=,8=i69<8;o34e?7f32c?<44?:%34f?25?2d:;l4>b:9j05>=83.:;o4;269m52g=9j10e9>8:18'52d=<;=0b<9n:0f8?l27>3:1(<9m:504?k70i3;n76g;0483>!70j3>9;6`>7`82b>=n;oo1<7*>7c8762=i9>k1>=54i2d0>5<#9>h18?94n05b>77<3`9n47>5$05a>1403g;<m7<=;:k0a2<72-;<n7:=7:l23d<5;21b8l=50;9a7f3=83;1<7>tH2a7?!7?i39h96a>7983>>{el10;6<4?:1yK7f2<,82j6i64oe594?=zj=>1<7o::00g>40>sA9h86T;5;35d<>2k09m7<8:3:96<<a28=1o7<m:3c96g<a2j0j6<952881<?402k026p*>8`871g=#<10?945+4d871d=#9>>1=:94i554>5<#9>h18:64n05b>5=<a===6=4+16`902><f8=j6<54i556>5<#9>h18:64n05b>7=<a==?6=4+16`902><f8=j6>54i550>5<#9>h18:64n05b>1=<a==96=4+16`902><f8=j6854i552>5<#9>h18:64n05b>3=<a==;6=4+16`902><f8=j6:54i54e>5<#9>h18:64n05b>==<a=<n6=4+16`902><f8=j6454i57f>5<<a=h:6=44i5`7>5<<g=h<6=44i54`>5<#9>h18;j4n05b>5=<a=<i6=4+16`903b<f8=j6<54i54b>5<#9>h18;j4n05b>7=<a=<26=4+16`903b<f8=j6>54i54;>5<#9>h18;j4n05b>1=<a=<<6=4+16`903b<f8=j6854i545>5<#9>h18;j4n05b>3=<a=<>6=4+16`903b<f8=j6:54i547>5<#9>h18;j4n05b>==<a=<86=4+16`903b<f8=j6454i5`3>5<<g=<:6=44i5:1>5<#9>h185=4n05b>5=<a=2:6=4+16`90=5<f8=j6<54i5:3>5<#9>h185=4n05b>7=<a==m6=4+16`90=5<f8=j6>54i55f>5<#9>h185=4n05b>1=<a==o6=4+16`90=5<f8=j6854i55`>5<#9>h185=4n05b>3=<a==i6=4+16`90=5<f8=j6:54i55b>5<#9>h185=4n05b>==<a==26=4+16`90=5<f8=j6454o2f;>5<<g:o?6=4+16`97`3<f8=j6=54o2g0>5<#9>h1?h;4n05b>4=<g:o96=4+16`97`3<f8=j6?54o2g2>5<#9>h1?h;4n05b>6=<g:o;6=4+16`97`3<f8=j6954o2fe>5<#9>h1?h;4n05b>0=<g:nn6=4+16`97`3<f8=j6;54o2fg>5<#9>h1?h;4n05b>2=<g:nh6=4+16`97`3<f8=j6554o5:7>5<<a=i?6=44i5:g>5<#9>h185k4n05b>5=<a=2h6=4+16`90=c<f8=j6<54i5:a>5<#9>h185k4n05b>7=<a=2j6=4+16`90=c<f8=j6>54i5::>5<#9>h185k4n05b>1=<a=236=4+16`90=c<f8=j6854i5:4>5<#9>h185k4n05b>3=<a=2=6=4+16`90=c<f8=j6:54i5:6>5<#9>h185k4n05b>==<g=?h6=44o575>5<<a=h26=44i2fb>5<<a=3<6=4+16`90<><f8=j6=54i5;5>5<#9>h18464n05b>4=<a=3>6=4+16`90<><f8=j6?54i5;7>5<#9>h18464n05b>6=<a=386=4+16`90<><f8=j6954i5;1>5<#9>h18464n05b>0=<a=3:6=4+16`90<><f8=j6;54i5;3>5<#9>h18464n05b>2=<a=2m6=4+16`90<><f8=j6554i5c2>5<#9>h18l<4n05b>5=<a=k;6=4+16`90d4<f8=j6<54i5;e>5<#9>h18l<4n05b>7=<a=3n6=4+16`90d4<f8=j6>54i5;g>5<#9>h18l<4n05b>1=<a=3h6=4+16`90d4<f8=j6854i5;a>5<#9>h18l<4n05b>3=<a=3j6=4+16`90d4<f8=j6:54i5;:>5<#9>h18l<4n05b>==<g:n<6=44i57e>5<<a:ni6=44i5a6>5<<g=h86=44o5`;>5<<a=h96=44o51:>5<#9>h189o4n05b>5=<g=936=4+16`901g<f8=j6<54o514>5<#9>h189o4n05b>7=<g=9=6=4+16`901g<f8=j6>54o516>5<#9>h189o4n05b>1=<g=9?6=4+16`901g<f8=j6854o510>5<#9>h189o4n05b>3=<g=996=4+16`901g<f8=j6:54o562>5<#9>h189o4n05b>==<g=>;6=4+16`901g<f8=j6454o51e>5<#9>h189o4n05b>d=<g=9n6=4+16`901g<f8=j6o54o51g>5<#9>h189o4n05b>f=<g=9h6=4+16`901g<f8=j6i54o51a>5<#9>h189o4n05b>`=<g=9j6=4+16`901g<f8=j6k54o512>5<#9>h189o4n05b>46<3f>8<7>5$05a>12f3g;<m7?>;:k741<72-;<n7:=7:l23d<732c?<>4?:%34f?25?2d:;l4>;:k747<72-;<n7:=7:l23d<532c?<<4?:%34f?25?2d:;l4<;:k745<72-;<n7:=7:l23d<332c8jk4?:%34f?25?2d:;l4:;:k0ba<72-;<n7:=7:l23d<132c8jn4?:%34f?25?2d:;l48;:k0bg<72-;<n7:=7:l23d<?32c8jl4?:%34f?25?2d:;l46;:k0b<<72-;<n7:=7:l23d<f32c8j54?:%34f?25?2d:;l4m;:k0b2<72-;<n7:=7:l23d<d32c8j;4?:%34f?25?2d:;l4k;:k0b0<72-;<n7:=7:l23d<b32c8j94?:%34f?25?2d:;l4i;:k0b7<72-;<n7:=7:l23d<6821b?k?50;&23g<3:>1e=:o51098m6`7290/=:l54358j41f28807d=jf;29 41e2=8<7c?8a;30?>o4ml0;6)?8b;613>h6?h0:865f3df94?"6?k0?>:5a16c950=<a:oh6=4+16`9071<f8=j6<84;h1ff?6=,8=i69<8;o34e?7032c8il4?:%34f?25?2d:;l4>8:9j7`?=83.:;o4;269m52g=9010e9>n:18'52d=<;=0b<9n:0c8?l2713:1(<9m:504?k70i3;i76g;0983>!70j3>9;6`>7`82g>=n<9=1<7*>7c8762=i9>k1=i54i525>5<#9>h18?94n05b>4c<3`>;97>5$05a>1403g;<m7?i;:k0b`<72-;<n7:=7:l23d<5821b?k=50;&23g<3:>1e=:o52098m6c?290/=:l54358j41f2;807d=j7;29 41e2=8<7c?8a;00?>o4l00;66a;ae83>!70j3>jj6`>7`83?>i3ij0;6)?8b;6bb>h6?h0:76a;ac83>!70j3>jj6`>7`81?>i3ih0;6)?8b;6bb>h6?h0876a;a883>!70j3>jj6`>7`87?>i3i10;6)?8b;6bb>h6?h0>76a;a683>!70j3>jj6`>7`85?>i3i?0;6)?8b;6bb>h6?h0<76a;a483>!70j3>jj6`>7`8;?>i3i=0;6)?8b;6bb>h6?h0276a;c383>!70j3>h?6`>7`83?>i3k80;6)?8b;6`7>h6?h0:76a;c183>!70j3>h?6`>7`81?>i3jo0;6)?8b;6`7>h6?h0876a;bd83>!70j3>h?6`>7`87?>i3jm0;6)?8b;6`7>h6?h0>76a;bb83>!70j3>h?6`>7`85?>i3jk0;6)?8b;6`7>h6?h0<76a;b`83>!70j3>h?6`>7`8;?>i3>;0;66g;5e83>>i4m?0;66g;a283>>i3j?0;66l<d183>4<729q/=5o5d99K7f`<@:i?7bj8:188yg5c93:1=7>50z&2<d<4k<1C?nh4H2a7?j7003:17pl=9c83>1<729q/=5o5d59K7f`<@:i?7)k::79j03<722c><7>5;h34g?6=3f;<h7>5;|`052<72=0;6=u+19c9`7=O;jl0D>m;;%g6>7=n<?0;66g;c;29?l372900c<9k:188yg56>3:187>50z&2<d<c:2B8ok5G3b68 `3=:2c?:7>5;h6`>5<<a<:1<75`16f94?=zj:h:6=4<:183!7?i3n:7E=lf:J0g1=O<:1/=>?54c78 `3=:2c?:7>5;h73>5<<g8=o6=44}c1ag?6=;3:1<v*>8`8g5>N4ko1C?n:4H518 4562=h>7)k::39j03<722c><7>5;n34`?6=3th8n=4?:283>5}#91k1h<5G3bd8L6e33A>87)?<1;6a1>"b=380e9850;9j15<722e:;i4?::a7gg=83?1<7>t$0:b>a3<@:im7E=l4:J77>"6;80?n85f4783>>o3?3:17d;?:188m41d2900c<9k:188yg5ej3:1?7>50z&2<d<c92B8ok5G3b68L15<,89:69l:;%g6>7=n<?0;66g:0;29?j70l3:17pl<ag83>0<729q/=5o5d49K7f`<@:i?7E:<;%305?2e=2c?:7>5;h64>5<<a<:1<75f16a94?=h9>n1<75rb2`:>5<3290;w)?7a;f7?M5dn2B8o95+e485?l212900e8>50;9j52e=831d=:j50;9~f6d?290?6=4?{%3;e?b33A9hj6F<c59'a0<13`>=6=44i4294?=n9>i1<75`16f94?=zj:h<6=4;:183!7?i3n?7E=lf:J0g1=#m<0=7d:9:188m06=831b=:m50;9l52b=831vn>m=:187>5<7s-;3m7j;;I1`b>N4k=1/i849;h65>5<<a<:1<75f16a94?=h9>n1<75rb2a2>5<3290;w)?7a;f7?M5dn2B8o95+e485?l212900e8>50;9j52e=831d=:j50;9~f4gc290?6=4?{%3;e?b53A9hj6F<c59'a0<53`>=6=44i5a94?=n=90;66a>7e83>>{e9hi1<7:50;2x 4>f2m80D>mi;I1`0>"b=380e9850;9j0f<722c><7>5;n34`?6=3th:mo4?:583>5}#91k1h?5G3bd8L6e33-o>6?5f4783>>o3k3:17d;?:188k41c2900qo?na;290?6=8r.:4l4k2:J0gc=O;j>0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0c:>5<3290;w)?7a;f1?M5dn2B8o95+e481?l212900e9m50;9j15<722e:;i4?::a5d>=83>1<7>t$0:b>a4<@:im7E=l4:&f1?4<a=<1<75f4b83>>o283:17b?8d;29?xd6i>0;694?:1y'5=g=l;1C?nh4H2a7?!c22;1b8;4?::k7g?6=3`?;6=44o05g>5<<uk;j:7>54;294~"60h0o>6F<cg9K7f2<,l?1>6g;6;29?l2d2900e8>50;9l52b=831vn<o::187>5<7s-;3m7j=;I1`b>N4k=1/i84=;h65>5<<a=i1<75f5183>>i6?m0;66sm20694?2=83:p(<6n:e08L6ea3A9h86*j5;08m10=831b8n4?::k64?6=3f;<h7>5;|`156<72=0;6=u+19c9`7=O;jl0D>m;;%g6>7=n<?0;66g;c;29?l372900c<9k:188yg46:3:187>50z&2<d<c:2B8ok5G3b68 `3=:2c?:7>5;h6`>5<<a<:1<75`16f94?=zj;;:6=4;:183!7?i3n97E=lf:J0g1=#m<097d:9:188m1e=831b9=4?::m23a<722wi><>50;694?6|,82j6i<4H2ae?M5d<2.n97<4i5494?=n<j0;66g:0;29?j70l3:17pl=0g83>1<729q/=5o5d39K7f`<@:i?7)k::39j03<722c?o7>5;h73>5<<g8=o6=44}c03a?6=<3:1<v*>8`8g6>N4ko1C?n:4$d796>o3>3:17d:l:188m06=831d=:j50;9~f76c290?6=4?{%3;e?b53A9hj6F<c59'a0<53`>=6=44i5a94?=n=90;66a>7e83>>{e:9i1<7:50;2x 4>f2m80D>mi;I1`0>"b=380e9850;9j0f<722c><7>5;n34`?6=3th99n4?:583>5}#91k1h?5G3bd8L6e33-o>6?5f4783>>o3k3:17d;?:188k41c2900qo<:b;290?6=8r.:4l4k2:J0gc=O;j>0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb37b>5<3290;w)?7a;f1?M5dn2B8o95+e481?l212900e9m50;9j15<722e:;i4?::a60?=83>1<7>t$0:b>a4<@:im7E=l4:&f1?4<a=<1<75f4b83>>o283:17b?8d;29?xd5=10;694?:1y'5=g=l;1C?nh4H2a7?!c22;1b8;4?::k7g?6=3`?;6=44o05g>5<<uk8>;7>54;294~"60h0o>6F<cg9K7f2<,l?1>6g;6;29?l2d2900e8>50;9l52b=831vn?;9:187>5<7s-;3m7j=;I1`b>N4k=1/i84=;h65>5<<a=i1<75f5183>>i6?m0;66sm24794?2=83:p(<6n:e08L6ea3A9h86*j5;08m10=831b8n4?::k64?6=3f;<h7>5;|`111<72=0;6=u+19c9`7=O;jl0D>m;;%g6>7=n<?0;66g;c;29?l372900c<9k:188yg7a13:187>50z&2<d<c:2B8ok5G3b68 `3=:2c?:7>5;h6`>5<<a<:1<75`16f94?=zj8l36=4;:183!7?i3n97E=lf:J0g1=#m<097d:9:188m1e=831b9=4?::m23a<722wi=k950;694?6|,82j6i<4H2ae?M5d<2.n97<4i5494?=n<j0;66g:0;29?j70l3:17pl>f783>1<729q/=5o5d39K7f`<@:i?7)k::39j03<722c?o7>5;h73>5<<g8=o6=44}c3e1?6=<3:1<v*>8`8g6>N4ko1C?n:4$d796>o3>3:17d:l:188m06=831d=:j50;9~f4`3290?6=4?{%3;e?b53A9hj6F<c59'a0<53`>=6=44i5a94?=n=90;66a>7e83>>{e9o91<7:50;2x 4>f2m80D>mi;I1`0>"b=380e9850;9j0f<722c><7>5;n34`?6=3th:j?4?:583>5}#91k1h?5G3bd8L6e33-o>6?5f4783>>o3k3:17d;?:188k41c2900qo?i1;290?6=8r.:4l4k2:J0gc=O;j>0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb36b>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb36:>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb36;>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb364>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb365>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb366>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb367>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb360>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb361>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g4>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g5>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g6>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g7>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g0>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g1>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g2>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0g3>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0fe>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0ff>5<3290;w)?7a;f1?M5dn2B8o95G429'567=<k?0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb0f0>5<3290;w)?7a;f1?M5dn2B8o95+e481?l212900e9m50;9j15<722e:;i4?::a5a4=83>1<7>t$0:b>a4<@:im7E=l4:&f1?4<a=<1<75f4b83>>o283:17b?8d;29?xd6l80;694?:1y'5=g=l;1C?nh4H2a7?!c22;1b8;4?::k7g?6=3`?;6=44o05g>5<<uk;o<7>54;294~"60h0o>6F<cg9K7f2<,l?1>6g;6;29?l2d2900e8>50;9l52b=831vn<mi:187>5<7s-;3m7j=;I1`b>N4k=1/i84=;h65>5<<a=i1<75f5183>>i6?m0;66sm1bg94?2=83:p(<6n:e08L6ea3A9h86*j5;08m10=831b8n4?::k64?6=3f;<h7>5;|`2ga<72=0;6=u+19c9`7=O;jl0D>m;;%g6>7=n<?0;66g;c;29?l372900c<9k:188yg7dk3:187>50z&2<d<c:2B8ok5G3b68 `3=:2c?:7>5;h6`>5<<a<:1<75`16f94?=zj8ii6=4;:183!7?i3n97E=lf:J0g1=#m<097d:9:188m1e=831b9=4?::m23a<722wi=no50;694?6|,82j6i<4H2ae?M5d<2.n97<4i5494?=n<j0;66g:0;29?j70l3:17pl=3983>1<729q/=5o5d39K7f`<@:i?7)k::39j03<722c?o7>5;h73>5<<g8=o6=44}c003?6=<3:1<v*>8`8g6>N4ko1C?n:4$d796>o3>3:17d:l:188m06=831d=:j50;9~f751290?6=4?{%3;e?b53A9hj6F<c59'a0<53`>=6=44i5a94?=n=90;66a>7e83>>{e::?1<7:50;2x 4>f2m80D>mi;I1`0>"b=380e9850;9j0f<722c><7>5;n34`?6=3th9?94?:583>5}#91k1h?5G3bd8L6e33-o>6?5f4783>>o3k3:17d;?:188k41c2900qo<<3;290?6=8r.:4l4k2:J0gc=O;j>0(h;52:k72?6=3`>h6=44i4294?=h9>n1<75rb311>5<3290;w)?7a;f1?M5dn2B8o95+e481?l212900e9m50;9j15<722e:;i4?::a667=83>1<7>t$0:b>a4<@:im7E=l4:&f1?4<a=<1<75f4b83>>o283:17b?8d;29?xd5;90;694?:1y'5=g=l;1C?nh4H2a7?!c22;1b8;4?::k7g?6=3`?;6=44o05g>5<<uk8o47>55;294~"60h0o?6F<cg9K7f2<,l?1>6g;6;29?l202900e9m50;9j15<722e:;i4?::a6a1=83?1<7>t$0:b>a5<@:im7E=l4:&f1?4<a=<1<75f4683>>o3k3:17d;?:188k41c2900qo<k5;291?6=8r.:4l4k3:J0gc=O;j>0(h;52:k72?6=3`><6=44i5a94?=n=90;66a>7e83>>{e:m>1<7;50;2x 4>f2m90D>mi;I1`0>"b=380e9850;9j02<722c?o7>5;h73>5<<g8=o6=44}c0g2?6==3:1<v*>8`8g7>N4ko1C?n:4$d796>o3>3:17d:8:188m1e=831b9=4?::m23a<722wi>i=50;794?6|,82j6i=4H2ae?M5d<2.n97<4i5494?=n<>0;66g;c;29?l372900c<9k:188yg4c:3:197>50z&2<d<c;2B8ok5G3b68 `3=:2c?:7>5;h64>5<<a=i1<75f5183>>i6?m0;66sm2e294?3=83:p(<6n:e18L6ea3A9h86*j5;08m10=831b8:4?::k7g?6=3`?;6=44o05g>5<<uk8hj7>55;294~"60h0o96F<cg9K7f2<,l?1:6g;6;29?l202900e8>50;9j52e=831d=:j50;9~f7b6290>6=4?{%3;e?b43A9hj6F<c59'a0<53`>=6=44i5594?=n<j0;66g:0;29?j70l3:17pl=c283>6<729q/=5o53bg8L6ea3A9h86g;9;29?l7503:17b?86;29?xd5k;0;6>4?:1y'5=g=;jo0D>mi;I1`0>o313:17d?=8;29?j70>3:17pl=b983>1<729q/=5o51208L6ea3A9h86g;9;29?l352900e<6<:188k4112900qo<l1;297?6=8r.:4l4<cd9K7f`<@:i?7d:6:188m44?2900c<99:188yg4e>3:187>50z&2<d<6;;1C?nh4H2a7?l2>2900e8<50;9j5=5=831d=:850;9~f7e729086=4?{%3;e?5dm2B8ok5G3b68m1?=831b=?650;9l520=831vn?l;:187>5<7s-;3m7?<2:J0gc=O;j>0e9750;9j17<722c:4>4?::m233<722wi>oh50;194?6|,82j6>mj;I1`b>N4k=1b844?::k26=<722e:;;4?::a6g4=83>1<7>t$0:b>4553A9hj6F<c59j0<<722c>>7>5;h3;7?6=3f;<:7>5;|`1f`<72:0;6=u+19c97fc<@:im7E=l4:k7=?6=3`;947>5;n342?6=3th9n=4?:583>5}#91k1=><4H2ae?M5d<2c?57>5;h71>5<<a8286=44o055>5<<uk8ih7>53;294~"60h08oh5G3bd8L6e33`>26=44i00;>5<<g8==6=44}c0ba?6=<3:1<v*>8`8277=O;jl0D>m;;h6:>5<<a<81<75f19194?=h9><1<75rb3``>5<4290;w)?7a;1`a>N4ko1C?n:4i5;94?=n9;21<75`16494?=zj;kh6=4;:183!7?i3;8>6F<cg9K7f2<a=31<75f5383>>o60:0;66a>7783>>{e:kh1<7=50;2x 4>f2:in7E=lf:J0g1=n<00;66g>2983>>i6??0;66sm2`c94?2=83:p(<6n:011?M5dn2B8o95f4883>>o2:3:17d?73;29?j70>3:17pl=b`83>6<729q/=5o53bg8L6ea3A9h86g;9;29?l7503:17b?86;29?xd5i10;694?:1y'5=g=9:80D>mi;I1`0>o313:17d;=:188m4>42900c<99:188yg4bk3:197>50z&2<d<c;2B8ok5G3b68 `3=:2c?:7>5;h64>5<<a=i1<75f5183>>i6?m0;66sm2d`94?3=83:p(<6n:e18L6ea3A9h86*j5;08m10=831b8:4?::k7g?6=3`?;6=44o05g>5<<uk8nm7>55;294~"60h0o?6F<cg9K7f2<,l?1>6g;6;29?l202900e9m50;9j15<722e:;i4?::a6`?=83?1<7>t$0:b>a5<@:im7E=l4:&f1?4<a=<1<75f4683>>o3k3:17d;?:188k41c2900qo<j8;291?6=8r.:4l4k3:J0gc=O;j>0(h;52:k72?6=3`><6=44i5a94?=n=90;66a>7e83>>{e:l=1<7;50;2x 4>f2m90D>mi;I1`0>"b=380e9850;9j02<722c?o7>5;h73>5<<g8=o6=44}c0f2?6==3:1<v*>8`8g7>N4ko1C?n:4$d796>o3>3:17d:8:188m1e=831b9=4?::m23a<722wi>h;50;794?6|,82j6i=4H2ae?M5d<2.n97<4i5494?=n<>0;66g;c;29?l372900c<9k:188yg4b<3:197>50z&2<d<c;2B8ok5G3b68 `3=:2c?:7>5;h64>5<<a=i1<75f5183>>i6?m0;66sm2d194?3=83:p(<6n:e18L6ea3A9h86*j5;08m10=831b8:4?::k7g?6=3`?;6=44o05g>5<<uk8=j7>54;294~"60h0o86F<cg9K7f2<,l?1:6g;6;29?l372900e<9l:188k41c2900qo<80;290?6=8r.:4l4k4:J0gc=O;j>0(h;56:k72?6=3`?;6=44i05`>5<<g8=o6=44}c05e?6=<3:1<v*>8`8g6>N4ko1C?n:4$d796>o3>3:17d:l:188m06=831d=:j50;9~f70>290?6=4?{%3;e?b53A9hj6F<c59'a0<53`>=6=44i5a94?=n=90;66a>7e83>>{e:1o1<7:50;2x 4>f28997E=lf:J0g1=n<00;66g:2;29?l7?;3:17b?86;29?xd50m0;694?:1y'5=g=9:80D>mi;I1`0>o313:17d;=:188m4>42900c<99:188yg4?k3:187>50z&2<d<6;;1C?nh4H2a7?l2>2900e8<50;9j5=5=831d=:850;9~f7>e290?6=4?{%3;e?74:2B8ok5G3b68m1?=831b9?4?::k2<6<722e:;;4?::a6=g=83>1<7>t$0:b>4553A9hj6F<c59j0<<722c>>7>5;h3;7?6=3f;<:7>5;|`13g<72=0;6=u+19c9564<@:im7E=l4:k7=?6=3`?96=44i0:0>5<<g8==6=44}c04e?6=<3:1<v*>8`8277=O;jl0D>m;;h6:>5<<a<81<75f19194?=h9><1<75rb35:>5<3290;w)?7a;306>N4ko1C?n:4i5;94?=n=;0;66g>8283>>i6??0;66sm26:94?2=83:p(<6n:011?M5dn2B8o95f4883>>o2:3:17d?73;29?j70>3:17pl=7683>1<729q/=5o51208L6ea3A9h86g;9;29?l352900e<6<:188k4112900qo=?9;290?6=8r.:4l4>339K7f`<@:i?7d:6:188m04=831b=5=50;9l520=831vn>>7:187>5<7s-;3m7?<2:J0gc=O;j>0e9750;9j17<722c:4>4?::m233<722wi?=950;694?6|,82j6<==;I1`b>N4k=1b844?::k66?6=3`;3?7>5;n342?6=3th8<;4?:583>5}#91k1=><4H2ae?M5d<2c?57>5;h71>5<<a8286=44o055>5<<uk9;97>54;294~"60h0:??5G3bd8L6e33`>26=44i4094?=n9191<75`16494?=zj;l=6=4;:183!7?i3;8>6F<cg9K7f2<a=31<75f5383>>o60:0;66a>7783>>{e:o?1<7:50;2x 4>f28997E=lf:J0g1=n<00;66g:2;29?l7?;3:17b?86;29?xd5n=0;694?:1y'5=g=9:80D>mi;I1`0>o313:17d;=:188m4>42900c<99:188yg4a;3:187>50z&2<d<6;;1C?nh4H2a7?l2>2900e8<50;9j5=5=831d=:850;9~f7`5290?6=4?{%3;e?74:2B8ok5G3b68m1?=831b9?4?::k2<6<722e:;;4?::a70d=83?1<7>t$0:b>a5<@:im7E=l4:&f1?4<a=<1<75f4683>>o3k3:17d;?:188k41c2900qo=:9;291?6=8r.:4l4k5:J0gc=O;j>0(h;56:k72?6=3`><6=44i4294?=n9>i1<75`16f94?=zj:?j6=4::183!7?i3n87E=lf:J0g1=#m<097d:9:188m11=831b8n4?::k64?6=3f;<h7>5;|`01f<72<0;6=u+19c9`6=O;jl0D>m;;%g6>7=n<?0;66g;7;29?l2d2900e8>50;9l52b=831vn>;k:186>5<7s-;3m7j<;I1`b>N4k=1/i84=;h65>5<<a==1<75f4b83>>o283:17b?8d;29?xd4=l0;684?:1y'5=g=l:1C?nh4H2a7?!c22;1b8;4?::k73?6=3`>h6=44i4294?=h9>n1<75rb27e>5<2290;w)?7a;f0?M5dn2B8o95+e481?l212900e9950;9j0f<722c><7>5;n34`?6=3th8:=4?:483>5}#91k1h>5G3bd8L6e33-o>6?5f4783>>o3?3:17d:l:188m06=831d=:j50;9~f606290>6=4?{%3;e?b43A9hj6F<c59'a0<53`>=6=44i5594?=n<j0;66g:0;29?j70l3:17pl<4g83>0<729q/=5o5d29K7f`<@:i?7)k::39j03<722c?;7>5;h6`>5<<a<:1<75`16f94?=zj:>n6=4::183!7?i3n87E=lf:J0g1=#m<097d:9:188m11=831b8n4?::k64?6=3f;<h7>5;|`00f<72<0;6=u+19c9`6=O;jl0D>m;;%g6>7=n<?0;66g;7;29?l2d2900e8>50;9l52b=831vn>:m:186>5<7s-;3m7j<;I1`b>N4k=1/i84=;h65>5<<a==1<75f4b83>>o283:17b?8d;29?xd4<m0;684?:1y'5=g=l:1C?nh4H2a7?!c22;1b8;4?::k73?6=3`>h6=44i4294?=h9>n1<75rb26b>5<2290;w)?7a;f0?M5dn2B8o95+e481?l212900e9950;9j0f<722c><7>5;n34`?6=3th8844?:483>5}#91k1h>5G3bd8L6e33-o>6?5f4783>>o3?3:17d:l:188m06=831d=:j50;9~f620290>6=4?{%3;e?b43A9hj6F<c59'a0<53`>=6=44i5594?=n<j0;66g:0;29?j70l3:17pl<4983>0<729q/=5o5d49K7f`<@:i?7)k::79j03<722c?;7>5;h73>5<<a8=h6=44o05g>5<<uk98o7>53;294~"60h08oh5G3bd8L6e33`>26=44i00;>5<<g8==6=44}c10f?6=;3:1<v*>8`80g`=O;jl0D>m;;h6:>5<<a8836=44o055>5<<uk98>7>54;294~"60h0:??5G3bd8L6e33`>26=44i4094?=n9191<75`16494?=zj:9j6=4<:183!7?i39hi6F<cg9K7f2<a=31<75f13:94?=h9><1<75rb213>5<3290;w)?7a;306>N4ko1C?n:4i5;94?=n=;0;66g>8283>>i6??0;66sm32;94?5=83:p(<6n:2af?M5dn2B8o95f4883>>o6:10;66a>7783>>{e;;o1<7:50;2x 4>f28997E=lf:J0g1=n<00;66g:2;29?l7?;3:17b?86;29?xd4;10;6>4?:1y'5=g=;jo0D>mi;I1`0>o313:17d?=8;29?j70>3:17pl<2b83>1<729q/=5o51208L6ea3A9h86g;9;29?l352900e<6<:188k4112900qo=<7;297?6=8r.:4l4<cd9K7f`<@:i?7d:6:188m44?2900c<99:188yg55i3:187>50z&2<d<6;;1C?nh4H2a7?l2>2900e8<50;9j5=5=831d=:850;9~f65129086=4?{%3;e?5dm2B8ok5G3b68m1?=831b=?650;9l520=831vn><7:187>5<7s-;3m7?<2:J0gc=O;j>0e9750;9j17<722c:4>4?::m233<722wi?>;50;194?6|,82j6>mj;I1`b>N4k=1b844?::k26=<722e:;;4?::a770=83>1<7>t$0:b>4553A9hj6F<c59j0<<722c>>7>5;h3;7?6=3f;<:7>5;|`071<72:0;6=u+19c97fc<@:im7E=l4:k7=?6=3`;947>5;n342?6=3th8>94?:583>5}#91k1=><4H2ae?M5d<2c?57>5;h71>5<<a8286=44o055>5<<uk9<?7>55;294~"60h0o?6F<cg9K7f2<,l?1>6g;6;29?l202900e9m50;9j15<722e:;i4?::a724=83?1<7>t$0:b>a5<@:im7E=l4:&f1?4<a=<1<75f4683>>o3k3:17d;?:188k41c2900qo=81;291?6=8r.:4l4k3:J0gc=O;j>0(h;52:k72?6=3`><6=44i5a94?=n=90;66a>7e83>>{e;>:1<7;50;2x 4>f2m90D>mi;I1`0>"b=380e9850;9j02<722c?o7>5;h73>5<<g8=o6=44}c15b?6==3:1<v*>8`8g7>N4ko1C?n:4$d796>o3>3:17d:8:188m1e=831b9=4?::m23a<722wi?;k50;794?6|,82j6i=4H2ae?M5d<2.n97<4i5494?=n<>0;66g;c;29?l372900c<9k:188yg51l3:197>50z&2<d<c;2B8ok5G3b68 `3=:2c?:7>5;h64>5<<a=i1<75f5183>>i6?m0;66sm37a94?3=83:p(<6n:e18L6ea3A9h86*j5;08m10=831b8:4?::k7g?6=3`?;6=44o05g>5<<uk9=n7>55;294~"60h0o?6F<cg9K7f2<,l?1>6g;6;29?l202900e9m50;9j15<722e:;i4?::a7<6=83?1<7>t$0:b>a0<@:im7E=l4:&f1?4<a=<1<75f4683>>o283:17d?8e;29?j70l3:17pl<8g83>0<729q/=5o5d79K7f`<@:i?7)k::39j03<722c?;7>5;h73>5<<a8=n6=44o05g>5<<uk93i7>55;294~"60h0o:6F<cg9K7f2<,l?1>6g;6;29?l202900e8>50;9j52c=831d=:j50;9~f6>c290>6=4?{%3;e?b13A9hj6F<c59'a0<53`>=6=44i5594?=n=90;66g>7d83>>i6?m0;66sm39a94?3=83:p(<6n:e48L6ea3A9h86*j5;08m10=831b8:4?::k64?6=3`;<i7>5;n34`?6=3th84o4?:483>5}#91k1h;5G3bd8L6e33-o>6?5f4783>>o3?3:17d;?:188m41b2900c<9k:188yg5?i3:197>50z&2<d<c>2B8ok5G3b68 `3=:2c?:7>5;h64>5<<a<:1<75f16g94?=h9>n1<75rb2::>5<2290;w)?7a;f5?M5dn2B8o95+e481?l212900e9950;9j15<722c:;h4?::m23a<722wi?4650;794?6|,82j6i84H2ae?M5d<2.n97<4i5494?=n<>0;66g:0;29?l70m3:17b?8d;29?xd41>0;684?:1y'5=g=l?1C?nh4H2a7?!c22;1b8;4?::k73?6=3`?;6=44i05f>5<<g8=o6=44}c1:2?6==3:1<v*>8`8g2>N4ko1C?n:4$d796>o3>3:17d:8:188m06=831b=:k50;9l52b=831vn>7::186>5<7s-;3m7j9;I1`b>N4k=1/i84=;h65>5<<a==1<75f5183>>o6?l0;66a>7e83>>{e;0>1<7;50;2x 4>f2m<0D>mi;I1`0>"b=380e9850;9j02<722c><7>5;h34a?6=3f;<h7>5;|`0=6<72<0;6=u+19c9`3=O;jl0D>m;;%g6>7=n<?0;66g;7;29?l372900e<9j:188k41c2900qo=62;291?6=8r.:4l4k6:J0gc=O;j>0(h;52:k72?6=3`><6=44i4294?=n9>o1<75`16f94?=zj:3:6=4::183!7?i3n=7E=lf:J0g1=#m<097d:9:188m11=831b9=4?::k23`<722e:;i4?::a7=>=83?1<7>t$0:b>a0<@:im7E=l4:&f1?4<a=<1<75f4683>>o283:17d?8e;29?j70l3:17pl<8683>0<729q/=5o5d79K7f`<@:i?7)k::39j03<722c?;7>5;h73>5<<a8=n6=44o05g>5<<uk9ii7>53;294~"60h0:>i5G3bd8L6e33-o>6<74ie;94?=nlh0;66a>7783>>{e;k91<7=50;2x 4>f288o7E=lf:J0g1=#m<0:56gk9;29?lbf2900c<99:188yg46>3:1?7>50z&2<d<6:m1C?nh4H2a7?!c228n0ei750;9j`d<722e:;;4?::a5d`=8391<7>t$0:b>44c3A9hj6F<c59'a0<6l2co57>5;hfb>5<<g8==6=44}c3:f?6=;3:1<v*>8`826a=O;jl0D>m;;%g6>4b<am31<75fd`83>>i6??0;66sm18c94?5=83:p(<6n:00g?M5dn2B8o95+e482`>oc13:17djn:188k4112900qo?69;297?6=8r.:4l4>2e9K7f`<@:i?7)k::0f8ma?=831bhl4?::m233<722wi=4650;194?6|,82j6<<k;I1`b>N4k=1/i84>d:kg=?6=3`nj6=44o055>5<<uk;2;7>53;294~"60h0:>i5G3bd8L6e33-o>6<j4ie;94?=nlh0;66a>7783>>{e90<1<7=50;2x 4>f288o7E=lf:J0g1=#m<0:h6gk9;29?lbf2900c<99:188yg7>=3:1?7>50z&2<d<6:m1C?nh4H2a7?!c228n0ei750;9j`d<722e:;;4?::a5<2=8391<7>t$0:b>44c3A9hj6F<c59'a0<6l2co57>5;hfb>5<<g8==6=44}c3:7?6=;3:1<v*>8`826a=O;jl0D>m;;%g6>4b<am31<75fd`83>>i6??0;66sm18094?5=83:p(<6n:00g?M5dn2B8o95+e482`>oc13:17djn:188k4112900qo?61;297?6=8r.:4l4>2e9K7f`<@:i?7)k::0f8ma?=831bhl4?::m233<722wi=4>50;194?6|,82j6<<k;I1`b>N4k=1/i84>d:kg=?6=3`nj6=44o055>5<<uk;3j7>53;294~"60h0:>i5G3bd8L6e33-o>6<j4ie;94?=nlh0;66a>7783>>{e91o1<7=50;2x 4>f288o7E=lf:J0g1=#m<0:h6gk9;29?lbf2900c<99:188yg7?l3:1?7>50z&2<d<6:m1C?nh4H2a7?!c228n0ei750;9j`d<722e:;;4?::a5=e=8391<7>t$0:b>44c3A9hj6F<c59'a0<6l2co57>5;hfb>5<<g8==6=44}c3;f?6=;3:1<v*>8`826a=O;jl0D>m;;%g6>4b<am31<75fd`83>>i6??0;66sm27g94?2=83:p(<6n:00f?M5dn2B8o95+e48``>oc13:17djn:188mad=831d=:850;9~f77?290?6=4?{%3;e?75m2B8ok5G3b68 `3=:=1bh44?::kge?6=3`ni6=44o055>5<<uk;i=7>54;294~"60h0:>h5G3bd8L6e33-o>6?:4ie;94?=nlh0;66gkb;29?j70>3:17pl=6b83>0<729q/=5o513d8L6ea3A9h86*j5;3b?lb>2900eio50;9j`g<722coo7>5;n342?6=3th9=l4?:483>5}#91k1=?h4H2ae?M5d<2.n97?i;hf:>5<<amk1<75fdc83>>ock3:17b?86;29?xd6j:0;684?:1y'5=g=9;l0D>mi;I1`0>"b=3;m7dj6:188mag=831bho4?::kgg?6=3f;<:7>5;|`137<72<0;6=u+19c957`<@:im7E=l4:&f1?463`n26=44iec94?=nlk0;66gkc;29?j70>3:17pl<1`83>6<729q/=5o513f8L6ea3A9h86*j5;33?lb>2900eio50;9l520=831vn?89:187>5<7s-;3m7?=e:J0gc=O;j>0(h;52b9j`<<722com7>5;hfa>5<<g8==6=44}c02g?6=;3:1<v*>8`826a=O;jl0D>m;;%g6>4b<am31<75fd`83>>i6??0;66sm1c794?5=83:p(<6n:00g?M5dn2B8o95+e482`>oc13:17djn:188k4112900qo<>e;290?6=8r.:4l4>2d9K7f`<@:i?7)k::368ma?=831bhl4?::kgf?6=3f;<:7>5;|`2f2<72=0;6=u+19c957c<@:im7E=l4:&f1?433`n26=44iec94?=nlk0;66a>7783>>{e:;:1<7;50;2x 4>f288m7E=lf:J0g1=#m<0:j6gk9;29?lbf2900eil50;9j`f<722e:;;4?::a5g?=83?1<7>t$0:b>44a3A9hj6F<c59'a0<6n2co57>5;hfb>5<<amh1<75fdb83>>i6??0;66sm3`f94?2=83:p(<6n:00f?M5dn2B8o95+e4865>oc13:17djn:188mad=831d=:850;9~f702290>6=4?{%3;e?75n2B8ok5G3b68 `3=9;1bh44?::kge?6=3`ni6=44iea94?=h9><1<75rb230>5<4290;w)?7a;31`>N4ko1C?n:4$d7967=nl00;66gka;29?j70>3:17pl<0183>6<729q/=5o513f8L6ea3A9h86*j5;01?lb>2900eio50;9l520=831vn?77:186>5<7s-;3m7?=f:J0gc=O;j>0(h;5219j`<<722com7>5;hfa>5<<ami1<75`16494?=zj;2>6=4::183!7?i3;9j6F<cg9K7f2<,l?1>>5fd883>>oci3:17djm:188mae=831d=:850;9~f675290>6=4?{%3;e?75n2B8ok5G3b68 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9><1<75rb3de>5<2290;w)?7a;31b>N4ko1C?n:4$d7966=nl00;66gka;29?lbe2900eim50;9l520=831vn?78:186>5<7s-;3m7?=f:J0gc=O;j>0(h;5219j`<<722com7>5;hfa>5<<ami1<75`16494?=zj;2?6=4::183!7?i3;9j6F<cg9K7f2<,l?1>=5fd883>>oci3:17djm:188mae=831d=:850;9~f676290>6=4?{%3;e?75n2B8ok5G3b68 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9><1<75rb3df>5<2290;w)?7a;31b>N4ko1C?n:4$d7966=nl00;66gka;29?lbe2900eim50;9l520=831vn?79:186>5<7s-;3m7?=f:J0gc=O;j>0(h;5219j`<<722com7>5;hfa>5<<ami1<75`16494?=zj;286=4::183!7?i3;9j6F<cg9K7f2<,l?1>=5fd883>>oci3:17djm:188mae=831d=:850;9~f677290>6=4?{%3;e?75n2B8ok5G3b68 `3=::1bh44?::kge?6=3`ni6=44iea94?=h9><1<75rb3dg>5<2290;w)?7a;31b>N4ko1C?n:4$d7966=nl00;66gka;29?lbe2900eim50;9l520=831vn?7::186>5<7s-;3m7?=f:J0gc=O;j>0(h;5219j`<<722com7>5;hfa>5<<ami1<75`16494?=zj;296=4::183!7?i3;9j6F<cg9K7f2<,l?1>=5fd883>>oci3:17djm:188mae=831d=:850;9~f7?c290?6=4?{%3;e?75m2B8ok5G3b68 `3=ko1bh44?::kge?6=3`ni6=44o055>5<<uk8287>54;294~"60h0:>h5G3bd8L6e33-o>6<?4ie;94?=nlh0;66gkb;29?j70>3:17pl=8083>1<729q/=5o513g8L6ea3A9h86*j5;32?lb>2900eio50;9j`g<722e:;;4?::a74?=83?1<7>t$0:b>44a3A9hj6F<c59'a0<dm2co57>5;hfb>5<<amh1<75fdb83>>i6??0;66sm31d94?3=83:p(<6n:00e?M5dn2B8o95+e4817>oc13:17djn:188mad=831bhn4?::m233<722wi>km50;794?6|,82j6<<i;I1`b>N4k=1/i84=3:kg=?6=3`nj6=44ie`94?=nlj0;66a>7783>>{e:;91<7=50;2x 4>f288o7E=lf:J0g1=#m<09>6gk9;29?lbf2900c<99:188yg7ek3:1?7>50z&2<d<6:m1C?nh4H2a7?!c22;80ei750;9j`d<722e:;;4?::a670=83>1<7>t$0:b>44b3A9hj6F<c59'a0<6m2co57>5;hfb>5<<amh1<75`16494?=zj8hm6=4;:183!7?i3;9i6F<cg9K7f2<,l?1=h5fd883>>oci3:17djm:188k4112900qo<m9;296?6=8r.:4l4>2b9K7f`<@:i?7)k::028ma?=831d=:850;9~f7d029096=4?{%3;e?75k2B8ok5G3b68 `3=991bh44?::m233<722wi>o;50;094?6|,82j6<<l;I1`b>N4k=1/i84>0:kg=?6=3f;<:7>5;|`1f6<72;0;6=u+19c957e<@:im7E=l4:&f1?773`n26=44o055>5<<uk8i=7>52;294~"60h0:>n5G3bd8L6e33-o>6<>4ie;94?=h9><1<75rb3ce>5<5290;w)?7a;31g>N4ko1C?n:4$d7955=nl00;66a>7783>>{e:hn1<7<50;2x 4>f288h7E=lf:J0g1=#m<0:<6gk9;29?j70>3:17pl=ac83>7<729q/=5o513a8L6ea3A9h86*j5;33?lb>2900c<99:188yg4f13:1>7>50z&2<d<6:j1C?nh4H2a7?!c228:0ei750;9l520=831vn>=<:181>5<7s-;3m7?=c:J0gc=O;j>0(h;5119j`<<722e:;;4?::a767=8381<7>t$0:b>44d3A9hj6F<c59'a0<682co57>5;n342?6=3th8>k4?:383>5}#91k1=?m4H2ae?M5d<2.n97??;hf:>5<<g8==6=44}c11`?6=:3:1<v*>8`826f=O;jl0D>m;;%g6>46<am31<75`16494?=zj:8i6=4=:183!7?i3;9o6F<cg9K7f2<,l?1==5fd883>>i6??0;66sm33;94?4=83:p(<6n:00`?M5dn2B8o95+e4824>oc13:17b?86;29?xd4:>0;6?4?:1y'5=g=9;i0D>mi;I1`0>"b=3;;7dj6:188k4112900qo==5;296?6=8r.:4l4>2b9K7f`<@:i?7)k::028ma?=831d=:850;9~f7e329096=4?{%3;e?75k2B8ok5G3b68 `3=991bh44?::m233<722wi?>j50;094?6|,82j6<<l;I1`b>N4k=1/i84>0:kg=?6=3f;<:7>5;|`167<72?0;6=u+19c9566<@:im7E=l4:&f1?423`n26=44iec94?=nlk0;66gkc;29?j7513:17b?86;29?xd6jk0;6;4?:1y'5=g=9::0D>mi;I1`0>"b=38>7dj6:188mag=831bho4?::kgg?6=3f;957>5;n342?6=3th8mo4?:9594?6|@:i?7)?7a;34b>\3=3kp47<9:e821?7428h1i7?9:0695f<z,88<695+de86?!bb2<1/hk4:;%g3>0=#m80>7)k=:49'a6<23-ii6i>4$d491>"b?3?0(h655:&f=?3<,lk196*jb;78 `e==2.nh7;4$dg91>"bn3?0(k>55:&e5?3<,o8196*i3;78 c2==2.m97;4$g491>"a?3?0(k655:&e=?3<,ok196*ib;78 ce==2.mh7;4$gg91>"an3?0(<>?:49'557==2.:<?4:;%337?3<,8:?685+11791>"68?0>7)??7;78 46?2<1/==755:&24d<23-;;n7;4$02`>0=#99n196*>0d86?!77n3?0(<??:49'547==2.:=?4:;%327?3<,8;?685+10791>"69?0>7)?>7;78 47?2<1/=<755:&25d<23-;:n7;4$03`>0=#98n196*>1d86?!76n3?0(<<?:49'577==2.:>?4:;%317?3<,88?685+13791>"6:?087)?74;61?!c32<1/=5853:&0g<<6091/?no51928j<c=82dh<7>4n0:2>44<f8296?:4n2aa>44<f:ih6?:4$ba9`5=#91=186g;a;29?l2e2900en750;9j7f>=831b=5650;9j<0<72-;<n769;o34e?7<3`9<6=4+16`973=i9>k1<65f3483>!70j39=7c?8a;38?l53290/=:l5379m52g=:21b?>4?:%34f?513g;<m7=4;h11>5<#9>h1?;5a16c90>=n;80;6)?8b;15?k70i3?07d=?:18'52d=;?1e=:o56:9j6c<72-;<n7=9;o34e?1<3`8n6=4+16`973=i9>k1465f2e83>!70j39=7c?8a;;8?l26290/=:l5419m52g=821b?k4?:%34f?273g;<m7?4;h1f>5<#9>h18=5a16c96>=n;m0;6)?8b;63?k70i3907d=l:18'52d=<91e=:o54:9j7g<72-;<n7:?;o34e?3<3`9j6=4+16`905=i9>k1:65f3883>!70j3>;7c?8a;58?l5?290/=:l5419m52g=021b;i4?:%34f?1d3g;<m7>4;h5a>5<#9>h1;n5a16c95>=n?00;6)?8b;5`?k70i3807d97:18'52d=?j1e=:o53:9j32<72-;<n79l;o34e?2<3`==6=4+16`93f=i9>k1965f7483>!70j3=h7c?8a;48?l13290/=:l57b9m52g=?21b;>4?:%34f?1d3g;<m764;h51>5<#9>h1;n5a16c9=>=n?80;6)?8b;5`?k70i3k07d9?:18'52d=?j1e=:o5b:9j2`<72-;<n79l;o34e?e<3`<o6=4+16`93f=i9>k1h65f6b83>!70j3=h7c?8a;g8?l0e290/=:l57b9m52g=n21b:l4?:%34f?1d3g;<m7??;:k5=?6=,8=i6:m4n05b>47<3`<36=4+16`93f=i9>k1=?54i7594?"6?k0<o6`>7`827>=n>?0;6)?8b;5`?k70i3;?76g95;29 41e2>i0b<9n:078?l>3290/=:l57b9m52g=9?10e5=50;&23g<0k2d:;l4>7:9j<7<72-;<n79l;o34e?7?32c3=7>5$05a>2e<f8=j6<74;h:3>5<#9>h1;n5a16c95d=<a>l1<7*>7c84g>h6?h0:n65f7d83>!70j3=h7c?8a;3`?>o0i3:1(<9m:6a8j41f28n07d8i:18'52d=?j1e=:o51d98m32=83.:;o48c:l23d<6n21b4n4?:%34f?>e3g;<m7>4;h:b>5<#9>h14o5a16c95>=n000;6)?8b;:a?k70i3807d67:18'52d=0k1e=:o53:9l=1<72-;<n77<;o34e?6<3f396=4+16`9=6=i9>k1=65`9083>!70j3387c?8a;08?j?7290/=:l5929m52g=;21d4k4?:%34f??43g;<m7:4;n:f>5<#9>h15>5a16c91>=h1m0;6)?8b;;0?k70i3<07b7l:18'52d=1:1e=:o57:9l=g<72-;<n77<;o34e?><3f3j6=4+16`9=6=i9>k1565`9883>!70j3387c?8a;c8?j??290/=:l5929m52g=j21d5:4?:%34f??43g;<m7m4;n;5>5<#9>h15>5a16c9`>=h1<0;6)?8b;;0?k70i3o07b6k:18'52d=1:1e=:o5f:9lg6<72-;<n7m=;o34e?6<3fi:6=4+16`9g7=i9>k1=65fc`83>>o6000;66g<c683>>o2i3:1(<9m:4;8j41f2910e8650;&23g<212d:;l4>;:k63?6=,8=i6874n05b>7=<a<<1<7*>7c86=>h6?h0876g:5;29 41e2<30b<9n:598m02=83.:;o4:9:l23d<232c=?7>5$05a>0?<f8=j6;54i7094?"6?k0>56`>7`84?>o193:1(<9m:4;8j41f2110e;>50;&23g<212d:;l46;:k6b?6=,8=i6874n05b>d=<a<o1<7*>7c86=>h6?h0i76g:d;29 41e2<30b<9n:b98m0e=83.:;o4:9:l23d<c32c>n7>5$05a>0?<f8=j6h54i4194?"6?k0>56`>7`8e?>o??3:1(<9m:948j41f2910co650;&23g<e?2d:;l4?;:ma2?6=,8=i6o94n05b>4=<gk>1<7*>7c8a3>h6?h0976am3;29 41e2k=0b<9n:298kg4=83.:;o4m7:l23d<332ei=7>5$05a>g1<f8=j6854oc294?"6?k0i;6`>7`85?>ifn3:1(<9m:c58j41f2>10clk50;&23g<e?2d:;l47;:mb`?6=,8=i6o94n05b><=<ghi1<7*>7c8a3>h6?h0j76anb;29 41e2k=0b<9n:c98kd?=83.:;o4m7:l23d<d32ej47>5$05a>g1<f8=j6i54o`594?"6?k0i;6`>7`8f?>if>3:1(<9m:c58j41f2o10cl;50;&23g<e?2d:;l4>0:9le1<72-;<n7l8;o34e?7632ej?7>5$05a>g1<f8=j6<<4;nc1>5<#9>h1n:5a16c956=<gh;1<7*>7c8a3>h6?h0:865`a183>!70j3h<7c?8a;36?>ien3:1(<9m:c58j41f28<07blj:18'52d=j>1e=:o51698kgb=83.:;o4m7:l23d<6021dnn4?:%34f?d03g;<m7?6;:maf?6=,8=i6o94n05b>4g<3fhj6=4+16`9f2=i9>k1=o54oc;94?"6?k0i;6`>7`82g>=hj<0;6)?8b;`4?k70i3;o76ana;29 41e2k=0b<9n:0g8?j?a290/=:l5b69m52g=9o10cn650;&23g<d?2d:;l4?;:m`2?6=,8=i6n94n05b>4=<gj?1<7*>7c8`3>h6?h0976al4;29 41e2j=0b<9n:298yv2e83:1:vP;b19>63c=lh16>;m5d89>624=lj16>;85dc9>633=l01v9oj:1853~X4m?1U?i64^5`;?[2e>2T8h:5Q4c18Z1063W>i;6P;639]0=2<V:o?7S=j3:\0a7=Y;l;0R>k?;_1gb>X4ll1U?ij4^2f`?[2d:2T?o<5Q4b28Z1da3W>ii6P;be9]0ge<V=hi7S:ma:\7ea=Y<hi0R9om;_6be>X3i01U8l64^5c4?[2f>2T?m85Q4`6896b72m=01>ln:42896ga2<:01>l6:42896d?2<:01>l8:42896e52<:01>m>:42897d?2<801?l9:40897d32<801?l=:40897d72<801?oj:40897gd2<801?on:40897g?2<801?6j:40897>c2<801?6l:40897>e2<801?6n:408971e2<801?9n:408971>2<801?97:40897102<801>>6:408966?2<801>>8:40896612<801>>::40897`12<801?h::40897`32<801?h<:40897`52<801>==:40896572<801><j:408964d2<801><n:408964?2<801><9:40896432<801>om:97896ge282270=nb;1`3>;4ik0>m63<ac86<>;4ik0>;63<ac862>;4ik0>963<ac860>;4ik0=?63<ac856>;4ik0==63<ac854>;4ik0>j63<ac86a>;4ik0>h63<ac86g>;4ik0>n63<ac867>;4ik03;6s|4c094?5|V=h970=ma;34g>;4io0:;n5rs353>5<5sW>>:63=71823a=z{=i?6=4<{_6`0>;49h0o563<188g=>{t<h91<7;7{_6b7>;51k0?:63<b0872>;4j90?:63<ag872>;4j00?:63<b9872>;4j>0?:63=15872>;59:0?:63=13872>;5980?:63=11872>;58o0?:63=0d872>;58m0?:63=0b872>;5=j0?:63=5c872>;5=h0?:63=58872>;5=10?:63=56872>;5=?0?:63=54872>;5==0?:63=4`872>;5<00?:63=49872>;5<>0?:63=47872>;5<<0?:63=45872>;5<:0?:63=43872>;6l:0?:63>d3872>;6l80?:63>d1872>;6ko0?:63>cd872>;6km0?:63>cb872>;6kk0?:63>c`872>;5l10?:63=d6872>;5l<0?:63=d5872>;5l?0?:63=d2872>;5l;0?:63=d1872>;5ko0?:63=d0872>;5mj0?:63=ec872>;5mh0?:63=e8872>;5m10?:63=e6872>;5m?0?:63=e4872>;5m=0?:63=e2872>;5>o0?:63=71872>;5>h0?:63=68872>;4190?:63<8g872>;40l0?:63<8e872>;40j0?:63<8c872>;40h0?:63<88872>;4110?:63<96872>;41?0?:63<94872>;41=0?:63<92872>;41;0?:63<90872>;4010?:63<86872>;4ik0?m6s|30594?4|V=?h70=>7;34`>{t<k31<7:6{_6a=>;49>0?:63<17872>;4jj0?:63<b`872>;4jk0?:63<c3872>;4k80?:63>ae872>;6ij0?:63>ac872>;6ih0?:63>a8872>;6i10?:63>a6872>;6i?0?:63>a4872>;6n00?:63>f9872>;6n>0?:63>f7872>;6n<0?:63>f5872>;6n:0?:63>f3872>;6n80?:63>e6872>;6m?0?:63>e4872>;6m=0?:63>e2872>;6m;0?:63>e0872>;6m90?:63>dg872>;6ll0?:63=39872>;5;>0?:63=37872>;5;<0?:63=35872>;5;:0?:63=33872>;5;80?:63=31872>;4=k0?:63<58872>;4=h0?:63<5b872>;4=m0?:63<5d872>;4=o0?:63<61872>;4>80?:63<4g872>;4<l0?:63<4b872>;4<k0?:63<4e872>;4<h0?:63<48872>;4<>0?:63<49872>;4?:0?:63<73872>;4?80?:63<71872>;4>o0?:63<6d872>;4>m0?:63<6b872>;4>k0?:63<ac87f>{t;>n1<7<t^51:?85>83;<h6s|36a94?4|V=9370=7f;34`>{t;>h1<7<t^514?85?m3;<h6s|36c94?4|V=9=70=7d;34`>{t;>31<7<t^516?85?k3;<h6s|36:94?4|V=9?70=7b;34`>{t;>=1<7<t^510?85?i3;<h6s|36494?4|V=9970=79;34`>{t;1<1<7<t^562?85>03;<h6s|39794?4|V=>;70=67;34`>{t;1>1<7<t^51e?85>>3;<h6s|39194?4|V=9n70=65;34`>{t;181<7<t^51g?85><3;<h6s|39394?4|V=9h70=63;34`>{t;1:1<7<t^51a?85>:3;<h6s|36d94?4|V=9j70=61;34`>{t;>o1<7<t^512?85?03;<h6s|36794?4|V=9;70=77;34`>{t<;21<7<t^527?85fj3227p};2783>7}Y<9901>om:7c8yv25=3:1>vP;039>7dd=>01v9<;:181[279278mo498:p075=838pR9>?;<1bf?003ty?>?4?:3y]7c`<5:ki6;84}r614?6=:rT8ji523``920=z{=;m6=4={_1eg>;4ik0386s|40g94?4|V:li70=nb;:0?xu39m0;6?uQ3gc896ge2120q~:>c;296~X4n016?ll5839~w17e2909wS=i8:?0eg<?92wx8<o50;0xZ6`0349jn76?;|q75<<72;qU?k84=2ca>2`<uz>:47>52z\0b0=:;hh1;h5rs534>5<5sW9m863<ac84e>{t<8?1<7<t^2d1?85fj3<m7p};1583>7}Y;o;01>om:768yv26;3:1>vP<f19>7dd=0j1v9?=:181[5bn278mo48d:p047=838pR>kj;<1bf?1e3ty?==4?:3y]7`b<5:ki6:74}r63b?6=:rT8in523``93==z{=:n6=4={_1ff>;4ik0<;6s|41f94?4|V:oj70=nb;55?xu38j0;6?uQ3d;896ge2>?0q~:=f;296~X38h16?ll5759~w14b2909wS:?9:?0eg<?i2wx8?j50;0xZ16?349jn79<;|q76f<72;qU8=94=2ca>24<uz>9n7>52z\743=:;hh1;<5rs50b>5<5sW>;963<ac844>{t<;31<7<t^2df?85fj3<n7p};2083>7}Y;o901>om:7f8yv26>3:1>vP<e99>7dd=>j1v9>m:181[5b?278mo49b:p563=833p1>j>:05;?84ei3>270<n8;6:?84?i3>270<87;6:?857=3>270<i2;6:?854<3>270==4;6:?xu51j0;6?u228`915=::0n1=:84}r1a2?6=9hq6>4l516a896d>28=o70<k8;6`?84c?3>h70<k5;6`?84c<3>h70<k6;6`?84c;3>h70<k2;6`?84c83>h70<lf;34g>;5l80?o63=eb87g>;5mk0?o63=e`87g>;5m00?o63=e987g>;5m>0?o63=e787g>;5m<0?o63=e587g>;5m:0?o63=6g823f=::>:1=:m4=34b>1e<5;<269m4}r0:f?6=<r795o4>7e9>63e=lj16?lj5d89>633=lh1v>li:181<~;49>0?o63<1787g>;4k80:;i521`f90f=:9hi18n521``90f=:9hk18n521`;90f=:9h218n521`590f=:9h<18n521`790f=:9o318n521g:90f=:9o=18n521g490f=:9o?18n521g690f=:9o918n521g090f=:9o;18n521d590f=:9l<18n521d790f=:9l>18n521d190f=:9l818n521d390f=:9l:18n521ed90f=:9mo18n5222:90f=:::=18n5222490f=:::?18n5222690f=:::918n5222090f=:::;18n5222290f=z{:;36=4<{<123?37349::7;?;<12=?70>2wx?<850;1x967128=o70=>a;fb?85613nj7p}<b183>6}:;k;19=523c2952b<5:km6994}r1a5?6=:r78n<4>7e9>7g5=l01v>lm:18085ek3?;70=ma;64?85ej3;<h6s|3ca94?4|5:hh6<9k;<1aa?b>3ty8mk4?:2y>7g6==916?lh516f896d42mk0q~=ma;297~;4jh0:;i523c`915=:;ko1hl5rs2`1>5<3s49i57?8c:?0f=<6?j16?o9516a896d428==7p}<b483>70|5:h36<9k;<020?2d348:?7:l;<026?2d348:=7:l;<024?2d348;j7:l;<03a?2d348;h7:l;<03g?2d348>o7:l;<06f?2d348>m7:l;<06=?2d348>47:l;<063?2d348>:7:l;<061?2d348>87:l;<07e?2d348?57:l;<07<?2d348?;7:l;<072?2d348?97:l;<070?2d348??7:l;<076?2d34;o?7:l;<3g6?2d34;o=7:l;<3g4?2d34;hj7:l;<3`a?2d34;hh7:l;<3`g?2d34;hn7:l;<3`e?2d3ty8n94?:07x96d028=o70=60;34a>;40o0:;h5239g952c<5:2o6<9j;<1;g?70m2784o4>7d9>7=g=9>o01>66:05f?85>03;<i63<96823`=:;0<1=:k4=2;6>41b349287?8e:?0=6<6?l16?4<516g896?628=n70=78;34a>;40>0:;h523`f9`d=:;hh1=564}r1a`?6=;r78o?4>7b9>7f7=9>i01>lj:055?xu4k90;6<mt=2a1>41c349>n7:l;<16=?70k2789l4;c:?01f<3k2789i4;c:?01`<3k2789k4;c:?025<3k278:<4;c:?00c<3k2788h4;c:?00f<3k2788o4;c:?00a<3k2788l4;c:?00<<3k2788:4;c:?00=<6?j16?:=54b9>724=<j16?:?54b9>726=<j16?;h54b9>73c=<j16?;j54b9>73e=<j16?;l54b9~w4`7290>w0?nd;73?87a13;<h63>ag8ge>;6j80o563>b28gg>{t9h>1<7=t=0cg>41c349:?7jn;<134?bf3ty:mh4?:3y>5de==916=lh51648yv7f;3:1?v3>ab823a=:;881h4522gd9`<=z{8h;6=4={<3bf?3734;i=7?86:p5d4=839p1<om:05g?856:3ni70<if;fa?xu6j;0;6;u21`c915=:9k91=:84=0`6>ag<58h<6i74=0`:>ae<58hi6im4}r3b5?6=;r7:ml4>7e9>747=l016>kk5d89~w4d32909w0?n9;73?87e=3;<:6s|1`294?5|58k26<9k;<125?be348mi7jm;|q2f3<72;q6=l65519>5g1=9><0q~?6f;297~;6i10:;i523029`<=::on1h45rs0`;>5<5s4;j;7;?;<3a=?70>2wx=4k50;1x94g028=o70=>0;fa?84al3ni7p}>b`83>7}:9h<19=521ca9520<uz;2h7>53z?2e3<6?m16?=h5d89>6ce=l01v<lj:18187f=3?;70?mf;342>{t90i1<7=t=0c6>41c349;j7jm;<0eg?be3ty99>4?:4y>642==916>8m516f897712mk01??7:e;8977f2mi0q~<?b;297~;59=0:;i5228:9`d=::1?1hl5rs336>5<5s48:?7;?;<022?70>2wx>=o50;1x977428=o70<68;f:?84?=3nh7p}=1683>7}::8819=5220:9520<uz8;57>53z?157<6?m16>495d`9>6=2=lh1v??6:18584693?;70<>a;342>;59j0om63=1d8g=>;5:90oo63=238gg>{t:921<7=t=332>41c3482;7j6;<0;0?b>3ty9=o4?:3y>646==916><m51648yv47?3:1?v3=11823a=::0<1hl522919`d=z{;;o6=4={<03b?37348:i7?86:p650=839p1?>i:05g?84>>3n270<73;f:?xu59o0;6?u221g915=::;:1=:84}r031?6=;r79<h4>7e9>6<3=lh16>5<5d`9~w7462909w0<?d;73?845;3;<:6s|21694?5|5;:o6<9k;<0:1?b>3483>7j6;|q160<72;q6>=m5519>670=9><0q~<?3;297~;58j0:;i522869`<=::1;1h45rs362>5<5s48>o7;?;<07e?70l2wx>9>50;0x973e2<:01?:6:05g?xu5=;0;69u224`952b<5;;=6i74=33;>ag<5;;j6il4}r00b?6=:r799l4:0:?10=<6?m1v?;>:180842i3;<h63=198gf>;59h0om6s|22g94?4|5;?268>4=364>41c3ty99=4?:3y>60?=9>n01??n:e;8yv44l3:1>v3=59864>;5<?0:;i5rs36e>5<2s48>47?8d:?15f<c1279=h4ka:?165<cj279>?4kb:p66e=838p1?;8:428972228=o7p}=4d83>1}::<=1=:j4=33f>ad<5;8;6io4=301>ag<uz88n7>52z?113<28279894>7e9~w72c2908w0<:6;34`>;5:90o563=238g=>{t::k1<7<t=376>06<5;>86<9k;|q10f<72:q6>8;516f897442m301?<9:ec8yv4413:1>v3=55864>;5<;0:;i5rs36a>5<5s48>87?8d:?163<c12wx=ij50;0x94`>2<:01<k8:05g?xu6lj0;6?u21g:915=:9l<1=:j4}r3fb?6=<r7:j54>7e9>5d`=l016=o?5d`9>5g5=lk1v<jm:18187a?3?;70?j5;34`>{t9lo1<7=t=0d4>41c34;i=7jm;<3a7?bf3ty:hl4?:3y>5c0==916=h:516f8yv7bl3:1>v3>f7823a=:9k91h45rs0f:>5<5s4;m97;?;<3f7?70l2wx=hm50;7x94`228=o70?m5;f:?87e?3nj70?m9;fa?87ej3ni7p}>d983>7}:9o>19=521d0952b<uz;nn7>54z?2b1<6?m16=o95dc9>5g?=lh16=ol5d`9~w4b02909w0?i3;73?87b93;<h6s|1dc94?5|58l86<9k;<3a=?b>34;in7j6;|q2`3<72;q6=k<5519>5`6=9>n0q~?j9;297~;6n;0:;i521ca9`<=:9kl1hl5rs0f6>5<5s4;m=7;?;<3gb?70l2wx=h650;0x94`628=o70?mf;f:?xu5:o0;6?u225c915=:::21=:j4}r01a?6=:r79844:0:?172<6?m1v?<k:18184303?;70<<6;34`>{t:;i1<7<t=364>06<5;9>6<9k;|q16g<72;q6>985519>662=9>n0q~<=a;296~;5<<0><63=32823a=z{;826=4={<070?373488>7?8d:p67>=838p1?:<:428975628=o7p}=2683>7}::=819=52222952b<uz;h57>52z?2a2<2827:h>4>7e9~w4e?2909w0?j6;73?87c:3;<h6s|1b594?4|58o>68>4=0f2>41c3ty:o;4?:3y>5`2==916=i>516f8yv7d=3:1>v3>e2864>;6ko0:;i5rs0a7>5<5s4;n>7;?;<3`a?70l2wx=n=50;0x94c62<:01<mk:05g?xu6k;0;6?u21d2915=:9ji1=:j4}r3`5?6=:r7:hk4:0:?2gg<6?m1v<m?:18187cm3?;70?la;34`>{t9m>1<7?t=0ff>41c3ty9i?4?:4y>5a5==916>hm516f894>e2m301?6::e;896ge2:=0q~?ia;296~;6l;0><63>8c8233=z{8li6=4={<3g5?3734;3o7?86:p5ce=838p1<j?:42894>c28==7p}>fe83>7}:9jl19=5219g9520<uz;mi7>52z?2g`<2827:4k4>779~w4`a2909w0?ld;73?87>83;<:6s|21294?4|58ih68>4=0;2>4113ty9<<4?:3y>5fd==916=4<51648yv47:3:1>v3>c`864>;61:0:;;5rs24b>5<3s48847;?;<147?70l27:594k9:?0eg<392wx>8j50;0x97502<:01<7;:055?xu5=l0;6?u2224915=:90?1=:84}r06b?6=:r79?84:0:?2=3<6??1v?8?:181844<3?;70?67;342>{t:?;1<7<t=310>06<58336<99;|q127<72;q6>><5519>5<?=9><0q~<93;296~;5;80><63>9`8233=z{;<?6=4={<004?3734;2n7?86:p6`b=83;<w0<k8;64?84c?3><70<k5;64?84c<3><70<k6;64?84c;3><70<k2;64?84c83><70<lf;64?84c93><70<jc;64?84bj3><70<ja;64?84b13><70<j8;64?84b?3><70<j6;64?84b=3><70<j4;64?84b;3><70=nd;fa?841=3;<:63=9e8g=>{t:h=1<7<t=3f;>06<5;i86<99;|q1g`<72=q6>i6516f897cd2<:01?77:ea897e32m30q~<n6;296~;5l>0><63=c38233=z{;io6=4;{<0g3?70l279io4:0:?1==<cj279n44k9:p6d2=838p1?j::42897e728==7p}=cc83>1}::m?1=:j4=3g:>06<5;3<6il4=3`6>a?<uz8j?7>52z?1`1<28279nk4>779~w7ef290?w0<k4;34`>;5m10><63=978gg>;5j:0o56s|2`794?4|5;n=68>4=3a2>4113ty9on4?:5y>6a0=9>n01?kn:42897?02mi01?l8:e;8yv4f:3:1>v3=d2864>;5jl0:;;5rs3a:>5<3s48o?7?8d:?1a2<282795;4kb:?1f4<c12wx>l?50;0x97b52<:01?lk:055?xu5k10;69u22e0952b<5;o=68>4=3;6>ae<5;km6i74}r0:b?6=:r79h=4:0:?1fg<6??1v?m9:18784c83;<h63=e5864>;51=0on63=ac8g=>{t:0o1<7<t=3ae>06<5;hj6<99;|q1g0<72=q6>nh516f897c42<:01?7;:ec897g>2m30q~<n0;296~;5l80><63=bb8233=z{;i<6=4;{<0g5?70l279i84:0:?1=0<cj279mi4k9:p6g>=838p1?m<:5;897d?28==7p}=c583>7}::j91=?64=3a7>4113ty9n;4?:2y>6f4=<016>o65489>6g0=9><0q~<m9;297~;5k;0:>5522c:95=5<5;h26<99;|q1f1<72:q6>n?5489>6g0=<016>o:51648yv4e?3:1?v3=c0826==::k<1=5=4=3`4>4113ty9n?4?:2y>6f6=<016>o:5489>6g4=9><0q~<m5;297~;5k90:>5522c695=5<5;h>6<99;|q1f5<72:q6>oh5489>6g4=<016>o>51648yv4e;3:1?v3=bg826==::k81=5=4=3`0>4113ty9mh4?:2y>6gc=<016>o>5489>6dc=9><0q~<m1;297~;5jl0:>5522c295=5<5;h:6<99;|q1ef<72:q6>oj5489>6dc=<016>lm51648yv4fn3:1?v3=be826==::ho1=5=4=3ce>4113ty9ml4?:2y>6ge=<016>lm5489>6dg=9><0q~<nd;297~;5jj0:>5522`a95=5<5;ko6<99;|q1e=<72:q6>ol5489>6dg=<016>l651648yv4fj3:1?v3=bc826==::hk1=5=4=3ca>4113ty9m44?:2y>6gg=9;201?o7:0:0?84f13;<:6s|2d394?3|5;oi6<9k;<3;g?b>34;3n7jn;<0;1?be349jn7=:;|q1a5<72<q6>ho516f894>c2m301<6l:ec897>32mi01>om:268yv4cn3:19v3=e8823a=:91o1h45219f9`d=::1>1ho523``976=z{;nn6=4:{<0f<?70l27:4k4k9:?2<`<ci2794>4kc:?0eg<4:2wx>ij50;7x97c028=o70?60;f:?87?n3nj70<73;fa?85fj39:7p}=db83>0}::l<1=:j4=0;2>a?<583;6io4=3:1>ae<5:ki6>>4}r0gf?6==r79i84>7e9>5<4=l016=4?5d`9>6=4=lk16?ll52g9~w7bf290>w0<j4;34`>;61:0o563>938ge>;5080on63<ac81a>{t:m31<7:t=3g0>41c34;2?7jn;<0;5?bf349jn7<k;|q134<72:q6>;h5519>626==916>:<51648yv41n3:1>v3=6g823a=::>81h45rs34a>5<5s48=m7;?;<05g?70>2wx>;650;4x970f28=o70<9e;fa?841k3ni70<82;fa?841>3n270<95;fa?xu5>m0;6?u227;915=::?o1=:84}r053?6=>r79:44>7e9>63c=l016>;m5d`9>624=lh16>;85d`9>633=lj1v?66:18184?m3>270<7d;342>{t:091<7<t=3:f>4>4348247?86:p6<g=838p1?6j:055?84>l3nj7p}=8983>7}::1n1845229a9520<uz82>7>52z?1<a<60:16>4951648yv4??3:1>v3=8b87=>;50k0:;;5rs3;2>5<5s483o7?73:?1=3<6??1v?69:18184?j3>270<7a;342>{t:0:1<7<t=3:a>4>4348297?86:p6=`=838p1?6n:0:0?84><3;<:6s|26494?4|5;=i6974=35b>4113ty94=4?:3y>62d=91901?6::055?xu5100;6?u226`9520<5;3o6il4}r041?6=:r79;l4;9:?13<<6??1v?9i:181840i3;3?63=858233=z{;=?6=4={<04=?2>348<47?86:p62c=838p1?96:0:0?84?;3;<:6s|26194?4|5;=36974=354>4113ty9;i4?:3y>62>=91901?6=:055?xu5?j0;6?u226595=5<5;2:6<99;|q041<72;q6?=75489>75>=9><0q~=?e;296~;4800:4>523019520<uz9:97>52z?04<<6??16?<75db9~w6642909w0=?8;6:?857?3;<:6s|31f94?4|5::36<6<;<126?70>2wx?=<50;0x96602=301>>9:055?xu48j0;6?u231595=5<5:;:6<99;|q044<72;q6?=85489>753=9><0q~=?b;296~;48?0:4>523029520<uz9;m7>52z?040<60:16?=h51648yv4a93:1>v3=f787=>;5n<0:;;5rs3da>5<5s48m:7?73:?045<6??1v>?;:18184a>3;<:63<188gf>{t:o:1<7<t=3d6>1?<5;l?6<99;|q1bd<72;q6>k;5191897`a28==7p}=eg83>7}::o>184522g19520<uz8m57>52z?1b1<60:16>kk51648yv4bm3:1>v3=f287=>;5n;0:;;5rs3d;>5<5s48m?7?73:?1ba<6??1v?h8:18184a:3;3?63=fb8233=z{:=?6=4>ez?01g<3?278944;7:?01d<3?2789n4;7:?01a<3?2789h4;7:?01c<3?278:=4;7:?024<3?2788k4;7:?00`<3?2788n4;7:?00g<3?2788i4;7:?00d<3?278844;7:?002<3?278854;7:?036<3?278;?4;7:?034<3?278;=4;7:?02c<3?278:h4;7:?02a<3?278:n4;7:?02g<3?278=l4>779>7dd=;j201>om:bc8yv5383:18v3<5c864>;4<00:;i523029`f=:;;31h45rs271>5<4s49>n7?8d:?02a<28279ji4kc:p76c=83>p1>;6:428962028=o70=?f;f`?855=3n27p}<5183>6}:;<31=:j4=24a>06<5;lh6im4}r10b?6=<r789l4:0:?00=<6?m16?=h5d`9>771=l01v>;>:180852i3;<h63<6b864>;5nj0om6s|35394?2|5:?h68>4=26b>41c349:<7jn;<11f?b>3ty89>4?:2y>70e=9>n01>8j:42897`c2mk0q~=;2;290~;4=m0><63<4c823a=:;8;1hn5233f9`<=z{:??6=4<{<16`?70l278:k4:0:?1b`<ck2wx?9=50;6x963b2<:01>:l:05g?85693nj70==f;f:?xu4=<0;6>u234g952b<5:=;68>4=3df>ag<uz9?87>54z?01c<282788i4>7e9>744=lj16?>?5d89~w6312908w0=:f;34`>;4?80><63=fg8gg>{t;=?1<7:t=243>06<5:>n6<9k;<126?bf3498?7j6;|q012<72:q6?;>516f896152<:01?hi:ec8yv53>3:18v3<60864>;4<o0:;i523019`<=:;:n1h45rs27;>5<4s49==7?8d:?036<28278<=4k9:p775=838p1>:i:428965d28==7p}<2383>7}:;=o19=5232`9520<uz99<7>52z?00f<28278?44>779~w67a2909w0=;b;73?85403;<:6s|33394?4|5:>o68>4=21b>4113ty8=h4?:3y>71g==916?>951648yv56l3:1>v3<48864>;4;?0:;;5rs23a>5<5s49?;7;?;<100?70>2wx?<m50;0x962?2<:01>=::055?xu4;;0;6?u232a90<=:;:81=:84}r10`?6=:r78?n4>299>76b=9><0q~=<0;297~;4;k0?563<3387=>;4;90:;;5rs210>5<4s498n7?=8:?077<60:16?>=51648yv55m3:1?v3<3`87=>;4;90?563<2d8233=z{:9:6=4<{<10e?750278?=4>829>767=9><0q~==c;297~;4;00?563<2d87=>;4:j0:;;5rs20e>5<4s49857?=8:?06`<60:16??h51648yv55i3:1?v3<3987=>;4:j0?563<2`8233=z{:8o6=4<{<10<?750278>n4>829>77b=9><0q~==8;297~;4;>0?563<2`87=>;4:10:;;5rs20a>5<4s498;7?=8:?06d<60:16??l51648yv55>3:1?v3<3787=>;4:10?563<278233=z{:826=4<{<102?750278>54>829>77?=9><0q~==4;297~;4;<0?563<2787=>;4:=0:;;5rs204>5<4s49897?=8:?063<60:16??951648yv55=3:1?v3<35826==:;;>1=5=4=206>4113ty8:44?:5y>724=9>n01<7::e;894?32mk01>om:2d8yv5103:18v3<70823a=:90<1h4521879`d=:;hh1?h5rs244>5<3s49<<7?8d:?2=2<c127:5;4ka:?0eg<4l2wx?;850;6x960a28=o70?68;f:?87>?3nj70=nb;1`?xu4><0;69u237g952b<58326i74=0;;>ag<5:ki6>l4}r150?6=<r78:i4>7e9>5<g=l016=475d`9>7dd=;h1v>8<:187851k3;<h63>9c8g=>;61h0om63<ac80=>{t;?81<7=t=24a>41c34;2n7jn;<1bf?5?3ty8mh4?:01x96?72==01>6i:55896>b2==01>6k:55896>d2==01>6m:55896>f2==01>66:55896??2==01>78:55896?12==01>7::55896?32==01>7<:55896?52==01>7>:55896>?2==01>68:558970128==7p}<a083>7}:;0:19=523``9g6=z{:k;6=4={<1;b?37349jn77;;|q0=c<72;q6?5k5519>7dd=1;1v>7j:18185?l3?;70=nb;;2?xu41m0;6?u239a915=:;hh15=5rs2;`>5<5s493n7;?;<1bf?>a3ty85o4?:3y>7=g==916?ll58d9~w6?f2909w0=79;73?85fj33o7p}<a`83>7}:;0219=523``9=f=z{:k26=4={<1:3?37349jn7m>;|q0e=<72;q6?485519>7dd=1k1v>o8:18185>=3?;70=nb;;b?xu4i?0;6?u2386915=:;hh1545rs2c6>5<5s492?7;?;<1bf???3ty8m94?:3y>7<4==916?ll5969~w6g42909w0=61;73?85fj33=7p}<a383>7}:;1219=523``9=0=z{:326=4={<1;3?37349jn76k;|q0ef<72;q6?lj5164896ge2j30q~?<7;296~;5::0om63=23826<=z{8?86=4={<3ag?bf34;in7?=9:p672=838p1?<9:e`8974528==7p}>be83>7}:9kl1ho521c`9520<uty?n?4?:3y]0g4<5=>18o<4$2a0>4163ty?n44?:3y]0g?<5=>18o74$2a0>4153ty?m>4?:3y]0d5<5=>18l=4$2a0>4143ty?>54?:3y]052<5=>18=:4$2a0>4503ty?>;4?:3y]055<5=>18==4$2a0>4253ty?>84?:3y]054<5=>18=<4$2a0>42e3ty?>94?:3y]057<5=>18=?4$2a0>42c3ty?>>4?:3y]056<5=>18=>4$2a0>42b3ty?>?4?:3y]7c`<5=>1?kh4$2a0>42a3ty?>=4?:3y]7cb<5=>1?kj4$2a0>4373ty?=k4?:3y]7ce<5=>1?km4$2a0>4363ty?=h4?:3y]7cd<5=>1?kl4$2a0>4353ty?=i4?:3y]7cg<5=>1?ko4$2a0>4333ty?=n4?:3y]7c?<5=>1?k74$2a0>4323ty?=o4?:3y]7c><5=>1?k64$2a0>4313ty?=l4?:3y]7c1<5=>1?k94$2a0>4303ty?=44?:3y]7c0<5=>1?k84$2a0>43?3ty?=54?:3y]7c3<5=>1?k;4$2a0>43>3ty?=:4?:3y]7c2<5=>1?k:4$2a0>43f3ty?=84?:3y]7c4<5=>1?k<4$2a0>43e3ty?=94?:3y]7c7<5=>1?k?4$2a0>43d3ty?=>4?:3y]7c6<5=>1?k>4$2a0>43c3ty?=?4?:3y]7``<5=>1?hh4$2a0>43b3ty?=<4?:3y]7`c<5=>1?hk4$2a0>43a3ty?==4?:3y]7`b<5=>1?hj4$2a0>4073ty?<k4?:3y]7`e<5=>1?hm4$2a0>4063ty?<h4?:3y]7`d<5=>1?hl4$2a0>4053ty?<i4?:3y]7`g<5=>1?ho4$2a0>4043ty?<n4?:3y]7`?<5=>1?h74$2a0>4033ty?>k4?:3y]05g<5=>18=o4$2a0>4023ty?>h4?:3y]05?<5=>18=74$2a0>4013ty?>i4?:3y]05><5=>18=64$2a0>4003ty?>n4?:3y]051<5=>18=94$2a0>40?3ty?>o4?:3y]050<5=>18=84$2a0>40>3ty?>l4?:3y]053<5=>18=;4$2a0>40f3ty?>44?:3y]7cc<5=>1?kk4$2a0>40e3ty?><4?:3y]7c5<5=>1?k=4$2a0>40d3ty?=;4?:3y]7`><5=>1?h64$2a0>40c3ty?<o4?:3y]7`1<5=>1?h94$2a0>40b3ty?o94?:3y]0f2<5=>18n:4$2a0>40a3ty?n=4?:3y]0g6<5=>18o>4$2a0>4173ty?8o4?:3y]06?<5=>18>74$2a0>4513ty?844?:3y]06><5=>18>64$2a0>45?3ty?854?:3y]061<5=>18>94$2a0>45>3ty?8:4?:3y]060<5=>18>84$2a0>45f3ty?8;4?:3y]063<5=>18>;4$2a0>45e3ty?884?:3y]062<5=>18>:4$2a0>45d3ty?894?:3y]065<5=>18>=4$2a0>45c3ty?8>4?:3y]064<5=>18><4$2a0>45b3ty?994?:3y]017<5=>189?4$2a0>45a3ty?9>4?:3y]016<5=>189>4$2a0>4273ty?9?4?:3y]06`<5=>18>h4$2a0>4263ty?9<4?:3y]06c<5=>18>k4$2a0>4243ty?9=4?:3y]06b<5=>18>j4$2a0>4233ty?8k4?:3y]06e<5=>18>m4$2a0>4223ty?8h4?:3y]06d<5=>18>l4$2a0>4213ty?8i4?:3y]06g<5=>18>o4$2a0>4203ty?8n4?:3y]067<5=>18>?4$2a0>42?3ty?8?4?:3y]066<5=>18>>4$2a0>42>3ty?9n4?:3y]00e<5=>188m4$2a0>42f3ty?9;4?:3y]000<5=>18884$2a0>42d3twe4oh50;0xL6e33td3o=4?:3yK7f2<ug2h=7>52zJ0g1=zf1i96=4={I1`0>{i0j91<7<tH2a7?xh?k=0;6?uG3b68yk>d=3:1>vF<c59~j=e12909wE=l4:m<f1=838pD>m;;|l;g=<72;qC?n:4}o:`=?6=:rB8o95rn9ab>5<5sA9h86sa8b`94?4|@:i?7p`7cb83>7}O;j>0qc6ld;296~N4k=1vb5mj:181M5d<2we4nh50;0xL6e33td3h=4?:3yK7f2<ug2o=7>52zJ0g1=zf1n96=4={I1`0>{i0m91<7<tH2a7?xh?l=0;6?uG3b68yk>c=3:1>vF<c59~j=b12909wE=l4:m<a1=838pD>m;;|l;`=<72;qC?n:4}o:g=?6=:rB8o95rn9fb>5<5sA9h86sa8e`94?4|@:i?7p`7db83>7}O;j>0qc6kd;296~N4k=1vb5jj:181M5d<2we4ih50;0xL6e33td3i=4?:3yK7f2<ug2n=7>52zJ0g1=zf1o96=4={I1`0>{i0l91<7<tH2a7?xh?m=0;6?uG3b68yk>b=3:1>vF<c59~j=c12909wE=l4:m<`1=838pD>m;;|l;a=<72;qC?n:4}o:f=?6=:rB8o95rn9gb>5<5sA9h86sa8d`94?4|@:i?7p`7eb83>7}O;j>0qc6jd;296~N4k=1vb5kj:181M5d<2we4hh50;0xL6e33td3j=4?:3yK7f2<ug2m=7>52zJ0g1=zf1l96=4={I1`0>{i0o91<7<tH2a7?xh?n=0;6?uG3b68yk>a=3:1>vF<c59~j=`12909wE=l4:m<c1=838pD>m;;|l;b=<72;qC?n:4}o:e=?6=:rB8o95rn9db>5<5sA9h86sa8g`94?4|@:i?7p`85683>4}O;j>0qc964;295~N4k=1vb:7::182M5d<2we;4850;3xL6e33td<5:4?:0yK7f2<ug=247>51zJ0g1=zf>326=4>{I1`0>{i?0k1<7?tH2a7?xh01k0;6<uG3b68yk1>k3:1=vF<c59~j2?c290:wE=l4:m3<c=83;pD>m;;|l4=c<728qC?n:4}o5b4?6=9rB8o95rn6c2>5<6sA9h86sa7`094?7|@:i?7p`8a283>4}O;j>0qc9n4;295~N4k=1vb:o::182M5d<2we;l850;3xL6e33td<m:4?:0yK7f2<ug=j47>51zJ0g1=zf>k26=4>{I1`0>{i?hk1<7?tH2a7?xh0ik0;6<uG3b68yk1fk3:1=vF<c59~j2gc290:wE=l4:m3dc=83;pD>m;;|l4ec<728qC?n:4}o5a4?6=9rB8o95rn6`2>5<6sA9h86sa7c094?7|@:i?7p`8b283>4}O;j>0qc9m4;295~N4k=1vb:l::182M5d<2we;o850;3xL6e33td<n:4?:0yK7f2<ug=i47>51zJ0g1=zf>h26=4>{I1`0>{i?kk1<7?tH2a7?xh0jk0;6<uG3b68yk1ek3:1=vF<c59~j2dc290:wE=l4:m3gc=83;pD>m;;|l4fc<728qC?n:4}o5`4?6=9rB8o95rn6a2>5<6sA9h86sa7b094?7|@:i?7p`8c283>4}O;j>0qc9l4;295~N4k=1vb:m::182M5d<2we;n850;3xL6e33td<o:4?:0yK7f2<ug=h47>51zJ0g1=zf>i26=4>{I1`0>{i?jk1<7?tH2a7?xh0kk0;6<uG3b68yk1dk3:1=vF<c59~j2ec290:wE=l4:m3fc=83;pD>m;;|l4gc<728qC?n:4}o5g4?6=9rB8o95rn6f2>5<6sA9h86sa7e094?7|@:i?7p`8d283>4}O;j>0qc9k4;295~N4k=1vb:j::182M5d<2we;i850;3xL6e33td<h:4?:0yK7f2<ug=o47>51zJ0g1=zf>n26=4>{I1`0>{i?mk1<7?tH2a7?xh0lk0;6<uG3b68yk1ck3:1=vF<c59~j2bc290:wE=l4:m3ac=83;pD>m;;|l4`c<728qC?n:4}o5f4?6=9rB8o95rn6g2>5<6sA9h86sa7d094?7|@:i?7p`8e283>4}O;j>0qc9j4;295~N4k=1vb:k::182M5d<2we;h850;3xL6e33td<i:4?:0yK7f2<ug=n47>51zJ0g1=zf>o26=4>{I1`0>{i?lk1<7?tH2a7?xh0mk0;6<uG3b68yk1bk3:1=vF<c59~j2cc290:wE=l4:m3`c=83;pD>m;;|l4ac<728qC?n:4}o5e4?6=9rB8o95rn6d2>5<6sA9h86sa7g094?7|@:i?7p`8f283>4}O;j>0qc9i4;295~N4k=1vb:h::182M5d<2we;k850;3xL6e33td<j:4?:0yK7f2<ug=m47>51zJ0g1=zf>l26=4>{I1`0>{i?ok1<7?tH2a7?xh0nk0;6<uG3b68yk1ak3:1=vF<c59~j2`c290:wE=l4:m3cc=83;pD>m;;|l4bc<728qC?n:4}o:34?6=9rB8o95rn922>5<6sA9h86sa81094?7|@:i?7p`70283>4}O;j>0qc6?4;295~N4k=1vb5>::182M5d<2we4=850;3xL6e33td3<:4?:0yK7f2<ug2;47>51zJ0g1=zf1:26=4>{I1`0>{i09k1<7?tH2a7?xh?8k0;6<uG3b68yk>7k3:1=vF<c59~j=6c290:wE=l4:m<5c=83;pD>m;;|l;4c<728qC?n:4}o:24?6=9rB8o95rn932>5<6sA9h86sa80094?7|@:i?7p`71283>4}O;j>0qc6>4;295~N4k=1vb5?::182M5d<2we4<850;3xL6e33td3=:4?:0yK7f2<ug2:47>51zJ0g1=zf1;26=4>{I1`0>{i08k1<7?tH2a7?xh?9k0;6<uG3b68yk>6k3:1=vF<c59~j=7c290:wE=l4:m<4c=83;pD>m;;|l;5c<728qC?n:4}o:14?6=9rB8o95rn902>5<6sA9h86sa83094?7|@:i?7p`72283>4}O;j>0qc6=4;295~N4k=1vb5<::182M5d<2we4?850;3xL6e33td3>:4?:0yK7f2<ug2947>51zJ0g1=zf1826=4>{I1`0>{i0;k1<7?tH2a7?xh?:k0;6<uG3b68yk>5k3:1=vF<c59~j=4c290:wE=l4:m<7c=83;pD>m;;|l;6c<728qC?n:4}o:04?6=9rB8o95rn912>5<6sA9h86sa82094?7|@:i?7p`73283>4}O;j>0qc6<4;295~N4k=1vb5=::182M5d<2we4>850;3xL6e33td3?:4?:0yK7f2<ug2847>51zJ0g1=zf1926=4>{I1`0>{i0:k1<7?tH2a7?xh?;k0;6<uG3b68yk>4k3:1=vF<c59~j=5c290:wE=l4:m<6c=83;pD>m;;|l;7c<728qC?n:4}o:74?6=9rB8o95rn962>5<6sA9h86sa85094?7|@:i?7p`74283>4}O;j>0qc6;4;295~N4k=1vb5:::182M5d<2we49850;3xL6e33td38:4?:0yK7f2<ug2?47>51zJ0g1=zf1>26=4>{I1`0>{i0=k1<7?tH2a7?xh?<k0;6<uG3b68yk>3k3:1=vF<c59~j=2c290:wE=l4:m<1c=83;pD>m;;|l;0c<728qC?n:4}o:64?6=9rB8o95rn972>5<6sA9h86sa84094?7|@:i?7p`75283>4}O;j>0qc6:4;295~N4k=1vb5;::182M5d<2we48850;3xL6e33td39:4?:0yK7f2<ug2>47>51zJ0g1=zf1?26=4>{I1`0>{i0<k1<7?tH2a7?xh?=k0;6<uG3b68yk>2k3:1=vF<c59~j=3c290:wE=l4:m<0c=83;pD>m;;|l;1c<728qC?n:4}o:54?6=9rB8o95rn942>5<6sA9h86sa87094?7|@:i?7p`76283>4}O;j>0qc694;295~N4k=1vb58::182M5d<2we4;850;3xL6e33td3::4?:0yK7f2<ug2=47>51zJ0g1=zf1<26=4>{I1`0>{i0?k1<7?tH2a7?xh?>k0;6<uG3b68yk>1k3:1=vF<c59~j=0c290:wE=l4:m<3c=83;pD>m;;|l;2c<728qC?n:4}o:44?6=9rB8o95rn952>5<6sA9h86sa86094?7|@:i?7p`77283>4}O;j>0qc684;295~N4k=1vb59::182M5d<2we4:850;3xL6e33td3;:4?:0yK7f2<ug2<47>51zJ0g1=zf1=26=4>{I1`0>{i0>k1<7?tH2a7?xh??k0;6<uG3b68yk>0k3:1=vF<c59~j=1c290:wE=l4:m<2c=83;pD>m;;|l;3c<728qC?n:4}o:;4?6=9rB8o95rn9:2>5<6sA9h86sa89094?7|@:i?7p`78283>4}O;j>0qc674;295~N4k=1vb56::182M5d<2we45850;3xL6e33td34:4?:0yK7f2<ug2347>51zJ0g1=zf1226=4>{I1`0>{i01k1<7?tH2a7?xh?0k0;6<uG3b68yk>?k3:1=vF<c59~j=>c290:wE=l4:m<=c=83;pD>m;;|l;<c<728qC?n:4}o::4?6=9rB8o95rn9;2>5<6sA9h86sa88094?7|@:i?7p`79283>4}O;j>0qc664;295~N4k=1vb57::182M5d<2we44850;3xL6e33td35:4?:0yK7f2<ug2247>51zJ0g1=zf1326=4>{I1`0>{i00k1<7?tH2a7?xh?1k0;6<uG3b68yk>>k3:1=vF<c59~j=?c290:wE=l4:m<<c=83;pD>m;;|l;=c<728qC?n:4}o:b4?6=9rB8o95rn9c2>5<6sA9h86sa8`094?7|@:i?7p`7a283>4}O;j>0qc6n4;295~N4k=1vb5o::182M5d<2we4l850;3xL6e33td3m:4?:0yK7f2<ug2j47>51zJ0g1=zf1k26=4>{I1`0>{i0hk1<7?tH2a7?xh?ik0;6<uG3b68yk>fk3:1=vF<c59~j=gc290:wE=l4:m<dc=83;pD>m;;|l;ec<728qC?n:4}o:a4?6=9rB8o95rn9`2>5<6sA9h86sa8c094?7|@:i?7p`7b283>4}O;j>0qc6m4;295~N4k=1vb5l::182M5d<2we4o850;3xL6e33td3n:4?:0yK7f2<ug2i47>51zJ0g1=zf1h26=4>{I1`0>{i0kk1<7?tH2a7?xh?jk0;6<uG3b68yk>ek3:1=vF<c59~j=dc290:wE=l4:m<gc=83;pD>m;;|~yEFDsh<>69>i25f;exFGJr:vLM^t}AB
\ No newline at end of file diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v new file mode 100644 index 000000000..b3d994ae8 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.v @@ -0,0 +1,169 @@ +/******************************************************************************* +* This file is owned and controlled by Xilinx and must be used * +* solely for design, simulation, implementation and creation of * +* design files limited to Xilinx devices or technologies. Use * +* with non-Xilinx devices or technologies is expressly prohibited * +* and immediately terminates your license. * +* * +* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * +* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * +* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * +* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * +* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * +* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * +* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * +* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * +* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE * +* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * +* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * +* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * +* FOR A PARTICULAR PURPOSE. * +* * +* Xilinx products are not intended for use in life support * +* appliances, devices, or systems. Use in such applications are * +* expressly prohibited. * +* * +* (c) Copyright 1995-2009 Xilinx, Inc. * +* All rights reserved. * +*******************************************************************************/ +// The synthesis directives "translate_off/translate_on" specified below are +// supported by Xilinx, Mentor Graphics and Synplicity synthesis +// tools. Ensure they are correct for your synthesis tool(s). + +// You must compile the wrapper file fifo_xlnx_512x36_2clk_36to18.v when simulating +// the core, fifo_xlnx_512x36_2clk_36to18. When compiling the wrapper file, be sure to +// reference the XilinxCoreLib Verilog simulation library. For detailed +// instructions, please refer to the "CORE Generator Help". + +`timescale 1ns/1ps + +module fifo_xlnx_512x36_2clk_36to18( + rst, + wr_clk, + rd_clk, + din, + wr_en, + rd_en, + dout, + full, + empty); + + +input rst; +input wr_clk; +input rd_clk; +input [35 : 0] din; +input wr_en; +input rd_en; +output [17 : 0] dout; +output full; +output empty; + +// synthesis translate_off + + FIFO_GENERATOR_V6_1 #( + .C_COMMON_CLOCK(0), + .C_COUNT_TYPE(0), + .C_DATA_COUNT_WIDTH(9), + .C_DEFAULT_VALUE("BlankString"), + .C_DIN_WIDTH(36), + .C_DOUT_RST_VAL("0"), + .C_DOUT_WIDTH(18), + .C_ENABLE_RLOCS(0), + .C_ENABLE_RST_SYNC(1), + .C_ERROR_INJECTION_TYPE(0), + .C_FAMILY("spartan3"), + .C_FULL_FLAGS_RST_VAL(0), + .C_HAS_ALMOST_EMPTY(0), + .C_HAS_ALMOST_FULL(0), + .C_HAS_BACKUP(0), + .C_HAS_DATA_COUNT(0), + .C_HAS_INT_CLK(0), + .C_HAS_MEMINIT_FILE(0), + .C_HAS_OVERFLOW(0), + .C_HAS_RD_DATA_COUNT(0), + .C_HAS_RD_RST(0), + .C_HAS_RST(1), + .C_HAS_SRST(0), + .C_HAS_UNDERFLOW(0), + .C_HAS_VALID(0), + .C_HAS_WR_ACK(0), + .C_HAS_WR_DATA_COUNT(0), + .C_HAS_WR_RST(0), + .C_IMPLEMENTATION_TYPE(2), + .C_INIT_WR_PNTR_VAL(0), + .C_MEMORY_TYPE(1), + .C_MIF_FILE_NAME("BlankString"), + .C_MSGON_VAL(1), + .C_OPTIMIZATION_MODE(0), + .C_OVERFLOW_LOW(0), + .C_PRELOAD_LATENCY(0), + .C_PRELOAD_REGS(1), + .C_PRIM_FIFO_TYPE("512x36"), + .C_PROG_EMPTY_THRESH_ASSERT_VAL(4), + .C_PROG_EMPTY_THRESH_NEGATE_VAL(5), + .C_PROG_EMPTY_TYPE(0), + .C_PROG_FULL_THRESH_ASSERT_VAL(509), + .C_PROG_FULL_THRESH_NEGATE_VAL(508), + .C_PROG_FULL_TYPE(0), + .C_RD_DATA_COUNT_WIDTH(10), + .C_RD_DEPTH(1024), + .C_RD_FREQ(1), + .C_RD_PNTR_WIDTH(10), + .C_UNDERFLOW_LOW(0), + .C_USE_DOUT_RST(1), + .C_USE_ECC(0), + .C_USE_EMBEDDED_REG(0), + .C_USE_FIFO16_FLAGS(0), + .C_USE_FWFT_DATA_COUNT(0), + .C_VALID_LOW(0), + .C_WR_ACK_LOW(0), + .C_WR_DATA_COUNT_WIDTH(9), + .C_WR_DEPTH(512), + .C_WR_FREQ(1), + .C_WR_PNTR_WIDTH(9), + .C_WR_RESPONSE_LATENCY(1)) + inst ( + .RST(rst), + .WR_CLK(wr_clk), + .RD_CLK(rd_clk), + .DIN(din), + .WR_EN(wr_en), + .RD_EN(rd_en), + .DOUT(dout), + .FULL(full), + .EMPTY(empty), + .BACKUP(), + .BACKUP_MARKER(), + .CLK(), + .SRST(), + .WR_RST(), + .RD_RST(), + .PROG_EMPTY_THRESH(), + .PROG_EMPTY_THRESH_ASSERT(), + .PROG_EMPTY_THRESH_NEGATE(), + .PROG_FULL_THRESH(), + .PROG_FULL_THRESH_ASSERT(), + .PROG_FULL_THRESH_NEGATE(), + .INT_CLK(), + .INJECTDBITERR(), + .INJECTSBITERR(), + .ALMOST_FULL(), + .WR_ACK(), + .OVERFLOW(), + .ALMOST_EMPTY(), + .VALID(), + .UNDERFLOW(), + .DATA_COUNT(), + .RD_DATA_COUNT(), + .WR_DATA_COUNT(), + .PROG_FULL(), + .PROG_EMPTY(), + .SBITERR(), + .DBITERR()); + + +// synthesis translate_on + +endmodule + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.veo b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.veo new file mode 100644 index 000000000..e93be1591 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.veo @@ -0,0 +1,51 @@ +/******************************************************************************* +* This file is owned and controlled by Xilinx and must be used * +* solely for design, simulation, implementation and creation of * +* design files limited to Xilinx devices or technologies. Use * +* with non-Xilinx devices or technologies is expressly prohibited * +* and immediately terminates your license. * +* * +* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" * +* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR * +* XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION * +* AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION * +* OR STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS * +* IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT, * +* AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE * +* FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY * +* WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE * +* IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR * +* REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF * +* INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * +* FOR A PARTICULAR PURPOSE. * +* * +* Xilinx products are not intended for use in life support * +* appliances, devices, or systems. Use in such applications are * +* expressly prohibited. * +* * +* (c) Copyright 1995-2009 Xilinx, Inc. * +* All rights reserved. * +*******************************************************************************/ +// The following must be inserted into your Verilog file for this +// core to be instantiated. Change the instance name and port connections +// (in parentheses) to your own signal names. + +//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG +fifo_xlnx_512x36_2clk_36to18 YourInstanceName ( + .rst(rst), + .wr_clk(wr_clk), + .rd_clk(rd_clk), + .din(din), // Bus [35 : 0] + .wr_en(wr_en), + .rd_en(rd_en), + .dout(dout), // Bus [17 : 0] + .full(full), + .empty(empty)); + +// INST_TAG_END ------ End INSTANTIATION Template --------- + +// You must compile the wrapper file fifo_xlnx_512x36_2clk_36to18.v when simulating +// the core, fifo_xlnx_512x36_2clk_36to18. When compiling the wrapper file, be sure to +// reference the XilinxCoreLib Verilog simulation library. For detailed +// instructions, please refer to the "CORE Generator Help". + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco new file mode 100644 index 000000000..d3115e7d5 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xco @@ -0,0 +1,84 @@ +############################################################## +# +# Xilinx Core Generator version 12.1 +# Date: Thu Aug 12 21:06:13 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = false +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc3s2000 +SET devicefamily = spartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = fg456 +SET removerpms = false +SET simulationfiles = Behavioral +SET speedgrade = -5 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT Fifo_Generator family Xilinx,_Inc. 6.1 +# END Select +# BEGIN Parameters +CSET almost_empty_flag=false +CSET almost_full_flag=false +CSET component_name=fifo_xlnx_512x36_2clk_36to18 +CSET data_count=false +CSET data_count_width=9 +CSET disable_timing_violations=false +CSET dout_reset_value=0 +CSET empty_threshold_assert_value=4 +CSET empty_threshold_negate_value=5 +CSET enable_ecc=false +CSET enable_int_clk=false +CSET enable_reset_synchronization=true +CSET fifo_implementation=Independent_Clocks_Block_RAM +CSET full_flags_reset_value=0 +CSET full_threshold_assert_value=509 +CSET full_threshold_negate_value=508 +CSET inject_dbit_error=false +CSET inject_sbit_error=false +CSET input_data_width=36 +CSET input_depth=512 +CSET output_data_width=18 +CSET output_depth=1024 +CSET overflow_flag=false +CSET overflow_sense=Active_High +CSET performance_options=First_Word_Fall_Through +CSET programmable_empty_type=No_Programmable_Empty_Threshold +CSET programmable_full_type=No_Programmable_Full_Threshold +CSET read_clock_frequency=1 +CSET read_data_count=false +CSET read_data_count_width=10 +CSET reset_pin=true +CSET reset_type=Asynchronous_Reset +CSET underflow_flag=false +CSET underflow_sense=Active_High +CSET use_dout_reset=true +CSET use_embedded_registers=false +CSET use_extra_logic=false +CSET valid_flag=false +CSET valid_sense=Active_High +CSET write_acknowledge_flag=false +CSET write_acknowledge_sense=Active_High +CSET write_clock_frequency=1 +CSET write_data_count=false +CSET write_data_count_width=9 +# END Parameters +GENERATE +# CRC: a4e70980 diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xise b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xise new file mode 100644 index 000000000..cfe983130 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18.xise @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?> +<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema"> + + <header> + <!-- ISE source project file created by Project Navigator. --> + <!-- --> + <!-- This file contains project source information including a list of --> + <!-- project source files, project and process properties. This file, --> + <!-- along with the project source files, is sufficient to open and --> + <!-- implement in ISE Project Navigator. --> + <!-- --> + <!-- Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. --> + </header> + + <version xil_pn:ise_version="12.1" xil_pn:schema_version="2"/> + + <files> + <file xil_pn:name="fifo_xlnx_512x36_2clk_36to18.ngc" xil_pn:type="FILE_NGC"> + <association xil_pn:name="BehavioralSimulation"/> + <association xil_pn:name="Implementation"/> + </file> + <file xil_pn:name="fifo_xlnx_512x36_2clk_36to18.v" xil_pn:type="FILE_VERILOG"> + <association xil_pn:name="BehavioralSimulation"/> + <association xil_pn:name="Implementation"/> + <association xil_pn:name="PostMapSimulation"/> + <association xil_pn:name="PostRouteSimulation"/> + <association xil_pn:name="PostTranslateSimulation"/> + </file> + </files> + + <properties> + <property xil_pn:name="Auto Implementation Top" xil_pn:value="false" xil_pn:valueState="non-default"/> + <property xil_pn:name="Device" xil_pn:value="xc3s2000" xil_pn:valueState="non-default"/> + <property xil_pn:name="Device Family" xil_pn:value="Spartan3" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Stop View" xil_pn:value="PreSynthesis" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top" xil_pn:value="Module|fifo_xlnx_512x36_2clk_36to18" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top File" xil_pn:value="fifo_xlnx_512x36_2clk_36to18.ngc" xil_pn:valueState="non-default"/> + <property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/fifo_xlnx_512x36_2clk_36to18" xil_pn:valueState="non-default"/> + <property xil_pn:name="Package" xil_pn:value="fg456" xil_pn:valueState="default"/> + <property xil_pn:name="Preferred Language" xil_pn:value="Verilog" xil_pn:valueState="default"/> + <property xil_pn:name="Project Generator" xil_pn:value="CoreGen" xil_pn:valueState="non-default"/> + <property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/> + <property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/> + <property xil_pn:name="Speed Grade" xil_pn:value="-5" xil_pn:valueState="default"/> + <property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/> + <property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/> + <property xil_pn:name="Working Directory" xil_pn:value="." xil_pn:valueState="non-default"/> + <!-- --> + <!-- The following properties are for internal use only. These should not be modified.--> + <!-- --> + <property xil_pn:name="PROP_DesignName" xil_pn:value="fifo_xlnx_512x36_2clk_36to18" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan3" xil_pn:valueState="default"/> + <property xil_pn:name="PROP_intProjectCreationTimestamp" xil_pn:value="2010-08-12T14:06:16" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWbtProjectID" xil_pn:value="3646C65496E43142DA83C69469B5BF88" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/> + <property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/> + </properties> + + <bindings/> + + <libraries/> + + <autoManagedFiles> + <!-- The following files are identified by `include statements in verilog --> + <!-- source files and are automatically managed by Project Navigator. --> + <!-- --> + <!-- Do not hand-edit this section, as it will be overwritten when the --> + <!-- project is analyzed based on files automatically identified as --> + <!-- include files. --> + </autoManagedFiles> + +</project> diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_flist.txt b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_flist.txt new file mode 100644 index 000000000..54c85b15e --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_flist.txt @@ -0,0 +1,12 @@ +# Output products list for <fifo_xlnx_512x36_2clk_36to18> +_xmsgs/pn_parser.xmsgs +fifo_generator_ug175.pdf +fifo_xlnx_512x36_2clk_36to18.gise +fifo_xlnx_512x36_2clk_36to18.ngc +fifo_xlnx_512x36_2clk_36to18.v +fifo_xlnx_512x36_2clk_36to18.veo +fifo_xlnx_512x36_2clk_36to18.xco +fifo_xlnx_512x36_2clk_36to18.xise +fifo_xlnx_512x36_2clk_36to18_flist.txt +fifo_xlnx_512x36_2clk_36to18_readme.txt +fifo_xlnx_512x36_2clk_36to18_xmdf.tcl diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_readme.txt b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_readme.txt new file mode 100644 index 000000000..3efc586bf --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_readme.txt @@ -0,0 +1,47 @@ +The following files were generated for 'fifo_xlnx_512x36_2clk_36to18' in directory +/home/ianb/ettus/sram_fifo/fpgapriv/usrp2/coregen/ + +fifo_generator_ug175.pdf: + Please see the core data sheet. + +fifo_xlnx_512x36_2clk_36to18.gise: + ISE Project Navigator support file. This is a generated file and should + not be edited directly. + +fifo_xlnx_512x36_2clk_36to18.ngc: + Binary Xilinx implementation netlist file containing the information + required to implement the module in a Xilinx (R) FPGA. + +fifo_xlnx_512x36_2clk_36to18.v: + Verilog wrapper file provided to support functional simulation. + This file contains simulation model customization data that is + passed to a parameterized simulation model for the core. + +fifo_xlnx_512x36_2clk_36to18.veo: + VEO template file containing code that can be used as a model for + instantiating a CORE Generator module in a Verilog design. + +fifo_xlnx_512x36_2clk_36to18.xco: + CORE Generator input file containing the parameters used to + regenerate a core. + +fifo_xlnx_512x36_2clk_36to18.xise: + ISE Project Navigator support file. This is a generated file and should + not be edited directly. + +fifo_xlnx_512x36_2clk_36to18_readme.txt: + Text file indicating the files generated and how they are used. + +fifo_xlnx_512x36_2clk_36to18_xmdf.tcl: + ISE Project Navigator interface file. ISE uses this file to determine + how the files output by CORE Generator for the core can be integrated + into your ISE project. + +fifo_xlnx_512x36_2clk_36to18_flist.txt: + Text file listing all of the output files produced when a customized + core was generated in the CORE Generator. + + +Please see the Xilinx CORE Generator online help for further details on +generated files and how to use them. + diff --git a/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_xmdf.tcl b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_xmdf.tcl new file mode 100644 index 000000000..5161c1826 --- /dev/null +++ b/fpga/usrp2/coregen/fifo_xlnx_512x36_2clk_36to18_xmdf.tcl @@ -0,0 +1,68 @@ +# The package naming convention is <core_name>_xmdf +package provide fifo_xlnx_512x36_2clk_36to18_xmdf 1.0 + +# This includes some utilities that support common XMDF operations +package require utilities_xmdf + +# Define a namespace for this package. The name of the name space +# is <core_name>_xmdf +namespace eval ::fifo_xlnx_512x36_2clk_36to18_xmdf { +# Use this to define any statics +} + +# Function called by client to rebuild the params and port arrays +# Optional when the use context does not require the param or ports +# arrays to be available. +proc ::fifo_xlnx_512x36_2clk_36to18_xmdf::xmdfInit { instance } { +# Variable containg name of library into which module is compiled +# Recommendation: <module_name> +# Required +utilities_xmdf::xmdfSetData $instance Module Attributes Name fifo_xlnx_512x36_2clk_36to18 +} +# ::fifo_xlnx_512x36_2clk_36to18_xmdf::xmdfInit + +# Function called by client to fill in all the xmdf* data variables +# based on the current settings of the parameters +proc ::fifo_xlnx_512x36_2clk_36to18_xmdf::xmdfApplyParams { instance } { + +set fcount 0 +# Array containing libraries that are assumed to exist +# Examples include unisim and xilinxcorelib +# Optional +# In this example, we assume that the unisim library will +# be magically +# available to the simulation and synthesis tool +utilities_xmdf::xmdfSetData $instance FileSet $fcount type logical_library +utilities_xmdf::xmdfSetData $instance FileSet $fcount logical_library unisim +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_generator_ug175.pdf +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_36to18.ngc +utilities_xmdf::xmdfSetData $instance FileSet $fcount type ngc +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_36to18.v +utilities_xmdf::xmdfSetData $instance FileSet $fcount type verilog +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_36to18.veo +utilities_xmdf::xmdfSetData $instance FileSet $fcount type verilog_template +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_36to18.xco +utilities_xmdf::xmdfSetData $instance FileSet $fcount type coregen_ip +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount relative_path fifo_xlnx_512x36_2clk_36to18_xmdf.tcl +utilities_xmdf::xmdfSetData $instance FileSet $fcount type AnyView +incr fcount + +utilities_xmdf::xmdfSetData $instance FileSet $fcount associated_module fifo_xlnx_512x36_2clk_36to18 +incr fcount + +} + +# ::gen_comp_name_xmdf::xmdfApplyParams diff --git a/fpga/usrp2/extramfifo/.gitignore b/fpga/usrp2/extramfifo/.gitignore new file mode 100644 index 000000000..94bbf6dcc --- /dev/null +++ b/fpga/usrp2/extramfifo/.gitignore @@ -0,0 +1,3 @@ +fifo_extram36_tb +fifo_extram_tb +*.vcd diff --git a/fpga/usrp2/extramfifo/Makefile.srcs b/fpga/usrp2/extramfifo/Makefile.srcs new file mode 100644 index 000000000..b255ef916 --- /dev/null +++ b/fpga/usrp2/extramfifo/Makefile.srcs @@ -0,0 +1,17 @@ +# +# Copyright 2010 Ettus Research LLC +# + +################################################## +# Extram Sources +################################################## +EXTRAM_SRCS = $(abspath $(addprefix $(BASE_DIR)/../extramfifo/, \ +ext_fifo.v \ +nobl_if.v \ +nobl_fifo.v \ +icon.v \ +icon.xco \ +ila.v \ +ila.xco \ +refill_randomizer.v \ +)) diff --git a/fpga/usrp2/extramfifo/ext_fifo.v b/fpga/usrp2/extramfifo/ext_fifo.v new file mode 100644 index 000000000..6888617a7 --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo.v @@ -0,0 +1,172 @@ +// +// FIFO backed by an off chip ZBT/NoBL SRAM. +// +// This module and its sub-hierarchy implment a FIFO capable of sustaining +// a data throughput rate of at least int_clk/2 * 36bits and bursts of int_clk * 36bits. +// +// This has been designed and tested for an int_clk of 100MHz and an ext_clk of 125MHz, +// your milage may vary with other clock ratio's especially those where int_clk < ext_clk. +// Testing has also exclusively used a rst signal synchronized to int_clk. +// +// Interface operation mimics a Xilinx FIFO configured as "First Word Fall Through", +// though signal naming differs. +// +// For FPGA use registers interfacing directly with signals prefixed "RAM_*" should be +// packed into the IO ring. +// + + //`define NO_EXT_FIFO + +module ext_fifo + #(parameter INT_WIDTH=36,EXT_WIDTH=18,RAM_DEPTH=19,FIFO_DEPTH=19) + ( + input int_clk, + input ext_clk, + input rst, + input [EXT_WIDTH-1:0] RAM_D_pi, + output [EXT_WIDTH-1:0] RAM_D_po, + output RAM_D_poe, + output [RAM_DEPTH-1:0] RAM_A, + output RAM_WEn, + output RAM_CENn, + output RAM_LDn, + output RAM_OEn, + output RAM_CE1n, + input [INT_WIDTH-1:0] datain, + input src_rdy_i, // WRITE + output dst_rdy_o, // not FULL + output [INT_WIDTH-1:0] dataout, + output src_rdy_o, // not EMPTY + input dst_rdy_i, // READ + output reg [31:0] debug, + output reg [31:0] debug2 + ); + + wire [EXT_WIDTH-1:0] write_data; + wire [EXT_WIDTH-1:0] read_data; + wire full1, empty1; + wire almost_full2, full2, empty2; + wire [INT_WIDTH-1:0] data_to_fifo; + wire [INT_WIDTH-1:0] data_from_fifo; + wire [FIFO_DEPTH-1:0] capacity; + wire space_avail; + wire data_avail; + + // These next 2 lines here purely because ICARUS is crap at handling generate statements. + // Empirically this has been determined to make simulations work. + wire read_input_fifo = space_avail & ~empty1; + wire write_output_fifo = data_avail; + + assign src_rdy_o = ~empty2; + assign dst_rdy_o = ~full1; + +`ifdef NO_EXT_FIFO + assign space_avail = ~full2; + assign data_avail = ~empty1; + assign read_data = write_data; +`else + + // External FIFO running at ext clock rate and 18 or 36 bit width. + nobl_fifo #(.WIDTH(EXT_WIDTH),.RAM_DEPTH(RAM_DEPTH),.FIFO_DEPTH(FIFO_DEPTH)) + nobl_fifo_i1 + ( + .clk(ext_clk), + .rst(rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), + .write_data(write_data), + .write_strobe(~empty1 ), + .space_avail(space_avail), + .read_data(read_data), + .read_strobe(~almost_full2_spread), + .data_avail(data_avail), + .capacity(capacity) + ); +`endif // !`ifdef NO_EXT_FIFO + + + generate + if (EXT_WIDTH == 18 && INT_WIDTH == 36) begin: fifo_g1 + // FIFO buffers data from UDP engine into external FIFO clock domain. + fifo_xlnx_512x36_2clk_36to18 fifo_xlnx_512x36_2clk_36to18_i1 ( + .rst(rst), + .wr_clk(int_clk), + .rd_clk(ext_clk), + .din(datain), // Bus [35 : 0] + .wr_en(src_rdy_i), + .rd_en(read_input_fifo), + .dout(write_data), // Bus [17 : 0] + .full(full1), + .empty(empty1)); + + + // FIFO buffers data read from external FIFO into DSP clk domain and to TX DSP. + fifo_xlnx_512x36_2clk_18to36 fifo_xlnx_512x36_2clk_18to36_i1 ( + .rst(rst), + .wr_clk(ext_clk), + .rd_clk(int_clk), + .din(read_data), // Bus [17 : 0] + .wr_en(write_output_fifo), + .rd_en(dst_rdy_i), + .dout(dataout), // Bus [35 : 0] + .full(full2), + .prog_full(almost_full2), + .empty(empty2)); + end // block: fifo_g1 + else if (EXT_WIDTH == 36 && INT_WIDTH == 36) begin: fifo_g1 + // FIFO buffers data from UDP engine into external FIFO clock domain. + fifo_xlnx_32x36_2clk fifo_xlnx_32x36_2clk_i1 ( + .rst(rst), + .wr_clk(int_clk), + .rd_clk(ext_clk), + .din(datain), // Bus [35 : 0] + .wr_en(src_rdy_i), + .rd_en(read_input_fifo), + .dout(write_data), // Bus [35 : 0] + .full(full1), + .empty(empty1)); + + // FIFO buffers data read from external FIFO into DSP clk domain and to TX DSP. + fifo_xlnx_32x36_2clk fifo_xlnx_32x36_2clk_i2 ( + .rst(rst), + .wr_clk(ext_clk), + .rd_clk(int_clk), + .din(read_data), // Bus [35 : 0] + .wr_en(write_output_fifo), + .rd_en(dst_rdy_i), + .dout(dataout), // Bus [35 : 0] + .full(full2), + .empty(empty2), + .prog_full(almost_full2)); + + end + endgenerate + + + refill_randomizer #(.BITS(7)) + refill_randomizer_i1 ( + .clk(ext_clk), + .rst(rst), + .full_in(almost_full2), + .full_out(almost_full2_spread) + ); + + + always @ (posedge int_clk) + debug[31:28] <= {empty2,full1,dst_rdy_i,src_rdy_i }; + + always @ (posedge ext_clk) + debug[27:0] <= {RAM_WEn,RAM_CE1n,RAM_A[3:0],read_data[17:0],empty1,space_avail,data_avail,almost_full2 }; + + always@ (posedge ext_clk) + // debug2[31:0] <= {write_data[15:0],read_data[15:0]}; + debug2[31:0] <= 0; + +endmodule // ext_fifo diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.cmd b/fpga/usrp2/extramfifo/ext_fifo_tb.cmd new file mode 100644 index 000000000..521f88f21 --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo_tb.cmd @@ -0,0 +1,12 @@ +/opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/glbl.v +-y . +-y ../coregen/ +-y ../fifo +-y ../models +-y /home/ianb/usrp-fpga/usrp2/sdr_lib +-y /home/ianb/usrp-fpga/usrp2/control_lib +-y /home/ianb/usrp-fpga/usrp2/models +-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/unisims +-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src +-y /opt/Xilinx/12.1/ISE_DS/ISE/verilog/src/XilinxCoreLib + diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.prj b/fpga/usrp2/extramfifo/ext_fifo_tb.prj new file mode 100644 index 000000000..a11a15b2f --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo_tb.prj @@ -0,0 +1,9 @@ +verilog work "./ext_fifo_tb.v" +verilog work "./ext_fifo.v" +verilog work "./nobl_fifo.v" +verilog work "./nobl_if.v" +verilog work "../coregen/fifo_xlnx_512x36_2clk_36to18.v" +verilog work "../coregen/fifo_xlnx_512x36_2clk_18to36.v" +verilog work "../models/CY7C1356C/cy1356.v" +verilog work "../models/idt71v65603s150.v" +verilog work "$XILINX/verilog/src/glbl.v" diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.sav b/fpga/usrp2/extramfifo/ext_fifo_tb.sav new file mode 100644 index 000000000..a54b40fc5 --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo_tb.sav @@ -0,0 +1,30 @@ +[timestart] 0 +[size] 1523 832 +[pos] -1 -1 +*-15.000000 66300 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] ext_fifo_tb. +[treeopen] ext_fifo_tb.ext_fifo_i1. +[treeopen] ext_fifo_tb.ext_fifo_i1.nobl_fifo_i1. +@28 +ext_fifo_tb.ext_fifo_i1.src_rdy_i +ext_fifo_tb.ext_fifo_i1.dst_rdy_o +@22 +ext_fifo_tb.ext_fifo_i1.datain[35:0] +@28 +ext_fifo_tb.ext_fifo_i1.src_rdy_o +ext_fifo_tb.ext_fifo_i1.dst_rdy_i +@22 +ext_fifo_tb.ext_fifo_i1.dataout[35:0] +ext_fifo_tb.ext_fifo_i1.RAM_A[17:0] +@28 +ext_fifo_tb.ext_fifo_i1.RAM_WEn +ext_fifo_tb.ext_fifo_i1.RAM_CE1n +@22 +ext_fifo_tb.ext_fifo_i1.RAM_D_pi[35:0] +ext_fifo_tb.ext_fifo_i1.RAM_D_po[35:0] +ext_fifo_tb.ext_fifo_i1.write_data[35:0] +@28 +ext_fifo_tb.ext_fifo_i1.full1 +ext_fifo_tb.ext_fifo_i1.empty1 +@29 +ext_fifo_tb.ext_fifo_i1.space_avail diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.sh b/fpga/usrp2/extramfifo/ext_fifo_tb.sh new file mode 100644 index 000000000..dcfede37a --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo_tb.sh @@ -0,0 +1,2 @@ +#fuse -prj ext_fifo_tb.prj -t work.glbl -t work.ext_fifo_tb -L unisims_ver -L xilinxcorelib_ver -o ext_fifo_tb +iverilog -c ext_fifo_tb.cmd -o ext_fifo_tb ext_fifo_tb.v diff --git a/fpga/usrp2/extramfifo/ext_fifo_tb.v b/fpga/usrp2/extramfifo/ext_fifo_tb.v new file mode 100644 index 000000000..395ad2884 --- /dev/null +++ b/fpga/usrp2/extramfifo/ext_fifo_tb.v @@ -0,0 +1,415 @@ +`timescale 1ns / 1ps +`define USRP2 +//`define USRP2PLUS + +`ifdef USRP2 + `define INT_WIDTH 36 + `define EXT_WIDTH 18 + `define RAM_DEPTH 19 + `define FIFO_DEPTH 8 + `define DUMP_VCD_FULL + `define INT_CLK_PERIOD 5 + `define EXT_CLK_PERIOD 4 +`elsif USRP2PLUS + `define INT_WIDTH 36 + `define EXT_WIDTH 36 + `define RAM_DEPTH 18 + `define FIFO_DEPTH 8 + `define DUMP_VCD_FULL + `define INT_CLK_PERIOD 5 + `define EXT_CLK_PERIOD 5 +`endif // `ifdef USRP2 + + +module ext_fifo_tb(); + + reg int_clk; + reg ext_clk; + reg rst; + + wire [`EXT_WIDTH-1:0] RAM_D_pi; + wire [`EXT_WIDTH-1:0] RAM_D_po; + wire [`EXT_WIDTH-1:0] RAM_D; + wire RAM_D_poe; + wire [`RAM_DEPTH-1:0] RAM_A; + wire RAM_WEn; + wire RAM_CENn; + wire RAM_LDn; + wire RAM_OEn; + wire RAM_CE1n; + reg [`INT_WIDTH-1:0] datain; + reg src_rdy_i; // WRITE + wire dst_rdy_o; // not FULL + wire [`INT_WIDTH-1:0] dataout; + reg [`INT_WIDTH-1:0] ref_dataout; + wire src_rdy_o; // not EMPTY + reg dst_rdy_i; + integer ether_frame; + + // Clocks + // Int clock is 100MHz + // Ext clock is 125MHz + initial + begin + int_clk <= 0; + ext_clk <= 0; + ref_dataout <= 1; + src_rdy_i <= 0; + dst_rdy_i <= 0; + end + + always + #(`INT_CLK_PERIOD/2) int_clk <= ~int_clk; + + always + #(`EXT_CLK_PERIOD/2) ext_clk <= ~ext_clk; + + initial + begin + datain <= 0; + ether_frame <= 0; + + rst <= 1; + repeat (5) @(negedge int_clk); + rst <= 0; + @(negedge int_clk); + while (datain < 10000) + begin + @(negedge int_clk); + datain <= datain + dst_rdy_o; + src_rdy_i <= dst_rdy_o; + // Simulate inter-frame time + if (ether_frame == 1500) + begin + ether_frame <= 0; + repeat(1600) + begin + @(negedge int_clk); + src_rdy_i <= 0; + end + end + else + ether_frame <= ether_frame + dst_rdy_o; + end + end // initial begin + + + initial + begin + repeat (5) @(negedge int_clk); + dst_rdy_i <= 1; + + while (src_rdy_o !== 1) + @(negedge int_clk); + + // Fall through fifo, first output already valid + if (dataout !== ref_dataout) + $display("Error: Expected %x, got %x @%d",ref_dataout, dataout, $time); + ref_dataout <= ref_dataout + src_rdy_o ; + + // Decimate by 16 rate + while (ref_dataout < 2000) + begin + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o ; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x @%d",ref_dataout, dataout, $time); + @(negedge int_clk); + dst_rdy_i <= 0; + repeat(14) @(negedge int_clk); + end // while (ref_dataout < 10000) + // Decimate by 8 rate + while (ref_dataout < 4000) + begin + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o ; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x @%d",ref_dataout, dataout, $time); + @(negedge int_clk); + dst_rdy_i <= 0; + repeat(6) @(negedge int_clk); + end // while (ref_dataout < 10000) + // Decimate by 4 rate + while (ref_dataout < 6000) + begin + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o ; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x @%d",ref_dataout, dataout, $time); + @(negedge int_clk); + dst_rdy_i <= 0; + repeat(2) @(negedge int_clk); + end // while (ref_dataout < 10000) + // Max rate + while (ref_dataout < 10000) + begin + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o ; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x @%d",ref_dataout, dataout, $time); + + end // while (ref_dataout < 10000) + + @(negedge int_clk); + $finish; + + end + + +/* -----\/----- EXCLUDED -----\/----- + + initial + begin + rst <= 1; + repeat (5) @(negedge int_clk); + rst <= 0; + @(negedge int_clk); + repeat (4000) + begin + @(negedge int_clk); + datain <= datain + dst_rdy_o; + src_rdy_i <= dst_rdy_o; +// @(negedge int_clk); +// src_rdy_i <= 0; +// @(negedge int_clk); +// dst_rdy_i <= src_rdy_o; +// @(negedge int_clk); +// dst_rdy_i <= 0; +// repeat (2) @(negedge int_clk); + end // repeat (1000) + // Fall through fifo, first output already valid + if (dataout !== ref_dataout) + $display("Error: Expected %x, got %x",ref_dataout, dataout); + repeat (1000) + begin + @(negedge int_clk); + datain <= datain + dst_rdy_o ; + src_rdy_i <= dst_rdy_o; + @(negedge int_clk); + src_rdy_i <= 0; + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o ; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x",ref_dataout, dataout); + @(negedge int_clk); + dst_rdy_i <= 0; +// repeat (2) @(negedge int_clk); + end // repeat (1000) + repeat (1000) + begin +// @(negedge int_clk); +// datain <= datain + 1; +// src_rdy_i <= 1; +// @(negedge int_clk); +// src_rdy_i <= 0; + @(negedge int_clk); + ref_dataout <= ref_dataout + src_rdy_o; + dst_rdy_i <= src_rdy_o; + if ((dataout !== ref_dataout) && src_rdy_o) + $display("Error: Expected %x, got %x",ref_dataout, dataout); + @(negedge int_clk); + dst_rdy_i <= 0; +// repeat (2) @(negedge int_clk); + end // repeat (1000) + + $finish; + + end // initial begin + + + -----/\----- EXCLUDED -----/\----- */ + /////////////////////////////////////////////////////////////////////////////////// + // Simulation control // + /////////////////////////////////////////////////////////////////////////////////// + `ifdef DUMP_LX2_TOP + // Set up output files + initial begin + $dumpfile("ext_fifo_tb.lx2"); + $dumpvars(1,ext_fifo_tb); + end + `endif + + `ifdef DUMP_LX2_FULL + // Set up output files + initial begin + $dumpfile("ext_fifo_tb.lx2"); + $dumpvars(0,ext_fifo_tb); + end + `endif + + `ifdef DUMP_VCD_TOP + // Set up output files + initial begin + $dumpfile("ext_fifo_tb.vcd"); + $dumpvars(1,ext_fifo_tb); + end + `endif + + `ifdef DUMP_VCD_TOP_PLUS_NEXT + // Set up output files + initial begin + $dumpfile("ext_fifo_tb.vcd"); + $dumpvars(2,ext_fifo_tb); + end + `endif + + + `ifdef DUMP_VCD_FULL + // Set up output files + initial begin + $dumpfile("ext_fifo_tb.vcd"); + $dumpvars(0,ext_fifo_tb); + end + `endif + + // Update display every 10 us + always #10000 $monitor("Time in uS ",$time/1000); + + wire [`EXT_WIDTH-1:0] RAM_D_pi_ext; + wire [`EXT_WIDTH-1:0] RAM_D_po_ext; + wire [`EXT_WIDTH-1:0] RAM_D_ext; + wire RAM_D_poe_ext; + + genvar i; + + // + // Instantiate IO for Bidirectional bus to SRAM + // + + generate + for (i=0;i<`EXT_WIDTH;i=i+1) + begin : gen_RAM_D_IO + + IOBUF #( + .DRIVE(12), + .IOSTANDARD("LVCMOS25"), + .SLEW("FAST") + ) + RAM_D_i ( + .O(RAM_D_pi_ext[i]), + .I(RAM_D_po_ext[i]), + .IO(RAM_D[i]), + .T(RAM_D_poe_ext) + ); + end // block: gen_RAM_D_IO + + endgenerate + + wire [`RAM_DEPTH-1:0] RAM_A_ext; + wire RAM_WEn_ext,RAM_LDn_ext,RAM_CE1n_ext,RAM_OEn_ext,RAM_CENn_ext; + + assign #1 RAM_D_pi = RAM_D_pi_ext; + + assign #1 RAM_D_po_ext = RAM_D_po; + + assign #1 RAM_D_poe_ext = RAM_D_poe; + + assign #2 RAM_WEn_ext = RAM_WEn; + + assign #2 RAM_LDn_ext = RAM_LDn; + + assign #2 RAM_CE1n_ext = RAM_CE1n; + + assign #2 RAM_OEn_ext = RAM_OEn; + + assign #2 RAM_CENn_ext = RAM_CENn; + + assign #2 RAM_A_ext = RAM_A; + + + generate + if (`EXT_WIDTH==18) begin: ram_tb_g1 + idt71v65603s150 idt71v65603s150_i1 + ( + .A(RAM_A_ext[17:0]), + .adv_ld_(RAM_LDn_ext), // advance (high) / load (low) + .bw1_(1'b0), + .bw2_(1'b0), + .bw3_(1'b1), + .bw4_(1'b1), // byte write enables (low) + .ce1_(RAM_CE1n_ext), + .ce2(1'b1), + .ce2_(1'b0), // chip enables + .cen_(RAM_CENn_ext), // clock enable (low) + .clk(ext_clk), // clock + .IO({RAM_D[16:9],RAM_D[7:0]}), + .IOP({RAM_D[17],RAM_D[8]}), // data bus + .lbo_(1'b0), // linear burst order (low) + .oe_(RAM_OEn_ext), // output enable (low) + .r_w_(RAM_WEn_ext) + ); // read (high) / write (low) + end // block: ram_tb_g1 + else if (`EXT_WIDTH==36) begin: ram_tb_g1 + idt71v65603s150 idt71v65603s150_i1 + ( + .A(RAM_A_ext[17:0]), + .adv_ld_(RAM_LDn_ext), // advance (high) / load (low) + .bw1_(1'b0), + .bw2_(1'b0), + .bw3_(1'b0), + .bw4_(1'b0), // byte write enables (low) + .ce1_(RAM_CE1n_ext), + .ce2(1'b1), + .ce2_(1'b0), // chip enables + .cen_(RAM_CENn_ext), // clock enable (low) + .clk(ext_clk), // clock + .IO(RAM_D[31:0]), + .IOP(RAM_D[35:32]), // data bus + .lbo_(1'b0), // linear burst order (low) + .oe_(RAM_OEn_ext), // output enable (low) + .r_w_(RAM_WEn_ext) + ); // read (high) / write (low) + end // block: ram_tb_g1 + + endgenerate + +/* -----\/----- EXCLUDED -----\/----- + + + cy1356 cy1356_i1 + ( .d(RAM_D), + .clk(ext_clk), + .a(RAM_A_ext), + .bws(2'b00), + .we_b(RAM_WEn_ext), + .adv_lb(RAM_LDn_ext), + .ce1b(RAM_CE1n_ext), + .ce2(1'b1), + .ce3b(1'b0), + .oeb(RAM_OEn_ext), + .cenb(RAM_CENn_ext), + .mode(1'b0) + ); + -----/\----- EXCLUDED -----/\----- */ + + + ext_fifo + #(.INT_WIDTH(`INT_WIDTH),.EXT_WIDTH(`EXT_WIDTH),.RAM_DEPTH(`RAM_DEPTH),.FIFO_DEPTH(`FIFO_DEPTH)) + ext_fifo_i1 + ( + .int_clk(int_clk), + .ext_clk(ext_clk), + .rst(rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), + .datain(datain), + .src_rdy_i(src_rdy_i), // WRITE + .dst_rdy_o(dst_rdy_o), // not FULL + .dataout(dataout), + .src_rdy_o(src_rdy_o), // not EMPTY + .dst_rdy_i(dst_rdy_i) + ); + +endmodule // ext_fifo_tb diff --git a/fpga/usrp2/extramfifo/fifo_extram.v b/fpga/usrp2/extramfifo/fifo_extram.v new file mode 100644 index 000000000..4e1f40371 --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram.v @@ -0,0 +1,188 @@ + +// Everything on sram_clk + +module fifo_extram + (input reset, input clear, + input [17:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, input [15:0] occ_in, + output [17:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, input [15:0] space_in, + input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we, + output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe, + output sram_mode, output sram_zz); + + localparam AWIDTH = 19; // 1 MB in x18 + localparam RAMSIZE = ((1<<AWIDTH) - 1); + + wire do_store, do_retrieve; + reg [1:0] do_store_del, do_retr_del; + + reg [AWIDTH-1:0] addr_retrieve, addr_store; + always @(posedge sram_clk) + if(reset | clear) + addr_retrieve <= 0; + else if (do_retrieve) + addr_retrieve <= addr_retrieve + 1; + + always @(posedge sram_clk) + if(reset | clear) + addr_store <= 0; + else if(do_store) + addr_store <= addr_store + 1; + + //wire [AWIDTH-1:0] fullness = (addr_store - addr_retrieve); + reg [AWIDTH-1:0] fullness; + always @(posedge sram_clk) + if(reset | clear) + fullness <= 0; + else if(do_store) + fullness <= fullness + 1; + else if(do_retrieve) + fullness <= fullness - 1; + + // wire empty = (fullness == 0); + //wire full = (fullness == RAMSIZE); // 19'h7FF); + reg empty, full; + + // The math in the following functions is 'AWIDTH wide. Use + // continuous assignments to prevent the numbers from being + // promoted to 32-bit (which would make it wrap wrong). + // + wire [AWIDTH-1:0] addr_retrieve_p1, addr_store_p2; + assign addr_retrieve_p1 = addr_retrieve + 1; + assign addr_store_p2 = addr_store + 2; + + always @(posedge sram_clk) + if(reset | clear) + empty <= 1; + else if(do_store) + empty <= 0; + else if(do_retrieve & (/*(addr_retrieve + 1)*/ addr_retrieve_p1 == addr_store)) + empty <= 1; + + always @(posedge sram_clk) + if(reset | clear) + full <= 0; + else if(do_retrieve) + full <= 0; + else if(do_store & (/*(addr_store+2)*/ addr_store_p2 == addr_retrieve)) + full <= 1; + + reg can_store; + always @* + if(full | ~src_rdy_i) + can_store <= 0; + else if(do_store_del == 0) + can_store <= 1; + else if((do_store_del == 1) || (do_store_del == 2)) + can_store <= (occ_in > 1); + else + can_store <= (occ_in > 2); + + reg can_retrieve; + always @* + if(empty | ~dst_rdy_i) + can_retrieve <= 0; + else if(do_retr_del == 0) + can_retrieve <= 1; + else if((do_retr_del == 1) || (do_retr_del == 2)) + can_retrieve <= (space_in > 1); + else + can_retrieve <= (space_in > 2); + + reg [1:0] state; + localparam IDLE_STORE_NEXT = 0; + localparam STORE = 1; + localparam IDLE_RETR_NEXT = 2; + localparam RETRIEVE = 3; + + reg [7:0] countdown; + wire countdown_done = (countdown == 0); + + localparam CYCLE_SIZE = 6; + + assign do_store = can_store & (state == STORE); + assign do_retrieve = can_retrieve & (state == RETRIEVE); + always @(posedge sram_clk) + if(reset) + do_store_del <= 0; + else + do_store_del <= {do_store_del[0],do_store}; + + always @(posedge sram_clk) + if(reset) + do_retr_del <= 0; + else + do_retr_del <= {do_retr_del[0],do_retrieve}; + + always @(posedge sram_clk) + if(reset | clear) + begin + state <= IDLE_STORE_NEXT; + countdown <= 0; + end + else + case(state) + IDLE_STORE_NEXT : + if(can_store) + begin + state <= STORE; + countdown <= CYCLE_SIZE; + end + else if(can_retrieve) + begin + state <= RETRIEVE; + countdown <= CYCLE_SIZE; + end + STORE : + if(~can_store | (can_retrieve & countdown_done)) + state <= IDLE_RETR_NEXT; + else if(~countdown_done) + countdown <= countdown - 1; + IDLE_RETR_NEXT : + if(can_retrieve) + begin + state <= RETRIEVE; + countdown <= CYCLE_SIZE; + end + else if(can_store) + begin + state <= STORE; + countdown <= CYCLE_SIZE; + end + RETRIEVE : + if(~can_retrieve | (can_store & countdown_done)) + state <= IDLE_STORE_NEXT; + else if(~countdown_done) + countdown <= countdown - 1; + endcase // case (state) + + // RAM wires + assign sram_bw = 0; + assign sram_adv = 0; + assign sram_mode = 0; + assign sram_zz = 0; + assign sram_ce = 0; + + assign sram_a = (state==STORE) ? addr_store : addr_retrieve; + assign sram_we = ~do_store; + assign sram_oe = ~do_retr_del[1]; + assign my_oe = do_store_del[1] & sram_oe; + assign sram_d = my_oe ? datain : 18'bz; + + // FIFO wires + assign dataout = sram_d; + assign src_rdy_o = do_retr_del[1]; + assign dst_rdy_o = do_store_del[1]; + +endmodule // fifo_extram + + + //wire have_1 = (fullness == 1); + //wire have_2 = (fullness == 2); + //wire have_atleast_1 = ~empty; + //wire have_atleast_2 = ~(empty | have_1); + //wire have_atleast_3 = ~(empty | have_1 | have_2); + //wire full_minus_1 = (fullness == (RAMSIZE-1)); // 19'h7FE); + //wire full_minus_2 = (fullness == (RAMSIZE-2)); // 19'h7FD); + //wire spacefor_atleast_1 = ~full; + //wire spacefor_atleast_2 = ~(full | full_minus_1); + //wire spacefor_atleast_3 = ~(full | full_minus_1 | full_minus_2); diff --git a/fpga/usrp2/extramfifo/fifo_extram36.v b/fpga/usrp2/extramfifo/fifo_extram36.v new file mode 100644 index 000000000..29342fdc4 --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram36.v @@ -0,0 +1,47 @@ + +// 18 bit interface means we either can't handle errors or can't handle odd lengths +// unless we go to heroic measures + +module fifo_extram36 + (input clk, input reset, input clear, + input [35:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, + output [35:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, + input sram_clk, output [18:0] sram_a, inout [17:0] sram_d, output sram_we, + output [1:0] sram_bw, output sram_adv, output sram_ce, output sram_oe, output sram_mode, + output sram_zz); + + wire [17:0] f18_data_1, f18_data_2, f18_data_3, f18_data_4; + wire f18_src_rdy_1, f18_dst_rdy_1, f18_src_rdy_2, f18_dst_rdy_2; + wire f18_src_rdy_3, f18_dst_rdy_3, f18_src_rdy_4, f18_dst_rdy_4; + + fifo36_to_fifo18 f36_to_f18 + (.clk(clk), .reset(reset), .clear(clear), + .f36_datain(datain), .f36_src_rdy_i(src_rdy_i), .f36_dst_rdy_o(dst_rdy_o), + .f18_dataout(f18_data_1), .f18_src_rdy_o(f18_src_rdy_1), .f18_dst_rdy_i(f18_dst_rdy_1) ); + + wire [15:0] f1_occ, f2_space; + + fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_in + (.wclk(clk), .datain(f18_data_1), .src_rdy_i(f18_src_rdy_1), .dst_rdy_o(f18_dst_rdy_1), .space(), + .rclk(sram_clk), .dataout(f18_data_2), .src_rdy_o(f18_src_rdy_2), .dst_rdy_i(f18_dst_rdy_2), .short_occupied(f1_occ), + .arst(reset) ); + + fifo_extram fifo_extram + (.reset(reset), .clear(clear), + .datain(f18_data_2), .src_rdy_i(f18_src_rdy_2), .dst_rdy_o(f18_dst_rdy_2), .space(), .occ_in(f1_occ), + .dataout(f18_data_3), .src_rdy_o(f18_src_rdy_3), .dst_rdy_i(f18_dst_rdy_3), .occupied(), .space_in(f2_space), + .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we), + .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe), + .sram_mode(sram_mode), .sram_zz(sram_zz)); + + fifo_2clock_cascade #(.WIDTH(18), .SIZE(4)) fifo_2clock_out + (.wclk(sram_clk), .datain(f18_data_3), .src_rdy_i(f18_src_rdy_3), .dst_rdy_o(f18_dst_rdy_3), .short_space(f2_space), + .rclk(clk), .dataout(f18_data_4), .src_rdy_o(f18_src_rdy_4), .dst_rdy_i(f18_dst_rdy_4), .occupied(), + .arst(reset) ); + + fifo18_to_fifo36 f18_to_f36 + (.clk(clk), .reset(reset), .clear(clear), + .f18_datain(f18_data_4), .f18_src_rdy_i(f18_src_rdy_4), .f18_dst_rdy_o(f18_dst_rdy_4), + .f36_dataout(dataout), .f36_src_rdy_o(src_rdy_o), .f36_dst_rdy_i(dst_rdy_i) ); + +endmodule // fifo_extram36 diff --git a/fpga/usrp2/extramfifo/fifo_extram36_tb.build b/fpga/usrp2/extramfifo/fifo_extram36_tb.build new file mode 100755 index 000000000..ac9369758 --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram36_tb.build @@ -0,0 +1 @@ +iverilog -y ../models -y . -y ../control_lib/ -y ../coregen -y ../fifo -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram36_tb fifo_extram36_tb.v diff --git a/fpga/usrp2/extramfifo/fifo_extram36_tb.v b/fpga/usrp2/extramfifo/fifo_extram36_tb.v new file mode 100644 index 000000000..e5f8cef4c --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram36_tb.v @@ -0,0 +1,475 @@ +`timescale 1ns/1ns + +module fifo_extram36_tb(); + + reg clk = 0; + reg sram_clk = 0; + reg rst = 1; + reg clear = 0; + + reg Verbose = 0; // + integer ErrorCount = 0; + + initial #1000 rst = 0; +// always #125 clk = ~clk; + task task_CLK; + reg [7:0] ran; + begin + while (1) begin + ran = $random; + if (ran[1]) + #62 clk = ~clk; + else + #63 clk = !clk; + end + end + endtask // task_CLK + initial task_CLK; + +// always #100 sram_clk = ~sram_clk; + task task_SSRAM_clk; + reg [7:0] ran; + begin + while (1) begin + ran = $random; + if (ran[0]) + #49 sram_clk = ~sram_clk; + else + #51 sram_clk = ~sram_clk; + end + end + endtask // task_SSRAM_clk + initial task_SSRAM_clk; + + reg [31:0] f36_data = 32'hX; + reg [1:0] f36_occ = 0; + reg f36_sof = 0, f36_eof = 0; + + wire [35:0] f36_in = {1'b0,f36_occ,f36_eof,f36_sof,f36_data}; + reg src_rdy_f36i = 0; + wire dst_rdy_f36i; + + wire [35:0] f36_out; + wire src_rdy_f36o; + reg dst_rdy_f36o = 0; + + wire [17:0] sram_d; + wire [18:0] sram_a; + wire [1:0] sram_bw; + wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz; + + reg [31:0] ScoreBoard [524288:0]; + reg [18:0] put_index = 0; + reg [18:0] get_index = 0; + +// integer put_index = 0; +// integer get_index = 0; + + wire [15:0] DUT_space, DUT_occupied; + + fifo_extram36 fifo_extram36 + (.clk(clk), .reset(rst), .clear(clear), + .datain(f36_in), .src_rdy_i(src_rdy_f36i), .dst_rdy_o(dst_rdy_f36i), .space(DUT_space), + .dataout(f36_out), .src_rdy_o(src_rdy_f36o), .dst_rdy_i(dst_rdy_f36o), .occupied(DUT_occupied), + .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we), + .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe), + .sram_mode(sram_mode), .sram_zz(sram_zz)); + +`define idt 1 +`ifdef idt + wire [15:0] dummy16; + wire [1:0] dummy2; + + idt71v65603s150 + ram_model(.A(sram_a[17:0]), + .adv_ld_(sram_adv), // advance (high) / load (low) + .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low) + .ce1_(0), .ce2(1), .ce2_(0), // chip enables + .cen_(sram_ce), // clock enable (low) + .clk(sram_clk), // clock + .IO({dummy16,sram_d[15:0]}), + .IOP({dummy2,sram_d[17:16]}), // data bus + .lbo_(sram_mode), // linear burst order (low) + .oe_(sram_oe), // output enable (low) + .r_w_(sram_we)); // read (high) / write (low) +`else + cy1356 ram_model(.d(sram_d),.clk(~sram_clk),.a(sram_a), + .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv), + .ce1b(0),.ce2(1),.ce3b(0), + .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) ); +`endif + + task task_SSRAMMonitor; + reg last_mode; + reg last_clock; + reg last_load; + reg [18:0] sram_addr; + + begin + last_mode = 1'bX; + last_clock = 1'bX; + last_load = 1'bX; + + @ (posedge Verbose); + $dumpvars(0,fifo_extram36_tb); + + $display("%t:%m\t*** Task Started",$time); + while (1) @ (posedge sram_clk) begin + if (sram_mode !== last_mode) begin + $display("%t:%m\tSSRAM mode: %b",$time,sram_mode); + last_mode = sram_mode; + end + if (sram_adv !== last_load) begin + $display("%t:%m\tSSRAM adv/load: %b",$time,sram_adv); + last_load = sram_adv; + end + if (sram_ce !== last_clock) begin + $display("%t:%m\tSSRAM clock enable: %b",$time,sram_ce); + last_clock = sram_ce; + end + if (sram_ce == 1'b0) begin + if (sram_adv == 1'b0) begin +// $display("%t:%m\tSSRAM Address Load A=%h",$time,sram_a); + sram_addr = sram_a; + end else begin + sram_addr = sram_addr + 1; + end + if (sram_oe == 1'b0) begin + $display("%t:%m\tSSRAM Read Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d); + end + if (sram_we == 1'b0) begin + $display("%t:%m\tSSRAM Write Cycle A=%h(%h), D=%o",$time,sram_addr-2,sram_a,sram_d); + end + if ((sram_we == 1'b0) && (sram_oe == 1'b0)) begin + $display("%t:%m\t*** ERROR: _oe and _we both active",$time); + end + + end // if (sram_ce == 1'b0) + + end // always @ (posedge sram_clk) + end + endtask // task_SSRAMMonitor + + task ReadFromFIFO36; + begin + $display("%t: Read from FIFO36",$time); + #1 dst_rdy_f36o <= 1; + while(1) + begin + while(~src_rdy_f36o) + @(posedge clk); + $display("%t: Read: %h>",$time,f36_out); + @(posedge clk); + end + end + endtask // ReadFromFIFO36 + + initial dst_rdy_f36o = 0; + + task task_ReadFIFO36; + reg [7:0] ran; + begin + $display("%t:%m\t*** Task Started",$time); + while (1) begin + // Read on one of four clocks + #5 dst_rdy_f36o <= 1; + @(posedge clk); + if (src_rdy_f36o) begin + if (f36_out[31:0] != ScoreBoard[get_index]) begin + $display("%t:%m\tFIFO Get Error: R:%h, E:%h (%h)",$time,f36_out[31:0],ScoreBoard[get_index],get_index); + ErrorCount = ErrorCount + 1; + end else begin + if (Verbose) + $display("%t:%m\t(%5h) %o>",$time,get_index,f36_out); + end + get_index = get_index+1; + end else begin + if (ErrorCount >= 192) + $finish; + end // else: !if(src_rdy_f36o) + + #10; + ran = $random; + if (ran[2:0] != 3'b000) begin + dst_rdy_f36o <= 0; + if (ran[2] != 1'b0) begin + @(posedge clk); + @(posedge clk); + @(posedge clk); + end + if (ran[1] != 1'b0) begin + @(posedge clk); + @(posedge clk); + end + if (ran[0] != 1'b0) begin + @(posedge clk); + end + end + end // while (1) + end + + endtask // task_ReadFIFO36 + + + reg [15:0] count; + + task PutPacketInFIFO36; + input [31:0] data_start; + input [31:0] data_len; + + begin + count = 4; + src_rdy_f36i = 1; + f36_data = data_start; + f36_sof = 1; + f36_eof = 0; + f36_occ = 0; + + $display("%t: Put Packet in FIFO36",$time); + while(~dst_rdy_f36i) + #1; //@(posedge clk); + @(posedge clk); + + $display("%t: <%h PPI_FIFO36: Entered First Line",$time,f36_data); + f36_sof <= 0; + while(count+4 < data_len) + begin + f36_data = f36_data + 32'h01010101; + count = count + 4; + while(~dst_rdy_f36i) + #1; //@(posedge clk); + @(posedge clk); + $display("%t: <%h PPI_FIFO36: Entered New Line",$time,f36_data); + end + f36_data <= f36_data + 32'h01010101; + f36_eof <= 1; + if(count + 4 == data_len) + f36_occ <= 0; + else if(count + 3 == data_len) + f36_occ <= 3; + else if(count + 2 == data_len) + f36_occ <= 2; + else + f36_occ <= 1; + while(~dst_rdy_f36i) + @(posedge clk); + @(posedge clk); + f36_occ <= 0; + f36_eof <= 0; + f36_data <= 0; + src_rdy_f36i <= 0; + $display("%t: <%h PPI_FIFO36: Entered Last Line",$time,f36_data); + end + endtask // PutPacketInFIFO36 + + task task_WriteFIFO36; + integer i; + reg [7:0] ran; + + begin + f36_data = 32'bX; + if (rst != 1'b0) + @ (negedge rst); + $display("%t:%m\t*** Task Started",$time); + #10; + src_rdy_f36i = 1; + f36_data = $random; + for (i=0; i<64; i=i+0 ) begin + @ (posedge clk) ; + if (dst_rdy_f36i) begin + if (Verbose) + $display("%t:%m\t(%5h) %o<",$time,put_index,f36_in); + ScoreBoard[put_index] = f36_in[31:0]; + put_index = put_index + 1; + #5; + f36_data = $random; + i = i + 1; + end + ran = $random; + if (ran[1:0] != 2'b00) begin + @ (negedge clk); + src_rdy_f36i = 0; + #5; + @ (negedge clk) ; + src_rdy_f36i = 1; + end + end + src_rdy_f36i = 0; + f36_data = 32'bX; +// if (put_index > 19'h3ff00) +// Verbose = 1'b1; + + end + endtask // task_WriteFIFO36 + + initial $dumpfile("fifo_extram36_tb.vcd"); +// initial $dumpvars(0,fifo_extram36_tb); + initial $timeformat(-9, 0, " ns", 10); + initial task_SSRAMMonitor; + + initial + begin + @(negedge rst); + #40000; + @(posedge clk); + @(posedge clk); + @(posedge clk); + @(posedge clk); +// ReadFromFIFO36; + task_ReadFIFO36; + + end + + integer i; + + initial + begin + @(negedge rst); + @(posedge clk); + @(posedge clk); + @(posedge clk); + task_WriteFIFO36; + @(posedge clk); + @(posedge clk); + @(posedge clk); +// PutPacketInFIFO36(32'hA0B0C0D0,12); + @(posedge clk); + @(posedge clk); + #10000; + @(posedge clk); +// PutPacketInFIFO36(32'hE0F0A0B0,36); + @(posedge clk); + @(posedge clk); + task_WriteFIFO36; + @(posedge clk); + @(posedge clk); + #10000; + @(posedge clk); + @(posedge clk); + task_WriteFIFO36; +// @(posedge clk); +// #30000; +// @(posedge clk); +// @(posedge clk); + task_WriteFIFO36; +// @(posedge clk); +// #30000; +// @(posedge clk); +// @(posedge clk); + task_WriteFIFO36; +// @(posedge clk); +// #30000; +// @(posedge clk); +// @(posedge clk); + task_WriteFIFO36; + @(posedge clk); + #10000; + @(posedge clk); + @(posedge clk); + task_WriteFIFO36; + for (i=0; i<8192; i = i+1) begin + @(posedge clk); + #10000; + @(posedge clk); + @(posedge clk); + task_WriteFIFO36; + @(posedge clk); + end + +// $dumpvars(0,fifo_extram36_tb); + @(posedge clk); + task_WriteFIFO36; + @(posedge clk); + + #100000000; + $finish; + + end + + + initial + begin + @(negedge rst); + f36_occ <= 0; + repeat (100) + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= 32'h10203040; + f36_sof <= 1; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= f36_data + 32'h01010101; + f36_sof <= 0; + f36_eof <= 0; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 1; + f36_data <= 32'h1F2F3F4F; + f36_sof <= 0; + f36_eof <= 1; + @(posedge clk); + @(posedge clk); + src_rdy_f36i <= 0; + + + + end + +// initial #500000 $finish; +endmodule // fifo_extram_tb diff --git a/fpga/usrp2/extramfifo/fifo_extram_tb.build b/fpga/usrp2/extramfifo/fifo_extram_tb.build new file mode 100755 index 000000000..5607c8691 --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram_tb.build @@ -0,0 +1 @@ +iverilog -y ../models -y . -y ../control_lib/ -y ../coregen -y ../fifo -y /opt/Xilinx/10.1/ISE/verilog/src/XilinxCoreLib -y /opt/Xilinx/10.1/ISE/verilog/src/unisims/ -o fifo_extram_tb fifo_extram_tb.v diff --git a/fpga/usrp2/extramfifo/fifo_extram_tb.v b/fpga/usrp2/extramfifo/fifo_extram_tb.v new file mode 100644 index 000000000..73550d9ca --- /dev/null +++ b/fpga/usrp2/extramfifo/fifo_extram_tb.v @@ -0,0 +1,134 @@ +module fifo_extram_tb(); + + reg clk = 0; + reg sram_clk = 0; + reg reset = 1; + reg clear = 0; + + initial #1000 reset = 0; + always #125 clk = ~clk; + always #100 sram_clk = ~sram_clk; + + reg [15:0] f18_data = 0; + reg f18_sof = 0, f18_eof = 0; + + wire [17:0] f18_in = {f18_eof,f18_sof,f18_data}; + reg src_rdy_f18i = 0; + wire dst_rdy_f18i; + + wire [17:0] f18_out; + wire src_rdy_f18o; + reg dst_rdy_f18o = 0; + + wire [17:0] f18_int; + wire src_rdy_f18int, dst_rdy_f18int; + + wire [17:0] sram_d; + wire [18:0] sram_a; + wire [1:0] sram_bw; + wire sram_we, sram_adv, sram_ce, sram_oe, sram_mode, sram_zz; + wire [15:0] f1_occ; + + fifo_short #(.WIDTH(18)) fifo_short + (.clk(sram_clk), .reset(reset), .clear(clear), + .datain(f18_in), .src_rdy_i(src_rdy_f18i), .dst_rdy_o(dst_rdy_f18i), .space(), + .dataout(f18_int), .src_rdy_o(src_rdy_f18int), .dst_rdy_i(dst_rdy_f18int), .occupied(f1_occ[4:0]) ); + + assign f1_occ[15:5] = 0; + + fifo_extram fifo_extram + (.reset(reset), .clear(clear), + .datain(f18_int), .src_rdy_i(src_rdy_f18int), .dst_rdy_o(dst_rdy_f18int), .space(), .occ_in(f1_occ), + .dataout(f18_out), .src_rdy_o(src_rdy_f18o), .dst_rdy_i(dst_rdy_f18o), .occupied(), .space_in(7), + .sram_clk(sram_clk), .sram_a(sram_a), .sram_d(sram_d), .sram_we(sram_we), + .sram_bw(sram_bw), .sram_adv(sram_adv), .sram_ce(sram_ce), .sram_oe(sram_oe), + .sram_mode(sram_mode), .sram_zz(sram_zz)); + +`define idt 1 +`ifdef idt + wire [15:0] dummy16; + wire [1:0] dummy2; + + idt71v65603s150 + ram_model(.A(sram_a[17:0]), + .adv_ld_(sram_adv), // advance (high) / load (low) + .bw1_(0), .bw2_(0), .bw3_(0), .bw4_(0), // byte write enables (low) + .ce1_(0), .ce2(1), .ce2_(0), // chip enables + .cen_(sram_ce), // clock enable (low) + .clk(sram_clk), // clock + .IO({dummy16,sram_d[15:0]}), + .IOP({dummy2,sram_d[17:16]}), // data bus + .lbo_(sram_mode), // linear burst order (low) + .oe_(sram_oe), // output enable (low) + .r_w_(sram_we)); // read (high) / write (low) +`else + cy1356 ram_model(.d(sram_d),.clk(sram_clk),.a(sram_a), + .bws(2'b00),.we_b(sram_we),.adv_lb(sram_adv), + .ce1b(0),.ce2(1),.ce3b(0), + .oeb(sram_oe),.cenb(sram_ce),.mode(sram_mode) ); +`endif // !`ifdef idt + + always @(posedge sram_clk) + if(dst_rdy_f18o & src_rdy_f18o) + $display("Read: %h",f18_out); + + always @(posedge sram_clk) + if(dst_rdy_f18int & src_rdy_f18int) + $display("Write: %h",f18_int); + + initial $dumpfile("fifo_extram_tb.vcd"); + initial $dumpvars(0,fifo_extram_tb); + + task SendPkt; + input [15:0] data_start; + input [31:0] data_len; + begin + @(posedge sram_clk); + f18_data = data_start; + f18_sof = 1; + f18_eof = 0; + src_rdy_f18i = 1; + while(~dst_rdy_f18i) + #1; + @(posedge sram_clk); + repeat(data_len - 2) + begin + f18_data = f18_data + 16'h0101; + f18_sof = 0; + while(~dst_rdy_f18i) + @(posedge sram_clk); + + @(posedge sram_clk); + end + f18_data = f18_data + 16'h0101; + f18_eof = 1; + while(~dst_rdy_f18i) + #1; + @(posedge sram_clk); + src_rdy_f18i = 0; + f18_data = 0; + f18_eof = 0; + end + endtask // SendPkt + + initial + begin + @(negedge reset); + @(posedge sram_clk); + @(posedge sram_clk); + #10000; + @(posedge sram_clk); + SendPkt(16'hA0B0, 100); + #10000; + //SendPkt(16'hC0D0, 220); + end + + initial + begin + #20000; + dst_rdy_f18o = 1; + end + + initial #200000 $finish; +endmodule // fifo_extram_tb + diff --git a/fpga/usrp2/extramfifo/icon.v b/fpga/usrp2/extramfifo/icon.v new file mode 100644 index 000000000..6537e9340 --- /dev/null +++ b/fpga/usrp2/extramfifo/icon.v @@ -0,0 +1,1286 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor: Xilinx +// \ \ \/ Version: M.53d +// \ \ Application: netgen +// / / Filename: icon.v +// /___/ /\ Timestamp: Tue Jul 20 20:31:15 2010 +// \ \ / \ +// \___\/\___\ +// +// Command : -w -sim -ofmt verilog /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/icon.ngc /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/icon.v +// Device : xc3s2000-fg456-5 +// Input file : /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/icon.ngc +// Output file : /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/icon.v +// # of Modules : 1 +// Design Name : icon +// Xilinx : /opt/Xilinx/12.1/ISE_DS/ISE +// +// Purpose: +// This verilog netlist is a verification model and uses simulation +// primitives which may not represent the true implementation of the +// device, however the netlist is functionally correct and should not +// be modified. This file cannot be synthesized and should only be used +// with supported simulation tools. +// +// Reference: +// Command Line Tools User Guide, Chapter 23 and Synthesis and Simulation Design Guide, Chapter 6 +// +//////////////////////////////////////////////////////////////////////////////// + +`timescale 1 ns/1 ps + +module icon ( +CONTROL0 +)/* synthesis syn_black_box syn_noprune=1 */; + inout [35 : 0] CONTROL0; + + // synthesis translate_off + + wire N1; + wire \U0/U_ICON/I_YES_BSCAN.U_BS/DRCK1 ; + wire \U0/U_ICON/U_CMD/iSEL_n ; + wire \U0/U_ICON/U_CMD/iTARGET_CE ; + wire \U0/U_ICON/U_CTRL_OUT/iDATA_VALID ; + wire \U0/U_ICON/U_STAT/iCMD_GRP0_SEL ; + wire \U0/U_ICON/U_STAT/iDATA_VALID ; + wire \U0/U_ICON/U_STAT/iSTATCMD_CE ; + wire \U0/U_ICON/U_STAT/iSTATCMD_CE_n ; + wire \U0/U_ICON/U_STAT/iSTAT_HIGH ; + wire \U0/U_ICON/U_STAT/iSTAT_LOW ; + wire \U0/U_ICON/U_STAT/iTDO_next ; + wire \U0/U_ICON/U_SYNC/iDATA_CMD_n ; + wire \U0/U_ICON/U_SYNC/iGOT_SYNC ; + wire \U0/U_ICON/U_SYNC/iGOT_SYNC_HIGH ; + wire \U0/U_ICON/U_SYNC/iGOT_SYNC_LOW ; + wire \U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_3_91 ; + wire \U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_4_92 ; + wire \U0/U_ICON/iCORE_ID_SEL[0] ; + wire \U0/U_ICON/iCORE_ID_SEL[15] ; + wire \U0/U_ICON/iDATA_CMD ; + wire \U0/U_ICON/iDATA_CMD_n ; + wire \U0/U_ICON/iSEL ; + wire \U0/U_ICON/iSEL_n ; + wire \U0/U_ICON/iSYNC ; + wire \U0/U_ICON/iTDI ; + wire \U0/U_ICON/iTDO ; + wire \U0/U_ICON/iTDO_next ; + wire \U0/iSHIFT_OUT ; + wire \U0/iUPDATE_OUT ; + wire \NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_DRCK2_UNCONNECTED ; + wire \NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_RESET_UNCONNECTED ; + wire \NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_CAPTURE_UNCONNECTED ; + wire \NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_SEL2_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[1].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[2].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[3].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[4].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[5].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[6].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[7].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[8].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[9].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[10].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[11].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[12].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[13].U_LUT_O_UNCONNECTED ; + wire \NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[14].U_LUT_O_UNCONNECTED ; + wire [11 : 8] \U0/U_ICON/U_CMD/iTARGET ; + wire [1 : 0] \U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL ; + wire [5 : 1] \U0/U_ICON/U_STAT/U_STAT_CNT/CI ; + wire [5 : 0] \U0/U_ICON/U_STAT/U_STAT_CNT/D ; + wire [5 : 0] \U0/U_ICON/U_STAT/U_STAT_CNT/S ; + wire [3 : 0] \U0/U_ICON/U_STAT/iSTAT ; + wire [5 : 0] \U0/U_ICON/U_STAT/iSTAT_CNT ; + wire [6 : 0] \U0/U_ICON/U_SYNC/iSYNC_WORD ; + wire [1 : 0] \U0/U_ICON/iCOMMAND_GRP ; + wire [15 : 0] \U0/U_ICON/iCOMMAND_SEL ; + wire [3 : 0] \U0/U_ICON/iCORE_ID ; + wire [15 : 15] \U0/U_ICON/iTDO_VEC ; + GND XST_GND ( + .G(CONTROL0[2]) + ); + VCC XST_VCC ( + .P(N1) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_TDI_reg ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/iTDI ), + .Q(CONTROL0[1]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_TDO_reg ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/iTDO_next ), + .Q(\U0/U_ICON/iTDO ) + ); + FDC #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_iDATA_CMD ( + .C(\U0/iUPDATE_OUT ), + .CLR(\U0/U_ICON/iSEL_n ), + .D(\U0/U_ICON/iDATA_CMD_n ), + .Q(\U0/U_ICON/iDATA_CMD ) + ); + MUXF5 \U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_2_f5 ( + .I0(\U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_4_92 ), + .I1(\U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_3_91 ), + .S(\U0/U_ICON/iCORE_ID [3]), + .O(\U0/U_ICON/iTDO_next ) + ); + LUT4 #( + .INIT ( 16'h0002 )) + \U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_4 ( + .I0(CONTROL0[3]), + .I1(\U0/U_ICON/iCORE_ID [0]), + .I2(\U0/U_ICON/iCORE_ID [1]), + .I3(\U0/U_ICON/iCORE_ID [2]), + .O(\U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_4_92 ) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_3 ( + .I0(\U0/U_ICON/iTDO_VEC [15]), + .I1(\U0/U_ICON/iCORE_ID [0]), + .I2(\U0/U_ICON/iCORE_ID [1]), + .I3(\U0/U_ICON/iCORE_ID [2]), + .O(\U0/U_ICON/U_TDO_MUX/U_CS_MUX/I4.U_MUX16/Mmux_O_3_91 ) + ); + INV \U0/U_ICON/U_iSEL_n ( + .I(\U0/U_ICON/iSEL ), + .O(\U0/U_ICON/iSEL_n ) + ); + INV \U0/U_ICON/U_iDATA_CMD_n ( + .I(\U0/U_ICON/iDATA_CMD ), + .O(\U0/U_ICON/iDATA_CMD_n ) + ); + BSCAN_SPARTAN3 \U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS ( + .TDI(\U0/U_ICON/iTDI ), + .SHIFT(\U0/iSHIFT_OUT ), + .DRCK1(\U0/U_ICON/I_YES_BSCAN.U_BS/DRCK1 ), + .DRCK2(\NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_DRCK2_UNCONNECTED ), + .RESET(\NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_RESET_UNCONNECTED ), + .UPDATE(\U0/iUPDATE_OUT ), + .TDO1(\U0/U_ICON/iTDO ), + .TDO2(CONTROL0[2]), + .CAPTURE(\NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_CAPTURE_UNCONNECTED ), + .SEL1(\U0/U_ICON/iSEL ), + .SEL2(\NLW_U0/U_ICON/I_YES_BSCAN.U_BS/I_SPARTAN3.ISYN.I_USE_SOFTBSCAN_EQ0.I_3.U_BS_SEL2_UNCONNECTED ) + ); + icon_bscan_bufg \U0/U_ICON/I_YES_BSCAN.U_BS/I_USE_SOFTBSCAN_EQ0.I_USE_XST_TCK_WORKAROUND_EQ1.U_ICON_BSCAN_BUFG ( + .DRCK_LOCAL_I(\U0/U_ICON/I_YES_BSCAN.U_BS/DRCK1 ), + .DRCK_LOCAL_O(CONTROL0[0]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/U_ICON/U_SYNC/U_GOT_SYNC ( + .I0(\U0/U_ICON/U_SYNC/iGOT_SYNC_LOW ), + .I1(\U0/U_ICON/U_SYNC/iGOT_SYNC_HIGH ), + .O(\U0/U_ICON/U_SYNC/iGOT_SYNC ) + ); + LUT4 #( + .INIT ( 16'h0200 )) + \U0/U_ICON/U_SYNC/U_GOT_SYNC_L ( + .I0(\U0/U_ICON/U_SYNC/iSYNC_WORD [0]), + .I1(\U0/U_ICON/U_SYNC/iSYNC_WORD [1]), + .I2(\U0/U_ICON/U_SYNC/iSYNC_WORD [2]), + .I3(\U0/U_ICON/U_SYNC/iSYNC_WORD [3]), + .O(\U0/U_ICON/U_SYNC/iGOT_SYNC_LOW ) + ); + LUT4 #( + .INIT ( 16'h0400 )) + \U0/U_ICON/U_SYNC/U_GOT_SYNC_H ( + .I0(\U0/U_ICON/U_SYNC/iSYNC_WORD [4]), + .I1(\U0/U_ICON/U_SYNC/iSYNC_WORD [5]), + .I2(\U0/U_ICON/U_SYNC/iSYNC_WORD [6]), + .I3(CONTROL0[1]), + .O(\U0/U_ICON/U_SYNC/iGOT_SYNC_HIGH ) + ); + INV \U0/U_ICON/U_SYNC/U_iDATA_CMD_n ( + .I(\U0/U_ICON/iDATA_CMD ), + .O(\U0/U_ICON/U_SYNC/iDATA_CMD_n ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/U_SYNC ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_SYNC/iGOT_SYNC ), + .D(N1), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/iSYNC ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[0].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [1]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [0]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[1].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [2]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [1]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[2].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [3]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [2]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[3].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [4]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [3]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[4].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [5]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [4]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[5].I_NE0.U_FDR ( + .C(CONTROL0[0]), + .D(\U0/U_ICON/U_SYNC/iSYNC_WORD [6]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [5]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_SYNC/G_SYNC_WORD[6].I_EQ0.U_FDR ( + .C(CONTROL0[0]), + .D(CONTROL0[1]), + .R(\U0/U_ICON/U_SYNC/iDATA_CMD_n ), + .Q(\U0/U_ICON/U_SYNC/iSYNC_WORD [6]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[0].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [0]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[20]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[0].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [0]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[4]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[1].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [1]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[21]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[1].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [1]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[5]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[2].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [2]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[22]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[2].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [2]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[6]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[3].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [3]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[23]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[3].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [3]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[7]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[4].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [4]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[24]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[4].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [4]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[8]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[5].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [5]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[25]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[5].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [5]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[9]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[6].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [6]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[26]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[6].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [6]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[10]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[7].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [7]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[27]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[7].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [7]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[11]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[8].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [8]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[28]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[8].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [8]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[12]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[9].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [9]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[29]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[9].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [9]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[13]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[10].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [10]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[30]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[10].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [10]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[14]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[11].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [11]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[31]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[11].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [11]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[15]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[12].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [12]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[32]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[12].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [12]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[16]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[13].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [13]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[33]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[13].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [13]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[17]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[14].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [14]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[34]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[14].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [14]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[18]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[15].U_HCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [15]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]), + .O(CONTROL0[35]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CTRL_OUT/F_NCP[0].F_CMD[15].U_LCE ( + .I0(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [15]), + .I2(\U0/U_ICON/iCORE_ID_SEL[0] ), + .I3(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]), + .O(CONTROL0[19]) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/U_ICON/U_CTRL_OUT/U_CMDGRP1 ( + .I0(\U0/U_ICON/iCOMMAND_GRP [0]), + .I1(\U0/U_ICON/iCOMMAND_GRP [1]), + .O(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [1]) + ); + LUT2 #( + .INIT ( 4'h1 )) + \U0/U_ICON/U_CTRL_OUT/U_CMDGRP0 ( + .I0(\U0/U_ICON/iCOMMAND_GRP [0]), + .I1(\U0/U_ICON/iCOMMAND_GRP [1]), + .O(\U0/U_ICON/U_CTRL_OUT/iCOMMAND_GRP_SEL [0]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/U_ICON/U_CTRL_OUT/U_DATA_VALID ( + .I0(\U0/U_ICON/iSYNC ), + .I1(\U0/iSHIFT_OUT ), + .O(\U0/U_ICON/U_CTRL_OUT/iDATA_VALID ) + ); + LUT4 #( + .INIT ( 16'h0001 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[0].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\U0/U_ICON/iCORE_ID_SEL[0] ) + ); + LUT4 #( + .INIT ( 16'h0002 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[1].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[1].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0004 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[2].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[2].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0008 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[3].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[3].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0010 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[4].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[4].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0020 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[5].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[5].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0040 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[6].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[6].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0080 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[7].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[7].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0100 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[8].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[8].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0200 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[9].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[9].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0400 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[10].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[10].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0800 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[11].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[11].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h1000 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[12].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[12].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h2000 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[13].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[13].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h4000 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[14].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\NLW_U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[14].U_LUT_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CMD/U_CORE_ID_SEL/I4.FI[15].U_LUT ( + .I0(\U0/U_ICON/iCORE_ID [0]), + .I1(\U0/U_ICON/iCORE_ID [1]), + .I2(\U0/U_ICON/iCORE_ID [2]), + .I3(\U0/U_ICON/iCORE_ID [3]), + .O(\U0/U_ICON/iCORE_ID_SEL[15] ) + ); + LUT4 #( + .INIT ( 16'h0001 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[0].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [0]) + ); + LUT4 #( + .INIT ( 16'h0002 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[1].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [1]) + ); + LUT4 #( + .INIT ( 16'h0004 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[2].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [2]) + ); + LUT4 #( + .INIT ( 16'h0008 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[3].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [3]) + ); + LUT4 #( + .INIT ( 16'h0010 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[4].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [4]) + ); + LUT4 #( + .INIT ( 16'h0020 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[5].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [5]) + ); + LUT4 #( + .INIT ( 16'h0040 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[6].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [6]) + ); + LUT4 #( + .INIT ( 16'h0080 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[7].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [7]) + ); + LUT4 #( + .INIT ( 16'h0100 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[8].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [8]) + ); + LUT4 #( + .INIT ( 16'h0200 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[9].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [9]) + ); + LUT4 #( + .INIT ( 16'h0400 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[10].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [10]) + ); + LUT4 #( + .INIT ( 16'h0800 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[11].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [11]) + ); + LUT4 #( + .INIT ( 16'h1000 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[12].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [12]) + ); + LUT4 #( + .INIT ( 16'h2000 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[13].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [13]) + ); + LUT4 #( + .INIT ( 16'h4000 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[14].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [14]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_CMD/U_COMMAND_SEL/I4.FI[15].U_LUT ( + .I0(\U0/U_ICON/U_CMD/iTARGET [8]), + .I1(\U0/U_ICON/U_CMD/iTARGET [9]), + .I2(\U0/U_ICON/U_CMD/iTARGET [10]), + .I3(\U0/U_ICON/U_CMD/iTARGET [11]), + .O(\U0/U_ICON/iCOMMAND_SEL [15]) + ); + LUT2 #( + .INIT ( 4'h4 )) + \U0/U_ICON/U_CMD/U_TARGET_CE ( + .I0(\U0/U_ICON/iDATA_CMD ), + .I1(\U0/iSHIFT_OUT ), + .O(\U0/U_ICON/U_CMD/iTARGET_CE ) + ); + INV \U0/U_ICON/U_CMD/U_SEL_n ( + .I(\U0/U_ICON/iSEL ), + .O(\U0/U_ICON/U_CMD/iSEL_n ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[6].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/iCOMMAND_GRP [1]), + .Q(\U0/U_ICON/iCOMMAND_GRP [0]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[7].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/U_CMD/iTARGET [8]), + .Q(\U0/U_ICON/iCOMMAND_GRP [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[8].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/U_CMD/iTARGET [9]), + .Q(\U0/U_ICON/U_CMD/iTARGET [8]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[9].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/U_CMD/iTARGET [10]), + .Q(\U0/U_ICON/U_CMD/iTARGET [9]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[10].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/U_CMD/iTARGET [11]), + .Q(\U0/U_ICON/U_CMD/iTARGET [10]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[11].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/iCORE_ID [0]), + .Q(\U0/U_ICON/U_CMD/iTARGET [11]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[12].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/iCORE_ID [1]), + .Q(\U0/U_ICON/iCORE_ID [0]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[13].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/iCORE_ID [2]), + .Q(\U0/U_ICON/iCORE_ID [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[14].I_NE0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(\U0/U_ICON/iCORE_ID [3]), + .Q(\U0/U_ICON/iCORE_ID [2]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_CMD/G_TARGET[15].I_EQ0.U_TARGET ( + .C(CONTROL0[0]), + .CE(\U0/U_ICON/U_CMD/iTARGET_CE ), + .CLR(\U0/U_ICON/U_CMD/iSEL_n ), + .D(CONTROL0[1]), + .Q(\U0/U_ICON/iCORE_ID [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[5].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [5]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[4].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [4]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[3].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [3]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[2].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [2]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[1].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [1]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[0].U_FDRE ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/U_STAT_CNT/D [0]), + .R(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/U_ICON/U_STAT/iSTAT_CNT [0]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[5].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [5]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [5]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[5].U_XORCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [5]), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [5]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [5]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[4].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [4]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [4]) + ); + MUXCY_L \U0/U_ICON/U_STAT/U_STAT_CNT/G[4].GnH.U_MUXCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [4]), + .DI(CONTROL0[2]), + .S(\U0/U_ICON/U_STAT/U_STAT_CNT/S [4]), + .LO(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [5]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[4].U_XORCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [4]), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [4]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [4]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[3].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [3]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [3]) + ); + MUXCY_L \U0/U_ICON/U_STAT/U_STAT_CNT/G[3].GnH.U_MUXCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [3]), + .DI(CONTROL0[2]), + .S(\U0/U_ICON/U_STAT/U_STAT_CNT/S [3]), + .LO(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [4]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[3].U_XORCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [3]), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [3]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [3]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[2].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [2]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [2]) + ); + MUXCY_L \U0/U_ICON/U_STAT/U_STAT_CNT/G[2].GnH.U_MUXCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [2]), + .DI(CONTROL0[2]), + .S(\U0/U_ICON/U_STAT/U_STAT_CNT/S [2]), + .LO(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [3]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[2].U_XORCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [2]), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [2]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [2]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[1].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [1]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [1]) + ); + MUXCY_L \U0/U_ICON/U_STAT/U_STAT_CNT/G[1].GnH.U_MUXCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [1]), + .DI(CONTROL0[2]), + .S(\U0/U_ICON/U_STAT/U_STAT_CNT/S [1]), + .LO(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [2]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[1].U_XORCY ( + .CI(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [1]), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [1]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [1]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/U_ICON/U_STAT/U_STAT_CNT/G[0].U_LUT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [0]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/S [0]) + ); + MUXCY_L \U0/U_ICON/U_STAT/U_STAT_CNT/G[0].GnH.U_MUXCY ( + .CI(N1), + .DI(CONTROL0[2]), + .S(\U0/U_ICON/U_STAT/U_STAT_CNT/S [0]), + .LO(\U0/U_ICON/U_STAT/U_STAT_CNT/CI [1]) + ); + XORCY \U0/U_ICON/U_STAT/U_STAT_CNT/G[0].U_XORCY ( + .CI(N1), + .LI(\U0/U_ICON/U_STAT/U_STAT_CNT/S [0]), + .O(\U0/U_ICON/U_STAT/U_STAT_CNT/D [0]) + ); + MUXF6 \U0/U_ICON/U_STAT/U_TDO_next ( + .I0(\U0/U_ICON/U_STAT/iSTAT_LOW ), + .I1(\U0/U_ICON/U_STAT/iSTAT_HIGH ), + .S(\U0/U_ICON/U_STAT/iSTAT_CNT [5]), + .O(\U0/U_ICON/U_STAT/iTDO_next ) + ); + MUXF5 \U0/U_ICON/U_STAT/U_STAT_LOW ( + .I0(\U0/U_ICON/U_STAT/iSTAT [0]), + .I1(\U0/U_ICON/U_STAT/iSTAT [1]), + .S(\U0/U_ICON/U_STAT/iSTAT_CNT [4]), + .O(\U0/U_ICON/U_STAT/iSTAT_LOW ) + ); + MUXF5 \U0/U_ICON/U_STAT/U_STAT_HIGH ( + .I0(\U0/U_ICON/U_STAT/iSTAT [2]), + .I1(\U0/U_ICON/U_STAT/iSTAT [3]), + .S(\U0/U_ICON/U_STAT/iSTAT_CNT [4]), + .O(\U0/U_ICON/U_STAT/iSTAT_HIGH ) + ); + LUT4 #( + .INIT ( 16'h0101 )) + \U0/U_ICON/U_STAT/F_STAT[0].U_STAT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [0]), + .I1(\U0/U_ICON/U_STAT/iSTAT_CNT [1]), + .I2(\U0/U_ICON/U_STAT/iSTAT_CNT [2]), + .I3(\U0/U_ICON/U_STAT/iSTAT_CNT [3]), + .O(\U0/U_ICON/U_STAT/iSTAT [0]) + ); + LUT4 #( + .INIT ( 16'hC101 )) + \U0/U_ICON/U_STAT/F_STAT[1].U_STAT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [0]), + .I1(\U0/U_ICON/U_STAT/iSTAT_CNT [1]), + .I2(\U0/U_ICON/U_STAT/iSTAT_CNT [2]), + .I3(\U0/U_ICON/U_STAT/iSTAT_CNT [3]), + .O(\U0/U_ICON/U_STAT/iSTAT [1]) + ); + LUT4 #( + .INIT ( 16'h2100 )) + \U0/U_ICON/U_STAT/F_STAT[2].U_STAT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [0]), + .I1(\U0/U_ICON/U_STAT/iSTAT_CNT [1]), + .I2(\U0/U_ICON/U_STAT/iSTAT_CNT [2]), + .I3(\U0/U_ICON/U_STAT/iSTAT_CNT [3]), + .O(\U0/U_ICON/U_STAT/iSTAT [2]) + ); + LUT4 #( + .INIT ( 16'h1610 )) + \U0/U_ICON/U_STAT/F_STAT[3].U_STAT ( + .I0(\U0/U_ICON/U_STAT/iSTAT_CNT [0]), + .I1(\U0/U_ICON/U_STAT/iSTAT_CNT [1]), + .I2(\U0/U_ICON/U_STAT/iSTAT_CNT [2]), + .I3(\U0/U_ICON/U_STAT/iSTAT_CNT [3]), + .O(\U0/U_ICON/U_STAT/iSTAT [3]) + ); + INV \U0/U_ICON/U_STAT/U_STATCMD_n ( + .I(\U0/U_ICON/U_STAT/iSTATCMD_CE ), + .O(\U0/U_ICON/U_STAT/iSTATCMD_CE_n ) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_ICON/U_STAT/U_STATCMD ( + .I0(\U0/U_ICON/U_STAT/iDATA_VALID ), + .I1(\U0/U_ICON/iCOMMAND_SEL [0]), + .I2(\U0/U_ICON/iCORE_ID_SEL[15] ), + .I3(\U0/U_ICON/U_STAT/iCMD_GRP0_SEL ), + .O(\U0/U_ICON/U_STAT/iSTATCMD_CE ) + ); + LUT2 #( + .INIT ( 4'h1 )) + \U0/U_ICON/U_STAT/U_CMDGRP0 ( + .I0(\U0/U_ICON/iCOMMAND_GRP [0]), + .I1(\U0/U_ICON/iCOMMAND_GRP [1]), + .O(\U0/U_ICON/U_STAT/iCMD_GRP0_SEL ) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/U_ICON/U_STAT/U_DATA_VALID ( + .I0(\U0/U_ICON/iSYNC ), + .I1(\U0/iSHIFT_OUT ), + .O(\U0/U_ICON/U_STAT/iDATA_VALID ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/U_ICON/U_STAT/U_TDO ( + .C(CONTROL0[0]), + .CE(N1), + .D(\U0/U_ICON/U_STAT/iTDO_next ), + .Q(\U0/U_ICON/iTDO_VEC [15]) + ); + +// synthesis translate_on + +endmodule + +// synthesis translate_off + +`ifndef GLBL +`define GLBL + +`timescale 1 ps / 1 ps + +module glbl (); + + parameter ROC_WIDTH = 100000; + parameter TOC_WIDTH = 0; + + wire GSR; + wire GTS; + wire GWE; + wire PRLD; + tri1 p_up_tmp; + tri (weak1, strong0) PLL_LOCKG = p_up_tmp; + + reg GSR_int; + reg GTS_int; + reg PRLD_int; + +//-------- JTAG Globals -------------- + wire JTAG_TDO_GLBL; + wire JTAG_TCK_GLBL; + wire JTAG_TDI_GLBL; + wire JTAG_TMS_GLBL; + wire JTAG_TRST_GLBL; + + reg JTAG_CAPTURE_GLBL; + reg JTAG_RESET_GLBL; + reg JTAG_SHIFT_GLBL; + reg JTAG_UPDATE_GLBL; + reg JTAG_RUNTEST_GLBL; + + reg JTAG_SEL1_GLBL = 0; + reg JTAG_SEL2_GLBL = 0 ; + reg JTAG_SEL3_GLBL = 0; + reg JTAG_SEL4_GLBL = 0; + + reg JTAG_USER_TDO1_GLBL = 1'bz; + reg JTAG_USER_TDO2_GLBL = 1'bz; + reg JTAG_USER_TDO3_GLBL = 1'bz; + reg JTAG_USER_TDO4_GLBL = 1'bz; + + assign (weak1, weak0) GSR = GSR_int; + assign (weak1, weak0) GTS = GTS_int; + assign (weak1, weak0) PRLD = PRLD_int; + + initial begin + GSR_int = 1'b1; + PRLD_int = 1'b1; + #(ROC_WIDTH) + GSR_int = 1'b0; + PRLD_int = 1'b0; + end + + initial begin + GTS_int = 1'b1; + #(TOC_WIDTH) + GTS_int = 1'b0; + end + +endmodule + +`endif + +// synthesis translate_on diff --git a/fpga/usrp2/extramfifo/icon.xco b/fpga/usrp2/extramfifo/icon.xco new file mode 100644 index 000000000..fda273149 --- /dev/null +++ b/fpga/usrp2/extramfifo/icon.xco @@ -0,0 +1,47 @@ +############################################################## +# +# Xilinx Core Generator version 12.1 +# Date: Wed Jul 21 03:31:19 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc3s2000 +SET devicefamily = spartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = fg456 +SET removerpms = false +SET simulationfiles = Structural +SET speedgrade = -5 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT ICON_(ChipScope_Pro_-_Integrated_Controller) family Xilinx,_Inc. 1.04.a +# END Select +# BEGIN Parameters +CSET component_name=icon +CSET enable_jtag_bufg=true +CSET number_control_ports=1 +CSET use_ext_bscan=false +CSET use_softbscan=false +CSET use_unused_bscan=false +CSET user_scan_chain=USER1 +# END Parameters +GENERATE +# CRC: 799ba5a1 diff --git a/fpga/usrp2/extramfifo/ila.v b/fpga/usrp2/extramfifo/ila.v new file mode 100644 index 000000000..b0d8f8d0c --- /dev/null +++ b/fpga/usrp2/extramfifo/ila.v @@ -0,0 +1,5544 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. +//////////////////////////////////////////////////////////////////////////////// +// ____ ____ +// / /\/ / +// /___/ \ / Vendor: Xilinx +// \ \ \/ Version: M.53d +// \ \ Application: netgen +// / / Filename: ila.v +// /___/ /\ Timestamp: Wed Jul 21 11:51:09 2010 +// \ \ / \ +// \___\/\___\ +// +// Command : -w -sim -ofmt verilog /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/ila.ngc /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/ila.v +// Device : xc3s2000-fg456-5 +// Input file : /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/ila.ngc +// Output file : /home/ianb/ettus/sram_fifo/fpgapriv/usrp2/extramfifo/tmp/_cg/ila.v +// # of Modules : 1 +// Design Name : ila +// Xilinx : /opt/Xilinx/12.1/ISE_DS/ISE +// +// Purpose: +// This verilog netlist is a verification model and uses simulation +// primitives which may not represent the true implementation of the +// device, however the netlist is functionally correct and should not +// be modified. This file cannot be synthesized and should only be used +// with supported simulation tools. +// +// Reference: +// Command Line Tools User Guide, Chapter 23 and Synthesis and Simulation Design Guide, Chapter 6 +// +//////////////////////////////////////////////////////////////////////////////// + +`timescale 1 ns/1 ps + +module ila ( + CLK, CONTROL, TRIG0, TRIG1, TRIG2, TRIG3 +)/* synthesis syn_black_box syn_noprune=1 */; + input CLK; + inout [35 : 0] CONTROL; + input [7 : 0] TRIG0; + input [7 : 0] TRIG1; + input [7 : 0] TRIG2; + input [3 : 0] TRIG3; + + // synthesis translate_off + + wire N0; + wire N1; + wire N38; + wire N39; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/CMP_RESET ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iOUT ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iOUT ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iOUT ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WCE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_CE ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[0] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[1] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[8] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[0] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[1] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[8] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[0] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[1] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[8] ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_CE ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_CE ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iCAP_WR_EN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_IN ; + wire \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_OUT ; + wire \U0/I_NO_D.U_ILA/U_RST/HALT_pulse ; + wire \U0/I_NO_D.U_ILA/U_RST/POR ; + wire \U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ; + wire \U0/I_NO_D.U_ILA/U_RST/PRE_RESET1 ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/din_latched ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[0] ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[1] ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[2] ; + wire \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[4] ; + wire \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/din_latched ; + wire \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ; + wire \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT ; + wire \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[0] ; + wire \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[2] ; + wire \U0/I_NO_D.U_ILA/U_STAT/ACTRESET_pulse ; + wire \U0/I_NO_D.U_ILA/U_STAT/ACT_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/ARM_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/CAP_RESET_dly1 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DIRTY_D0 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DIRTY_D1 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DIRTY_SEL ; + wire \U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly1 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly3 ; + wire \U0/I_NO_D.U_ILA/U_STAT/DSTAT_load ; + wire \U0/I_NO_D.U_ILA/U_STAT/EXTCAP_READY_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/FULL_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/NS_load ; + wire \U0/I_NO_D.U_ILA/U_STAT/TDO_mux_in<0>1 ; + wire \U0/I_NO_D.U_ILA/U_STAT/TDO_next ; + wire \U0/I_NO_D.U_ILA/U_STAT/TRIGGER_dstat ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_10_443 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_101_444 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_11_445 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_12_f5_446 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_13_447 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_14_448 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_3_449 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_4_450 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_7_f6_451 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_452 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_f5_453 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_454 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91_455 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_f5_456 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/din_latched ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O15_463 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O2_464 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O26_465 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O36_466 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O82_467 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f5_470 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f6_471 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_472 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f5_473 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f51 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_475 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_121_476 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_122_477 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_f5_478 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_13_479 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_131_480 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_132_481 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_14_482 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_8_f7_483 ; + wire \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_9_f6_484 ; + wire \U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE ; + wire \U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ; + wire \U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<1>1_535 ; + wire \U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<2>1_537 ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/iTRIGGER ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/iTRIGGER ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCAPTURE ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/DOUT_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/dout_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/DOUT_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/dout_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/DOUT_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/dout_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/DOUT_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<3> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<4> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ; + wire \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/dout_tmp ; + wire \U0/I_NO_D.U_ILA/U_TRIG/trigCondOut ; + wire \U0/I_NO_D.U_ILA/iARM ; + wire \U0/I_NO_D.U_ILA/iCAPTURE ; + wire \U0/I_NO_D.U_ILA/iCAP_DONE ; + wire \U0/I_NO_D.U_ILA/iCAP_TRIGGER_OUT ; + wire \U0/I_NO_D.U_ILA/iCAP_WR_EN ; + wire \U0/I_NO_D.U_ILA/iDATA_DOUT ; + wire \U0/I_NO_D.U_ILA/iSTAT_DOUT ; + wire \U0/I_NO_D.U_ILA/iTRIGGER ; + wire \NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF_cs_cfglut4_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_STAT/U_DSR_O_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_CAP_B_O_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_SRLC16E_Q15_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<31>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<30>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<29>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<28>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<27>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<26>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<25>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<24>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<23>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<22>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<21>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<20>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<19>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<18>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<17>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<16>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<15>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<14>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<13>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<12>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<11>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<10>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<9>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<8>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<7>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<6>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<5>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<4>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<3>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<2>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<1>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<0>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<3>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<2>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<1>_UNCONNECTED ; + wire \NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<0>_UNCONNECTED ; + wire [27 : 0] \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp ; + wire [13 : 1] \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI ; + wire [13 : 0] \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D ; + wire [13 : 0] \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S ; + wire [13 : 0] \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR ; + wire [3 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/jO ; + wire [3 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/jO ; + wire [7 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA ; + wire [7 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/kO ; + wire [7 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA ; + wire [7 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/kO ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DATA ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iO ; + wire [3 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/jO ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DATA ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iO ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DATA ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iO ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next ; + wire [8 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S ; + wire [8 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/cfg_data ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCompData ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/cfg_data ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCompData ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/cfg_data ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCompData ; + wire [4 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data ; + wire [16 : 1] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT ; + wire [9 : 0] \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN ; + wire [0 : 0] \U0/I_NO_D.U_ILA/U_RST/iRESET ; + wire [8 : 0] \U0/I_NO_D.U_ILA/U_STAT/NS_dstat ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_STAT/STATE_dstat ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDOUT_dly ; + wire [1 : 0] \U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT ; + wire [9 : 1] \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI ; + wire [9 : 0] \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D ; + wire [9 : 0] \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S ; + wire [16 : 0] \U0/I_NO_D.U_ILA/U_STAT/iSTAT ; + wire [9 : 0] \U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT ; + wire [1 : 1] \U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCFG_DATA ; + wire [3 : 0] \U0/I_NO_D.U_ILA/U_TRIG/trigCondIn ; + wire [8 : 0] \U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES ; + wire [1 : 0] \U0/I_NO_D.U_ILA/iCAP_STATE ; + wire [8 : 0] \U0/I_NO_D.U_ILA/iCAP_WR_ADDR ; + wire [27 : 0] \U0/I_NO_D.U_ILA/iDATA ; + wire [7 : 0] \U0/I_NO_D.U_ILA/iRESET ; + wire [8 : 0] \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy ; + wire [8 : 0] \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut ; + wire [27 : 0] \U0/iTRIG_IN ; + GND XST_GND ( + .G(N0) + ); + VCC XST_VCC ( + .P(N1) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_WCNT_HCMP_Q ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP ), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/CMP_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_WCNT_LCMP_Q ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP ), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/CMP_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_SCNT_CMP_Q ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP ), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/CMP_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_INTCAP_F.U_CAPWE0 ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iCAP_WR_EN ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_INTCAP_F.U_CAPWE1 ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iCAP_WR_EN ), + .R(\U0/I_NO_D.U_ILA/iRESET [7]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_EN ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_TRIG0 ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_IN ), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_OUT ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_TRIG1 ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_OUT ), + .R(\U0/I_NO_D.U_ILA/iRESET [7]), + .Q(\U0/I_NO_D.U_ILA/iCAP_TRIGGER_OUT ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.OUT_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iOUT ), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_STATE [0]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.OUT_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iOUT ), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_STATE [1]) + ); + LUT3 #( + .INIT ( 8'h20 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_TRIG ( + .I0(\U0/I_NO_D.U_ILA/iTRIGGER ), + .I1(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .I2(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/iTRIGGER_IN ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCE/I_NOLUT6.I_SRL_T2.U_SRLC16E ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [5]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [4]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCE/iCFG_DIN ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WCE/I_NOLUT6.I_SRL_T2.U_SRLC16E ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WCE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [4]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WCE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [3]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WCE/iCFG_DIN ) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.U_MUXF7 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/kO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/kO [0]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iOUT ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U0_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/kO [0]) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U1_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/kO [1]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U0_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U1_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [1]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U2_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [5]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [4]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [2]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U3_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [7]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [6]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/jO [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [2]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [4]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [3]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF2_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [5]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [4]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [4]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG2_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [5]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [5]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF3_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [7]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [6]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [6]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG3_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iO [7]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DATA [7]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [1]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS0/iCFG_DIN ) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.U_MUXF7 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/kO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/kO [0]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iOUT ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U0_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/kO [0]) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U1_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/kO [1]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U0_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U1_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [1]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U2_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [5]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [4]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [2]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.U3_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [7]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [6]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/jO [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [2]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [4]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [3]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF2_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [5]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [4]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [4]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG2_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [5]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [5]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UF3_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [7]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [6]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [6]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_S3.UG3_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iO [7]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DATA [7]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [0]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_NS1/iCFG_DIN ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_NO_OREG.U_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/jO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/jO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/CMP_RESET ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.U0_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/jO [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.U1_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/jO [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [6]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [2]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iO [3]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DATA [3]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [5]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CMPRESET/iCFG_DIN ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_NO_OREG.U_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/jO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/jO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.U0_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/jO [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.U1_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/jO [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [2]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iO [3]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DATA [3]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [2]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCRST/iCFG_DIN ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_NO_OREG.U_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_CE ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iO [0]), + .Q15(\NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF_cs_cfglut4_Q15_UNCONNECTED ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DATA [1]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [9]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WHCMPCE/iCFG_DIN ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_NO_OREG.U_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_CE ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [9]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DATA [1]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [8]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_WLCMPCE/iCFG_DIN ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_NO_OREG.U_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP_CE ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [8]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG_cs_cfglut4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DATA [1]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [7]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_SCMPCE/iCFG_DIN ) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.U_MUXF6 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/jO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/jO [0]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iOUT ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.U0_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [0]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/jO [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.U1_MUXF5 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [2]), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP_Q ), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/jO [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [0]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [7]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG0_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [1]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UF1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [2]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [2]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.UG1_CFGLUT4 ( + .A0(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .A2(\U0/I_NO_D.U_ILA/iTRIGGER ), + .A3(\U0/I_NO_D.U_ILA/iCAPTURE ), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iO [3]), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DATA [3]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [6]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iCFG_DIN ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/I_NOLUT6.I_SRL_T2.I_YES_RPM.I_YES_OREG.OUT_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/I_SRLT_NE_1.U_CDONE/iOUT ), + .R(N0), + .Q(\U0/I_NO_D.U_ILA/iCAP_DONE ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[8].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [8]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [8]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[7].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [7]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [7]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[6].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [6]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [6]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[5].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [5]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[4].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [4]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[3].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [3]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[2].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [2]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[1].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [1]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[0].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [0]), + .R(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_RESET ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [0]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[8].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [8]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[8].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [8]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [8]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [8]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[7].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [7]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [7]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[7].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [7]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [7]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[7].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [7]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [7]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [7]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[6].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [6]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [6]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[6].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [6]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [6]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [7]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[6].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [6]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [6]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [6]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[5].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [5]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [5]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[5].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [5]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [5]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [6]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[5].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [5]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [5]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [5]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[4].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [4]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [4]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[4].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [4]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [4]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [5]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[4].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [4]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [4]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [4]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[3].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [3]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [3]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[3].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [3]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [3]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [4]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[3].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [3]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [3]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [3]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[2].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [2]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [2]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[2].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [2]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [2]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [3]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[2].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [2]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [2]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [2]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[1].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [1]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[1].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [1]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [2]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[1].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [1]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [1]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[0].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [0]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[0].GnH.U_MUXCY ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [0]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/CI [1]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/G[0].U_XORCY ( + .CI(N1), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/S [0]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_NO_TSEQ.I_SRLT_NE_1.U_SCNT/D [0]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[8].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [8]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[7].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [7]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[6].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [6]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[5].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [5]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[4].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [4]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[3].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [3]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[2].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [2]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[1].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [1]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[0].U_FDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_CE ), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [0]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[8].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[8].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [8]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [8]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [8]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[7].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [7]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[7].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [7]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [7]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[7].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [7]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [7]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [7]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[6].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [6]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[6].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [6]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [6]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [7]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[6].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [6]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [6]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [6]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[5].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [5]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[5].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [5]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [5]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [6]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[5].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [5]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [5]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [5]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[4].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [4]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[4].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [4]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [4]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [5]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[4].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [4]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [4]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [4]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[3].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [3]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[3].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [3]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [3]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [4]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[3].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [3]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [3]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [3]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[2].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [2]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[2].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [2]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [2]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [3]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[2].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [2]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [2]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [2]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[1].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [1]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[1].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [1]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [2]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[1].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [1]), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [1]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[0].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[0].GnH.U_MUXCY ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [0]), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/CI [1]) + ); + XORCY \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/G[0].U_XORCY ( + .CI(N1), + .LI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/S [0]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_SRLT_NE_1.U_WCNT/D [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.U_MUXL ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/SCNT_CMP ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [8]), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/cfg_data [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [0]), + .Q(\NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [0]), + .A1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [1]), + .A2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [2]), + .A3(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [3]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [4]), + .A1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [5]), + .A2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [6]), + .A3(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [7]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/cfg_data [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_SCNT_CMP/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.U_MUXL ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_HCMP ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/cfg_data [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [2]), + .Q(\NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ) +, + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]), + .A2(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]), + .A3(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [3]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]), + .A1(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]), + .A2(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]), + .A3(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/cfg_data [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_HCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.U_MUXL ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/WCNT_LCMP ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[8] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/cfg_data [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [4]), + .Q(\NLW_U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH_Q_UNCONNECTED ) +, + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData0 ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCompData [0]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .LO(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCompData [1]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]), + .A1(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]), + .A2(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]), + .A3(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[0] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/cfg_data [0]) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]), + .A1(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]), + .A2(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]), + .A3(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/cfg_data [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/sel[1] ), + .Q15(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_WCNT_LCMP/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_BRK1 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [3]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [4]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/U_BRK0 ( + .I0(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [1]), + .I1(CONTROL[9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [2]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[8].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [8]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [9]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [8]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[7].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [7]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [8]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [7]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[6].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [6]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [7]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [6]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[5].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [5]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [6]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [5]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[4].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [4]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [5]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [4]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[3].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [3]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [4]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [3]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[2].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [2]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [3]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [2]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[1].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [2]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [1]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[0].U_CAP_ADDR_MUX ( + .I0(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]), + .I1(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iSCNT [0]), + .I2(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [1]), + .O(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [0]) + ); + SRL16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.I_SRL.U_SELX ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[9]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [16]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data [0]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[8].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [8]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [8]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[8].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [8]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [8]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[7].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [7]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [7]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[7].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [7]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [7]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[6].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [6]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [6]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[6].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [6]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [6]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[5].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [5]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [5]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[5].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [5]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [5]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[4].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [4]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [4]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[4].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [4]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [4]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[3].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [3]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [3]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[3].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [3]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [3]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[2].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [2]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [2]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[2].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [2]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [2]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[1].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [1]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [1]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[1].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [1]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [1]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[0].U_CAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [0]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [0]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_INTCAP.F_CAP_ADDR[0].U_iCAP_ADDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/CAP_ADDR_next [0]), + .R(\U0/I_NO_D.U_ILA/iRESET [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/iCAP_ADDR [0]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[15].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [15]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [16]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[14].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [14]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [15]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[13].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [13]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [14]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[12].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [12]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [13]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[11].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [11]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [12]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[10].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [10]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [11]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[9].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [9]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [10]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[8].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [8]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [9]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[7].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [7]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [8]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[6].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [6]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [7]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[5].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [5]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [6]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[4].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [4]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [5]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[3].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [3]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [4]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[2].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [2]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [3]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[1].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [2]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/I_0_TO_64K.F_SEL[0].U_SEL ( + .C(CONTROL[0]), + .CE(CONTROL[9]), + .D(CONTROL[1]), + .Q(\U0/I_NO_D.U_ILA/U_G2_SQ.U_CAPCTRL/U_CAP_ADDRGEN/cfg_data_vec [1]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL2 ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly1 ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL3 ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly3 ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_CR ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/iRESET [0]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/CAP_RESET_dly1 ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[8].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [8]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [8]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[7].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [7]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [7]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[6].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [6]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [6]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[5].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [5]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[4].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [4]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[3].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [3]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[2].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [2]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[1].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [1]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/G_NS[0].U_NSQ ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/NS_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_NUM_SAMPLES [0]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [0]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STATE1 ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_STATE [1]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/STATE_dstat [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STATE0 ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_load ), + .D(\U0/I_NO_D.U_ILA/iCAP_STATE [0]), + .R(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/STATE_dstat [0]) + ); + FDRS #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_ARM ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_STAT/ARM_dstat ), + .R(\U0/I_NO_D.U_ILA/iRESET [0]), + .S(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/ARM_dstat ) + ); + FDRS #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_TRIGGER ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_STAT/TRIGGER_dstat ), + .R(\U0/I_NO_D.U_ILA/iRESET [0]), + .S(\U0/I_NO_D.U_ILA/iCAP_TRIGGER_OUT ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/TRIGGER_dstat ) + ); + FDRS #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_FULL ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_STAT/FULL_dstat ), + .R(\U0/I_NO_D.U_ILA/iARM ), + .S(\U0/I_NO_D.U_ILA/iCAP_DONE ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/FULL_dstat ) + ); + FDRS #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_ECR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_STAT/EXTCAP_READY_dstat ), + .R(\U0/I_NO_D.U_ILA/iARM ), + .S(N1), + .Q(\U0/I_NO_D.U_ILA/U_STAT/EXTCAP_READY_dstat ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DIRTY_FDCE ( + .C(CONTROL[0]), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/iARM ), + .D(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_D0 ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DIRTY_FDPE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat ), + .PRE(CONTROL[13]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_D1 ) + ); + LDC #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DIRTY_LDC ( + .CLR(\U0/I_NO_D.U_ILA/iARM ), + .D(N1), + .G(CONTROL[13]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_SEL ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_RISING ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_STAT/ACTRESET_pulse ), + .D(N1), + .Q(\U0/I_NO_D.U_ILA/U_STAT/ACT_dstat ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_TDO ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/TDO_next ), + .Q(\U0/I_NO_D.U_ILA/iSTAT_DOUT ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_GEN_DELAY[1].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDOUT_dly [0]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDOUT_dly [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_RFDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly1 ), + .CLR(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly1 ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDOUT_dly [0]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_DOUT ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN [0]), + .R(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN [1]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly1 ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_DOUT1 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN [0]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_DOUT0 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/din_latched ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDIN [0]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_TFDRE ( + .C(CONTROL[0]), + .CE(CONTROL[5]), + .CLR(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ), + .D(CONTROL[5]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/din_latched ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/I_H2L.U_DOUT ( + .C(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT [1]), + .R(\U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT [0]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/ACTRESET_pulse ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/U_DOUT1 ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT [0]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT [1]) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/U_DOUT0 ( + .C(CONTROL[0]), + .CE(N1), + .D(CONTROL[5]), + .Q(\U0/I_NO_D.U_ILA/U_STAT/U_RESET_EDGE/iDOUT [0]) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_2_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_4_450 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_3_449 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/TDO_mux_in<0>1 ) + ); + LUT4 #( + .INIT ( 16'h5140 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_4 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91_455 ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_452 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_4_450 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<1>1_535 ), + .I2(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_12_f5_446 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_452 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_12_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_14_448 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_13_447 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_12_f5_446 ) + ); + LUT2 #( + .INIT ( 4'hD )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_14 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/FULL_dstat ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_14_448 ) + ); + LUT3 #( + .INIT ( 8'h53 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_13 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/STATE_dstat [1]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/STATE_dstat [0]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_13_447 ) + ); + LUT4 #( + .INIT ( 16'hFBEA )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_3 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<2>1_537 ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_7_f6_451 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_3_449 ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_7_f6 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_f5_456 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_f5_453 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_7_f6_451 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_11_445 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_101_444 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_f5_456 ) + ); + LUT3 #( + .INIT ( 8'h53 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_11 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [1]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [0]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_11_445 ) + ); + LUT3 #( + .INIT ( 8'h53 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_101 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [3]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [2]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_101_444 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_10_443 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_454 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_8_f5_453 ) + ); + LUT3 #( + .INIT ( 8'h53 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_10 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [5]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [4]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_10_443 ) + ); + LUT3 #( + .INIT ( 8'h53 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [7]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [6]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_9_454 ) + ); + MUXF7 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_8_f7 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f6_471 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_9_f6_484 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [7]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_8_f7_483 ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f6 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_f5_478 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f51 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f6_471 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_14_482 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_132_481 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_f5_478 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_14 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [0]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_14_482 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_132 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [2]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_132_481 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f5_0 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_131_480 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_122_477 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f51 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_131 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [4]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_131_480 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_122 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [6]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [7]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_122_477 ) + ); + MUXF6 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_9_f6 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f5_473 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f5_470 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_9_f6_484 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_13_479 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_121_476 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_f5_473 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_13 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [8]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [9]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_13_479 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_121 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [10]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [11]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_121_476 ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f5 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_475 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_472 ), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_10_f5_470 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [12]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [13]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_12_475 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [14]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [15]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_11_472 ) + ); + LUT2 #( + .INIT ( 4'hE )) + \U0/I_NO_D.U_ILA/U_STAT/U_STATCMD ( + .I0(CONTROL[4]), + .I1(CONTROL[5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE ) + ); + INV \U0/I_NO_D.U_ILA/U_STAT/U_STATCMD_n ( + .I(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE ), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ) + ); + LUT2 #( + .INIT ( 4'h4 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly3 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_load ) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSR ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly3 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ), + .O(\NLW_U0/I_NO_D.U_ILA/U_STAT/U_DSR_O_UNCONNECTED ) + ); + LUT4 #( + .INIT ( 16'h0F22 )) + \U0/I_NO_D.U_ILA/U_STAT/U_NSL ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly3 ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/DSTAT_en_dly2 ), + .I2(\U0/I_NO_D.U_ILA/U_STAT/CAP_RESET_dly1 ), + .I3(\U0/I_NO_D.U_ILA/iRESET [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/NS_load ) + ); + LUT4 #( + .INIT ( 16'h0030 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[16].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [16]) + ); + LUT4 #( + .INIT ( 16'h1030 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[15].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [15]) + ); + LUT4 #( + .INIT ( 16'h0070 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[14].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [14]) + ); + LUT4 #( + .INIT ( 16'h1020 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[13].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [13]) + ); + LUT4 #( + .INIT ( 16'h0070 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[12].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [12]) + ); + LUT4 #( + .INIT ( 16'h1010 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[11].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [11]) + ); + LUT4 #( + .INIT ( 16'h0070 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[10].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [10]) + ); + LUT4 #( + .INIT ( 16'h100F )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[9].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [9]) + ); + LUT4 #( + .INIT ( 16'hFFF0 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[8].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [8]) + ); + LUT4 #( + .INIT ( 16'h0004 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[7].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [7]) + ); + LUT4 #( + .INIT ( 16'h3000 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[6].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [6]) + ); + LUT4 #( + .INIT ( 16'h001F )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[5].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [5]) + ); + LUT4 #( + .INIT ( 16'hF001 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[4].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [4]) + ); + LUT4 #( + .INIT ( 16'hB610 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[3].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [3]) + ); + LUT4 #( + .INIT ( 16'h2100 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[2].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [2]) + ); + LUT4 #( + .INIT ( 16'hC102 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[1].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [1]) + ); + LUT4 #( + .INIT ( 16'h0101 )) + \U0/I_NO_D.U_ILA/U_STAT/F_SSTAT[0].I_STAT.U_STAT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [0]) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DSL1/U_CLEAR ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iDOUT_dly [1]), + .I1(CONTROL[5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DSL1/iCLR ) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[0].U_XORCY ( + .CI(N1), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[0].GnH.U_MUXCY ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [0]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [1]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[0].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [0]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[1].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [1]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [1]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[1].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [1]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [2]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[1].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [1]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[2].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [2]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [2]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [2]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[2].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [2]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [2]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [3]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[2].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [2]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[3].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [3]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [3]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[3].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [3]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [3]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [4]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[3].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [3]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[4].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [4]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [4]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [4]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[4].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [4]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [4]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [5]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[4].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [4]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[5].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [5]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [5]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[5].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [5]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [5]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [6]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[5].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [5]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[6].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [6]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [6]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [6]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[6].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [6]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [6]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [7]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[6].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [6]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[7].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [7]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [7]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [7]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[7].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [7]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [7]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [8]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[7].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [7]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [7]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[8].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [8]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [8]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [8]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[8].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [8]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [8]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [9]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[8].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [8]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[9].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/CI [9]), + .LI(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [9]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [9]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[9].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [9]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/S [9]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[0].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [0]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[1].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [1]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[2].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [2]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[3].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [3]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[4].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [4]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[5].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [5]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[6].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [6]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[7].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [7]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [7]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[8].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [8]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [8]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/G[9].U_FDRE ( + .C(CONTROL[0]), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_STAT/U_STAT_CNT/D [9]), + .R(\U0/I_NO_D.U_ILA/U_STAT/iSTATCMD_CE_n ), + .Q(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [9]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/U_POR ( + .C(CLK), + .D(N0), + .PRE(N0), + .Q(\U0/I_NO_D.U_ILA/U_RST/POR ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[0].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_RST/iRESET [0]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [0]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[1].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [0]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [1]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[2].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [1]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [2]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[3].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [2]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [3]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[4].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [3]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [4]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[5].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [4]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [5]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[6].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [5]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [6]) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_RST/G_RST[7].U_RST ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/iRESET [6]), + .S(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ), + .Q(\U0/I_NO_D.U_ILA/iRESET [7]) + ); + LUT3 #( + .INIT ( 8'hEF )) + \U0/I_NO_D.U_ILA/U_RST/U_PRST1 ( + .I0(\U0/I_NO_D.U_ILA/U_RST/HALT_pulse ), + .I1(\U0/I_NO_D.U_ILA/U_RST/POR ), + .I2(N1), + .O(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET1 ) + ); + LUT4 #( + .INIT ( 16'hFFFE )) + \U0/I_NO_D.U_ILA/U_RST/U_PRST0 ( + .I0(N0), + .I1(\U0/I_NO_D.U_ILA/iCAP_DONE ), + .I2(N0), + .I3(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET1 ), + .O(\U0/I_NO_D.U_ILA/U_RST/PRE_RESET0 ) + ); + LUT2 #( + .INIT ( 4'h4 )) + \U0/I_NO_D.U_ILA/U_RST/U_RST0 ( + .I0(\U0/I_NO_D.U_ILA/iARM ), + .I1(\U0/I_NO_D.U_ILA/iRESET [0]), + .O(\U0/I_NO_D.U_ILA/U_RST/iRESET [0]) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_CLEAR ( + .I0(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[2] ), + .I1(CONTROL[13]), + .O(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_GEN_DELAY[2].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_RST/HALT_pulse ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[2] ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_GEN_DELAY[1].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[0] ), + .Q(\U0/I_NO_D.U_ILA/U_RST/HALT_pulse ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_RFDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT ), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT_dly[0] ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_DOUT ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN [0]), + .R(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN [1]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDOUT ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_DOUT1 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN [0]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_DOUT0 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/din_latched ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iDIN [0]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/U_TFDRE ( + .C(CONTROL[0]), + .CE(CONTROL[13]), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/iCLR ), + .D(CONTROL[13]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_HALT_XFER/din_latched ) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_CLEAR ( + .I0(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[4] ), + .I1(CONTROL[12]), + .O(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_GEN_DELAY[4].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/iARM ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[4] ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_GEN_DELAY[3].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[2] ), + .Q(\U0/I_NO_D.U_ILA/iARM ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_GEN_DELAY[2].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[1] ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[2] ) + ); + FDE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_GEN_DELAY[1].U_FD ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[0] ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[1] ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_RFDRE ( + .C(CLK), + .CE(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT ), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT_dly[0] ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_DOUT ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN [0]), + .R(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN [1]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDOUT ) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_DOUT1 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN [0]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN [1]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_DOUT0 ( + .C(CLK), + .CE(N1), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ), + .D(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/din_latched ), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iDIN [0]) + ); + FDCE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/U_TFDRE ( + .C(CONTROL[0]), + .CE(CONTROL[12]), + .CLR(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/iCLR ), + .D(CONTROL[12]), + .Q(\U0/I_NO_D.U_ILA/U_RST/U_ARM_XFER/din_latched ) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[13].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [13]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [13]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[12].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [12]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [12]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[11].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [11]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [11]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[10].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [10]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [10]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[9].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [9]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [9]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[8].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [8]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [8]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[7].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [7]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [7]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[6].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [6]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [6]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[5].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [5]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [5]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[4].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [4]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [4]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[3].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [3]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [3]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[2].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [2]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [2]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[1].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [1]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [1]) + ); + FDRE #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[0].U_FDRE ( + .C(CONTROL[0]), + .CE(CONTROL[6]), + .D(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [0]), + .R(CONTROL[14]), + .Q(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [0]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[13].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [13]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [13]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[13].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [13]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [13]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [13]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[12].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [12]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [12]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[12].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [12]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [12]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [13]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[12].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [12]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [12]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [12]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[11].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [11]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [11]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[11].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [11]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [11]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [12]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[11].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [11]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [11]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [11]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[10].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [10]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [10]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[10].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [10]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [10]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [11]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[10].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [10]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [10]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [10]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[9].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [9]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [9]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[9].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [9]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [9]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [10]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[9].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [9]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [9]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [9]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[8].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [8]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [8]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[8].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [8]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [8]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [9]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[8].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [8]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [8]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [8]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[7].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [7]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [7]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[7].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [7]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [7]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [8]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[7].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [7]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [7]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [7]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[6].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [6]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [6]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[6].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [6]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [6]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [7]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[6].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [6]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [6]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [6]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[5].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [5]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [5]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[5].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [5]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [5]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [6]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[5].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [5]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [5]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [5]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[4].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [4]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [4]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[4].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [4]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [4]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [5]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[4].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [4]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [4]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [4]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[3].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [3]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [3]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[3].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [3]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [3]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [4]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[3].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [3]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [3]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [3]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[2].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [2]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [2]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[2].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [2]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [2]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [3]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[2].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [2]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [2]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [2]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[1].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [1]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [1]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[1].GnH.U_MUXCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [1]), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [1]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [2]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[1].U_XORCY ( + .CI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [1]), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [1]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [1]) + ); + LUT1 #( + .INIT ( 2'h2 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[0].U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [0]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [0]) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[0].GnH.U_MUXCY ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [0]), + .LO(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/CI [1]) + ); + XORCY \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/G[0].U_XORCY ( + .CI(N1), + .LI(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/S [0]), + .O(\U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.I_RDADDR/U_HC/D [0]) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[0].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [24]), + .PRE(CONTROL[23]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[1].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [25]), + .PRE(CONTROL[23]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[2].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [26]), + .PRE(CONTROL[23]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[3].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [27]), + .PRE(CONTROL[23]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_OREG.U_OREG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ), + .S(\U0/I_NO_D.U_ILA/iRESET [0]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/DOUT_tmp ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N1), + .CE(CONTROL[23]), + .CLK(CONTROL[0]), + .D(CONTROL[1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<4> ), + .Q15(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ), + .CE(CONTROL[23]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<3> ), + .Q15 +(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ) + + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.I_YES_MUXH.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<4> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TWMOD8_NE0.I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<3> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[0].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [0]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[1].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [1]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[2].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [2]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[3].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [3]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[4].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [4]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[5].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [5]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[6].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [6]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[7].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [7]), + .PRE(CONTROL[20]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_OREG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ), + .S(\U0/I_NO_D.U_ILA/iRESET [0]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/DOUT_tmp ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ), + .CE(CONTROL[20]), + .CLK(CONTROL[0]), + .D(CONTROL[1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .Q15(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ), + .CE(CONTROL[20]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .Q15 +(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ) + + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ) + ); + XORCY \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_XORH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ), + .LI(N0), + .O(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[0].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [8]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[1].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [9]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[2].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [10]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[3].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [11]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[4].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [12]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[5].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [13]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[6].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [14]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[7].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [15]), + .PRE(CONTROL[21]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_OREG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ), + .S(\U0/I_NO_D.U_ILA/iRESET [0]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/DOUT_tmp ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ), + .CE(CONTROL[21]), + .CLK(CONTROL[0]), + .D(CONTROL[1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .Q15(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ), + .CE(CONTROL[21]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .Q15 +(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ) + + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ) + ); + XORCY \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_XORH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ), + .LI(N0), + .O(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[0].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [16]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[1].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [17]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[2].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [18]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[3].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [19]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[4].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [20]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[5].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [21]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[6].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [22]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_YES_IREG.F_TW[7].U_IREG ( + .C(CLK), + .CE(N1), + .D(\U0/iTRIG_IN [23]), + .PRE(CONTROL[22]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_OREG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ), + .S(\U0/I_NO_D.U_ILA/iRESET [0]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/DOUT_tmp ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLH ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<4> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<5> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<6> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<7> ), + .CE(CONTROL[22]), + .CLK(CONTROL[0]), + .D(CONTROL[1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .Q15(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<0> ), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<1> ), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<2> ), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/din_dly1<3> ), + .CE(CONTROL[22]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCfgData ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .Q15 +(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_SRLT_EQ_2.U_SRLL_Q15_UNCONNECTED ) + + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<1> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ) + ); + MUXCY_L \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.U_MUXL ( + .CI(N1), + .DI(N0), + .S(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/sel<0> ), + .LO(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<0> ) + ); + XORCY \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/I_TW_GTE8.F_TW[0].I_YES_RPM.I_OREG.U_XORH ( + .CI(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<1> ), + .LI(N0), + .O(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_MUT_GAND.U_match/I_SRL16.U_GAND_SRL16/tmpCompData<2> ) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[0].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [0]), + .Q(\U0/I_NO_D.U_ILA/iDATA [0]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[1].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [1]), + .Q(\U0/I_NO_D.U_ILA/iDATA [1]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[2].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [2]), + .Q(\U0/I_NO_D.U_ILA/iDATA [2]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[3].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [3]), + .Q(\U0/I_NO_D.U_ILA/iDATA [3]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[4].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [4]), + .Q(\U0/I_NO_D.U_ILA/iDATA [4]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[5].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [5]), + .Q(\U0/I_NO_D.U_ILA/iDATA [5]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[6].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [6]), + .Q(\U0/I_NO_D.U_ILA/iDATA [6]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[7].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [7]), + .Q(\U0/I_NO_D.U_ILA/iDATA [7]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[8].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [8]), + .Q(\U0/I_NO_D.U_ILA/iDATA [8]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[9].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [9]), + .Q(\U0/I_NO_D.U_ILA/iDATA [9]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[10].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [10]), + .Q(\U0/I_NO_D.U_ILA/iDATA [10]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[11].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [11]), + .Q(\U0/I_NO_D.U_ILA/iDATA [11]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[12].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [12]), + .Q(\U0/I_NO_D.U_ILA/iDATA [12]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[13].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [13]), + .Q(\U0/I_NO_D.U_ILA/iDATA [13]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[14].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [14]), + .Q(\U0/I_NO_D.U_ILA/iDATA [14]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[15].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [15]), + .Q(\U0/I_NO_D.U_ILA/iDATA [15]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[16].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [16]), + .Q(\U0/I_NO_D.U_ILA/iDATA [16]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[17].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [17]), + .Q(\U0/I_NO_D.U_ILA/iDATA [17]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[18].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [18]), + .Q(\U0/I_NO_D.U_ILA/iDATA [18]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[19].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [19]), + .Q(\U0/I_NO_D.U_ILA/iDATA [19]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[20].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [20]), + .Q(\U0/I_NO_D.U_ILA/iDATA [20]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[21].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [21]), + .Q(\U0/I_NO_D.U_ILA/iDATA [21]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[22].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [22]), + .Q(\U0/I_NO_D.U_ILA/iDATA [22]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[23].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [23]), + .Q(\U0/I_NO_D.U_ILA/iDATA [23]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[24].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [24]), + .Q(\U0/I_NO_D.U_ILA/iDATA [24]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[25].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [25]), + .Q(\U0/I_NO_D.U_ILA/iDATA [25]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[26].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [26]), + .Q(\U0/I_NO_D.U_ILA/iDATA [26]) + ); + FD #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[27].I_SRLT_NE_0.FF ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [27]), + .Q(\U0/I_NO_D.U_ILA/iDATA [27]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[0].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [0]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [0]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[1].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [1]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [1]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[2].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [2]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [2]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[3].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [3]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [3]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[4].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [4]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [4]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[5].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [5]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [5]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[6].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [6]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [6]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[7].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [7]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [7]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[8].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [8]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [8]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[9].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [9]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [9]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[10].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [10]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [10]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[11].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [11]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [11]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[12].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [12]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [12]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[13].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [13]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [13]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[14].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [14]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [14]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[15].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [15]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [15]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[16].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [16]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [16]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[17].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [17]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [17]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[18].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [18]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [18]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[19].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [19]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [19]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[20].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [20]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [20]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[21].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [21]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [21]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[22].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [22]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [22]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[23].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [23]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [23]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[24].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [24]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [24]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[25].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [25]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [25]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[26].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [26]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [26]) + ); + SRL16 #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/I_DQ.U_DQQ/DLY_9.DLY_9_GEN[27].I_SRLT_NE_0.DLY9 ( + .A0(N1), + .A1(N1), + .A2(N1), + .A3(N0), + .CLK(CLK), + .D(\U0/iTRIG_IN [27]), + .Q(\U0/I_NO_D.U_ILA/I_DQ.U_DQQ/temp [27]) + ); + LUT3 #( + .INIT ( 8'hCA )) + \U0/I_NO_D.U_ILA/U_DOUT ( + .I0(\U0/I_NO_D.U_ILA/iSTAT_DOUT ), + .I1(\U0/I_NO_D.U_ILA/iDATA_DOUT ), + .I2(CONTROL[6]), + .O(CONTROL[3]) + ); + LUT1 #( + .INIT ( 2'h1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_CAP_B ( + .I0(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCAPTURE ), + .O(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_CAP_B_O_UNCONNECTED ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_SRLC16E ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [0]), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [1]), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [2]), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [3]), + .CE(CONTROL[8]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ), + .Q15 +(\NLW_U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_SRLC16E_Q15_UNCONNECTED ) + + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCFG_DATA [1]), + .I1(CONTROL[8]), + .O(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ) + ); + SRLC16E #( + .INIT ( 16'h0000 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_SRLC16E ( + .A0(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [0]), + .A1(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [1]), + .A2(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [2]), + .A3(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [3]), + .CE(CONTROL[8]), + .CLK(CONTROL[0]), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ), + .Q15(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCFG_DATA [1]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/I_NOLUT6.I_SRL_T2.U_LUT ( + .I0(CONTROL[1]), + .I1(CONTROL[8]), + .O(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_NMU_EQ4.U_iDOUT/iCFG_DIN ) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/I_OREG.I_YES_OREG.U_OREG ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/U_MU/DOUT_tmp ), + .PRE(\U0/I_NO_D.U_ILA/iRESET [1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/dout_tmp ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/I_MC_NO.U_NO_MC_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[2].U_M/dout_tmp ), + .S(\U0/I_NO_D.U_ILA/iRESET [2]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [2]) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/I_OREG.I_YES_OREG.U_OREG ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/U_MU/DOUT_tmp ), + .PRE(\U0/I_NO_D.U_ILA/iRESET [1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/dout_tmp ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/I_MC_NO.U_NO_MC_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[1].U_M/dout_tmp ), + .S(\U0/I_NO_D.U_ILA/iRESET [2]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [1]) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/I_OREG.I_YES_OREG.U_OREG ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/U_MU/DOUT_tmp ), + .PRE(\U0/I_NO_D.U_ILA/iRESET [1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/dout_tmp ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/I_MC_NO.U_NO_MC_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[0].U_M/dout_tmp ), + .S(\U0/I_NO_D.U_ILA/iRESET [2]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [0]) + ); + FDPE #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/I_OREG.I_YES_OREG.U_OREG ( + .C(CLK), + .CE(N1), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/U_MU/DOUT_tmp ), + .PRE(\U0/I_NO_D.U_ILA/iRESET [1]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/dout_tmp ) + ); + FDS #( + .INIT ( 1'b1 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/I_MC_NO.U_NO_MC_REG ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TM/G_NMU[3].U_M/dout_tmp ), + .S(\U0/I_NO_D.U_ILA/iRESET [2]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/trigCondIn [3]) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_CAP_DLY ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCAPTURE ), + .R(\U0/I_NO_D.U_ILA/iRESET [3]), + .Q(\U0/I_NO_D.U_ILA/iCAPTURE ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_OUTREG.U_DOUT ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ), + .R(\U0/I_NO_D.U_ILA/iRESET [3]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/iTRIGGER ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/I_SRLT_NE_1.I_NMU_1_TO_4.U_TRIGQ ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_STORAGE_QUAL.U_STORAGE_QUAL/iTRIGGER ), + .R(\U0/I_NO_D.U_ILA/iRESET [4]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/iCAPTURE ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/I_OUTREG.U_DOUT ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TCL/iDOUT ), + .R(\U0/I_NO_D.U_ILA/iRESET [3]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/iTRIGGER ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/I_SRLT_NE_1.I_NMU_1_TO_4.U_TRIGQ ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/U_TC/I_TSEQ_NEQ2.U_TC_EQUATION/iTRIGGER ), + .R(\U0/I_NO_D.U_ILA/iRESET [4]), + .Q(\U0/I_NO_D.U_ILA/U_TRIG/trigCondOut ) + ); + FDR #( + .INIT ( 1'b0 )) + \U0/I_NO_D.U_ILA/U_TRIG/F_NO_TCMC.U_FDR ( + .C(CLK), + .D(\U0/I_NO_D.U_ILA/U_TRIG/trigCondOut ), + .R(\U0/I_NO_D.U_ILA/iRESET [5]), + .Q(\U0/I_NO_D.U_ILA/iTRIGGER ) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ3.G_TW[3].U_TQ ( + .C(CLK), + .D(TRIG3[3]), + .PRE(N0), + .Q(\U0/iTRIG_IN [27]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ3.G_TW[2].U_TQ ( + .C(CLK), + .D(TRIG3[2]), + .PRE(N0), + .Q(\U0/iTRIG_IN [26]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ3.G_TW[1].U_TQ ( + .C(CLK), + .D(TRIG3[1]), + .PRE(N0), + .Q(\U0/iTRIG_IN [25]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ3.G_TW[0].U_TQ ( + .C(CLK), + .D(TRIG3[0]), + .PRE(N0), + .Q(\U0/iTRIG_IN [24]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[7].U_TQ ( + .C(CLK), + .D(TRIG2[7]), + .PRE(N0), + .Q(\U0/iTRIG_IN [23]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[6].U_TQ ( + .C(CLK), + .D(TRIG2[6]), + .PRE(N0), + .Q(\U0/iTRIG_IN [22]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[5].U_TQ ( + .C(CLK), + .D(TRIG2[5]), + .PRE(N0), + .Q(\U0/iTRIG_IN [21]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[4].U_TQ ( + .C(CLK), + .D(TRIG2[4]), + .PRE(N0), + .Q(\U0/iTRIG_IN [20]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[3].U_TQ ( + .C(CLK), + .D(TRIG2[3]), + .PRE(N0), + .Q(\U0/iTRIG_IN [19]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[2].U_TQ ( + .C(CLK), + .D(TRIG2[2]), + .PRE(N0), + .Q(\U0/iTRIG_IN [18]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[1].U_TQ ( + .C(CLK), + .D(TRIG2[1]), + .PRE(N0), + .Q(\U0/iTRIG_IN [17]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ2.G_TW[0].U_TQ ( + .C(CLK), + .D(TRIG2[0]), + .PRE(N0), + .Q(\U0/iTRIG_IN [16]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[7].U_TQ ( + .C(CLK), + .D(TRIG1[7]), + .PRE(N0), + .Q(\U0/iTRIG_IN [15]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[6].U_TQ ( + .C(CLK), + .D(TRIG1[6]), + .PRE(N0), + .Q(\U0/iTRIG_IN [14]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[5].U_TQ ( + .C(CLK), + .D(TRIG1[5]), + .PRE(N0), + .Q(\U0/iTRIG_IN [13]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[4].U_TQ ( + .C(CLK), + .D(TRIG1[4]), + .PRE(N0), + .Q(\U0/iTRIG_IN [12]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[3].U_TQ ( + .C(CLK), + .D(TRIG1[3]), + .PRE(N0), + .Q(\U0/iTRIG_IN [11]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[2].U_TQ ( + .C(CLK), + .D(TRIG1[2]), + .PRE(N0), + .Q(\U0/iTRIG_IN [10]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[1].U_TQ ( + .C(CLK), + .D(TRIG1[1]), + .PRE(N0), + .Q(\U0/iTRIG_IN [9]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ1.G_TW[0].U_TQ ( + .C(CLK), + .D(TRIG1[0]), + .PRE(N0), + .Q(\U0/iTRIG_IN [8]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[7].U_TQ ( + .C(CLK), + .D(TRIG0[7]), + .PRE(N0), + .Q(\U0/iTRIG_IN [7]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[6].U_TQ ( + .C(CLK), + .D(TRIG0[6]), + .PRE(N0), + .Q(\U0/iTRIG_IN [6]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[5].U_TQ ( + .C(CLK), + .D(TRIG0[5]), + .PRE(N0), + .Q(\U0/iTRIG_IN [5]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[4].U_TQ ( + .C(CLK), + .D(TRIG0[4]), + .PRE(N0), + .Q(\U0/iTRIG_IN [4]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[3].U_TQ ( + .C(CLK), + .D(TRIG0[3]), + .PRE(N0), + .Q(\U0/iTRIG_IN [3]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[2].U_TQ ( + .C(CLK), + .D(TRIG0[2]), + .PRE(N0), + .Q(\U0/iTRIG_IN [2]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[1].U_TQ ( + .C(CLK), + .D(TRIG0[1]), + .PRE(N0), + .Q(\U0/iTRIG_IN [1]) + ); + FDP #( + .INIT ( 1'b1 )) + \U0/I_TQ0.G_TW[0].U_TQ ( + .C(CLK), + .D(TRIG0[0]), + .PRE(N0), + .Q(\U0/iTRIG_IN [0]) + ); + LUT2 #( + .INIT ( 4'h8 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<0> ( + .I0(CONTROL[10]), + .I1(CONTROL[11]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [0]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<0> ( + .CI(N1), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [0]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [0]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<1> ( + .I0(CONTROL[12]), + .I1(CONTROL[13]), + .I2(CONTROL[9]), + .I3(CONTROL[14]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [1]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<1> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [0]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [1]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [1]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<2> ( + .I0(CONTROL[15]), + .I1(CONTROL[16]), + .I2(CONTROL[8]), + .I3(CONTROL[17]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [2]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<2> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [1]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [2]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [2]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<3> ( + .I0(CONTROL[18]), + .I1(CONTROL[21]), + .I2(CONTROL[7]), + .I3(CONTROL[19]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [3]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<3> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [2]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [3]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [3]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<4> ( + .I0(CONTROL[20]), + .I1(CONTROL[22]), + .I2(CONTROL[6]), + .I3(CONTROL[23]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [4]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<4> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [3]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [4]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [4]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<5> ( + .I0(CONTROL[24]), + .I1(CONTROL[25]), + .I2(CONTROL[5]), + .I3(CONTROL[26]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [5]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<5> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [4]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [5]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [5]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<6> ( + .I0(CONTROL[27]), + .I1(CONTROL[28]), + .I2(CONTROL[2]), + .I3(CONTROL[29]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [6]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<6> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [5]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [6]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [6]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<7> ( + .I0(CONTROL[30]), + .I1(CONTROL[31]), + .I2(CONTROL[1]), + .I3(CONTROL[32]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [7]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<7> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [6]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [7]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [7]) + ); + LUT4 #( + .INIT ( 16'h8000 )) + \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut<8> ( + .I0(CONTROL[33]), + .I1(CONTROL[34]), + .I2(CONTROL[4]), + .I3(CONTROL[35]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [8]) + ); + MUXCY \U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy<8> ( + .CI(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [7]), + .DI(N0), + .S(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_lut [8]), + .O(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [8]) + ); + LUT4 #( + .INIT ( 16'hFEFF )) + \U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<2>1 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/NS_dstat [8]), + .O(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<2>1_537 ) + ); + LUT3 #( + .INIT ( 8'hE4 )) + \U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat1 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_SEL ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_D0 ), + .I2(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_D1 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat ) + ); + LUT2 #( + .INIT ( 4'h2 )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O2 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [9]), + .I1(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [8]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O2_464 ) + ); + LUT4 #( + .INIT ( 16'h0001 )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O15 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [7]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O15_463 ) + ); + LUT4 #( + .INIT ( 16'hFFFE )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O26 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [7]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [6]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [5]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [4]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O26_465 ) + ); + LUT4 #( + .INIT ( 16'hF222 )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O36 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O26_465 ), + .I1(\U0/U_XST_CONTROLBUS_WORKAROUND/CONTROL_XST_WORKAROUND_O_cmp_eq0000_wg_cy [8]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O15_463 ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT [16]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O36_466 ) + ); + LUT4 #( + .INIT ( 16'hAF8D )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O129 ( + .I0(CONTROL[4]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O2_464 ), + .I2(\U0/I_NO_D.U_ILA/U_STAT/TDO_mux_in<0>1 ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O82_467 ), + .O(\U0/I_NO_D.U_ILA/U_STAT/TDO_next ) + ); + MUXF5 \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91 ( + .I0(N38), + .I1(N39), + .S(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .O(\U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91_455 ) + ); + LUT3 #( + .INIT ( 8'h15 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91_F ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/DIRTY_dstat ), + .O(N38) + ); + LUT4 #( + .INIT ( 16'h0145 )) + \U0/I_NO_D.U_ILA/U_STAT/U_DMUX/U_CS_MUX/I3.U_MUX8/Mmux_O_91_G ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [2]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/EXTCAP_READY_dstat ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/ACT_dstat ), + .O(N39) + ); + LUT4_L #( + .INIT ( 16'h3F50 )) + \U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<1>1 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/ARM_dstat ), + .I1(\U0/I_NO_D.U_ILA/U_STAT/TRIGGER_dstat ), + .I2(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [1]), + .I3(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [0]), + .LO(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT<1>1_535 ) + ); + LUT4_L #( + .INIT ( 16'h3120 )) + \U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O82 ( + .I0(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [8]), + .I1(\U0/I_NO_D.U_ILA/U_STAT/iSTAT_CNT [9]), + .I2(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O36_466 ), + .I3(\U0/I_NO_D.U_ILA/U_STAT/U_SMUX/U_CS_MUX/I6.U_MUX64/Mmux_O_8_f7_483 ), + .LO(\U0/I_NO_D.U_ILA/U_STAT/U_MUX/U_CS_MUX/I1.U_MUX2/O82_467 ) + ); + RAMB16_S1_S36 #( + .INIT_B ( 36'h000000000 ), + .INITP_00 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_01 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_02 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_03 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_04 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_05 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INITP_06 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_00 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_01 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_02 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_03 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_04 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_05 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_06 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_07 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_08 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_09 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0A ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0B ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0C ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0D ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0E ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_0F ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_10 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_11 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_12 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_13 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_14 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_15 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_16 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_17 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_18 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_19 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1A ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1B ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1C ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1D ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1E ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_1F ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_20 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_21 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_22 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_23 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_24 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_25 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_26 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_27 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_28 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_29 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2A ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2B ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2C ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2D ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2E ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_2F ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_30 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_31 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_32 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_33 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_34 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_35 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_36 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_37 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_38 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_39 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3A ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3B ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3C ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3D ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3E ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_3F ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .INIT_A ( 1'h0 ), + .SIM_COLLISION_CHECK ( "ALL" ), + .INITP_07 ( 256'h0000000000000000000000000000000000000000000000000000000000000000 ), + .SRVAL_A ( 1'h0 ), + .WRITE_MODE_A ( "WRITE_FIRST" ), + .WRITE_MODE_B ( "WRITE_FIRST" ), + .SRVAL_B ( 36'h000000000 )) + \U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i ( + .CLKA(CONTROL[0]), + .CLKB(CLK), + .ENA(CONTROL[6]), + .ENB(N1), + .WEB(\U0/I_NO_D.U_ILA/iCAP_WR_EN ), + .SSRA(N0), + .SSRB(N0), + .WEA(N0), + .DIPB({N0, N0, N0, N0}), + .ADDRA({\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [13], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [12], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [11], +\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [10], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [9], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [8], +\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [7], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [6], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [5], +\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [4], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [3], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [2], +\U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [1], \U0/I_NO_D.U_ILA/U_CAPSTOR/RD_ADDR [0]}), + .ADDRB({\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [8], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [7], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [6], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [5] +, \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [4], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [3], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [2], \U0/I_NO_D.U_ILA/iCAP_WR_ADDR [1], +\U0/I_NO_D.U_ILA/iCAP_WR_ADDR [0]}), + .DIB({N0, N0, N0, \U0/I_NO_D.U_ILA/iDATA [27], \U0/I_NO_D.U_ILA/iDATA [26], \U0/I_NO_D.U_ILA/iDATA [25], \U0/I_NO_D.U_ILA/iDATA [24], +\U0/I_NO_D.U_ILA/iDATA [23], \U0/I_NO_D.U_ILA/iDATA [22], \U0/I_NO_D.U_ILA/iDATA [21], \U0/I_NO_D.U_ILA/iDATA [20], \U0/I_NO_D.U_ILA/iDATA [19], +\U0/I_NO_D.U_ILA/iDATA [18], \U0/I_NO_D.U_ILA/iDATA [17], \U0/I_NO_D.U_ILA/iDATA [16], \U0/I_NO_D.U_ILA/iDATA [15], \U0/I_NO_D.U_ILA/iDATA [14], +\U0/I_NO_D.U_ILA/iDATA [13], \U0/I_NO_D.U_ILA/iDATA [12], \U0/I_NO_D.U_ILA/iDATA [11], \U0/I_NO_D.U_ILA/iDATA [10], \U0/I_NO_D.U_ILA/iDATA [9], +\U0/I_NO_D.U_ILA/iDATA [8], \U0/I_NO_D.U_ILA/iDATA [7], \U0/I_NO_D.U_ILA/iDATA [6], \U0/I_NO_D.U_ILA/iDATA [5], \U0/I_NO_D.U_ILA/iDATA [4], +\U0/I_NO_D.U_ILA/iDATA [3], \U0/I_NO_D.U_ILA/iDATA [2], \U0/I_NO_D.U_ILA/iDATA [1], \U0/I_NO_D.U_ILA/iDATA [0], \U0/I_NO_D.U_ILA/iCAP_TRIGGER_OUT }), + .DOA({\U0/I_NO_D.U_ILA/iDATA_DOUT }), + .DIA({N0}), + .DOB({\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<31>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<30>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<29>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<28>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<27>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<26>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<25>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<24>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<23>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<22>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<21>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<20>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<19>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<18>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<17>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<16>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<15>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<14>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<13>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<12>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<11>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<10>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<9>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<8>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<7>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<6>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<5>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<4>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<3>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<2>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<1>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOB<0>_UNCONNECTED }), + .DOPB({\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<3>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<2>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<1>_UNCONNECTED , +\NLW_U0/I_NO_D.U_ILA/U_CAPSTOR/I_CASE1.I_NO_TB.I_RT1.U_RAM/G_BRAM[0].U_BRAM/ram_rt1_s1_s32_if.ram_rt1_s1_s32_i_DOPB<0>_UNCONNECTED }) + ); + +// synthesis translate_on + +endmodule + +// synthesis translate_off + +`ifndef GLBL +`define GLBL + +`timescale 1 ps / 1 ps + +module glbl (); + + parameter ROC_WIDTH = 100000; + parameter TOC_WIDTH = 0; + + wire GSR; + wire GTS; + wire GWE; + wire PRLD; + tri1 p_up_tmp; + tri (weak1, strong0) PLL_LOCKG = p_up_tmp; + + reg GSR_int; + reg GTS_int; + reg PRLD_int; + +//-------- JTAG Globals -------------- + wire JTAG_TDO_GLBL; + wire JTAG_TCK_GLBL; + wire JTAG_TDI_GLBL; + wire JTAG_TMS_GLBL; + wire JTAG_TRST_GLBL; + + reg JTAG_CAPTURE_GLBL; + reg JTAG_RESET_GLBL; + reg JTAG_SHIFT_GLBL; + reg JTAG_UPDATE_GLBL; + reg JTAG_RUNTEST_GLBL; + + reg JTAG_SEL1_GLBL = 0; + reg JTAG_SEL2_GLBL = 0 ; + reg JTAG_SEL3_GLBL = 0; + reg JTAG_SEL4_GLBL = 0; + + reg JTAG_USER_TDO1_GLBL = 1'bz; + reg JTAG_USER_TDO2_GLBL = 1'bz; + reg JTAG_USER_TDO3_GLBL = 1'bz; + reg JTAG_USER_TDO4_GLBL = 1'bz; + + assign (weak1, weak0) GSR = GSR_int; + assign (weak1, weak0) GTS = GTS_int; + assign (weak1, weak0) PRLD = PRLD_int; + + initial begin + GSR_int = 1'b1; + PRLD_int = 1'b1; + #(ROC_WIDTH) + GSR_int = 1'b0; + PRLD_int = 1'b0; + end + + initial begin + GTS_int = 1'b1; + #(TOC_WIDTH) + GTS_int = 1'b0; + end + +endmodule + +`endif + +// synthesis translate_on diff --git a/fpga/usrp2/extramfifo/ila.xco b/fpga/usrp2/extramfifo/ila.xco new file mode 100644 index 000000000..c8d4d2f75 --- /dev/null +++ b/fpga/usrp2/extramfifo/ila.xco @@ -0,0 +1,130 @@ +############################################################## +# +# Xilinx Core Generator version 12.1 +# Date: Wed Jul 21 18:51:14 2010 +# +############################################################## +# +# This file contains the customisation parameters for a +# Xilinx CORE Generator IP GUI. It is strongly recommended +# that you do not manually alter this file as it may cause +# unexpected and unsupported behavior. +# +############################################################## +# +# BEGIN Project Options +SET addpads = false +SET asysymbol = true +SET busformat = BusFormatAngleBracketNotRipped +SET createndf = false +SET designentry = Verilog +SET device = xc3s2000 +SET devicefamily = spartan3 +SET flowvendor = Other +SET formalverification = false +SET foundationsym = false +SET implementationfiletype = Ngc +SET package = fg456 +SET removerpms = false +SET simulationfiles = Structural +SET speedgrade = -5 +SET verilogsim = true +SET vhdlsim = false +# END Project Options +# BEGIN Select +SELECT ILA_(ChipScope_Pro_-_Integrated_Logic_Analyzer) family Xilinx,_Inc. 1.03.a +# END Select +# BEGIN Parameters +CSET component_name=ila +CSET counter_width_1=Disabled +CSET counter_width_10=Disabled +CSET counter_width_11=Disabled +CSET counter_width_12=Disabled +CSET counter_width_13=Disabled +CSET counter_width_14=Disabled +CSET counter_width_15=Disabled +CSET counter_width_16=Disabled +CSET counter_width_2=Disabled +CSET counter_width_3=Disabled +CSET counter_width_4=Disabled +CSET counter_width_5=Disabled +CSET counter_width_6=Disabled +CSET counter_width_7=Disabled +CSET counter_width_8=Disabled +CSET counter_width_9=Disabled +CSET data_port_width=0 +CSET data_same_as_trigger=true +CSET enable_storage_qualification=true +CSET enable_trigger_output_port=false +CSET exclude_from_data_storage_1=false +CSET exclude_from_data_storage_10=false +CSET exclude_from_data_storage_11=false +CSET exclude_from_data_storage_12=false +CSET exclude_from_data_storage_13=false +CSET exclude_from_data_storage_14=false +CSET exclude_from_data_storage_15=false +CSET exclude_from_data_storage_16=false +CSET exclude_from_data_storage_2=false +CSET exclude_from_data_storage_3=false +CSET exclude_from_data_storage_4=false +CSET exclude_from_data_storage_5=false +CSET exclude_from_data_storage_6=false +CSET exclude_from_data_storage_7=false +CSET exclude_from_data_storage_8=false +CSET exclude_from_data_storage_9=false +CSET match_type_1=basic +CSET match_type_10=basic +CSET match_type_11=basic +CSET match_type_12=basic +CSET match_type_13=basic +CSET match_type_14=basic +CSET match_type_15=basic +CSET match_type_16=basic +CSET match_type_2=basic +CSET match_type_3=basic +CSET match_type_4=basic +CSET match_type_5=basic +CSET match_type_6=basic +CSET match_type_7=basic +CSET match_type_8=basic +CSET match_type_9=basic +CSET match_units_1=1 +CSET match_units_10=1 +CSET match_units_11=1 +CSET match_units_12=1 +CSET match_units_13=1 +CSET match_units_14=1 +CSET match_units_15=1 +CSET match_units_16=1 +CSET match_units_2=1 +CSET match_units_3=1 +CSET match_units_4=1 +CSET match_units_5=1 +CSET match_units_6=1 +CSET match_units_7=1 +CSET match_units_8=1 +CSET match_units_9=1 +CSET max_sequence_levels=1 +CSET number_of_trigger_ports=4 +CSET sample_data_depth=512 +CSET sample_on=Rising +CSET trigger_port_width_1=8 +CSET trigger_port_width_10=8 +CSET trigger_port_width_11=8 +CSET trigger_port_width_12=8 +CSET trigger_port_width_13=8 +CSET trigger_port_width_14=8 +CSET trigger_port_width_15=8 +CSET trigger_port_width_16=8 +CSET trigger_port_width_2=8 +CSET trigger_port_width_3=8 +CSET trigger_port_width_4=4 +CSET trigger_port_width_5=8 +CSET trigger_port_width_6=8 +CSET trigger_port_width_7=8 +CSET trigger_port_width_8=8 +CSET trigger_port_width_9=8 +CSET use_rpms=true +# END Parameters +GENERATE +# CRC: 66151c7c diff --git a/fpga/usrp2/extramfifo/nobl_fifo.v b/fpga/usrp2/extramfifo/nobl_fifo.v new file mode 100644 index 000000000..4c009d980 --- /dev/null +++ b/fpga/usrp2/extramfifo/nobl_fifo.v @@ -0,0 +1,96 @@ +// Since this FIFO uses a ZBT/NoBL SRAM for its storage which is a since port +// device it can only sustain data throughput at half the RAM clock rate. +// Fair arbitration to ensure this occurs is included in this logic and +// requests for transactions that can not be completed are held off. +// This FIFO requires a an external signal driving read_strobe that assures space for at least 6 +// reads since this the theopretical maximum number in flight due to pipeling. + +module nobl_fifo + #(parameter WIDTH=18,RAM_DEPTH=19,FIFO_DEPTH=19) + ( + input clk, + input rst, + input [WIDTH-1:0] RAM_D_pi, + output [WIDTH-1:0] RAM_D_po, + output RAM_D_poe, + output [RAM_DEPTH-1:0] RAM_A, + output RAM_WEn, + output RAM_CENn, + output RAM_LDn, + output RAM_OEn, + output RAM_CE1n, + input [WIDTH-1:0] write_data, + input write_strobe, + output reg space_avail, + output [WIDTH-1:0] read_data, + input read_strobe, // Triggers a read, result in approximately 6 cycles. + output data_avail, // Qulaifys read data available this cycle on read_data. + output reg [FIFO_DEPTH-1:0] capacity + ); + + //reg [FIFO_DEPTH-1:0] capacity; + reg [FIFO_DEPTH-1:0] wr_pointer; + reg [FIFO_DEPTH-1:0] rd_pointer; + wire [RAM_DEPTH-1:0] address; + reg data_avail_int; // Internal not empty flag. + + assign read = read_strobe && data_avail_int; + assign write = write_strobe && space_avail; + + // When a read and write collision occur, supress the space_avail flag next cycle + // and complete write followed by read over 2 cycles. This forces balanced arbitration + // and makes for a simple logic design. + + always @(posedge clk) + if (rst) + begin + capacity <= (1 << FIFO_DEPTH) - 1; + wr_pointer <= 0; + rd_pointer <= 0; + space_avail <= 1; + data_avail_int <= 0; + end + else + begin + // No space available if: + // Capacity is already zero; Capacity is 1 and write is asserted (lookahead); both read and write are asserted (collision) + space_avail <= ~((capacity == 0) || (read&&write) || ((capacity == 1) && write) ); + // Capacity has 1 cycle delay so look ahead here for corner case of read of last item in FIFO. + data_avail_int <= ~((capacity == ((1 << FIFO_DEPTH)-1)) || ((capacity == ((1 << FIFO_DEPTH)-2)) && (~write && read)) ); + wr_pointer <= wr_pointer + write; + rd_pointer <= rd_pointer + (~write && read); + capacity <= capacity - write + (~write && read) ; + end // else: !if(rst) + + assign address = write ? wr_pointer : rd_pointer; + assign enable = write || read; + + + // + // Simple NoBL SRAM interface, 4 cycle read latency. + // Read/Write arbitration via temprary application of empty/full flags. + // + nobl_if nobl_if_i1 + ( + .clk(clk), + .rst(rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), + .address(address), + .data_out(write_data), + .data_in(read_data), + .data_in_valid(data_avail), + .write(write), + .enable(enable) + ); + + + +endmodule // nobl_fifo diff --git a/fpga/usrp2/extramfifo/nobl_if.v b/fpga/usrp2/extramfifo/nobl_if.v new file mode 100644 index 000000000..adf9f165b --- /dev/null +++ b/fpga/usrp2/extramfifo/nobl_if.v @@ -0,0 +1,145 @@ +// Tested against an IDT 71v65603s150 in simulation and a Cypress 7C1356C in the real world. + +module nobl_if + #(parameter WIDTH=18,DEPTH=19) + ( + input clk, + input rst, + input [WIDTH-1:0] RAM_D_pi, + output [WIDTH-1:0] RAM_D_po, + output reg RAM_D_poe, + output [DEPTH-1:0] RAM_A, + output reg RAM_WEn, + output RAM_CENn, + output RAM_LDn, + output RAM_OEn, + output reg RAM_CE1n, + input [DEPTH-1:0] address, + input [WIDTH-1:0] data_out, + output reg [WIDTH-1:0] data_in, + output reg data_in_valid, + input write, + input enable + ); + + + reg enable_pipe1; + reg [DEPTH-1:0] address_pipe1; + reg write_pipe1; + reg [WIDTH-1:0] data_out_pipe1; + + reg enable_pipe2; + reg write_pipe2; + reg [WIDTH-1:0] data_out_pipe2; + + reg enable_pipe3; + reg write_pipe3; + reg [WIDTH-1:0] data_out_pipe3; + + assign RAM_LDn = 0; + // ZBT/NoBL RAM actually manages its own output enables very well. + assign RAM_OEn = 0; + + // gray code the address to reduce EMI + wire [DEPTH-1:0] address_gray; + + bin2gray #(.WIDTH(DEPTH)) bin2gray (.bin(address),.gray(address_gray)); + + + // + // Pipeline stage 1 + // + always @(posedge clk) + if (rst) + begin + enable_pipe1 <= 0; + address_pipe1 <= 0; + write_pipe1 <= 0; + data_out_pipe1 <= 0; + end + else + begin + enable_pipe1 <= enable; + RAM_CE1n <= ~enable; // Creates IOB flob + + + if (enable) + begin + address_pipe1 <= address_gray; + write_pipe1 <= write; + RAM_WEn <= ~write; // Creates IOB flob + + + if (write) + data_out_pipe1 <= data_out; + end + end // always @ (posedge clk) + + // Pipeline 1 drives address, write_enable, chip_select on NoBL SRAM + assign RAM_A = address_pipe1; + assign RAM_CENn = 1'b0; + // assign RAM_WEn = ~write_pipe1; +// assign RAM_CE1n = ~enable_pipe1; + + // + // Pipeline stage2 + // + always @(posedge clk) + if (rst) + begin + enable_pipe2 <= 0; + data_out_pipe2 <= 0; + write_pipe2 <= 0; + end + else + begin + data_out_pipe2 <= data_out_pipe1; + write_pipe2 <= write_pipe1; + enable_pipe2 <= enable_pipe1; + end + + // + // Pipeline stage3 + // + always @(posedge clk) + if (rst) + begin + enable_pipe3 <= 0; + data_out_pipe3 <= 0; + write_pipe3 <= 0; + RAM_D_poe <= 0; + end + else + begin + data_out_pipe3 <= data_out_pipe2; + write_pipe3 <= write_pipe2; + enable_pipe3 <= enable_pipe2; + RAM_D_poe <= ~(write_pipe2 & enable_pipe2); // Active low driver enable in Xilinx. + end + + // Pipeline 3 drives write data on NoBL SRAM + assign RAM_D_po = data_out_pipe3; + + + // + // Pipeline stage4 + // + always @(posedge clk) + if (rst) + begin + data_in_valid <= 0; + data_in <= 0; + end + else + begin + data_in <= RAM_D_pi; + if (enable_pipe3 & ~write_pipe3) + begin + // Read data now available to be registered. + data_in_valid <= 1'b1; + end + else + data_in_valid <= 1'b0; + end // always @ (posedge clk) + +endmodule // nobl_if diff --git a/fpga/usrp2/extramfifo/refill_randomizer.v b/fpga/usrp2/extramfifo/refill_randomizer.v new file mode 100644 index 000000000..0b30f4049 --- /dev/null +++ b/fpga/usrp2/extramfifo/refill_randomizer.v @@ -0,0 +1,66 @@ +// +// EMI mitigation. +// Process FULL flag from FIFO so that de-assertion +// (FIFO now not FULL) is delayed by a pseudo random +// value, but assertion is passed straight through. +// + + +module refill_randomizer + #(parameter BITS=7) + ( + input clk, + input rst, + input full_in, + output full_out + ); + + wire feedback; + reg full_last; + wire full_deasserts; + reg [6:0] shift_reg; + reg [6:0] count; + reg delayed_fall; + + + always @(posedge clk) + full_last <= full_in; + + assign full_deasserts = full_last & ~full_in; + + // 7 bit LFSR + always @(posedge clk) + if (rst) + shift_reg <= 7'b1; + else + if (full_deasserts) + shift_reg <= {shift_reg[5:0],feedback}; + + assign feedback = ^(shift_reg & 7'h41); + + always @(posedge clk) + if (rst) + begin + count <= 1; + delayed_fall <= 1; + end + else if (full_deasserts) + begin + count <= shift_reg; + delayed_fall <= 1; + end + else if (count == 1) + begin + count <= 1; + delayed_fall <= 0; + end + else + begin + count <= count - 1; + delayed_fall <= 1; + end + + // Full_out goes instantly high if full_in does. However its fall is delayed. + assign full_out = (full_in == 1) || (full_last == 1) || delayed_fall; + +endmodule
\ No newline at end of file diff --git a/fpga/usrp2/extramfifo/test_sram_if.v b/fpga/usrp2/extramfifo/test_sram_if.v new file mode 100644 index 000000000..0e74b49eb --- /dev/null +++ b/fpga/usrp2/extramfifo/test_sram_if.v @@ -0,0 +1,175 @@ +// Instantiate this block at the core level to conduct closed +// loop testing of the AC performance of the USRP2 SRAM interface + + +`define WIDTH 18 +`define DEPTH 19 + +module test_sram_if + ( + input clk, + input rst, + input [`WIDTH-1:0] RAM_D_pi, + output [`WIDTH-1:0] RAM_D_po, + output RAM_D_poe, + output [`DEPTH-1:0] RAM_A, + output RAM_WEn, + output RAM_CENn, + output RAM_LDn, + output RAM_OEn, + output RAM_CE1n, + output reg correct + ); + + reg [`DEPTH-1:0] write_count; + reg [`DEPTH-1:0] read_count; + reg enable; + reg write; + reg write_cycle; + reg read_cycle; + reg enable_reads; + reg [18:0] address; + reg [17:0] data_out; + wire [17:0] data_in; + wire data_in_valid; + + reg [17:0] check_data; + reg [17:0] check_data_old; + reg [17:0] check_data_old2; + + // + // Create counter that generates both external modulo 2^19 address and modulo 2^18 data to test RAM. + // + + always @(posedge clk) + if (rst) + begin + write_count <= 19'h0; + read_count <= 19'h0; + end + else if (write_cycle) // Write cycle + if (write_count == 19'h7FFFF) + begin + write_count <= 19'h0; + end + else + begin + write_count <= write_count + 1'b1; + end + else if (read_cycle) // Read cycle + if (read_count == 19'h7FFFF) + begin + read_count <= 19'h0; + end + else + begin + read_count <= read_count + 1'b1; + end + + always @(posedge clk) + if (rst) + begin + enable_reads <= 0; + read_cycle <= 0; + write_cycle <= 0; + end + else + begin + write_cycle <= ~write_cycle; + if (enable_reads) + read_cycle <= write_cycle; + if (write_count == 15) // Enable reads 15 writes after reset terminates. + enable_reads <= 1; + end // else: !if(rst) + + always @(posedge clk) + if (rst) + begin + enable <= 0; + end + else if (write_cycle) + begin + address <= write_count; + data_out <= write_count[17:0]; + enable <= 1; + write <= 1; + end + else if (read_cycle) + begin + address <= read_count; + check_data <= read_count[17:0]; + check_data_old <= check_data; + check_data_old2 <= check_data_old; + enable <= 1; + write <= 0; + end + else + enable <= 0; + + always @(posedge clk) + if (data_in_valid) + begin + correct <= (data_in == check_data_old2); + end + + + nobl_if nobl_if_i1 + ( + .clk(clk), + .rst(rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), + .address(address), + .data_out(data_out), + .data_in(data_in), + .data_in_valid(data_in_valid), + .write(write), + .enable(enable) + ); + + + wire [35:0] CONTROL0; + reg [7:0] data_in_reg, data_out_reg, address_reg; + reg data_in_valid_reg,write_reg,enable_reg,correct_reg; + + always @(posedge clk) + begin + data_in_reg <= data_in[7:0]; + data_out_reg <= data_out[7:0]; + data_in_valid_reg <= data_in_valid; + write_reg <= write; + enable_reg <= enable; + correct_reg <= correct; + address_reg <= address; + + end + + + icon icon_i1 + ( + .CONTROL0(CONTROL0) + ); + + ila ila_i1 + ( + .CLK(clk), + .CONTROL(CONTROL0), + // .TRIG0(address_reg), + .TRIG0(data_in_reg[7:0]), + .TRIG1(data_out_reg[7:0]), + .TRIG2(address_reg[7:0]), + .TRIG3({data_in_valid_reg,write_reg,enable_reg,correct_reg}) + ); + + + +endmodule // test_sram_if + +
\ No newline at end of file diff --git a/fpga/usrp2/fifo/fifo18_to_fifo36.v b/fpga/usrp2/fifo/fifo18_to_fifo36.v new file mode 100644 index 000000000..25bb215a1 --- /dev/null +++ b/fpga/usrp2/fifo/fifo18_to_fifo36.v @@ -0,0 +1,20 @@ + +// For now just assume FIFO18 is same as FIFO19 without occupancy bit + +module fifo18_to_fifo36 + (input clk, input reset, input clear, + input [17:0] f18_datain, + input f18_src_rdy_i, + output f18_dst_rdy_o, + + output [35:0] f36_dataout, + output f36_src_rdy_o, + input f36_dst_rdy_i + ); + + fifo19_to_fifo36 fifo19_to_fifo36 + (.clk(clk), .reset(reset), .clear(clear), + .f19_datain({1'b0,f18_datain}), .f19_src_rdy_i(f18_src_rdy_i), .f19_dst_rdy_o(f18_dst_rdy_o), + .f36_dataout(f36_dataout), .f36_src_rdy_o(f36_src_rdy_o), .f36_dst_rdy_i(f36_dst_rdy_i) ); + +endmodule // fifo18_to_fifo36 diff --git a/fpga/usrp2/fifo/fifo36_mux.v b/fpga/usrp2/fifo/fifo36_mux.v index 92bf13ff9..c6fd40f27 100644 --- a/fpga/usrp2/fifo/fifo36_mux.v +++ b/fpga/usrp2/fifo/fifo36_mux.v @@ -20,6 +20,9 @@ module fifo36_mux wire eof0 = data0_i[33]; wire eof1 = data1_i[33]; + wire [35:0] data_int; + wire src_rdy_int, dst_rdy_int; + always @(posedge clk) if(reset | clear) state <= MUX_IDLE0; @@ -32,7 +35,7 @@ module fifo36_mux state <= MUX_DATA1; MUX_DATA0 : - if(src0_rdy_i & dst_rdy_i & eof0) + if(src0_rdy_i & dst_rdy_int & eof0) state <= prio ? MUX_IDLE0 : MUX_IDLE1; MUX_IDLE1 : @@ -42,16 +45,20 @@ module fifo36_mux state <= MUX_DATA0; MUX_DATA1 : - if(src1_rdy_i & dst_rdy_i & eof1) + if(src1_rdy_i & dst_rdy_int & eof1) state <= MUX_IDLE0; default : state <= MUX_IDLE0; endcase // case (state) - assign dst0_rdy_o = (state==MUX_DATA0) ? dst_rdy_i : 0; - assign dst1_rdy_o = (state==MUX_DATA1) ? dst_rdy_i : 0; - assign src_rdy_o = (state==MUX_DATA0) ? src0_rdy_i : (state==MUX_DATA1) ? src1_rdy_i : 0; - assign data_o = (state==MUX_DATA0) ? data0_i : data1_i; + assign dst0_rdy_o = (state==MUX_DATA0) ? dst_rdy_int : 0; + assign dst1_rdy_o = (state==MUX_DATA1) ? dst_rdy_int : 0; + assign src_rdy_int = (state==MUX_DATA0) ? src0_rdy_i : (state==MUX_DATA1) ? src1_rdy_i : 0; + assign data_int = (state==MUX_DATA0) ? data0_i : data1_i; + fifo_short #(.WIDTH(36)) mux_fifo + (.clk(clk), .reset(reset), .clear(clear), + .datain(data_int), .src_rdy_i(src_rdy_int), .dst_rdy_o(dst_rdy_int), + .dataout(data_o), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); endmodule // fifo36_demux diff --git a/fpga/usrp2/fifo/fifo_2clock_cascade.v b/fpga/usrp2/fifo/fifo_2clock_cascade.v index 5ce726977..4e8c244c2 100644 --- a/fpga/usrp2/fifo/fifo_2clock_cascade.v +++ b/fpga/usrp2/fifo/fifo_2clock_cascade.v @@ -1,8 +1,10 @@ module fifo_2clock_cascade #(parameter WIDTH=32, SIZE=9) - (input wclk, input [WIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output [15:0] space, - input rclk, output [WIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output [15:0] occupied, + (input wclk, input [WIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, + output [15:0] space, output [15:0] short_space, + input rclk, output [WIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, + output [15:0] occupied, output [15:0] short_occupied, input arst); wire [WIDTH-1:0] data_int1, data_int2; @@ -29,7 +31,11 @@ module fifo_2clock_cascade .space(s2_space), .occupied(s2_occupied)); // Be conservative -- Only advertise space from input side of fifo, occupied from output side - assign space = {11'b0,s1_space} + l_space; - assign occupied = {11'b0,s2_occupied} + l_occupied; + assign space = {11'b0,s1_space} + l_space; + assign occupied = {11'b0,s2_occupied} + l_occupied; + + // For the fifo_extram, we only want to know the immediately adjacent space + assign short_space = {11'b0,s1_space}; + assign short_occupied = {11'b0,s2_occupied}; endmodule // fifo_2clock_cascade diff --git a/fpga/usrp2/models/idt71v65603s150.v b/fpga/usrp2/models/idt71v65603s150.v new file mode 100755 index 000000000..457dfa6dd --- /dev/null +++ b/fpga/usrp2/models/idt71v65603s150.v @@ -0,0 +1,301 @@ +/******************************************************************************* + * + * File Name : idt71v65603s150.v + * Product : IDT71V65603 + * Function : 256K x 36 pipeline ZBT Static RAM + * Simulation Tool/Version : Verilog-XL 2.5 + * Date : 07/19/00 + * + * Copyright 1999 Integrated Device Technology, Inc. + * + * Revision Notes: 07/19/00 Rev00 + * + ******************************************************************************/ +/******************************************************************************* + * Module Name: idt71v65603s150 + * + * Notes : This model is believed to be functionally + * accurate. Please direct any inquiries to + * IDT SRAM Applications at: sramhelp@idt.com + * + *******************************************************************************/ + + /*************************************************************** + * + * Integrated Device Technology, Inc. ("IDT") hereby grants the + * user of this Verilog/VCS model a non-exclusive, nontransferable + * license to use this Verilog/VCS model under the following terms. + * The user is granted this license only to use the Verilog/VCS + * model and is not granted rights to sell, copy (except as needed + * to run the IBIS model), rent, lease or sub-license the Verilog/VCS + * model in whole or in part, or in modified form to anyone. The User + * may modify the Verilog/VCS model to suit its specific applications, + * but rights to derivative works and such modifications shall belong + * to IDT. + * + * This Verilog/VCS model is provided on an "AS IS" basis and + * IDT makes absolutely no warranty with respect to the information + * contained herein. IDT DISCLAIMS AND CUSTOMER WAIVES ALL + * WARRANTIES, EXPRESS AND IMPLIED, INCLUDING WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * ENTIRE RISK AS TO QUALITY AND PERFORMANCE IS WITH THE + * USER ACCORDINGLY, IN NO EVENT SHALL IDT BE LIABLE + * FOR ANY DIRECT OR INDIRECT DAMAGES, WHETHER IN CONTRACT OR + * TORT, INCLUDING ANY LOST PROFITS OR OTHER INCIDENTAL, + * CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES ARISING OUT OF + * THE USE OR APPLICATION OF THE VERILOG/VCS model. Further, + * IDT reserves the right to make changes without notice to any + * product herein to improve reliability, function, or design. + * IDT does not convey any license under patent rights or + * any other intellectual property rights, including those of + * third parties. IDT is not obligated to provide maintenance + * or support for the licensed Verilog/VCS model. + * + ***************************************************************/ + + `timescale 1ns/100ps + +module idt71v65603s150 (A, + adv_ld_, // advance (high) / load (low) + bw1_, bw2_, bw3_, bw4_, // byte write enables (low) + ce1_, ce2, ce2_, // chip enables + cen_, // clock enable (low) + clk, // clock + IO, IOP, // data bus + lbo_, // linear burst order (low) + oe_, // output enable (low) + r_w_); // read (high) / write (low) + +initial +begin + $write("\n********************************************************\n"); + $write(" idt71v65603s150, 256K x 36 Pipelined burst ZBT SRAM \n"); + $write(" Rev: 00 July 2000 \n"); + $write(" copyright 1997,1998,1999,2000 by IDT, Inc. \n"); + $write("********************************************************\n\n"); +end + +input [17:0] A; +inout [31:0] IO; +inout [4:1] IOP; +input adv_ld_, bw1_, bw2_, bw3_, bw4_, ce1_, ce2, ce2_, + cen_, clk, lbo_, oe_, r_w_; + + +//internal registers for data, address, etc +reg [8:0] mem1[0:262143]; //memory array +reg [8:0] mem2[0:262143]; //memory array +reg [8:0] mem3[0:262143]; //memory array +reg [8:0] mem4[0:262143]; //memory array + +reg [35:0] dout; +reg [17:0] addr_a, + addr_b; +reg wren_a, wren_b; +reg cs_a, cs_b; +reg bw_a1, bw_b1; +reg bw_a2, bw_b2; +reg bw_a3, bw_b3; +reg bw_a4, bw_b4; +reg [1:0] brst_cnt; + +wire[35:0] data_out; +wire doe; +wire cs = (~ce1_ & ce2 & ~ce2_); +wire baddr0, baddr1; + + +parameter regdelay = 0.2; +parameter outdly = 0.2; + +specify +specparam +//Clock Parameters + tCYC = 6.7, //clock cycle time + tCH = 2.0, //clock high time + tCL = 2.0, //clock low time + +//Output Parameters + tCD = 3.8, //clk to data valid + tCLZ = 1.5, //clk to output Low-Z + tCHZ = 3.0, //clk to data Hi-Z + tOE = 3.8, //OE to output valid + tOLZ = 0.0, //OE to output Hi-Z + tOHZ = 3.8, //OE to output Hi-Z + +//Set up times + tSE = 1.5, //clock enable set-up + tSA = 1.5, //address set-up + tSD = 1.5, //data set-up + tSW = 1.5, //Read/Write set-up + tSADV = 1.5, //Advance/Load set-up + tSC = 1.5, //Chip enable set-up + tSB = 1.5, //Byte write enable set-up + +//Hold times + tHE = 0.5, //clock enable hold + tHA = 0.5, //address hold + tHD = 0.5, //data hold + tHW = 0.5, //Read/Write hold + tHADV = 0.5, //Advance/Load hold + tHC = 0.5, //Chip enable hold + tHB = 0.5; //Byte write enable hold + + + (oe_ *> IO) = (tOE,tOE,tOHZ,tOLZ,tOHZ,tOLZ); //(01,10,0z,z1,1z,z0) + (clk *> IO) = (tCD,tCD,tCHZ,tCLZ,tCHZ,tCLZ); //(01,10,0z,z1,1z,z0) + + (oe_ *> IOP) = (tOE,tOE,tOHZ,tOLZ,tOHZ,tOLZ); //(01,10,0z,z1,1z,z0) + (clk *> IOP) = (tCD,tCD,tCHZ,tCLZ,tCHZ,tCLZ); //(01,10,0z,z1,1z,z0) + +//timing checks + + $period(posedge clk, tCYC ); + $width (posedge clk, tCH ); + $width (negedge clk, tCL ); + + + $setuphold(posedge clk, A, tSA, tHA); + $setuphold(posedge clk, IO, tSD, tHD); + $setuphold(posedge clk, IOP, tSD, tHD); + $setuphold(posedge clk, adv_ld_, tSADV, tHADV); + $setuphold(posedge clk, bw1_, tSB, tHB); + $setuphold(posedge clk, bw2_, tSB, tHB); + $setuphold(posedge clk, bw3_, tSB, tHB); + $setuphold(posedge clk, bw4_, tSB, tHB); + $setuphold(posedge clk, ce1_, tSC, tHC); + $setuphold(posedge clk, ce2, tSC, tHC); + $setuphold(posedge clk, ce2_, tSC, tHC); + $setuphold(posedge clk, cen_, tSE, tHE); + $setuphold(posedge clk, r_w_, tSW, tHW); + +endspecify + +initial begin + cs_a = 0; + cs_b = 0; +end + + +///////////////////////////////////////////////////////////////////////// +//input registers +//-------------------- +always @(posedge clk) +begin + if ( ~cen_ & ~adv_ld_ ) cs_a <= #regdelay cs; + if ( ~cen_ ) cs_b <= #regdelay cs_a; + + if ( ~cen_ & ~adv_ld_ ) wren_a <= #regdelay (cs & ~r_w_); + if ( ~cen_ ) wren_b <= #regdelay wren_a; + + if ( ~cen_ ) bw_a1 <= #regdelay ~bw1_; + if ( ~cen_ ) bw_a2 <= #regdelay ~bw2_; + if ( ~cen_ ) bw_a3 <= #regdelay ~bw3_; + if ( ~cen_ ) bw_a4 <= #regdelay ~bw4_; + + if ( ~cen_ ) bw_b1 <= #regdelay bw_a1; + if ( ~cen_ ) bw_b2 <= #regdelay bw_a2; + if ( ~cen_ ) bw_b3 <= #regdelay bw_a3; + if ( ~cen_ ) bw_b4 <= #regdelay bw_a4; + + if ( ~cen_ & ~adv_ld_ ) addr_a[17:0] <= #regdelay A[17:0]; + if ( ~cen_ ) addr_b[17:0] <= #regdelay {addr_a[17:2], baddr1, baddr0}; +end + + +///////////////////////////////////////////////////////////////////////// +//burst counter +//-------------------- +always @(posedge clk) +begin + if ( lbo_ & ~cen_ & ~adv_ld_) brst_cnt <= #regdelay 0; + else if (~lbo_ & ~cen_ & ~adv_ld_) brst_cnt <= #regdelay A[1:0]; + else if ( ~cen_ & adv_ld_) brst_cnt <= #regdelay brst_cnt + 1; +end + + +///////////////////////////////////////////////////////////////////////// +//address logic +//-------------------- +assign baddr1 = lbo_ ? (brst_cnt[1] ^ addr_a[1]) : brst_cnt[1]; +assign baddr0 = lbo_ ? (brst_cnt[0] ^ addr_a[0]) : brst_cnt[0]; + + +///////////////////////////////////////////////////////////////////////// +//data output register +//-------------------- +always @(posedge clk) +begin + #regdelay; + #regdelay; + dout[8:0] = mem1[addr_b]; + dout[17:9] = mem2[addr_b]; + dout[26:18] = mem3[addr_b]; + dout[35:27] = mem4[addr_b]; +end + +assign data_out = dout; + + +///////////////////////////////////////////////////////////////////////// +//Output buffers: using a bufif1 has the same effect as... +// +// assign D = doe ? data_out : 36'hz; +// +//It was coded this way to support SPECIFY delays in the specparam section. +//-------------------- +bufif1 #outdly (IO[0],data_out[0],doe); +bufif1 #outdly (IO[1],data_out[1],doe); +bufif1 #outdly (IO[2],data_out[2],doe); +bufif1 #outdly (IO[3],data_out[3],doe); +bufif1 #outdly (IO[4],data_out[4],doe); +bufif1 #outdly (IO[5],data_out[5],doe); +bufif1 #outdly (IO[6],data_out[6],doe); +bufif1 #outdly (IO[7],data_out[7],doe); +bufif1 #outdly (IOP[1],data_out[8],doe); + +bufif1 #outdly (IO[8],data_out[9],doe); +bufif1 #outdly (IO[9],data_out[10],doe); +bufif1 #outdly (IO[10],data_out[11],doe); +bufif1 #outdly (IO[11],data_out[12],doe); +bufif1 #outdly (IO[12],data_out[13],doe); +bufif1 #outdly (IO[13],data_out[14],doe); +bufif1 #outdly (IO[14],data_out[15],doe); +bufif1 #outdly (IO[15],data_out[16],doe); +bufif1 #outdly (IOP[2],data_out[17],doe); + +bufif1 #outdly (IO[16],data_out[18],doe); +bufif1 #outdly (IO[17],data_out[19],doe); +bufif1 #outdly (IO[18],data_out[20],doe); +bufif1 #outdly (IO[19],data_out[21],doe); +bufif1 #outdly (IO[20],data_out[22],doe); +bufif1 #outdly (IO[21],data_out[23],doe); +bufif1 #outdly (IO[22],data_out[24],doe); +bufif1 #outdly (IO[23],data_out[25],doe); +bufif1 #outdly (IOP[3],data_out[26],doe); + +bufif1 #outdly (IO[24],data_out[27],doe); +bufif1 #outdly (IO[25],data_out[28],doe); +bufif1 #outdly (IO[26],data_out[29],doe); +bufif1 #outdly (IO[27],data_out[30],doe); +bufif1 #outdly (IO[28],data_out[31],doe); +bufif1 #outdly (IO[29],data_out[32],doe); +bufif1 #outdly (IO[30],data_out[33],doe); +bufif1 #outdly (IO[31],data_out[34],doe); +bufif1 #outdly (IOP[4],data_out[35],doe); + +assign doe = cs_b & ~wren_b & ~oe_ ; + + +///////////////////////////////////////////////////////////////////////// +// write to ram +//------------- +always @(posedge clk) +begin + if (wren_b & bw_b1 & ~cen_) mem1[addr_b] = {IOP[1], IO[7:0]}; + if (wren_b & bw_b2 & ~cen_) mem2[addr_b] = {IOP[2], IO[15:8]}; + if (wren_b & bw_b3 & ~cen_) mem3[addr_b] = {IOP[3], IO[23:16]}; + if (wren_b & bw_b4 & ~cen_) mem4[addr_b] = {IOP[4], IO[31:24]}; +end + +endmodule diff --git a/fpga/usrp2/top/Makefile.common b/fpga/usrp2/top/Makefile.common index 4da64ac28..9a180d10e 100644 --- a/fpga/usrp2/top/Makefile.common +++ b/fpga/usrp2/top/Makefile.common @@ -31,6 +31,7 @@ synth: $(ISE_FILE) $(ISE_HELPER) "Synthesize - XST" bin: $(BIN_FILE) + $(ISE_HELPER) "Generate Programming File" mcs: $(MCS_FILE) diff --git a/fpga/usrp2/top/u2_rev3/Makefile.udp b/fpga/usrp2/top/u2_rev3/Makefile.udp index 9962887d4..99effb038 100644 --- a/fpga/usrp2/top/u2_rev3/Makefile.udp +++ b/fpga/usrp2/top/u2_rev3/Makefile.udp @@ -24,6 +24,8 @@ include ../../vrt/Makefile.srcs include ../../udp/Makefile.srcs include ../../coregen/Makefile.srcs include ../../extram/Makefile.srcs +include ../../extramfifo/Makefile.srcs + ################################################## # Project Properties diff --git a/fpga/usrp2/top/u2_rev3/u2_core.v b/fpga/usrp2/top/u2_rev3/u2_core.v index 9ba3cc136..a5963f6b1 100755 --- a/fpga/usrp2/top/u2_rev3/u2_core.v +++ b/fpga/usrp2/top/u2_rev3/u2_core.v @@ -123,7 +123,7 @@ module u2_core output [18:0] RAM_A, output RAM_CE1n, output RAM_CENn, - output RAM_CLK, + // output RAM_CLK, output RAM_WEn, output RAM_OEn, output RAM_LDn, diff --git a/fpga/usrp2/top/u2_rev3/u2_core_udp.v b/fpga/usrp2/top/u2_rev3/u2_core_udp.v index c9502898b..b47e7e311 100644 --- a/fpga/usrp2/top/u2_rev3/u2_core_udp.v +++ b/fpga/usrp2/top/u2_rev3/u2_core_udp.v @@ -119,11 +119,13 @@ module u2_core inout [15:0] io_rx, // External RAM - inout [17:0] RAM_D, + input [17:0] RAM_D_pi, + output [17:0] RAM_D_po, + output RAM_D_poe, output [18:0] RAM_A, output RAM_CE1n, output RAM_CENn, - output RAM_CLK, + // output RAM_CLK, output RAM_WEn, output RAM_OEn, output RAM_LDn, @@ -169,7 +171,7 @@ module u2_core wire [31:0] atr_lines; wire [31:0] debug_rx, debug_mac, debug_mac0, debug_mac1, debug_tx_dsp, debug_txc, - debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp; + debug_serdes0, debug_serdes1, debug_serdes2, debug_rx_dsp, debug_udp, debug_extfifo, debug_extfifo2; wire [15:0] ser_rx_occ, ser_tx_occ, dsp_rx_occ, dsp_tx_occ, eth_rx_occ, eth_tx_occ, eth_rx_occ2; wire ser_rx_full, ser_tx_full, dsp_rx_full, dsp_tx_full, eth_rx_full, eth_tx_full, eth_rx_full2; @@ -412,7 +414,7 @@ module u2_core .cyc_i(s4_cyc),.stb_i(s4_stb),.adr_i(s4_adr[3:0]),.we_i(s4_we), .dat_i(s4_dat_o),.dat_o(s4_dat_i),.ack_o(s4_ack), .atr(atr_lines),.debug_0(debug_gpio_0),.debug_1(debug_gpio_1), - .gpio( {io_tx,io_rx} ) ); + .gpio({io_tx,io_rx}) ); // ///////////////////////////////////////////////////////////////////////// // Buffer Pool Status -- Slave #5 @@ -425,7 +427,7 @@ module u2_core cycle_count <= cycle_count + 1; //compatibility number -> increment when the fpga has been sufficiently altered - localparam compat_num = 32'd2; + localparam compat_num = 32'd3; wb_readback_mux buff_pool_status (.wb_clk_i(wb_clk), .wb_rst_i(wb_rst), .wb_stb_i(s5_stb), @@ -539,10 +541,17 @@ module u2_core // ///////////////////////////////////////////////////////////////////////// // Interrupt Controller, Slave #8 + // Pass interrupts on dsp_clk to wb_clk. These need edge triggering in the pic + wire underrun_wb, overrun_wb, pps_wb; + + oneshot_2clk underrun_1s (.clk_in(dsp_clk), .in(underrun), .clk_out(wb_clk), .out(underrun_wb)); + oneshot_2clk overrun_1s (.clk_in(dsp_clk), .in(overrun), .clk_out(wb_clk), .out(overrun_wb)); + oneshot_2clk pps_1s (.clk_in(dsp_clk), .in(pps_int), .clk_out(wb_clk), .out(pps_wb)); + assign irq= {{8'b0}, {8'b0}, {3'b0, periodic_int, clk_status, serdes_link_up, uart_tx_int, uart_rx_int}, - {pps_int,overrun,underrun,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}}; + {pps_wb,overrun_wb,underrun_wb,PHY_INTn,i2c_int,spi_int,onetime_int,buffer_int}}; pic pic(.clk_i(wb_clk),.rst_i(wb_rst),.cyc_i(s8_cyc),.stb_i(s8_stb),.adr_i(s8_adr[4:2]), .we_i(s8_we),.dat_i(s8_dat_o),.dat_o(s8_dat_i),.ack_o(s8_ack),.int_o(proc_int), @@ -653,14 +662,47 @@ module u2_core wire [35:0] tx_data; wire tx_src_rdy, tx_dst_rdy; wire [31:0] debug_vt; + + // FIFO cascade draws from buffer pool, feeds vita tx deframer +/* -----\/----- EXCLUDED -----\/----- fifo_cascade #(.WIDTH(36), .SIZE(DSP_TX_FIFOSIZE)) tx_fifo_cascade (.clk(dsp_clk), .reset(dsp_rst), .clear(0), .datain({rd1_flags,rd1_dat}), .src_rdy_i(rd1_ready_o), .dst_rdy_o(rd1_ready_i), .dataout(tx_data), .src_rdy_o(tx_src_rdy), .dst_rdy_i(tx_dst_rdy) ); + -----/\----- EXCLUDED -----/\----- */ + + ext_fifo #(.EXT_WIDTH(18),.INT_WIDTH(36),.RAM_DEPTH(19),.FIFO_DEPTH(19)) + ext_fifo_i1 + ( + .int_clk(dsp_clk), + .ext_clk(clk_to_mac), +// .ext_clk(wb_clk), + .rst(dsp_rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), +// .datain({rd1_flags,rd1_dat}), + .datain({rd1_flags[3:2],rd1_dat[31:16],rd1_flags[1:0],rd1_dat[15:0]}), + .src_rdy_i(rd1_ready_o), // WRITE + .dst_rdy_o(rd1_ready_i), // not FULL +// .dataout(tx_data), + .dataout({tx_data[35:34],tx_data[31:16],tx_data[33:32],tx_data[15:0]}), + .src_rdy_o(tx_src_rdy), // not EMPTY + .dst_rdy_i(tx_dst_rdy), + .debug(debug_extfifo), + .debug2(debug_extfifo2) + ); vita_tx_chain #(.BASE_CTRL(SR_TX_CTRL), .BASE_DSP(SR_TX_DSP), - .REPORT_ERROR(1), .PROT_ENG_FLAGS(1)) + .REPORT_ERROR(1), .DO_FLOW_CONTROL(1), + .PROT_ENG_FLAGS(1), .USE_TRANS_HEADER(1)) vita_tx_chain (.clk(dsp_clk), .reset(dsp_rst), .set_stb(set_stb_dsp),.set_addr(set_addr_dsp),.set_data(set_data_dsp), @@ -719,7 +761,30 @@ module u2_core assign RAM_CE1n = 0; assign RAM_D[17:16] = 2'bzz; - */ +/* -----\/----- EXCLUDED -----\/----- + *-/ + + test_sram_if test_sram_if_i1 + ( + // .clk(wb_clk), + .clk(clk_to_mac), + .rst(wb_rst), + .RAM_D_pi(RAM_D_pi), + .RAM_D_po(RAM_D_po), + .RAM_D_poe(RAM_D_poe), + .RAM_A(RAM_A), + .RAM_WEn(RAM_WEn), + .RAM_CENn(RAM_CENn), + .RAM_LDn(RAM_LDn), + .RAM_OEn(RAM_OEn), + .RAM_CE1n(RAM_CE1n), + .correct() + ); + -----/\----- EXCLUDED -----/\----- */ + + //assign RAM_CLK = wb_clk; + //assign RAM_CLK = clk_to_mac; + // ///////////////////////////////////////////////////////////////////////// // VITA Timing @@ -731,8 +796,8 @@ module u2_core // ///////////////////////////////////////////////////////////////////////////////////////// // Debug Pins - assign debug_clk = 2'b00; - assign debug = 32'd0; + assign debug_clk = 2'b00; // {dsp_clk, clk_to_mac}; + assign debug = 32'd0; // debug_extfifo; assign debug_gpio_0 = 32'd0; assign debug_gpio_1 = 32'd0; diff --git a/fpga/usrp2/top/u2_rev3/u2_rev3.ucf b/fpga/usrp2/top/u2_rev3/u2_rev3.ucf index 6aa699d2a..deaeecb53 100644 --- a/fpga/usrp2/top/u2_rev3/u2_rev3.ucf +++ b/fpga/usrp2/top/u2_rev3/u2_rev3.ucf @@ -74,49 +74,49 @@ NET "MDC" LOC = "V18" ; NET "PHY_INTn" LOC = "AB13" ; NET "PHY_RESETn" LOC = "AA19" ; NET "PHY_CLK" LOC = "V15" ; -NET "RAM_D[0]" LOC = "N20" ; -NET "RAM_D[1]" LOC = "N21" ; -NET "RAM_D[2]" LOC = "N22" ; -NET "RAM_D[3]" LOC = "M17" ; -NET "RAM_D[4]" LOC = "M18" ; -NET "RAM_D[5]" LOC = "M19" ; -NET "RAM_D[6]" LOC = "M20" ; -NET "RAM_D[7]" LOC = "M21" ; -NET "RAM_D[8]" LOC = "M22" ; -NET "RAM_D[9]" LOC = "Y22" ; -NET "RAM_D[10]" LOC = "Y21" ; -NET "RAM_D[11]" LOC = "Y20" ; -NET "RAM_D[12]" LOC = "Y19" ; -NET "RAM_D[13]" LOC = "W22" ; -NET "RAM_D[14]" LOC = "W21" ; -NET "RAM_D[15]" LOC = "W20" ; -NET "RAM_D[16]" LOC = "W19" ; -NET "RAM_D[17]" LOC = "V22" ; -NET "RAM_A[0]" LOC = "U21" ; -NET "RAM_A[1]" LOC = "T19" ; -NET "RAM_A[2]" LOC = "V21" ; -NET "RAM_A[3]" LOC = "V20" ; -NET "RAM_A[4]" LOC = "T20" ; -NET "RAM_A[5]" LOC = "T21" ; -NET "RAM_A[6]" LOC = "T22" ; -NET "RAM_A[7]" LOC = "T18" ; -NET "RAM_A[8]" LOC = "R18" ; -NET "RAM_A[9]" LOC = "P19" ; -NET "RAM_A[10]" LOC = "P21" ; -NET "RAM_A[11]" LOC = "P22" ; -NET "RAM_A[12]" LOC = "N19" ; -NET "RAM_A[13]" LOC = "N17" ; -NET "RAM_A[14]" LOC = "N18" ; -NET "RAM_A[15]" LOC = "T17" ; -NET "RAM_A[16]" LOC = "U19" ; -NET "RAM_A[17]" LOC = "U18" ; -NET "RAM_A[18]" LOC = "V19" ; -NET "RAM_CE1n" LOC = "U20" ; -NET "RAM_CENn" LOC = "P18" ; -NET "RAM_CLK" LOC = "P17" ; -NET "RAM_WEn" LOC = "R22" ; -NET "RAM_OEn" LOC = "R21" ; -NET "RAM_LDn" LOC = "R19" ; +NET "RAM_D[0]" LOC = "N20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[1]" LOC = "N21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[2]" LOC = "N22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[3]" LOC = "M17" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[4]" LOC = "M18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[5]" LOC = "M19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[6]" LOC = "M20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[7]" LOC = "M21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[8]" LOC = "M22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[9]" LOC = "Y22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[10]" LOC = "Y21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[11]" LOC = "Y20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[12]" LOC = "Y19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[13]" LOC = "W22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[14]" LOC = "W21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[15]" LOC = "W20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[16]" LOC = "W19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_D[17]" LOC = "V22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[0]" LOC = "U21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[1]" LOC = "T19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[2]" LOC = "V21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[3]" LOC = "V20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[4]" LOC = "T20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[5]" LOC = "T21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[6]" LOC = "T22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[7]" LOC = "T18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[8]" LOC = "R18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[9]" LOC = "P19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[10]" LOC = "P21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[11]" LOC = "P22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[12]" LOC = "N19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[13]" LOC = "N17" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[14]" LOC = "N18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[15]" LOC = "T17" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[16]" LOC = "U19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[17]" LOC = "U18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_A[18]" LOC = "V19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_CE1n" LOC = "U20" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_CENn" LOC = "P18" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_CLK" LOC = "P17" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_WEn" LOC = "R22" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_OEn" LOC = "R21" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; +NET "RAM_LDn" LOC = "R19" |IOSTANDARD = LVCMOS25 |DRIVE = 8 |SLEW = SLOW ; NET "ser_enable" LOC = "W11" ; NET "ser_prbsen" LOC = "AA3" ; NET "ser_loopen" LOC = "Y4" ; @@ -264,22 +264,22 @@ NET "sdi_tx_adc" LOC = "J4" ; NET "sen_tx_dac" LOC = "H4" ; NET "sclk_tx_dac" LOC = "J5" ; NET "sdi_tx_dac" LOC = "J6" ; -NET "io_tx[0]" LOC = "K4" ; -NET "io_tx[1]" LOC = "K3" ; -NET "io_tx[2]" LOC = "G1" ; -NET "io_tx[3]" LOC = "G5" ; -NET "io_tx[4]" LOC = "H5" ; -NET "io_tx[5]" LOC = "F3" ; -NET "io_tx[6]" LOC = "F2" ; -NET "io_tx[7]" LOC = "F5" ; -NET "io_tx[8]" LOC = "G6" ; -NET "io_tx[9]" LOC = "E2" ; -NET "io_tx[10]" LOC = "E1" ; -NET "io_tx[11]" LOC = "E3" ; -NET "io_tx[12]" LOC = "F4" ; -NET "io_tx[13]" LOC = "D2" ; -NET "io_tx[14]" LOC = "D4" ; -NET "io_tx[15]" LOC = "E4" ; +NET "io_tx[0]" LOC = "K4" ; +NET "io_tx[1]" LOC = "K3" ; +NET "io_tx[2]" LOC = "G1" ; +NET "io_tx[3]" LOC = "G5" ; +NET "io_tx[4]" LOC = "H5" ; +NET "io_tx[5]" LOC = "F3" ; +NET "io_tx[6]" LOC = "F2" ; +NET "io_tx[7]" LOC = "F5" ; +NET "io_tx[8]" LOC = "G6" ; +NET "io_tx[9]" LOC = "E2" ; +NET "io_tx[10]" LOC = "E1" ; +NET "io_tx[11]" LOC = "E3" ; +NET "io_tx[12]" LOC = "F4" ; +NET "io_tx[13]" LOC = "D2" ; +NET "io_tx[14]" LOC = "D4" ; +NET "io_tx[15]" LOC = "E4" ; NET "sen_rx_db" LOC = "D22" ; NET "sclk_rx_db" LOC = "F19" ; NET "sdo_rx_db" LOC = "G20" ; @@ -291,22 +291,22 @@ NET "sdi_rx_adc" LOC = "H22" ; NET "sen_rx_dac" LOC = "J18" ; NET "sclk_rx_dac" LOC = "J19" ; NET "sdi_rx_dac" LOC = "J21" ; -NET "io_rx[0]" LOC = "L21" ; -NET "io_rx[1]" LOC = "L20" ; -NET "io_rx[2]" LOC = "L19" ; -NET "io_rx[3]" LOC = "L18" ; -NET "io_rx[4]" LOC = "L17" ; -NET "io_rx[5]" LOC = "K22" ; -NET "io_rx[6]" LOC = "K21" ; -NET "io_rx[7]" LOC = "K20" ; -NET "io_rx[8]" LOC = "G22" ; -NET "io_rx[9]" LOC = "G21" ; -NET "io_rx[10]" LOC = "F21" ; -NET "io_rx[11]" LOC = "F20" ; -NET "io_rx[12]" LOC = "G19" ; -NET "io_rx[13]" LOC = "G18" ; -NET "io_rx[14]" LOC = "G17" ; -NET "io_rx[15]" LOC = "E22" ; +NET "io_rx[0]" LOC = "L21" ; +NET "io_rx[1]" LOC = "L20" ; +NET "io_rx[2]" LOC = "L19" ; +NET "io_rx[3]" LOC = "L18" ; +NET "io_rx[4]" LOC = "L17" ; +NET "io_rx[5]" LOC = "K22" ; +NET "io_rx[6]" LOC = "K21" ; +NET "io_rx[7]" LOC = "K20" ; +NET "io_rx[8]" LOC = "G22" ; +NET "io_rx[9]" LOC = "G21" ; +NET "io_rx[10]" LOC = "F21" ; +NET "io_rx[11]" LOC = "F20" ; +NET "io_rx[12]" LOC = "G19" ; +NET "io_rx[13]" LOC = "G18" ; +NET "io_rx[14]" LOC = "G17" ; +NET "io_rx[15]" LOC = "E22" ; NET "clk_to_mac" TNM_NET = "clk_to_mac"; TIMESPEC "TS_clk_to_mac" = PERIOD "clk_to_mac" 8 ns HIGH 50 %; @@ -324,6 +324,7 @@ NET "ser_rx_clk" TNM_NET = "ser_rx_clk"; TIMESPEC "TS_ser_rx_clk" = PERIOD "ser_rx_clk" 10 ns HIGH 50 %; NET "cpld_clk" CLOCK_DEDICATED_ROUTE = FALSE; +NET "GMII_RX_CLK" CLOCK_DEDICATED_ROUTE = FALSE; #NET "adc_a<*>" TNM_NET = ADC_DATA_GRP; #NET "adc_b<*>" TNM_NET = ADC_DATA_GRP; diff --git a/fpga/usrp2/top/u2_rev3/u2_rev3.v b/fpga/usrp2/top/u2_rev3/u2_rev3.v index 4daa66212..4f7f9bf1a 100644 --- a/fpga/usrp2/top/u2_rev3/u2_rev3.v +++ b/fpga/usrp2/top/u2_rev3/u2_rev3.v @@ -330,8 +330,8 @@ module u2_rev3 wire [15:0] dac_a_int, dac_b_int; // DAC A and B are swapped in schematic to facilitate clean layout // DAC A is also inverted in schematic to facilitate clean layout - always @(negedge dsp_clk) dac_a <= ~dac_b_int; - always @(negedge dsp_clk) dac_b <= dac_a_int; + always @(posedge dsp_clk) dac_a <= ~dac_b_int; + always @(posedge dsp_clk) dac_b <= dac_a_int; /* OFDDRRSE OFDDRRSE_serdes_inst @@ -345,100 +345,228 @@ module u2_rev3 .S(0) // Synchronous preset input ); */ + + wire [17:0] RAM_D_pi; + wire [17:0] RAM_D_po; + wire RAM_D_poe; + + genvar i; + + // + // Instantiate IO for Bidirectional bus to SRAM + // + + generate + for (i=0;i<18;i=i+1) + begin : gen_RAM_D_IO + + IOBUF #( + .DRIVE(12), + .IOSTANDARD("LVCMOS25"), + .SLEW("FAST") + ) + RAM_D_i ( + .O(RAM_D_pi[i]), + .I(RAM_D_po[i]), + .IO(RAM_D[i]), + .T(RAM_D_poe) + ); + end // block: gen_RAM_D_IO + endgenerate + + // + // DCM edits start here + // + + + wire RAM_CLK_buf; + wire clk_to_mac_buf; + wire clk125_ext_clk0; + wire clk125_ext_clk180; + wire clk125_ext_clk0_buf; + wire clk125_ext_clk180_buf; + wire clk125_int_buf; + wire clk125_int; + + IBUFG clk_to_mac_buf_i1 (.I(clk_to_mac), + .O(clk_to_mac_buf)); + + DCM DCM_INST1 (.CLKFB(RAM_CLK_buf), + .CLKIN(clk_to_mac_buf), + .DSSEN(1'b0), + .PSCLK(1'b0), + .PSEN(1'b0), + .PSINCDEC(1'b0), + .RST(1'b0), + .CLK0(clk125_ext_clk0), + .CLK180(clk125_ext_clk180) ); + defparam DCM_INST1.CLK_FEEDBACK = "1X"; + defparam DCM_INST1.CLKDV_DIVIDE = 2.0; + defparam DCM_INST1.CLKFX_DIVIDE = 1; + defparam DCM_INST1.CLKFX_MULTIPLY = 4; + defparam DCM_INST1.CLKIN_DIVIDE_BY_2 = "FALSE"; + defparam DCM_INST1.CLKIN_PERIOD = 8.000; + defparam DCM_INST1.CLKOUT_PHASE_SHIFT = "FIXED"; + defparam DCM_INST1.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; + defparam DCM_INST1.DFS_FREQUENCY_MODE = "LOW"; + defparam DCM_INST1.DLL_FREQUENCY_MODE = "LOW"; + defparam DCM_INST1.DUTY_CYCLE_CORRECTION = "TRUE"; + defparam DCM_INST1.FACTORY_JF = 16'h8080; + defparam DCM_INST1.PHASE_SHIFT = -64; + defparam DCM_INST1.STARTUP_WAIT = "FALSE"; + + IBUFG RAM_CLK_buf_i1 (.I(RAM_CLK), + .O(RAM_CLK_buf)); + BUFG clk125_ext_clk0_buf_i1 (.I(clk125_ext_clk0), + .O(clk125_ext_clk0_buf)); + BUFG clk125_ext_clk180_buf_i1 (.I(clk125_ext_clk180), + .O(clk125_ext_clk180_buf)); + + OFDDRRSE RAM_CLK_i1 (.Q(RAM_CLK), + .C0(clk125_ext_clk0_buf), + .C1(clk125_ext_clk180_buf), + .CE(1'b1), + .D0(1'b1), + .D1(1'b0), + .R(1'b0), + .S(1'b0)); + +// SRL16 dcm2_rst_i1 (.D(1'b0), +// .CLK(clk_to_mac_buf), +// .Q(dcm2_rst), +// .A0(1'b1), +// .A1(1'b1), +// .A2(1'b1), +// .A3(1'b1)); + // synthesis attribute init of dcm2_rst_i1 is "000F"; + + DCM DCM_INST2 (.CLKFB(clk125_int_buf), + .CLKIN(clk_to_mac_buf), + .DSSEN(1'b0), + .PSCLK(1'b0), + .PSEN(1'b0), + .PSINCDEC(1'b0), + .RST(1'b0), + .CLK0(clk125_int)); + defparam DCM_INST2.CLK_FEEDBACK = "1X"; + defparam DCM_INST2.CLKDV_DIVIDE = 2.0; + defparam DCM_INST2.CLKFX_DIVIDE = 1; + defparam DCM_INST2.CLKFX_MULTIPLY = 4; + defparam DCM_INST2.CLKIN_DIVIDE_BY_2 = "FALSE"; + defparam DCM_INST2.CLKIN_PERIOD = 8.000; + defparam DCM_INST2.CLKOUT_PHASE_SHIFT = "NONE"; + defparam DCM_INST2.DESKEW_ADJUST = "SYSTEM_SYNCHRONOUS"; + defparam DCM_INST2.DFS_FREQUENCY_MODE = "LOW"; + defparam DCM_INST2.DLL_FREQUENCY_MODE = "LOW"; + defparam DCM_INST2.DUTY_CYCLE_CORRECTION = "TRUE"; + defparam DCM_INST2.FACTORY_JF = 16'h8080; + defparam DCM_INST2.PHASE_SHIFT = 0; + defparam DCM_INST2.STARTUP_WAIT = "FALSE"; + + BUFG clk125_int_buf_i1 (.I(clk125_int), + .O(clk125_int_buf)); + + // + // DCM edits end here + // + + u2_core #(.RAM_SIZE(32768)) - u2_core(.dsp_clk (dsp_clk), - .wb_clk (wb_clk), - .clock_ready (clock_ready), - .clk_to_mac (clk_to_mac), - .pps_in (pps_in), - .leds (leds_int), - .debug (debug[31:0]), - .debug_clk (debug_clk[1:0]), - .exp_pps_in (exp_pps_in), - .exp_pps_out (exp_pps_out), - .GMII_COL (GMII_COL), - .GMII_CRS (GMII_CRS), - .GMII_TXD (GMII_TXD_unreg[7:0]), - .GMII_TX_EN (GMII_TX_EN_unreg), - .GMII_TX_ER (GMII_TX_ER_unreg), - .GMII_GTX_CLK (GMII_GTX_CLK_int), - .GMII_TX_CLK (GMII_TX_CLK), - .GMII_RXD (GMII_RXD[7:0]), - .GMII_RX_CLK (GMII_RX_CLK), - .GMII_RX_DV (GMII_RX_DV), - .GMII_RX_ER (GMII_RX_ER), - .MDIO (MDIO), - .MDC (MDC), - .PHY_INTn (PHY_INTn), - .PHY_RESETn (PHY_RESETn), - .ser_enable (ser_enable), - .ser_prbsen (ser_prbsen), - .ser_loopen (ser_loopen), - .ser_rx_en (ser_rx_en), - .ser_tx_clk (ser_tx_clk_int), - .ser_t (ser_t_unreg[15:0]), - .ser_tklsb (ser_tklsb_unreg), - .ser_tkmsb (ser_tkmsb_unreg), - .ser_rx_clk (ser_rx_clk_buf), - .ser_r (ser_r_int[15:0]), - .ser_rklsb (ser_rklsb_int), - .ser_rkmsb (ser_rkmsb_int), - .cpld_start (cpld_start), - .cpld_mode (cpld_mode), - .cpld_done (cpld_done), - .cpld_din (cpld_din), - .cpld_clk (cpld_clk), - .cpld_detached (cpld_detached), - .cpld_misc (cpld_misc), - .cpld_init_b (cpld_init_b), - .por (~POR), - .config_success (config_success), - .adc_a (adc_a_reg2), - .adc_ovf_a (adc_ovf_a_reg2), - .adc_on_a (adc_on_a), - .adc_oe_a (adc_oe_a), - .adc_b (adc_b_reg2), - .adc_ovf_b (adc_ovf_b_reg2), - .adc_on_b (adc_on_b), - .adc_oe_b (adc_oe_b), - .dac_a (dac_a_int), - .dac_b (dac_b_int), - .scl_pad_i (scl_pad_i), - .scl_pad_o (scl_pad_o), - .scl_pad_oen_o (scl_pad_oen_o), - .sda_pad_i (sda_pad_i), - .sda_pad_o (sda_pad_o), - .sda_pad_oen_o (sda_pad_oen_o), - .clk_en (clk_en[1:0]), - .clk_sel (clk_sel[1:0]), - .clk_func (clk_func), - .clk_status (clk_status), - .sclk (sclk_int), - .mosi (mosi), - .miso (miso), - .sen_clk (sen_clk), - .sen_dac (sen_dac), - .sen_tx_db (sen_tx_db), - .sen_tx_adc (sen_tx_adc), - .sen_tx_dac (sen_tx_dac), - .sen_rx_db (sen_rx_db), - .sen_rx_adc (sen_rx_adc), - .sen_rx_dac (sen_rx_dac), - .io_tx (io_tx[15:0]), - .io_rx (io_rx[15:0]), - .RAM_D (RAM_D), - .RAM_A (RAM_A), - .RAM_CE1n (RAM_CE1n), - .RAM_CENn (RAM_CENn), - .RAM_CLK (RAM_CLK), - .RAM_WEn (RAM_WEn), - .RAM_OEn (RAM_OEn), - .RAM_LDn (RAM_LDn), - .uart_tx_o (uart_tx_o), - .uart_rx_i (uart_rx_i), - .uart_baud_o (), - .sim_mode (1'b0), - .clock_divider (2) - ); + u2_core(.dsp_clk (dsp_clk), + .wb_clk (wb_clk), + .clock_ready (clock_ready), + .clk_to_mac (clk125_int_buf), + .pps_in (pps_in), + .leds (leds_int), + .debug (debug[31:0]), + .debug_clk (debug_clk[1:0]), + .exp_pps_in (exp_pps_in), + .exp_pps_out (exp_pps_out), + .GMII_COL (GMII_COL), + .GMII_CRS (GMII_CRS), + .GMII_TXD (GMII_TXD_unreg[7:0]), + .GMII_TX_EN (GMII_TX_EN_unreg), + .GMII_TX_ER (GMII_TX_ER_unreg), + .GMII_GTX_CLK (GMII_GTX_CLK_int), + .GMII_TX_CLK (GMII_TX_CLK), + .GMII_RXD (GMII_RXD[7:0]), + .GMII_RX_CLK (GMII_RX_CLK), + .GMII_RX_DV (GMII_RX_DV), + .GMII_RX_ER (GMII_RX_ER), + .MDIO (MDIO), + .MDC (MDC), + .PHY_INTn (PHY_INTn), + .PHY_RESETn (PHY_RESETn), + .ser_enable (ser_enable), + .ser_prbsen (ser_prbsen), + .ser_loopen (ser_loopen), + .ser_rx_en (ser_rx_en), + .ser_tx_clk (ser_tx_clk_int), + .ser_t (ser_t_unreg[15:0]), + .ser_tklsb (ser_tklsb_unreg), + .ser_tkmsb (ser_tkmsb_unreg), + .ser_rx_clk (ser_rx_clk_buf), + .ser_r (ser_r_int[15:0]), + .ser_rklsb (ser_rklsb_int), + .ser_rkmsb (ser_rkmsb_int), + .cpld_start (cpld_start), + .cpld_mode (cpld_mode), + .cpld_done (cpld_done), + .cpld_din (cpld_din), + .cpld_clk (cpld_clk), + .cpld_detached (cpld_detached), + .cpld_misc (cpld_misc), + .cpld_init_b (cpld_init_b), + .por (~POR), + .config_success (config_success), + .adc_a (adc_a_reg2), + .adc_ovf_a (adc_ovf_a_reg2), + .adc_on_a (adc_on_a), + .adc_oe_a (adc_oe_a), + .adc_b (adc_b_reg2), + .adc_ovf_b (adc_ovf_b_reg2), + .adc_on_b (adc_on_b), + .adc_oe_b (adc_oe_b), + .dac_a (dac_a_int), + .dac_b (dac_b_int), + .scl_pad_i (scl_pad_i), + .scl_pad_o (scl_pad_o), + .scl_pad_oen_o (scl_pad_oen_o), + .sda_pad_i (sda_pad_i), + .sda_pad_o (sda_pad_o), + .sda_pad_oen_o (sda_pad_oen_o), + .clk_en (clk_en[1:0]), + .clk_sel (clk_sel[1:0]), + .clk_func (clk_func), + .clk_status (clk_status), + .sclk (sclk_int), + .mosi (mosi), + .miso (miso), + .sen_clk (sen_clk), + .sen_dac (sen_dac), + .sen_tx_db (sen_tx_db), + .sen_tx_adc (sen_tx_adc), + .sen_tx_dac (sen_tx_dac), + .sen_rx_db (sen_rx_db), + .sen_rx_adc (sen_rx_adc), + .sen_rx_dac (sen_rx_dac), + .io_tx (io_tx[15:0]), + .io_rx (io_rx[15:0]), + .RAM_D_pi (RAM_D_pi), + .RAM_D_po (RAM_D_po), + .RAM_D_poe (RAM_D_poe), + .RAM_A (RAM_A), + .RAM_CE1n (RAM_CE1n), + .RAM_CENn (RAM_CENn), + // .RAM_CLK (RAM_CLK), + .RAM_WEn (RAM_WEn), + .RAM_OEn (RAM_OEn), + .RAM_LDn (RAM_LDn), + .uart_tx_o (uart_tx_o), + .uart_rx_i (uart_rx_i), + .uart_baud_o (), + .sim_mode (1'b0), + .clock_divider (2) + ); endmodule // u2_rev2 diff --git a/fpga/usrp2/vrt/Makefile.srcs b/fpga/usrp2/vrt/Makefile.srcs index dc4bd8c96..aa1356d82 100644 --- a/fpga/usrp2/vrt/Makefile.srcs +++ b/fpga/usrp2/vrt/Makefile.srcs @@ -12,4 +12,5 @@ vita_tx_control.v \ vita_tx_deframer.v \ vita_tx_chain.v \ gen_context_pkt.v \ +trigger_context_pkt.v \ )) diff --git a/fpga/usrp2/vrt/gen_context_pkt.v b/fpga/usrp2/vrt/gen_context_pkt.v index 780a027ba..0eb035f3e 100644 --- a/fpga/usrp2/vrt/gen_context_pkt.v +++ b/fpga/usrp2/vrt/gen_context_pkt.v @@ -7,6 +7,8 @@ module gen_context_pkt input [31:0] streamid, input [63:0] vita_time, input [31:0] message, + input [31:0] seqnum0, + input [31:0] seqnum1, output [35:0] data_o, output src_rdy_o, input dst_rdy_i); localparam CTXT_IDLE = 0; @@ -17,17 +19,32 @@ module gen_context_pkt localparam CTXT_TICS = 5; localparam CTXT_TICS2 = 6; localparam CTXT_MESSAGE = 7; - localparam CTXT_DONE = 8; + localparam CTXT_FLOWCTRL0 = 8; + localparam CTXT_FLOWCTRL1 = 9; + localparam CTXT_DONE = 10; reg [33:0] data_int; wire src_rdy_int, dst_rdy_int; - wire [3:0] seqno = 0; + reg [3:0] seqno; reg [3:0] ctxt_state; reg [63:0] err_time; + reg [31:0] stored_message; always @(posedge clk) if(reset | clear) - ctxt_state <= CTXT_IDLE; + stored_message <= 0; + else + if(trigger) + stored_message <= message; + else if(ctxt_state == CTXT_FLOWCTRL1) + stored_message <= 0; + + always @(posedge clk) + if(reset | clear) + begin + ctxt_state <= CTXT_IDLE; + seqno <= 0; + end else case(ctxt_state) CTXT_IDLE : @@ -41,9 +58,10 @@ module gen_context_pkt end CTXT_DONE : - if(~trigger) - ctxt_state <= CTXT_IDLE; - + begin + ctxt_state <= CTXT_IDLE; + seqno <= seqno + 4'd1; + end default : if(dst_rdy_int) ctxt_state <= ctxt_state + 1; @@ -53,13 +71,15 @@ module gen_context_pkt always @* case(ctxt_state) - CTXT_PROT_ENG : data_int <= { 2'b01, 16'd1, 16'd24 }; - CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd6 }; + CTXT_PROT_ENG : data_int <= { 2'b01, 16'd1, 16'd32 }; + CTXT_HEADER : data_int <= { 1'b0, (PROT_ENG_FLAGS ? 1'b0 : 1'b1), 12'b010100001101, seqno, 16'd8 }; CTXT_STREAMID : data_int <= { 2'b00, streamid }; CTXT_SECS : data_int <= { 2'b00, err_time[63:32] }; CTXT_TICS : data_int <= { 2'b00, 32'd0 }; CTXT_TICS2 : data_int <= { 2'b00, err_time[31:0] }; - CTXT_MESSAGE : data_int <= { 2'b10, message }; + CTXT_MESSAGE : data_int <= { 2'b00, message }; + CTXT_FLOWCTRL0 : data_int <= { 2'b00, seqnum0 }; + CTXT_FLOWCTRL1 : data_int <= { 2'b10, seqnum1 }; default : data_int <= {2'b00, 32'b00}; endcase // case (ctxt_state) diff --git a/fpga/usrp2/vrt/trigger_context_pkt.v b/fpga/usrp2/vrt/trigger_context_pkt.v new file mode 100644 index 000000000..226ec45f2 --- /dev/null +++ b/fpga/usrp2/vrt/trigger_context_pkt.v @@ -0,0 +1,52 @@ + + +module trigger_context_pkt + #(parameter BASE=0) + (input clk, input reset, input clear, + input set_stb, input [7:0] set_addr, input [31:0] set_data, + input packet_consumed, output reg trigger); + + wire [23:0] cycles; + wire [15:0] packets; + wire [6:0] dummy1; + wire [14:0] dummy2; + wire enable_timed, enable_consumed; + reg [30:0] cycle_count, packet_count; + + + setting_reg #(.my_addr(BASE+4), .at_reset(0)) sr_cycles + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out({enable_cycle,dummy1,cycles}),.changed()); + + setting_reg #(.my_addr(BASE+5), .at_reset(0)) sr_packets + (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), + .in(set_data),.out({enable_consumed,dummy2,packets}),.changed()); + + always @(posedge clk) + if(reset | clear) + cycle_count <= 0; + else + if(trigger) + cycle_count <= 0; + else if(enable_cycle) + cycle_count <= cycle_count + 1; + + always @(posedge clk) + if(reset | clear) + packet_count <= 0; + else + if(trigger) + packet_count <= 0; + else if(packet_consumed & enable_consumed) + packet_count <= packet_count + 1; + + always @(posedge clk) + if(reset | clear) + trigger <= 0; + else + if((cycle_count > cycles)|(packet_count > packets)) + trigger <= 1; + else + trigger <= 0; + +endmodule // trigger_context_pkt diff --git a/fpga/usrp2/vrt/vita_tx_chain.v b/fpga/usrp2/vrt/vita_tx_chain.v index 662cdca62..00da4c6e1 100644 --- a/fpga/usrp2/vrt/vita_tx_chain.v +++ b/fpga/usrp2/vrt/vita_tx_chain.v @@ -3,7 +3,9 @@ module vita_tx_chain #(parameter BASE_CTRL=0, parameter BASE_DSP=0, parameter REPORT_ERROR=0, - parameter PROT_ENG_FLAGS=0) + parameter DO_FLOW_CONTROL=0, + parameter PROT_ENG_FLAGS=0, + parameter USE_TRANS_HEADER=0) (input clk, input reset, input set_stb, input [7:0] set_addr, input [31:0] set_data, input [63:0] vita_time, @@ -24,22 +26,27 @@ module vita_tx_chain wire trigger, sent; wire [31:0] debug_vtc, debug_vtd, debug_tx_dsp; - wire error; + wire error, packet_consumed; wire [31:0] error_code; wire clear_seqnum; + wire [31:0] current_seqnum; - assign underrun = error; + assign underrun = error & ~(error_code == 1); assign message = error_code; setting_reg #(.my_addr(BASE_CTRL+2), .at_reset(0)) sr_streamid (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),.out(streamid),.changed(clear_seqnum)); - vita_tx_deframer #(.BASE(BASE_CTRL), .MAXCHAN(MAXCHAN)) vita_tx_deframer + vita_tx_deframer #(.BASE(BASE_CTRL), + .MAXCHAN(MAXCHAN), + .USE_TRANS_HEADER(USE_TRANS_HEADER)) + vita_tx_deframer (.clk(clk), .reset(reset), .clear(clear_vita), .clear_seqnum(clear_seqnum), .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .data_i(tx_data_i), .src_rdy_i(tx_src_rdy_i), .dst_rdy_o(tx_dst_rdy_o), .sample_fifo_o(tx1_data), .sample_fifo_src_rdy_o(tx1_src_rdy), .sample_fifo_dst_rdy_i(tx1_dst_rdy), + .current_seqnum(current_seqnum), .debug(debug_vtd) ); vita_tx_control #(.BASE(BASE_CTRL), .WIDTH(32*MAXCHAN)) vita_tx_control @@ -47,7 +54,7 @@ module vita_tx_chain .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), .vita_time(vita_time),.error(error),.error_code(error_code), .sample_fifo_i(tx1_data), .sample_fifo_src_rdy_i(tx1_src_rdy), .sample_fifo_dst_rdy_o(tx1_dst_rdy), - .sample(sample_tx), .run(run), .strobe(strobe_tx), + .sample(sample_tx), .run(run), .strobe(strobe_tx), .packet_consumed(packet_consumed), .debug(debug_vtc) ); dsp_core_tx #(.BASE(BASE_DSP)) dsp_core_tx @@ -57,15 +64,33 @@ module vita_tx_chain .dac_a(dac_a),.dac_b(dac_b), .debug(debug_tx_dsp) ); - generate - if(REPORT_ERROR==1) - gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) gen_tx_err_pkt - (.clk(clk), .reset(reset), .clear(clear_vita), - .trigger(error), .sent(), - .streamid(streamid), .vita_time(vita_time), .message(message), - .data_o(err_data_o), .src_rdy_o(err_src_rdy_o), .dst_rdy_i(err_dst_rdy_i)); - endgenerate + wire [35:0] flow_data, err_data_int; + wire flow_src_rdy, flow_dst_rdy, err_src_rdy_int, err_dst_rdy_int; + + gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) gen_flow_pkt + (.clk(clk), .reset(reset), .clear(clear_vita), + .trigger(trigger & (DO_FLOW_CONTROL==1)), .sent(), + .streamid(streamid), .vita_time(vita_time), .message(32'd0), + .seqnum0(current_seqnum), .seqnum1(32'd0), + .data_o(flow_data), .src_rdy_o(flow_src_rdy), .dst_rdy_i(flow_dst_rdy)); + trigger_context_pkt #(.BASE(BASE_CTRL)) trigger_context_pkt + (.clk(clk), .reset(reset), .clear(clear_vita), + .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), + .packet_consumed(packet_consumed), .trigger(trigger)); + gen_context_pkt #(.PROT_ENG_FLAGS(PROT_ENG_FLAGS)) gen_tx_err_pkt + (.clk(clk), .reset(reset), .clear(clear_vita), + .trigger(error & (REPORT_ERROR==1)), .sent(), + .streamid(streamid), .vita_time(vita_time), .message(message), + .seqnum0(current_seqnum), .seqnum1(32'd0), + .data_o(err_data_int), .src_rdy_o(err_src_rdy_int), .dst_rdy_i(err_dst_rdy_int)); + assign debug = debug_vtc | debug_vtd; + fifo36_mux #(.prio(1)) mux_err_and_flow // Priority to err messages + (.clk(clk), .reset(reset), .clear(clear_vita), + .data0_i(err_data_int), .src0_rdy_i(err_src_rdy_int), .dst0_rdy_o(err_dst_rdy_int), + .data1_i(flow_data), .src1_rdy_i(flow_src_rdy), .dst1_rdy_o(flow_dst_rdy), + .data_o(err_data_o), .src_rdy_o(err_src_rdy_o), .dst_rdy_i(err_dst_rdy_i)); + endmodule // vita_tx_chain diff --git a/fpga/usrp2/vrt/vita_tx_control.v b/fpga/usrp2/vrt/vita_tx_control.v index d0516bec8..936762212 100644 --- a/fpga/usrp2/vrt/vita_tx_control.v +++ b/fpga/usrp2/vrt/vita_tx_control.v @@ -8,7 +8,8 @@ module vita_tx_control input [63:0] vita_time, output error, output reg [31:0] error_code, - + output reg packet_consumed, + // From vita_tx_deframer input [5+64+16+WIDTH-1:0] sample_fifo_i, input sample_fifo_src_rdy_i, @@ -48,6 +49,7 @@ module vita_tx_control localparam IBS_ERROR_DONE = 4; localparam IBS_ERROR_WAIT = 5; + wire [31:0] CODE_EOB_ACK = {seqnum,16'd1}; wire [31:0] CODE_UNDERRUN = {seqnum,16'd2}; wire [31:0] CODE_SEQ_ERROR = {seqnum,16'd4}; wire [31:0] CODE_TIME_ERROR = {seqnum,16'd8}; @@ -106,7 +108,11 @@ module vita_tx_control end else if(eop) if(eob) - ibs_state <= IBS_IDLE; + begin + ibs_state <= IBS_ERROR_DONE; // Not really an error + error_code <= CODE_EOB_ACK; + send_error <= 1; + end else ibs_state <= IBS_CONT_BURST; @@ -154,9 +160,14 @@ module vita_tx_control assign sample_fifo_dst_rdy_o = (ibs_state == IBS_ERROR) | (strobe & (ibs_state == IBS_RUN)); // FIXME also cleanout assign run = (ibs_state == IBS_RUN) | (ibs_state == IBS_CONT_BURST); - //assign error = (ibs_state == IBS_ERROR_DONE); assign error = send_error; + always @(posedge clk) + if(reset) + packet_consumed <= 0; + else + packet_consumed <= eop & sample_fifo_src_rdy_i & sample_fifo_dst_rdy_o; + assign debug = { { now,early,late,too_early,eop,eob,sob,send_at }, { sample_fifo_src_rdy_i, sample_fifo_dst_rdy_o, strobe, run, error, ibs_state[2:0] }, { 8'b0 }, diff --git a/fpga/usrp2/vrt/vita_tx_deframer.v b/fpga/usrp2/vrt/vita_tx_deframer.v index f9cd7d00d..7fb8e3893 100644 --- a/fpga/usrp2/vrt/vita_tx_deframer.v +++ b/fpga/usrp2/vrt/vita_tx_deframer.v @@ -1,7 +1,8 @@ module vita_tx_deframer #(parameter BASE=0, - parameter MAXCHAN=1) + parameter MAXCHAN=1, + parameter USE_TRANS_HEADER=0) (input clk, input reset, input clear, input clear_seqnum, input set_stb, input [7:0] set_addr, input [31:0] set_data, @@ -13,6 +14,8 @@ module vita_tx_deframer output [5+64+16+(32*MAXCHAN)-1:0] sample_fifo_o, output sample_fifo_src_rdy_o, input sample_fifo_dst_rdy_i, + + output [31:0] current_seqnum, // FIFO Levels output [15:0] fifo_occupied, @@ -45,58 +48,80 @@ module vita_tx_deframer reg [1:0] vector_phase; wire line_done; - reg seqnum_err; - reg [3:0] seqnum_reg; - wire [3:0] seqnum = data_i[19:16]; - wire [3:0] next_seqnum = seqnum_reg + 4'd1; + wire [31:0] seqnum = data_i; + reg [31:0] seqnum_reg; + wire [31:0] next_seqnum = seqnum_reg + 32'd1; + wire [3:0] vita_seqnum = data_i[19:16]; + reg [3:0] vita_seqnum_reg; + wire [3:0] next_vita_seqnum = vita_seqnum_reg[3:0] + 4'd1; + reg seqnum_err; + + assign current_seqnum = seqnum_reg; // Output FIFO for packetized data - localparam VITA_HEADER = 0; - localparam VITA_STREAMID = 1; - localparam VITA_CLASSID = 2; - localparam VITA_CLASSID2 = 3; - localparam VITA_SECS = 4; - localparam VITA_TICS = 5; - localparam VITA_TICS2 = 6; - localparam VITA_PAYLOAD = 7; - localparam VITA_STORE = 8; - localparam VITA_TRAILER = 9; - + localparam VITA_TRANS_HEADER = 0; + localparam VITA_HEADER = 1; + localparam VITA_STREAMID = 2; + localparam VITA_CLASSID = 3; + localparam VITA_CLASSID2 = 4; + localparam VITA_SECS = 5; + localparam VITA_TICS = 6; + localparam VITA_TICS2 = 7; + localparam VITA_PAYLOAD = 8; + localparam VITA_STORE = 9; + localparam VITA_TRAILER = 10; + localparam VITA_DUMP = 11; + wire [15:0] hdr_len = 2 + has_streamid_reg + has_classid_reg + has_classid_reg + has_secs_reg + has_tics_reg + has_tics_reg + has_trailer_reg; - wire eop = eof | (pkt_len==hdr_len); // FIXME would ignoring eof allow larger VITA packets? + wire vita_eof = (pkt_len==hdr_len); + wire eop = eof | vita_eof; // FIXME would ignoring eof allow larger VITA packets? wire fifo_space; always @(posedge clk) if(reset | clear_seqnum) - seqnum_reg <= 4'hF; + begin + seqnum_reg <= 32'hFFFF_FFFF; + vita_seqnum_reg <= 4'hF; + end else - if((vita_state==VITA_HEADER) & src_rdy_i) - seqnum_reg <= seqnum; + begin + if((vita_state==VITA_TRANS_HEADER) & src_rdy_i) + seqnum_reg <= seqnum; + if((vita_state==VITA_HEADER) & src_rdy_i) + vita_seqnum_reg <= vita_seqnum; + end // else: !if(reset | clear_seqnum) always @(posedge clk) if(reset | clear) begin - vita_state <= VITA_HEADER; + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; {has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg} <= 0; seqnum_err <= 0; end else if((vita_state == VITA_STORE) & fifo_space) - if(eop) - if(has_trailer_reg) + if(vita_eof) + if(eof) + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; + else if(has_trailer_reg) vita_state <= VITA_TRAILER; else - vita_state <= VITA_HEADER; - else + vita_state <= VITA_DUMP; + else begin vita_state <= VITA_PAYLOAD; pkt_len <= pkt_len - 1; end else if(src_rdy_i) case(vita_state) + VITA_TRANS_HEADER : + begin + seqnum_err <= ~(seqnum == next_seqnum); + vita_state <= VITA_HEADER; + end VITA_HEADER : begin {has_streamid_reg, has_classid_reg, has_secs_reg, has_tics_reg, has_trailer_reg, is_sob_reg, is_eob_reg} @@ -113,7 +138,7 @@ module vita_tx_deframer vita_state <= VITA_TICS; else vita_state <= VITA_PAYLOAD; - seqnum_err <= ~(seqnum == next_seqnum); + seqnum_err <= seqnum_err | ~(vita_seqnum == next_vita_seqnum); end // case: VITA_HEADER VITA_STREAMID : if(has_classid_reg) @@ -151,11 +176,17 @@ module vita_tx_deframer else vector_phase <= vector_phase + 1; VITA_TRAILER : - vita_state <= VITA_HEADER; + if(eof) + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; + else + vita_state <= VITA_DUMP; + VITA_DUMP : + if(eof) + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; VITA_STORE : ; default : - vita_state <= VITA_HEADER; + vita_state <= (USE_TRANS_HEADER==1) ? VITA_TRANS_HEADER : VITA_HEADER; endcase // case (vita_state) assign line_done = (vector_phase == numchan); @@ -191,7 +222,7 @@ module vita_tx_deframer // sob, eob, has_secs (send_at) ignored on all lines except first assign fifo_i = {sample_d,sample_c,sample_b,sample_a,seqnum_err,has_secs_reg,is_sob_reg,is_eob_reg,eop, - 12'd0,seqnum_reg,send_time}; + 12'd0,seqnum_reg[3:0],send_time}; assign dst_rdy_o = ~(vita_state == VITA_PAYLOAD) & ~((vita_state==VITA_STORE)& ~fifo_space) ; diff --git a/host/README b/host/README index cab1e0b10..c4a72cd83 100644 --- a/host/README +++ b/host/README @@ -8,6 +8,7 @@ The hardware driver for Ettus Research products. ######################################################################## USRP1 USRP2 +USRP-N2XX ######################################################################## # Supported USRP Daughterboards @@ -20,6 +21,7 @@ RFX Series XCVR 2450 WBX Series DBSRX +DBSRX2 TVRX ######################################################################## diff --git a/host/config/Version.cmake b/host/config/Version.cmake index 9e4b6b306..214002b7b 100644 --- a/host/config/Version.cmake +++ b/host/config/Version.cmake @@ -18,9 +18,9 @@ ######################################################################## # Setup Version Numbers ######################################################################## -SET(UHD_VERSION_MAJOR 0) -SET(UHD_VERSION_MINOR 0) -SET(UHD_VERSION_PATCH 0) +SET(UHD_VERSION_MAJOR 0001) #API compatibility number +SET(UHD_VERSION_MINOR 0) #Timestamp of git commit +SET(UHD_VERSION_PATCH 0) #Short hash of git commit ######################################################################## # Find GIT to get repo information @@ -46,19 +46,12 @@ ELSE(${GIT} STREQUAL "GIT-NOTFOUND") OUTPUT_VARIABLE _git_timestamp OUTPUT_STRIP_TRAILING_WHITESPACE ) - #format the timestamp into YYYY-MM-DD + #format the timestamp into YYYY-MM-DD-HH-MM-SS EXECUTE_PROCESS( - COMMAND ${PYTHON_EXECUTABLE} -c "import time; print time.strftime('%Y%m%d', time.gmtime(${_git_timestamp}))" + COMMAND ${PYTHON_EXECUTABLE} -c "import time; print time.strftime('%Y%m%d%H%M%S', time.gmtime(${_git_timestamp}))" OUTPUT_VARIABLE _git_date OUTPUT_STRIP_TRAILING_WHITESPACE ) - SET(UHD_VERSION_MAJOR ${_git_date}) - - #format the timestamp into HH-MM-SS - EXECUTE_PROCESS( - COMMAND ${PYTHON_EXECUTABLE} -c "import time; print time.strftime('%H%M%S', time.gmtime(${_git_timestamp}))" - OUTPUT_VARIABLE _git_time OUTPUT_STRIP_TRAILING_WHITESPACE - ) - SET(UHD_VERSION_MINOR ${_git_time}) + SET(UHD_VERSION_MINOR ${_git_date}) #grab the git ref id for the current head EXECUTE_PROCESS( diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt index 4d3269543..c649dbb61 100644 --- a/host/docs/CMakeLists.txt +++ b/host/docs/CMakeLists.txt @@ -28,7 +28,7 @@ SET(manual_sources images.rst transport.rst usrp1.rst - usrp2.rst + usrp_nxxx.rst ) ######################################################################## diff --git a/host/docs/index.rst b/host/docs/index.rst index 9d6d14d0f..c491c5da6 100644 --- a/host/docs/index.rst +++ b/host/docs/index.rst @@ -24,7 +24,7 @@ Application Notes * `Device Identification Notes <./identification.html>`_ * `Firmware and FPGA Image Notes <./images.html>`_ * `USRP1 Application Notes <./usrp1.html>`_ -* `USRP2 Application Notes <./usrp2.html>`_ +* `USRP2 and USRP-N Series Application Notes <./usrp_nxxx.html>`_ * `Daughterboard Application Notes <./dboards.html>`_ * `Transport Application Notes <./transport.html>`_ diff --git a/host/docs/transport.rst b/host/docs/transport.rst index 432db4bb5..2f730f8e4 100644 --- a/host/docs/transport.rst +++ b/host/docs/transport.rst @@ -40,6 +40,17 @@ The following parameters can be used to alter the transport's default behavior: as the asynchronous send implementation is currently disabled. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Flow control parameters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The host-based flow control expects periodic update packets from the device. +These update packets inform the host of the last packet consumed by the device, +which allows the host to determine throttling conditions for the transmission of packets. +The following mechanisms affect the transmission of periodic update packets: + +* **ups_per_fifo:** The number of update packets for each FIFO's worth of bytes sent into the device +* **ups_per_sec:** The number of update packets per second + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Resize socket buffers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It may be useful increase the size of the socket buffers to diff --git a/host/docs/usrp2.rst b/host/docs/usrp_nxxx.rst index d07175ce4..1c270df08 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp_nxxx.rst @@ -1,11 +1,11 @@ ======================================================================== -UHD - USRP2 Application Notes +UHD - USRP2 and USRP-N Series Application Notes ======================================================================== .. contents:: Table of Contents ------------------------------------------------------------------------ -Load the images onto the SD card +Load the images onto the SD card (USRP2 only) ------------------------------------------------------------------------ **Warning!** Use the usrp2_card_burner.py with caution. If you specify the wrong device node, @@ -46,14 +46,45 @@ Use the card burner tool (windows) ------------------------------------------------------------------------ +Load the images onto the on-board flash (USRP-N Series only) +------------------------------------------------------------------------ +The USRP-N Series can be reprogrammed over the network +to update or change the firmware and FPGA images. + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use the net burner tool (unix) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + cd <prefix>/share/uhd/utils + ./usrp_n2xx_net_burner.py --ip=<ip address> --fw=<path for firmware image> + ./usrp_n2xx_net_burner.py --ip=<ip address> --fpga=<path to FPGA image> + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Use the net burner tool (Windows) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +:: + + <path_to_python.exe> <prefix>/share/uhd/utils/usrp_n2xx_net_burner.py --ip=<ip address> --fw=<path for firmware image> + <path_to_python.exe> <prefix>/share/uhd/utils/usrp_n2xx_net_burner.py --ip=<ip address> --fpga=<path to FPGA image> + +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Device recovery and bricking +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Its possible to put the device into an unusable state by loading bad images. +Fortunately, the USRP-N Series can be booted into a safe (read-only) image. +Once booted into the safe image, the user can once again load images onto the device. + +To boot into the safe image, hold down the reset button while power-cycling the device. +The reset button is a pushbutton switch (S2) located inside the enclosure. + +------------------------------------------------------------------------ Setup networking ------------------------------------------------------------------------ -The USRP2 only supports gigabit ethernet, and -will not work with a 10/100 Mbps interface. -Because the USRP2 uses gigabit ethernet pause frames for flow control, -you cannot use multiple USRP2s with a switch or a hub. -It is recommended that each USRP2 be plugged directly into its own -dedicated gigabit ethernet interface on the host computer. +The USRP2 only supports gigabit ethernet, +and will not work with a 10/100 Mbps interface. +However, a 10/100 Mbps interface can be connected indirectly +to a USRP2 through a gigabit ethernet switch. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Setup the host interface @@ -72,8 +103,9 @@ It is recommended that you change or disable your firewall settings. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Multiple device configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -As described above, you will need one ethernet interface per USRP2. -Each ethernet interface should have its own subnet, +For maximum throughput, one ethernet interface per USRP2 is recommended, +although multiple devices may be connected via a gigabit ethernet switch. +In any case, each ethernet interface should have its own subnet, and the corresponding USRP2 device should be assigned an address in that subnet. Example: diff --git a/host/examples/test_async_messages.cpp b/host/examples/test_async_messages.cpp index e4a996ef5..b1d9d56d4 100644 --- a/host/examples/test_async_messages.cpp +++ b/host/examples/test_async_messages.cpp @@ -19,21 +19,25 @@ #include <uhd/utils/safe_main.hpp> #include <uhd/utils/static.hpp> #include <uhd/usrp/single_usrp.hpp> +#include <boost/assign/list_of.hpp> #include <boost/program_options.hpp> +#include <boost/foreach.hpp> +#include <boost/bind.hpp> #include <boost/format.hpp> +#include <cstdlib> #include <complex> #include <iostream> namespace po = boost::program_options; /*! - * Test that no messages are received: + * Test the burst ack message: * Send a burst of many samples that will fragment internally. - * We expect to not get any async messages. + * We expect to get an burst ack async message. */ -void test_no_async_message(uhd::usrp::single_usrp::sptr sdev){ +bool test_burst_ack_message(uhd::usrp::single_usrp::sptr sdev){ uhd::device::sptr dev = sdev->get_device(); - std::cout << "Test no async message... " << std::flush; + std::cout << "Test burst ack message... " << std::flush; uhd::tx_metadata_t md; md.start_of_burst = true; @@ -50,19 +54,28 @@ void test_no_async_message(uhd::usrp::single_usrp::sptr sdev){ ); uhd::async_metadata_t async_md; - if (dev->recv_async_msg(async_md)){ + if (not dev->recv_async_msg(async_md)){ std::cout << boost::format( "failed:\n" - " Got unexpected event code 0x%x.\n" - ) % async_md.event_code << std::endl; - //clear the async messages - while (dev->recv_async_msg(async_md, 0)){}; + " Async message recv timed out.\n" + ) << std::endl; + return false; } - else{ + + switch(async_md.event_code){ + case uhd::async_metadata_t::EVENT_CODE_BURST_ACK: std::cout << boost::format( "success:\n" - " Did not get an async message.\n" + " Got event code burst ack message.\n" ) << std::endl; + return true; + + default: + std::cout << boost::format( + "failed:\n" + " Got unexpected event code 0x%x.\n" + ) % async_md.event_code << std::endl; + return false; } } @@ -71,7 +84,7 @@ void test_no_async_message(uhd::usrp::single_usrp::sptr sdev){ * Send a start of burst packet with no following end of burst. * We expect to get an underflow(within a burst) async message. */ -void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ +bool test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ uhd::device::sptr dev = sdev->get_device(); std::cout << "Test underflow message... " << std::flush; @@ -80,18 +93,19 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ md.end_of_burst = false; md.has_time_spec = false; - dev->send(NULL, 0, md, + dev->send( + NULL, 0, md, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF ); uhd::async_metadata_t async_md; - if (not dev->recv_async_msg(async_md)){ + if (not dev->recv_async_msg(async_md, 1)){ std::cout << boost::format( "failed:\n" " Async message recv timed out.\n" ) << std::endl; - return; + return false; } switch(async_md.event_code){ @@ -100,13 +114,14 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ "success:\n" " Got event code underflow message.\n" ) << std::endl; - break; + return true; default: std::cout << boost::format( "failed:\n" " Got unexpected event code 0x%x.\n" ) % async_md.event_code << std::endl; + return false; } } @@ -115,7 +130,7 @@ void test_underflow_message(uhd::usrp::single_usrp::sptr sdev){ * Send a burst packet that occurs at a time in the past. * We expect to get a time error async message. */ -void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ +bool test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ uhd::device::sptr dev = sdev->get_device(); std::cout << "Test time error message... " << std::flush; @@ -127,7 +142,8 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ sdev->set_time_now(uhd::time_spec_t(200.0)); //time at 200s - dev->send(NULL, 0, md, + dev->send( + NULL, 0, md, uhd::io_type_t::COMPLEX_FLOAT32, uhd::device::SEND_MODE_FULL_BUFF ); @@ -138,7 +154,7 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ "failed:\n" " Async message recv timed out.\n" ) << std::endl; - return; + return false; } switch(async_md.event_code){ @@ -147,29 +163,38 @@ void test_time_error_message(uhd::usrp::single_usrp::sptr sdev){ "success:\n" " Got event code time error message.\n" ) << std::endl; - break; + return true; default: std::cout << boost::format( "failed:\n" " Got unexpected event code 0x%x.\n" ) % async_md.event_code << std::endl; + return false; } } +void flush_async_md(uhd::usrp::single_usrp::sptr sdev){ + uhd::device::sptr dev = sdev->get_device(); + uhd::async_metadata_t async_md; + while (dev->recv_async_msg(async_md, 1.0)){} +} + int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::set_thread_priority_safe(); //variables to be set by po std::string args; double rate; + size_t ntests; //setup the program options po::options_description desc("Allowed options"); desc.add_options() ("help", "help message") - ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") - ("rate", po::value<double>(&rate)->default_value(1.5e6), "rate of outgoing samples") + ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args") + ("rate", po::value<double>(&rate)->default_value(1.5e6), "rate of outgoing samples") + ("ntests", po::value<size_t>(&ntests)->default_value(10), "number of tests to run") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -195,9 +220,38 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //------------------------------------------------------------------ // begin asyc messages test //------------------------------------------------------------------ - test_no_async_message(sdev); - test_underflow_message(sdev); - test_time_error_message(sdev); + static const uhd::dict<std::string, boost::function<bool(uhd::usrp::single_usrp::sptr)> > + tests = boost::assign::map_list_of + ("Test Burst ACK ", &test_burst_ack_message) + ("Test Underflow ", &test_underflow_message) + ("Test Time Error", &test_time_error_message) + ; + + //init result counts + uhd::dict<std::string, size_t> failures, successes; + BOOST_FOREACH(const std::string &key, tests.keys()){ + failures[key] = 0; + successes[key] = 0; + } + + //run the tests, pick at random + for (size_t n = 0; n < ntests; n++){ + std::string key = tests.keys()[std::rand() % tests.size()]; + bool pass = tests[key](sdev); + flush_async_md(sdev); + + //store result + if (pass) successes[key]++; + else failures[key]++; + } + + //print the result summary + std::cout << std::endl << "Summary:" << std::endl << std::endl; + BOOST_FOREACH(const std::string &key, tests.keys()){ + std::cout << boost::format( + "%s -> %3d successes, %3d failures" + ) % key % successes[key] % failures[key] << std::endl; + } //finished std::cout << std::endl << "Done!" << std::endl << std::endl; diff --git a/host/include/uhd/config.hpp b/host/include/uhd/config.hpp index 2918c2340..316d60c2b 100644 --- a/host/include/uhd/config.hpp +++ b/host/include/uhd/config.hpp @@ -56,14 +56,17 @@ #define UHD_HELPER_DLL_IMPORT __declspec(dllimport) #define UHD_HELPER_DLL_EXPORT __declspec(dllexport) #define UHD_HELPER_DLL_LOCAL + #define UHD_HELPER_EXIMP_TMPL #elif defined(__GNUG__) && __GNUG__ >= 4 #define UHD_HELPER_DLL_IMPORT __attribute__ ((visibility("default"))) #define UHD_HELPER_DLL_EXPORT __attribute__ ((visibility("default"))) #define UHD_HELPER_DLL_LOCAL __attribute__ ((visibility("hidden"))) + #define UHD_HELPER_EXIMP_TMPL extern #else #define UHD_HELPER_DLL_IMPORT #define UHD_HELPER_DLL_EXPORT #define UHD_HELPER_DLL_LOCAL + #define UHD_HELPER_EXIMP_TMPL extern #endif // Now we use the generic helper definitions above to define UHD_API and UHD_LOCAL. @@ -75,13 +78,16 @@ #ifdef UHD_DLL // defined if UHD is compiled as a DLL #ifdef UHD_DLL_EXPORTS // defined if we are building the UHD DLL (instead of using it) #define UHD_API UHD_HELPER_DLL_EXPORT + #define UHD_EXIMP_TMPL UHD_HELPER_EXIMP_TMPL #else #define UHD_API UHD_HELPER_DLL_IMPORT + #define UHD_EXIMP_TMPL #endif // UHD_DLL_EXPORTS #define UHD_LOCAL UHD_HELPER_DLL_LOCAL #else // UHD_DLL is not defined: this means UHD is a static lib. #define UHD_API #define UHD_LOCAL + #define UHD_EXIMP_TMPL #endif // UHD_DLL // Define force inline macro diff --git a/host/include/uhd/transport/udp_simple.hpp b/host/include/uhd/transport/udp_simple.hpp index c84393ecf..83f895ba9 100644 --- a/host/include/uhd/transport/udp_simple.hpp +++ b/host/include/uhd/transport/udp_simple.hpp @@ -73,10 +73,10 @@ public: * Receive into the provided buffer. * Blocks until data is received or a timeout occurs. * \param buff a mutable buffer to receive into - * \param timeout_ms the timeout in milliseconds + * \param timeout the timeout in seconds * \return the number of bytes received or zero on timeout */ - virtual size_t recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms) = 0; + virtual size_t recv(const boost::asio::mutable_buffer &buff, double timeout = 0.1) = 0; }; }} //namespace diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index a96976b5e..1d2c0c41c 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -25,6 +25,7 @@ INSTALL(FILES mac_addr.hpp metadata.hpp otw_type.hpp + ranges.ipp ranges.hpp serial.hpp stream_cmd.hpp diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp index ba05d5272..f037d7988 100644 --- a/host/include/uhd/types/dict.ipp +++ b/host/include/uhd/types/dict.ipp @@ -46,12 +46,11 @@ namespace uhd{ /* NOP */ } - template <typename Key, typename Val> - template <typename InputIterator> - dict<Key, Val>::dict(InputIterator first, InputIterator last){ - for(InputIterator it = first; it != last; it++){ - _map.push_back(*it); - } + template <typename Key, typename Val> template <typename InputIterator> + dict<Key, Val>::dict(InputIterator first, InputIterator last): + _map(first, last) + { + /* NOP */ } template <typename Key, typename Val> diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 3f250d13e..f4e084430 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -132,8 +132,8 @@ namespace uhd{ * The type of event for a receive async message call. */ enum event_code_t { - //! A packet was successfully transmitted. - EVENT_CODE_SUCCESS = 0x1, + //! A burst was successfully transmitted. + EVENT_CODE_BURST_ACK = 0x1, //! An internal send buffer has emptied. EVENT_CODE_UNDERFLOW = 0x2, //! Packet loss between host and device. diff --git a/host/include/uhd/types/ranges.hpp b/host/include/uhd/types/ranges.hpp index a2057d1c8..03aa69ba8 100644 --- a/host/include/uhd/types/ranges.hpp +++ b/host/include/uhd/types/ranges.hpp @@ -19,28 +19,110 @@ #define INCLUDED_UHD_TYPES_RANGES_HPP #include <uhd/config.hpp> +#include <uhd/utils/pimpl.hpp> +#include <string> +#include <vector> +#include <string> namespace uhd{ /*! - * The gain range struct describes possible gain settings. - * The mimumum gain, maximum gain, and step size are in dB. + * A range object describes a set of discrete values of the form: + * y = start + step*n, where n is an integer between 0 and (stop - start)/step */ - struct UHD_API gain_range_t{ - float min, max, step; - gain_range_t(float min = 0.0, float max = 0.0, float step = 0.0); + template <typename T> class range_t{ + public: + /*! + * Create a range from a single value. + * The step size will be taken as zero. + * \param value the only possible value in this range + */ + range_t(const T &value = T(0)); + + /*! + * Create a range from a full set of values. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the start value for this range. + const T start(void) const; + + //! Get the stop value for this range. + const T stop(void) const; + + //! Get the step value for this range. + const T step(void) const; + + //! Convert this range to a printable string + const std::string to_pp_string(void) const; + + private: + UHD_PIMPL_DECL(impl) _impl; }; /*! - * The frequency range struct describes possible frequency settings. - * Because tuning is very granular (sub-Hz), step size is not listed. - * The mimumum frequency and maximum frequency are in Hz. + * A meta-range object holds a list of individual ranges. */ - struct UHD_API freq_range_t{ - double min, max; - freq_range_t(double min = 0.0, double max = 0.0); + template <typename T> struct meta_range_t : std::vector<range_t<T> >{ + + //! A default constructor for an empty meta-range + meta_range_t(void); + + /*! + * Input iterator constructor: + * Makes boost::assign::list_of work. + * \param first the begin iterator + * \param last the end iterator + */ + template <typename InputIterator> + meta_range_t(InputIterator first, InputIterator last); + + /*! + * A convenience constructor for a single range. + * A step size of zero implies infinite precision. + * \param start the minimum value for this range + * \param stop the maximum value for this range + * \param step the step size for this range + */ + meta_range_t(const T &start, const T &stop, const T &step = T(0)); + + //! Get the overall start value for this meta-range. + const T start(void) const; + + //! Get the overall stop value for this meta-range. + const T stop(void) const; + + //! Get the overall step value for this meta-range. + const T step(void) const; + + /*! + * Clip the target value to a possible range value. + * \param value the value to clip to this range + * \param clip_step if true, clip to steps as well + * \return a value that is in one of the ranges + */ + const T clip(const T &value, bool clip_step = false) const; + + //! Convert this meta-range to a printable string + const std::string to_pp_string(void) const; + }; + //! export a symbol for the gain range type + UHD_EXIMP_TMPL template struct UHD_API meta_range_t<float>; + typedef meta_range_t<float> gain_range_t; + + //! export a symbol for the freq range type + UHD_EXIMP_TMPL template struct UHD_API meta_range_t<double>; + typedef meta_range_t<double> freq_range_t; + + } //namespace uhd +#include <uhd/types/ranges.ipp> + #endif /* INCLUDED_UHD_TYPES_RANGES_HPP */ diff --git a/host/include/uhd/types/ranges.ipp b/host/include/uhd/types/ranges.ipp new file mode 100644 index 000000000..29f389fca --- /dev/null +++ b/host/include/uhd/types/ranges.ipp @@ -0,0 +1,185 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_UHD_TYPES_RANGES_IPP +#define INCLUDED_UHD_TYPES_RANGES_IPP + +#include <boost/math/special_functions/round.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <stdexcept> +#include <sstream> + +namespace uhd{ + + /******************************************************************* + * range_t implementation code + ******************************************************************/ + template <typename T> struct range_t<T>::impl{ + impl(const T &start, const T &stop, const T &step): + start(start), stop(stop), step(step) + { + /* NOP */ + } + const T start, stop, step; + }; + + template <typename T> range_t<T>::range_t(const T &value): + _impl(UHD_PIMPL_MAKE(impl, (value, value, T(0)))) + { + /* NOP */ + } + + template <typename T> range_t<T>::range_t( + const T &start, const T &stop, const T &step + ): + _impl(UHD_PIMPL_MAKE(impl, (start, stop, step))) + { + if (stop < start){ + throw std::invalid_argument("cannot make range where stop < start"); + } + } + + template <typename T> const T range_t<T>::start(void) const{ + return _impl->start; + } + + template <typename T> const T range_t<T>::stop(void) const{ + return _impl->stop; + } + + template <typename T> const T range_t<T>::step(void) const{ + return _impl->step; + } + + template <typename T> const std::string range_t<T>::to_pp_string(void) const{ + std::stringstream ss; + ss << "(" << this->start(); + if (this->start() != this->stop()) ss << ", " << this->stop(); + if (this->step() != T(0)) ss << ", " << this->step(); + ss << ")"; + return ss.str(); + } + + /******************************************************************* + * meta_range_t implementation code + ******************************************************************/ + + namespace /*anon*/{ + template <typename T> inline + void check_meta_range_monotonic(const meta_range_t<T> &mr){ + if (mr.empty()){ + throw std::runtime_error("meta-range cannot be empty"); + } + for (size_t i = 1; i < mr.size(); i++){ + if (mr.at(i).start() < mr.at(i-1).stop()){ + throw std::runtime_error("meta-range is not monotonic"); + } + } + } + } //namespace /*anon*/ + + + template <typename T> meta_range_t<T>::meta_range_t(void){ + /* NOP */ + } + + template <typename T> template <typename InputIterator> + meta_range_t<T>::meta_range_t( + InputIterator first, InputIterator last + ): + std::vector<range_t<T> >(first, last) + { + /* NOP */ + } + + template <typename T> meta_range_t<T>::meta_range_t( + const T &start, const T &stop, const T &step + ): + std::vector<range_t<T> > (1, range_t<T>(start, stop, step)) + { + /* NOP */ + } + + template <typename T> const T meta_range_t<T>::start(void) const{ + check_meta_range_monotonic(*this); + T min_start = this->front().start(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + min_start = std::min(min_start, r.start()); + } + return min_start; + } + + template <typename T> const T meta_range_t<T>::stop(void) const{ + check_meta_range_monotonic(*this); + T max_stop = this->front().stop(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + max_stop = std::max(max_stop, r.stop()); + } + return max_stop; + } + + template <typename T> const T meta_range_t<T>::step(void) const{ + check_meta_range_monotonic(*this); + std::vector<T> non_zero_steps; + range_t<T> last = this->front(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + //steps at each range + if (r.step() > T(0)) non_zero_steps.push_back(r.step()); + //and steps in-between ranges + T ibtw_step = r.start() - last.stop(); + if (ibtw_step > T(0)) non_zero_steps.push_back(ibtw_step); + //store ref to last + last = r; + } + if (non_zero_steps.empty()) return T(0); //all zero steps, its zero... + return *std::min_element(non_zero_steps.begin(), non_zero_steps.end()); + } + + template <typename T> const T meta_range_t<T>::clip( + const T &value, bool clip_step + ) const{ + check_meta_range_monotonic(*this); + T last_stop = this->front().stop(); + BOOST_FOREACH(const range_t<T> &r, (*this)){ + //in-between ranges, clip to nearest + if (value < r.start()){ + return (std::abs(value - r.start()) < std::abs(value - last_stop))? + r.start() : last_stop; + } + //in this range, clip here + if (value <= r.stop()){ + if (not clip_step or r.step() == T(0)) return value; + return boost::math::round((value - r.start())/r.step())*r.step() + r.start(); + } + //continue on to the next range + last_stop = r.stop(); + } + return last_stop; + } + + template <typename T> const std::string meta_range_t<T>::to_pp_string(void) const{ + std::stringstream ss; + BOOST_FOREACH(const range_t<T> &r, (*this)){ + ss << r.to_pp_string() << std::endl; + } + return ss.str(); + } + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_RANGES_IPP */ diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt index cdf31df87..c8d7281d3 100644 --- a/host/include/uhd/usrp/CMakeLists.txt +++ b/host/include/uhd/usrp/CMakeLists.txt @@ -40,9 +40,7 @@ INSTALL(FILES tune_helper.hpp ### interfaces ### - simple_usrp.hpp single_usrp.hpp - mimo_usrp.hpp multi_usrp.hpp DESTINATION ${INCLUDE_DIR}/uhd/usrp diff --git a/host/include/uhd/usrp/dsp_utils.hpp b/host/include/uhd/usrp/dsp_utils.hpp index 8ec04dd2f..5b81ce322 100644 --- a/host/include/uhd/usrp/dsp_utils.hpp +++ b/host/include/uhd/usrp/dsp_utils.hpp @@ -85,12 +85,9 @@ namespace dsp_type1{ /*! * Calculate the stream command word from the stream command struct. * \param stream_cmd the requested stream command with mode, flags, timestamp - * \param num_samps_continuous number of samples to request in continuous mode * \return the 32-bit stream command word */ - UHD_API boost::uint32_t calc_stream_cmd_word( - const stream_cmd_t &stream_cmd, size_t num_samps_continuous - ); + UHD_API boost::uint32_t calc_stream_cmd_word(const stream_cmd_t &stream_cmd); } //namespace dsp_type1 diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp deleted file mode 100644 index a2092f04f..000000000 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ /dev/null @@ -1,525 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#ifndef INCLUDED_UHD_USRP_MIMO_USRP_HPP -#define INCLUDED_UHD_USRP_MIMO_USRP_HPP - -#include <uhd/config.hpp> -#include <uhd/device.hpp> -#include <uhd/types/ranges.hpp> -#include <uhd/types/stream_cmd.hpp> -#include <uhd/types/clock_config.hpp> -#include <uhd/types/tune_result.hpp> -#include <uhd/usrp/subdev_spec.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> -#include <vector> - -namespace uhd{ namespace usrp{ - -/*! - * The MIMO USRP device class (DEPRECATED): - * A mimo usrp facilitates ease-of-use for multi-usrp scenarios. - * The wrapper provides convenience functions to control the group - * of underlying devices as if they consisted of a single device. - */ -class UHD_API UHD_DEPRECATED mimo_usrp : boost::noncopyable{ -public: - typedef boost::shared_ptr<mimo_usrp> sptr; - - /*! - * Make a new mimo usrp from the device address. - * \param dev_addr the device address - * \return a new mimo usrp object - */ - static sptr make(const device_addr_t &dev_addr); - - /*! - * Get the underlying device object. - * This is needed to get access to the streaming API and properties. - * \return the device object within this simple usrp - */ - virtual device::sptr get_device(void) = 0; - - /*! - * Get a printable name for this mimo usrp. - * \return a printable string - */ - virtual std::string get_pp_string(void) = 0; - - /*! - * Get the number of channels in this mimo configuration. - * The number of rx channels == the number of tx channels. - * \return the number of channels - */ - virtual size_t get_num_channels(void) = 0; - - /******************************************************************* - * Misc - ******************************************************************/ - /*! - * Gets the current time in the usrp time registers. - * \return a timespec representing current usrp time - */ - virtual time_spec_t get_time_now(void) = 0; - - /*! - * Set the time registers on the usrp at the next pps tick. - * The values will not be latched in until the pulse occurs. - * It is recommended that the user sleep(1) after calling to ensure - * that the time registers will be in a known state prior to use. - * This call works across all mboards in the mimo configuration. - * - * Note: Because this call sets the time on the "next" pps, - * the seconds in the time spec should be current seconds + 1. - * - * \param time_spec the time to latch into the usrp device - */ - virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; - - /*! - * Synchronize the times across all motherboards in this configuration. - * Use this method to sync the times when the edge of the PPS is unknown. - * - * Ex: Host machine is not attached to serial port of GPSDO - * and can therefore not query the GPSDO for the PPS edge. - * - * This is a 3-step process, and will take at most 3 seconds to complete. - * Upon completion, the times will be synchronized to the time provided. - * - * - Step1: set the time at the next pps (potential race condition) - * - Step2: wait for the seconds to rollover to catch the pps edge - * - Step3: set the time at the next pps (synchronous for all boards) - * - * \param time_spec the time to latch into the usrp device - */ - virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0; - - /*! - * Issue a stream command to the usrp device. - * This tells the usrp to send samples into the host. - * See the documentation for stream_cmd_t for more info. - * \param stream_cmd the stream command to issue - */ - virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; - - /******************************************************************* - * RX methods - ******************************************************************/ - virtual void set_rx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0; - virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(size_t chan) = 0; - - virtual void set_rx_rate_all(double rate) = 0; - virtual double get_rx_rate_all(void) = 0; - - virtual tune_result_t set_rx_freq(size_t chan, double freq) = 0; - //virtual tune_result_t set_rx_freq(size_t chan, double freq, double lo_off) = 0; - virtual double get_rx_freq(size_t chan) = 0; - virtual freq_range_t get_rx_freq_range(size_t chan) = 0; - - virtual void set_rx_gain(size_t chan, float gain) = 0; - virtual float get_rx_gain(size_t chan) = 0; - virtual gain_range_t get_rx_gain_range(size_t chan) = 0; - - virtual void set_rx_antenna(size_t chan, const std::string &ant) = 0; - virtual std::string get_rx_antenna(size_t chan) = 0; - virtual std::vector<std::string> get_rx_antennas(size_t chan) = 0; - - virtual bool get_rx_lo_locked(size_t chan) = 0; - - /*! - * Read the RSSI value from a usrp device. - * Or throw if the dboard does not support an RSSI readback. - * \param chan which mimo channel 0 to N-1 - * \return the rssi in dB - */ - virtual float read_rssi(size_t chan) = 0; - - virtual void set_rx_bandwidth(size_t chan, float bandwidth) = 0; - - /******************************************************************* - * TX methods - ******************************************************************/ - virtual void set_tx_subdev_spec(size_t chan, const uhd::usrp::subdev_spec_t &spec) = 0; - virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(size_t chan) = 0; - - virtual void set_tx_rate_all(double rate) = 0; - virtual double get_tx_rate_all(void) = 0; - - virtual tune_result_t set_tx_freq(size_t chan, double freq) = 0; - //virtual tune_result_t set_tx_freq(size_t chan, double freq, double lo_off) = 0; - virtual double get_tx_freq(size_t chan) = 0; - virtual freq_range_t get_tx_freq_range(size_t chan) = 0; - - virtual void set_tx_gain(size_t chan, float gain) = 0; - virtual float get_tx_gain(size_t chan) = 0; - virtual gain_range_t get_tx_gain_range(size_t chan) = 0; - - virtual void set_tx_antenna(size_t chan, const std::string &ant) = 0; - virtual std::string get_tx_antenna(size_t chan) = 0; - virtual std::vector<std::string> get_tx_antennas(size_t chan) = 0; - - virtual bool get_tx_lo_locked(size_t chan) = 0; - -}; - -}} - -#include <uhd/utils/warning.hpp> -#include <uhd/usrp/tune_helper.hpp> -#include <uhd/utils/assert.hpp> -#include <uhd/utils/gain_group.hpp> -#include <uhd/utils/algorithm.hpp> -#include <uhd/utils/warning.hpp> -#include <uhd/usrp/subdev_props.hpp> -#include <uhd/usrp/mboard_props.hpp> -#include <uhd/usrp/device_props.hpp> -#include <uhd/usrp/dboard_props.hpp> -#include <uhd/usrp/dsp_props.hpp> -#include <boost/foreach.hpp> -#include <boost/format.hpp> -#include <boost/thread.hpp> -#include <stdexcept> -#include <iostream> - -namespace uhd{ namespace usrp{ namespace /*anon*/{ - -static inline freq_range_t add_dsp_shift(const freq_range_t &range, wax::obj dsp){ - double codec_rate = dsp[DSP_PROP_CODEC_RATE].as<double>(); - return freq_range_t(range.min - codec_rate/2.0, range.max + codec_rate/2.0); -} - -/*********************************************************************** - * MIMO USRP Implementation - **********************************************************************/ -class mimo_usrp_impl : public mimo_usrp{ -public: - mimo_usrp_impl(const device_addr_t &addr){ - _dev = device::make(addr); - - //set the clock config across all mboards (TODO set through api) - clock_config_t clock_config; - clock_config.ref_source = clock_config_t::REF_SMA; - clock_config.pps_source = clock_config_t::PPS_SMA; - for (size_t chan = 0; chan < get_num_channels(); chan++){ - _mboard(chan)[MBOARD_PROP_CLOCK_CONFIG] = clock_config; - } - } - - ~mimo_usrp_impl(void){ - /* NOP */ - } - - device::sptr get_device(void){ - return _dev; - } - - std::string get_pp_string(void){ - std::string buff = str(boost::format( - "MIMO USRP:\n" - " Device: %s\n" - ) - % (*_dev)[DEVICE_PROP_NAME].as<std::string>() - ); - for (size_t chan = 0; chan < get_num_channels(); chan++){ - buff += str(boost::format( - " Channel: %u\n" - " Mboard: %s\n" - " RX DSP: %s\n" - " RX Dboard: %s\n" - " RX Subdev: %s\n" - " TX DSP: %s\n" - " TX Dboard: %s\n" - " TX Subdev: %s\n" - ) % chan - % _mboard(chan)[MBOARD_PROP_NAME].as<std::string>() - % _rx_dsp(chan)[DSP_PROP_NAME].as<std::string>() - % _rx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>() - % _rx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>() - % _tx_dsp(chan)[DSP_PROP_NAME].as<std::string>() - % _tx_dboard(chan)[DBOARD_PROP_NAME].as<std::string>() - % _tx_subdev(chan)[SUBDEV_PROP_NAME].as<std::string>() - ); - } - return buff; - } - - size_t get_num_channels(void){ - return (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>().size(); - } - - /******************************************************************* - * Misc - ******************************************************************/ - time_spec_t get_time_now(void){ - //the time on the first mboard better be the same on all - return _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>(); - } - - void set_time_next_pps(const time_spec_t &time_spec){ - for (size_t chan = 0; chan < get_num_channels(); chan++){ - _mboard(chan)[MBOARD_PROP_TIME_NEXT_PPS] = time_spec; - } - } - - void set_time_unknown_pps(const time_spec_t &time_spec){ - std::cout << "Set time with unknown pps edge:" << std::endl; - std::cout << " 1) set times next pps (race condition)" << std::endl; - set_time_next_pps(time_spec); - boost::this_thread::sleep(boost::posix_time::seconds(1)); - - std::cout << " 2) catch seconds rollover at pps edge" << std::endl; - time_t last_secs = 0, curr_secs = 0; - while(curr_secs == last_secs){ - last_secs = curr_secs; - curr_secs = get_time_now().get_full_secs(); - } - - std::cout << " 3) set times next pps (synchronously)" << std::endl; - set_time_next_pps(time_spec); - boost::this_thread::sleep(boost::posix_time::seconds(1)); - - //verify that the time registers are read to be within a few RTT - for (size_t chan = 1; chan < get_num_channels(); chan++){ - time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as<time_spec_t>(); - time_spec_t time_i = _mboard(chan)[MBOARD_PROP_TIME_NOW].as<time_spec_t>(); - if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big - uhd::warning::post(str(boost::format( - "Detected time deviation between board %d and board 0.\n" - "Board 0 time is %f seconds.\n" - "Board %d time is %f seconds.\n" - ) % chan % time_0.get_real_secs() % chan % time_i.get_real_secs())); - } - } - } - - void issue_stream_cmd(const stream_cmd_t &stream_cmd){ - for (size_t chan = 0; chan < get_num_channels(); chan++){ - _mboard(chan)[MBOARD_PROP_STREAM_CMD] = stream_cmd; - } - } - - /******************************************************************* - * RX methods - ******************************************************************/ - void set_rx_subdev_spec(size_t chan, const subdev_spec_t &spec){ - UHD_ASSERT_THROW(spec.size() <= 1); - _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC] = spec; - } - - subdev_spec_t get_rx_subdev_spec(size_t chan){ - return _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>(); - } - - void set_rx_rate_all(double rate){ - std::vector<double> _actual_rates; - for (size_t chan = 0; chan < get_num_channels(); chan++){ - _rx_dsp(chan)[DSP_PROP_HOST_RATE] = rate; - _actual_rates.push_back(_rx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>()); - } - _rx_rate = _actual_rates.front(); - if (std::count(_actual_rates, _rx_rate) != _actual_rates.size()) throw std::runtime_error( - "MIMO configuratio error: rx rate inconsistent across mboards" - ); - } - - double get_rx_rate_all(void){ - return _rx_rate; - } - - tune_result_t set_rx_freq(size_t chan, double target_freq){ - return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0, target_freq); - } - - //tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){ - // return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0, target_freq, lo_off); - //} - - double get_rx_freq(size_t chan){ - return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0); - } - - freq_range_t get_rx_freq_range(size_t chan){ - return add_dsp_shift(_rx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _rx_dsp(chan)); - } - - void set_rx_gain(size_t chan, float gain){ - return _rx_gain_group(chan)->set_value(gain); - } - - float get_rx_gain(size_t chan){ - return _rx_gain_group(chan)->get_value(); - } - - gain_range_t get_rx_gain_range(size_t chan){ - return _rx_gain_group(chan)->get_range(); - } - - void set_rx_antenna(size_t chan, const std::string &ant){ - _rx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant; - } - - std::string get_rx_antenna(size_t chan){ - return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); - } - - std::vector<std::string> get_rx_antennas(size_t chan){ - return _rx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); - } - - bool get_rx_lo_locked(size_t chan){ - return _rx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); - } - - float read_rssi(size_t chan){ - return _rx_subdev(chan)[SUBDEV_PROP_RSSI].as<float>(); - } - - void set_rx_bandwidth(size_t chan, float bandwidth){ - _rx_subdev(chan)[SUBDEV_PROP_BANDWIDTH] = bandwidth; - } - - /******************************************************************* - * TX methods - ******************************************************************/ - void set_tx_subdev_spec(size_t chan, const subdev_spec_t &spec){ - UHD_ASSERT_THROW(spec.size() <= 1); - _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC] = spec; - } - - subdev_spec_t get_tx_subdev_spec(size_t chan){ - return _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>(); - } - - void set_tx_rate_all(double rate){ - std::vector<double> _actual_rates; - for (size_t chan = 0; chan < get_num_channels(); chan++){ - _tx_dsp(chan)[DSP_PROP_HOST_RATE] = rate; - _actual_rates.push_back(_tx_dsp(chan)[DSP_PROP_HOST_RATE].as<double>()); - } - _tx_rate = _actual_rates.front(); - if (std::count(_actual_rates, _tx_rate) != _actual_rates.size()) throw std::runtime_error( - "MIMO configuratio error: tx rate inconsistent across mboards" - ); - } - - double get_tx_rate_all(void){ - return _tx_rate; - } - - tune_result_t set_tx_freq(size_t chan, double target_freq){ - return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0, target_freq); - } - - //tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){ - // return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0, target_freq, lo_off); - //} - - double get_tx_freq(size_t chan){ - return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0); - } - - freq_range_t get_tx_freq_range(size_t chan){ - return add_dsp_shift(_tx_subdev(chan)[SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>(), _tx_dsp(chan)); - } - - void set_tx_gain(size_t chan, float gain){ - return _tx_gain_group(chan)->set_value(gain); - } - - float get_tx_gain(size_t chan){ - return _tx_gain_group(chan)->get_value(); - } - - gain_range_t get_tx_gain_range(size_t chan){ - return _tx_gain_group(chan)->get_range(); - } - - void set_tx_antenna(size_t chan, const std::string &ant){ - _tx_subdev(chan)[SUBDEV_PROP_ANTENNA] = ant; - } - - std::string get_tx_antenna(size_t chan){ - return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA].as<std::string>(); - } - - std::vector<std::string> get_tx_antennas(size_t chan){ - return _tx_subdev(chan)[SUBDEV_PROP_ANTENNA_NAMES].as<prop_names_t>(); - } - - bool get_tx_lo_locked(size_t chan){ - return _tx_subdev(chan)[SUBDEV_PROP_LO_LOCKED].as<bool>(); - } - -private: - device::sptr _dev; - wax::obj _mboard(size_t chan){ - prop_names_t names = (*_dev)[DEVICE_PROP_MBOARD_NAMES].as<prop_names_t>(); - return (*_dev)[named_prop_t(DEVICE_PROP_MBOARD, names.at(chan))]; - } - wax::obj _rx_dsp(size_t chan){ - return _mboard(chan)[MBOARD_PROP_RX_DSP]; - } - wax::obj _tx_dsp(size_t chan){ - return _mboard(chan)[MBOARD_PROP_TX_DSP]; - } - wax::obj _rx_dboard(size_t chan){ - std::string db_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name; - return _mboard(chan)[named_prop_t(MBOARD_PROP_RX_DBOARD, db_name)]; - } - wax::obj _tx_dboard(size_t chan){ - std::string db_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().db_name; - return _mboard(chan)[named_prop_t(MBOARD_PROP_TX_DBOARD, db_name)]; - } - wax::obj _rx_subdev(size_t chan){ - std::string sd_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name; - return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)]; - } - wax::obj _tx_subdev(size_t chan){ - std::string sd_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name; - return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_SUBDEV, sd_name)]; - } - gain_group::sptr _rx_gain_group(size_t chan){ - std::string sd_name = _mboard(chan)[MBOARD_PROP_RX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name; - return _rx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>(); - } - gain_group::sptr _tx_gain_group(size_t chan){ - std::string sd_name = _mboard(chan)[MBOARD_PROP_TX_SUBDEV_SPEC].as<subdev_spec_t>().front().sd_name; - return _tx_dboard(chan)[named_prop_t(DBOARD_PROP_GAIN_GROUP, sd_name)].as<gain_group::sptr>(); - } - - //shadows - double _rx_rate, _tx_rate; -}; -}}} - -namespace uhd{ namespace usrp{ -/*********************************************************************** - * The Make Function - **********************************************************************/ -inline mimo_usrp::sptr mimo_usrp::make(const device_addr_t &dev_addr){ - uhd::warning::post( - "The mimo USRP interface has been deprecated.\n" - "Please switch to the multi USRP interface.\n" - "#include <uhd/usrp/multi_usrp.hpp>\n" - "multi_usrp::sptr sdev = multi_usrp::make(args);\n" - ); - return sptr(new mimo_usrp_impl(dev_addr)); -} -}} - -#endif /* INCLUDED_UHD_USRP_MIMO_USRP_HPP */ diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp deleted file mode 100644 index 77416dbbd..000000000 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ /dev/null @@ -1,388 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// - -#ifndef INCLUDED_UHD_USRP_SIMPLE_USRP_HPP -#define INCLUDED_UHD_USRP_SIMPLE_USRP_HPP - -#include <uhd/config.hpp> -#include <uhd/device.hpp> -#include <uhd/types/ranges.hpp> -#include <uhd/types/stream_cmd.hpp> -#include <uhd/types/clock_config.hpp> -#include <uhd/types/tune_result.hpp> -#include <uhd/usrp/subdev_spec.hpp> -#include <uhd/usrp/dboard_iface.hpp> -#include <boost/shared_ptr.hpp> -#include <boost/utility.hpp> -#include <vector> - -namespace uhd{ namespace usrp{ - -/*! - * The simple USRP device class (DEPRECATED): - * This interface has been deprecated in favor of the single USRP interface. - * A simple usrp facilitates ease-of-use for most use-case scenarios. - * The wrapper provides convenience functions to tune the devices - * as well as to set the dboard gains, antennas, and other properties. - */ -class UHD_API UHD_DEPRECATED simple_usrp : boost::noncopyable{ -public: - typedef boost::shared_ptr<simple_usrp> sptr; - - /*! - * Make a new simple usrp from the device address. - * \param dev_addr the device address - * \return a new simple usrp object - */ - static sptr make(const device_addr_t &dev_addr); - - /*! - * Get the underlying device object. - * This is needed to get access to the streaming API and properties. - * \return the device object within this simple usrp - */ - virtual device::sptr get_device(void) = 0; - - /*! - * Get a printable name for this simple usrp. - * \return a printable string - */ - virtual std::string get_pp_string(void) = 0; - - /******************************************************************* - * Misc - ******************************************************************/ - /*! - * Gets the current time in the usrp time registers. - * \return a timespec representing current usrp time - */ - virtual time_spec_t get_time_now(void) = 0; - - /*! - * Sets the time registers on the usrp immediately. - * \param time_spec the time to latch into the usrp device - */ - virtual void set_time_now(const time_spec_t &time_spec) = 0; - - /*! - * Set the time registers on the usrp at the next pps tick. - * The values will not be latched in until the pulse occurs. - * It is recommended that the user sleep(1) after calling to ensure - * that the time registers will be in a known state prior to use. - * - * Note: Because this call sets the time on the "next" pps, - * the seconds in the time spec should be current seconds + 1. - * - * \param time_spec the time to latch into the usrp device - */ - virtual void set_time_next_pps(const time_spec_t &time_spec) = 0; - - /*! - * Issue a stream command to the usrp device. - * This tells the usrp to send samples into the host. - * See the documentation for stream_cmd_t for more info. - * \param stream_cmd the stream command to issue - */ - virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0; - - /*! - * Set the clock configuration for the usrp device. - * This tells the usrp how to get a 10Mhz reference and PPS clock. - * See the documentation for clock_config_t for more info. - * \param clock_config the clock configuration to set - */ - virtual void set_clock_config(const clock_config_t &clock_config) = 0; - - /******************************************************************* - * RX methods - ******************************************************************/ - virtual void set_rx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; - virtual uhd::usrp::subdev_spec_t get_rx_subdev_spec(void) = 0; - - virtual void set_rx_rate(double rate) = 0; - virtual double get_rx_rate(void) = 0; - - virtual tune_result_t set_rx_freq(double freq) = 0; - //virtual tune_result_t set_rx_freq(double freq, double lo_off) = 0; - virtual double get_rx_freq(void) = 0; - virtual freq_range_t get_rx_freq_range(void) = 0; - - virtual void set_rx_gain(float gain) = 0; - virtual float get_rx_gain(void) = 0; - virtual gain_range_t get_rx_gain_range(void) = 0; - - virtual void set_rx_antenna(const std::string &ant) = 0; - virtual std::string get_rx_antenna(void) = 0; - virtual std::vector<std::string> get_rx_antennas(void) = 0; - - virtual bool get_rx_lo_locked(void) = 0; - - /*! - * Read the RSSI value from a usrp device. - * Or throw if the dboard does not support an RSSI readback. - * \return the rssi in dB - */ - virtual float read_rssi(void) = 0; - - virtual dboard_iface::sptr get_rx_dboard_iface(void) = 0; - - virtual void set_rx_bandwidth(float) = 0; - - /******************************************************************* - * TX methods - ******************************************************************/ - virtual void set_tx_subdev_spec(const uhd::usrp::subdev_spec_t &spec) = 0; - virtual uhd::usrp::subdev_spec_t get_tx_subdev_spec(void) = 0; - - virtual void set_tx_rate(double rate) = 0; - virtual double get_tx_rate(void) = 0; - - virtual tune_result_t set_tx_freq(double freq) = 0; - //virtual tune_result_t set_tx_freq(double freq, double lo_off) = 0; - virtual double get_tx_freq(void) = 0; - virtual freq_range_t get_tx_freq_range(void) = 0; - - virtual void set_tx_gain(float gain) = 0; - virtual float get_tx_gain(void) = 0; - virtual gain_range_t get_tx_gain_range(void) = 0; - - virtual void set_tx_antenna(const std::string &ant) = 0; - virtual std::string get_tx_antenna(void) = 0; - virtual std::vector<std::string> get_tx_antennas(void) = 0; - - virtual bool get_tx_lo_locked(void) = 0; - - virtual dboard_iface::sptr get_tx_dboard_iface(void) = 0; -}; - -}} - -#include <uhd/usrp/single_usrp.hpp> -#include <uhd/utils/warning.hpp> - -namespace uhd{ namespace usrp{ namespace /*anon*/{ - -/*********************************************************************** - * Simple USRP Implementation - **********************************************************************/ -class simple_usrp_impl : public simple_usrp{ -public: - simple_usrp_impl(const device_addr_t &addr){ - _sdev = single_usrp::make(addr); - } - - ~simple_usrp_impl(void){ - /* NOP */ - } - - device::sptr get_device(void){ - return _sdev->get_device(); - } - - std::string get_pp_string(void){ - return _sdev->get_pp_string(); - } - - /******************************************************************* - * Misc - ******************************************************************/ - time_spec_t get_time_now(void){ - return _sdev->get_time_now(); - } - - void set_time_now(const time_spec_t &time_spec){ - return _sdev->set_time_now(time_spec); - } - - void set_time_next_pps(const time_spec_t &time_spec){ - return _sdev->set_time_next_pps(time_spec); - } - - void issue_stream_cmd(const stream_cmd_t &stream_cmd){ - return _sdev->issue_stream_cmd(stream_cmd); - } - - void set_clock_config(const clock_config_t &clock_config){ - return _sdev->set_clock_config(clock_config); - } - - /******************************************************************* - * RX methods - ******************************************************************/ - void set_rx_subdev_spec(const subdev_spec_t &spec){ - return _sdev->set_rx_subdev_spec(spec); - } - - subdev_spec_t get_rx_subdev_spec(void){ - return _sdev->get_rx_subdev_spec(); - } - - void set_rx_rate(double rate){ - return _sdev->set_rx_rate(rate); - } - - double get_rx_rate(void){ - return _sdev->get_rx_rate(); - } - - tune_result_t set_rx_freq(double target_freq){ - return _sdev->set_rx_freq(target_freq); - } - - //tune_result_t set_rx_freq(double target_freq, double lo_off){ - // return _sdev->set_rx_freq(target_freq, lo_off); - //} - - double get_rx_freq(void){ - return _sdev->get_rx_freq(); - } - - freq_range_t get_rx_freq_range(void){ - return _sdev->get_rx_freq_range(); - } - - void set_rx_gain(float gain){ - return _sdev->set_rx_gain(gain); - } - - float get_rx_gain(void){ - return _sdev->get_rx_gain(); - } - - gain_range_t get_rx_gain_range(void){ - return _sdev->get_rx_gain_range(); - } - - void set_rx_antenna(const std::string &ant){ - return _sdev->set_rx_antenna(ant); - } - - std::string get_rx_antenna(void){ - return _sdev->get_rx_antenna(); - } - - std::vector<std::string> get_rx_antennas(void){ - return _sdev->get_rx_antennas(); - } - - bool get_rx_lo_locked(void){ - return _sdev->get_rx_lo_locked(); - } - - float read_rssi(void){ - return _sdev->read_rssi(); - } - - dboard_iface::sptr get_rx_dboard_iface(void){ - return _sdev->get_rx_dboard_iface(); - } - - void set_rx_bandwidth(float bandwidth) { - return _sdev->set_rx_bandwidth(bandwidth); - } - - /******************************************************************* - * TX methods - ******************************************************************/ - void set_tx_subdev_spec(const subdev_spec_t &spec){ - return _sdev->set_tx_subdev_spec(spec); - } - - subdev_spec_t get_tx_subdev_spec(void){ - return _sdev->get_tx_subdev_spec(); - } - - void set_tx_rate(double rate){ - return _sdev->set_tx_rate(rate); - } - - double get_tx_rate(void){ - return _sdev->get_tx_rate(); - } - - tune_result_t set_tx_freq(double target_freq){ - return _sdev->set_tx_freq(target_freq); - } - - //tune_result_t set_tx_freq(double target_freq, double lo_off){ - // return _sdev->set_tx_freq(target_freq, lo_off); - //} - - double get_tx_freq(void){ - return _sdev->get_tx_freq(); - } - - freq_range_t get_tx_freq_range(void){ - return _sdev->get_tx_freq_range(); - } - - void set_tx_gain(float gain){ - return _sdev->set_tx_gain(gain); - } - - float get_tx_gain(void){ - return _sdev->get_tx_gain(); - } - - gain_range_t get_tx_gain_range(void){ - return _sdev->get_tx_gain_range(); - } - - void set_tx_antenna(const std::string &ant){ - return _sdev->set_tx_antenna(ant); - } - - std::string get_tx_antenna(void){ - return _sdev->get_tx_antenna(); - } - - std::vector<std::string> get_tx_antennas(void){ - return _sdev->get_tx_antennas(); - } - - bool get_tx_lo_locked(void){ - return _sdev->get_tx_lo_locked(); - } - - dboard_iface::sptr get_tx_dboard_iface(void){ - return _sdev->get_tx_dboard_iface(); - } - -private: - single_usrp::sptr _sdev; -}; - -}}} - -namespace uhd{ namespace usrp{ - -/*********************************************************************** - * The Make Function - **********************************************************************/ -inline simple_usrp::sptr simple_usrp::make(const device_addr_t &dev_addr){ - uhd::warning::post( - "The simple USRP interface has been deprecated.\n" - "Please switch to the single USRP interface.\n" - "#include <uhd/usrp/single_usrp.hpp>\n" - "single_usrp::sptr sdev = single_usrp::make(args);\n" - ); - return sptr(new simple_usrp_impl(dev_addr)); -} - -}} - -#endif /* INCLUDED_UHD_USRP_SIMPLE_USRP_HPP */ diff --git a/host/lib/gain_group.cpp b/host/lib/gain_group.cpp new file mode 100644 index 000000000..1be09dee2 --- /dev/null +++ b/host/lib/gain_group.cpp @@ -0,0 +1,149 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils/gain_group.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/utils/algorithm.hpp> +#include <uhd/utils/assert.hpp> +#include <boost/foreach.hpp> +#include <boost/bind.hpp> +#include <algorithm> +#include <vector> +#include <iostream> + +using namespace uhd; + +static const bool verbose = false; + +static bool compare_by_step_size( + const size_t &rhs, const size_t &lhs, std::vector<gain_fcns_t> &fcns +){ + return fcns.at(rhs).get_range().step > fcns.at(lhs).get_range().step; +} + +/*********************************************************************** + * gain group implementation + **********************************************************************/ +class gain_group_impl : public gain_group{ +public: + gain_group_impl(void){ + /*NOP*/ + } + + gain_range_t get_range(void){ + float overall_min = 0, overall_max = 0, overall_step = 0; + BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){ + const gain_range_t range = fcns.get_range(); + overall_min += range.min; + overall_max += range.max; + //the overall step is the min (zero is invalid, first run) + if (overall_step == 0) overall_step = range.step; + overall_step = std::min(overall_step, range.step); + } + return gain_range_t(overall_min, overall_max, overall_step); + } + + float get_value(void){ + float overall_gain = 0; + BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){ + overall_gain += fcns.get_value(); + } + return overall_gain; + } + + void set_value(float gain){ + std::vector<gain_fcns_t> all_fcns = get_all_fcns(); + if (all_fcns.size() == 0) return; //nothing to set! + + //get the max step size among the gains + float max_step = 0; + BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ + max_step = std::max(max_step, fcns.get_range().step); + } + + //create gain bucket to distribute power + std::vector<float> gain_bucket; + + //distribute power according to priority (round to max step) + float gain_left_to_distribute = gain; + BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ + const gain_range_t range = fcns.get_range(); + gain_bucket.push_back( + max_step*int(std::clip(gain_left_to_distribute, range.min, range.max)/max_step) + ); + gain_left_to_distribute -= gain_bucket.back(); + } + + //get a list of indexes sorted by step size large to small + std::vector<size_t> indexes_step_size_dec; + for (size_t i = 0; i < all_fcns.size(); i++){ + indexes_step_size_dec.push_back(i); + } + std::sort( + indexes_step_size_dec.begin(), indexes_step_size_dec.end(), + boost::bind(&compare_by_step_size, _1, _2, all_fcns) + ); + UHD_ASSERT_THROW( + all_fcns.at(indexes_step_size_dec.front()).get_range().step >= + all_fcns.at(indexes_step_size_dec.back()).get_range().step + ); + + //distribute the remainder (less than max step) + //fill in the largest step sizes first that are less than the remainder + BOOST_FOREACH(size_t i, indexes_step_size_dec){ + const gain_range_t range = all_fcns.at(i).get_range(); + float additional_gain = range.step*int( + std::clip(gain_bucket.at(i) + gain_left_to_distribute, range.min, range.max + )/range.step) - gain_bucket.at(i); + gain_bucket.at(i) += additional_gain; + gain_left_to_distribute -= additional_gain; + } + if (verbose) std::cout << "gain_left_to_distribute " << gain_left_to_distribute << std::endl; + + //now write the bucket out to the individual gain values + for (size_t i = 0; i < gain_bucket.size(); i++){ + if (verbose) std::cout << gain_bucket.at(i) << std::endl; + all_fcns.at(i).set_value(gain_bucket.at(i)); + } + } + + void register_fcns( + const gain_fcns_t &gain_fcns, size_t priority + ){ + _registry[priority].push_back(gain_fcns); + } + +private: + //! get the gain function sets in order (highest priority first) + std::vector<gain_fcns_t> get_all_fcns(void){ + std::vector<gain_fcns_t> all_fcns; + BOOST_FOREACH(ssize_t key, std::sorted(_registry.keys())){ + const std::vector<gain_fcns_t> &fcns = _registry[key]; + all_fcns.insert(all_fcns.begin(), fcns.begin(), fcns.end()); + } + return all_fcns; + } + + uhd::dict<size_t, std::vector<gain_fcns_t> > _registry; +}; + +/*********************************************************************** + * gain group factory function + **********************************************************************/ +gain_group::sptr gain_group::make(void){ + return sptr(new gain_group_impl()); +} diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt index a328fa033..ac051b843 100644 --- a/host/lib/ic_reg_maps/CMakeLists.txt +++ b/host/lib/ic_reg_maps/CMakeLists.txt @@ -80,6 +80,11 @@ LIBUHD_PYTHON_GEN_SOURCE( ) LIBUHD_PYTHON_GEN_SOURCE( + ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ads62p44_regs.py + ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ads62p44_regs.hpp + ) + +LIBUHD_PYTHON_GEN_SOURCE( ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_tuner_4937di5_regs.py ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/tuner_4937di5_regs.hpp ) diff --git a/host/lib/ic_reg_maps/gen_ads62p44_regs.py b/host/lib/ic_reg_maps/gen_ads62p44_regs.py new file mode 100755 index 000000000..f0a84d940 --- /dev/null +++ b/host/lib/ic_reg_maps/gen_ads62p44_regs.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_TMPL="""\ +######################################################################## +## address 0 +######################################################################## +reset 0[1] 0 +serial_readout 0[0] 0 +######################################################################## +## address 16 +######################################################################## +clkout_strength 16[6:7] 0 weaker=1, default=0, stronger=3 +######################################################################## +## address 17 +######################################################################## +dataout_strength 17[0:1] 0 weaker=1, default=0, stronger=3, maximum=2 +lvds_current 17[2:3] 0 3_5ma, 2_5ma, 4_5ma, 1_75ma +lvds_current_double 17[4:5] 0 default, dblclk, dbldataclock +######################################################################## +## address 18 +######################################################################## +lvds_clk_term 18[0:2] 0 none, 300, 180, 110, 150, 100, 81, 60 +lvds_data_term 18[3:5] 0 none, 300, 180, 110, 150, 100, 81, 60 +######################################################################## +## address 19 +######################################################################## +offset_freeze 19[4] 0 +######################################################################## +## address 20 +######################################################################## +power_down 20[0:2] 0 normal, a_dis, b_dis, ab_dis, global_pd, a_sby, b_sby, mux +ref_select 20[3] 0 internal, external +coarse_gain 20[4] 0 0db, 3_5db +output_interface 20[5] 0 cmos, lvds +override 20[7] 0 +######################################################################## +## address 22 +######################################################################## +test_patterns 22[0:2] 0 normal, zeros, ones, toggle, ramp, custom +lvds_bytewise 22[3] 0 +data_format 22[4] 0 twos_complement, binary +######################################################################## +## address 23 +######################################################################## +fine_gain 23[0:3] 0 +######################################################################## +## address 24 and 25 +######################################################################## +custom_low 24[0:7] 0 +custom_high 25[0:5] 0 +######################################################################## +## address 26 +######################################################################## +gain_correction 26[0:3] 0 +offset_tc 26[4:6] 0 1_1s, 0_55s, 0_27s, 0_13s, 2_15s, 4_3s +low_latency 26[7] 0 +######################################################################## +## address 27 +######################################################################## +decimation 27[0:2] 0 decimate_2, decimate_4, decimate_1, decimate_8 +odd_tap_enable 27[3] 0 +filter_enable 27[4] 0 +filter_coeff_sel 27[5] 0 predefined, userdefined +offset_enable 27[7] 0 +######################################################################## +## address 29 +######################################################################## +decimation_filter_bands 29[0:1] 0 +""" + +######################################################################## +# Template for methods in the body of the struct +######################################################################## +BODY_TMPL="""\ +boost::uint8_t get_reg(boost::uint8_t addr){ + boost::uint8_t reg = 0; + switch(addr){ + #for $addr in sorted(set(map(lambda r: r.get_addr(), $regs))) + case $addr: + #for $reg in filter(lambda r: r.get_addr() == addr, $regs) + reg |= (boost::uint8_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); + #end for + break; + #end for + } + return reg; +} + +boost::uint16_t get_write_reg(boost::uint8_t addr){ + return (boost::uint16_t(addr) << 8) | get_reg(addr); +} + +boost::uint16_t get_read_reg(boost::uint8_t addr){ + return (boost::uint16_t(addr) << 8) | (1 << 7); +} +""" + +if __name__ == '__main__': + import common; common.generate( + name='ads62p44_regs', + regs_tmpl=REGS_TMPL, + body_tmpl=BODY_TMPL, + file=__file__, + ) diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 89750f99d..6799ac7b2 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -27,23 +27,38 @@ using namespace uhd::transport; * Helper Functions **********************************************************************/ /*! - * A receive timeout for a socket: - * - * It seems that asio cannot have timeouts with synchronous io. - * However, we can implement a polling loop that will timeout. - * This is okay bacause this is the slow-path implementation. - * + * Wait for available data or timeout. * \param socket the asio socket - * \param timeout_ms the timeout in milliseconds + * \param timeout the timeout in seconds + * \return false for timeout, true for data */ -static void reasonable_recv_timeout( - boost::asio::ip::udp::socket &socket, size_t timeout_ms +static bool wait_available( + boost::asio::ip::udp::socket &socket, double timeout ){ - boost::asio::deadline_timer timer(socket.get_io_service()); - timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms)); - while (not (socket.available() or timer.expires_from_now().is_negative())){ + #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) + + //setup timeval for timeout + timeval tv; + tv.tv_sec = 0; + tv.tv_usec = long(timeout*1e6); + + //setup rset for timeout + fd_set rset; + FD_ZERO(&rset); + FD_SET(socket.native(), &rset); + + return ::select(socket.native()+1, &rset, NULL, NULL, &tv) > 0; + + #else /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ + + //FIXME: why does select fail on macintosh? + for (size_t i = 0; i < size_t(timeout*1e3); i++){ + if (socket.available()) return true; boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } + return false; + + #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ } /*********************************************************************** @@ -57,7 +72,7 @@ public: //send/recv size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, size_t); + size_t recv(const boost::asio::mutable_buffer &, double); private: boost::asio::ip::udp::socket *_socket; @@ -86,9 +101,8 @@ size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){ return _socket->send(boost::asio::buffer(buff)); } -size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ - reasonable_recv_timeout(*_socket, timeout_ms); - if (not _socket->available()) return 0; +size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ + if (not wait_available(*_socket, timeout)) return 0; return _socket->receive(boost::asio::buffer(buff)); } @@ -103,7 +117,7 @@ public: //send/recv size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, size_t); + size_t recv(const boost::asio::mutable_buffer &, double); private: boost::asio::ip::udp::socket *_socket; @@ -137,9 +151,8 @@ size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){ return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint); } -size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, size_t timeout_ms){ - reasonable_recv_timeout(*_socket, timeout_ms); - if (not _socket->available()) return 0; +size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ + if (not wait_available(*_socket, timeout)) return 0; boost::asio::ip::udp::endpoint sender_endpoint; return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint); } diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index ed29864e9..c758fa894 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -59,16 +59,23 @@ static const size_t DEFAULT_NUM_RECV_FRAMES = 32; #else static const size_t DEFAULT_NUM_RECV_FRAMES = MIN_RECV_SOCK_BUFF_SIZE/udp_simple::mtu; #endif + //The non-async send only ever requires a single frame //because the buffer will be committed before a new get. #ifdef USE_ASIO_ASYNC_SEND static const size_t DEFAULT_NUM_SEND_FRAMES = 32; #else -static const size_t DEFAULT_NUM_SEND_FRAMES = MIN_SEND_SOCK_BUFF_SIZE/udp_simple::mtu;; +static const size_t DEFAULT_NUM_SEND_FRAMES = MIN_SEND_SOCK_BUFF_SIZE/udp_simple::mtu; #endif -//a single concurrent thread for io_service seems to be the fastest +//The number of service threads to spawn for async ASIO: +//A single concurrent thread for io_service seems to be the fastest. +//Threads are disabled when no async implementations are enabled. +#if defined(USE_ASIO_ASYNC_RECV) || defined(USE_ASIO_ASYNC_SEND) static const size_t CONCURRENCY_HINT = 1; +#else +static const size_t CONCURRENCY_HINT = 0; +#endif /*********************************************************************** * Zero Copy UDP implementation with ASIO: @@ -86,11 +93,12 @@ public: const std::string &port, const device_addr_t &hints ): - _io_service(hints.cast<size_t>("concurrency_hint", CONCURRENCY_HINT)), _recv_frame_size(size_t(hints.cast<double>("recv_frame_size", udp_simple::mtu))), _num_recv_frames(size_t(hints.cast<double>("num_recv_frames", DEFAULT_NUM_RECV_FRAMES))), _send_frame_size(size_t(hints.cast<double>("send_frame_size", udp_simple::mtu))), - _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_SEND_FRAMES))) + _num_send_frames(size_t(hints.cast<double>("num_send_frames", DEFAULT_NUM_SEND_FRAMES))), + _concurrency_hint(hints.cast<size_t>("concurrency_hint", CONCURRENCY_HINT)), + _io_service(_concurrency_hint) { //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; @@ -129,7 +137,7 @@ public: //spawn the service threads that will run the io service _work = new asio::io_service::work(_io_service); //new work to delete later - for (size_t i = 0; i < CONCURRENCY_HINT; i++) _thread_group.create_thread( + for (size_t i = 0; i < _concurrency_hint; i++) _thread_group.create_thread( boost::bind(&udp_zero_copy_asio_impl::service, this) ); } @@ -292,12 +300,6 @@ public: size_t get_send_frame_size(void) const {return _send_frame_size;} private: - //asio guts -> socket and service - asio::ip::udp::socket *_socket; - asio::io_service _io_service; - asio::io_service::work *_work; - int _sock_fd; - //memory management -> buffers and fifos boost::thread_group _thread_group; boost::shared_array<char> _send_buffer, _recv_buffer; @@ -305,6 +307,13 @@ private: pending_buffs_type::sptr _pending_recv_buffs, _pending_send_buffs; const size_t _recv_frame_size, _num_recv_frames; const size_t _send_frame_size, _num_send_frames; + + //asio guts -> socket and service + size_t _concurrency_hint; + asio::io_service _io_service; + asio::ip::udp::socket *_socket; + asio::io_service::work *_work; + int _sock_fd; }; /*********************************************************************** diff --git a/host/lib/transport/vrt_packet_handler.hpp b/host/lib/transport/vrt_packet_handler.hpp index 939517411..278bcfeaa 100644 --- a/host/lib/transport/vrt_packet_handler.hpp +++ b/host/lib/transport/vrt_packet_handler.hpp @@ -318,7 +318,7 @@ template <typename T> UHD_INLINE T get_context_code( ){ //load the rest of the if_packet_info in here if_packet_info.num_payload_words32 = (num_samps*chans_per_otw_buff*otw_type.get_sample_size())/sizeof(boost::uint32_t); - if_packet_info.packet_count = state.next_packet_seq++; + if_packet_info.packet_count = state.next_packet_seq; //get send buffers for each channel managed_send_buffs_t send_buffs(buffs.size()/chans_per_otw_buff); @@ -345,6 +345,7 @@ template <typename T> UHD_INLINE T get_context_code( size_t num_bytes_total = (vrt_header_offset_words32+if_packet_info.num_packet_words32)*sizeof(boost::uint32_t); send_buffs[i]->commit(num_bytes_total); } + state.next_packet_seq++; //increment sequence after commits return num_samps; } @@ -387,10 +388,19 @@ template <typename T> UHD_INLINE T get_context_code( if_packet_info.sob = metadata.start_of_burst; if_packet_info.eob = metadata.end_of_burst; + //TODO remove this code when sample counts of zero are supported by hardware + std::vector<const void *> buffs_(buffs); + size_t total_num_samps_(total_num_samps); + if (total_num_samps == 0){ + static const boost::uint64_t zeros = 0; //max size of a host sample + buffs_ = std::vector<const void *>(buffs.size(), &zeros); + total_num_samps_ = 1; + } + return _send1( state, - buffs, 0, - std::min(total_num_samps, max_samples_per_packet), + buffs_, 0, + std::min(total_num_samps_, max_samples_per_packet), if_packet_info, io_type, otw_type, vrt_packer, diff --git a/host/lib/types.cpp b/host/lib/types.cpp index e5e6a2512..bea20a4aa 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -16,12 +16,12 @@ // #include <uhd/utils/assert.hpp> -#include <uhd/types/ranges.hpp> #include <uhd/types/tune_request.hpp> #include <uhd/types/tune_result.hpp> #include <uhd/types/clock_config.hpp> #include <uhd/types/stream_cmd.hpp> #include <uhd/types/metadata.hpp> +#include <uhd/types/ranges.hpp> #include <uhd/types/time_spec.hpp> #include <uhd/types/device_addr.hpp> #include <uhd/types/mac_addr.hpp> @@ -41,22 +41,10 @@ using namespace uhd; /*********************************************************************** - * ranges + * ranges template instantiation **********************************************************************/ -gain_range_t::gain_range_t(float min, float max, float step): - min(min), - max(max), - step(step) -{ - /* NOP */ -} - -freq_range_t::freq_range_t(double min, double max): - min(min), - max(max) -{ - /* NOP */ -} +template struct uhd::meta_range_t<float>; +template struct uhd::meta_range_t<double>; /*********************************************************************** * tune request diff --git a/host/lib/usrp/README b/host/lib/usrp/README new file mode 100644 index 000000000..c125d1dad --- /dev/null +++ b/host/lib/usrp/README @@ -0,0 +1,12 @@ +######################################################################## +# lib USRP directories: +######################################################################## + +dboard: + Daughterboard implementation code for all USRP daughterboards + +usrp1: + Implementation code for the USB-based USRP Classic motherboard. + +usrp2: + Implementation code for USRP2 and USRP-N2XX. diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index f03dd43d1..73f894374 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -106,6 +106,11 @@ UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ **********************************************************************/ basic_rx::basic_rx(ctor_args_t args, double max_freq) : rx_dboard_base(args){ _max_freq = max_freq; + + //set GPIOs to output 0x0000 to decrease noise pickup + this->get_iface()->set_pin_ctrl(dboard_iface::UNIT_RX, 0x0000); + this->get_iface()->set_gpio_ddr(dboard_iface::UNIT_RX, 0xFFFF); + this->get_iface()->write_gpio(dboard_iface::UNIT_RX, 0x0000); } basic_rx::~basic_rx(void){ diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 85251bdf9..7edc1822c 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -212,10 +212,10 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ //set defaults for LO, gains, and filter bandwidth _bandwidth = 33e6; - set_lo_freq(dbsrx_freq_range.min); + set_lo_freq(dbsrx_freq_range.start()); BOOST_FOREACH(const std::string &name, dbsrx_gain_ranges.keys()){ - set_gain(dbsrx_gain_ranges[name].min, name); + set_gain(dbsrx_gain_ranges[name].start(), name); } set_bandwidth(33e6); // default bandwidth from datasheet @@ -229,7 +229,7 @@ dbsrx::~dbsrx(void){ * Tuning **********************************************************************/ void dbsrx::set_lo_freq(double target_freq){ - target_freq = std::clip(target_freq, dbsrx_freq_range.min, dbsrx_freq_range.max); + target_freq = dbsrx_freq_range.clip(target_freq); double actual_freq=0.0, pfd_freq=0.0, ref_clock=0.0; int R=0, N=0, r=0, m=0; @@ -261,7 +261,7 @@ void dbsrx::set_lo_freq(double target_freq){ pfd_freq = ref_clock / R; //constrain the PFD frequency to specified range - if ((pfd_freq < dbsrx_pfd_freq_range.min) or (pfd_freq > dbsrx_pfd_freq_range.max)) continue; + if ((pfd_freq < dbsrx_pfd_freq_range.start()) or (pfd_freq > dbsrx_pfd_freq_range.stop())) continue; //compute N N = int(std::floor(target_freq/pfd_freq)); @@ -278,7 +278,7 @@ void dbsrx::set_lo_freq(double target_freq){ //Assert because we failed to find a suitable combination of ref_clock, R and N UHD_ASSERT_THROW(ref_clock <= 27.0e6 and ref_clock >= 0.0); UHD_ASSERT_THROW(ref_clock/m >= 1e6 and ref_clock/m <= 2.5e6); - UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.min) and (pfd_freq <= dbsrx_pfd_freq_range.max)); + UHD_ASSERT_THROW((pfd_freq >= dbsrx_pfd_freq_range.start()) and (pfd_freq <= dbsrx_pfd_freq_range.stop())); UHD_ASSERT_THROW((N >= 256) and (N <= 32768)); if(dbsrx_debug) std::cerr << boost::format( @@ -374,6 +374,9 @@ void dbsrx::set_lo_freq(double target_freq){ //update vco selection and check vtune send_reg(0x2, 0x2); read_reg(0x0, 0x0); + + //allow for setup time before checking condition again + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); } if(dbsrx_debug) std::cerr << boost::format( @@ -417,7 +420,7 @@ void dbsrx::set_lo_freq(double target_freq){ */ static int gain_to_gc2_vga_reg(float &gain){ int reg = 0; - gain = std::clip<float>(float(boost::math::iround(gain)), dbsrx_gain_ranges["GC2"].min, dbsrx_gain_ranges["GC2"].max); + gain = dbsrx_gain_ranges["GC2"].clip(gain); // Half dB steps from 0-5dB, 1dB steps from 5-24dB if (gain < 5) { @@ -443,11 +446,11 @@ static int gain_to_gc2_vga_reg(float &gain){ */ static float gain_to_gc1_rfvga_dac(float &gain){ //clip the input - gain = std::clip<float>(gain, dbsrx_gain_ranges["GC1"].min, dbsrx_gain_ranges["GC1"].max); + gain = dbsrx_gain_ranges["GC1"].clip(gain); //voltage level constants static const float max_volts = float(1.2), min_volts = float(2.7); - static const float slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].max; + static const float slope = (max_volts-min_volts)/dbsrx_gain_ranges["GC1"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; diff --git a/host/lib/usrp/dboard/db_dbsrx2.cpp b/host/lib/usrp/dboard/db_dbsrx2.cpp index 5a65e6123..cdafd6a78 100644 --- a/host/lib/usrp/dboard/db_dbsrx2.cpp +++ b/host/lib/usrp/dboard/db_dbsrx2.cpp @@ -195,15 +195,15 @@ dbsrx2::dbsrx2(ctor_args_t args) : rx_dboard_base(args){ //for (boost::uint8_t addr=0; addr<=12; addr++) this->send_reg(addr, addr); //set defaults for LO, gains - set_lo_freq(dbsrx2_freq_range.min); + set_lo_freq(dbsrx2_freq_range.start()); BOOST_FOREACH(const std::string &name, dbsrx2_gain_ranges.keys()){ - set_gain(dbsrx2_gain_ranges[name].min, name); + set_gain(dbsrx2_gain_ranges[name].start(), name); } set_bandwidth(40e6); // default bandwidth from datasheet get_locked(); - _max2112_write_regs.bbg = boost::math::iround(std::clip<float>(0, dbsrx2_gain_ranges["BBG"].min, dbsrx2_gain_ranges["BBG"].max)); + _max2112_write_regs.bbg = boost::math::iround(dbsrx2_gain_ranges["BBG"].start()); send_reg(0x9, 0x9); } @@ -270,7 +270,7 @@ void dbsrx2::set_lo_freq(double target_freq){ * \return 4 bit the register value */ static int gain_to_bbg_vga_reg(float &gain){ - int reg = boost::math::iround(std::clip<float>(gain, dbsrx2_gain_ranges["BBG"].min, dbsrx2_gain_ranges["BBG"].max)); + int reg = boost::math::iround(dbsrx2_gain_ranges["BBG"].clip(gain)); gain = float(reg); @@ -290,11 +290,11 @@ static int gain_to_bbg_vga_reg(float &gain){ */ static float gain_to_gc1_rfvga_dac(float &gain){ //clip the input - gain = std::clip<float>(gain, dbsrx2_gain_ranges["GC1"].min, dbsrx2_gain_ranges["GC1"].max); + gain = dbsrx2_gain_ranges["GC1"].clip(gain); //voltage level constants static const float max_volts = float(0.5), min_volts = float(2.7); - static const float slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].max; + static const float slope = (max_volts-min_volts)/dbsrx2_gain_ranges["GC1"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 152198c3a..74a9fb37b 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -93,9 +93,9 @@ public: void tx_set(const wax::obj &key, const wax::obj &val); private: - freq_range_t _freq_range; - uhd::dict<std::string, gain_range_t> _rx_gain_ranges; - uhd::dict<dboard_iface::unit_t, bool> _div2; + const freq_range_t _freq_range; + const uhd::dict<std::string, gain_range_t> _rx_gain_ranges; + const uhd::dict<dboard_iface::unit_t, bool> _div2; double _rx_lo_freq, _tx_lo_freq; std::string _rx_ant; uhd::dict<std::string, float> _rx_gains; @@ -168,19 +168,17 @@ rfx_xcvr::rfx_xcvr( ctor_args_t args, const freq_range_t &freq_range, bool rx_div2, bool tx_div2 -) : xcvr_dboard_base(args){ - _freq_range = freq_range; - _div2[dboard_iface::UNIT_RX] = rx_div2; - _div2[dboard_iface::UNIT_TX] = tx_div2; - - if(this->get_rx_id() == 0x0024) { //RFX400 - _rx_gain_ranges = rfx400_rx_gain_ranges; - } - else { - _rx_gain_ranges = rfx_rx_gain_ranges; - } - - +): + xcvr_dboard_base(args), + _freq_range(freq_range), + _rx_gain_ranges((get_rx_id() == 0x0024)? + rfx400_rx_gain_ranges : rfx_rx_gain_ranges + ), + _div2(map_list_of + (dboard_iface::UNIT_RX, rx_div2) + (dboard_iface::UNIT_TX, tx_div2) + ) +{ //enable the clocks that we need this->get_iface()->set_clock_enabled(dboard_iface::UNIT_TX, true); this->get_iface()->set_clock_enabled(dboard_iface::UNIT_RX, true); @@ -204,12 +202,12 @@ rfx_xcvr::rfx_xcvr( this->get_iface()->set_atr_reg(dboard_iface::UNIT_RX, dboard_iface::ATR_REG_FULL_DUPLEX, POWER_UP | ANT_RX2| MIXER_ENB); //set some default values - set_rx_lo_freq((_freq_range.min + _freq_range.max)/2.0); - set_tx_lo_freq((_freq_range.min + _freq_range.max)/2.0); + set_rx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); + set_tx_lo_freq((_freq_range.start() + _freq_range.stop())/2.0); set_rx_ant("RX2"); BOOST_FOREACH(const std::string &name, _rx_gain_ranges.keys()){ - set_rx_gain(_rx_gain_ranges[name].min, name); + set_rx_gain(_rx_gain_ranges[name].start(), name); } } @@ -265,7 +263,7 @@ void rfx_xcvr::set_rx_gain(float gain, const std::string &name){ assert_has(_rx_gain_ranges.keys(), name, "rfx rx gain name"); if(name == "PGA0"){ float dac_volts = rx_pga0_gain_to_dac_volts(gain, - (_rx_gain_ranges["PGA0"].max - _rx_gain_ranges["PGA0"].min)); + (_rx_gain_ranges["PGA0"].stop() - _rx_gain_ranges["PGA0"].start())); _rx_gains[name] = gain; //write the new voltage to the aux dac @@ -294,7 +292,7 @@ double rfx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, _freq_range.min, _freq_range.max); + target_freq = _freq_range.clip(target_freq); if (_div2[unit]) target_freq *= 2; //map prescalers to the register enums diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index 2873e3d54..17fdad74a 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -200,12 +200,12 @@ tvrx::tvrx(ctor_args_t args) : rx_dboard_base(args){ //send initial register settings if necessary //set default freq - _lo_freq = tvrx_freq_range.min + tvrx_if_freq; //init _lo_freq to a sane default - set_freq(tvrx_freq_range.min); + _lo_freq = tvrx_freq_range.start() + tvrx_if_freq; //init _lo_freq to a sane default + set_freq(tvrx_freq_range.start()); //set default gains BOOST_FOREACH(const std::string &name, get_tvrx_gain_ranges().keys()){ - set_gain(get_tvrx_gain_ranges()[name].min, name); + set_gain(get_tvrx_gain_ranges()[name].start(), name); } } @@ -219,7 +219,7 @@ tvrx::~tvrx(void){ static std::string get_band(double freq) { BOOST_FOREACH(const std::string &band, tvrx_freq_ranges.keys()) { - if(freq >= tvrx_freq_ranges[band].min && freq <= tvrx_freq_ranges[band].max){ + if(freq >= tvrx_freq_ranges[band].start() && freq <= tvrx_freq_ranges[band].stop()){ if(tvrx_debug) std::cout << "Band: " << band << std::endl; return band; } @@ -277,7 +277,7 @@ static double gain_interp(double gain, boost::array<double, 17> db_vector, boost static float rf_gain_to_voltage(float gain, double lo_freq){ //clip the input - gain = std::clip<float>(gain, get_tvrx_gain_ranges()["RF"].min, get_tvrx_gain_ranges()["RF"].max); + gain = get_tvrx_gain_ranges()["RF"].clip(gain); //first we need to find out what band we're in, because gains are different across different bands std::string band = get_band(lo_freq + tvrx_if_freq); @@ -305,7 +305,7 @@ static float rf_gain_to_voltage(float gain, double lo_freq){ static float if_gain_to_voltage(float gain){ //clip the input - gain = std::clip<float>(gain, get_tvrx_gain_ranges()["IF"].min, get_tvrx_gain_ranges()["IF"].max); + gain = get_tvrx_gain_ranges()["IF"].clip(gain); double gain_volts = gain_interp(gain, tvrx_if_gains_db, tvrx_gains_volts); double dac_volts = gain_volts / opamp_gain; @@ -337,7 +337,7 @@ void tvrx::set_gain(float gain, const std::string &name){ */ void tvrx::set_freq(double freq) { - freq = std::clip<double>(freq, tvrx_freq_range.min, tvrx_freq_range.max); + freq = tvrx_freq_range.clip(freq); std::string prev_band = get_band(_lo_freq - tvrx_if_freq); std::string new_band = get_band(freq); diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index d0359d124..168e1971c 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -131,7 +131,7 @@ void unknown_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ_RANGE: - val = freq_range_t(0, 0); + val = freq_range_t(0.0, 0.0); return; case SUBDEV_PROP_ANTENNA: @@ -233,7 +233,7 @@ void unknown_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_FREQ_RANGE: - val = freq_range_t(0, 0); + val = freq_range_t(0.0, 0.0); return; case SUBDEV_PROP_ANTENNA: diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 572f5de97..dd5bd600b 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -177,15 +177,15 @@ wbx_xcvr::wbx_xcvr(ctor_args_t args) : xcvr_dboard_base(args){ ) % RXIO_MASK % TXIO_MASK << std::endl; //set some default values - set_rx_lo_freq((wbx_freq_range.min + wbx_freq_range.max)/2.0); - set_tx_lo_freq((wbx_freq_range.min + wbx_freq_range.max)/2.0); + set_rx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); + set_tx_lo_freq((wbx_freq_range.start() + wbx_freq_range.stop())/2.0); set_rx_ant("RX2"); BOOST_FOREACH(const std::string &name, wbx_tx_gain_ranges.keys()){ - set_tx_gain(wbx_tx_gain_ranges[name].min, name); + set_tx_gain(wbx_tx_gain_ranges[name].start(), name); } BOOST_FOREACH(const std::string &name, wbx_rx_gain_ranges.keys()){ - set_rx_gain(wbx_rx_gain_ranges[name].min, name); + set_rx_gain(wbx_rx_gain_ranges[name].start(), name); } } @@ -198,33 +198,32 @@ wbx_xcvr::~wbx_xcvr(void){ **********************************************************************/ static int rx_pga0_gain_to_iobits(float &gain){ //clip the input - gain = std::clip<float>(gain, wbx_rx_gain_ranges["PGA0"].min, wbx_rx_gain_ranges["PGA0"].max); + gain = wbx_rx_gain_ranges["PGA0"].clip(gain); //convert to attenuation and update iobits for atr - float attn = wbx_rx_gain_ranges["PGA0"].max - gain; + float attn = wbx_rx_gain_ranges["PGA0"].stop() - gain; //calculate the attenuation - int attn_code = int(floor(attn*2)); + int attn_code = boost::math::iround(attn*2); int iobits = ((~attn_code) << RX_ATTN_SHIFT) & RX_ATTN_MASK; - if (wbx_debug) std::cerr << boost::format( "WBX Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x" ) % attn % attn_code % (iobits & RX_ATTN_MASK) % RX_ATTN_MASK << std::endl; //the actual gain setting - gain = wbx_rx_gain_ranges["PGA0"].max - float(attn_code)/2; + gain = wbx_rx_gain_ranges["PGA0"].stop() - float(attn_code)/2; return iobits; } static float tx_pga0_gain_to_dac_volts(float &gain){ //clip the input - gain = std::clip<float>(gain, wbx_tx_gain_ranges["PGA0"].min, wbx_tx_gain_ranges["PGA0"].max); + gain = wbx_tx_gain_ranges["PGA0"].clip(gain); //voltage level constants static const float max_volts = float(0.5), min_volts = float(1.4); - static const float slope = (max_volts-min_volts)/wbx_tx_gain_ranges["PGA0"].max; + static const float slope = (max_volts-min_volts)/wbx_tx_gain_ranges["PGA0"].stop(); //calculate the voltage for the aux dac float dac_volts = gain*slope + min_volts; @@ -328,7 +327,7 @@ double wbx_xcvr::set_lo_freq( ) % (target_freq/1e6) << std::endl; //clip the input - target_freq = std::clip(target_freq, wbx_freq_range.min, wbx_freq_range.max); + target_freq = wbx_freq_range.clip(target_freq); //map prescaler setting to mininmum integer divider (N) values (pg.18 prescaler) static const uhd::dict<int, int> prescaler_to_min_int_div = map_list_of diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index be0e42b92..a3a1e6242 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -72,8 +72,10 @@ using namespace boost::assign; **********************************************************************/ static const bool xcvr2450_debug = false; -static const freq_range_t xcvr_freq_range(2.4e9, 6.0e9); -static const freq_range_t xcvr_freq_band_seperation(2.5e9, 4.9e9); +static const freq_range_t xcvr_freq_range = list_of + (range_t<double>(2.4e9, 2.5e9)) + (range_t<double>(4.9e9, 6.0e9)) +; static const prop_names_t xcvr_antennas = list_of("J1")("J2"); @@ -82,7 +84,11 @@ static const uhd::dict<std::string, gain_range_t> xcvr_tx_gain_ranges = map_list ("BB", gain_range_t(0, 5, 1.5)) ; static const uhd::dict<std::string, gain_range_t> xcvr_rx_gain_ranges = map_list_of - ("LNA", gain_range_t(0, 30.5, 15)) + ("LNA", gain_range_t(list_of + (range_t<float>(0)) + (range_t<float>(15)) + (range_t<float>(30.5)) + )) ("VGA", gain_range_t(0, 62, 2.0)) ; @@ -212,10 +218,10 @@ xcvr2450::xcvr2450(ctor_args_t args) : xcvr_dboard_base(args){ set_rx_ant(xcvr_antennas.at(0)); set_tx_ant(xcvr_antennas.at(1)); BOOST_FOREACH(const std::string &name, xcvr_tx_gain_ranges.keys()){ - set_tx_gain(xcvr_tx_gain_ranges[name].min, name); + set_tx_gain(xcvr_tx_gain_ranges[name].start(), name); } BOOST_FOREACH(const std::string &name, xcvr_rx_gain_ranges.keys()){ - set_rx_gain(xcvr_rx_gain_ranges[name].min, name); + set_rx_gain(xcvr_rx_gain_ranges[name].start(), name); } } @@ -259,17 +265,9 @@ void xcvr2450::update_atr(void){ * Tuning **********************************************************************/ void xcvr2450::set_lo_freq(double target_freq){ - //clip for highband and lowband - if((target_freq > xcvr_freq_band_seperation.min) and (target_freq < xcvr_freq_band_seperation.max)){ - if(target_freq - xcvr_freq_band_seperation.min < xcvr_freq_band_seperation.max - target_freq){ - target_freq = xcvr_freq_band_seperation.min; - }else{ - target_freq = xcvr_freq_band_seperation.max; - } - } - //clip for max and min - target_freq = std::clip(target_freq, xcvr_freq_range.min, xcvr_freq_range.max); + //clip the input to the range + target_freq = xcvr_freq_range.clip(target_freq); //variables used in the calculation below double scaler = xcvr2450::is_highband(target_freq)? (4.0/5.0) : (4.0/3.0); diff --git a/host/lib/usrp/dsp_utils.cpp b/host/lib/usrp/dsp_utils.cpp index 10ae9a086..2553e4a25 100644 --- a/host/lib/usrp/dsp_utils.cpp +++ b/host/lib/usrp/dsp_utils.cpp @@ -109,9 +109,7 @@ boost::uint32_t dsp_type1::calc_iq_scale_word(unsigned rate){ return calc_iq_scale_word(scale, scale); } -boost::uint32_t dsp_type1::calc_stream_cmd_word( - const stream_cmd_t &stream_cmd, size_t num_samps_continuous -){ +boost::uint32_t dsp_type1::calc_stream_cmd_word(const stream_cmd_t &stream_cmd){ UHD_ASSERT_THROW(stream_cmd.num_samps <= 0x3fffffff); //setup the mode to instruction flags @@ -133,6 +131,6 @@ boost::uint32_t dsp_type1::calc_stream_cmd_word( word |= boost::uint32_t((stream_cmd.stream_now)? 1 : 0) << 31; word |= boost::uint32_t((inst_chain)? 1 : 0) << 30; word |= boost::uint32_t((inst_reload)? 1 : 0) << 29; - word |= (inst_samps)? stream_cmd.num_samps : ((inst_chain)? num_samps_continuous : 1); + word |= (inst_samps)? stream_cmd.num_samps : ((inst_chain)? 1 : 0); return word; } diff --git a/host/lib/usrp/mboard_eeprom.cpp b/host/lib/usrp/mboard_eeprom.cpp index 70f4664a0..a9270cda6 100644 --- a/host/lib/usrp/mboard_eeprom.cpp +++ b/host/lib/usrp/mboard_eeprom.cpp @@ -66,7 +66,7 @@ static const boost::uint8_t N100_EEPROM_ADDR = 0x50; static const uhd::dict<std::string, boost::uint8_t> USRP_N100_OFFSETS = boost::assign::map_list_of ("rev-lsb-msb", 0x00) ("mac-addr", 0x02) - ("ip-addr", 0x08) + ("ip-addr", 0x0C) //leave space here for other addresses (perhaps) ("serial", 0x18) ("name", 0x18 + SERIAL_LEN) @@ -141,7 +141,7 @@ static void store_n100(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ * Implementation of B000 load/store **********************************************************************/ static const boost::uint8_t B000_EEPROM_ADDR = 0x50; -static const size_t B000X_SERIAL_LEN = 8; +static const size_t B000_SERIAL_LEN = 8; static const uhd::dict<std::string, boost::uint8_t> USRP_B000_OFFSETS = boost::assign::map_list_of ("serial", 0xf8) @@ -151,7 +151,7 @@ static const uhd::dict<std::string, boost::uint8_t> USRP_B000_OFFSETS = boost::a static void load_b000(mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ //extract the serial mb_eeprom["serial"] = bytes_to_string(iface.read_eeprom( - B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], B000X_SERIAL_LEN + B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], B000_SERIAL_LEN )); //extract the name @@ -164,7 +164,7 @@ static void store_b000(const mboard_eeprom_t &mb_eeprom, i2c_iface &iface){ //store the serial if (mb_eeprom.has_key("serial")) iface.write_eeprom( B000_EEPROM_ADDR, USRP_B000_OFFSETS["serial"], - string_to_bytes(mb_eeprom["serial"], B000X_SERIAL_LEN) + string_to_bytes(mb_eeprom["serial"], B000_SERIAL_LEN) ); //store the name diff --git a/host/lib/usrp/usrp1/codec_ctrl.cpp b/host/lib/usrp/usrp1/codec_ctrl.cpp index 4aa730573..18f794632 100644 --- a/host/lib/usrp/usrp1/codec_ctrl.cpp +++ b/host/lib/usrp/usrp1/codec_ctrl.cpp @@ -160,19 +160,19 @@ usrp1_codec_ctrl_impl::~usrp1_codec_ctrl_impl(void) static const int mtpgw = 255; //maximum tx pga gain word void usrp1_codec_ctrl_impl::set_tx_pga_gain(float gain){ - int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); + int gain_word = int(mtpgw*(gain - tx_pga_gain_range.start())/(tx_pga_gain_range.stop() - tx_pga_gain_range.start())); _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); this->send_reg(16); } float usrp1_codec_ctrl_impl::get_tx_pga_gain(void){ - return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; + return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.stop() - tx_pga_gain_range.start())/mtpgw) + tx_pga_gain_range.start(); } static const int mrpgw = 0x14; //maximum rx pga gain word void usrp1_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ - int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); + int gain_word = int(mrpgw*(gain - rx_pga_gain_range.start())/(rx_pga_gain_range.stop() - rx_pga_gain_range.start())); gain_word = std::clip(gain_word, 0, mrpgw); switch(which){ case 'A': @@ -194,7 +194,7 @@ float usrp1_codec_ctrl_impl::get_rx_pga_gain(char which){ case 'B': gain_word = _ad9862_regs.rx_pga_b; break; default: UHD_THROW_INVALID_CODE_PATH(); } - return (gain_word*(rx_pga_gain_range.max - rx_pga_gain_range.min)/mrpgw) + rx_pga_gain_range.min; + return (gain_word*(rx_pga_gain_range.stop() - rx_pga_gain_range.start())/mrpgw) + rx_pga_gain_range.start(); } /*********************************************************************** diff --git a/host/lib/usrp/usrp2/CMakeLists.txt b/host/lib/usrp/usrp2/CMakeLists.txt index 078485d6a..f7984fce5 100644 --- a/host/lib/usrp/usrp2/CMakeLists.txt +++ b/host/lib/usrp/usrp2/CMakeLists.txt @@ -44,6 +44,8 @@ IF(ENABLE_USRP2) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dboard_iface.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/dsp_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/gps_ctrl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/mboard_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/serdes_ctrl.cpp @@ -53,6 +55,7 @@ IF(ENABLE_USRP2) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_impl.hpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp2/usrp2_regs.cpp ) ELSE(ENABLE_USRP2) MESSAGE(STATUS " Skipping USRP2 support.") diff --git a/host/lib/usrp/usrp2/clock_ctrl.cpp b/host/lib/usrp/usrp2/clock_ctrl.cpp index 232f3b32a..428d5539b 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.cpp +++ b/host/lib/usrp/usrp2/clock_ctrl.cpp @@ -18,6 +18,7 @@ #include "clock_ctrl.hpp" #include "ad9510_regs.hpp" #include "usrp2_regs.hpp" //spi slave constants +#include "usrp2_clk_regs.hpp" #include <uhd/utils/assert.hpp> #include <boost/cstdint.hpp> #include <boost/lexical_cast.hpp> @@ -32,9 +33,10 @@ class usrp2_clock_ctrl_impl : public usrp2_clock_ctrl{ public: usrp2_clock_ctrl_impl(usrp2_iface::sptr iface){ _iface = iface; + clk_regs = usrp2_clk_regs_t(_iface->get_rev()); _ad9510_regs.cp_current_setting = ad9510_regs_t::CP_CURRENT_SETTING_3_0MA; - this->write_reg(0x09); + this->write_reg(clk_regs.pll_3); // Setup the clock registers to 100MHz: // This was already done by the firmware (or the host couldnt communicate). @@ -44,20 +46,20 @@ public: _ad9510_regs.pll_power_down = ad9510_regs_t::PLL_POWER_DOWN_NORMAL; _ad9510_regs.prescaler_value = ad9510_regs_t::PRESCALER_VALUE_DIV2; - this->write_reg(0x0A); + this->write_reg(clk_regs.pll_4); _ad9510_regs.acounter = 0; - this->write_reg(0x04); + this->write_reg(clk_regs.acounter); _ad9510_regs.bcounter_msb = 0; _ad9510_regs.bcounter_lsb = 5; - this->write_reg(0x05); - this->write_reg(0x06); + this->write_reg(clk_regs.bcounter_msb); + this->write_reg(clk_regs.bcounter_lsb); _ad9510_regs.ref_counter_msb = 0; _ad9510_regs.ref_counter_lsb = 1; // r divider = 1 - this->write_reg(0x0B); - this->write_reg(0x0C); + this->write_reg(clk_regs.ref_counter_msb); + this->write_reg(clk_regs.ref_counter_lsb); /* regs will be updated in commands below */ @@ -84,16 +86,13 @@ public: } void enable_mimo_clock_out(bool enb){ - boost::uint16_t rev = boost::lexical_cast<boost::uint16_t>(_iface->mb_eeprom["rev"]); - boost::uint8_t rev_hi = boost::uint8_t(rev >> 8); - //calculate the low and high dividers size_t divider = size_t(this->get_master_clock_rate()/10e6); size_t high = divider/2; size_t low = divider - high; - switch(rev_hi){ - case 3: //clock 2 + switch(clk_regs.exp){ + case 2: //U2 rev 3 _ad9510_regs.power_down_lvpecl_out2 = enb? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; @@ -102,11 +101,9 @@ public: _ad9510_regs.divider_low_cycles_out2 = low - 1; _ad9510_regs.divider_high_cycles_out2 = high - 1; _ad9510_regs.bypass_divider_out2 = 0; - this->write_reg(0x3e); - this->write_reg(0x4c); break; - case 4: //clock 5 + case 5: //U2 rev 4 _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_LVDS; _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; @@ -114,14 +111,23 @@ public: _ad9510_regs.divider_low_cycles_out5 = low - 1; _ad9510_regs.divider_high_cycles_out5 = high - 1; _ad9510_regs.bypass_divider_out5 = 0; - this->write_reg(0x41); - this->write_reg(0x52); + break; + + case 6: //U2+ + _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_LVDS; + _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; + //set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out6 = low - 1; + _ad9510_regs.divider_high_cycles_out6 = high - 1; + _ad9510_regs.bypass_divider_out5 = 0; break; - //TODO FIXME do i want to throw, what about uninitialized boards? - //default: throw std::runtime_error("unknown rev hi in mboard eeprom"); - default: std::cerr << "unknown rev hi: " << rev_hi << std::endl; + default: + break; } + this->write_reg(clk_regs.output(clk_regs.exp)); + this->write_reg(clk_regs.div_lo(clk_regs.exp)); this->update_regs(); } @@ -130,7 +136,7 @@ public: _ad9510_regs.power_down_lvds_cmos_out7 = enb? 0 : 1; _ad9510_regs.lvds_cmos_select_out7 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT7_CMOS; _ad9510_regs.output_level_lvds_out7 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT7_1_75MA; - this->write_reg(0x43); + this->write_reg(clk_regs.output(clk_regs.rx_db)); this->update_regs(); } @@ -146,8 +152,8 @@ public: _ad9510_regs.divider_low_cycles_out7 = low - 1; _ad9510_regs.divider_high_cycles_out7 = high - 1; //write the registers - this->write_reg(0x56); - this->write_reg(0x57); + this->write_reg(clk_regs.div_lo(clk_regs.rx_db)); + this->write_reg(clk_regs.div_hi(clk_regs.rx_db)); this->update_regs(); } @@ -157,12 +163,22 @@ public: return rates; } - //uses output clock 6 (cmos) + //uses output clock 6 (cmos) on USRP2 and output clock 5 (cmos) on USRP2+ void enable_tx_dboard_clock(bool enb){ - _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; - _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; - this->write_reg(0x42); + switch(clk_regs.tx_db) { + case 5: //USRP2+ + _ad9510_regs.power_down_lvds_cmos_out5 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out5 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT5_CMOS; + _ad9510_regs.output_level_lvds_out5 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT5_1_75MA; + break; + case 6: //USRP2 + _ad9510_regs.power_down_lvds_cmos_out6 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out6 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT6_CMOS; + _ad9510_regs.output_level_lvds_out6 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT6_1_75MA; + break; + } + + this->write_reg(clk_regs.output(clk_regs.tx_db)); this->update_regs(); } @@ -174,18 +190,44 @@ public: //calculate the low and high dividers size_t high = divider/2; size_t low = divider - high; - //set the registers (divider - 1) - _ad9510_regs.divider_low_cycles_out6 = low - 1; - _ad9510_regs.divider_high_cycles_out6 = high - 1; + + switch(clk_regs.tx_db) { + case 5: //USRP2+ + _ad9510_regs.bypass_divider_out5 = (divider == 1)? 1 : 0; + _ad9510_regs.divider_low_cycles_out5 = low - 1; + _ad9510_regs.divider_high_cycles_out5 = high - 1; + break; + case 6: //USRP2 + //bypass when the divider ratio is one + _ad9510_regs.bypass_divider_out6 = (divider == 1)? 1 : 0; + //set the registers (divider - 1) + _ad9510_regs.divider_low_cycles_out6 = low - 1; + _ad9510_regs.divider_high_cycles_out6 = high - 1; + break; + } + //write the registers - this->write_reg(0x54); - this->write_reg(0x55); + this->write_reg(clk_regs.div_hi(clk_regs.tx_db)); + this->write_reg(clk_regs.div_lo(clk_regs.tx_db)); this->update_regs(); } std::vector<double> get_rates_tx_dboard_clock(void){ return get_rates_rx_dboard_clock(); //same master clock, same dividers... } + + void enable_test_clock(bool enb) { + _ad9510_regs.power_down_lvpecl_out0 = enb? + ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_NORMAL : + ad9510_regs_t::POWER_DOWN_LVPECL_OUT0_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out0 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT0_810MV; + _ad9510_regs.divider_low_cycles_out0 = 0; + _ad9510_regs.divider_high_cycles_out0 = 0; + _ad9510_regs.bypass_divider_out0 = 1; + this->write_reg(0x3c); + this->write_reg(0x48); + this->write_reg(0x49); + } /*! * If we are to use an external reference, enable the charge pump. @@ -197,7 +239,7 @@ public: ad9510_regs_t::CHARGE_PUMP_MODE_3STATE ; _ad9510_regs.pll_mux_control = ad9510_regs_t::PLL_MUX_CONTROL_DLD_HIGH; _ad9510_regs.pfd_polarity = ad9510_regs_t::PFD_POLARITY_POS; - this->write_reg(0x08); + this->write_reg(clk_regs.pll_2); this->update_regs(); } @@ -220,33 +262,46 @@ private: */ void update_regs(void){ _ad9510_regs.update_registers = 1; - this->write_reg(0x5a); + this->write_reg(clk_regs.update); } //uses output clock 3 (pecl) + //this is the same between USRP2 and USRP2+ and doesn't get a switch statement void enable_dac_clock(bool enb){ _ad9510_regs.power_down_lvpecl_out3 = (enb)? ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_NORMAL : ad9510_regs_t::POWER_DOWN_LVPECL_OUT3_SAFE_PD; _ad9510_regs.output_level_lvpecl_out3 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT3_810MV; _ad9510_regs.bypass_divider_out3 = 1; - this->write_reg(0x3F); - this->write_reg(0x4F); + this->write_reg(clk_regs.output(clk_regs.dac)); + this->write_reg(clk_regs.div_hi(clk_regs.dac)); this->update_regs(); } - //uses output clock 4 (lvds) + //uses output clock 4 (lvds) on USRP2 and output clock 2 (lvpecl) on USRP2+ void enable_adc_clock(bool enb){ - _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1; - _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; - _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; - _ad9510_regs.bypass_divider_out4 = 1; - this->write_reg(0x40); - this->write_reg(0x51); + switch(clk_regs.adc) { + case 2: + _ad9510_regs.power_down_lvpecl_out2 = enb? ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_NORMAL : ad9510_regs_t::POWER_DOWN_LVPECL_OUT2_SAFE_PD; + _ad9510_regs.output_level_lvpecl_out2 = ad9510_regs_t::OUTPUT_LEVEL_LVPECL_OUT2_500MV; + _ad9510_regs.bypass_divider_out2 = 1; + break; + case 4: + _ad9510_regs.power_down_lvds_cmos_out4 = enb? 0 : 1; + _ad9510_regs.lvds_cmos_select_out4 = ad9510_regs_t::LVDS_CMOS_SELECT_OUT4_LVDS; + _ad9510_regs.output_level_lvds_out4 = ad9510_regs_t::OUTPUT_LEVEL_LVDS_OUT4_1_75MA; + _ad9510_regs.bypass_divider_out4 = 1; + break; + } + + this->write_reg(clk_regs.output(clk_regs.adc)); + this->write_reg(clk_regs.div_hi(clk_regs.adc)); this->update_regs(); } - + usrp2_iface::sptr _iface; + + usrp2_clk_regs_t clk_regs; ad9510_regs_t _ad9510_regs; }; diff --git a/host/lib/usrp/usrp2/clock_ctrl.hpp b/host/lib/usrp/usrp2/clock_ctrl.hpp index 70a104a81..db6c52c83 100644 --- a/host/lib/usrp/usrp2/clock_ctrl.hpp +++ b/host/lib/usrp/usrp2/clock_ctrl.hpp @@ -83,6 +83,12 @@ public: * \param enb true to enable */ virtual void enable_external_ref(bool enb) = 0; + + /*! + * Enable/disable test clock output. + * \param enb true to enable + */ + virtual void enable_test_clock(bool enb) = 0; /*! * TODO other clock control api here.... diff --git a/host/lib/usrp/usrp2/codec_ctrl.cpp b/host/lib/usrp/usrp2/codec_ctrl.cpp index 32cc13ded..ad1ae1acb 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.cpp +++ b/host/lib/usrp/usrp2/codec_ctrl.cpp @@ -17,10 +17,12 @@ #include "codec_ctrl.hpp" #include "ad9777_regs.hpp" +#include "ads62p44_regs.hpp" #include "usrp2_regs.hpp" #include <boost/cstdint.hpp> #include <boost/foreach.hpp> #include <iostream> +#include <uhd/utils/exception.hpp> static const bool codec_ctrl_debug = false; @@ -57,7 +59,24 @@ public: } //power-up adc - _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_ON); + switch(_iface->get_rev()){ + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_ON); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.reset = 1; + this->send_ads62p44_reg(0x00); //issue a reset to the ADC + //everything else should be pretty much default, i think + //_ads62p44_regs.decimation = DECIMATION_DECIMATE_1; + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_NORMAL; + this->send_ads62p44_reg(0x14); + break; + + case usrp2_iface::USRP_NXXX: break; + } } ~usrp2_codec_ctrl_impl(void){ @@ -66,11 +85,62 @@ public: this->send_ad9777_reg(0); //power-down adc - _iface->poke32(U2_REG_MISC_CTRL_ADC, U2_FLAG_MISC_CTRL_ADC_OFF); + switch(_iface->get_rev()){ + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + _iface->poke32(_iface->regs.misc_ctrl_adc, U2_FLAG_MISC_CTRL_ADC_OFF); + break; + + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + //send a global power-down to the ADC here... it will get lifted on reset + _ads62p44_regs.power_down = ads62p44_regs_t::POWER_DOWN_GLOBAL_PD; + this->send_ads62p44_reg(0x14); + break; + + case usrp2_iface::USRP_NXXX: break; + } + } + + void set_rx_digital_gain(float gain) { //fine digital gain + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.fine_gain = int(gain/0.5); + this->send_ads62p44_reg(0x17); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } + } + + void set_rx_digital_fine_gain(float gain) { //gain correction + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.gain_correction = int(gain / 0.05); + this->send_ads62p44_reg(0x1A); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } + } + + void set_rx_analog_gain(bool gain) { //turns on/off analog 3.5dB preamp + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + _ads62p44_regs.coarse_gain = gain ? ads62p44_regs_t::COARSE_GAIN_3_5DB : ads62p44_regs_t::COARSE_GAIN_0DB; + this->send_ads62p44_reg(0x14); + break; + + default: UHD_THROW_INVALID_CODE_PATH(); + } } private: ad9777_regs_t _ad9777_regs; + ads62p44_regs_t _ads62p44_regs; usrp2_iface::sptr _iface; void send_ad9777_reg(boost::uint8_t addr){ @@ -81,6 +151,14 @@ private: reg, 16, false /*no rb*/ ); } + + void send_ads62p44_reg(boost::uint8_t addr) { + boost::uint16_t reg = _ads62p44_regs.get_write_reg(addr); + _iface->transact_spi( + SPI_SS_ADS62P44, spi_config_t::EDGE_FALL, + reg, 16, false /*no rb*/ + ); + } }; /*********************************************************************** diff --git a/host/lib/usrp/usrp2/codec_ctrl.hpp b/host/lib/usrp/usrp2/codec_ctrl.hpp index ad014e0e1..57a37b94b 100644 --- a/host/lib/usrp/usrp2/codec_ctrl.hpp +++ b/host/lib/usrp/usrp2/codec_ctrl.hpp @@ -33,6 +33,27 @@ public: */ static sptr make(usrp2_iface::sptr iface); + /*! + * Set the analog preamplifier on the USRP2+ ADC (ADS62P44). + * \param gain enable or disable the 3.5dB preamp + */ + + virtual void set_rx_analog_gain(bool gain) = 0; + + /*! + * Set the digital gain on the USRP2+ ADC (ADS62P44). + * \param gain from 0-6dB + */ + + virtual void set_rx_digital_gain(float gain) = 0; + + /*! + * Set the digital gain correction on the USRP2+ ADC (ADS62P44). + * \param gain from 0-0.5dB + */ + + virtual void set_rx_digital_fine_gain(float gain) = 0; + }; #endif /* INCLUDED_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/codec_impl.cpp b/host/lib/usrp/usrp2/codec_impl.cpp index fc917b102..e417bc340 100644 --- a/host/lib/usrp/usrp2/codec_impl.cpp +++ b/host/lib/usrp/usrp2/codec_impl.cpp @@ -17,10 +17,23 @@ #include "usrp2_impl.hpp" #include <uhd/usrp/codec_props.hpp> +#include <uhd/types/dict.hpp> +#include <uhd/types/ranges.hpp> #include <boost/bind.hpp> +#include <boost/assign/list_of.hpp> +#include <uhd/utils/assert.hpp> +#include <uhd/utils/exception.hpp> using namespace uhd; using namespace uhd::usrp; +using namespace boost::assign; + +//this only applies to USRP2P +static const uhd::dict<std::string, gain_range_t> codec_rx_gain_ranges = map_list_of + ("analog", gain_range_t(0, float(3.5), float(3.5))) + ("digital", gain_range_t(0, float(6.0), float(0.5))) + ("digital-fine", gain_range_t(0, float(0.5), float(0.05))); + /*********************************************************************** * Helper Methods @@ -40,12 +53,27 @@ void usrp2_mboard_impl::codec_init(void){ /*********************************************************************** * RX Codec Properties **********************************************************************/ -void usrp2_mboard_impl::rx_codec_get(const wax::obj &key, wax::obj &val){ +void usrp2_mboard_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as<codec_prop_t>()){ case CODEC_PROP_NAME: - val = std::string("usrp2 adc"); + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + val = _iface->get_cname() + " adc - ads62p44"; + break; + + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + val = _iface->get_cname() + " adc - ltc2284"; + break; + + case usrp2_iface::USRP_NXXX: + val = _iface->get_cname() + " adc - ??????"; + break; + } return; case CODEC_PROP_OTHERS: @@ -53,26 +81,79 @@ void usrp2_mboard_impl::rx_codec_get(const wax::obj &key, wax::obj &val){ return; case CODEC_PROP_GAIN_NAMES: - val = prop_names_t(); //no gain elements to be controlled + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + val = prop_names_t(codec_rx_gain_ranges.keys()); + return; + + default: val = prop_names_t(); + } + return; + + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + assert_has(_codec_rx_gains.keys(), key.name, "codec rx gain name"); + val = _codec_rx_gains[key.name]; return; + case CODEC_PROP_GAIN_RANGE: + assert_has(codec_rx_gain_ranges.keys(), key.name, "codec rx gain range name"); + val = codec_rx_gain_ranges[key.name]; + return; + default: UHD_THROW_PROP_GET_ERROR(); } } -void usrp2_mboard_impl::rx_codec_set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); +void usrp2_mboard_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as<codec_prop_t>()) { + case CODEC_PROP_GAIN_I: + case CODEC_PROP_GAIN_Q: + this->rx_codec_set_gain(val.as<float>(), key.name); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} + +/*********************************************************************** + * Helper function to set RX codec gain + ***********************************************************************/ + +void usrp2_mboard_impl::rx_codec_set_gain(float gain, const std::string &name){ + assert_has(codec_rx_gain_ranges.keys(), name, "codec rx gain name"); + + _codec_rx_gains[name] = gain; + + if(name == "analog") { + _codec_ctrl->set_rx_analog_gain(gain > 0); //just turn it on or off + return; + } + if(name == "digital") { + _codec_ctrl->set_rx_digital_gain(gain); + return; + } + if(name == "digital-fine") { + _codec_ctrl->set_rx_digital_fine_gain(gain); + return; + } + UHD_THROW_PROP_SET_ERROR(); } + /*********************************************************************** * TX Codec Properties **********************************************************************/ -void usrp2_mboard_impl::tx_codec_get(const wax::obj &key, wax::obj &val){ +void usrp2_mboard_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key switch(key.as<codec_prop_t>()){ case CODEC_PROP_NAME: - val = std::string("usrp2 dac - ad9777"); + val = _iface->get_cname() + " dac - ad9777"; return; case CODEC_PROP_OTHERS: diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp index fdfbf0d17..ab5f62355 100644 --- a/host/lib/usrp/usrp2/dboard_iface.cpp +++ b/host/lib/usrp/usrp2/dboard_iface.cpp @@ -180,8 +180,8 @@ void usrp2_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ //write the selection mux value to register switch(unit){ - case UNIT_RX: _iface->poke32(U2_REG_GPIO_RX_SEL, new_sels); return; - case UNIT_TX: _iface->poke32(U2_REG_GPIO_TX_SEL, new_sels); return; + case UNIT_RX: _iface->poke32(_iface->regs.gpio_rx_sel, new_sels); return; + case UNIT_TX: _iface->poke32(_iface->regs.gpio_tx_sel, new_sels); return; } } @@ -189,18 +189,18 @@ void usrp2_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ _ddr_shadow = \ (_ddr_shadow & ~(0xffff << unit_to_shift[unit])) | (boost::uint32_t(value) << unit_to_shift[unit]); - _iface->poke32(U2_REG_GPIO_DDR, _ddr_shadow); + _iface->poke32(_iface->regs.gpio_ddr, _ddr_shadow); } void usrp2_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ _gpio_shadow = \ (_gpio_shadow & ~(0xffff << unit_to_shift[unit])) | (boost::uint32_t(value) << unit_to_shift[unit]); - _iface->poke32(U2_REG_GPIO_IO, _gpio_shadow); + _iface->poke32(_iface->regs.gpio_io, _gpio_shadow); } boost::uint16_t usrp2_dboard_iface::read_gpio(unit_t unit){ - return boost::uint16_t(_iface->peek32(U2_REG_GPIO_IO) >> unit_to_shift[unit]); + return boost::uint16_t(_iface->peek32(_iface->regs.gpio_io) >> unit_to_shift[unit]); } void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ @@ -209,16 +209,16 @@ void usrp2_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t unit_t, uhd::dict<atr_reg_t, boost::uint32_t> > unit_to_atr_to_addr = map_list_of (UNIT_RX, map_list_of - (ATR_REG_IDLE, U2_REG_ATR_IDLE_RXSIDE) - (ATR_REG_TX_ONLY, U2_REG_ATR_INTX_RXSIDE) - (ATR_REG_RX_ONLY, U2_REG_ATR_INRX_RXSIDE) - (ATR_REG_FULL_DUPLEX, U2_REG_ATR_FULL_RXSIDE) + (ATR_REG_IDLE, _iface->regs.atr_idle_rxside) + (ATR_REG_TX_ONLY, _iface->regs.atr_intx_rxside) + (ATR_REG_RX_ONLY, _iface->regs.atr_inrx_rxside) + (ATR_REG_FULL_DUPLEX, _iface->regs.atr_full_rxside) ) (UNIT_TX, map_list_of - (ATR_REG_IDLE, U2_REG_ATR_IDLE_TXSIDE) - (ATR_REG_TX_ONLY, U2_REG_ATR_INTX_TXSIDE) - (ATR_REG_RX_ONLY, U2_REG_ATR_INRX_TXSIDE) - (ATR_REG_FULL_DUPLEX, U2_REG_ATR_FULL_TXSIDE) + (ATR_REG_IDLE, _iface->regs.atr_idle_txside) + (ATR_REG_TX_ONLY, _iface->regs.atr_intx_txside) + (ATR_REG_RX_ONLY, _iface->regs.atr_inrx_txside) + (ATR_REG_FULL_DUPLEX, _iface->regs.atr_full_txside) ) ; _iface->poke16(unit_to_atr_to_addr[unit][atr], value); @@ -238,8 +238,8 @@ void usrp2_dboard_iface::set_gpio_debug(unit_t unit, int which){ //write the selection mux value to register switch(unit){ - case UNIT_RX: _iface->poke32(U2_REG_GPIO_RX_SEL, new_sels); return; - case UNIT_TX: _iface->poke32(U2_REG_GPIO_TX_SEL, new_sels); return; + case UNIT_RX: _iface->poke32(_iface->regs.gpio_rx_sel, new_sels); return; + case UNIT_TX: _iface->poke32(_iface->regs.gpio_tx_sel, new_sels); return; } } diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index 540c9fefb..4192c4f78 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -64,7 +64,7 @@ void usrp2_mboard_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ //handle the get request conditioned on the key switch(key.as<dboard_prop_t>()){ case DBOARD_PROP_NAME: - val = std::string("usrp2 dboard (rx unit)"); + val = _iface->get_cname() + " dboard (rx unit)"; return; case DBOARD_PROP_SUBDEV: @@ -121,7 +121,7 @@ void usrp2_mboard_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ //handle the get request conditioned on the key switch(key.as<dboard_prop_t>()){ case DBOARD_PROP_NAME: - val = std::string("usrp2 dboard (tx unit)"); + val = _iface->get_cname() + " dboard (tx unit)"; return; case DBOARD_PROP_SUBDEV: diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp index 0c85e643f..77ed594f5 100644 --- a/host/lib/usrp/usrp2/dsp_impl.cpp +++ b/host/lib/usrp/usrp2/dsp_impl.cpp @@ -61,7 +61,7 @@ void usrp2_mboard_impl::ddc_get(const wax::obj &key_, wax::obj &val){ switch(key.as<dsp_prop_t>()){ case DSP_PROP_NAME: - val = std::string("usrp2 ddc0"); + val = _iface->get_cname() + " ddc0"; return; case DSP_PROP_OTHERS: @@ -95,7 +95,7 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as<double>(); - _iface->poke32(U2_REG_DSP_RX_FREQ, + _iface->poke32(_iface->regs.dsp_rx_freq, dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq()) ); _ddc_freq = new_freq; //shadow @@ -107,11 +107,11 @@ void usrp2_mboard_impl::ddc_set(const wax::obj &key_, const wax::obj &val){ _ddc_decim = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); //set the decimation - _iface->poke32(U2_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); + _iface->poke32(_iface->regs.dsp_rx_decim_rate, dsp_type1::calc_cic_filter_word(_ddc_decim)); //set the scaling static const boost::int16_t default_rx_scale_iq = 1024; - _iface->poke32(U2_REG_DSP_RX_SCALE_IQ, + _iface->poke32(_iface->regs.dsp_rx_scale_iq, dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) ); } @@ -144,7 +144,7 @@ void usrp2_mboard_impl::duc_get(const wax::obj &key_, wax::obj &val){ switch(key.as<dsp_prop_t>()){ case DSP_PROP_NAME: - val = std::string("usrp2 duc0"); + val = _iface->get_cname() + " duc0"; return; case DSP_PROP_OTHERS: @@ -178,7 +178,7 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){ case DSP_PROP_FREQ_SHIFT:{ double new_freq = val.as<double>(); - _iface->poke32(U2_REG_DSP_TX_FREQ, + _iface->poke32(_iface->regs.dsp_tx_freq, dsp_type1::calc_cordic_word_and_update(new_freq, get_master_clock_freq()) ); _duc_freq = new_freq; //shadow @@ -190,10 +190,10 @@ void usrp2_mboard_impl::duc_set(const wax::obj &key_, const wax::obj &val){ _duc_interp = pick_closest_rate(extact_rate, _allowed_decim_and_interp_rates); //set the interpolation - _iface->poke32(U2_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); + _iface->poke32(_iface->regs.dsp_tx_interp_rate, dsp_type1::calc_cic_filter_word(_duc_interp)); //set the scaling - _iface->poke32(U2_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); + _iface->poke32(_iface->regs.dsp_tx_scale_iq, dsp_type1::calc_iq_scale_word(_duc_interp)); } return; diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 4ff31ddfd..a9c39e650 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -33,8 +33,8 @@ extern "C" { #endif //fpga and firmware compatibility numbers -#define USRP2_FPGA_COMPAT_NUM 2 -#define USRP2_FW_COMPAT_NUM 6 +#define USRP2_FPGA_COMPAT_NUM 3 +#define USRP2_FW_COMPAT_NUM 7 //used to differentiate control packets over data port #define USRP2_INVALID_VRT_HEADER 0 @@ -52,6 +52,14 @@ extern "C" { #define USRP2_I2C_ADDR_TX_DB (USRP2_I2C_DEV_EEPROM | 0x4) #define USRP2_I2C_ADDR_RX_DB (USRP2_I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// +// EEPROM Layout +//////////////////////////////////////////////////////////////////////// +#define USRP2_EE_MBOARD_REV 0x00 //2 bytes, little-endian (historic, don't blame me) +#define USRP2_EE_MBOARD_MAC_ADDR 0x02 //6 bytes +#define USRP2_EE_MBOARD_IP_ADDR 0x0C //uint32, big-endian +#define USRP2_EE_MBOARD_BOOTLOADER_FLAGS 0xF7 + typedef enum{ USRP2_CTRL_ID_HUH_WHAT = ' ', //USRP2_CTRL_ID_FOR_SURE, //TODO error condition enums @@ -75,6 +83,12 @@ typedef enum{ USRP2_CTRL_ID_PEEK_AT_THIS_REGISTER_FOR_ME_BRO = 'r', USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE = 'R', + USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO = 'u', + USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE = 'U', + + USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO = 'v', + USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE = 'V', + USRP2_CTRL_ID_PEACE_OUT = '~' } usrp2_ctrl_id_t; @@ -115,6 +129,11 @@ typedef struct{ __stdint(uint32_t) datahi; __stdint(uint8_t) num_bytes; //1, 2, 4, 8 } poke_args; + struct { + __stdint(uint8_t) dev; + __stdint(uint8_t) bytes; + __stdint(uint8_t) data[20]; + } uart_args; } data; } usrp2_ctrl_data_t; diff --git a/host/lib/usrp/usrp2/gps_ctrl.cpp b/host/lib/usrp/usrp2/gps_ctrl.cpp new file mode 100644 index 000000000..2273b2cd9 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.cpp @@ -0,0 +1,207 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "gps_ctrl.hpp" +#include <uhd/utils/assert.hpp> +#include <boost/cstdint.hpp> +#include <string> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/thread.hpp> +#include <boost/algorithm/string/trim.hpp> +#include <boost/tokenizer.hpp> + +using namespace uhd; +using namespace boost::gregorian; +using namespace boost::posix_time; +using namespace boost::algorithm; + +/*! + * A usrp2 GPS control for Jackson Labs devices + */ + +//TODO: multiple baud rate support (requires mboard_impl changes for poking UART registers) +class usrp2_gps_ctrl_impl : public usrp2_gps_ctrl{ +public: + usrp2_gps_ctrl_impl(usrp2_iface::sptr iface){ + _iface = iface; + + std::string reply; + bool i_heard_some_nmea = false, i_heard_something_weird = false; + + gps_type = GPS_TYPE_NONE; + +// set_uart_baud_rate(GPS_UART, 115200); + //first we look for a Jackson Labs Firefly (since that's what we sell with the USRP2+...) + + _iface->read_uart(GPS_UART); //get whatever junk is in the rx buffer right now, and throw it away + _iface->write_uart(GPS_UART, "HAAAY GUYYYYS\n"); //to elicit a response from the Firefly + + //then we loop until we either timeout, or until we get a response that indicates we're a JL device + int timeout = GPS_TIMEOUT_TRIES; + while(timeout--) { + reply = safe_gps_read(); + if(trim_right_copy(reply) == "Command Error") { + gps_type = GPS_TYPE_JACKSON_LABS; + break; + } + else if(reply.substr(0, 3) == "$GP") i_heard_some_nmea = true; //but keep looking for that "Command Error" response + else if(reply.length() != 0) i_heard_something_weird = true; //probably wrong baud rate + } + + if((i_heard_some_nmea) && (gps_type != GPS_TYPE_JACKSON_LABS)) gps_type = GPS_TYPE_GENERIC_NMEA; + + //otherwise, we can try some other common baud rates looking to see if a GPS is connected (todo, later) + if((gps_type == GPS_TYPE_NONE) && i_heard_something_weird) { + std::cout << "Invalid reply, possible incorrect baud rate" << std::endl; + } + + bool found_gprmc = false; + + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: + std::cout << "Found a Jackson Labs GPS" << std::endl; + //issue some setup stuff so it spits out the appropriate data + //none of these should issue replies so we don't bother looking for them + //we have to sleep between commands because the JL device, despite not acking, takes considerable time to process each command. + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + _iface->write_uart(GPS_UART, "SYST:COMM:SER:ECHO OFF\n"); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + _iface->write_uart(GPS_UART, "SYST:COMM:SER:PRO OFF\n"); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + _iface->write_uart(GPS_UART, "GPS:GPGGA 0\n"); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + _iface->write_uart(GPS_UART, "GPS:GGAST 0\n"); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + _iface->write_uart(GPS_UART, "GPS:GPRMC 1\n"); + boost::this_thread::sleep(boost::posix_time::milliseconds(FIREFLY_STUPID_DELAY_MS)); + +// break; + + case GPS_TYPE_GENERIC_NMEA: + if(gps_type == GPS_TYPE_GENERIC_NMEA) std::cout << "Found a generic NMEA GPS device" << std::endl; + found_gprmc = false; + //here we loop around looking for a GPRMC packet. if we don't get one, we don't have a usable GPS. + timeout = GPS_TIMEOUT_TRIES; + while(timeout--) { + reply = safe_gps_read(); + if(reply.substr(0, 6) == "$GPRMC") { + found_gprmc = true; + break; + } + } + if(!found_gprmc) { + if(gps_type == GPS_TYPE_JACKSON_LABS) std::cout << "Firefly GPS not locked or warming up." << std::endl; + else std::cout << "GPS does not output GPRMC packets. Cannot retrieve time." << std::endl; + gps_type = GPS_TYPE_NONE; + } + break; + + case GPS_TYPE_NONE: + default: + break; + + } + + + } + + ~usrp2_gps_ctrl_impl(void){ + + } + + std::string safe_gps_read() { + std::string reply; + try { + reply = _iface->read_uart(GPS_UART); + //std::cerr << "Got reply from GPS: " << reply.c_str() << " with length = " << reply.length() << std::endl; + } catch (std::runtime_error err) { + if(err.what() != std::string("usrp2 no control response")) throw; //sorry can't cope with that + else { //we don't actually have a GPS installed + reply = std::string(); + } + } + return reply; + } + + ptime get_time(void) { + std::string reply; + ptime now; + boost::tokenizer<boost::escaped_list_separator<char> > tok(reply); + std::vector<std::string> toked; + int timeout = GPS_TIMEOUT_TRIES; + bool found_gprmc = false; + switch(gps_type) { + case GPS_TYPE_JACKSON_LABS: //deprecated in favor of a single NMEA parser + case GPS_TYPE_GENERIC_NMEA: + + while(timeout--) { + reply = safe_gps_read(); + if(reply.substr(0, 6) == "$GPRMC") { + found_gprmc = true; + break; + } + } + UHD_ASSERT_THROW(found_gprmc); + + tok.assign(reply); + toked.assign(tok.begin(), tok.end()); + + UHD_ASSERT_THROW(toked.size() == 11); //if it's not we got something weird in there + + now = ptime( date( + greg_year(boost::lexical_cast<int>(toked[8].substr(4, 2)) + 2000), //just trust me on this one + greg_month(boost::lexical_cast<int>(toked[8].substr(2, 2))), + greg_day(boost::lexical_cast<int>(toked[8].substr(0, 2))) + ), + hours( boost::lexical_cast<int>(toked[1].substr(0, 2))) + + minutes(boost::lexical_cast<int>(toked[1].substr(2, 2))) + + seconds(boost::lexical_cast<int>(toked[1].substr(4, 2))) + ); + break; + case GPS_TYPE_NONE: + default: + throw std::runtime_error("get_time(): Unsupported GPS or no GPS detected\n"); + break; + } + return now; + } + + bool gps_detected(void) { + return (gps_type != GPS_TYPE_NONE); + } + +private: + usrp2_iface::sptr _iface; + + enum { + GPS_TYPE_JACKSON_LABS, + GPS_TYPE_GENERIC_NMEA, + GPS_TYPE_NONE + } gps_type; + + static const int GPS_UART = 2; //TODO: this should be plucked from fw_common.h or memory_map.h or somewhere in common with the firmware + static const int GPS_TIMEOUT_TRIES = 5; + static const int FIREFLY_STUPID_DELAY_MS = 200; + +}; + +/*********************************************************************** + * Public make function for the GPS control + **********************************************************************/ +usrp2_gps_ctrl::sptr usrp2_gps_ctrl::make(usrp2_iface::sptr iface){ + return sptr(new usrp2_gps_ctrl_impl(iface)); +} diff --git a/host/lib/usrp/usrp2/gps_ctrl.hpp b/host/lib/usrp/usrp2/gps_ctrl.hpp new file mode 100644 index 000000000..5936a6fb6 --- /dev/null +++ b/host/lib/usrp/usrp2/gps_ctrl.hpp @@ -0,0 +1,53 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_GPS_CTRL_HPP +#define INCLUDED_GPS_CTRL_HPP + +#include "usrp2_iface.hpp" +#include <boost/shared_ptr.hpp> +#include <boost/utility.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> + +using namespace boost::posix_time; + +class usrp2_gps_ctrl : boost::noncopyable{ +public: + typedef boost::shared_ptr<usrp2_gps_ctrl> sptr; + + /*! + * Make a GPS config for Jackson Labs or generic NMEA GPS devices + */ + static sptr make(usrp2_iface::sptr iface); + + /*! + * Get the current GPS time and date + * \return current GPS time and date as boost::posix_time::ptime object + */ + virtual ptime get_time(void) = 0; + + /*! + * Tell you if there's a supported GPS connected or not + * \return true if a supported GPS is connected + */ + virtual bool gps_detected(void) = 0; + + //TODO: other fun things you can do with a GPS. + +}; + +#endif /* INCLUDED_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index 83b70bddc..f903a80f6 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -18,11 +18,11 @@ #include "../../transport/vrt_packet_handler.hpp" #include "usrp2_impl.hpp" #include "usrp2_regs.hpp" +#include <uhd/utils/byteswap.hpp> #include <uhd/utils/thread_priority.hpp> #include <uhd/transport/convert_types.hpp> #include <uhd/transport/alignment_buffer.hpp> #include <boost/format.hpp> -#include <boost/asio.hpp> //htonl and ntohl #include <boost/bind.hpp> #include <boost/thread.hpp> #include <iostream> @@ -32,7 +32,73 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET; +/*********************************************************************** + * constants + **********************************************************************/ +static const int underflow_flags = 0 + | async_metadata_t::EVENT_CODE_UNDERFLOW + | async_metadata_t::EVENT_CODE_UNDERFLOW_IN_PACKET +; + +static const size_t vrt_send_header_offset_words32 = 1; + +/*********************************************************************** + * flow control monitor for a single tx channel + * - the pirate thread calls update + * - the get send buffer calls check + **********************************************************************/ +class flow_control_monitor{ +public: + typedef boost::uint32_t seq_type; + typedef boost::shared_ptr<flow_control_monitor> sptr; + + /*! + * Make a new flow control monitor. + * \param max_seqs_out num seqs before throttling + */ + flow_control_monitor(seq_type max_seqs_out){ + _last_seq_out = 0; + _last_seq_ack = 0; + _max_seqs_out = max_seqs_out; + } + + /*! + * Check the flow control condition. + * \param seq the sequence to go out + * \param timeout the timeout in seconds + * \return false on timeout + */ + UHD_INLINE bool check_fc_condition(seq_type seq, double timeout){ + boost::this_thread::disable_interruption di; //disable because the wait can throw + boost::unique_lock<boost::mutex> lock(_fc_mutex); + _last_seq_out = seq; + return _fc_cond.timed_wait( + lock, + boost::posix_time::microseconds(long(timeout*1e6)), + boost::bind(&flow_control_monitor::ready, this) + ); + } + + /*! + * Update the flow control condition. + * \param seq the last sequence number to be ACK'd + */ + UHD_INLINE void update_fc_condition(seq_type seq){ + boost::unique_lock<boost::mutex> lock(_fc_mutex); + _last_seq_ack = seq; + lock.unlock(); + _fc_cond.notify_one(); + } + +private: + bool ready(void){ + return seq_type(_last_seq_out -_last_seq_ack) < _max_seqs_out; + } + + boost::mutex _fc_mutex; + boost::condition _fc_cond; + seq_type _last_seq_out, _last_seq_ack, _max_seqs_out; +}; /*********************************************************************** * io impl details (internal to this file) @@ -44,12 +110,14 @@ static const int underflow_flags = async_metadata_t::EVENT_CODE_UNDERFLOW | asyn struct usrp2_impl::io_impl{ typedef alignment_buffer<managed_recv_buffer::sptr, time_spec_t> alignment_buffer_type; - io_impl(size_t num_frames, size_t width): + io_impl(size_t num_recv_frames, size_t send_frame_size, size_t width): packet_handler_recv_state(width), - recv_pirate_booty(alignment_buffer_type::make(num_frames-3, width)), + recv_pirate_booty(alignment_buffer_type::make(num_recv_frames-3, width)), async_msg_fifo(bounded_buffer<async_metadata_t>::make(100/*messages deep*/)) { - /* NOP */ + for (size_t i = 0; i < width; i++) fc_mons.push_back( + flow_control_monitor::sptr(new flow_control_monitor(usrp2_impl::sram_bytes/send_frame_size)) + ); } ~io_impl(void){ @@ -63,6 +131,29 @@ struct usrp2_impl::io_impl{ return recv_pirate_booty->pop_elems_with_timed_wait(buffs, timeout); } + bool get_send_buffs( + const std::vector<zero_copy_if::sptr> &trans, + vrt_packet_handler::managed_send_buffs_t &buffs, + double timeout + ){ + UHD_ASSERT_THROW(trans.size() == buffs.size()); + + //calculate the flow control word + const boost::uint32_t fc_word32 = packet_handler_send_state.next_packet_seq; + + //grab a managed buffer for each index + for (size_t i = 0; i < buffs.size(); i++){ + if (not fc_mons[i]->check_fc_condition(fc_word32, timeout)) return false; + buffs[i] = trans[i]->get_send_buff(timeout); + if (not buffs[i].get()) return false; + buffs[i]->cast<boost::uint32_t *>()[0] = uhd::htonx(fc_word32); + } + return true; + } + + //flow control monitors + std::vector<flow_control_monitor::sptr> fc_mons; + //state management for the vrt packet handler code vrt_packet_handler::recv_state packet_handler_recv_state; vrt_packet_handler::send_state packet_handler_send_state; @@ -73,6 +164,7 @@ struct usrp2_impl::io_impl{ bool recv_pirate_crew_raiding; alignment_buffer_type::sptr recv_pirate_booty; bounded_buffer<async_metadata_t>::sptr async_msg_fifo; + boost::mutex spawn_mutex; }; /*********************************************************************** @@ -89,6 +181,8 @@ void usrp2_impl::io_impl::recv_pirate_loop( recv_pirate_crew_raiding = true; size_t next_packet_seq = 0; + spawn_mutex.unlock(); + while(recv_pirate_crew_raiding){ managed_recv_buffer::sptr buff = zc_if->get_recv_buff(); if (not buff.get()) continue; //ignore timeout/error buffers @@ -100,8 +194,27 @@ void usrp2_impl::io_impl::recv_pirate_loop( const boost::uint32_t *vrt_hdr = buff->cast<const boost::uint32_t *>(); vrt::if_hdr_unpack_be(vrt_hdr, if_packet_info); + //handle the rx data stream + if (if_packet_info.sid == usrp2_impl::RECV_SID and if_packet_info.packet_type == vrt::if_packet_info_t::PACKET_TYPE_DATA){ + //handle the packet count / sequence number + if (if_packet_info.packet_count != next_packet_seq){ + //std::cerr << "S" << (if_packet_info.packet_count - next_packet_seq)%16; + std::cerr << "O" << std::flush; //report overflow (drops in the kernel) + } + next_packet_seq = (if_packet_info.packet_count+1)%16; + + //extract the timespec and round to the nearest packet + UHD_ASSERT_THROW(if_packet_info.has_tsi and if_packet_info.has_tsf); + time_spec_t time( + time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), mboard->get_master_clock_freq() + ); + + //push the packet into the buffer with the new time + recv_pirate_booty->push_with_pop_on_full(buff, time, index); + } + //handle a tx async report message - if (if_packet_info.sid == 1 and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ + else if (if_packet_info.sid == usrp2_impl::ASYNC_SID and if_packet_info.packet_type != vrt::if_packet_info_t::PACKET_TYPE_DATA){ //fill in the async metadata async_metadata_t metadata; @@ -112,27 +225,21 @@ void usrp2_impl::io_impl::recv_pirate_loop( ); metadata.event_code = vrt_packet_handler::get_context_code<async_metadata_t::event_code_t>(vrt_hdr, if_packet_info); + //catch the flow control packets and react + if (metadata.event_code == 0){ + boost::uint32_t fc_word32 = (vrt_hdr + if_packet_info.num_header_words32)[1]; + this->fc_mons[index]->update_fc_condition(uhd::ntohx(fc_word32)); + continue; + } + //print the famous U, and push the metadata into the message queue if (metadata.event_code & underflow_flags) std::cerr << "U" << std::flush; + //else std::cout << "metadata.event_code " << metadata.event_code << std::endl; async_msg_fifo->push_with_pop_on_full(metadata); - continue; } - - //handle the packet count / sequence number - if (if_packet_info.packet_count != next_packet_seq){ - //std::cerr << "S" << (if_packet_info.packet_count - next_packet_seq)%16; - std::cerr << "O" << std::flush; //report overflow (drops in the kernel) + else{ + //TODO unknown received packet, may want to print error... } - next_packet_seq = (if_packet_info.packet_count+1)%16; - - //extract the timespec and round to the nearest packet - UHD_ASSERT_THROW(if_packet_info.has_tsi and if_packet_info.has_tsf); - time_spec_t time( - time_t(if_packet_info.tsi), size_t(if_packet_info.tsf), mboard->get_master_clock_freq() - ); - - //push the packet into the buffer with the new time - recv_pirate_booty->push_with_pop_on_full(buff, time, index); }catch(const std::exception &e){ std::cerr << "Error (usrp2 recv pirate loop): " << e.what() << std::endl; } @@ -143,30 +250,38 @@ void usrp2_impl::io_impl::recv_pirate_loop( * Helper Functions **********************************************************************/ void usrp2_impl::io_init(void){ - //send a small data packet so the usrp2 knows the udp source port - BOOST_FOREACH(zero_copy_if::sptr data_transport, _data_transports){ - managed_send_buffer::sptr send_buff = data_transport->get_send_buff(); - static const boost::uint32_t data = htonl(USRP2_INVALID_VRT_HEADER); - std::memcpy(send_buff->cast<void*>(), &data, sizeof(data)); - send_buff->commit(sizeof(data)); - //drain the recv buffers (may have junk) - while (data_transport->get_recv_buff().get()){}; - } - //the number of recv frames is the number for the first transport //the assumption is that all data transports should be identical - size_t num_frames = _data_transports.front()->get_num_recv_frames(); + const size_t num_recv_frames = _data_transports.front()->get_num_recv_frames(); + const size_t send_frame_size = _data_transports.front()->get_send_frame_size(); //create new io impl - _io_impl = UHD_PIMPL_MAKE(io_impl, (num_frames, _data_transports.size())); + _io_impl = UHD_PIMPL_MAKE(io_impl, (num_recv_frames, send_frame_size, _data_transports.size())); + + //TODO temporary fix for weird power up state, remove when FPGA fixed + { + //send an initial packet to all transports + tx_metadata_t md; md.end_of_burst = true; + this->send( + std::vector<const void *>(_data_transports.size(), NULL), 0, md, + io_type_t::COMPLEX_FLOAT32, device::SEND_MODE_ONE_PACKET, 0 + ); + } //create a new pirate thread for each zc if (yarr!!) for (size_t i = 0; i < _data_transports.size(); i++){ + //lock the unlocked mutex (non-blocking) + _io_impl->spawn_mutex.lock(); + //spawn a new pirate to plunder the recv booty _io_impl->recv_pirate_crew.create_thread(boost::bind( &usrp2_impl::io_impl::recv_pirate_loop, _io_impl.get(), _data_transports.at(i), _mboards.at(i), i )); + //block here until the spawned thread unlocks + _io_impl->spawn_mutex.lock(); + //exit loop iteration in an unlocked condition + _io_impl->spawn_mutex.unlock(); } } @@ -183,23 +298,10 @@ bool usrp2_impl::recv_async_msg( /*********************************************************************** * Send Data **********************************************************************/ -static bool get_send_buffs( - const std::vector<udp_zero_copy::sptr> &trans, - vrt_packet_handler::managed_send_buffs_t &buffs, - double timeout -){ - UHD_ASSERT_THROW(trans.size() == buffs.size()); - bool good = true; - for (size_t i = 0; i < buffs.size(); i++){ - buffs[i] = trans[i]->get_send_buff(timeout); - good = good and (buffs[i].get() != NULL); - } - return good; -} - size_t usrp2_impl::get_max_send_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + + vrt_send_header_offset_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used ; const size_t bpp = _data_transports.front()->get_send_frame_size() - hdr_size; @@ -218,8 +320,9 @@ size_t usrp2_impl::send( io_type, _tx_otw_type, //input and output types to convert _mboards.front()->get_master_clock_freq(), //master clock tick rate uhd::transport::vrt::if_hdr_pack_be, - boost::bind(&get_send_buffs, _data_transports, _1, timeout), - get_max_send_samps_per_packet() + boost::bind(&usrp2_impl::io_impl::get_send_buffs, _io_impl.get(), _data_transports, _1, timeout), + get_max_send_samps_per_packet(), + vrt_send_header_offset_words32 ); } diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index a6ca7f2d3..13d8b9856 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -21,12 +21,15 @@ #include <uhd/usrp/dsp_utils.hpp> #include <uhd/usrp/mboard_props.hpp> #include <uhd/utils/assert.hpp> +#include <uhd/utils/byteswap.hpp> #include <uhd/utils/algorithm.hpp> #include <boost/bind.hpp> #include <iostream> +#include <boost/date_time/posix_time/posix_time.hpp> using namespace uhd; using namespace uhd::usrp; +using namespace boost::posix_time; /*********************************************************************** * Structors @@ -34,16 +37,31 @@ using namespace uhd::usrp; usrp2_mboard_impl::usrp2_mboard_impl( size_t index, transport::udp_simple::sptr ctrl_transport, - size_t recv_frame_size + transport::zero_copy_if::sptr data_transport, + size_t recv_samps_per_packet, + const device_addr_t &flow_control_hints ): _index(index), - _recv_frame_size(recv_frame_size), _iface(usrp2_iface::make(ctrl_transport)) { + //Send a small data packet so the usrp2 knows the udp source port. + //This setup must happen before further initialization occurs + //or the async update packets will cause ICMP destination unreachable. + transport::managed_send_buffer::sptr send_buff = data_transport->get_send_buff(); + static const boost::uint32_t data[2] = { + uhd::htonx(boost::uint32_t(0 /* don't care seq num */)), + uhd::htonx(boost::uint32_t(USRP2_INVALID_VRT_HEADER)) + }; + std::memcpy(send_buff->cast<void*>(), &data, sizeof(data)); + send_buff->commit(sizeof(data)); + //contruct the interfaces to mboard perifs _clock_ctrl = usrp2_clock_ctrl::make(_iface); _codec_ctrl = usrp2_codec_ctrl::make(_iface); _serdes_ctrl = usrp2_serdes_ctrl::make(_iface); + //_gps_ctrl = usrp2_gps_ctrl::make(_iface); + + //if(_gps_ctrl->gps_detected()) std::cout << "GPS time: " << _gps_ctrl->get_time() << std::endl; //TODO move to dsp impl... //load the allowed decim/interp rates @@ -59,30 +77,42 @@ usrp2_mboard_impl::usrp2_mboard_impl( _allowed_decim_and_interp_rates.push_back(i); } + //Issue a stop streaming command (in case it was left running). //Since this command is issued before the networking is setup, //most if not all junk packets will never make it to the socket. this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS); - //init the rx control registers - _iface->poke32(U2_REG_RX_CTRL_NSAMPS_PER_PKT, _recv_frame_size); - _iface->poke32(U2_REG_RX_CTRL_NCHANNELS, 1); - _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); //reset - _iface->poke32(U2_REG_RX_CTRL_VRT_HEADER, 0 + //setup the vrt rx registers + _iface->poke32(_iface->regs.rx_ctrl_clear_overrun, 1); //reset + _iface->poke32(_iface->regs.rx_ctrl_nsamps_per_pkt, recv_samps_per_packet); + _iface->poke32(_iface->regs.rx_ctrl_nchannels, 1); + _iface->poke32(_iface->regs.rx_ctrl_vrt_header, 0 | (0x1 << 28) //if data with stream id | (0x1 << 26) //has trailer | (0x3 << 22) //integer time other | (0x1 << 20) //fractional time sample count ); - _iface->poke32(U2_REG_RX_CTRL_VRT_STREAM_ID, 0); - _iface->poke32(U2_REG_RX_CTRL_VRT_TRAILER, 0); - _iface->poke32(U2_REG_TIME64_TPS, size_t(get_master_clock_freq())); + _iface->poke32(_iface->regs.rx_ctrl_vrt_stream_id, usrp2_impl::RECV_SID); + _iface->poke32(_iface->regs.rx_ctrl_vrt_trailer, 0); + _iface->poke32(_iface->regs.time64_tps, size_t(get_master_clock_freq())); //init the tx control registers - _iface->poke32(U2_REG_TX_CTRL_NUM_CHAN, 0); //1 channel - _iface->poke32(U2_REG_TX_CTRL_CLEAR_STATE, 1); //reset - _iface->poke32(U2_REG_TX_CTRL_REPORT_SID, 1); //sid 1 (different from rx) - _iface->poke32(U2_REG_TX_CTRL_POLICY, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); + _iface->poke32(_iface->regs.tx_ctrl_clear_state, 1); //reset + _iface->poke32(_iface->regs.tx_ctrl_num_chan, 0); //1 channel + _iface->poke32(_iface->regs.tx_ctrl_report_sid, usrp2_impl::ASYNC_SID); + _iface->poke32(_iface->regs.tx_ctrl_policy, U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET); + + //setting the cycles per update + const double ups_per_sec = flow_control_hints.cast<double>("ups_per_sec", 100); + const size_t cycles_per_up = size_t(_clock_ctrl->get_master_clock_rate()/ups_per_sec); + _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, U2_FLAG_TX_CTRL_UP_ENB | cycles_per_up); + _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, 0); //cycles per update is disabled + + //setting the packets per update + const double ups_per_fifo = flow_control_hints.cast<double>("ups_per_fifo", 8); + const size_t packets_per_up = size_t(usrp2_impl::sram_bytes/ups_per_fifo/data_transport->get_send_frame_size()); + _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, U2_FLAG_TX_CTRL_UP_ENB | packets_per_up); //init the ddc init_ddc_config(); @@ -105,7 +135,8 @@ usrp2_mboard_impl::usrp2_mboard_impl( } usrp2_mboard_impl::~usrp2_mboard_impl(void){ - /* NOP */ + _iface->poke32(_iface->regs.tx_ctrl_cycles_per_up, 0); + _iface->poke32(_iface->regs.tx_ctrl_packets_per_up, 0); } /*********************************************************************** @@ -128,46 +159,60 @@ void usrp2_mboard_impl::update_clock_config(void){ switch(_clock_config.pps_source){ case clock_config_t::PPS_SMA: pps_flags |= U2_FLAG_TIME64_PPS_SMA; break; case clock_config_t::PPS_MIMO: pps_flags |= U2_FLAG_TIME64_PPS_MIMO; break; - default: throw std::runtime_error("usrp2: unhandled clock configuration pps source"); + default: throw std::runtime_error("unhandled clock configuration pps source"); } //translate pps polarity enums switch(_clock_config.pps_polarity){ case clock_config_t::PPS_POS: pps_flags |= U2_FLAG_TIME64_PPS_POSEDGE; break; case clock_config_t::PPS_NEG: pps_flags |= U2_FLAG_TIME64_PPS_NEGEDGE; break; - default: throw std::runtime_error("usrp2: unhandled clock configuration pps polarity"); + default: throw std::runtime_error("unhandled clock configuration pps polarity"); } //set the pps flags - _iface->poke32(U2_REG_TIME64_FLAGS, pps_flags); + _iface->poke32(_iface->regs.time64_flags, pps_flags); //clock source ref 10mhz - switch(_clock_config.ref_source){ - case clock_config_t::REF_INT : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x10); break; - case clock_config_t::REF_SMA : _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x1C); break; - case clock_config_t::REF_MIMO: _iface->poke32(U2_REG_MISC_CTRL_CLOCK, 0x15); break; - default: throw std::runtime_error("usrp2: unhandled clock configuration reference source"); - } + switch(_iface->get_rev()){ + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x12); break; + case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; + default: throw std::runtime_error("unhandled clock configuration reference source"); + } + _clock_ctrl->enable_external_ref(true); //USRP2P has an internal 10MHz TCXO + break; + + case usrp2_iface::USRP2_REV3: + case usrp2_iface::USRP2_REV4: + switch(_clock_config.ref_source){ + case clock_config_t::REF_INT : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x10); break; + case clock_config_t::REF_SMA : _iface->poke32(_iface->regs.misc_ctrl_clock, 0x1C); break; + case clock_config_t::REF_MIMO: _iface->poke32(_iface->regs.misc_ctrl_clock, 0x15); break; + default: throw std::runtime_error("unhandled clock configuration reference source"); + } + _clock_ctrl->enable_external_ref(_clock_config.ref_source != clock_config_t::REF_INT); + break; - //clock source ref 10mhz - bool use_external = _clock_config.ref_source != clock_config_t::REF_INT; - _clock_ctrl->enable_external_ref(use_external); + case usrp2_iface::USRP_NXXX: break; + } } void usrp2_mboard_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set the ticks - _iface->poke32(U2_REG_TIME64_TICKS, time_spec.get_tick_count(get_master_clock_freq())); + _iface->poke32(_iface->regs.time64_ticks, time_spec.get_tick_count(get_master_clock_freq())); //set the flags register boost::uint32_t imm_flags = (now)? U2_FLAG_TIME64_LATCH_NOW : U2_FLAG_TIME64_LATCH_NEXT_PPS; - _iface->poke32(U2_REG_TIME64_IMM, imm_flags); + _iface->poke32(_iface->regs.time64_imm, imm_flags); //set the seconds (latches in all 3 registers) - _iface->poke32(U2_REG_TIME64_SECS, boost::uint32_t(time_spec.get_full_secs())); + _iface->poke32(_iface->regs.time64_secs, boost::uint32_t(time_spec.get_full_secs())); } void usrp2_mboard_impl::handle_overflow(void){ - _iface->poke32(U2_REG_RX_CTRL_CLEAR_OVERRUN, 1); if (_continuous_streaming){ //re-issue the stream command if already continuous this->issue_ddc_stream_cmd(stream_cmd_t::STREAM_MODE_START_CONTINUOUS); } @@ -175,11 +220,9 @@ void usrp2_mboard_impl::handle_overflow(void){ void usrp2_mboard_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ _continuous_streaming = stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS; - _iface->poke32(U2_REG_RX_CTRL_STREAM_CMD, dsp_type1::calc_stream_cmd_word( - stream_cmd, _recv_frame_size - )); - _iface->poke32(U2_REG_RX_CTRL_TIME_SECS, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); - _iface->poke32(U2_REG_RX_CTRL_TIME_TICKS, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); + _iface->poke32(_iface->regs.rx_ctrl_stream_cmd, dsp_type1::calc_stream_cmd_word(stream_cmd)); + _iface->poke32(_iface->regs.rx_ctrl_time_secs, boost::uint32_t(stream_cmd.time_spec.get_full_secs())); + _iface->poke32(_iface->regs.rx_ctrl_time_ticks, stream_cmd.time_spec.get_tick_count(get_master_clock_freq())); } /*********************************************************************** @@ -189,11 +232,10 @@ static const std::string dboard_name = "0"; void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); - //handle the get request conditioned on the key switch(key.as<mboard_prop_t>()){ case MBOARD_PROP_NAME: - val = str(boost::format("usrp2 mboard%d - rev %s") % _index % _iface->mb_eeprom["rev"]); + val = _iface->get_cname() + " mboard"; return; case MBOARD_PROP_OTHERS: @@ -242,7 +284,7 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ case MBOARD_PROP_TIME_NOW:{ usrp2_iface::pair64 time64( - _iface->peek64(U2_REG_TIME64_SECS_RB, U2_REG_TIME64_TICKS_RB) + _iface->peek64(_iface->regs.time64_secs_rb, _iface->regs.time64_ticks_rb) ); val = time_spec_t( time64.first, time64.second, get_master_clock_freq() @@ -270,8 +312,7 @@ void usrp2_mboard_impl::get(const wax::obj &key_, wax::obj &val){ * MBoard Set Properties **********************************************************************/ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ - - //handle the get request conditioned on the key + //handle the set request conditioned on the key switch(key.as<mboard_prop_t>()){ case MBOARD_PROP_CLOCK_CONFIG: @@ -297,7 +338,7 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ //sanity check UHD_ASSERT_THROW(_rx_subdev_spec.size() == 1); //set the mux - _iface->poke32(U2_REG_DSP_RX_MUX, dsp_type1::calc_rx_mux_word( + _iface->poke32(_iface->regs.dsp_rx_mux, dsp_type1::calc_rx_mux_word( _dboard_manager->get_rx_subdev(_rx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() )); return; @@ -308,7 +349,7 @@ void usrp2_mboard_impl::set(const wax::obj &key, const wax::obj &val){ //sanity check UHD_ASSERT_THROW(_tx_subdev_spec.size() == 1); //set the mux - _iface->poke32(U2_REG_DSP_TX_MUX, dsp_type1::calc_tx_mux_word( + _iface->poke32(_iface->regs.dsp_tx_mux, dsp_type1::calc_tx_mux_word( _dboard_manager->get_tx_subdev(_tx_subdev_spec.front().sd_name)[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>() )); return; diff --git a/host/lib/usrp/usrp2/serdes_ctrl.cpp b/host/lib/usrp/usrp2/serdes_ctrl.cpp index e83dceb96..1cda22f45 100644 --- a/host/lib/usrp/usrp2/serdes_ctrl.cpp +++ b/host/lib/usrp/usrp2/serdes_ctrl.cpp @@ -27,11 +27,11 @@ class usrp2_serdes_ctrl_impl : public usrp2_serdes_ctrl{ public: usrp2_serdes_ctrl_impl(usrp2_iface::sptr iface){ _iface = iface; - _iface->poke32(U2_REG_MISC_CTRL_SERDES, U2_FLAG_MISC_CTRL_SERDES_ENABLE | U2_FLAG_MISC_CTRL_SERDES_RXEN); + _iface->poke32(_iface->regs.misc_ctrl_serdes, U2_FLAG_MISC_CTRL_SERDES_ENABLE | U2_FLAG_MISC_CTRL_SERDES_RXEN); } ~usrp2_serdes_ctrl_impl(void){ - _iface->poke32(U2_REG_MISC_CTRL_SERDES, 0); //power-down + _iface->poke32(_iface->regs.misc_ctrl_serdes, 0); //power-down } private: diff --git a/host/lib/usrp/usrp2/usrp2_clk_regs.hpp b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp new file mode 100644 index 000000000..6c46d0a35 --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_clk_regs.hpp @@ -0,0 +1,85 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#ifndef INCLUDED_USRP2_CLK_REGS_HPP +#define INCLUDED_USRP2_CLK_REGS_HPP + +#include "usrp2_iface.hpp" + +class usrp2_clk_regs_t { +public: + usrp2_clk_regs_t(void) { ; } + usrp2_clk_regs_t(usrp2_iface::rev_type rev) { + test = 0; + fpga = 1; + dac = 3; + + switch(rev) { + case usrp2_iface::USRP2_REV3: + exp = 2; + adc = 4; + serdes = 2; + tx_db = 6; + break; + case usrp2_iface::USRP2_REV4: + exp = 5; + adc = 4; + serdes = 2; + tx_db = 6; + break; + case usrp2_iface::USRP_N200: + case usrp2_iface::USRP_N210: + exp = 6; + adc = 2; + serdes = 4; + tx_db = 5; + break; + case usrp2_iface::USRP_NXXX: + //dont throw, it may be unitialized + break; + } + + rx_db = 7; + } + + static int output(int clknum) { return 0x3C + clknum; } + static int div_lo(int clknum) { return 0x48 + 2 * clknum; } + static int div_hi(int clknum) { return 0x49 + 2 * clknum; } + + const static int acounter = 0x04; + const static int bcounter_msb = 0x05; + const static int bcounter_lsb = 0x06; + const static int pll_1 = 0x07; + const static int pll_2 = 0x08; + const static int pll_3 = 0x09; + const static int pll_4 = 0x0A; + const static int ref_counter_msb = 0x0B; + const static int ref_counter_lsb = 0x0C; + const static int pll_5 = 0x0D; + const static int update = 0x5A; + + int test; + int fpga; + int adc; + int dac; + int serdes; + int exp; + int tx_db; + int rx_db; +}; + +#endif //INCLUDED_USRP2_CLK_REGS_HPP diff --git a/host/lib/usrp/usrp2/usrp2_iface.cpp b/host/lib/usrp/usrp2/usrp2_iface.cpp index 09f3432d6..81bc80c88 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.cpp +++ b/host/lib/usrp/usrp2/usrp2_iface.cpp @@ -17,6 +17,7 @@ #include "usrp2_regs.hpp" #include "usrp2_iface.hpp" +#include <uhd/utils/exception.hpp> #include <uhd/utils/assert.hpp> #include <uhd/types/dict.hpp> #include <boost/thread.hpp> @@ -24,6 +25,7 @@ #include <boost/asio.hpp> //used for htonl and ntohl #include <boost/assign/list_of.hpp> #include <boost/format.hpp> +#include <boost/tokenizer.hpp> #include <stdexcept> #include <algorithm> @@ -31,18 +33,6 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -/*! - * FIXME: large timeout, ethernet pause frames... - * - * Use a large timeout to work-around the fact that - * flow-control may throttle outgoing control packets - * due to its use of ethernet pause frames. - * - * This will be fixed when host-based flow control is implemented, - * along with larger incoming send buffers using the on-board SRAM. - */ -static const size_t CONTROL_TIMEOUT_MS = 3000; //3 seconds - class usrp2_iface_impl : public usrp2_iface{ public: /*********************************************************************** @@ -51,16 +41,28 @@ public: usrp2_iface_impl(udp_simple::sptr ctrl_transport){ _ctrl_transport = ctrl_transport; - //check the fpga compatibility number - const boost::uint32_t fpga_compat_num = this->peek32(U2_REG_COMPAT_NUM_RB); + mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); + switch(this->get_rev()){ + case USRP2_REV3: + case USRP2_REV4: + regs = usrp2_get_regs(false); + break; + + case USRP_NXXX: + case USRP_N200: + case USRP_N210: + regs = usrp2_get_regs(true); + break; + } + + //check the fpga compatibility number + const boost::uint32_t fpga_compat_num = this->peek32(this->regs.compat_num_rb); if (fpga_compat_num != USRP2_FPGA_COMPAT_NUM){ throw std::runtime_error(str(boost::format( "Expected fpga compatibility number %d, but got %d:\n" "The fpga build is not compatible with the host code build." ) % int(USRP2_FPGA_COMPAT_NUM) % fpga_compat_num)); } - - mb_eeprom = mboard_eeprom_t(*this, mboard_eeprom_t::MAP_N100); } ~usrp2_iface_impl(void){ @@ -175,6 +177,58 @@ public: } /*********************************************************************** + * UART + **********************************************************************/ + void write_uart(boost::uint8_t dev, const std::string &buf){ + //first tokenize the string into 20-byte substrings + boost::offset_separator f(20, 1, true, true); + boost::tokenizer<boost::offset_separator> tok(buf, f); + std::vector<std::string> queue(tok.begin(), tok.end()); + + BOOST_FOREACH(std::string item, queue) { + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_HEY_WRITE_THIS_UART_FOR_ME_BRO); + out_data.data.uart_args.dev = dev; + out_data.data.uart_args.bytes = item.size(); + + //limitation of uart transaction size + UHD_ASSERT_THROW(item.size() <= sizeof(out_data.data.uart_args.data)); + + //copy in the data + std::copy(item.begin(), item.end(), out_data.data.uart_args.data); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_MAN_I_TOTALLY_WROTE_THAT_UART_DUDE); + } + } + + std::string read_uart(boost::uint8_t dev){ + int readlen = 20; + std::string result; + while(readlen == 20) { //while we keep receiving full packets + //setup the out data + usrp2_ctrl_data_t out_data; + out_data.id = htonl(USRP2_CTRL_ID_SO_LIKE_CAN_YOU_READ_THIS_UART_BRO); + out_data.data.uart_args.dev = dev; + out_data.data.uart_args.bytes = 20; + + //limitation of uart transaction size + //UHD_ASSERT_THROW(num_bytes <= sizeof(out_data.data.uart_args.data)); + + //send and recv + usrp2_ctrl_data_t in_data = this->ctrl_send_and_recv(out_data); + UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_I_HELLA_READ_THAT_UART_DUDE); + readlen = in_data.data.uart_args.bytes; + + //copy out the data + result += std::string((const char *)in_data.data.uart_args.data, (size_t)readlen); + } + return result; + } + +/*********************************************************************** * Send/Recv over control **********************************************************************/ usrp2_ctrl_data_t ctrl_send_and_recv(const usrp2_ctrl_data_t &out_data){ @@ -190,7 +244,7 @@ public: boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem); while(true){ - size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem), CONTROL_TIMEOUT_MS); + size_t len = _ctrl_transport->recv(boost::asio::buffer(usrp2_ctrl_data_in_mem)); if(len >= sizeof(boost::uint32_t) and ntohl(ctrl_data_in->proto_ver) != USRP2_FW_COMPAT_NUM){ throw std::runtime_error(str(boost::format( "Expected protocol compatibility number %d, but got %d:\n" @@ -203,7 +257,28 @@ public: if (len == 0) break; //timeout //didnt get seq or bad packet, continue looking... } - throw std::runtime_error("usrp2 no control response"); + throw std::runtime_error(this->get_cname() + ": no control response"); + } + + rev_type get_rev(void){ + switch (boost::lexical_cast<boost::uint16_t>(mb_eeprom["rev"])){ + case 0x0300: return USRP2_REV3; + case 0x0400: return USRP2_REV4; + case 0x0A00: return USRP_N200; + case 0x0A01: return USRP_N210; + } + return USRP_NXXX; //unknown type + } + + const std::string get_cname(void){ + switch(this->get_rev()){ + case USRP2_REV3: return "USRP2-REV3"; + case USRP2_REV4: return "USRP2-REV4"; + case USRP_N200: return "USRP-N200"; + case USRP_N210: return "USRP-N210"; + case USRP_NXXX: return "USRP-N???"; + } + UHD_THROW_INVALID_CODE_PATH(); } private: @@ -242,7 +317,6 @@ private: UHD_ASSERT_THROW(ntohl(in_data.id) == USRP2_CTRL_ID_WOAH_I_DEFINITELY_PEEKED_IT_DUDE); return T(ntohl(in_data.data.poke_args.data)); } - }; /*********************************************************************** @@ -251,3 +325,4 @@ private: usrp2_iface::sptr usrp2_iface::make(udp_simple::sptr ctrl_transport){ return usrp2_iface::sptr(new usrp2_iface_impl(ctrl_transport)); } + diff --git a/host/lib/usrp/usrp2/usrp2_iface.hpp b/host/lib/usrp/usrp2/usrp2_iface.hpp index bf36cbf6e..af3ed6c9f 100644 --- a/host/lib/usrp/usrp2/usrp2_iface.hpp +++ b/host/lib/usrp/usrp2/usrp2_iface.hpp @@ -25,7 +25,9 @@ #include <boost/utility.hpp> #include <boost/cstdint.hpp> #include <utility> +#include <string> #include "fw_common.h" +#include "usrp2_regs.hpp" /*! * The usrp2 interface class: @@ -104,6 +106,30 @@ public: bool readback ) = 0; + virtual void write_uart(boost::uint8_t dev, const std::string &buf) = 0; + + virtual std::string read_uart(boost::uint8_t dev) = 0; + + //! The list of possible revision types + enum rev_type { + USRP2_REV3 = 3, + USRP2_REV4 = 4, + USRP_N200 = 200, + USRP_N210 = 210, + USRP_NXXX = 0 + }; + + //! Get the revision type for this device + virtual rev_type get_rev(void) = 0; + + //! Get the canonical name for this device + virtual const std::string get_cname(void) = 0; + + /*! + * Register map selected from USRP2/USRP2+. + */ + usrp2_regs_t regs; + //motherboard eeprom map structure uhd::usrp::mboard_eeprom_t mb_eeprom; }; diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 5f549c4fd..610e2f404 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -17,7 +17,7 @@ #include "usrp2_impl.hpp" #include <uhd/transport/if_addrs.hpp> -#include <uhd/transport/udp_simple.hpp> +#include <uhd/transport/udp_zero_copy.hpp> #include <uhd/usrp/device_props.hpp> #include <uhd/utils/assert.hpp> #include <uhd/utils/static.hpp> @@ -36,9 +36,6 @@ using namespace uhd::usrp; using namespace uhd::transport; namespace asio = boost::asio; -//! wait this long for a control response when discovering devices -static const size_t DISCOVERY_TIMEOUT_MS = 100; - /*********************************************************************** * Helper Functions **********************************************************************/ @@ -100,7 +97,7 @@ static uhd::device_addrs_t usrp2_find(const device_addr_t &hint){ boost::uint8_t usrp2_ctrl_data_in_mem[udp_simple::mtu]; //allocate max bytes for recv const usrp2_ctrl_data_t *ctrl_data_in = reinterpret_cast<const usrp2_ctrl_data_t *>(usrp2_ctrl_data_in_mem); while(true){ - size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem), DISCOVERY_TIMEOUT_MS); + size_t len = udp_transport->recv(asio::buffer(usrp2_ctrl_data_in_mem)); //std::cout << len << "\n"; if (len > offsetof(usrp2_ctrl_data_t, data) and ntohl(ctrl_data_in->id) == USRP2_CTRL_ID_WAZZUP_DUDE){ //make a boost asio ipv4 with the raw addr in host byte order @@ -147,7 +144,7 @@ static device::sptr usrp2_make(const device_addr_t &device_addr){ //create a ctrl and data transport for each address std::vector<udp_simple::sptr> ctrl_transports; - std::vector<udp_zero_copy::sptr> data_transports; + std::vector<zero_copy_if::sptr> data_transports; BOOST_FOREACH(const std::string &addr, std::split_string(device_addr["addr"])){ ctrl_transports.push_back(udp_simple::make_connected( @@ -160,7 +157,7 @@ static device::sptr usrp2_make(const device_addr_t &device_addr){ //create the usrp2 implementation guts return device::sptr( - new usrp2_impl(ctrl_transports, data_transports) + new usrp2_impl(ctrl_transports, data_transports, device_addr) ); } @@ -173,7 +170,8 @@ UHD_STATIC_BLOCK(register_usrp2_device){ **********************************************************************/ usrp2_impl::usrp2_impl( std::vector<udp_simple::sptr> ctrl_transports, - std::vector<udp_zero_copy::sptr> data_transports + std::vector<zero_copy_if::sptr> data_transports, + const device_addr_t &flow_control_hints ): _data_transports(data_transports) { @@ -192,7 +190,9 @@ usrp2_impl::usrp2_impl( //create a new mboard handler for each control transport for(size_t i = 0; i < ctrl_transports.size(); i++){ _mboards.push_back(usrp2_mboard_impl::sptr(new usrp2_mboard_impl( - i, ctrl_transports[i], this->get_max_recv_samps_per_packet() + i, ctrl_transports[i], data_transports[i], + this->get_max_recv_samps_per_packet(), + flow_control_hints ))); //use an empty name when there is only one mboard std::string name = (ctrl_transports.size() > 1)? boost::lexical_cast<std::string>(i) : ""; @@ -217,8 +217,8 @@ void usrp2_impl::get(const wax::obj &key_, wax::obj &val){ //handle the get request conditioned on the key switch(key.as<device_prop_t>()){ case DEVICE_PROP_NAME: - if (_mboards.size() > 1) val = std::string("usrp2 mimo device"); - else val = std::string("usrp2 device"); + if (_mboards.size() > 1) val = std::string("USRP-NXXX mimo device"); + else val = std::string("USRP-NXXX device"); return; case DEVICE_PROP_MBOARD: diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp index 71f52878c..aa8eb0155 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.hpp +++ b/host/lib/usrp/usrp2/usrp2_impl.hpp @@ -21,6 +21,7 @@ #include "usrp2_iface.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" +#include "gps_ctrl.hpp" #include "serdes_ctrl.hpp" #include <uhd/device.hpp> #include <uhd/utils/pimpl.hpp> @@ -84,7 +85,9 @@ public: usrp2_mboard_impl( size_t index, uhd::transport::udp_simple::sptr, - size_t recv_frame_size + uhd::transport::zero_copy_if::sptr, + size_t recv_samps_per_packet, + const uhd::device_addr_t &flow_control_hints ); ~usrp2_mboard_impl(void); @@ -96,7 +99,6 @@ public: private: size_t _index; - const size_t _recv_frame_size; bool _continuous_streaming; //interfaces @@ -104,6 +106,7 @@ private: usrp2_clock_ctrl::sptr _clock_ctrl; usrp2_codec_ctrl::sptr _codec_ctrl; usrp2_serdes_ctrl::sptr _serdes_ctrl; + usrp2_gps_ctrl::sptr _gps_ctrl; //properties for this mboard void get(const wax::obj &, wax::obj &); @@ -130,6 +133,9 @@ private: wax_obj_proxy::sptr _rx_codec_proxy; wax_obj_proxy::sptr _tx_codec_proxy; + void rx_codec_set_gain(float, const std::string &); + uhd::dict<std::string, float> _codec_rx_gains; + //properties interface for rx dboard void rx_dboard_get(const wax::obj &, wax::obj &); void rx_dboard_set(const wax::obj &, const wax::obj &); @@ -173,14 +179,20 @@ private: */ class usrp2_impl : public uhd::device{ public: + static const size_t sram_bytes = size_t(1 << 20); + static const boost::uint32_t RECV_SID = 1; + static const boost::uint32_t ASYNC_SID = 2; + /*! * Create a new usrp2 impl base. * \param ctrl_transports the udp transports for control * \param data_transports the udp transports for data + * \param flow_control_hints optional flow control params */ usrp2_impl( std::vector<uhd::transport::udp_simple::sptr> ctrl_transports, - std::vector<uhd::transport::udp_zero_copy::sptr> data_transports + std::vector<uhd::transport::zero_copy_if::sptr> data_transports, + const uhd::device_addr_t &flow_control_hints ); ~usrp2_impl(void); @@ -210,7 +222,7 @@ private: uhd::dict<std::string, usrp2_mboard_impl::sptr> _mboard_dict; //io impl methods and members - std::vector<uhd::transport::udp_zero_copy::sptr> _data_transports; + std::vector<uhd::transport::zero_copy_if::sptr> _data_transports; uhd::otw_type_t _rx_otw_type, _tx_otw_type; UHD_PIMPL_DECL(io_impl) _io_impl; void io_init(void); diff --git a/host/lib/usrp/usrp2/usrp2_regs.cpp b/host/lib/usrp/usrp2/usrp2_regs.cpp new file mode 100644 index 000000000..dd0433816 --- /dev/null +++ b/host/lib/usrp/usrp2/usrp2_regs.cpp @@ -0,0 +1,102 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include "usrp2_regs.hpp" +#include "usrp2_iface.hpp" + +int sr_addr(int misc_output_base, int sr) { + return misc_output_base + 4 * sr; +} + +usrp2_regs_t usrp2_get_regs(bool use_n2xx_map) { + + //how about you just make this dependent on hw_rev instead of doing the init before main, and give up the const globals, since the application won't ever need both. + const int misc_output_base = (use_n2xx_map) ? USRP2P_MISC_OUTPUT_BASE : USRP2_MISC_OUTPUT_BASE, + gpio_base = (use_n2xx_map) ? USRP2P_GPIO_BASE : USRP2_GPIO_BASE, + atr_base = (use_n2xx_map) ? USRP2P_ATR_BASE : USRP2_ATR_BASE, + bp_base = (use_n2xx_map) ? USRP2P_BP_STATUS_BASE : USRP2_BP_STATUS_BASE; + + usrp2_regs_t x; + x.sr_misc = 0; + x.sr_tx_prot_eng = 32; + x.sr_rx_prot_eng = 48; + x.sr_buffer_pool_ctrl = 64; + x.sr_udp_sm = 96; + x.sr_tx_dsp = 208; + x.sr_tx_ctrl = 224; + x.sr_rx_dsp = 160; + x.sr_rx_ctrl = 176; + x.sr_time64 = 192; + x.sr_simtimer = 198; + x.sr_last = 255; + x.misc_ctrl_clock = sr_addr(misc_output_base, 0); + x.misc_ctrl_serdes = sr_addr(misc_output_base, 1); + x.misc_ctrl_adc = sr_addr(misc_output_base, 2); + x.misc_ctrl_leds = sr_addr(misc_output_base, 3); + x.misc_ctrl_phy = sr_addr(misc_output_base, 4); + x.misc_ctrl_dbg_mux = sr_addr(misc_output_base, 5); + x.misc_ctrl_ram_page = sr_addr(misc_output_base, 6); + x.misc_ctrl_flush_icache = sr_addr(misc_output_base, 7); + x.misc_ctrl_led_src = sr_addr(misc_output_base, 8); + x.time64_secs = sr_addr(misc_output_base, x.sr_time64 + 0); + x.time64_ticks = sr_addr(misc_output_base, x.sr_time64 + 1); + x.time64_flags = sr_addr(misc_output_base, x.sr_time64 + 2); + x.time64_imm = sr_addr(misc_output_base, x.sr_time64 + 3); + x.time64_tps = sr_addr(misc_output_base, x.sr_time64 + 4); + x.time64_secs_rb = bp_base + 4*10; + x.time64_ticks_rb = bp_base + 4*11; + x.compat_num_rb = bp_base + 4*12; + x.dsp_tx_freq = sr_addr(misc_output_base, x.sr_tx_dsp + 0); + x.dsp_tx_scale_iq = sr_addr(misc_output_base, x.sr_tx_dsp + 1); + x.dsp_tx_interp_rate = sr_addr(misc_output_base, x.sr_tx_dsp + 2); + x.dsp_tx_mux = sr_addr(misc_output_base, x.sr_tx_dsp + 4); + x.dsp_rx_freq = sr_addr(misc_output_base, x.sr_rx_dsp + 0); + x.dsp_rx_scale_iq = sr_addr(misc_output_base, x.sr_rx_dsp + 1); + x.dsp_rx_decim_rate = sr_addr(misc_output_base, x.sr_rx_dsp + 2); + x.dsp_rx_dcoffset_i = sr_addr(misc_output_base, x.sr_rx_dsp + 3); + x.dsp_rx_dcoffset_q = sr_addr(misc_output_base, x.sr_rx_dsp + 4); + x.dsp_rx_mux = sr_addr(misc_output_base, x.sr_rx_dsp + 5); + x.gpio_io = gpio_base + 0; + x.gpio_ddr = gpio_base + 4; + x.gpio_tx_sel = gpio_base + 8; + x.gpio_rx_sel = gpio_base + 12; + x.atr_idle_txside = atr_base + 0; + x.atr_idle_rxside = atr_base + 2; + x.atr_intx_txside = atr_base + 4; + x.atr_intx_rxside = atr_base + 6; + x.atr_inrx_txside = atr_base + 8; + x.atr_inrx_rxside = atr_base + 10; + x.atr_full_txside = atr_base + 12; + x.atr_full_rxside = atr_base + 14; + x.rx_ctrl_stream_cmd = sr_addr(misc_output_base, x.sr_rx_ctrl + 0); + x.rx_ctrl_time_secs = sr_addr(misc_output_base, x.sr_rx_ctrl + 1); + x.rx_ctrl_time_ticks = sr_addr(misc_output_base, x.sr_rx_ctrl + 2); + x.rx_ctrl_clear_overrun = sr_addr(misc_output_base, x.sr_rx_ctrl + 3); + x.rx_ctrl_vrt_header = sr_addr(misc_output_base, x.sr_rx_ctrl + 4); + x.rx_ctrl_vrt_stream_id = sr_addr(misc_output_base, x.sr_rx_ctrl + 5); + x.rx_ctrl_vrt_trailer = sr_addr(misc_output_base, x.sr_rx_ctrl + 6); + x.rx_ctrl_nsamps_per_pkt = sr_addr(misc_output_base, x.sr_rx_ctrl + 7); + x.rx_ctrl_nchannels = sr_addr(misc_output_base, x.sr_rx_ctrl + 8); + x.tx_ctrl_num_chan = sr_addr(misc_output_base, x.sr_tx_ctrl + 0); + x.tx_ctrl_clear_state = sr_addr(misc_output_base, x.sr_tx_ctrl + 1); + x.tx_ctrl_report_sid = sr_addr(misc_output_base, x.sr_tx_ctrl + 2); + x.tx_ctrl_policy = sr_addr(misc_output_base, x.sr_tx_ctrl + 3); + x.tx_ctrl_cycles_per_up = sr_addr(misc_output_base, x.sr_tx_ctrl + 4); + x.tx_ctrl_packets_per_up = sr_addr(misc_output_base, x.sr_tx_ctrl + 5); + + return x; +} diff --git a/host/lib/usrp/usrp2/usrp2_regs.hpp b/host/lib/usrp/usrp2/usrp2_regs.hpp index 064ad4e95..9936d634a 100644 --- a/host/lib/usrp/usrp2/usrp2_regs.hpp +++ b/host/lib/usrp/usrp2/usrp2_regs.hpp @@ -18,6 +18,93 @@ #ifndef INCLUDED_USRP2_REGS_HPP #define INCLUDED_USRP2_REGS_HPP +#include <boost/cstdint.hpp> + +#define USRP2_MISC_OUTPUT_BASE 0xD400 +#define USRP2_GPIO_BASE 0xC800 +#define USRP2_ATR_BASE 0xE400 +#define USRP2_BP_STATUS_BASE 0xCC00 + +#define USRP2P_MISC_OUTPUT_BASE 0x2000 +#define USRP2P_GPIO_BASE 0x3200 +#define USRP2P_ATR_BASE 0x3800 +#define USRP2P_BP_STATUS_BASE 0x3300 + +typedef struct { + int sr_misc; + int sr_tx_prot_eng; + int sr_rx_prot_eng; + int sr_buffer_pool_ctrl; + int sr_udp_sm; + int sr_tx_dsp; + int sr_tx_ctrl; + int sr_rx_dsp; + int sr_rx_ctrl; + int sr_time64; + int sr_simtimer; + int sr_last; + int misc_ctrl_clock; + int misc_ctrl_serdes; + int misc_ctrl_adc; + int misc_ctrl_leds; + int misc_ctrl_phy; + int misc_ctrl_dbg_mux; + int misc_ctrl_ram_page; + int misc_ctrl_flush_icache; + int misc_ctrl_led_src; + int time64_secs; // value to set absolute secs to on next PPS + int time64_ticks; // value to set absolute ticks to on next PPS + int time64_flags; // flags -- see chart below + int time64_imm; // set immediate (0=latch on next pps, 1=latch immediate, default=0) + int time64_tps; // ticks per second rollover count + int time64_secs_rb; + int time64_ticks_rb; + int compat_num_rb; + int dsp_tx_freq; + int dsp_tx_scale_iq; + int dsp_tx_interp_rate; + int dsp_tx_mux; + int dsp_rx_freq; + int dsp_rx_scale_iq; + int dsp_rx_decim_rate; + int dsp_rx_dcoffset_i; + int dsp_rx_dcoffset_q; + int dsp_rx_mux; + int gpio_base; + int gpio_io; + int gpio_ddr; + int gpio_tx_sel; + int gpio_rx_sel; + int atr_base; + int atr_idle_txside; + int atr_idle_rxside; + int atr_intx_txside; + int atr_intx_rxside; + int atr_inrx_txside; + int atr_inrx_rxside; + int atr_full_txside; + int atr_full_rxside; + int rx_ctrl_stream_cmd; + int rx_ctrl_time_secs; + int rx_ctrl_time_ticks; + int rx_ctrl_clear_overrun; + int rx_ctrl_vrt_header; + int rx_ctrl_vrt_stream_id; + int rx_ctrl_vrt_trailer; + int rx_ctrl_nsamps_per_pkt; + int rx_ctrl_nchannels; + int tx_ctrl_num_chan; + int tx_ctrl_clear_state; + int tx_ctrl_report_sid; + int tx_ctrl_policy; + int tx_ctrl_cycles_per_up; + int tx_ctrl_packets_per_up; +} usrp2_regs_t; + +extern const usrp2_regs_t usrp2_regs; //the register definitions, set in usrp2_regs.cpp and usrp2p_regs.cpp + +usrp2_regs_t usrp2_get_regs(bool); + //////////////////////////////////////////////////// // Settings Bus, Slave #7, Not Byte Addressable! // @@ -25,27 +112,12 @@ // 1KB of address space (== 256 32-bit write-only regs) -#define MISC_OUTPUT_BASE 0xD400 +//#define MISC_OUTPUT_BASE 0xD400 //#define TX_PROTOCOL_ENGINE_BASE 0xD480 //#define RX_PROTOCOL_ENGINE_BASE 0xD4C0 //#define BUFFER_POOL_CTRL_BASE 0xD500 //#define LAST_SETTING_REG 0xD7FC // last valid setting register -#define SR_MISC 0 -#define SR_TX_PROT_ENG 32 -#define SR_RX_PROT_ENG 48 -#define SR_BUFFER_POOL_CTRL 64 -#define SR_UDP_SM 96 -#define SR_TX_DSP 208 -#define SR_TX_CTRL 224 -#define SR_RX_DSP 160 -#define SR_RX_CTRL 176 -#define SR_TIME64 192 -#define SR_SIMTIMER 198 -#define SR_LAST 255 - -#define _SR_ADDR(sr) ((MISC_OUTPUT_BASE) + (4*(sr))) - ///////////////////////////////////////////////// // SPI Slave Constants //////////////////////////////////////////////// @@ -58,20 +130,11 @@ #define SPI_SS_TX_DAC 32 #define SPI_SS_TX_ADC 64 #define SPI_SS_TX_DB 128 +#define SPI_SS_ADS62P44 256 //for usrp2p ///////////////////////////////////////////////// // Misc Control //////////////////////////////////////////////// -#define U2_REG_MISC_CTRL_CLOCK _SR_ADDR(0) -#define U2_REG_MISC_CTRL_SERDES _SR_ADDR(1) -#define U2_REG_MISC_CTRL_ADC _SR_ADDR(2) -#define U2_REG_MISC_CTRL_LEDS _SR_ADDR(3) -#define U2_REG_MISC_CTRL_PHY _SR_ADDR(4) // LSB is reset line to eth phy -#define U2_REG_MISC_CTRL_DBG_MUX _SR_ADDR(5) -#define U2_REG_MISC_CTRL_RAM_PAGE _SR_ADDR(6) // FIXME should go somewhere else... -#define U2_REG_MISC_CTRL_FLUSH_ICACHE _SR_ADDR(7) // Flush the icache -#define U2_REG_MISC_CTRL_LED_SRC _SR_ADDR(8) // HW or SW control for LEDs - #define U2_FLAG_MISC_CTRL_SERDES_ENABLE 8 #define U2_FLAG_MISC_CTRL_SERDES_PRBSEN 4 #define U2_FLAG_MISC_CTRL_SERDES_LOOPEN 2 @@ -99,15 +162,6 @@ * * </pre> */ -#define U2_REG_TIME64_SECS _SR_ADDR(SR_TIME64 + 0) // value to set absolute secs to on next PPS -#define U2_REG_TIME64_TICKS _SR_ADDR(SR_TIME64 + 1) // value to set absolute ticks to on next PPS -#define U2_REG_TIME64_FLAGS _SR_ADDR(SR_TIME64 + 2) // flags - see chart above -#define U2_REG_TIME64_IMM _SR_ADDR(SR_TIME64 + 3) // set immediate (0=latch on next pps, 1=latch immediate, default=0) -#define U2_REG_TIME64_TPS _SR_ADDR(SR_TIME64 + 4) // the ticks per second rollover count - -#define U2_REG_TIME64_SECS_RB (0xCC00 + 4*10) -#define U2_REG_TIME64_TICKS_RB (0xCC00 + 4*11) -#define U2_REG_COMPAT_NUM_RB (0xCC00 + 4*12) //pps flags (see above) #define U2_FLAG_TIME64_PPS_NEGEDGE (0 << 0) @@ -121,34 +175,72 @@ ///////////////////////////////////////////////// // DSP TX Regs //////////////////////////////////////////////// -#define U2_REG_DSP_TX_FREQ _SR_ADDR(SR_TX_DSP + 0) -#define U2_REG_DSP_TX_SCALE_IQ _SR_ADDR(SR_TX_DSP + 1) // {scale_i,scale_q} -#define U2_REG_DSP_TX_INTERP_RATE _SR_ADDR(SR_TX_DSP + 2) -#define U2_REG_DSP_TX_MUX _SR_ADDR(SR_TX_DSP + 4) + + /*! + * \brief output mux configuration. + * + * <pre> + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-------------------------------+-------+-------+-------+-------+ + * | | DAC1 | DAC0 | + * +-------------------------------+-------+-------+-------+-------+ + * + * There are N DUCs (1 now) with complex inputs and outputs. + * There are two DACs. + * + * Each 4-bit DACx field specifies the source for the DAC + * Each subfield is coded like this: + * + * 3 2 1 0 + * +-------+ + * | N | + * +-------+ + * + * N specifies which DUC output is connected to this DAC. + * + * N which interp output + * --- ------------------- + * 0 DUC 0 I + * 1 DUC 0 Q + * 2 DUC 1 I + * 3 DUC 1 Q + * F All Zeros + * + * The default value is 0x10 + * </pre> + */ + ///////////////////////////////////////////////// // DSP RX Regs //////////////////////////////////////////////// -#define U2_REG_DSP_RX_FREQ _SR_ADDR(SR_RX_DSP + 0) -#define U2_REG_DSP_RX_SCALE_IQ _SR_ADDR(SR_RX_DSP + 1) // {scale_i,scale_q} -#define U2_REG_DSP_RX_DECIM_RATE _SR_ADDR(SR_RX_DSP + 2) -#define U2_REG_DSP_RX_DCOFFSET_I _SR_ADDR(SR_RX_DSP + 3) // Bit 31 high sets fixed offset mode, using lower 14 bits, - // otherwise it is automatic -#define U2_REG_DSP_RX_DCOFFSET_Q _SR_ADDR(SR_RX_DSP + 4) // Bit 31 high sets fixed offset mode, using lower 14 bits -#define U2_REG_DSP_RX_MUX _SR_ADDR(SR_RX_DSP + 5) // called adc_mux in dsp_core_rx.v + + /*! + * \brief input mux configuration. + * + * This determines which ADC (or constant zero) is connected to + * each DDC input. There are N DDCs (1 now). Each has two inputs. + * + * <pre> + * Mux value: + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * | |Q0 |I0 | + * +-------+-------+-------+-------+-------+-------+-------+-------+ + * + * Each 2-bit I field is either 00 (A/D A), 01 (A/D B) or 1X (const zero) + * Each 2-bit Q field is either 00 (A/D A), 01 (A/D B) or 1X (const zero) + * + * The default value is 0x4 + * </pre> + */ //////////////////////////////////////////////// // GPIO, Slave 4 //////////////////////////////////////////////// -// -// These go to the daughterboard i/o pins -// -#define U2_REG_GPIO_BASE 0xC800 - -#define U2_REG_GPIO_IO U2_REG_GPIO_BASE + 0 // 32 bits, gpio io pins (tx high 16 bits, rx low 16 bits) -#define U2_REG_GPIO_DDR U2_REG_GPIO_BASE + 4 // 32 bits, gpio ddr, 1 means output (tx high 16 bits, rx low 16 bits) -#define U2_REG_GPIO_TX_SEL U2_REG_GPIO_BASE + 8 // 16 2-bit fields select which source goes to TX DB -#define U2_REG_GPIO_RX_SEL U2_REG_GPIO_BASE + 12 // 16 2-bit fields select which source goes to RX DB // each 2-bit sel field is layed out this way #define U2_FLAG_GPIO_SEL_GPIO 0 // if pin is an output, set by GPIO register @@ -159,43 +251,39 @@ /////////////////////////////////////////////////// // ATR Controller, Slave 11 //////////////////////////////////////////////// -#define U2_REG_ATR_BASE 0xE400 -#define U2_REG_ATR_IDLE_TXSIDE U2_REG_ATR_BASE + 0 -#define U2_REG_ATR_IDLE_RXSIDE U2_REG_ATR_BASE + 2 -#define U2_REG_ATR_INTX_TXSIDE U2_REG_ATR_BASE + 4 -#define U2_REG_ATR_INTX_RXSIDE U2_REG_ATR_BASE + 6 -#define U2_REG_ATR_INRX_TXSIDE U2_REG_ATR_BASE + 8 -#define U2_REG_ATR_INRX_RXSIDE U2_REG_ATR_BASE + 10 -#define U2_REG_ATR_FULL_TXSIDE U2_REG_ATR_BASE + 12 -#define U2_REG_ATR_FULL_RXSIDE U2_REG_ATR_BASE + 14 /////////////////////////////////////////////////// // RX CTRL regs /////////////////////////////////////////////////// // The following 3 are logically a single command register. // They are clocked into the underlying fifo when time_ticks is written. -#define U2_REG_RX_CTRL_STREAM_CMD _SR_ADDR(SR_RX_CTRL + 0) // {now, chain, num_samples(30) -#define U2_REG_RX_CTRL_TIME_SECS _SR_ADDR(SR_RX_CTRL + 1) -#define U2_REG_RX_CTRL_TIME_TICKS _SR_ADDR(SR_RX_CTRL + 2) +//#define U2_REG_RX_CTRL_STREAM_CMD _SR_ADDR(SR_RX_CTRL + 0) // {now, chain, num_samples(30) +//#define U2_REG_RX_CTRL_TIME_SECS _SR_ADDR(SR_RX_CTRL + 1) +//#define U2_REG_RX_CTRL_TIME_TICKS _SR_ADDR(SR_RX_CTRL + 2) -#define U2_REG_RX_CTRL_CLEAR_OVERRUN _SR_ADDR(SR_RX_CTRL + 3) // write anything to clear overrun -#define U2_REG_RX_CTRL_VRT_HEADER _SR_ADDR(SR_RX_CTRL + 4) // word 0 of packet. FPGA fills in packet counter -#define U2_REG_RX_CTRL_VRT_STREAM_ID _SR_ADDR(SR_RX_CTRL + 5) // word 1 of packet. -#define U2_REG_RX_CTRL_VRT_TRAILER _SR_ADDR(SR_RX_CTRL + 6) -#define U2_REG_RX_CTRL_NSAMPS_PER_PKT _SR_ADDR(SR_RX_CTRL + 7) -#define U2_REG_RX_CTRL_NCHANNELS _SR_ADDR(SR_RX_CTRL + 8) // 1 in basic case, up to 4 for vector sources +//#define U2_REG_RX_CTRL_CLEAR_STATE _SR_ADDR(SR_RX_CTRL + 3) +//#define U2_REG_RX_CTRL_VRT_HEADER _SR_ADDR(SR_RX_CTRL + 4) // word 0 of packet. FPGA fills in packet counter +//#define U2_REG_RX_CTRL_VRT_STREAM_ID _SR_ADDR(SR_RX_CTRL + 5) // word 1 of packet. +//#define U2_REG_RX_CTRL_VRT_TRAILER _SR_ADDR(SR_RX_CTRL + 6) +//#define U2_REG_RX_CTRL_NSAMPS_PER_PKT _SR_ADDR(SR_RX_CTRL + 7) +//#define U2_REG_RX_CTRL_NCHANNELS _SR_ADDR(SR_RX_CTRL + 8) // 1 in basic case, up to 4 for vector sources /////////////////////////////////////////////////// // TX CTRL regs /////////////////////////////////////////////////// -#define U2_REG_TX_CTRL_NUM_CHAN _SR_ADDR(SR_TX_CTRL + 0) -#define U2_REG_TX_CTRL_CLEAR_STATE _SR_ADDR(SR_TX_CTRL + 1) -#define U2_REG_TX_CTRL_REPORT_SID _SR_ADDR(SR_TX_CTRL + 2) -#define U2_REG_TX_CTRL_POLICY _SR_ADDR(SR_TX_CTRL + 3) +//#define U2_REG_TX_CTRL_NUM_CHAN _SR_ADDR(SR_TX_CTRL + 0) +//#define U2_REG_TX_CTRL_CLEAR_STATE _SR_ADDR(SR_TX_CTRL + 1) +//#define U2_REG_TX_CTRL_REPORT_SID _SR_ADDR(SR_TX_CTRL + 2) +//#define U2_REG_TX_CTRL_POLICY _SR_ADDR(SR_TX_CTRL + 3) +//#define U2_REG_TX_CTRL_CYCLES_PER_UP _SR_ADDR(SR_TX_CTRL + 4) +//#define U2_REG_TX_CTRL_PACKETS_PER_UP _SR_ADDR(SR_TX_CTRL + 5) #define U2_FLAG_TX_CTRL_POLICY_WAIT (0x1 << 0) #define U2_FLAG_TX_CTRL_POLICY_NEXT_PACKET (0x1 << 1) #define U2_FLAG_TX_CTRL_POLICY_NEXT_BURST (0x1 << 2) +//enable flag for registers: cycles and packets per update packet +#define U2_FLAG_TX_CTRL_UP_ENB (1ul << 31) + #endif /* INCLUDED_USRP2_REGS_HPP */ diff --git a/host/lib/usrp/wrapper_utils.hpp b/host/lib/usrp/wrapper_utils.hpp index 6f9fdbfca..a7b5c5da6 100644 --- a/host/lib/usrp/wrapper_utils.hpp +++ b/host/lib/usrp/wrapper_utils.hpp @@ -30,7 +30,7 @@ static inline uhd::freq_range_t add_dsp_shift( wax::obj dsp ){ double codec_rate = dsp[uhd::usrp::DSP_PROP_CODEC_RATE].as<double>(); - return uhd::freq_range_t(range.min - codec_rate/2.0, range.max + codec_rate/2.0); + return uhd::freq_range_t(range.start() - codec_rate/2.0, range.stop() + codec_rate/2.0); } static inline void do_samp_rate_warning_message( diff --git a/host/lib/utils/gain_group.cpp b/host/lib/utils/gain_group.cpp index 54146726a..11bbb8c0a 100644 --- a/host/lib/utils/gain_group.cpp +++ b/host/lib/utils/gain_group.cpp @@ -32,7 +32,7 @@ static const bool verbose = false; static bool compare_by_step_size( const size_t &rhs, const size_t &lhs, std::vector<gain_fcns_t> &fcns ){ - return fcns.at(rhs).get_range().step > fcns.at(lhs).get_range().step; + return fcns.at(rhs).get_range().step() > fcns.at(lhs).get_range().step(); } /*! @@ -69,11 +69,11 @@ public: float overall_min = 0, overall_max = 0, overall_step = 0; BOOST_FOREACH(const gain_fcns_t &fcns, get_all_fcns()){ const gain_range_t range = fcns.get_range(); - overall_min += range.min; - overall_max += range.max; + overall_min += range.start(); + overall_max += range.stop(); //the overall step is the min (zero is invalid, first run) - if (overall_step == 0) overall_step = range.step; - overall_step = std::min(overall_step, range.step); + if (overall_step == 0) overall_step = range.step(); + overall_step = std::min(overall_step, range.step()); } return gain_range_t(overall_min, overall_max, overall_step); } @@ -97,7 +97,7 @@ public: //get the max step size among the gains float max_step = 0; BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ - max_step = std::max(max_step, fcns.get_range().step); + max_step = std::max(max_step, fcns.get_range().step()); } //create gain bucket to distribute power @@ -108,7 +108,7 @@ public: BOOST_FOREACH(const gain_fcns_t &fcns, all_fcns){ const gain_range_t range = fcns.get_range(); gain_bucket.push_back(floor_step(std::clip( - gain_left_to_distribute, range.min, range.max + gain_left_to_distribute, range.start(), range.stop() ), max_step)); gain_left_to_distribute -= gain_bucket.back(); } @@ -123,8 +123,8 @@ public: boost::bind(&compare_by_step_size, _1, _2, all_fcns) ); UHD_ASSERT_THROW( - all_fcns.at(indexes_step_size_dec.front()).get_range().step >= - all_fcns.at(indexes_step_size_dec.back()).get_range().step + all_fcns.at(indexes_step_size_dec.front()).get_range().step() >= + all_fcns.at(indexes_step_size_dec.back()).get_range().step() ); //distribute the remainder (less than max step) @@ -132,8 +132,8 @@ public: BOOST_FOREACH(size_t i, indexes_step_size_dec){ const gain_range_t range = all_fcns.at(i).get_range(); float additional_gain = floor_step(std::clip( - gain_bucket.at(i) + gain_left_to_distribute, range.min, range.max - ), range.step) - gain_bucket.at(i); + gain_bucket.at(i) + gain_left_to_distribute, range.start(), range.stop() + ), range.step()) - gain_bucket.at(i); gain_bucket.at(i) += additional_gain; gain_left_to_distribute -= additional_gain; } diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt index 2cc987f0c..bdbde4b2c 100644 --- a/host/test/CMakeLists.txt +++ b/host/test/CMakeLists.txt @@ -26,6 +26,7 @@ SET(test_sources dict_test.cpp error_test.cpp gain_group_test.cpp + ranges_test.cpp subdev_spec_test.cpp time_spec_test.cpp tune_helper_test.cpp diff --git a/host/test/convert_types_test.cpp b/host/test/convert_types_test.cpp index 2148302b6..378e184de 100644 --- a/host/test/convert_types_test.cpp +++ b/host/test/convert_types_test.cpp @@ -38,6 +38,9 @@ template <typename T> const void * pod2ptr(const T &pod){ return boost::asio::buffer_cast<const void *>(boost::asio::buffer(pod)); } +#define MY_CHECK_CLOSE(a, b, f) if ((std::abs(a) > (f) and std::abs(b) > (f))) \ + BOOST_CHECK_CLOSE_FRACTION(a, b, f) + /*********************************************************************** * Loopback runner: * convert input buffer into intermediate buffer @@ -130,8 +133,8 @@ static void test_convert_types_fc32( //run the loopback and test loopback(nsamps, io_type, otw_type, input, output); for (size_t i = 0; i < nsamps; i++){ - BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real(), float(0.01)); - BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag(), float(0.01)); + MY_CHECK_CLOSE(input[i].real(), output[i].real(), float(0.01)); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag(), float(0.01)); } } @@ -195,8 +198,8 @@ BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){ //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ - BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real()/float(32767), float(0.01)); - BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag()/float(32767), float(0.01)); + MY_CHECK_CLOSE(input[i].real(), output[i].real()/float(32767), float(0.01)); + MY_CHECK_CLOSE(input[i].imag(), output[i].imag()/float(32767), float(0.01)); } } @@ -236,7 +239,7 @@ BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ //test that the inputs and outputs match for (size_t i = 0; i < nsamps; i++){ - BOOST_CHECK_CLOSE_FRACTION(input[i].real()/float(32767), output[i].real(), float(0.01)); - BOOST_CHECK_CLOSE_FRACTION(input[i].imag()/float(32767), output[i].imag(), float(0.01)); + MY_CHECK_CLOSE(input[i].real()/float(32767), output[i].real(), float(0.01)); + MY_CHECK_CLOSE(input[i].imag()/float(32767), output[i].imag(), float(0.01)); } } diff --git a/host/test/gain_group_test.cpp b/host/test/gain_group_test.cpp index 555ccaed3..dbb585987 100644 --- a/host/test/gain_group_test.cpp +++ b/host/test/gain_group_test.cpp @@ -40,7 +40,7 @@ public: } void set_value(float gain){ - float step = get_range().step; + float step = get_range().step(); _gain = step*rint(gain/step); } @@ -60,7 +60,7 @@ public: } void set_value(float gain){ - float step = get_range().step; + float step = get_range().step(); _gain = step*rint(gain/step); } @@ -102,9 +102,9 @@ BOOST_AUTO_TEST_CASE(test_gain_group_overall){ //test the overall stuff gg->set_value(80); BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().start(), float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().stop(), float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step(), float(0.1), tolerance); } BOOST_AUTO_TEST_CASE(test_gain_group_priority){ @@ -113,10 +113,10 @@ BOOST_AUTO_TEST_CASE(test_gain_group_priority){ //test the overall stuff gg->set_value(80); BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); - BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().start(), float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().stop(), float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step(), float(0.1), tolerance); //test the the higher priority gain got filled first (gain 2) - BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().max, tolerance); + BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().stop(), tolerance); } diff --git a/host/test/ranges_test.cpp b/host/test/ranges_test.cpp new file mode 100644 index 000000000..ad61867e1 --- /dev/null +++ b/host/test/ranges_test.cpp @@ -0,0 +1,57 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/types/ranges.hpp> +#include <iostream> + +using namespace uhd; + +static const double tolerance = 0.001; + +BOOST_AUTO_TEST_CASE(test_ranges_bounds){ + meta_range_t<double> mr; + mr.push_back(range_t<double>(-1.0, +1.0, 0.1)); + BOOST_CHECK_CLOSE(mr.start(), -1.0, tolerance); + BOOST_CHECK_CLOSE(mr.stop(), +1.0, tolerance); + BOOST_CHECK_CLOSE(mr.step(), 0.1, tolerance); + + mr.push_back(range_t<double>(40.0, 60.0, 1.0)); + BOOST_CHECK_CLOSE(mr.start(), -1.0, tolerance); + BOOST_CHECK_CLOSE(mr.stop(), 60.0, tolerance); + BOOST_CHECK_CLOSE(mr.step(), 0.1, tolerance); + + BOOST_CHECK_EQUAL(mr.size(), 2); + + BOOST_CHECK_CLOSE(mr[0].start(), -1.0, tolerance); + BOOST_CHECK_CLOSE(mr[0].stop(), +1.0, tolerance); + BOOST_CHECK_CLOSE(mr[0].step(), 0.1, tolerance); +} + +BOOST_AUTO_TEST_CASE(test_ranges_clip){ + meta_range_t<double> mr; + mr.push_back(range_t<double>(-1.0, +1.0, 0.1)); + mr.push_back(range_t<double>(40.0, 60.0, 1.0)); + + BOOST_CHECK_CLOSE(mr.clip(-30.0), -1.0, tolerance); + BOOST_CHECK_CLOSE(mr.clip(70.0), 60.0, tolerance); + BOOST_CHECK_CLOSE(mr.clip(20.0), 1.0, tolerance); + BOOST_CHECK_CLOSE(mr.clip(50.0), 50.0, tolerance); + + BOOST_CHECK_CLOSE(mr.clip(50.9, false), 50.9, tolerance); + BOOST_CHECK_CLOSE(mr.clip(50.9, true), 51.0, tolerance); +} diff --git a/host/utils/uhd_usrp_probe.cpp b/host/utils/uhd_usrp_probe.cpp index 8cea52fa6..5cba7c362 100644 --- a/host/utils/uhd_usrp_probe.cpp +++ b/host/utils/uhd_usrp_probe.cpp @@ -81,13 +81,13 @@ static std::string get_subdev_pp_string(const std::string &type, wax::obj subdev ss << boost::format("Antennas: %s") % prop_names_to_pp_string(ant_names) << std::endl; freq_range_t freq_range(subdev[usrp::SUBDEV_PROP_FREQ_RANGE].as<freq_range_t>()); - ss << boost::format("Freq range: %.3f to %.3f Mhz") % (freq_range.min/1e6) % (freq_range.max/1e6) << std::endl; + ss << boost::format("Freq range: %.3f to %.3f Mhz") % (freq_range.start()/1e6) % (freq_range.stop()/1e6) << std::endl; prop_names_t gain_names(subdev[usrp::SUBDEV_PROP_GAIN_NAMES].as<prop_names_t>()); if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; BOOST_FOREACH(const std::string &gain_name, gain_names){ gain_range_t gain_range(subdev[named_prop_t(usrp::SUBDEV_PROP_GAIN_RANGE, gain_name)].as<gain_range_t>()); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.min % gain_range.max % gain_range.step << std::endl; + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; } ss << boost::format("Connection Type: %c") % char(subdev[usrp::SUBDEV_PROP_CONNECTION].as<usrp::subdev_conn_t>()) << std::endl; @@ -104,7 +104,7 @@ static std::string get_codec_pp_string(const std::string &type, wax::obj codec){ if (gain_names.size() == 0) ss << "Gain Elements: None" << std::endl; BOOST_FOREACH(const std::string &gain_name, gain_names){ gain_range_t gain_range(codec[named_prop_t(usrp::CODEC_PROP_GAIN_RANGE, gain_name)].as<gain_range_t>()); - ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.min % gain_range.max % gain_range.step << std::endl; + ss << boost::format("Gain range %s: %.1f to %.1f step %.1f dB") % gain_name % gain_range.start() % gain_range.stop() % gain_range.step() << std::endl; } return ss.str(); } diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py new file mode 100755 index 000000000..21327e0af --- /dev/null +++ b/host/utils/usrp_n2xx_net_burner.py @@ -0,0 +1,288 @@ +#!/usr/bin/env python +# +# Copyright 2010 Ettus Research LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +# TODO: make it autodetect UHD devices +# TODO: you should probably watch sequence numbers + +import optparse +import math +import os +import re +import struct +import socket +import sys + +######################################################################## +# constants +######################################################################## +UDP_FW_UPDATE_PORT = 49154 +UDP_MAX_XFER_BYTES = 1024 +UDP_TIMEOUT = 3 +UDP_POLL_INTERVAL = 0.10 #in seconds + +USRP2_FW_PROTO_VERSION = 7 + +#from bootloader_utils.h + +FPGA_IMAGE_SIZE_BYTES = 1572864 +FW_IMAGE_SIZE_BYTES = 31744 +SAFE_FPGA_IMAGE_LOCATION_ADDR = 0x00000000 +SAFE_FW_IMAGE_LOCATION_ADDR = 0x003F0000 +PROD_FPGA_IMAGE_LOCATION_ADDR = 0x00180000 +PROD_FW_IMAGE_LOCATION_ADDR = 0x00300000 + +FLASH_DATA_PACKET_SIZE = 256 + +#see fw_common.h +FLASH_ARGS_FMT = '!LLLLL256s' +FLASH_INFO_FMT = '!LLLLL256x' +FLASH_IP_FMT = '!LLLL260x' + +class update_id_t: + USRP2_FW_UPDATE_ID_WAT = ord(' ') + USRP2_FW_UPDATE_ID_OHAI_LOL = ord('a') + USRP2_FW_UPDATE_ID_OHAI_OMG = ord('A') + USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL = ord('f') + USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG = ord('F') + USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL = ord('e') + USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG = ord('E') + USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL = ord('d') + USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG = ord('D') + USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG = ord('B') + USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL = ord('w') + USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG = ord('W') + USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL = ord('r') + USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG = ord('R') + USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL = ord('s') + USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG = ord('S') + USRP2_FW_UPDATE_ID_KTHXBAI = ord('~') + +_seq = -1 +def seq(): + global _seq + _seq = _seq+1 + return _seq + +######################################################################## +# helper functions +######################################################################## +def unpack_flash_args_fmt(s): + return struct.unpack(FLASH_ARGS_FMT, s) #(proto_ver, pktid, seq, flash_addr, length, data) + +def unpack_flash_info_fmt(s): + return struct.unpack(FLASH_INFO_FMT, s) #(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + +def unpack_flash_ip_fmt(s): + return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr) + +def pack_flash_args_fmt(proto_ver, pktid, seq, flash_addr, length, data): + return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data) + +def pack_flash_info_fmt(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes): + return struct.pack(FLASH_INFO_FMT, proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + +def send_and_recv(pkt, ip): + update_socket = create_socket() + + try: + update_socket.sendto(pkt, (ip, UDP_FW_UPDATE_PORT)) + except Exception, e: + print e + sys.exit(1) + + try: + (recv_pkt, recv_addr) = update_socket.recvfrom(UDP_MAX_XFER_BYTES) + except Exception, e: + print e + sys.exit(1) + + if recv_addr != (options.ip, UDP_FW_UPDATE_PORT): + raise Exception, "Packet received from invalid IP %s, expected %s" % (recv_addr, options.ip) + + return recv_pkt + +def create_socket(): + socket.setdefaulttimeout(UDP_TIMEOUT) + update_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + return update_socket + +#just here to validate comms +def init_update(ip): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") + in_pkt = send_and_recv(out_pkt, ip) + (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: + print "USRP2P found." + else: + raise Exception, "Invalid reply received from device." + +# print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr) + +def get_flash_info(ip): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "") + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + + return (memory_size_bytes, sector_size_bytes) + +def burn_fw(ip, fw, fpga, reset, safe): + init_update(ip) + (flash_size, sector_size) = get_flash_info(ip) + + print "Flash size: %i\nSector size: %i" % (flash_size, sector_size) + + if fpga: + if safe: + image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR + else: + image_location = PROD_FPGA_IMAGE_LOCATION_ADDR + + fpga_file = open(fpga, 'rb') + fpga_image = fpga_file.read() + erase_image(ip, image_location, FPGA_IMAGE_SIZE_BYTES) + write_image(ip, fpga_image, image_location) + verify_image(ip, fpga_image, image_location) + + if fw: + if safe: + image_location = SAFE_FW_IMAGE_LOCATION_ADDR + else: + image_location = PROD_FW_IMAGE_LOCATION_ADDR + + fw_file = open(fw, 'rb') + fw_image = fw_file.read() + erase_image(ip, image_location, FW_IMAGE_SIZE_BYTES) + write_image(ip, fw_image, image_location) + verify_image(ip, fw_image, image_location) + + if reset: + reset_usrp(ip) + +def write_image(ip, image, addr): + print "Writing image" +#we split the image into smaller (256B) bits and send them down the wire + while image: + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + image = image[FLASH_DATA_PACKET_SIZE:] + addr += FLASH_DATA_PACKET_SIZE + +def verify_image(ip, image, addr): + print "Verifying data" + readsize = len(image) + readdata = str() + while readsize > 0: + if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize + else: thisreadsize = FLASH_DATA_PACKET_SIZE + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + readdata += data[:thisreadsize] + readsize -= FLASH_DATA_PACKET_SIZE + addr += FLASH_DATA_PACKET_SIZE + + print "Read back %i bytes" % len(readdata) +# print readdata + +# for i in range(256, 512): +# print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) + + if readdata != image: + print "Verify failed. Image did not write correctly." + else: + print "Success." + +def reset_usrp(ip): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: + raise Exception, "Device failed to reset." + +def erase_image(ip, addr, length): + #get flash info first + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + print "Erasing %i bytes at %i" % (length, addr) + + #now wait for it to finish + while(1): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "") + in_pkt = send_and_recv(out_pkt, ip) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break + elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + +######################################################################## +# command line options +######################################################################## +def get_options(): + parser = optparse.OptionParser() + parser.add_option("--ip", type="string", help="USRP2P firmware address", default='') + parser.add_option("--fw", type="string", help="firmware image path (optional)", default='') + parser.add_option("--fpga", type="string", help="fpga image path (optional)", default='') + parser.add_option("--reset", action="store_true", help="reset the device after writing", default=False) + parser.add_option("--overwrite-safe", action="store_true", help="never ever use this option", default=False) + (options, args) = parser.parse_args() + + return options + +######################################################################## +# main +######################################################################## +if __name__=='__main__': + options = get_options() + if not options.ip: raise Exception, 'no ip address specified' + + if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.' + + if options.overwrite_safe: + print("Are you REALLY, REALLY sure you want to overwrite the safe image? This is ALMOST ALWAYS a terrible idea.") + print("If your image is faulty, your USRP2+ will become a brick until reprogrammed via JTAG.") + response = raw_input("""Type "yes" to continue, or anything else to quit: """) + if response != "yes": + sys.exit(0) + + burn_fw(ip=options.ip, fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) diff --git a/images/Makefile b/images/Makefile index 559245e85..34943cc59 100644 --- a/images/Makefile +++ b/images/Makefile @@ -78,12 +78,13 @@ $(_usrp1_fpga_4rx_rbf): cp $(_usrp1_fpga_dir)/std_4rx_0tx.rbf $@ ######################################################################## -# USRP2 firmware +# USRP2/2+ firmware ######################################################################## ifdef HAS_MB_GCC _usrp2_fw_dir = $(TOP_FW_DIR)/microblaze _usrp2_fw_bin = $(BUILT_IMAGES_DIR)/usrp2_fw.bin +_usrp2p_fw_bin = $(BUILT_IMAGES_DIR)/usrp2p_fw.bin IMAGES_LIST += $(_usrp2_fw_bin) $(_usrp2_fw_bin): @@ -91,7 +92,8 @@ $(_usrp2_fw_bin): cd $(_usrp2_fw_dir) && ./configure --host=mb make -C $(_usrp2_fw_dir) clean make -C $(_usrp2_fw_dir) all - cp $(_usrp2_fw_dir)/usrp2/usrp2_txrx_uhd.bin $@ + cp $(_usrp2_fw_dir)/usrp2/usrp2_txrx_uhd.bin $(_usrp2_fw_bin) + cp $(_usrp2_fw_dir)/usrp2p/usrp2p_txrx_uhd.bin $(_usrp2p_fw_bin) endif |