def connect(cls, sim_core, usrps, bee7blades, hosts, app_settings): USRPS_PER_BLADE = 32 # Create NULL source of "zero" partial products null_items = ['null[(0);(0)]', 'null[(0);(0)]'] null_src = rfnocsim.Producer(sim_core, 'NULL_SRC', 4, null_items) if app_settings['domain'] == 'frequency': null_src.set_rate(app_settings['samp_rate']*(1.0 + (float(app_settings['fft_overlap'])/app_settings['fft_size']))) else: null_src.set_rate(app_settings['samp_rate']) # Reshape BEE7s # The blades are arranged in 2D Torus network with 4 blades across # each dimension (4x4 = 16) bee7grid = [] for r in range(4): bee7row = [] for c in range(4): blade = bee7blades[4*r + c] pp_chans = list(range(64*c,64*(c+1))) for i in range(4): Topology_2D_4x4_Torus.config_bitstream( blade.fpgas[i], app_settings, pp_chans, pp_chans[i*16:(i+1)*16], 256, (r==c)) bee7row.append(blade) bee7grid.append(bee7row) # USRP-Bee7 Connections # Blades across the diagonal are connected to USRPs for b in range(4): for u in range(USRPS_PER_BLADE): sim_core.connect_bidir( usrps[USRPS_PER_BLADE*b + u], 0, bee7grid[b][b], len(hw.Bee7Fpga.EXT_IO_LANES)*(u/8) + hw.Bee7Fpga.BP_BASE+(u%8), 'SAMP') sim_core.connect_bidir( hosts[b], 0, bee7grid[b][b], hw.Bee7Fpga.FP_BASE+8, 'CONFIG', ['blue','blue']) # Bee7-Bee7 Connections null_srcs = [] for r in range(4): # Traverse across row for c in range(4): # Traverse across col for f in range(4): samp_in_base = len(hw.Bee7Fpga.EXT_IO_LANES)*f + hw.Bee7Fpga.BP_BASE samp_out_base = len(hw.Bee7Fpga.EXT_IO_LANES)*f + hw.Bee7Fpga.BP_BASE+8 pp_in_base = len(hw.Bee7Fpga.EXT_IO_LANES)*f + hw.Bee7Fpga.FP_BASE pp_out_base = len(hw.Bee7Fpga.EXT_IO_LANES)*f + hw.Bee7Fpga.FP_BASE+8 if r != c: sim_core.connect_multi_bidir( bee7grid[r][(c+3)%4], list(range(samp_out_base,samp_out_base+8)), bee7grid[r][c], list(range(samp_in_base,samp_in_base+8)), 'SAMP_O2I', ['black','blue']) sim_core.connect_multi_bidir( bee7grid[r][c], list(range(pp_out_base,pp_out_base+8)), bee7grid[(r+1)%4][c], list(range(pp_in_base,pp_in_base+8)), 'PP_O2I', ['black','blue']) else: for i in range(8): sim_core.connect(null_src, 0, bee7grid[(r+1)%4][c], pp_in_base + i)
def __init__(self, sim_core, index, app_settings): rfnocsim.SimComp.__init__(self, sim_core, name='USRP_%03d' % (index), ctype=rfnocsim.comptype.hardware) # USRP i carries data for radio 2i and 2i+1 interleaved into one stream self.index = index items = [ rfnocsim.DataStream.submatrix_gen('rx', [2 * index]), rfnocsim.DataStream.submatrix_gen('rx', [2 * index + 1]) ] # Samples are 4 bytes I and Q latency = (self.RADIO_LATENCY + self.IO_LATENCY / 2) * self.get_tick_rate() if app_settings['domain'] == 'frequency': # Max latency per direction depends on the FFT size and sample rate latency += self.__get_fft_latency(app_settings['fft_size'], app_settings['samp_rate'], self.get_tick_rate()) # An X310 Radio has two producers (RX data) and consumers (TX data) (i.e. two ethernet ports) # Both ports can carry data from both radio frontends self.sources = ([ rfnocsim.Producer(sim_core, self.name + '/TX0', self.BPI, items, self.MAX_SAMP_RATE, latency), rfnocsim.Producer(sim_core, self.name + '/TX1', self.BPI, items, self.MAX_SAMP_RATE, latency) ]) self.sinks = ([ rfnocsim.Consumer(sim_core, self.name + '/RX0', self.BPI * self.MAX_SAMP_RATE, latency), rfnocsim.Consumer(sim_core, self.name + '/RX1', self.BPI * self.MAX_SAMP_RATE, latency) ]) # The actual sample rate depends over the wire depends on the radio sample rate, # the FFT size and FFT overlap for src in self.sources: if app_settings['domain'] == 'frequency': src.set_rate(app_settings['samp_rate'] * (1.0 + (float(app_settings['fft_overlap']) / app_settings['fft_size']))) else: src.set_rate(app_settings['samp_rate'])
def __init__(self, sim_core, index, num_coeffs, switch_ports, app_settings): rfnocsim.SimComp.__init__(self, sim_core, name='MGMT_HOST_%03d' % (index), ctype=rfnocsim.comptype.other) if app_settings['domain'] == 'frequency': k = app_settings['fft_size'] else: k = app_settings['fir_taps'] self.sources = dict() self.sinks = dict() for l in range(switch_ports): self.sources[l] = rfnocsim.Producer( sim_core, '%s/COEFF_%d' % (self.name, l), 4, ['coeff_%03d[%d]' % (index, l)], (10e9 / 8) / switch_ports, 0) self.sinks[l] = rfnocsim.Consumer( sim_core, self.name + '%s/ACK%d' % (self.name, l)) self.sources[l].set_rate(k * num_coeffs * app_settings['coherence_rate'])