def vcd2wave(vcdfile, trigname, cfg=None, delta=4): """Simple conversion of VCD file. Requires passing of the name of the trigger signal, normally the highest running clock in the system. The signals are sampled according to that clock and returned as schematic waveform for wavedrom display""" vcd = parse_vcd(vcdfile) vcd_dict = {} if cfg == None: for nm, t in vcd.items(): trace = t['nets'][0] identifier = trace['hier'] + '.' + trace['name'] s = int(trace['size']) tp = trace['type'] if 'tv' in t: vcd_dict[identifier] = (s, t['tv'], tp, None) else: print("Warning: no timevalue for %s" % identifier) vcd_dict[identifier] = (s, [(0, 'x')], tp, None) print(t) else: for nm, t in vcd.items(): trace = t['nets'][0] identifier = trace['hier'] + '.' + trace['name'] s = int(trace['size']) tp = trace['type'] if 'tv' in t: if identifier in cfg: vcd_dict[identifier] = (s, t['tv'], tp, cfg[identifier]) elif identifier == trigname: vcd_dict[trigname] = (s, t['tv'], tp, None) else: print("Warning: no timevalue for %s" % identifier) wdwave = {} signals = [] try: trigger = vcd_dict[trigname] # Get trigger signal except KeyError: print("Choose one of:") for n, _ in vcd_dict.items(): print(n) raise ValueError("Signal not found") for n, wave in vcd_dict.items(): try: wdwaveform, data = to_wave(wave, trigger, delta) except AssertionError: print("Failed to create waveform for '%s'" % n) if data != "": trace = {'name': n, 'wave': wdwaveform, 'data': data} else: trace = {'name': n, 'wave': wdwaveform} signals.append(trace) wdrom = {'signal': signals} return wdrom
def vcd2wavedrom(): vcd = parse_vcd(config['input']) timescale = int(re.match(r'(\d+)', get_timescale()).group(1)) vcd_dict = {} for i in vcd: vcd_dict[vcd[i]['nets'][0]['hier']+'.'+vcd[i]['nets'][0]['name']] = \ vcd[i]['tv'] homogenize_waves(vcd_dict, timescale) dump_wavedrom(vcd_dict, timescale)
def extract_from_vcd(filename): rawdata = parse_vcd(filename) # Get raw data from file # Find the lines corresponding to clock and databit for key in rawdata.keys(): if (rawdata[key]['nets'][0]['size'] == '1'): if (rawdata[key]['nets'][0]['name'] == 'databit'): # databit will be shortened as db db_line = key elif (rawdata[key]['nets'][0]['name'] == 'clock'): # clock will be shortened as ck ck_line = key db_values = rawdata[db_line]['tv'] ck_values = rawdata[ck_line]['tv'] # Clock tick counter, used to find a bit's position in the PS/2 frame ck_count = 0 # 0 is start bit, 10 is stop bit ck_real = 0 databyte = 0 # Current databyte csum = 0 # Check sum extracted_bytes = [] for (t, ck) in ck_values: if ck == '0' and ck_count > 0: # If the value considered is a clock tick (skip default starting value) ck_real += 1 db = find_val_at_t(db_values, t) # Find the databit value at that time bitpos = ck_count % 11 if (bitpos == 0) and (db == 0): # If the considered bit is the start bit databyte = 0 # Reset the "output" databyte, csum = 0 # reset the check sum ck_count += 1 # and read the folowing bits #print ck_count, 'Start bit' elif (bitpos > 0) and (bitpos < 9): # If the considered bit is a databit databyte += (db << (bitpos - 1)) csum += db ck_count += 1 #print ck_count, 'Data bit' elif (bitpos == 9) and (csum % 2 == db): # If the considered bit is the parity bit and if its value is correct extracted_bytes.append(databyte) ck_count += 1 #print ck_count, 'Parity bit' elif (bitpos == 10) and (db == 1): # If the considered bit is the stop bit ck_count += 1 # Ignore it and read the folowing bits #print ck_count, 'Stop bit' # # # This code WILL skip some bits if they don't match PS/2 frame !! if (ck_real > ck_count): print 'Exactly', (ck_real - ck_count), 'bits were skipped while decoding.' return extracted_bytes
__status__ = "Prototype" import os import sys import pprint from Verilog_VCD import parse_vcd, get_endtime # Verilog_VCD.py version 1.11 taken from # https://pypi.org/project/Verilog_VCD/#files pp = pprint.PrettyPrinter(indent=4) fn = os.path.basename(__file__) fns = fn.split('.') vcd = parse_vcd(fns[0] + '.vcd') start = 0 end = get_endtime() scale = 1000 for f in fns[1:-1]: if f.startswith("start="): start = int(f[6:]) if start > get_endtime(): start = get_endtime() if start < 0: start = 0 if start > end: start = end # print("start: " + str(start))
return None def decode_pn(dec, value): if dec['rdn'] == dec['rdp'] == value: return "±" elif dec['rdn'] == value: return '-' elif dec['rdp'] == value: return '+' else: return '?' vcd = parse_vcd(args.filename, siglist=args.signals) for sidid, sigval in vcd.items(): net = sigval['nets'][0] print(net['hier'] + '.' + net['name'] + '\t', end='') current_token = "" i = 0 for v in periodic_scanning(sigval['tv']): if args.group_by > 0 and i - args.group_shift >= 0 and (i - args.group_shift) % args.group_by == 0: print(' ', end='') if args.decode_8b10b: dec = decode_d(current_token)
from Verilog_VCD import parse_vcd import json waveform = parse_vcd('verilator.vcd') result = {'signal': []} endtime = 500 for k in waveform.keys(): signal = waveform[k] nets = signal['nets'][0] tv = signal['tv'] ''' if nets['name'] != 'aclk' and nets['name'] != 'm_axis_tdata[18:0]': continue ''' signal_name = "{}.{}".format(nets['hier'], nets['name']) signals = [] current = 0 data = [] for i in range(0, endtime): if current < len(tv): current_timestamp = tv[current] else: current_timestamp = (endtime + 1, '') if i < current_timestamp[0]: signals.append('.') elif i == current_timestamp[0]: if nets['size'] == '1':
def parse_vcd(self): self.vcd = parse_vcd(self.vcd_name, siglist=self.vcd_signals, opt_timescale=self.timeunit) self.gen_signal_map()
global signals signal = signals[name] curvalstr = signal.timevals[signal.timeslot][1] if curvalstr != 'x': curvalstr = '{0:08x}'.format(int(curvalstr, 2)) return(curvalstr) if __name__ == '__main__': # --- load debug information load_debug() table = parse_vcd('system.vcd',siglist = \ ['system_tb.clk', \ 'system_tb.uut.picorv32_core.reg_pc[31:0]', \ 'system_tb.uut.picorv32_core.\cpuregs[10][31:0]', \ 'system_tb.uut.picorv32_core.\cpuregs[12][31:0]', \ 'system_tb.uut.picorv32_core.mem_addr[31:0]', \ 'system_tb.uut.picorv32_core.mem_rdata[31:0]', \ 'system_tb.uut.picorv32_core.mem_wdata[31:0]', \ 'system_tb.uut.picorv32_core.mem_wstrb[3:0]', \ 'system_tb.uut.picorv32_core.mem_valid', 'system_tb.uut.picorv32_core.mem_ready']) codes = list(table.keys()) globals = ['x'] global signals signals = {} pctimevals = [] watchadr = {} for var in globals: watchadr[globalmap[var].adr] = var for code in table.keys(): name = table[code]['nets'][0]['name']
def main(): ## # Set Global Program Switches ## # General Switches sws.VERBOSE = 0 sws.WARNINGS = False # DEBUG Switches sws.DEBUG = False sws.DEBUG_PRINTS = False ## # Check argv ## if (len(sys.argv) != 11): print "Usage: ./analyze.py" print " <start time>" print " <time limit>" print " <time resolution>" print " <DUT top module>" print " <num. malicious cntrs>" print " <deterministic signal basename (for malicious simulation)>" print " <non-deterministic signal basename (for malicious simulation)>" print " <input dot file>" print " <input vcd file>" print " <output json file (basename)>" sys.exit(-1) ## # Start Overall Timer ## overall_start_time = time.time() ## # Input Files ## print "--------------------------------------------------------------------------------" print "Loading Configuration Inputs..." start_time = int(sys.argv[1]) time_limit = int(sys.argv[2]) time_resolution = int(sys.argv[3]) dut_top_module = sys.argv[4] num_mal_cntrs = int(sys.argv[5]) mal_d_sig_basename = sys.argv[6] mal_n_sig_basename = sys.argv[7] dot_file = sys.argv[8] vcd_file = sys.argv[9] json_base_filename = sys.argv[10] print print "Start Time: ", start_time print "Time Limit: ", time_limit print "Time Resolution: ", time_resolution print "DUT Top Module: ", dut_top_module print "Num. Malicious Cntrs: ", num_mal_cntrs print "Deter. Signal Basename: ", mal_d_sig_basename print "Nondeter. Signal Basename: ", mal_n_sig_basename print "Num. Malicious Cntrs: ", num_mal_cntrs print "DOT File: ", dot_file print "VCD File: ", vcd_file print "(Output) JSON Base Filename:", json_base_filename ## # Load DOT file ## print "--------------------------------------------------------------------------------" print "Loading Dot File..." task_start_time = time.time() signals = parse_file(dot_file) task_end_time = time.time() calculate_and_print_time(task_start_time, task_end_time) ## # Load VCD file ## print "--------------------------------------------------------------------------------" print "Loading VCD File..." print task_start_time = time.time() # Get VCD data vcd, signals = parse_vcd(vcd_file, signals, types={"reg", "wire", "integer"}) # Get Timescale Info timescale_str = get_timescale() timescale_units = re.sub(r'\d+', '', timescale_str) timescale_val = int(timescale_str.rstrip('fpnums')) print "Timescale: %d (%s)" % (timescale_val, timescale_units) # Get Simulation Time sim_end_time = int(get_endtime()) scaled_sim_end_time = sim_end_time * timescale_val print "Simulation End Time: %d (%s)" % (scaled_sim_end_time, timescale_units) task_end_time = time.time() print calculate_and_print_time(task_start_time, task_end_time) ## # Check inputs ## # Check simulation coverage check_simulation_coverage(signals, dut_top_module) # Check time limits print "--------------------------------------------------------------------------------" print "Checking time limits..." if time_limit == -1: time_limit = sim_end_time elif time_limit < -1: print "ERROR: time limit cannot be negative." print "Exception is -1, which indicates entire simulation time." sys.exit(1) # Print Simulation Time Settings print print "Start Time: %d" % (start_time) print "Time Limit: %d" % (time_limit) print "Time Resolution: %d" % (time_resolution) # Checked loaded Dot/VCD file data ## if sws.DEBUG_PRINTS: print "--------------------------------------------------------------------------------" print "All Signals:" for signal_name in signals: signals[signal_name].debug_print() print ## # Identify Coalesced Counters ## print "--------------------------------------------------------------------------------" print "Identifying Coalesced Counter Candidates..." task_start_time = time.time() coal_counters = generate_coalesced_counters(signals, vcd, num_mal_cntrs, dut_top_module, mal_d_sig_basename, mal_n_sig_basename) task_end_time = time.time() print print "Found " + str(len(coal_counters)) + " possible coalesced counters." if sws.DEBUG_PRINTS and coal_counters: for counter in coal_counters: print " Coalesced Counter: %s (Size: %d)" % (counter.fullname(), counter.width) counter.debug_print() coal_counter_sizes = get_counter_sizes(coal_counters) print calculate_and_print_time(task_start_time, task_end_time) ## # Identify Distributed Counters ## print "--------------------------------------------------------------------------------" print "Identifying Distributed Counter Candidates..." task_start_time = time.time() dist_counters = generate_distributed_counters(signals, vcd, num_mal_cntrs, dut_top_module, mal_d_sig_basename, mal_n_sig_basename) task_end_time = time.time() print print "Found " + str( len(dist_counters)) + " possible distributed counters." if sws.DEBUG_PRINTS and dist_counters: for dist_counter in dist_counters: print " Distributed Counter: %s (Size: %d)" % ( dist_counter.fullname(), dist_counter.width) dist_counter.debug_print() dist_counter_sizes = get_counter_sizes(dist_counters) print calculate_and_print_time(task_start_time, task_end_time) ## # Write counter sizes to JSON file ## export_sizes_json(coal_counter_sizes, dist_counter_sizes, json_base_filename + ".sizes.json") ## # Classify counter behaviors ## analyze_counters(signals, vcd, coal_counters, dist_counters, start_time, time_limit, time_resolution, json_base_filename) ## # Stop Overall Timer ## overall_end_time = time.time() calculate_and_print_time(overall_start_time, overall_end_time)
import struct import sys from parse_verilog_header import ParseParams if len(sys.argv) != 3: exit("give vcd as first arg, params as 2nd") params = ParseParams(sys.argv[2]).parse() N = params['freq_bins'] data_width = params['data_width'] freq_d_width = params['freq_data_w'] print("N: %d, data width: %d, freq width %d" % (N, data_width, freq_d_width)) vcd = parse_vcd(sys.argv[1]) def twos_comp(val, bits): """compute the 2's complement of int value val""" if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255 val = val - (1 << bits) # compute negative value return val # return positive value as is def fetch_data(name, bitlength=freq_d_width): for key in vcd.keys(): if name in vcd[key]['nets'][0]['name']: data = (vcd[key]['tv']) ints = []
def to_json(filename, dump_signals, endtime): waveform = parse_vcd(filename) if endtime == -1: endtime = get_endtime() result = {'signal': []} for k in waveform.keys(): signal = waveform[k] nets = signal['nets'][0] tv = signal['tv'] if len(dump_signals) != 0 and nets['name'] not in dump_signals: continue signal_name = "{}.{}".format(nets['hier'], nets['name']) signals = [] current = 0 data = [] for i in range(0, endtime): if current < len(tv): current_timestamp = tv[current] else: current_timestamp = (endtime + 1, '') if i < current_timestamp[0]: signals.append('.') elif i == current_timestamp[0]: if nets['size'] == '1': signals.append(current_timestamp[1]) else: signals.append('=') str_to_add = "" try: str_to_add = int(current_timestamp[1], 2) except: str_to_add = current_timestamp[1] data.append(str_to_add) current = current + 1 wave = { "name": signal_name, "wave": ''.join(signals), "data": [str(dt) for dt in data] } result['signal'].append(wave) index = 0 while True: r = result['signal'] ok = True for i in range(0, len(r)): if r[i]['wave'][index] != '.': ok = False if not ok: index = index + 1 else: for i in range(0, len(r)): r[i]['wave'] = r[i]['wave'][:index] + r[i]['wave'][(index + 1):] if index >= len(r[0]['wave']): break return json.dumps(result)