gvim【二】【ab命令快速制作verilog模板】

一、前言

gvim对于编写Verilog代码有个神奇的功能,可以快速制作verilog模板,但是网上没有相应的分享,所以自己制作了一个,分享出来(windows下)。

模板包括:文件头、常用自定义命令、Module中常用模板(包括模块基本模板、组合时序逻辑模板、计数器、状态机、边沿检测器、同步器、触发器、触发器例化、头文件等)、预编译模板(延时、仿真精度)、TB模板(TB基本模板、产生时钟复位、延时任务、生成波形图文件、产生随机数、取对数、打开文件、断言等)、注释(注释头、段注释、端口注释等)、任务模板(延时任务、任务模板)。

注: 这些模板都是我自己经常使用的模板

二、使用方法

1.将以下代码拷贝到 _vimrc文件

该文件在安装目录中,如果不知道安装目录在哪,可以在末行模式下输入::echo $VIM就可以显示安装位置。

各命令意思已经在注释中注明。

请注意:以下内容其实具有灵活性,可以根据你自己的需求添加相应的代码。我的命名规格一般是大写缩写+小写缩写,什么意思呢,举个例子:就拿最常见的Verilog模块的框架来说,我的重命名为:MBmkMB就是模板的缩写,mk模块的缩写,所以如果你想生成一个模块的模板,只需要输入MBmk即可,其他的都类似。

"""""""""""""""""""""""""""""""新文件标题""""""""""""""""""""""""""""""""""""""""""""""""""
 
"按F4自动插入文件头 
map <F4> :call SetTitle() <cr>:11 <cr><end>i

"定义函数SetTitle,自动插入文件头 
func SetTitle() 
  call append(line(".")-1 , "`timescale 1ns/1ps")
  call append(line(".")+0 , "//******************************************************************")
  call append(line(".")+1 , "//") 
  call append(line(".")+2 , "//*@File Name: ".expand("%"))
  if expand("%:e") == "v"
    let tmp1 = "verilog"
  elseif expand("%:e") == "sv"
    let tmp1 = "system verilog"
  elseif expand("%:e") == "c"
    let tmp1 = "C"
  elseif expand("%:e") == "cpp"
    let tmp1 = "C++"
  elseif expand("%:e") == "txt"
    let tmp1 = "plain text"
  else
    let tmp1 = "NONE"
  endif
  call append(line(".")+3 , "//*@File Type: ".expand(tmp1))
  call append(line(".")+4 , "//*@Version  : 0.0")
  call append(line(".")+5 , "//*@Author   : Zehua Dong, SIGS")
  call append(line(".")+6 , "//*@E-mail   : 1285507636@qq.com")
  call append(line(".")+7 , "//*@Date     : ".strftime("%c"))  
  call append(line(".")+8 , "//*@Function :  ")  
  call append(line(".")+9 , "//")
  call append(line(".")+10, "//*@V0.0     : Initial.")  
  call append(line(".")+11, "//")
  call append(line(".")+12, "//******************************************************************") 
  call append(line(".")+13, "")
  call append(line(".")+14, "//")
  call append(line(".")+15, "// Header file")
  call append(line(".")+16, "`include \"common.vh\"")
  call append(line(".")+17, "")
  call append(line(".")+18, "//")
  call append(line(".")+19, "// Module")
  call append(line(".")+20, "")
 
  "新建文件后,自动定位到文件末尾
  autocmd BufNewFile * normal G

endfunc 


""""""""""""""""""""""""""""""""自定义命令"""""""""""""""""""""""""""""""""""

"显示时间,两种方式,可以取消注释都试试效果
":ab xtime <c-r>=strftime("%Y-%m-%d")<cr>
:ab xtime <c-r>=strftime("%Y-%m-%d %H:%M:%S")<cr>

""""""""""""""""""""""""""""""""Module"""""""""""""""""""""""""""""""""""

"模块定义
:ab MBmk module (<enter>clk                  <enter>rst_n            <enter>);<enter><enter>input                           clk                     <enter>input                           rst_n                <enter><enter><enter><enter><enter><enter><enter><enter><enter><enter><enter><enter><enter><enter><enter>endmodule

