下载
GitHub - lidong1028/verilog_mode2
Verilog-mode2安装
适用范围
已经安装了gvim(version 7.x or above)的linux系统
安装教程
step1: 拷贝当前文件夹到自己的路径(任意路径)
step2: 执行./setup.sh,显示下面结果即安装成功
功能介绍
Verilog-mode功能
Verilog-mode的功能依然保留:
FileTemplate功能
File template可以根据自定义的模板进行新建文件,module名就是当前的文件名。
结果如下:
模板可以在plugin/automatic.v2.vim中修改这段来适用自己的编码风格:
Header功能
自动添加文件头
结果如下:
其中源码在plugin/automatic.v2.vim如下图位置,可以根据个人需求自定义。
Comment
Comment只是添加注释行,但不能直接注释代码,效果如下图所示。
添加always时序逻辑块
Always的风格也可以在这里修改:
添加always组合逻辑块
Always的风格也可以在这里修改:
添加case语句
Case语句的风格也可以在这里修改:
V2AA/V2DA
V2AA表示自动定义信号,V2DA表示删掉自动定义的信号。
V2AA表示自动定义信号包括两种:
- 端口的输出如果是寄存器类型,会自动定义成logic;
- 模块内部使用的信号会自动声明(包括reg和wire,目前不支持数组,需要在User define里面自己声明)
例如这是手动编辑的代码:
在执行V2AA后:
如果要删除自动定义的信号,可以执行V2DA:
但输出端口无法区分是用户自己加的logic,还是工具加的,所以V2DA不会删掉输出端口的logic。
VMAA/VMDA
VMAA是用来自动例化模块,VMDA是删除自动例化连接。
- 使用方法1:修改端口信号名
对mult模块进行例化,4个红框的内容都要保留。62~64行根据需求修改,如果不在62~64行的信号,会按照端口名直接连接。2号红框的逗号要保留,1号和3号红框的模块名要一致。
并且文件末尾的配置一定要包含例化的模块的文件。
verilog-library-files:设置verilog-mode的搜索文件
verilog-library-directories:设置verilog-mode的搜索路径
verilog-auto-inst-param-value: 值为t时,表示在autoinst时,使用模块例化的参数进行连线;值为nil时,表示在autoinst时,使用模块内部的参数例化端口进行连线;
执行结果如下:
可以看到:
- 对于模块中有clk和rst打头的信号,会自动定义到模块的输入端口(用户可以把21行删掉,即不会实现该功能)
- 变量声明区会自动定义模块的输出信号mult_out
- 在auto_template重新命名的,会按照用户定义的信号名连接,并且相应的端口后面会标记Templated
- 如果在auto_template重新改名后的信号加了[](例如dinb[]),则例化时对应的信号连接时会声明位宽(如dinb[DW_IN-1:0]),如果没有加[](例如dina),则例化时对应的信号连接时不会声明位宽(如dina)
- 模块例化是按照80行的括号对齐的。
- 使用方法2:正则匹配
信号支持正则匹配,如下图,把红框匹配到的内容赋给蓝框。
结果如下:
- 使用方法3:多个模块同时例化
新增1号红框的定义,与下面的蓝框内容匹配的,匹配的内容会赋给4号框。2号框匹配的内容会赋给3号框。
执行结果如下:
实例
afifo_wctrl模块
新建afifo_wctrl.v文件
使用FileTemplate
结果如下:
编写代码
选择空白处,执行如下操作:
手动编辑后的代码:
//=========================================
//Created by :xxx
//Filename :afifo_wctrl.v
//Author :xxx(RDC)
//Created On :2024-07-02 20:11
//Last Modified :
//Update Count :
//Description :
//
//
//=========================================
//
module afifo_wctrl #(
parameter integer AW = 4,
parameter integer ALFULL = 12
)
(
//=========================================
//ports declared by Verilog-mode tool
//=========================================
/*autoinput("^clk\|^rst")*/
input wclk,
input wrst_n,
input wsrst,
/*autoinput("^din\([0-1]\)_\(a\|b\)")*/
/*autooutput("^dout_*")*/
//=========================================
// ports declared by user
//=========================================
// input/output to/from internal logic block
input winc,
input [AW:0] r2w_gptr,
// output from inter-connection of internal instance
output ram_wen,
output [AW-1:0] ram_waddr, // Write address for memory
output logic [AW:0] wgptr, // Gray write address for sync to read clock domain
output logic wfull, // Write address for memory
output logic awfull, // Write almost full flag
output werr
);
//===========================
//Local parameters
//===========================
//
//===========================
//Local wires and registers
//===========================
/*autologic*/
/*autodefine*/
// Define flip-flop registers here
reg [AW:0] wbptr; //
// Define combination registers here
// Define wires here
wire awfull_tmp; //
wire [AW:0] wbptr_next; //
wire wfull_tmp; //
wire [AW:0] wgptr_next; //
// End of automatic define
// User define
reg [AW:0] r2w_bptr;
// End of user define
//
//===========================
//Main code begins here
//===========================
// 写指针产生
assign ram_wen = (winc & (~wfull)); //非满且写的时候,产生memory写使能
assign wbptr_next[AW:0] = wbptr[AW:0] + ram_wen; //非满且写的时候,写指针加一
assign wgptr_next[AW:0] = {1'd0,wbptr_next[AW:1]}^wbptr_next[AW:0]; //写指针二进制转格雷码
assign ram_waddr[AW-1:0] = wbptr[AW-1:0];
always@( posedge wclk or negedge wrst_n ) begin
if( !wrst_n) begin
wbptr[AW:0] <= {(AW+1){1'b0}};
wgptr[AW:0] <= {(AW+1){1'b0}};
end else if( wsrst) begin
wbptr[AW:0] <= {(AW+1){1'b0}};
wgptr[AW:0] <= {(AW+1){1'b0}};
end else begin
wbptr[AW:0] <= wbptr_next[AW:0];
wgptr[AW:0] <= wgptr_next[AW:0];
end
end
// 满/将满标志产生
assign wfull_tmp = (wgptr_next[AW:0] == {~r2w_gptr[AW:AW-1],r2w_gptr[AW-2:0]});
assign awfull_tmp = ((wbptr_next[AW:0] - r2w_bptr[AW:0]) > ALFULL);
always@( posedge wclk or negedge wrst_n ) begin
if( !wrst_n) begin
wfull <= 1'b0;
awfull <= 1'b0;
end else if( wsrst) begin
wfull <= 1'b0;
awfull <= 1'b0;
end else begin
wfull <= wfull_tmp;
awfull <= awfull_tmp;
end
end
//////////////////////////////// 格雷码转二进制 ///////////////////////////////////////////
generate for(genvar i=0;i<AW+1;i=i+1) begin :GRAY2BIN_R2W
always@(*) begin
r2w_bptr[i] = ^r2w_gptr[AW:i];
end
end
endgenerate
//////////////////////////////// 维测相关 ///////////////////////////////////////////
assign werr = winc & wfull; //强写
//=========================================
//Verilog-mode Setting:
//Local Variables:
//verilog-library-files: (
//"./test.v"
//)
//verilog-library-directories: (
//"."
//".."
//)
//verilog-auto-inst-param-value: t
//End:
//=========================================
endmodule
自动定义变量
执行完后:
(1)端口信号类型会自动更改
(2)自动新增中间信号的定义
其它子模块代码
afifo_rctrl模块
afifo_sync模块
afifo_mem模块
顶层模块集成
Step1: 新建afifo_top.v文件
Step2: 对这段进行修改
修改结果如下:
Step3:执行VMAA
结果如下:
模块的端口进行自动连接,并且可以按照指定的名字,并且模块间的信号自动声明。