diff --git a/bsg_clk_gen_pearl/.gitignore b/bsg_clk_gen_pearl/.gitignore new file mode 100644 index 0000000..afad9ae --- /dev/null +++ b/bsg_clk_gen_pearl/.gitignore @@ -0,0 +1,3 @@ +basejump_stl/ +bsg_cadenv/ +*.pyc diff --git a/bsg_clk_gen_pearl/Makefile b/bsg_clk_gen_pearl/Makefile new file mode 100644 index 0000000..e155bdf --- /dev/null +++ b/bsg_clk_gen_pearl/Makefile @@ -0,0 +1,35 @@ +THIS_DIR :=$(realpath $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))) + +GIT_CLONE_STYLE :=ssh +#GIT_CLONE_STYLE :=https + +ifeq ($(GIT_CLONE_STYLE),ssh) + GITHUB :=git@github.com: + +else ifeq ($(GIT_CLONE_STYLE),https) + GITHUB :=https://github.com/ + +endif + +basejump_stl_dir :=$(THIS_DIR)/basejump_stl +basejump_stl_url :=$(GITHUB)bespoke-silicon-group/basejump_stl +basejump_stl_commit :=nonsynth_osc + +bsg_cadenv_dir :=$(THIS_DIR)/bsg_cadenv +bsg_cadenv_url :=$(GITHUB)bespoke-silicon-group/bsg_cadenv +bsg_cadenv_commit :=master + +all_repos = $(subst _url,.repo,$(filter %_url,$(.VARIABLES))) + +all: $(all_repos) + +%.repo: + -git clone $($*_url) $($*_dir) + -cd $($*_dir) ; git checkout $($*_commit) + +clean: are_you_sure + rm -rf $(subst .repo,,$(all_repos)) + +DISABLE_SAFETY_PROMPT ?= false +are_you_sure: + @$(DISABLE_SAFETY_PROMPT) || (echo -n "Are you sure [Y/n]? " && read ans && ([ "$$ans" == "Y" ] || [ "$$ans" == "y" ])) diff --git a/bsg_clk_gen_pearl/tcl/filelist.tcl b/bsg_clk_gen_pearl/tcl/filelist.tcl new file mode 100644 index 0000000..89b6cfd --- /dev/null +++ b/bsg_clk_gen_pearl/tcl/filelist.tcl @@ -0,0 +1,51 @@ +### filelist.tcl + +#------------------------------------------------------------------------------- +# Do NOT arbitrarily change the order of files. Some module and macro +# definitions may be needed by the subsequent files +#------------------------------------------------------------------------------- + +set bsg_designs_target_dir $::env(BSG_DESIGNS_TARGET_DIR) +set basejump_stl_dir $::env(BASEJUMP_STL_DIR) + +set SVERILOG_INCLUDE_PATHS [join " + $basejump_stl_dir/bsg_clk_gen + $basejump_stl_dir/bsg_misc + $basejump_stl_dir/bsg_tag +"] + +set SVERILOG_PACKAGE_FILES [join " + $basejump_stl_dir/bsg_tag/bsg_tag_pkg.v + $bsg_designs_target_dir/bsg_clk_gen_pearl_pkg.v +"] + +set SVERILOG_SOURCE_FILES [join " + $SVERILOG_PACKAGE_FILES + $basejump_stl_dir/bsg_async/bsg_launch_sync_sync.v + $basejump_stl_dir/bsg_async/bsg_sync_sync.v + $basejump_stl_dir/bsg_clk_gen/bsg_clk_gen.v + $basejump_stl_dir/bsg_clk_gen/bsg_clk_gen_osc.v + $basejump_stl_dir/bsg_misc/bsg_buf.v + $basejump_stl_dir/bsg_misc/bsg_counter_clock_downsample.v + $basejump_stl_dir/bsg_misc/bsg_dff.v + $basejump_stl_dir/bsg_misc/bsg_dff_en.v + $basejump_stl_dir/bsg_misc/bsg_dff_reset_en.v + $basejump_stl_dir/bsg_misc/bsg_dff_async_reset.v + $basejump_stl_dir/bsg_misc/bsg_mux.v + $basejump_stl_dir/bsg_misc/bsg_mux2_gatestack.v + $basejump_stl_dir/bsg_misc/bsg_muxi2_gatestack.v + $basejump_stl_dir/bsg_misc/bsg_nand.v + $basejump_stl_dir/bsg_misc/bsg_nor3.v + $basejump_stl_dir/bsg_misc/bsg_reduce.v + $basejump_stl_dir/bsg_misc/bsg_strobe.v + $basejump_stl_dir/bsg_misc/bsg_xnor.v + $basejump_stl_dir/bsg_misc/bsg_counter_clear_up.v + $basejump_stl_dir/bsg_tag/bsg_tag_master_decentralized.v + $basejump_stl_dir/bsg_tag/bsg_tag_client.v + $basejump_stl_dir/bsg_tag/bsg_tag_client_unsync.v + $bsg_designs_target_dir/bsg_clk_gen_pearl_lfsr_div30.v + $bsg_designs_target_dir/bsg_clk_gen_pearl_monitor_clk_buf.v + $bsg_designs_target_dir/bsg_clk_gen_pearl_monitor.v + $bsg_designs_target_dir/bsg_clk_gen_pearl.v +"] + diff --git a/bsg_clk_gen_pearl/tcl/parameters.tcl b/bsg_clk_gen_pearl/tcl/parameters.tcl new file mode 100644 index 0000000..535e79c --- /dev/null +++ b/bsg_clk_gen_pearl/tcl/parameters.tcl @@ -0,0 +1,7 @@ +set TOPLEVEL_PARAMETERS [join " + toplevel_tag_els_p=6 + toplevel_tag_max_payload_width_p=7 + toplevel_tag_node_id_offset_p=0 + toplevel_ds_width_p=6 + toplevel_num_adgs_p=1 +"] diff --git a/bsg_clk_gen_pearl/testing/README.md b/bsg_clk_gen_pearl/testing/README.md new file mode 100644 index 0000000..c16421c --- /dev/null +++ b/bsg_clk_gen_pearl/testing/README.md @@ -0,0 +1,18 @@ +# Bsg_clk_gen_pearl Testbench User Guide + +## Run RTL Simulation +``` +cd bsg_clk_gen_pearl/testing/rtl +make +``` +## Run RTL OSC Sweep +``` +cd bsg_clk_gen_pearl/testing/clk_gen_sweep/rtl +make +``` +## Use Testbench on ASIC +1. Update `bsg_clk_gen_pearl/tcl/filelist.tcl` and `bsg_clk_gen_pearl/tcl/parameters.tcl` accordingly +2. Create a new version of `bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_pcb.v`, in which the DUT ASIC should be attached to the testbench +*Note that the watch_clk bind pin should be up-to-date +3. Update `bsg_clk_gen_pearl/testing/tcl/filelist.tcl` accordingly +4. Update the following variables in `bsg_clk_gen_pearl/testing/rtl/Makefile`: `BSG_TOP_SIM_MODULE`, `BSG_CHIP_INSTANCE_PATH`, `BSG_OSC_BASE_DELAY` and `BSG_OSC_GRANULARITY` diff --git a/bsg_clk_gen_pearl/testing/clk_gen_sweep/.gitignore b/bsg_clk_gen_pearl/testing/clk_gen_sweep/.gitignore new file mode 100644 index 0000000..dab86fc --- /dev/null +++ b/bsg_clk_gen_pearl/testing/clk_gen_sweep/.gitignore @@ -0,0 +1,2 @@ +results/ +runs/ \ No newline at end of file diff --git a/bsg_clk_gen_pearl/testing/clk_gen_sweep/py/output_csv.py b/bsg_clk_gen_pearl/testing/clk_gen_sweep/py/output_csv.py new file mode 100644 index 0000000..c631eac --- /dev/null +++ b/bsg_clk_gen_pearl/testing/clk_gen_sweep/py/output_csv.py @@ -0,0 +1,75 @@ + +import sys, os, glob, re + +#import matplotlib +#import matplotlib.pyplot as plt + +data = {} + +if len(sys.argv) == 2: + logpath = sys.argv[1] + filelist = glob.glob(os.path.join(logpath, '*.log')) + filelist.sort() + for file in filelist: + corner = os.path.basename(file).replace('.log', '') + print(corner+',', end='') + data[corner] = {"pos": [], "neg": []} + f = open(file, "r") + lines = f.readlines() + pos_list = [] + neg_list = [] + pos_line_num = 0 + neg_line_num = 0 + for line in lines: + pos_pattern = re.compile(".*POSEDGE.*[0-9]+\s+ps") + neg_pattern = re.compile(".*NEGEDGE.*[0-9]+\s+ps") + if neg_pattern.match(line): + line_num = int(line.split(':')[0]) + # remove previous number if two lines are close to each other + # usually caused by smooth transition of osc + if line_num <= neg_line_num + 2: + neg_list.pop(-1) + neg_list.append(line.split()[-2]) + neg_line_num = line_num + if pos_pattern.match(line): + line_num = int(line.split(':')[0]) + if line_num <= pos_line_num + 2: + pos_list.pop(-1) + pos_list.append(line.split()[-2]) + pos_line_num = line_num + # Print results + print('NEG,', end='') + for num in neg_list: + print(num+',', end='') + data[corner]["pos"].append(int(num)) + print('\n,POS,', end='') + for num in pos_list: + print(num+',', end='') + data[corner]["neg"].append(int(num)) + print('') + +# for k,v in data.items(): +# data[k]['per'] = [] +# for p,n in zip(v['pos'], v['neg']): +# data[k]['per'].append(p + n) +# data[k]['duty'] = [] +# for p,n in zip(v['pos'], v['per']): +# data[k]['duty'].append(p / n) +# +# fig = plt.figure() +# ax1 = fig.add_subplot(211) +# ax2 = fig.add_subplot(212) +# x_labels = [i for i in range(32)] +# ax1.title.set_text("DUTY CYCLE") +# for k,v in data.items(): +# ax1.plot(x_labels, v['duty'], label=k) +# ax2.title.set_text("PERIOD") +# for k,v in data.items(): +# ax2.plot(x_labels, v['per'], label=k) +# fig.savefig("graph.png") +# #plt.show() + +else: + print("USAGE:") + command = "python output_csv.py {logpath}" + print(command) diff --git a/bsg_clk_gen_pearl/testing/clk_gen_sweep/rtl/Makefile b/bsg_clk_gen_pearl/testing/clk_gen_sweep/rtl/Makefile new file mode 100644 index 0000000..eaab1ff --- /dev/null +++ b/bsg_clk_gen_pearl/testing/clk_gen_sweep/rtl/Makefile @@ -0,0 +1,40 @@ +.DEFAULT_GOAL=run + +export BSG_DESIGNS_DIR := $(abspath ../../../../) +export BSG_DESIGNS_TARGET_DIR := $(abspath ../../../) + +CLK_GEN_SWEEP_RUN_DIR := $(abspath ./) +CLK_GEN_SWEEP_DIR := $(CLK_GEN_SWEEP_RUN_DIR)/../ +SIMULATION_DIR := $(BSG_DESIGNS_TARGET_DIR)/testing/rtl + +SWEEP_RUNS_DIR := $(CLK_GEN_SWEEP_RUN_DIR)/runs +SWEEP_RESULTS_DIR := $(CLK_GEN_SWEEP_RUN_DIR)/results + +OUTPUT_CSV_PY := $(CLK_GEN_SWEEP_DIR)/py/output_csv.py +RESULT_CSV := $(SWEEP_RESULTS_DIR)/result.csv +PYTHON := python3 + +RUNS := run-rtl + +run: $(RUNS) + $(PYTHON) $(OUTPUT_CSV_PY) $(SWEEP_RESULTS_DIR) > $(RESULT_CSV) + +run-%: $(SWEEP_RUNS_DIR) $(SWEEP_RESULTS_DIR) + mkdir $(SWEEP_RUNS_DIR)/$* + cd $(SWEEP_RUNS_DIR)/$* \ + && ln -s $(SIMULATION_DIR)/* . \ + && make run \ + && make summarize_details > $(SWEEP_RESULTS_DIR)/$*.log + +csv: + $(PYTHON) $(OUTPUT_CSV_PY) $(SWEEP_RESULTS_DIR) > $(RESULT_CSV) + +$(SWEEP_RUNS_DIR): + mkdir -p $@ + +$(SWEEP_RESULTS_DIR): + mkdir -p $@ + +clean: + rm -rf $(SWEEP_RUNS_DIR) + rm -rf $(SWEEP_RESULTS_DIR) diff --git a/bsg_clk_gen_pearl/testing/py/bsg_tag_boot.py b/bsg_clk_gen_pearl/testing/py/bsg_tag_boot.py new file mode 100644 index 0000000..6c4c55d --- /dev/null +++ b/bsg_clk_gen_pearl/testing/py/bsg_tag_boot.py @@ -0,0 +1,89 @@ +import sys +import os + +sys.path.append(os.environ.get("BSG_DESIGNS_TARGET_DIR")+"/testing/py") +from bsg_tag_trace_gen import * + +# Client ID Mapping +# =================== +# 0 = async_reset +# 1 = osc +# 2 = osc trigger +# 3 = ds +# 4 = sel +# 5 = monitor_reset + +if len(sys.argv) != 6: + print("USAGE:") + command = "python bsg_tag_boot.py {num_clients_p} {max_payload_width_p} {offset_p} {ds_width_p} {num_adgs_p}" + print(command) + sys.exit("Error: tag trace generation failed") + +num_masters_p = 1 +num_clients_p = int(sys.argv[1]) +max_payload_width_p = int(sys.argv[2]) +offset_p = int(sys.argv[3]) +ds_width_p = int(sys.argv[4]) +num_adgs_p = int(sys.argv[5]) + +osc_width_p = 2+2+num_adgs_p # fdt+cdt+adg +osc_max_val_p = pow(2, osc_width_p)-1 +ds_tag_width_p = ds_width_p+1 +ds_tag_max_val_p = pow(2, ds_tag_width_p)-1 + +# instantiate tag trace gen +tg = TagTraceGen(num_masters_p, num_clients_p, max_payload_width_p) + +# reset all bsg_tag master +tg.send(masters=0, client_id=offset_p+0, data_not_reset=0, length=0, data=0) +tg.wait(32) + +# reset each bsg_tag client +tg.send(masters=0, client_id=offset_p+0, data_not_reset=0, length=1, data=0b1) # async_reset +tg.send(masters=0, client_id=offset_p+1, data_not_reset=0, length=osc_width_p, data=osc_max_val_p) # osc +tg.send(masters=0, client_id=offset_p+2, data_not_reset=0, length=1, data=0b1) # osc trigger +tg.send(masters=0, client_id=offset_p+3, data_not_reset=0, length=ds_tag_width_p, data=ds_tag_max_val_p) # ds +tg.send(masters=0, client_id=offset_p+4, data_not_reset=0, length=2, data=0b11) # sel +tg.send(masters=0, client_id=offset_p+5, data_not_reset=0, length=1, data=0b1) # monitor_reset + +# select zero output clk +tg.send(masters=0, client_id=offset_p+4, data_not_reset=1, length=2, data=0b11) + +# reset oscillator and trigger flops +tg.send(masters=0, client_id=offset_p+0, data_not_reset=1, length=1, data=0b1) + +# init trigger to low, init oscillator to zero +# OSC INIT VALUE MUST BE ZERO TO AVOID X IN SIMULATION +tg.send(masters=0, client_id=offset_p+2, data_not_reset=1, length=1, data=0b0) +tg.send(masters=0, client_id=offset_p+1, data_not_reset=1, length=osc_width_p, data=0) + +# take oscillator and trigger flops out of reset +tg.send(masters=0, client_id=offset_p+0, data_not_reset=1, length=1, data=0b0) + +# trigger oscillator value +tg.send(masters=0, client_id=offset_p+2, data_not_reset=1, length=1, data=0b1) +tg.send(masters=0, client_id=offset_p+2, data_not_reset=1, length=1, data=0b0) + +# reset ds, then set ds value +tg.send(masters=0, client_id=offset_p+3, data_not_reset=1, length=ds_tag_width_p, data=1) +tg.send(masters=0, client_id=offset_p+3, data_not_reset=1, length=ds_tag_width_p, data=0) + +# select ds output clk +tg.send(masters=0, client_id=offset_p+4, data_not_reset=1, length=2, data=0b01) + +# sweep oscillator values +for tap in range(osc_max_val_p+1): + # set osc value + tg.send(masters=0, client_id=offset_p+1, data_not_reset=1, length=osc_width_p, data=tap) + # trigger osc value + tg.send(masters=0, client_id=offset_p+2, data_not_reset=1, length=1, data=0b1) + tg.send(masters=0, client_id=offset_p+2, data_not_reset=1, length=1, data=0b0) + # reset monitor + tg.send(masters=0, client_id=offset_p+5, data_not_reset=1, length=1, data=0b1) + tg.send(masters=0, client_id=offset_p+5, data_not_reset=1, length=1, data=0b0) + # wait + tg.wait(64) + +# all done +tg.done() + diff --git a/bsg_clk_gen_pearl/testing/py/bsg_tag_trace_gen.py b/bsg_clk_gen_pearl/testing/py/bsg_tag_trace_gen.py new file mode 100644 index 0000000..d4cd20a --- /dev/null +++ b/bsg_clk_gen_pearl/testing/py/bsg_tag_trace_gen.py @@ -0,0 +1,61 @@ +# +# bsg_tag_trace_gen.py +# + +import math + +SEND_OP = 0b0001 +DONE_OP = 0b0011 +COUNT_INIT_OP = 0b0110 +COUNT_WAIT_OP = 0b0101 + +class TagTraceGen: + + # Constructor + def __init__(self, num_masters_p, num_clients_p, max_payload_width_p): + self.num_masters_p = num_masters_p + self.num_clients_p = num_clients_p + self.max_payload_width_p = max_payload_width_p + self.client_id_width_lp = self.safe_clog2(num_clients_p) + self.length_width_lp = self.safe_clog2(max_payload_width_p+1) + + # BSG_SAFE_CLOG2(x) + def safe_clog2(self, x): + if x == 1: + return 1 + else: + return int(math.ceil(math.log(x,2))) + + # Get binary string + def get_bin_str(self, val, width): + return format(val, "0" + str(width) + "b") + + # Print trace. + def get_trace(self, opcode, masters, client_id, data_not_reset, length, data): + trace = self.get_bin_str(opcode, 4) + "_" + trace += self.get_bin_str(masters, self.num_masters_p) + "_" + trace += self.get_bin_str(client_id, self.client_id_width_lp) + "_" + trace += self.get_bin_str(data_not_reset, 1) + "_" + trace += self.get_bin_str(length, self.length_width_lp) + "_" + trace += self.get_bin_str(data, self.max_payload_width_p) + return trace + + # Send trace + def send(self, masters, client_id, data_not_reset, length, data): + print(self.get_trace(SEND_OP, masters, client_id, data_not_reset, length, data)) + + # Wait cycles. + def wait(self, cycles): + count_width = self.num_masters_p + self.client_id_width_lp + 1 + self.length_width_lp + self.max_payload_width_p + trace = self.get_bin_str(COUNT_INIT_OP, 4) + "_" + trace += self.get_bin_str(cycles, count_width) + print(trace) + trace = self.get_bin_str(COUNT_WAIT_OP, 4) + "_" + trace += self.get_bin_str(0, count_width) + print(trace) + + # done + def done(self): + trace = self.get_trace(DONE_OP, 0,0,0,0,0) + print(trace) + \ No newline at end of file diff --git a/bsg_clk_gen_pearl/testing/rtl/Makefile b/bsg_clk_gen_pearl/testing/rtl/Makefile new file mode 100644 index 0000000..8ce75fe --- /dev/null +++ b/bsg_clk_gen_pearl/testing/rtl/Makefile @@ -0,0 +1,141 @@ + +# Note: most variables that are file/dir paths are ?= because they can be +# overriden by the chip repo if this makefile is called from the chip +# infrastructure. + +.DEFAULT_GOAL=run +.SECONDARY: + +export BSG_DESIGNS_TARGET_DIR ?= $(abspath ../../) +export BASEJUMP_STL_DIR ?= $(BSG_DESIGNS_TARGET_DIR)/basejump_stl + +include $(BSG_DESIGNS_TARGET_DIR)/bsg_cadenv/cadenv.mk +#include $(BSG_DESIGNS_TARGET_DIR)/mk/hier.mk + +BSG_WORK_DIR := $(abspath ./) +BSG_OUT_DIR := $(BSG_WORK_DIR)/out +BSG_OUT_SIM := $(BSG_OUT_DIR)/simv + +# ========================================================== +# VCS OPTIONS +# ========================================================== + +VCS_OPTIONS := -full64 +VCS_OPTIONS += -notice +VCS_OPTIONS += -debug_pp +VCS_OPTIONS += +vcs+vcdpluson +VCS_OPTIONS += -V +VCS_OPTIONS += +v2k +VCS_OPTIONS += -sverilog +VCS_OPTIONS += -assert svaext +VCS_OPTIONS += +noportcoerce +VCS_OPTIONS += +vc +VCS_OPTIONS += +vcs+loopreport +VCS_OPTIONS += -timescale=1ps/1ps +VCS_OPTIONS += -diag timescale +VCS_OPTIONS += -o $(BSG_OUT_SIM) +VCS_OPTIONS += -Mdir=$(BSG_OUT_DIR) +VCS_OPTIONS += -top bsg_config bsg_config.v +VCS_OPTIONS += +vcs+lic+wait + +# ========================================================== +# CHIP AND TESTING FILELISTS AND LIBLISTS +# ========================================================== + +BSG_TOP_SIM_MODULE = bsg_clk_gen_pearl_pcb +BSG_CHIP_INSTANCE_PATH = $(BSG_TOP_SIM_MODULE).IC + +VCS_OPTIONS += +define+BSG_TOP_SIM_MODULE=$(BSG_TOP_SIM_MODULE) +VCS_OPTIONS += +define+BSG_CHIP_INSTANCE_PATH=$(BSG_CHIP_INSTANCE_PATH) + +export BSG_CHIP_LIBRARY_NAME = bsg_chip +export BSG_CHIP_FILELIST = $(BSG_OUT_DIR)/$(BSG_CHIP_LIBRARY_NAME).filelist +export BSG_CHIP_LIBRARY = $(BSG_OUT_DIR)/$(BSG_CHIP_LIBRARY_NAME).library + +VCS_OPTIONS += +define+BSG_CHIP_LIBRARY_NAME=$(BSG_CHIP_LIBRARY_NAME) +VCS_OPTIONS += -f $(BSG_CHIP_FILELIST) +VCS_OPTIONS += -libmap $(BSG_CHIP_LIBRARY) + +export BSG_DESIGNS_TESTING_LIBRARY_NAME = bsg_design_testing +export BSG_DESIGNS_TESTING_FILELIST = $(BSG_OUT_DIR)/$(BSG_DESIGNS_TESTING_LIBRARY_NAME).filelist +export BSG_DESIGNS_TESTING_LIBRARY = $(BSG_OUT_DIR)/$(BSG_DESIGNS_TESTING_LIBRARY_NAME).library + +VCS_OPTIONS += +define+BSG_DESIGNS_TESTING_LIBRARY_NAME=$(BSG_DESIGNS_TESTING_LIBRARY_NAME) +VCS_OPTIONS += -f $(BSG_DESIGNS_TESTING_FILELIST) +VCS_OPTIONS += -libmap $(BSG_DESIGNS_TESTING_LIBRARY) + +$(BSG_CHIP_FILELIST): $(BSG_DESIGNS_TESTING_LIBRARY) +$(BSG_CHIP_LIBRARY): $(BSG_DESIGNS_TESTING_LIBRARY) +$(BSG_DESIGNS_TESTING_FILELIST): $(BSG_DESIGNS_TESTING_LIBRARY) +$(BSG_DESIGNS_TESTING_LIBRARY): $(BSG_OUT_DIR) + /usr/bin/tclsh bsg_config.tcl + +# ========================================================== +# TOPLEVEL PARAMETERS +# ========================================================== + +BSG_TOPLEVEL_PARAMS_DIR ?= $(BSG_DESIGNS_TARGET_DIR)/tcl/parameters.tcl +BSG_TOPLEVEL_PARAMS := $(shell grep "=" $(BSG_TOPLEVEL_PARAMS_DIR)) +VCS_OPTIONS += $(foreach PARAM, $(BSG_TOPLEVEL_PARAMS), -pvalue+$(PARAM)) + +#VCS_OPTIONS += +define+DUT_MODULE_NAME=$(TOP_HIER_BLOCK) + +VCS_OPTIONS += +define+BSG_OSC_BASE_DELAY=125 +VCS_OPTIONS += +define+BSG_OSC_GRANULARITY=5 + +# ========================================================== +# TRACE REPLAY ROMS +# ========================================================== + +BSG_TRACE_NAME := bsg_tag_boot +BSG_TRACE_PY := $(BSG_DESIGNS_TARGET_DIR)/testing/py/$(BSG_TRACE_NAME).py +BSG_TRACE_FILES := $(BSG_OUT_DIR)/$(BSG_TRACE_NAME).tr +BSG_TRACE_ROMS := $(BSG_OUT_DIR)/$(BSG_TRACE_NAME)_rom.v +BSG_TRACE_PY_PARAMS := $(foreach PARAM, $(BSG_TOPLEVEL_PARAMS), $(word 2, $(subst =, ,$(PARAM)))) + +$(BSG_TRACE_FILES): $(BSG_TRACE_PY) | $(BSG_OUT_DIR) + python $< $(BSG_TRACE_PY_PARAMS) > $@ + +$(BSG_TRACE_ROMS): $(BSG_TRACE_FILES) | $(BSG_OUT_DIR) + $(BASEJUMP_STL_DIR)/bsg_mem/bsg_ascii_to_rom.py $< $(BSG_TRACE_NAME)_rom > $@ + +VCS_OPTIONS += $(addprefix -v ,$(BSG_TRACE_ROMS)) + +# ========================================================== +# RUN TARGETS +# ========================================================== + +summarize: + grep -o -E ".*NEGEDGE.*[0-9]+\s+ps" $(BSG_OUT_DIR)/run.log | grep -o -E "[0-9]+\s+ps" | grep -o -E "[0-9]+" | column -c 100 + grep -o -E ".*POSEDGE.*[0-9]+\s+ps" $(BSG_OUT_DIR)/run.log | grep -o -E "[0-9]+\s+ps" | grep -o -E "[0-9]+" | column -c 100 + +summarize_details: + grep -o -E -n ".*NEGEDGE.*[0-9]+\s+ps" $(BSG_OUT_DIR)/run.log + grep -o -E -n ".*POSEDGE.*[0-9]+\s+ps" $(BSG_OUT_DIR)/run.log + +run: $(BSG_OUT_SIM) + cd $(BSG_OUT_DIR); $(BSG_OUT_SIM) $(PLUSARGS) | tee -i run.log + +run-no-tee: $(BSG_OUT_SIM) + cd $(BSG_OUT_DIR); $(BSG_OUT_SIM) $(PLUSARGS) + +rerun: + cd $(BSG_OUT_DIR); $(BSG_OUT_SIM) $(PLUSARGS) | tee -i run.log + +rerun-no-tee: + cd $(BSG_OUT_DIR); $(BSG_OUT_SIM) $(PLUSARGS) + +build: $(BSG_OUT_SIM) +$(BSG_OUT_SIM): $(BSG_CHIP_FILELIST) $(BSG_CHIP_LIBRARY) $(BSG_DESIGNS_TESTING_FILELIST) $(BSG_DESIGNS_TESTING_LIBRARY) $(BSG_TRACE_ROMS) + $(VCS) $(VCS_OPTIONS) | tee -i $(BSG_OUT_DIR)/build.log + +dve view: + $(VCS_BIN)/dve -full64 -vpd $(BSG_OUT_DIR)/vcdplus.vpd + +$(BSG_OUT_DIR): + mkdir -p $@ + +clean: + rm -rf $(BSG_OUT_DIR) DVEfiles + rm -f stack.info.* vc_hdrs.h vcdplus.vpd inter.vpd ucli.key + diff --git a/bsg_clk_gen_pearl/testing/rtl/bsg_config.tcl b/bsg_clk_gen_pearl/testing/rtl/bsg_config.tcl new file mode 100644 index 0000000..f5ba7f7 --- /dev/null +++ b/bsg_clk_gen_pearl/testing/rtl/bsg_config.tcl @@ -0,0 +1,24 @@ + +source $::env(BSG_DESIGNS_TARGET_DIR)/testing/tcl/bsg_config_utils.tcl + +# chip source (rtl) files and include paths list +source $::env(BSG_DESIGNS_TARGET_DIR)/tcl/filelist.tcl + +bsg_create_filelist $::env(BSG_CHIP_FILELIST) \ + $SVERILOG_SOURCE_FILES + +bsg_create_library $::env(BSG_CHIP_LIBRARY_NAME) \ + $::env(BSG_CHIP_LIBRARY) \ + $SVERILOG_SOURCE_FILES \ + $SVERILOG_INCLUDE_PATHS + +# testing source (rtl) files and include paths list +source $::env(BSG_DESIGNS_TARGET_DIR)/testing/tcl/filelist.tcl + +bsg_create_filelist $::env(BSG_DESIGNS_TESTING_FILELIST) \ + [bsg_list_diff $TESTING_SOURCE_FILES $SVERILOG_SOURCE_FILES] \ + +bsg_create_library $::env(BSG_DESIGNS_TESTING_LIBRARY_NAME) \ + $::env(BSG_DESIGNS_TESTING_LIBRARY) \ + [bsg_list_diff $TESTING_SOURCE_FILES $SVERILOG_SOURCE_FILES] \ + $TESTING_INCLUDE_PATHS diff --git a/bsg_clk_gen_pearl/testing/rtl/bsg_config.v b/bsg_clk_gen_pearl/testing/rtl/bsg_config.v new file mode 100644 index 0000000..229423a --- /dev/null +++ b/bsg_clk_gen_pearl/testing/rtl/bsg_config.v @@ -0,0 +1,5 @@ +config bsg_config; + design `BSG_DESIGNS_TESTING_LIBRARY_NAME.`BSG_TOP_SIM_MODULE; + default liblist `BSG_DESIGNS_TESTING_LIBRARY_NAME `BSG_CHIP_LIBRARY_NAME work; + instance `BSG_CHIP_INSTANCE_PATH liblist `BSG_CHIP_LIBRARY_NAME; +endconfig diff --git a/bsg_clk_gen_pearl/testing/tcl/bsg_config_utils.tcl b/bsg_clk_gen_pearl/testing/tcl/bsg_config_utils.tcl new file mode 100644 index 0000000..ec19a71 --- /dev/null +++ b/bsg_clk_gen_pearl/testing/tcl/bsg_config_utils.tcl @@ -0,0 +1,69 @@ + +# bsg_write_file +proc bsg_write_file {floc flist} { + set f $floc + set fid [open $f "w"] + foreach item $flist { + puts $fid $item + } + close $fid +} + +# bsg_get_length +proc bsg_get_length {flist} { + if {[info exists flist]} { + return [llength $flist] + } +} + +# bsg_create_filelist +proc bsg_create_filelist {filelist source_files} { + bsg_write_file $filelist $source_files +} + +# bsg_create_library, include_paths arg is optional +proc bsg_create_library {library_name library_file source_files {include_paths ""}} { + + # header + lappend library_list "library $library_name" + + # source files + set len [bsg_get_length $source_files] + set i 0 + foreach f $source_files { + if {$i == [expr $len - 1]} { + lappend library_list "$f" + } else { + lappend library_list "$f," + } + incr i + } + + # include paths + set len [bsg_get_length $include_paths] + if {$len > 0} { + lappend library_list "-incdir" + } + set i 0 + foreach f $include_paths { + if {$i == [expr $len - 1]} { + lappend library_list "$f" + } else { + lappend library_list "$f," + } + incr i + } + + # footer + lappend library_list ";" + + # write library + bsg_write_file $library_file $library_list +} + +proc bsg_list_diff {full_list base_list} { + foreach elem $full_list {dict set x $elem 1} + foreach elem $base_list {dict unset x $elem} + return [dict keys $x] +} + diff --git a/bsg_clk_gen_pearl/testing/tcl/filelist.tcl b/bsg_clk_gen_pearl/testing/tcl/filelist.tcl new file mode 100644 index 0000000..34b1dba --- /dev/null +++ b/bsg_clk_gen_pearl/testing/tcl/filelist.tcl @@ -0,0 +1,36 @@ +#------------------------------------------------------------ +# Do NOT arbitrarily change the order of files. Some module +# and macro definitions may be needed by the subsequent files +#------------------------------------------------------------ + +set bsg_designs_target_dir $::env(BSG_DESIGNS_TARGET_DIR) +set basejump_stl_dir $::env(BASEJUMP_STL_DIR) + +set TESTING_INCLUDE_PATHS [join " + $basejump_stl_dir/bsg_misc + $basejump_stl_dir/bsg_tag +"] + +set TESTING_PACKAGE_FILES [join " + $basejump_stl_dir/bsg_tag/bsg_tag_pkg.v + $bsg_designs_target_dir/bsg_clk_gen_pearl_pkg.v +"] + +set TESTING_SOURCE_FILES [join " + $TESTING_PACKAGE_FILES + $basejump_stl_dir/bsg_clk_gen/bsg_nonsynth_clk_watcher.v + $basejump_stl_dir/bsg_dataflow/bsg_one_fifo.v + $basejump_stl_dir/bsg_dataflow/bsg_parallel_in_serial_out.v + $basejump_stl_dir/bsg_dataflow/bsg_two_fifo.v + $basejump_stl_dir/bsg_fsb/bsg_fsb_node_trace_replay.v + $basejump_stl_dir/bsg_mem/bsg_mem_1r1w.v + $basejump_stl_dir/bsg_mem/bsg_mem_1r1w_synth.v + $basejump_stl_dir/bsg_misc/bsg_dff_en.v + $basejump_stl_dir/bsg_misc/bsg_dff_reset.v + $basejump_stl_dir/bsg_tag/bsg_tag_trace_replay.v + $basejump_stl_dir/bsg_test/bsg_nonsynth_clock_gen.v + $basejump_stl_dir/bsg_test/bsg_nonsynth_reset_gen.v + $bsg_designs_target_dir/testing/v/bsg_clk_gen_pearl_testbench.v + $bsg_designs_target_dir/testing/v/bsg_clk_gen_pearl_pcb.v +"] + diff --git a/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_pcb.v b/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_pcb.v new file mode 100644 index 0000000..52c08e4 --- /dev/null +++ b/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_pcb.v @@ -0,0 +1,49 @@ +`timescale 1ps/1ps +`include "bsg_defines.v" + +module bsg_clk_gen_pearl_pcb + + import bsg_clk_gen_pearl_pkg::*; + + #(parameter `BSG_INV_PARAM(toplevel_tag_els_p) + ,parameter `BSG_INV_PARAM(toplevel_tag_max_payload_width_p) + ,parameter `BSG_INV_PARAM(toplevel_tag_node_id_offset_p) + ,parameter `BSG_INV_PARAM(toplevel_ds_width_p) + ,parameter `BSG_INV_PARAM(toplevel_num_adgs_p) + ) + + (); + + logic ext_clk, async_clk_gen_disable; + logic tag_clk, tag_data, tag_en; + + bsg_clk_gen_pearl + #(.ds_width_p(toplevel_ds_width_p) + ,.num_adgs_p(toplevel_num_adgs_p) + ,.tag_els_p(toplevel_tag_els_p) + ,.tag_lg_width_p(`BSG_SAFE_CLOG2(toplevel_tag_max_payload_width_p+1)) + ,.tag_local_els_p(bsg_clk_gen_pearl_tag_local_els_gp) + ) IC + (.ext_clk_i(ext_clk) + ,.async_output_disable_i(async_clk_gen_disable) + + ,.tag_clk_i(tag_clk) + ,.tag_data_i(tag_data & tag_en) + ,.tag_node_id_offset_i((`BSG_SAFE_CLOG2(toplevel_tag_els_p))'(toplevel_tag_node_id_offset_p)) + + ,.clk_o() + ,.clk_monitor_o() + ); + + bsg_clk_gen_pearl_testbench GW + (.ext_clk_o(ext_clk) + ,.async_clk_gen_disable_o(async_clk_gen_disable) + + ,.tag_clk_o(tag_clk) + ,.tag_data_o(tag_data) + ,.tag_en_o(tag_en) + + ,.watch_clk_i(bsg_clk_gen_pearl_pcb.IC.clk_o) + ); + +endmodule diff --git a/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_testbench.v b/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_testbench.v new file mode 100644 index 0000000..b062cf0 --- /dev/null +++ b/bsg_clk_gen_pearl/testing/v/bsg_clk_gen_pearl_testbench.v @@ -0,0 +1,147 @@ +`timescale 1ps/1ps +`include "bsg_defines.v" + +`define TAG_CLK_PERIOD 20000 // 50 MHz +`define EXT_CLK_PERIOD 10000 // 100 MHz + +module bsg_clk_gen_pearl_testbench + + import bsg_tag_pkg::*; + + #(parameter `BSG_INV_PARAM(toplevel_tag_els_p) + ,parameter `BSG_INV_PARAM(toplevel_tag_max_payload_width_p) + ) + + (output ext_clk_o + ,output async_clk_gen_disable_o + + ,output tag_clk_o + ,output tag_data_o + ,output tag_en_o + + ,input watch_clk_i + ); + + logic tag_clk, tag_reset, ext_clk; + logic async_clk_gen_disable; + + assign ext_clk_o = ext_clk; + assign async_clk_gen_disable_o = async_clk_gen_disable; + assign tag_clk_o = ~tag_clk; + + // ========================================================== + // NONSYNTH CLK/RESET GENERATORS + // ========================================================== + + bsg_nonsynth_clock_gen #(.cycle_time_p(`TAG_CLK_PERIOD)) + tag_clk_gen + (.o(tag_clk) + ); + + bsg_nonsynth_clock_gen #(.cycle_time_p(`EXT_CLK_PERIOD)) + ext_clk_gen + (.o(ext_clk) + ); + + bsg_nonsynth_reset_gen #(.num_clocks_p(1), .reset_cycles_lo_p(10), .reset_cycles_hi_p(5)) + tag_reset_gen + (.clk_i(tag_clk) + ,.async_reset_o(tag_reset) + ); + + // ========================================================== + // BSG TAG TRACK REPLAY + // ========================================================== + + localparam tag_num_masters_lp = 1; + localparam tag_num_clients_lp = toplevel_tag_els_p; + localparam tag_max_payload_width_lp = toplevel_tag_max_payload_width_p; + localparam tag_lg_max_payload_width_lp = `BSG_SAFE_CLOG2(tag_max_payload_width_lp+1); + localparam tag_trace_rom_addr_width_lp = 32; + localparam tag_trace_rom_data_width_lp = 4 + tag_num_masters_lp + `BSG_SAFE_CLOG2(tag_num_clients_lp) + 1 + tag_lg_max_payload_width_lp + tag_max_payload_width_lp; + + logic [tag_trace_rom_addr_width_lp-1:0] rom_addr_li; + logic [tag_trace_rom_data_width_lp-1:0] rom_data_lo; + + logic tag_trace_valid_lo, tag_trace_data_lo, tag_trace_done_lo; + + assign tag_data_o = tag_trace_data_lo; + assign tag_en_o = tag_trace_valid_lo; + + bsg_tag_boot_rom #(.width_p(tag_trace_rom_data_width_lp) + ,.addr_width_p(tag_trace_rom_addr_width_lp) + ) + tag_trace_rom + (.addr_i(rom_addr_li) + ,.data_o(rom_data_lo) + ); + + bsg_tag_trace_replay #(.rom_addr_width_p(tag_trace_rom_addr_width_lp) + ,.rom_data_width_p(tag_trace_rom_data_width_lp) + ,.num_masters_p(tag_num_masters_lp) + ,.num_clients_p(tag_num_clients_lp) + ,.max_payload_width_p(tag_max_payload_width_lp) + ) + tag_trace_replay + (.clk_i(tag_clk) + ,.reset_i(tag_reset) + ,.en_i(1'b1) + + ,.rom_addr_o(rom_addr_li) + ,.rom_data_i(rom_data_lo) + + ,.valid_i(1'b0) + ,.data_i('0) + ,.ready_o() + + ,.valid_o(tag_trace_valid_lo) + ,.en_r_o() + ,.tag_data_o(tag_trace_data_lo) + ,.yumi_i(tag_trace_valid_lo) + + ,.done_o(tag_trace_done_lo) + ,.error_o() + ) ; + + // ========================================================== + // CLOCK GENERATOR WATCHER + // ========================================================== + + logic clk_lo; + assign clk_lo = watch_clk_i; + + // filter out first cycle to eliminate glitch from ds + logic watch_state; + always_ff @(posedge clk_lo) begin + if (clk_lo !== 1'bX) begin + if (watch_state === 1'bX) begin + watch_state <= 1'b0; + end else if (watch_state === 1'b0) begin + watch_state <= 1'b1; + end + end + end + + wire watch_clk = (watch_state === 1'b1) ? clk_lo : 1'b0; + + bsg_nonsynth_clk_watcher #(.tolerance_p(1)) + watcher + (.clk_i(watch_clk) + ); + + // ========================================================== + // BSG TAG MASTER INSTANCE + // ========================================================== + + initial + begin + async_clk_gen_disable = 1; + @(negedge tag_reset) + async_clk_gen_disable = 0; + while (tag_trace_done_lo == 1'b0) + #(`TAG_CLK_PERIOD); + $display("Clock Sweep Done!\n"); + $finish; + end + +endmodule