GVIM 是类似于记事本的代码编辑工具,但相比于记事本其输入效率更高,可以更好的提升工作 效率。由于 GVIM 具有丰富的代码补全、编译及错误跳转等便于编程的功能,其在 IC 开发领域得到 了广泛应用,也为学习 FPGA 工程提供了助力。GVIM 是一款 FPGA 工程师常用的软件,本文是基于明德扬的教程总结了一些常用且相对好用的命令。
首先是GVIM分为三种模式:命令模式(打开gvim为默认模式,即光标闪烁时就是命令模式);插入模式(左下角显示“插入”);列操作模式(左下角显示“可视块”)。
下图是三者的转换关系:
1.列删除的方法:在插入模式下,选择要删除的块,再按”ctrl+q“,再按delete
2.列插入:在命令模式下,光标放在要添加的行,然后按下”ctrl+q“,使用h,j,k,l(小写的L)去选择范围,最后按下I(大写的i),输入想要添加的数据,最后按下ESC。(多注意左下角在什么模式下)
3.模块框架:在插入模式下,输入”Module“
module module_name(
clk ,
rst_n ,
//其他信号,举例dout
dout
);
//参数定义
parameter DATA_W = 8;
//输入信号定义
input clk ;
input rst_n ;
//输出信号定义
output[DATA_W-1:0] dout ;
//输出信号reg定义
reg [DATA_W-1:0] dout ;
//中间信号定义
reg signal1;
//组合逻辑写法
always@(*)begin
end
//时序逻辑写法
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
end
else begin
end
end
endmodule
4.时序逻辑:在插入模式下输入“Shixu”或者“Shixu2”或“Shixu3”
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
end
else begin
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
end
else if()begin
end
else if()begin
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
end
else if()begin
end
else if()begin
end
else if()begin
end
end
5.组合逻辑:在插入模式下输入“Zuhe”或者“Zuhe2”或“Zuhe3”
always @(*)begin
end
always @(*)begin
if()begin
end
else begin
end
end
always @(*)begin
if()begin
end
else if()begin
end
else begin
end
end
6.计数器:在命令模式下,输入“:call MDYJSQ()” (当有多个计数器时,仍然用这个命令,计数器命名会自动+1)
reg [ ():0] cnt0 ;
wire add_cnt0 ;
wire end_cnt0 ;
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
cnt0 <= 0;
end
else if(add_cnt0) begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0+1 ;
end
end
assign add_cnt0 = ();
assign end_cnt0 = add_cnt0 && cnt0 == ()-1 ;
reg [ ():0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
cnt1 <= 0;
end
else if(add_cnt1) begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1+1 ;
end
end
assign add_cnt1 = ();
assign end_cnt1 = add_cnt1 && cnt1 == ()-1 ;
7.状态机:在插入模式下,输入“Ztj”
//四段式状态机
//第一段:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器(不需更改)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
state_c <= IDLE;
end
else begin
state_c <= state_n;
end
end
//第二段:组合逻辑always模块,描述状态转移条件判断
always@(*)begin
case(state_c)
IDLE:begin
if(idl2s1_start)begin
state_n = S1;
end
else begin
state_n = state_c;
end
end
S1:begin
if(s12s2_start)begin
state_n = S2;
end
else begin
state_n = state_c;
end
end
S2:begin
if(s22s3_start)begin
state_n = S3;
end
else begin
state_n = state_c;
end
end
default:begin
state_n = IDLE;
end
endcase
end
//第三段:设计转移条件
assign idl2s1_start = state_c==IDLE && ;
assign s12s2_start = state_c==S1 && ;
assign s22s3_start = state_c==S2 && ;
//第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出)
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
out1 <=1'b0 //初始化
end
else if(state_c==S1)begin
out1 <= 1'b1;
end
else begin
out1 <= 1'b0;
end
end
8.测试文件模板:在插入模式下,输入“Test”
`timescale 1 ns/1 ns
module testbench_name();
//时钟和复位
reg clk ;
reg rst_n;
//uut的输入信号
reg[3:0] din0 ;
reg din1 ;
//uut的输出信号
wire dout0;
wire[4:0] dout1;
//时钟周期,单位为ns,可在此修改时钟周期。
parameter CYCLE = 20;
//复位时间,此时表示复位3个时钟周期的时间。
parameter RST_TIME = 3 ;
//待测试的模块例化
module_name uut(
.clk (clk ),
.rst_n (rst_n ),
.din0 (din0 ),
.din1 (din1 ),
.dout0 (dout0 ),
.dout1 (dout1 )
);
//生成本地时钟50M
initial begin
clk = 0;
forever
#(CYCLE/2)
clk=~clk;
end
//产生复位信号
initial begin
rst_n = 1;
#2;
rst_n = 0;
#(CYCLE*RST_TIME);
rst_n = 1;
end
//输入信号din0赋值方式
initial begin
#1;
//赋初值
din0 = 0;
#(10*CYCLE);
//开始赋值
end
//输入信号din1赋值方式
initial begin
#1;
//赋初值
din1 = 0;
#(10*CYCLE);
//开始赋值
end
endmodule
总结:将GVIM编辑器和quartus或者vivado结合起来使用会事半功倍。