def generate_dit_files(fft_length, tf_width): """ Generate the fft files to perform an fft. Args: fft_length: Length of the FFT. tf_width: Number of bits in each real number of each twiddle factor. """ get_builddir() inputfiles = generate_math_files() inputfiles.append(copyfile('fft', 'butterfly.v')) log_fft_length = math.log(fft_length) / math.log(2) if log_fft_length != int(log_fft_length): raise ValueError("fft_length must be a power of two") log_fft_length = int(log_fft_length) # Generate the dit.v file dit_fn = 'dit_{0}'.format(fft_length) inputfiles.append( format_template('fft', 'dit.v.t', dit_fn, {'N': fft_length})) # Generate twiddle factor file. tf_fn = 'twiddlefactors_{0}'.format(fft_length) vs = [ cmath.exp(-i * 2j * cmath.pi / fft_length) for i in range(0, fft_length / 2) ] tfs = cs_to_dicts(vs, tf_width * 2, clean1=True) tf_dict = { 'N': fft_length, 'log_N': log_fft_length, 'tf_width': tf_width, 'tfs': tfs, } inputfiles.append( format_template('fft', 'twiddlefactors.v.t', tf_fn, tf_dict)) return inputfiles
def generate_channelizer_executable(name, n_chans, width, filter_length, defines): """ Generate an icarus verilog channelizer executable. Args: name: A name to identify the executable by. n_chans: Number of channels to split into. width: The width of a complex number (actually required so we can get the twiddle factor widths for fft). filter_length: The length of each filter in the filterbank. defines: Macro definitions for the verilog files. """ builddir = get_builddir() inputfiles = generate_channelizer_files(n_chans, width, filter_length) dut_channelizer_fn = copyfile('channelizer', 'dut_channelizer.v') executable = "channelizer_{name}".format(name=name) executable = os.path.join(config.builddir, 'channelizer', executable) inputfilestr = ' '.join(inputfiles + [dut_channelizer_fn]) defines.update({ 'N': n_chans, 'LOG_N': int(math.ceil(math.log(n_chans)/math.log(2))), 'FLTLEN': filter_length, 'LOG_FLTLEN': int(math.ceil(math.log(filter_length)/math.log(2))), }) definestr = make_define_string(defines) cmd = ("iverilog -o {executable} {definestr} {inputfiles}" ).format(executable=executable, definestr=definestr, inputfiles=inputfilestr) logger.debug(cmd) os.system(cmd) return executable
def generate_dit_files(fft_length, tf_width): """ Generate the fft files to perform an fft. Args: fft_length: Length of the FFT. tf_width: Number of bits in each real number of each twiddle factor. """ get_builddir() inputfiles = generate_math_files() inputfiles.append(copyfile('fft', 'butterfly.v')) log_fft_length = math.log(fft_length)/math.log(2) if log_fft_length != int(log_fft_length): raise ValueError("fft_length must be a power of two") log_fft_length = int(log_fft_length) # Generate the dit.v file dit_fn = 'dit_{0}'.format(fft_length) inputfiles.append( format_template('fft', 'dit.v.t', dit_fn, {'N': fft_length})) # Generate twiddle factor file. tf_fn = 'twiddlefactors_{0}'.format(fft_length) vs = [cmath.exp(-i*2j*cmath.pi/fft_length) for i in range(0, fft_length/2)] tfs = cs_to_dicts(vs, tf_width*2, clean1=True) tf_dict = { 'N': fft_length, 'log_N': log_fft_length, 'tf_width': tf_width, 'tfs': tfs, } inputfiles.append( format_template('fft', 'twiddlefactors.v.t', tf_fn, tf_dict)) return inputfiles
def generate_sample_msg_splitter_B100_image(name, defines=config.default_defines): message_builddir= os.path.join(config.builddir, 'message') inputfiles = generate_sample_msg_splitter_files() inputfiles.append(copyfile('message', 'qa_sample_msg_splitter.v')) b100.make_make(name, message_builddir, inputfiles, defines) for f in inputfiles: b100.prefix_defines(f, defines) b100.synthesise(name, message_builddir)
def generate_slicer_files(): """ Generate the files for the message slicer. """ check_builddir() inputfiles = ['message_slicer.v'] outputfiles = [] for f in inputfiles: outputfiles.append(copyfile('message', f)) return outputfiles
def generate_qa_wrapper_files(): """ Generate the files to make the 'nothing' block. """ uhd_builddir = os.path.join(config.builddir, 'uhd') if not os.path.exists(uhd_builddir): os.makedirs(uhd_builddir) inputfiles = [copyfile('uhd', 'qa_wrapper.v')] inputfiles += generate_sample_msg_splitter_files() inputfiles += generate_stream_combiner_files() return inputfiles
def generate_qa_wrapper_files(): """ Generate the files to make the 'nothing' block. """ uhd_builddir= os.path.join(config.builddir, 'uhd') if not os.path.exists(uhd_builddir): os.makedirs(uhd_builddir) inputfiles = [copyfile('uhd', 'qa_wrapper.v')] inputfiles += generate_sample_msg_splitter_files() inputfiles += generate_stream_combiner_files() return inputfiles
def generate_dit_executable(name, fft_length, defines): log_fft_length = math.log(fft_length) / math.log(2) if log_fft_length != int(log_fft_length): raise ValueError("fft_length must be a power of two") log_fft_length = int(log_fft_length) get_builddir() defines['N'] = fft_length defines['LOG_N'] = log_fft_length dut_dit_fn = copyfile('fft', 'dut_dit.v') inputfiles = generate_dit_files(fft_length, defines['WIDTH'] / 2) executable = "dit_{name}".format(name=name) executable = os.path.join(config.builddir, 'fft', executable) inputfilestr = ' '.join(inputfiles + [dut_dit_fn]) definestr = make_define_string(defines) cmd = ("iverilog -o {executable} {definestr} {inputfiles}").format( executable=executable, definestr=definestr, inputfiles=inputfilestr) logger.debug(cmd) os.system(cmd) return executable
def generate_stream_combiner_executable( method, n_streams, width, input_buffer_length, max_packet_length): """ Generate an executable for the stream combiner DUT. Use for MyHDL testing. Args: method: What are we generating for (icarus or xilinx). n_streams: Number of message streams to combine. width: Bit width of a data block. input_buffer_length: Number of data blocks in each input buffer. max_packet_length: Maximum number of data blocks in a packet. """ assert(method in ('icarus', 'xilinx')) check_builddir() # Check that buffer lengths are power of two log_input_buffer_length = math.log(input_buffer_length)/math.log(2) if log_input_buffer_length != int(log_input_buffer_length): raise ValueError("input_buffer_length must be a power of 2") dut_msc_fn = copyfile('message', 'dut_message_stream_combiner.v') executable = "message_stream_combiner" executable = os.path.join(config.builddir, 'message', executable) inputfiles = generate_stream_combiner_files() inputfilestr = ' '.join(inputfiles + [dut_msc_fn]) cmd = ("iverilog -o {executable} -DN_STREAMS={n_streams} -DLOG_N_STREAMS={log_n_streams} " "-DWIDTH={width} -DINPUT_BUFFER_LENGTH={input_buffer_length} " "-DLOG_INPUT_BUFFER_LENGTH={log_input_buffer_length} " "-DMAX_PACKET_LENGTH={max_packet_length} " "-DLOG_MAX_PACKET_LENGTH={log_max_packet_length} " "{inputfiles} " ).format(executable=executable, n_streams=n_streams, log_n_streams=logceil(n_streams), width=width, input_buffer_length=input_buffer_length, log_input_buffer_length=int(log_input_buffer_length), max_packet_length=max_packet_length, log_max_packet_length=logceil(max_packet_length), inputfiles=inputfilestr) logger.debug(cmd) os.system(cmd) return executable
def generate_channelizer_files(n_chans, width, filter_length): """ Generate the channelizer module files. Args: n_chans: Number of channels to split into. width: The width of a complex number (actually required so we can get the twiddle factor widths for fft). filter_length: The length of each filter in the filterbank. """ builddir = get_builddir() logn = math.log(n_chans)/math.log(2) if int(logn) != logn: raise ValueError("Number of channels must be a power of two.") # Divide width by 2 since generate_dit_files takes real width not complex width. inputfiles = generate_dit_files(n_chans, width/2) inputfiles += generate_filterbank_files(filter_length) inputfiles.append(copyfile('channelizer', 'channelizer.v')) # Remove repeated dependencies inputfiles = list(set(inputfiles)) return inputfiles
def generate_dit_executable(name, fft_length, defines): log_fft_length = math.log(fft_length)/math.log(2) if log_fft_length != int(log_fft_length): raise ValueError("fft_length must be a power of two") log_fft_length = int(log_fft_length) get_builddir() defines['N'] = fft_length defines['LOG_N'] = log_fft_length dut_dit_fn = copyfile('fft', 'dut_dit.v') inputfiles = generate_dit_files(fft_length, defines['WIDTH']/2) executable = "dit_{name}".format(name=name) executable = os.path.join(config.builddir, 'fft', executable) inputfilestr = ' '.join(inputfiles + [dut_dit_fn]) definestr = make_define_string(defines) cmd = ("iverilog -o {executable} {definestr} {inputfiles}" ).format(executable=executable, definestr=definestr, inputfiles=inputfilestr) logger.debug(cmd) os.system(cmd) return executable
def generate_slicer_executable(method, n_slices, width, buffer_length): """ Generate the files for creating message streams. Args: method: What are we generating for (icarus or xilinx). n_slices: How many times bigger the input is that width. width: Bit width of a data block. buffer_length: Number of data blocks in the buffer. """ assert(method in ('icarus', 'xilinx')) check_builddir() # Check that buffer lengths are power of two log_buffer_length = math.log(buffer_length)/math.log(2) if log_buffer_length != int(log_buffer_length): raise ValueError("buffer_length must be a power of 2") dut_ms_fn = copyfile('message', 'dut_message_slicer.v') inputfiles = generate_slicer_files() executable = "message_slicer" executable = os.path.join(config.builddir, 'message', executable) inputfiles = [os.path.join(config.builddir, 'message', f) for f in inputfiles] inputfilestr = ' '.join(inputfiles + [dut_ms_fn]) cmd = ("iverilog -o {executable} -DN_SLICES={n_slices} " "-DLOG_N_SLICES={log_n_slices} " "-DWIDTH={width} -DBUFFER_LENGTH={buffer_length} " "-DLOG_BUFFER_LENGTH={log_buffer_length} " "{inputfiles} " ).format(executable=executable, n_slices=n_slices, log_n_slices=int(math.ceil(math.log(n_slices)/math.log(2))), width=width, buffer_length=buffer_length, log_buffer_length=int(log_buffer_length), inputfiles=inputfilestr) logger.debug(cmd) os.system(cmd) return executable
def generate_qa_wrapper_null_files(): uhd_builddir = os.path.join(config.builddir, 'uhd') if not os.path.exists(uhd_builddir): os.makedirs(uhd_builddir) inputfiles = [copyfile('uhd', 'qa_wrapper_null.v')] return inputfiles
def generate_qa_wrapper_null_files(): uhd_builddir= os.path.join(config.builddir, 'uhd') if not os.path.exists(uhd_builddir): os.makedirs(uhd_builddir) inputfiles = [copyfile('uhd', 'qa_wrapper_null.v')] return inputfiles
def generate_sample_msg_splitter_files(): check_builddir() return [copyfile('message', 'sample_msg_splitter.v')]