def __init__(self, step_width=None, step_shift=0, **kwargs): Filter.__init__(self, **kwargs) # required by tests self.step_shift = step_shift width = len(self.y) if step_width is None: step_width = width self.shift = CSRConstant(step_shift, bits_for(step_shift)) self.step = CSRStorage(step_width) self.min = CSRStorage(width, reset=1 << (width - 1)) self.max = CSRStorage(width, reset=(1 << (width - 1)) - 1) self.run = CSRStorage(1) ### self.submodules.sweep = Sweep(width + step_shift + 1) self.submodules.limit = Limit(width + 1) min, max = self.min.storage, self.max.storage self.comb += [ self.sweep.run.eq(~self.clear & self.run.storage), self.sweep.hold.eq(self.hold), self.limit.x.eq(self.sweep.y >> step_shift), self.sweep.step.eq(self.step.storage), ] self.sync += [ self.limit.min.eq(Cat(min, min[-1])), self.limit.max.eq(Cat(max, max[-1])), self.sweep.turn.eq(self.limit.railed), self.y.eq(self.limit.y), ]
def init_csr(self, width, signal_width, chain_factor_width): factor_reset = 1 << (chain_factor_width - 1) # we use chain_factor_width + 1 for the single channel mode self.dual_channel = CSRStorage(1) self.chain_a_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_b_factor = CSRStorage(chain_factor_width + 1, reset=factor_reset) self.chain_a_offset = CSRStorage(width) self.chain_b_offset = CSRStorage(width) self.chain_a_offset_signed = Signal((width, True)) self.chain_b_offset_signed = Signal((width, True)) self.combined_offset = CSRStorage(width) self.combined_offset_signed = Signal((width, True)) self.out_offset = CSRStorage(width) self.out_offset_signed = Signal((width, True)) self.mod_channel = CSRStorage(1) self.control_channel = CSRStorage(1) self.sweep_channel = CSRStorage(2) self.slow_value = CSRStatus(width) max_decimation = 16 self.slow_decimation = CSRStorage(bits_for(max_decimation)) for i in range(4): if i == 0: continue name = "analog_out_%d" % i setattr(self, name, CSRStorage(15, name=name))
def relabel_with_parts(g, parts): peid_offset = 1 for part in parts: if peid_offset < bits_for(len(part)): peid_offset = bits_for(len(part)) relabel_d = {} for i, part in enumerate(parts): for j, n in enumerate(part): if i == 0: idx = j + 1 else: idx = j assert idx < 2**peid_offset relabel_d[n] = (i << peid_offset) | idx g = nx.relabel_nodes(g, relabel_d) log_stats(g) return g, 2**peid_offset
def relabel_with_parts(g, parts): peid_offset = 1 for part in parts: if peid_offset < bits_for(len(part)): peid_offset = bits_for(len(part)) relabel_d = {} for i, part in enumerate(parts): for j, n in enumerate(part): if i == 0: idx = j+1 else: idx = j assert idx < 2**peid_offset relabel_d[n] = (i << peid_offset) | idx g = nx.relabel_nodes(g, relabel_d) log_stats(g) return g, 2**peid_offset
def cross_connect(gpio, chains): state_names = ["force"] + ["di%i" % i for i in range(len(gpio.i))] states = [1, gpio.i] signal_names = ["zero"] signals = Array([0]) for n, c in chains: for s in c.state_out: states.append(s) state_names.append("%s_%s" % (n, s.backtrace[-1][0])) for s in c.signal_out: signals.append(s) name = s.backtrace[-1][0] signal_names.append("%s_%s" % (n, name)) sig = CSRStatus(len(s), name=name) clr = CSR(name="%s_clr" % name) max = CSRStatus(len(s), name="%s_max" % name) min = CSRStatus(len(s), name="%s_min" % name) # setattr(c, sig.name, sig) setattr(c, clr.name, clr) setattr(c, max.name, max) setattr(c, min.name, min) c.comb += sig.status.eq(s) c.sync += If(clr.re | (max.status < s), max.status.eq(s)) c.sync += If(clr.re | (min.status > s), min.status.eq(s)) states = Cat(states) state = Signal(len(states)) gpio.comb += state.eq(states) gpio.state = CSRStatus(len(state)) gpio.state_clr = CSR() gpio.sync += [ If( gpio.state_clr.re, gpio.state.status.eq(0), ).Else(gpio.state.status.eq(gpio.state.status | state), ) ] # connect gpio output to "doi%i_en" for i, s in enumerate(gpio.o): csr = CSRStorage(len(state), name="do%i_en" % i) setattr(gpio, csr.name, csr) gpio.sync += s.eq((state & csr.storage) != 0) # connect state ins to "%s_en" and signal ins to "%s_sel" for n, c in chains: for s in c.state_in: csr = CSRStorage(len(state), name="%s_en" % s.backtrace[-1][0]) setattr(c, csr.name, csr) c.sync += s.eq((state & csr.storage) != 0) for s in c.signal_in: csr = CSRStorage(bits_for(len(signals) - 1), name="%s_sel" % s.backtrace[-1][0]) setattr(c, csr.name, csr) c.sync += s.eq(signals[csr.storage]) return state_names, signal_names
def __init__(self, input_bit, max_delay): self.delay = Signal(bits_for(max_delay)) self.restart = Signal() self.writing_data_now = Signal() self.input = Signal((input_bit, True)) self.output = Signal((input_bit, True)) # this ensures that counter overflows / underflows correctly assert max_delay == (2**(bits_for(max_delay)) - 1) self.mem_rdport, self.mem_wrport = create_memory( self, input_bit, max_delay, "dynamic_delay_mem") # register all the ports self.specials += [self.mem_rdport, self.mem_wrport] self.counter = Signal(bits_for(max_delay)) self.counter_delayed = Signal((bits_for(max_delay))) negative_delay = 1 self.sync += [ If(self.restart, self.counter.eq(0)).Else( If(self.writing_data_now, self.counter.eq(self.counter + 1))), ] self.comb += [ self.mem_wrport.we.eq(self.writing_data_now), self.mem_wrport.adr.eq(self.counter), self.mem_wrport.dat_w.eq(self.input), self.mem_rdport.adr.eq(self.counter_delayed), self.counter_delayed.eq(self.counter - self.delay + negative_delay), self.mem_rdport.adr.eq(self.counter_delayed), If(self.counter < self.delay - negative_delay, self.output.eq(0)).Else(self.output.eq( self.mem_rdport.dat_r), ), ]
def __init__(self, width=14, N_points=16383, max_delay=16383): self.restart = Signal() self.writing_data_now = Signal() self.input = Signal((width, True)) self.delay_value = Signal(bits_for(N_points)) sum_value_bits = bits_for(((2**width) - 1) * N_points) self.sum_value = Signal((sum_value_bits, True)) delayed_sum = Signal((sum_value_bits, True)) current_sum_diff = Signal((sum_value_bits + 1, True)) self.output = Signal.like(current_sum_diff) self.submodules.delayer = DynamicDelay(sum_value_bits, max_delay=max_delay) self.sync += [ If( self.restart, self.sum_value.eq(0), ).Else( If( self.writing_data_now, # not at start self.sum_value.eq(self.sum_value + self.input), )) ] self.comb += [ self.delayer.writing_data_now.eq(self.writing_data_now), self.delayer.restart.eq(self.restart), self.delayer.delay.eq(self.delay_value), self.delayer.input.eq(self.sum_value), delayed_sum.eq(self.delayer.output), current_sum_diff.eq(self.sum_value - delayed_sum), self.output.eq(current_sum_diff), ]
def init_csr(self, N_points): # CSR storages self.time_scale = CSRStorage(bits_for(N_points)) self.N_instructions = CSRStorage( bits_for(AUTOLOCK_MAX_N_INSTRUCTIONS - 1)) self.final_wait_time = CSRStorage(bits_for(N_points)) peak_height_bit = len(self.sum_diff_calculator.sum_value) self.peak_heights = [ CSRStorage(peak_height_bit, name="peak_height_%d" % idx) for idx in range(AUTOLOCK_MAX_N_INSTRUCTIONS) ] for idx, peak_height in enumerate(self.peak_heights): setattr(self, "peak_height_%d" % idx, peak_height) x_data_length_bit = bits_for(N_points) self.wait_for = [ CSRStorage(x_data_length_bit, name="wait_for_%d" % idx) for idx in range(AUTOLOCK_MAX_N_INSTRUCTIONS) ] for idx, wait_for in enumerate(self.wait_for): setattr(self, "wait_for_%d" % idx, wait_for) return peak_height_bit, x_data_length_bit
def partition_random(g, pe): num_nodes = nx.number_of_nodes(g) peid_offset = bits_for((num_nodes + pe - 1) // pe) next_number = 0 next_pe = 1 relabel_d = {} for n in g.nodes(): if next_pe == pe: next_pe = 0 next_number += 1 assert next_number < 2**peid_offset relabel_d[n] = (next_pe << peid_offset) | next_number next_pe += 1 g = nx.relabel_nodes(g, relabel_d) log_stats(g) return g, 2**peid_offset
def partition_random(g, pe): num_nodes = nx.number_of_nodes(g) peid_offset = bits_for((num_nodes + pe - 1)//pe) next_number = 0 next_pe = 1 relabel_d = {} for n in g.nodes(): if next_pe == pe: next_pe = 0 next_number += 1 assert next_number < 2**peid_offset relabel_d[n] = (next_pe << peid_offset) | next_number next_pe += 1 g = nx.relabel_nodes(g, relabel_d) log_stats(g) return g, 2**peid_offset
def resolve_defaults(config, inverted=False, graphfile=None, num_nodes=None, num_edges=None, digraph=False, graphsave=None, sim=True): if not graphfile and not num_nodes: if 'graphfile' in config['graph']: graphfile = config['graph'].get('graphfile') elif 'nodes' in config['graph']: num_nodes = eval(config['graph'].get('nodes')) if not num_edges: if 'edges' in config['graph']: num_edges = eval(config['graph'].get('edges')) else: num_edges = num_nodes - 1 else: raise ValueError("Graph not specified") if 'approach' in config['graph']: approach = config['graph'].get('approach') else: approach = "random_walk" graphfile_basename = os.path.splitext(os.path.basename(graphfile))[0] if graphfile else str(num_nodes) log_file_basename = "{}_{}_{}".format(config['logging'].get('log_file_name', fallback='fpgagraphlib'), config['app']['algo'], graphfile_basename) logger = logging.getLogger() logger.setLevel("DEBUG") handler = logging.StreamHandler() formatter_args = {"fmt": "{levelname:.1s}: {name:>20.20s}: {message:s}", "style": "{"} if sys.stderr.isatty() and sys.platform != 'win32': handler.setFormatter(ANSIColorFormatter(**formatter_args)) else: handler.setFormatter(logging.Formatter(**formatter_args)) handler.setLevel(config['logging'].get('console_log_level', fallback='INFO')) logger.addHandler(handler) log_file_number = 0 while os.path.exists("{}_{}.log".format(log_file_basename, log_file_number)): log_file_number += 1 alt_adj_val_data_name = None if not config['logging'].get('disable_logfile', fallback=False): file_log_level = config['logging'].get('file_log_level', fallback='DEBUG') logger.info("Logging to file {}_{}.log with level {}".format(log_file_basename, log_file_number, file_log_level)) # define a Handler which writes INFO messages or higher to the sys.stderr logfile = logging.FileHandler(filename="{}_{}.log".format(log_file_basename, log_file_number), mode='w') logfile.setLevel(file_log_level) # set a format which is simpler for console use formatter = logging.Formatter('%(levelname)-8s: %(name)-25s: %(message)s') # tell the handler to use this format logfile.setFormatter(formatter) # add the handler to the root logger logger.addHandler(logfile) alt_adj_val_data_name = "{}_{}.data".format(log_file_basename, log_file_number) # root is set up, now get logger for local logging logger = logging.getLogger('init') kwargs = dict() for k in config['arch']: try: kwargs[k] = eval(config['arch'].get(k)) except NameError: kwargs[k] = config['arch'].get(k) if "num_channels" not in kwargs: kwargs["num_channels"] = 3 kwargs["channel_bits"] = bits_for(kwargs["num_channels"] - 1) if "num_fpga" not in kwargs: if "num_pe_per_fpga" in kwargs and "num_pe" in kwargs: kwargs["num_fpga"] = (kwargs["num_pe"] + kwargs["num_pe_per_fpga"] - 1)//kwargs["num_pe_per_fpga"] else: kwargs["num_fpga"] = 1 if "num_pe" not in kwargs: if "num_pe_per_fpga" in kwargs: kwargs["num_pe"] = kwargs["num_pe_per_fpga"]*kwargs["num_fpga"] else: kwargs["num_pe"] = 8 if "num_pe_per_fpga" not in kwargs: kwargs["num_pe_per_fpga"] = (kwargs["num_pe"] + kwargs["num_fpga"] - 1)//kwargs["num_fpga"] if graphfile: logger.info("Reading graph from file {}".format(graphfile)) g = read_graph(graphfile, digraph=digraph, connected=True) num_nodes = nx.number_of_nodes(g) num_edges = nx.number_of_edges(g) else: logger.info("Generating graph with {} nodes and {} edges".format(num_nodes, num_edges)) g = generate_graph(num_nodes, num_edges, approach=approach, digraph=digraph) if graphsave: logger.info("Saving graph to file {}".format(graphsave)) export_graph(g, graphsave) if "memtype" not in kwargs: kwargs["memtype"] = "BRAM" if "use_hmc" in kwargs: logger.warning("\"use_hmc\" is deprecated. Use \"memtype = HMC\" instead.") if kwargs["use_hmc"]: kwargs["memtype"] = "HMC" if "use_ddr" in kwargs: logger.warning("\"use_ddr\" is deprecated. Use \"memtype = AXI\" instead.") if kwargs["use_ddr"]: kwargs["memtype"] = "AXI" if "updates_in_hmc" not in kwargs: kwargs["updates_in_hmc"] = False kwargs["inverted"] = inverted if kwargs["memtype"] == "HMC" and kwargs["updates_in_hmc"]: raise NotImplementedError("Can't use HMC for edges in 2-phase mode") updates_in_hmc = kwargs["updates_in_hmc"] if "updates_in_hmc" in kwargs else False if "num_nodes_per_pe" in kwargs or "max_edges_per_pe" in kwargs: logger.warning("Setting num_nodes_per_pe or max_edges_per_pe manually is no longer supported! Value ignored.") if 'partition' in config['graph']: kwargs["partition"] = config['graph'].get('partition') if 'partition_ufactor' in config['graph']: kwargs["partition_ufactor"] = config['graph'].getint('partition_ufactor') else: kwargs["partition_ufactor"] = 1 else: kwargs["partition"] = "robin" if "peidsize" not in kwargs: kwargs["peidsize"] = bits_for(kwargs["num_pe"]) algo_config_module = "{}.config".format(config['app']['algo']) algo = import_module(algo_config_module) algo_config = algo.Config(g, **kwargs) if config['logging'].get('disable_logfile', fallback=False): algo_config.vcdname = None else: algo_config.vcdname = "{}_{}".format(log_file_basename, log_file_number) algo_config.alt_adj_val_data_name = alt_adj_val_data_name algo_config.hmc_fifo_bits = 20 if sim else 32-bits_for(algo_config.addresslayout.num_pe-1) for pe in range(algo_config.addresslayout.num_pe): if not inverted: assert len(algo_config.adj_idx[pe]) <= algo_config.addresslayout.num_nodes_per_pe assert len(algo_config.adj_idx[pe]) <= 2**(algo_config.addresslayout.nodeidsize - algo_config.addresslayout.peidsize) if algo_config.memtype == "BRAM": assert len(algo_config.adj_val[pe]) <= algo_config.addresslayout.max_edges_per_pe return algo_config
def __init__(self, width=14, N_points=16383, max_delay=16383): self.init_submodules(width, N_points, max_delay) peak_height_bit, x_data_length_bit = self.init_csr(N_points) self.init_inout_signals(width) # is the autolock actively trying to detect peaks? This is set to true # if lock is requested and once the ramp is at start watching = Signal() # the following signals are property of the peak that the autolock is # trying to detet right now self.current_instruction_idx = Signal( bits_for(AUTOLOCK_MAX_N_INSTRUCTIONS - 1)) current_peak_height = Signal((peak_height_bit, True)) abs_current_peak_height = Signal.like(current_peak_height) current_wait_for = Signal(x_data_length_bit) self.comb += [ current_peak_height.eq( Array([ peak_height.storage for peak_height in self.peak_heights ])[self.current_instruction_idx]), current_wait_for.eq( Array([wait_for.storage for wait_for in self.wait_for ])[self.current_instruction_idx]), ] # after detecting the last peak, how many cycles have passed? waited_for = Signal(bits_for(N_points)) # after all peaks have been detected, how many cycles have passed? final_waited_for = Signal(bits_for(N_points)) # this is the signal that's used for detecting peaks sum_diff = Signal((len(self.sum_diff_calculator.output), True)) abs_sum_diff = Signal.like(sum_diff) self.comb += [ self.sum_diff_calculator.writing_data_now.eq( self.writing_data_now), self.sum_diff_calculator.restart.eq(self.at_start), self.sum_diff_calculator.input.eq(self.input), self.sum_diff_calculator.delay_value.eq(self.time_scale.storage), sum_diff.eq(self.sum_diff_calculator.output), ] # has this signal at the moment the same sign as the peak we are looking # for? sign_equal = Signal() # is this signal higher than the peak we are looking for? over_threshold = Signal() # since detecting the previous peak, has enough time passed? waited_long_enough = Signal() # have we detected all peaks (and can turn on the lock)? all_instructions_triggered = Signal() self.comb += [ sign_equal.eq((sum_diff > 0) == (current_peak_height > 0)), If(sum_diff >= 0, abs_sum_diff.eq(sum_diff)).Else(abs_sum_diff.eq(-1 * sum_diff)), If( current_peak_height >= 0, abs_current_peak_height.eq(current_peak_height), ).Else(abs_current_peak_height.eq(-1 * current_peak_height)), over_threshold.eq(abs_sum_diff >= abs_current_peak_height), waited_long_enough.eq(waited_for > current_wait_for), all_instructions_triggered.eq( self.current_instruction_idx >= self.N_instructions.storage), self.turn_on_lock.eq( all_instructions_triggered & (final_waited_for >= self.final_wait_time.storage)), ] self.sync += [ If( self.at_start, waited_for.eq(0), # fpga robust autolock algorithm registeres trigger events delayed. # Therefore, we give it a head start for `final_waited_for` final_waited_for.eq(ROBUST_AUTOLOCK_FPGA_DELAY), self.current_instruction_idx.eq(0), If(self.request_lock, watching.eq(1)).Else(watching.eq(0)), ).Else( # not at start If( ~self.request_lock, # disable `watching` if `request_lock` was disabled while # the ramp is running. This is important for slow scan # speeds when disabling the autolock and enabling it again # with different parameters. In this case we want to take # care that we start watching at start. watching.eq(0), ), If( self.writing_data_now & ~all_instructions_triggered & self.sweep_up, If( watching & sign_equal & over_threshold & waited_long_enough, self.current_instruction_idx.eq( self.current_instruction_idx + 1), waited_for.eq(0), ).Else(waited_for.eq(waited_for + 1)), ), If( self.writing_data_now & all_instructions_triggered & self.sweep_up, final_waited_for.eq(final_waited_for + 1), ), ), ] self.signal_out = [] self.signal_in = [] self.state_out = [ watching, self.turn_on_lock, sign_equal, over_threshold, waited_long_enough, ] self.state_in = []
def resolve_defaults(config, graphfile=None, num_nodes=None, num_edges=None, digraph=False, graphsave=None, sim=True, inverted=None): if not graphfile and not num_nodes: if 'graphfile' in config['graph']: graphfile = config['graph'].get('graphfile') elif 'nodes' in config['graph']: num_nodes = eval(config['graph'].get('nodes')) if not num_edges: if 'edges' in config['graph']: num_edges = eval(config['graph'].get('edges')) else: num_edges = num_nodes - 1 else: raise ValueError("Graph not specified") if 'approach' in config['graph']: approach = config['graph'].get('approach') else: approach = "random_walk" graphfile_basename = os.path.splitext(os.path.basename(graphfile))[0] if graphfile else str(num_nodes) log_file_basename = "{}_{}_{}".format(config['logging'].get('log_file_name', fallback='fpgagraphlib'), config['app']['algo'], graphfile_basename) logger = logging.getLogger() logger.setLevel("DEBUG") handler = logging.StreamHandler() formatter_args = {"fmt": "{levelname:.1s}: {name:>20.20s}: {message:s}", "style": "{"} if sys.stderr.isatty() and sys.platform != 'win32': handler.setFormatter(ANSIColorFormatter(**formatter_args)) else: handler.setFormatter(logging.Formatter(**formatter_args)) handler.setLevel(config['logging'].get('console_log_level', fallback='INFO')) logger.addHandler(handler) log_file_number = 0 while os.path.exists("{}_{}.log".format(log_file_basename, log_file_number)): log_file_number += 1 alt_adj_val_data_name = None if not config['logging'].get('disable_logfile', fallback=False): file_log_level = config['logging'].get('file_log_level', fallback='DEBUG') logger.info("Logging to file {}_{}.log with level {}".format(log_file_basename, log_file_number, file_log_level)) # define a Handler which writes INFO messages or higher to the sys.stderr logfile = logging.FileHandler(filename="{}_{}.log".format(log_file_basename, log_file_number), mode='w') logfile.setLevel(file_log_level) # set a format which is simpler for console use formatter = logging.Formatter('%(levelname)-8s: %(name)-25s: %(message)s') # tell the handler to use this format logfile.setFormatter(formatter) # add the handler to the root logger logger.addHandler(logfile) alt_adj_val_data_name = "{}_{}.data".format(log_file_basename, log_file_number) # root is set up, now get logger for local logging logger = logging.getLogger('init') kwargs = dict() for k in config['arch']: try: kwargs[k] = eval(config['arch'].get(k)) except NameError: kwargs[k] = config['arch'].get(k) if "num_channels" not in kwargs: kwargs["num_channels"] = 3 kwargs["channel_bits"] = bits_for(kwargs["num_channels"] - 1) if "num_fpga" not in kwargs: if "num_pe_per_fpga" in kwargs and "num_pe" in kwargs: kwargs["num_fpga"] = (kwargs["num_pe"] + kwargs["num_pe_per_fpga"] - 1)//kwargs["num_pe_per_fpga"] else: kwargs["num_fpga"] = 1 if "num_pe" not in kwargs: if "num_pe_per_fpga" in kwargs: kwargs["num_pe"] = kwargs["num_pe_per_fpga"]*kwargs["num_fpga"] else: kwargs["num_pe"] = 8 if "num_pe_per_fpga" not in kwargs: kwargs["num_pe_per_fpga"] = (kwargs["num_pe"] + kwargs["num_fpga"] - 1)//kwargs["num_fpga"] if graphfile: logger.info("Reading graph from file {}".format(graphfile)) g = read_graph(graphfile, digraph=digraph, connected=True) num_nodes = nx.number_of_nodes(g) num_edges = nx.number_of_edges(g) else: logger.info("Generating graph with {} nodes and {} edges".format(num_nodes, num_edges)) g = generate_graph(num_nodes, num_edges, approach=approach, digraph=digraph) if graphsave: logger.info("Saving graph to file {}".format(graphsave)) export_graph(g, graphsave) if "memtype" not in kwargs: kwargs["memtype"] = "BRAM" if "use_hmc" in kwargs: logger.warning("\"use_hmc\" is deprecated. Use \"memtype = HMC\" instead.") if kwargs["use_hmc"]: kwargs["memtype"] = "HMC" if "use_ddr" in kwargs: logger.warning("\"use_ddr\" is deprecated. Use \"memtype = AXI\" instead.") if kwargs["use_ddr"]: kwargs["memtype"] = "AXI" if "updates_in_hmc" not in kwargs: kwargs["updates_in_hmc"] = False if inverted != None: kwargs["inverted"] = inverted elif "arch" in kwargs: if kwargs["arch"] == "S": kwargs["inverted"] = False elif kwargs["arch"] == "M": kwargs["inverted"] = True else: ValueError("Unknown architecture \"{}\"".format(kwargs["arch"])) else: kwargs["inverted"] = (kwargs["num_fpga"] > 1) if kwargs["memtype"] == "HMC" and kwargs["updates_in_hmc"]: raise NotImplementedError("Can't use HMC for edges in 2-phase mode") updates_in_hmc = kwargs["updates_in_hmc"] if "updates_in_hmc" in kwargs else False if "num_nodes_per_pe" in kwargs or "max_edges_per_pe" in kwargs: logger.warning("Setting num_nodes_per_pe or max_edges_per_pe manually is no longer supported! Value ignored.") if 'partition' in config['graph']: kwargs["partition"] = config['graph'].get('partition') if 'partition_ufactor' in config['graph']: kwargs["partition_ufactor"] = config['graph'].getint('partition_ufactor') else: kwargs["partition_ufactor"] = 1 else: kwargs["partition"] = "robin" if "peidsize" not in kwargs: kwargs["peidsize"] = bits_for(kwargs["num_pe"]) algo_config_module = "{}.config".format(config['app']['algo']) algo = import_module(algo_config_module) algo_config = algo.Config(g, **kwargs) if config['logging'].get('disable_logfile', fallback=False): algo_config.vcdname = None else: algo_config.vcdname = "{}_{}".format(log_file_basename, log_file_number) algo_config.alt_adj_val_data_name = alt_adj_val_data_name algo_config.hmc_fifo_bits = 20 if sim else 32-bits_for(algo_config.addresslayout.num_pe-1) for pe in range(algo_config.addresslayout.num_pe): if not kwargs["inverted"]: assert len(algo_config.adj_idx[pe]) <= algo_config.addresslayout.num_nodes_per_pe assert len(algo_config.adj_idx[pe]) <= 2**(algo_config.addresslayout.nodeidsize - algo_config.addresslayout.peidsize) if algo_config.memtype == "BRAM": assert len(algo_config.adj_val[pe]) <= algo_config.addresslayout.max_edges_per_pe return algo_config
def __init__(self, platform, pads, size=2 * 1024 * 1024): self.size = size self.bus = bus = wishbone.Interface() self.reset = Signal() self.cfg1 = CSRStorage(fields=[ CSRField( "bb_out", size=4, description="Output bits in bit-bang mode"), CSRField("bb_clk", description="Serial clock line in bit-bang mode"), CSRField("bb_cs", description="Chip select line in bit-bang mode"), ]) self.cfg2 = CSRStorage(fields=[ CSRField("bb_oe", size=4, description="Output Enable bits in bit-bang mode"), ]) self.cfg3 = CSRStorage(fields=[ CSRField( "rlat", size=4, description="Read latency/dummy cycle count"), CSRField("crm", description="Continuous Read Mode enable bit"), CSRField("qspi", description="Quad-SPI enable bit"), CSRField("ddr", description="Double Data Rate enable bit"), ]) self.cfg4 = CSRStorage(fields=[ CSRField( "memio", offset=7, reset=1, description= "Enable memory-mapped mode (set to 0 to enable bit-bang mode)") ]) self.stat1 = CSRStatus(fields=[ CSRField( "bb_in", size=4, description="Input bits in bit-bang mode"), ]) self.stat2 = CSRStatus(1, fields=[], description="Reserved") self.stat3 = CSRStatus(1, fields=[], description="Reserved") self.stat4 = CSRStatus(1, fields=[], description="Reserved") cfg = Signal(32) cfg_we = Signal(4) cfg_out = Signal(32) self.comb += [ cfg.eq( Cat(self.cfg1.storage, self.cfg2.storage, self.cfg3.storage, self.cfg4.storage)), cfg_we.eq( Cat(self.cfg1.re, self.cfg2.re, self.cfg3.re, self.cfg4.re)), self.stat1.status.eq(cfg_out[0:8]), self.stat2.status.eq(cfg_out[8:16]), self.stat3.status.eq(cfg_out[16:24]), self.stat4.status.eq(cfg_out[24:32]), ] mosi_pad = TSTriple() miso_pad = TSTriple() cs_n_pad = TSTriple() clk_pad = TSTriple() wp_pad = TSTriple() hold_pad = TSTriple() self.specials += mosi_pad.get_tristate(pads.mosi) self.specials += miso_pad.get_tristate(pads.miso) self.specials += cs_n_pad.get_tristate(pads.cs_n) self.specials += clk_pad.get_tristate(pads.clk) self.specials += wp_pad.get_tristate(pads.wp) self.specials += hold_pad.get_tristate(pads.hold) reset = Signal() self.comb += [ reset.eq(ResetSignal() | self.reset), cs_n_pad.oe.eq(~reset), clk_pad.oe.eq(~reset), ] flash_addr = Signal(24) # size/4 because data bus is 32 bits wide, -1 for base 0 mem_bits = bits_for(int(size / 4) - 1) pad = Signal(2) self.comb += flash_addr.eq(Cat(pad, bus.adr[0:mem_bits - 1])) read_active = Signal() spi_ready = Signal() self.sync += [ If( bus.stb & bus.cyc & ~read_active, read_active.eq(1), bus.ack.eq(0), ).Elif( read_active & spi_ready, read_active.eq(0), bus.ack.eq(1), ).Else( bus.ack.eq(0), read_active.eq(0), ) ] o_rdata = Signal(32) self.comb += bus.dat_r.eq(o_rdata) self.specials += Instance( "spimemio", o_flash_io0_oe=mosi_pad.oe, o_flash_io1_oe=miso_pad.oe, o_flash_io2_oe=wp_pad.oe, o_flash_io3_oe=hold_pad.oe, o_flash_io0_do=mosi_pad.o, o_flash_io1_do=miso_pad.o, o_flash_io2_do=wp_pad.o, o_flash_io3_do=hold_pad.o, o_flash_csb=cs_n_pad.o, o_flash_clk=clk_pad.o, i_flash_io0_di=mosi_pad.i, i_flash_io1_di=miso_pad.i, i_flash_io2_di=wp_pad.i, i_flash_io3_di=hold_pad.i, i_resetn=~reset, i_clk=ClockSignal(), i_valid=bus.stb & bus.cyc, o_ready=spi_ready, i_addr=flash_addr, o_rdata=o_rdata, i_cfgreg_we=cfg_we, i_cfgreg_di=cfg, o_cfgreg_do=cfg_out, ) platform.add_source("rtl/spimemio.v")