This commit is contained in:
2025-08-14 07:20:24 -07:00
parent 1019422be6
commit 33f682cb53
4 changed files with 0 additions and 320 deletions

View File

@@ -1,30 +0,0 @@
`timescale 10ns/1ns
`include "div3.v"
module div3_tb;
reg CLK;
wire LED;
initial CLK=0;
always #1 CLK=~CLK;
div3 dut (.clk(CLK), .r(1'b1), .q(LED));
//-- Begin test
initial begin
//-- Set the dumpfile
$dumpfile("div3_tb.vcd");
//-- Dump everything into the dumpfile
$dumpvars(0, div3_tb);
//-- End after 10 time units
# 100 $finish;
end
endmodule

View File

@@ -1,32 +0,0 @@
`timescale 10ns/1ns
module blinky_tb;
reg CLK;
wire LED;
blinky dut (
.CLK (CLK),
.PIN_24 (PIN_24)
);
initial CLK=0;
always #1 CLK=~CLK;
//-- Begin test
initial begin
//-- Set the dumpfile
$dumpfile("blinky_tb.vcd");
//-- Dump everything into the dumpfile
$dumpvars(0, blinky_tb);
//-- End after 10 time units
# 100000 $finish;
end
endmodule

View File

@@ -1,23 +0,0 @@
module SB_HFOSC(
input CLKHFPU,
input CLKHFEN,
output CLKHF
);
parameter CLKHF_DIV = "0b00";
endmodule
module SB_RGBA_DRV (
input RGBLEDEN,
input RGB0PWM,
input RGB1PWM,
input RGB2PWM,
input CURREN,
output RGB0,
output RGB1,
output RGB2
);
parameter CURRENT_MODE="0b1";
parameter RGB0_CURRENT="0b000001";
parameter RGB1_CURRENT="0b000001";
parameter RGB2_CURRENT="0b000001";
endmodule

View File

@@ -1,235 +0,0 @@
#! /usr/bin/python
# THE BEER-WARE LICENSE" (Revision 42):
# <xfguo@xfguo.org> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return Xiongfei(Alex) Guo.
# some minor additions by Al Williams 2018-9-11
'''
Created on 2010-4-23
@author: Alex Guo
'''
import re
import sys
import argparse
class TestbenchGenerator(object):
'''
verilog test bench auto generation
'''
def __init__(self, vfile_name = None, ofile_name = None):
self.vfile_name = vfile_name
self.vfile = None
self.ofile_name = ofile_name
if(ofile_name == None):
self.ofile = sys.stdout
self.vcont = ""
self.mod_name = ""
self.pin_list = []
self.clock_name = 'clk'
self.reset_name = 'rst'
if vfile_name == None:
sys.stderr.write("ERROR: You did not provide an input file name.\n")
sys.exit(1)
else:
self.open()
self.parser()
self.open_outputfile()
def open(self, vfile_name = None):
if vfile_name != None:
self.vfile_name = vfile_name
try:
self.vfile = open(self.vfile_name, 'r')
self.vcont = self.vfile.read()
except Exception as e:
print("ERROR: Input file error.\n ERROR: %s" % e)
sys.exit(1)
def open_outputfile(self, ofile_name = None):
try:
if(ofile_name == None):
if(self.ofile_name == None):
ofname = "tb_%s.v" % self.mod_name
self.ofile = open(ofname, 'w')
print("You did not specify an output file name, using '%s'." % ofname)
else:
self.ofile = open(self.ofile_name, 'w')
print("Output file is '%s'." % self.ofile_name)
else:
self.ofile = open(ofile_name, 'w')
print("Output file is '%s'." % ofile_name)
except Exception as e:
print("ERROR: Output file error. \n ERROR: %s" % e)
sys.exit(1)
def clean_other(self, cont):
## clean '// ...'
cont = re.sub(r"//[^\n^\r]*", '\n', cont)
## clean '/* ... */'
cont = re.sub(r"/\*.*\*/", '', cont)
## clean '`define ..., etc.'
#cont = re.sub(r"[^\n^\r]+`[^\n^\r]*", '\n', cont)
## clean tables
cont = re.sub(r' +', ' ', cont)
## clean '\n' * '\r'
#cont = re.sub(r'[\n\r]+', '', cont)
return cont
def parser(self):
print("Parsing...")
# print vf_cont
mod_pattern = r"module[\s]+(\S*)[\s]*\([^\)]*\)[\s\S]*"
module_result = re.findall(mod_pattern, self.clean_other(self.vcont))
#print module_result
self.mod_name = module_result[0]
self.parser_inoutput()
self.find_clk_rst()
def parser_inoutput(self):
pin_list = self.clean_other(self.vcont)
comp_pin_list_pre = []
for i in re.findall(r'(input|output|inout)[\s]+([^;,\)]+)[\s]*[;,]', pin_list):
comp_pin_list_pre.append((i[0], re.sub(r"^reg[\s]*", "", i[1])))
comp_pin_list = []
type_name = ['reg', 'wire', 'wire', "ERROR"]
for i in comp_pin_list_pre:
x = re.split(r']', i[1])
type = 0;
if i[0] == 'input':
type = 0
elif i[0] == 'output':
type = 1
elif i[0] == 'inout':
type = 2
else:
type = 3
if len(x) == 2:
x[1] = re.sub('[\s]*', '', x[1])
comp_pin_list.append((i[0], x[1], x[0] + ']', type_name[type]))
else:
comp_pin_list.append((i[0], x[0], '', type_name[type]))
self.pin_list = comp_pin_list
# for i in self.pin_list: print i
def print_dut(self):
max_len = 0
for cpin_name in self.pin_list:
pin_name = cpin_name[1]
if len(pin_name) > max_len:
max_len = len(pin_name)
self.printo( "%s uut (\n" % self.mod_name )
align_cont = self.align_print(list(map(lambda x:("", "." + x[1], "(", x[1], '),'), self.pin_list)), 4)
align_cont = align_cont[:-2] + "\n"
self.printo( align_cont )
self.printo( ");\n" )
def print_wires(self):
self.printo(self.align_print(list(map(lambda x:(x[3], x[2], x[1], ';'), self.pin_list)), 4))
self.printo("\n")
def print_clock_gen(self,period,dfile,depth,resetpol):
fsdb = " $dumpfile(\"%s\");\n $dumpvars(%d, tb_%s);\n" % (dfile, depth, self.mod_name)
clock_gen_text = "\nparameter PERIOD = %d; //adjust for your timescale\n\ninitial begin\n%s CLK = 1'b0;\n #(PERIOD/2);\n forever\n #(PERIOD/2) CLK = ~CLK;\nend\n" % (period, fsdb)
self.printo(re.sub('CLK', self.clock_name, clock_gen_text))
if self.reset_name!="":
clock_gen_text = "\ninitial begin\n RST=1'b%d;\n #(PERIOD*2) RST=~RST;\n #PERIOD RST=~RST;\n end\n" % resetpol
self.printo(re.sub('RST',self.reset_name, clock_gen_text))
def find_clk_rst(self):
for pin in self.pin_list:
if re.match(r'[\S]*(clk|clock)[\S]*', pin[1]):
self.clock_name = pin[1]
print("Clock signal detected: '%s'." % pin[1])
break
for pin in self.pin_list:
if re.match(r'rst|reset', pin[1]):
self.reset_name = pin[1]
print("Reset signal detected: '%s'." % pin[1])
break
# Original code -- no longer used
def print_module_head_orig(self):
self.printo("`include \"timescale.v\"\nmodule tb_%s;\n\n" % self.mod_name)
def print_module_head(self,timescale):
self.printo("`timescale %s //Adjust to suit\n\nmodule tb_%s;\n\n" % (timescale,self.mod_name))
def print_module_end(self,iname):
if iname is None:
iname='user.tb_%s.v' % self.mod_name
self.printo("`include \"%s\"\nendmodule\n" % iname)
def printo(self, cont):
self.ofile.write(cont)
def close(self):
if self.vfile != None:
self.vfile.close()
print("Output complete.\n\n")
def align_print(self, content, indent):
""" Align pretty print."""
row_len = len(content)
col_len = len(content[0])
align_cont = [""] * row_len
for i in range(col_len):
col = list(map(lambda x:x[i], content))
max_len = max(list(map(len, col)))
for i in range(row_len):
l = len(col[i])
align_cont[i] += "%s%s" % (col[i], (indent + max_len - l) * ' ')
# remove space in line end
align_cont = list(map(lambda s:re.sub('[ ]*$', '', s), align_cont))
return "\n".join(align_cont) + "\n"
if __name__ == "__main__":
print('''***************** tbgen - Auto generate a testbench. *****************
Author: Xiongfei(Alex) Guo <xfguo@credosemi.com>
License: Beerware
''')
ofile_name = None
aparse = argparse.ArgumentParser(description='Automatically generate Verilog testbench')
aparse.add_argument('input_file', help='input Verilog file')
aparse.add_argument('output_file', help='output Verilog testbench', nargs='?', default=None)
aparse.add_argument('-p','--period', type=int, help='set period in clock ticks (default=10)', default=10)
aparse.add_argument('-t','--timescale',help='set timescale (default=1ns/10ps)', default='1ns/10ps')
aparse.add_argument('-d','--dumpfile',help='set dumpfile (default=tb_output.vcd)', default='tb_output.vcd')
aparse.add_argument('-l','--level', type=int, help='set dump depth level (usually 0,1, or 2; default=2)', default=2)
aparse.add_argument('-r','--resetneg', help='set reset to negative (default positive)', action='store_const', const=1, default=0)
aparse.add_argument('-i','--include', help='sets user include file name (default=user.tb_<name>.v)', default=None)
args = aparse.parse_args()
tbg = TestbenchGenerator(args.input_file, args.output_file)
tbg.print_module_head(args.timescale)
tbg.print_wires()
tbg.print_dut()
tbg.print_clock_gen(args.period,args.dumpfile,args.level,args.resetneg)
tbg.print_module_end(args.include)
tbg.close()