"组合逻辑
:ab Zuhe always @(*) begin<Enter>if(  )begin<Enter>end<Enter>else begin<Enter>end<Enter>end
     
"时序逻辑
:ab Shixu always @( posedge clk or negedge rst_n ) begin<enter>if( ~rst_n ) begin<enter>end<enter>else begin<enter>end<enter>end      
      
"计数器
:ab MBjsq `define   COUNT_BITS       8<enter><enter>reg    [ `COUNT_BITS-1:0 ] count;<enter><enter>always @( posedge clk or negedge rst_n ) begin<enter>if( ~rst_n ) begin<enter>count <= #`DEL `COUNT_BITS'd0;<enter>end<enter>else if( count ) begin<enter>count <= #`DEL `COUNT_BITS'd0;<enter>end<enter>else begin<enter>count <= #`DEL count + `COUNT_BITS'd1;<enter>end<enter>end
     
"状态机
:ab MBfsm reg       [2:0]   cs;<enter>reg       [2:0]   ns;<enter>parameter [2:0]  IDLE   = 3'b000,<enter>S1     = 3'b001,<enter>S2     = 3'b010,<enter>ERROR  = 3'b100;<enter>always @( posedge clk or negedge rst_n ) begin<enter>if ( !rst_n ) begin<enter>cs <= IDLE;<enter>end<enter>else begin<enter>cs <= ns;<enter>end<enter>end<enter><enter>always @( * ) begin<enter>ns = IDLE;<enter>case ( cs )<enter>IDLE: begin<enter>if (  ) begin<enter>ns = S1;<enter>end<enter>else begin<enter>ns = IDLE;<enter>end<enter>end<enter>S1: begin<enter>if (  ) begin<enter>ns = S2;<enter>end <enter>else begin <enter>ns = S1;<enter>end<enter>end <enter>S2: begin <enter>  if (  ) begin<enter>ns = ERROR; <enter>end <enter>else begin <enter>ns = S2;<enter>end<enter>end<enter>ERROR: begin <enter>  if (  ) begin<enter>ns = IDLE; <enter>end<enter>else begin<enter>ns = ERROR;<enter>end<enter>end <enter>endcase <enter>end<enter><enter>always @( posedge clk or negedge rst_n ) begin <enter>if ( !rst_n ) begin <enter>end<enter>else begin <enter>case ( ns )<enter>endcase <enter>end <enter>end      

"边沿检测器
:ab MBby reg     _en_q;<enter>wire    _en_flag;<enter><enter>always @( posedge clk or negedge rst_n ) begin<enter>if( ~rst_n ) begin<enter>_en_q <= #`DEL 1'b0;<enter>end<enter>else begin<enter>_en_q <= #`DEL _en;<enter>end<enter>end<enter>assign _en_flag = ( ~_en_q ) && ( _en );

"同步器
:ab MBtongbuqi  reg rst_s1;<enter>reg rst_s2;<enter><enter>always @ (posedge clk or negedge rst_n) begin<enter>if (!rst_n) begin<enter>rst_s1 <= 1'b0;<enter>rst_s2 <= 1'b0;<enter>end<enter>else begin<enter>rst_s1 <= 1'b1	;<enter>rst_s2 <= rst_s1;<enter>end<enter>end

"触发器模板
:ab MBdff module dff #( parameter SIZE = 64 )(<enter>  clk    ,<enter>rst_n  ,<enter>D      ,<enter>Q<enter>);<enter><enter>input                     clk    ;<enter>input                     rst_n  ;<enter>input   [SIZE - 1 : 0]    D      ;<enter>output  [SIZE - 1 : 0]    Q      ;<enter><enter>wire                      clk    ;<enter>wire                      rst_n  ;<enter>wire    [SIZE - 1 : 0]    D      ;<enter>reg     [SIZE - 1 : 0]    Q      ;<enter><enter>always @( posedge clk or negedge rst_n ) begin<enter>if( ~rst_n ) begin<enter>Q <= 'b0;<enter>end<enter>else begin<enter>Q <= D;<enter>end<enter>end<enter><enter>endmodule<enter>

