利用python自动生成verilog模块例化模板
转载请注明出处:

一、前言
之前写过一篇关于利用Python生成module instance的文章,现直接在这篇文章基础上修改完善。作为一名IC验证工程师在公司经常写些脚本,自己在这方面的功底也提高了不少,再者有网友评论之前的脚本有不足之处,所以本文编写了一个进阶版的脚本,扩展性也比较强,方便大家使用。
二、代码设计
新添加的功能特性包括:
1 支持inout端口
2 支持多module文件中指定module的instance生成(不指定则默认与文件名一致)
3 检查注释行
4 生成Instance同时提供端口参数注释,包括端口方向和位宽
5 可选同时生成端口连接信号及其声明
因为提供了上述特性,代码逻辑较基础版更为复杂点。整个生成过程分为三个阶段:获得指定module的代码段,从中提取出端口信息以及按照指定工作模式生成instance文件。先上代码再加以说明:
基础版:
#!/usr/bin/python import re
import os #regex compile
regex_module = re.compile('(module)(\s+)(\w+)') regex_ports = re.compile('''
(input|output) #0
(\s+) #1
(wire|reg\s+)? #2
(\[\w+\-1\:0\]\s+)? #3
(\w+) #4
''',re.VERBOSE) directory = os.getcwd()
#open the design file
file_design = input('Please enter the file name:')
with open(directory+'/'+file_design,'r') as file_obj:
comment = file_obj.read() #regex match module name
module_obj = regex_module.search(comment)
print(module_obj.group())
#regex match ports name
groups_ports = regex_ports.findall(comment)
print('\nnumber of ports:',len(groups_ports)) #write the instantiation templete to an assigned file
file_tb = input('Please enter the top file name:')
with open(directory+'/'+file_tb,'a') as file_obj2:
if module_obj is not None:
file_obj2.write(module_obj.group(3)+' uut\n(\n') num = len(groups_ports)
for i in range(num):
if i == num-1:
file_obj2.write('.'+groups_ports[i][4]+' ()\n')
else:
file_obj2.write('.'+groups_ports[i][4]+' (),\n')
file_obj2.write(');\n')
python_inst.py
进阶版:
import re
import argparse
import os class Rtl_generator:
def __init__(self):
self.extract_list=[]
self.info_list=[]
self.module_name = None @staticmethod
def display_list_for_test(list_name):
print('list :\n')
for unit in list_name:
print(unit) def get_module_specified_lines(self,regex,file_name):
print('input function: get_module_specified\n')
with open(file_name,'r') as file_obj:
add_flag = 0
for line in file_obj:
line = line.strip()
if not line.startswith('//'):
re_head_obj = re.match(regex,line)
re_tail_obj = re.match(r'endmodule',line)
if re_head_obj is not None:
add_flag = 1
elif add_flag == 1 and re_tail_obj is not None:
add_flag = 0
break
else:
continue if add_flag == 1:
self.extract_list.append(line) def extract_ports_info(self,regex_ports, regex_width):
print('input function: get_ports_info\n')
for unit in self.extract_list:
re_ports_obj = re.search(regex_ports,unit)
if re_ports_obj is not None:
port_name = re_ports_obj.group(6)
port_direction = re_ports_obj.group(1)
port_width_str = re_ports_obj.group(4)
if port_width_str is None:
port_width = 1
else:
#port_width = port_width_str
width_str = re.search(regex_width,port_width_str).group(2)
width_info_list = width_str.split(":")
high_str = width_info_list[0]
low_str = width_info_list[1]
if '-1' in high_str:
port_width = high_str.split("-")[0]
else:
high = int(high_str)
low = int(low_str)
port_width = high - low + 1 if high >= low else low - high + 1
port_info = {'name':port_name,'direct':port_direction,'width':port_width}
self.info_list.append(port_info) def gen_module_instance(self,filename,mode):
print('input function: gen_module_instance')
ports_num = len(self.info_list)
line_list = []
line_list.append('module wrapper();')
if mode == 'gen_inst_wc':
for i in range(ports_num):
var_type = 'reg' if self.info_list[i]['direct'] == 'input' else 'wire'
line_list.append('{:<5} [{}-1:0] {};'.format(var_type,
self.info_list[i]['width'],
self.info_list[i]['name']))
line_list.append('\n')
line_list.append('{} inst_name'.format(self.module_name))
line_list.append('(')
index = 0 for unit in self.info_list:
if index == ports_num - 1:
post_fix = '//{:<15}width:{}'.format(unit['direct'], unit['width'])
else:
post_fix = ',//{:<15}width:{}'.format(unit['direct'], unit['width'])
index+=1 if mode == 'gen_inst_wc':
line_list.append('.{:<30}{:<30}{}'.format(unit['name'], '('+unit['name']+')', post_fix))
elif mode == 'gen_inst_only':
line_list.append('.{:<30}{:<5}{}'.format(unit['name'], '(' + ')', post_fix))
line_list.append(');')
line_list.append('endmodule\n')
with open(filename,'w') as file_obj:
for line in line_list:
file_obj.write(line)
file_obj.write('\n')
print('generate instance finish')
rtl_generator.py
from rtl_generator import *
#import rtl_generator mode_list = ['gen_inst_only','gen_inst_wc'] def create_arg_parser():
parser = argparse.ArgumentParser()
parser.add_argument("-filename",required=True)
parser.add_argument("-target",default='wrapper.v')
parser.add_argument("-modulename")
parser.add_argument("-mode",choices=mode_list,default=mode_list[0]) options = parser.parse_args()
return options def get_arg(options,option):
if hasattr(options,option):
arg = getattr(options,option)
return arg
else:
return None def compile_regex(**key_args):
regex_dict={}
if 'module_head' in key_args.keys():
regex_module_head = re.compile(r'''
(module\s+)
(%s)
''' %(key_args['module_head']),re.VERBOSE)
regex_dict['module_head'] = regex_module_head if 'module_ports' in key_args.keys():
regex_module_ports = re.compile(r'''
(output|input|inout) #1 direction
(\s+) #2
(wire|reg)? #3
(\[[\w\-\:]+\])? #4 width
(\s+)? #5
(\w+) #6 port name
''',re.VERBOSE)
regex_dict['module_ports'] = regex_module_ports if 'width' in key_args.keys():
regex_width = re.compile(r'''
(\[)
([\w\-\:]+)
(\])
''',re.VERBOSE)
regex_dict['width'] = regex_width return regex_dict rg = Rtl_generator() if __name__ == "__main__":
options = create_arg_parser()
#print(options)
file_name_arg = get_arg(options,"filename")
module_name_arg=get_arg(options,"modulename")
work_mode_arg = get_arg(options,"mode")
target_file_arg = get_arg(options,"target") (filepath,filename_we) = os.path.split(file_name_arg)
(filename,ext) = os.path.splitext(filename_we) rg.module_name = filename if module_name_arg is None else module_name_arg
print('file name:{}\t\tmodule name:{}'.format(filename_we,rg.module_name)) regex_dict = compile_regex(module_head=rg.module_name,module_ports=True,width=True)
rg.get_module_specified_lines(regex_dict['module_head'],file_name_arg)
#rg.display_list_for_test(rg.extract_list) rg.extract_ports_info(regex_dict['module_ports'],regex_dict['width'])
#rg.display_list_for_test(rg.info_list) rg.gen_module_instance(target_file_arg,work_mode_arg)
inst_gen_app.py
在进阶版的脚本中采用了OOP特性,将相关的数据结构和function封装为Rtl_generator class。把命令行选项参数提取和正则表达式部分放在了inst_gen_app.py中完成。
根据生成逻辑中的三个阶段详细阐述内部原理:获取指定module代码段过程中,首先检测是否为注释行,若是则利用continue跳过,为有效行才进一步分析。利用add_flag指示是否检测到module头,若检测到则将代码行添加在extract_list里直至遇到endmodule停止。从module代码段中提取端口信息,使用regex_ports的各个group分离出端口名称、位宽以及方向部分字符串。其中位宽部分再次使用regex_width以及运算得到真实的位宽数值,很简单一看就懂不再赘述了。之后以字典的形式存储在info_list中。最后是生成Instance的部分,判断工作模式,若是默认的gen_inst_only则只产生Instance,若是gen_inst_wc,也就是generate instance with connections,那么在instance的端口上添加同名的连接信号以及该信号的声明,有木有太方便!
三、运行结果
最后我们来看下运行结果,这次在WINDOW的Pycharm环境下开发的,terminal和LINUX中的命令行用起来一样:
> python inst_gen_app.py -filename video_system_wrapper.v -mode gen_inst_wc -target testbench.sv
设计原文件与生成文件如下:
//Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
//--------------------------------------------------------------------------------
//Tool Version: Vivado v.2017.4 (win64) Build 2086221 Fri Dec 15 20:55:39 MST 2017
//Date : Sun Mar 22 12:40:33 2020
//Host : DESKTOP-CE32R3P running 64-bit major release (build 9200)
//Command : generate_target video_system_wrapper.bd
//Design : video_system_wrapper
//Purpose : IP block netlist
//--------------------------------------------------------------------------------
`timescale ps / ps module video_system_wrapper
(aclk_0,
aresetn_0,
camera_rstn,
din_0,
en_capture_0,
href_0,
locked_0,
m_axis_video_0_tdata,
m_axis_video_0_tlast,
m_axis_video_0_tready,
m_axis_video_0_tuser,
m_axis_video_0_tvalid,
overflow_0,
pclk_0,
s_axis_video_0_tdata,
s_axis_video_0_tlast,
s_axis_video_0_tready,
s_axis_video_0_tuser,
s_axis_video_0_tvalid,
status_0,
underflow_0,
vga_clk,
vid_io_out_0_active_video,
vid_io_out_0_data,
vid_io_out_0_field,
vid_io_out_0_hblank,
vid_io_out_0_hsync,
vid_io_out_0_vblank,
vid_io_out_0_vsync,
vid_io_out_reset_0,
vsync_0,
vtc_ctrl_araddr,
vtc_ctrl_arready,
vtc_ctrl_arvalid,
vtc_ctrl_awaddr,
vtc_ctrl_awready,
vtc_ctrl_awvalid,
vtc_ctrl_bready,
vtc_ctrl_bresp,
vtc_ctrl_bvalid,
vtc_ctrl_rdata,
vtc_ctrl_rready,
vtc_ctrl_rresp,
vtc_ctrl_rvalid,
vtc_ctrl_wdata,
vtc_ctrl_wready,
vtc_ctrl_wstrb,
vtc_ctrl_wvalid);
input aclk_0;
input aresetn_0;
output camera_rstn;
input [:]din_0;
input en_capture_0;
input href_0;
output locked_0;
output [:]m_axis_video_0_tdata;
output m_axis_video_0_tlast;
input m_axis_video_0_tready;
output m_axis_video_0_tuser;
output m_axis_video_0_tvalid;
output overflow_0;
input pclk_0;
input [:]s_axis_video_0_tdata;
input s_axis_video_0_tlast;
output s_axis_video_0_tready;
input s_axis_video_0_tuser;
input s_axis_video_0_tvalid;
output [:]status_0;
output underflow_0;
input vga_clk;
output vid_io_out_0_active_video;
output [:]vid_io_out_0_data;
output vid_io_out_0_field;
output vid_io_out_0_hblank;
output vid_io_out_0_hsync;
output vid_io_out_0_vblank;
output vid_io_out_0_vsync;
input vid_io_out_reset_0;
input vsync_0;
input [:]vtc_ctrl_araddr;
output vtc_ctrl_arready;
input vtc_ctrl_arvalid;
input [:]vtc_ctrl_awaddr;
output vtc_ctrl_awready;
input vtc_ctrl_awvalid;
input vtc_ctrl_bready;
output [:]vtc_ctrl_bresp;
output vtc_ctrl_bvalid;
output [:]vtc_ctrl_rdata;
input vtc_ctrl_rready;
output [:]vtc_ctrl_rresp;
output vtc_ctrl_rvalid;
input [:]vtc_ctrl_wdata;
output vtc_ctrl_wready;
input [:]vtc_ctrl_wstrb;
input vtc_ctrl_wvalid; wire aclk_0;
wire aresetn_0;
wire camera_rstn;
wire [:]din_0;
wire en_capture_0;
wire href_0;
wire locked_0;
wire [:]m_axis_video_0_tdata;
wire m_axis_video_0_tlast;
wire m_axis_video_0_tready;
wire m_axis_video_0_tuser;
wire m_axis_video_0_tvalid;
wire overflow_0;
wire pclk_0;
wire [:]s_axis_video_0_tdata;
wire s_axis_video_0_tlast;
wire s_axis_video_0_tready;
wire s_axis_video_0_tuser;
wire s_axis_video_0_tvalid;
wire [:]status_0;
wire underflow_0;
wire vga_clk;
wire vid_io_out_0_active_video;
wire [:]vid_io_out_0_data;
wire vid_io_out_0_field;
wire vid_io_out_0_hblank;
wire vid_io_out_0_hsync;
wire vid_io_out_0_vblank;
wire vid_io_out_0_vsync;
wire vid_io_out_reset_0;
wire vsync_0;
wire [:]vtc_ctrl_araddr;
wire vtc_ctrl_arready;
wire vtc_ctrl_arvalid;
wire [:]vtc_ctrl_awaddr;
wire vtc_ctrl_awready;
wire vtc_ctrl_awvalid;
wire vtc_ctrl_bready;
wire [:]vtc_ctrl_bresp;
wire vtc_ctrl_bvalid;
wire [:]vtc_ctrl_rdata;
wire vtc_ctrl_rready;
wire [:]vtc_ctrl_rresp;
wire vtc_ctrl_rvalid;
wire [:]vtc_ctrl_wdata;
wire vtc_ctrl_wready;
wire [:]vtc_ctrl_wstrb;
wire vtc_ctrl_wvalid; video_system video_system_i
(.aclk_0(aclk_0),
.aresetn_0(aresetn_0),
.camera_rstn(camera_rstn),
.din_0(din_0),
.en_capture_0(en_capture_0),
.href_0(href_0),
.locked_0(locked_0),
.m_axis_video_0_tdata(m_axis_video_0_tdata),
.m_axis_video_0_tlast(m_axis_video_0_tlast),
.m_axis_video_0_tready(m_axis_video_0_tready),
.m_axis_video_0_tuser(m_axis_video_0_tuser),
.m_axis_video_0_tvalid(m_axis_video_0_tvalid),
.overflow_0(overflow_0),
.pclk_0(pclk_0),
.s_axis_video_0_tdata(s_axis_video_0_tdata),
.s_axis_video_0_tlast(s_axis_video_0_tlast),
.s_axis_video_0_tready(s_axis_video_0_tready),
.s_axis_video_0_tuser(s_axis_video_0_tuser),
.s_axis_video_0_tvalid(s_axis_video_0_tvalid),
.status_0(status_0),
.underflow_0(underflow_0),
.vga_clk(vga_clk),
.vid_io_out_0_active_video(vid_io_out_0_active_video),
.vid_io_out_0_data(vid_io_out_0_data),
.vid_io_out_0_field(vid_io_out_0_field),
.vid_io_out_0_hblank(vid_io_out_0_hblank),
.vid_io_out_0_hsync(vid_io_out_0_hsync),
.vid_io_out_0_vblank(vid_io_out_0_vblank),
.vid_io_out_0_vsync(vid_io_out_0_vsync),
.vid_io_out_reset_0(vid_io_out_reset_0),
.vsync_0(vsync_0),
.vtc_ctrl_araddr(vtc_ctrl_araddr),
.vtc_ctrl_arready(vtc_ctrl_arready),
.vtc_ctrl_arvalid(vtc_ctrl_arvalid),
.vtc_ctrl_awaddr(vtc_ctrl_awaddr),
.vtc_ctrl_awready(vtc_ctrl_awready),
.vtc_ctrl_awvalid(vtc_ctrl_awvalid),
.vtc_ctrl_bready(vtc_ctrl_bready),
.vtc_ctrl_bresp(vtc_ctrl_bresp),
.vtc_ctrl_bvalid(vtc_ctrl_bvalid),
.vtc_ctrl_rdata(vtc_ctrl_rdata),
.vtc_ctrl_rready(vtc_ctrl_rready),
.vtc_ctrl_rresp(vtc_ctrl_rresp),
.vtc_ctrl_rvalid(vtc_ctrl_rvalid),
.vtc_ctrl_wdata(vtc_ctrl_wdata),
.vtc_ctrl_wready(vtc_ctrl_wready),
.vtc_ctrl_wstrb(vtc_ctrl_wstrb),
.vtc_ctrl_wvalid(vtc_ctrl_wvalid));
endmodule
video_system_wrapper.v
module wrapper();
reg [-:] aclk_0;
reg [-:] aresetn_0;
wire [-:] camera_rstn;
reg [-:] din_0;
reg [-:] en_capture_0;
reg [-:] href_0;
wire [-:] locked_0;
wire [-:] m_axis_video_0_tdata;
wire [-:] m_axis_video_0_tlast;
reg [-:] m_axis_video_0_tready;
wire [-:] m_axis_video_0_tuser;
wire [-:] m_axis_video_0_tvalid;
wire [-:] overflow_0;
reg [-:] pclk_0;
reg [-:] s_axis_video_0_tdata;
reg [-:] s_axis_video_0_tlast;
wire [-:] s_axis_video_0_tready;
reg [-:] s_axis_video_0_tuser;
reg [-:] s_axis_video_0_tvalid;
wire [-:] status_0;
wire [-:] underflow_0;
reg [-:] vga_clk;
wire [-:] vid_io_out_0_active_video;
wire [-:] vid_io_out_0_data;
wire [-:] vid_io_out_0_field;
wire [-:] vid_io_out_0_hblank;
wire [-:] vid_io_out_0_hsync;
wire [-:] vid_io_out_0_vblank;
wire [-:] vid_io_out_0_vsync;
reg [-:] vid_io_out_reset_0;
reg [-:] vsync_0;
reg [-:] vtc_ctrl_araddr;
wire [-:] vtc_ctrl_arready;
reg [-:] vtc_ctrl_arvalid;
reg [-:] vtc_ctrl_awaddr;
wire [-:] vtc_ctrl_awready;
reg [-:] vtc_ctrl_awvalid;
reg [-:] vtc_ctrl_bready;
wire [-:] vtc_ctrl_bresp;
wire [-:] vtc_ctrl_bvalid;
wire [-:] vtc_ctrl_rdata;
reg [-:] vtc_ctrl_rready;
wire [-:] vtc_ctrl_rresp;
wire [-:] vtc_ctrl_rvalid;
reg [-:] vtc_ctrl_wdata;
wire [-:] vtc_ctrl_wready;
reg [-:] vtc_ctrl_wstrb;
reg [-:] vtc_ctrl_wvalid; video_system_wrapper inst_name
(
.aclk_0 (aclk_0) ,//input width:1
.aresetn_0 (aresetn_0) ,//input width:1
.camera_rstn (camera_rstn) ,//output width:1
.din_0 (din_0) ,//input width:8
.en_capture_0 (en_capture_0) ,//input width:1
.href_0 (href_0) ,//input width:1
.locked_0 (locked_0) ,//output width:1
.m_axis_video_0_tdata (m_axis_video_0_tdata) ,//output width:24
.m_axis_video_0_tlast (m_axis_video_0_tlast) ,//output width:1
.m_axis_video_0_tready (m_axis_video_0_tready) ,//input width:1
.m_axis_video_0_tuser (m_axis_video_0_tuser) ,//output width:1
.m_axis_video_0_tvalid (m_axis_video_0_tvalid) ,//output width:1
.overflow_0 (overflow_0) ,//output width:1
.pclk_0 (pclk_0) ,//input width:1
.s_axis_video_0_tdata (s_axis_video_0_tdata) ,//input width:24
.s_axis_video_0_tlast (s_axis_video_0_tlast) ,//input width:1
.s_axis_video_0_tready (s_axis_video_0_tready) ,//output width:1
.s_axis_video_0_tuser (s_axis_video_0_tuser) ,//input width:1
.s_axis_video_0_tvalid (s_axis_video_0_tvalid) ,//input width:1
.status_0 (status_0) ,//output width:32
.underflow_0 (underflow_0) ,//output width:1
.vga_clk (vga_clk) ,//input width:1
.vid_io_out_0_active_video (vid_io_out_0_active_video) ,//output width:1
.vid_io_out_0_data (vid_io_out_0_data) ,//output width:24
.vid_io_out_0_field (vid_io_out_0_field) ,//output width:1
.vid_io_out_0_hblank (vid_io_out_0_hblank) ,//output width:1
.vid_io_out_0_hsync (vid_io_out_0_hsync) ,//output width:1
.vid_io_out_0_vblank (vid_io_out_0_vblank) ,//output width:1
.vid_io_out_0_vsync (vid_io_out_0_vsync) ,//output width:1
.vid_io_out_reset_0 (vid_io_out_reset_0) ,//input width:1
.vsync_0 (vsync_0) ,//input width:1
.vtc_ctrl_araddr (vtc_ctrl_araddr) ,//input width:9
.vtc_ctrl_arready (vtc_ctrl_arready) ,//output width:1
.vtc_ctrl_arvalid (vtc_ctrl_arvalid) ,//input width:1
.vtc_ctrl_awaddr (vtc_ctrl_awaddr) ,//input width:9
.vtc_ctrl_awready (vtc_ctrl_awready) ,//output width:1
.vtc_ctrl_awvalid (vtc_ctrl_awvalid) ,//input width:1
.vtc_ctrl_bready (vtc_ctrl_bready) ,//input width:1
.vtc_ctrl_bresp (vtc_ctrl_bresp) ,//output width:2
.vtc_ctrl_bvalid (vtc_ctrl_bvalid) ,//output width:1
.vtc_ctrl_rdata (vtc_ctrl_rdata) ,//output width:32
.vtc_ctrl_rready (vtc_ctrl_rready) ,//input width:1
.vtc_ctrl_rresp (vtc_ctrl_rresp) ,//output width:2
.vtc_ctrl_rvalid (vtc_ctrl_rvalid) ,//output width:1
.vtc_ctrl_wdata (vtc_ctrl_wdata) ,//input width:32
.vtc_ctrl_wready (vtc_ctrl_wready) ,//output width:1
.vtc_ctrl_wstrb (vtc_ctrl_wstrb) ,//input width:4
.vtc_ctrl_wvalid (vtc_ctrl_wvalid) //input width:1
);
endmodule
testbench.sv
总结下Usage:
-filename module所在文件的文件名
-modulename 指定要产生instance的module名称(可选项,默认与文件同名)
-mode 工作模式,包括gen_inst_only和gen_inst_wc(可选项,默认为gen_inst_only)
-target 指定生成文件的文件名(可选项,默认为wrapper.v)
测试还不太充分,若有问题后续会在这篇文章基础上继续改进。下面会传到GITHUB上方便更新!
利用python自动生成verilog模块例化模板的更多相关文章
- 利用Python自动生成暴力破解的字典
Python是一款非常强大的语言.用于测试时它非常有效,因此Python越来越受到欢迎. 因此,在此次教程中我将聊一聊如何在Python中生成字典,并将它用于任何你想要的用途. 前提要求 1,Pyth ...
- python笔记 利用python 自动生成条形码 二维码
1. ean13标准条形码 from pystrich.ean13 import EAN13Encoder encode = EAN13Encoder(') encode.save('d:/barco ...
- Python自动生成代码工具
项目中有一个需求,对一个基类而言,拥有一个比较方法和拷贝方法,某些地方需要频繁地对这两个方法进行调用.对于所有子类而言,需要重写这两个方法,并在其中维护类内一些成员变量.例如有一个变量m_iMyVal ...
- 基于MATLAB2016b图形化设计自动生成Verilog语言的积分模块及其应用
在电力电子变流器设备中,常常需要计算发电量,由于电力电子变流器设备一般是高频变流设备,所以发电量的计算几乎时实时功率的积分,此时就会用到一个积分模块.发电量计算的公式如下:Q=∫P. FPGA由于其并 ...
- Verilog与VHDL的混合模块例化
1,大小写与转义 对VHDL解释器而言,对于模块名和端口名, (1) 若有转义 a) 先不考虑转义,寻找与字符串完全相同的VHDL模块: 若找不到: b) 考虑转义,寻找对应的Verilog模块. ( ...
- 【机器学习PAI实战】—— 玩转人工智能之利用GAN自动生成二次元头像
前言 深度学习作为人工智能的重要手段,迎来了爆发,在NLP.CV.物联网.无人机等多个领域都发挥了非常重要的作用.最近几年,各种深度学习算法层出不穷, Generative Adverarial Ne ...
- 从用python自动生成.h的头文件集合和类声明集合到用python读写文件
最近在用python自动生成c++的类.因为这些类会根据需求不同产生不同的类,所以需要用python自动生成.由于会产生大量的类,而且这些类是变化的.所以如果是在某个.h中要用include来加载这些 ...
- [06] 利用mybatis-generator自动生成代码
1.mybatis-generator 概述 MyBatis官方提供了逆向工程 mybatis-generator,可以针对数据库表自动生成MyBatis执行所需要的代码(如Mapper.java.M ...
- 利用Python 脚本生成 .h5 文件 代码
利用Python 脚本生成 .h5 文件 import os, json, argparse from threading import Thread from Queue import Queue ...
随机推荐
- 设计模式-状态模式(State)
状态模式是行为模式的一种,状态模式允许改变对象内部状态来改变对象的行为. 角色和职责: 1.上下文(Context)-Order: 拥有内部的状态 2.状态接口(Status)-State: 一 ...
- c++学习书籍推荐《面向对象程序设计:C++语言描述(原书第2版)》下载
百度云及其他网盘下载地址:点我 <面向对象程序设计:C++语言描述(原书第2版)>内容丰富,结构合理,写作风格严谨,深刻地论述了c++语言的面向对象编程的各种技术,主要内容包括:面向对象编 ...
- Windows下通过CMD命令行程序操作MySQL数据库
注意:如果您的MySQL没有安装在C盘下,先使用命令进入MySQL的安装目录下的bin目录中才可以进行后续操作. 方法如下:例如您安装在D盘.先输入 D: 回车即可进入D盘,再输入cd D:\您my ...
- Java SpringBoot 如何使用 IdentityServer4 作为验证学习笔记
这边记录下如何使用IdentityServer4 作为 Java SpringBoot 的 认证服务器和令牌颁发服务器.本人也是新手,所以理解不足的地方请多多指教.另外由于真的很久没有写中文了,用词不 ...
- python接口自动化(三十二)--Python发送邮件(常见四种邮件内容)番外篇——上(详解)
简介 本篇文章与前边没有多大关联,就是对前边有关发邮件的总结和梳理.在写脚本时,放到后台运行,想知道执行情况,会通过邮件.SMS(短信).飞信.微信等方式通知管理员,用的最多的是邮件.在linux下, ...
- Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现
Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现 一.漏洞描述 S2-057漏洞产生于网站配置xml的时候,有一个namespace的 ...
- Linux 文件编程、时间编程基本函数
文件编程 文件描述符 fd --->>>数字(文件的身份证,代表文件身份),通过 fd 可找到正在操作或需要打开的文件. 基本函数操作: 1)打开/创建文件 int open (co ...
- 【译】深入理解G1的GC日志(一)
本文翻译自:https://www.redhat.com/en/blog/collecting-and-reading-g1-garbage-collector-logs-part-2?source= ...
- Git常用操作指南
目录 前言 Git简介 安装之后第一步 创建版本库 本地仓库 远程仓库 版本控制 工作区和暂存区 版本回退 撤销修改 删除文件 分支管理 创建与合并分支 解决冲突 分支管理策略 状态存储 多人协作 R ...
- Envoy 源码分析--LDS
Envoy 源码分析--LDS LDS 是 Envoy 用来自动获取 listener 的 API. Envoy 通过 API 可以增加.修改或删除 listener. 先来总结下 listener ...