用Emacs写Verilog

介绍verilog-mode的一个ppt:http://www.veripool.org/papers/verilog-mode_veritedium_20090925.pdf。它的官方网站:http://www.veripool.org/wiki/verilog-mode(应该是吧,没仔细考证)

电脑跑仿真,还得挺长时间的,顺便把用emacs写verilog的方便之处大概总结一下吧,我只能说:太方便了!

以 前用verilog-mode也就用个/*AUTOARG*/、/*AUTOWIRE*/、/*AUTOSENSE*/、/*AUTOINST*/之类 的,写个小工程基本也足够了。后来开始用/* AUTO_TEMPLATE*/、/*AUTOINSERTLISP*/,发现这个大大提高工作效率:有一个1000行左右的verilog模块(主要是 例化了很多其他模块),用verilog-mode只写了100行,然后等着自动生成就行了。虽说也可以copy-paste,然后再改改,不用真写 1000行,但这个工作量也不小,也有容易出错。

verilog-mode大概有这么几个作用吧(代码摘自http://www.veripool.org/projects/verilog-mode/wiki/Verilog-mode_veritedium):

注意:左边是需要写的,右边是C-c a自动生成的。

1 自动生成组合逻辑敏感列表 /*AUTOSENSE*/

always @ (/*AUTOSENSE*/) begin
outin = ina | inb;
out = outin;
end always @ (/*AUTOSENSE*/ina or inb) begin
outin = ina | inb;
out = outin;
end

2 自动生成端口 /*AUTOARG*/

module ex_arg (/*AUTOARG*/);
input i;
output o;
endmodule module ex_arg (/*AUTOARG*/
// Outputs
o,
// Inputs
i);

input i;
output o;
endmodule

3 自动例化 /*AUTOINST*/

module fanout (o,i)
input i;
output [31:0] o;
wire [31:0] o = {32{i}};
endmodule

module ex_inst (o,i)
input i;
output [31:0] o;
fanout fanout (/*AUTOINST*/);
endmodule

module fanout (o,i)
input i;
output [31:0] o;
wire [31:0] o = {32{i}};
endmodule

module ex_inst (o,i)
output o;
input i;
fanout fanout (/*AUTOINST*/
// Outputs
.o (o[31:0]),
// Inputs
.i (i));
endmodule

4 模板 /*AUTO_TEMPLATE*/,注意下面的@,和例化的序号(如下面的ms2中的2)是一致的

/* psm_mas AUTO_TEMPLATE (
.PTL_MAPVALIDX     (PTL_MAPVALID[@]),
.PTL_BUS                (PTL_BUSNEW[]),
); */

psm_mas ms2 (/*AUTOINST*/);

/* psm_mas AUTO_TEMPLATE (
.PTL_MAPVALIDX     (PTL_MAPVALID[@]),
.PTL_BUS                (PTL_BUSNEW[]),
); */

psm_mas ms2 (/*AUTOINST*/
// Outputs
.INSTDATAOUT     (INSTDATAOUT),
.PTL_MAPVALIDX   (PTL_MAPVALID[2]),   // Templated
.PTL_BUS         (PTL_BUSNEW[3:0]),   // Templated

5 lisp模板 /*AUTO_TEMPLATE*/,注意下面的@,后面可以跟一些lisp代码,比如上面的例子,ms2的PTL_MAPVALIDX 不是接(PTL_MAPVALID[2]),而是(PTL_MAPVALID[2+1]),那前面写成这样就行了((+ 1 @)是elisp的1+@):

/* psm_mas AUTO_TEMPLATE (
.PTL_MAPVALIDX     (PTL_MAPVALID[@“(+ 1 @)”]),
.PTL_BUS                (PTL_BUSNEW[]),
); */

这个功能相当强大,比如例化很多相同的模块的时候,连接关系通常会有规律,那么按照这个规律写elisp就可以了。

6 插入lisp语句 /*AUTOINSERTLISP*/,比如 /*AUTOINSERTLISP(my-insert 0 22 “my_init(\”c:\\\\my_src\\\\my_src%d\”);\n”)*/        /*AUTOINSERTLISP(my-insert 0 22 “my_init(\”c:\\\\my_src\\\\my_src%d\”);\n”)*/
// Beginning of automatic insert lisp
my_init(“c:\\my_src\\my_src0”);
my_init(“c:\\my_src\\my_src1”);
my_init(“c:\\my_src\\my_src2”);
my_init(“c:\\my_src\\my_src3”);
my_init(“c:\\my_src\\my_src4”);
my_init(“c:\\my_src\\my_src5”);
my_init(“c:\\my_src\\my_src6”);
my_init(“c:\\my_src\\my_src7”);
my_init(“c:\\my_src\\my_src8”);
my_init(“c:\\my_src\\my_src9”);
my_init(“c:\\my_src\\my_src10”);
my_init(“c:\\my_src\\my_src11”);
my_init(“c:\\my_src\\my_src12”);
my_init(“c:\\my_src\\my_src13”);
my_init(“c:\\my_src\\my_src14”);
my_init(“c:\\my_src\\my_src15”);
my_init(“c:\\my_src\\my_src16”);
my_init(“c:\\my_src\\my_src17”);
my_init(“c:\\my_src\\my_src18”);
my_init(“c:\\my_src\\my_src19”);
my_init(“c:\\my_src\\my_src20”);
my_init(“c:\\my_src\\my_src21”);
// End of automatics

如果要例化很多模块,或者写很多my_reg_0、my_reg_1……什么的,方便很多很多。上面的例子是做仿真时候指定test vector源文件的,就是现在正在跑的,也很方便。其中my-insert是自己写的一个简陋的elisp函数:

(defun my-insert (num1 num2 prefix)
(let ((@ num1))
(save-restriction
(while (< @ num2)
(insert (format prefix @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @))
(setq @ (1+ @))))))
elisp高手不要笑话我啊……不知道写成AUTO_TEMPLATE的那个样子需要怎么写……

总 结一下,用verilog-mode基本上只需要写真正需要的,而那些由于verilog的语法什么的规则导致的重复劳动都可以省下了。还有一个好处,自 动生成的这些C-c k就没有了,也就是说那1000行的代码就被缩减到100行,维护起来方便很多。还有一些快捷键,写module、always、case之类的只用写名 字、条件之类的就行了,像begin、end、endmodule、endcase、case之类的也都是自动生成的。

其实还漏了一些,比如/*AUTOWIRE*/,他会把例化模块的输出中,没有声明wire的自动声明;/*AUTORESET*/,自动把寄存器初始化写好;/*AUTOREG*/,如果输出中不应该是wire型,自己又没写reg,这个就自动生成了。

总之很推荐!不过vimer可能就不太爽了,Verilog-mode的网站上虽然有个解决方法,但是其实很不好用,原文是这样:

For those that use vi, or have a script generating code, it is useful to be able to expand the automatics from the shell. Batch invocation is done with the shell command:

emacs –batch filename.v -f verilog-auto -f save-buffer

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s