"触发器例化tb_
:ab LHdff dff #(  ) dff_dut1(<enter>.clk  ( clk    ),<enter>.rst_n( rst_n  ),<enter>.D    (  ),<enter>.Q    (  )<enter>);

"共同的头文件
:ab MBc `ifndef COMMON_HEADER <cr>`define COMMON_HEADER<cr><cr>`define CYCLE 10<cr>`define HALF_CYCLE (CYCLE/2)<cr><cr>`define TB_BEGIN $display("=== BEGIN TESTBENCH %m ===\n");<cr>`define TB_END #`CYCLE $display("\n===== END TESTBENCH %m ===");<cr><cr>`endif

"""""""""""""""""""""""""""""""""预编译""""""""""""""""""""""""""""""""""
"延时宏定义
:ab YBYys `define DEL 1

"仿真精度
:ab YBYjd `timescale 1ns/1ps

""""""""""""""""""""""""""""""""Testbench""""""""""""""""""""""""""""""""""

"产生时钟
:ab TBsz initial begin<enter>tb_clk = 0;<enter>end<enter>always #`HALF_CYCLE tb_clk = ~tb_clk;

"产生复位信号
:ab TBfw initial begin<enter>tb_rst_n = 1;<enter>repeat(1) @( posedge tb_clk ) #1;<enter>tb_rst_n = 0;<enter>repeat(1) @( posedge tb_clk ) #1;<enter>tb_rst_n = 1;<enter>end

"延时
:ab TBys repeat( 1 ) @( posedge tb_clk ) #1;

"波形图
:ab TBbxt initial begin<enter>$dumpfile(" .vcd ");<enter>$dumpvars();<enter>end

"随机数
:ab TBsjs   integer   seed;<enter>reg[31:0] num1;<enter>initial begin<enter>if ( !$value$plusargs("seed+%d", seed) ) begin<enter>seed = 0;<enter>end<enter>@(posedge tb_clk);<enter>#1;<enter>num1 = $random(seed);<enter>end

"取对数,用来求位宽
:ab TBds function integer clogb2;<enter>input [31:0] value;<enter>begin<enter>value = value - 1;<enter>for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) begin<enter>value = value >> 1;<enter>end<enter>end<enter>endfunction 

"打开文件
:ab TBwj integer                     FILE;<enter>  FILE=$fopen(" .txt ", "a+");<enter>$fdisplay(FILE, " = %h", );<enter>$fclose(FILE);

"TB模板
:ab TBmb module _tb();<enter><enter>  reg                 tb_clk                         <enter>reg                 tb_rst_n                <enter><enter>task delay;<enter>input [31:0] num;<enter>begin<enter>repeat(num) @(posedge tb_clk);<enter>#1;<enter>end<enter>endtask<enter><enter>initial begin<enter>tb_clk = 0;<enter>end<enter>always #`HALF_CYCLE tb_clk = ~tb_clk;<enter><enter>initial begin<enter>tb_rst_n = 1;<enter>delay(1);<enter>tb_rst_n = 0;<enter>delay(1);<enter>tb_rst_n = 1;<enter>end<enter><enter>initial begin<enter>$dumpfile(" _tb.vcd ");<enter>$dumpvars();<enter>end<enter><enter>initial begin<enter>`TB_BEGIN<enter>delay(3);<enter><enter>`TB_END<enter>$finish;<enter>end<enter><enter><enter>endmodule

:ab TBb `TB_BEGIN
:ab TBe `TB_END

"断言assert
:ab TBas assert( tb_ ==  ) $strobe("%0d, !!TEST SUCCESS!!", $time);<enter>else $error("tb_ = %0d", tb_);

"TB中initial块
:ab TBin initial begin<CR>`TB_BEGIN<CR><CR>`TB_END<CR>$finish;<CR>end




""""""""""""""""""""""""""""""""注释""""""""""""""""""""""""""""""""""""""""
"注释头
:ab ZSt //*************************************************************<enter><enter>*@File name: <enter><enter>*@File type: <enter><enter>*@Version  : 0.0.1<enter><enter>*@Author   : Zehua Dong, HITWH<enter><enter>*@E-mail   : hitdongzh@163.com<enter><enter>*@Date     : <enter>*@Function : <enter><enter>*************************************************************<enter><enter> Head files<enter>`include "common.v"<enter><enter> Module definition

"段注释
:ab ZSk /<enter>*Function Description:<enter>*  <enter>*  <enter>///

"端口注释
:ab ZSdk   //===========================================================<enter>* Input and output ports<enter>* Internal signals<enter>===========================================================

"分割注释
:ab ZS //*******************************<enter><enter>*******************************




""""""""""""""""""""""""""""""""任务""""""""""""""""""""""""""""""""""""""""

"延时任务
:ab RWys task delay;<enter>input [31:0] num;<enter>begin<enter>repeat(num) @(posedge tb_clk);<enter>#1;<enter>end<enter>endtask

"任务模板
:ab RWmb task ;<enter>input [ :0] <enter>begin<enter>end<enter>endtask

上面的代码中新文件标题那里,定义了代码的注释头,大家修改成自己的信息后,直接按F4即可插入。

2.打开gvim,敲入模板名字,敲回车即可

此处给大家演示一下我平时写Verilog的步骤:

请添加图片描述
1、首先按F4,插入文件头,然后输入该文件的功能注释(对了我上面的演示忘记写模块名了哈哈哈,总是忘记,大家记得写呀)。
2、跳到最后一行,输入MBmk,敲回车,就形成了一个模块的模板。
3、添加输入输出端口,clk和rst_n默认已经添加。请注意我的操作,在输入一个端口后,敲了很多空格(或者TAB),一个原因是美观,再者是为了方便写逗号,这样子你就可以通过列操作将逗号整齐的写到端口后面。但是对于某些软件来说,可能把空格也识别为端口名,所以这种做法要根据具体软件来决定是否使用。

为什么要将逗号写整齐呢?难道只是强迫症为了好看嘛?

当然不是,这样写端口,后面你在例化模块的时候就可以直接复制这里的代码,而不用手敲了。如下所示。
请添加图片描述
是不是方便了很多呢?
4、添加完端口名后,开始定义端口的输入输出,以及wire、reg等类型,只需要按yy复制input clk;那一行,然后有多少个端口就粘贴几次,快捷键为数字+p,然后修改inputoutput关键字。当然信号位宽也要修改。
5、将改好的inputoutput的所有端口都复制一下,然后按p进行粘贴,ctrl+q列选,将inputoutput全部先改为wire,然后修改需要的端口为reg类型。
6、添加核心代码,通过GVIM中的别名,添加你想要的代码即可。

上述过程看着麻烦,其实等你实践的时候就知道有多爽了。比起你手动一行一行敲,这样可以提升你的编程效率,把时间花在刀刃上。

_vimrc文件路径:
在这里插入图片描述
在这里插入图片描述

3. 自己制作模板方法

:ab name  code

:ab 为命令,name为你要制作的模板名字,code为代码,如果需要换行使用<enter>即可。

4. 注意事项

我的gvim自动缩进2空格,tab也为2空格,如果将代码复制进去格式不太好看的话可能是这个引起的,将以下代码复制到_vimrc文件中即可:

"设置缩进
"设置Tab长度为2空格
set expandtab
set tabstop=2
"设置自动缩进长度为2空格
set shiftwidth=2
"继承前一行的缩进方式,适用于多行注释"
set autoindent

使用模板可以减少不必要的重复,大量缩短时间,希望我的分享对你有帮助,转载请说明出处~

5. 下载

从我的github上进行下载。

三、本系列其他博客

  1. gvim【一】【安装和基本使用】
  2. gvim【二】【ab命令快速制作verilog模板】
  3. gvim【三】【_vimrc配置】
  • 19
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值