EP3是一个perl5的程序,它可以预处理STDIN或者输入文件,并产生一个输出文件。EP3是为了对verilog硬件描述语言进行灵活预处理而开发出来的。如果你需要预处理数组或类似高级数据结构,你应该直接用perl写脚本。
安装
标准的ep3在cpan上可以找到:https://metacpan.org/pod/Text::EP3
但是该版本不支持@for,要想使用该功能,需要下载这个版本:https://github.com/weiqi7777/ep3
该版本是卢骏开发,来源:http://www.lujun.org.cn/?p=4470
从github下载支持@for的ep3。
修改ep3-master/lib/Text/EP3.pm中2152行。因为我安装之后会报这个数组未初始化,可能是perl的版本不同的原因吧。
1
$self->{For_Exe} = ()
==>
1
$self->{For_Exe} = [()]
在ep3-master目录下执行如下命令,会将ep3安装到/home/fzheng/perl5目录下。
1
2
3perl Makefile.PL INSTALL_BASE=/home/fzheng/perl5
make
make install添加环境变量
1
2export PERL5LIB="/home/fzheng/perl5/lib/perl5:$PERL5LIB";
export PATH="/home/fzheng/perl5/bin:$PATH";
简单的小例子
命令的分隔符默认是“@”,这是为了避免和其他分隔符产生冲突,verilog中有使用$, &等。你也可以在命令行通过参数修改该分隔符。
EP3会对每行进行解析,遇到命令分隔符,则调用相应的函数。
先创建一个src文件,里面有@for命令
1 | % gvim src |
1 | @for i=0 to 1 |
然后调用ep3进行处理
1 | % ep3 src |
在STDOUT得到输出结果
1 | hello world 0 |
可以看到,EP3进行了一个循环,得到了2行代码。这在处理verilog/system verilog代码时非常有用。
EP3 option
[-no]protect
默认是protect,表示注释代码中的宏不会被替换。
noprotect,表示注释代码中的宏会被替换。
例:
src:
1 | @define VAR 100 |
执行如下命令:
1 | % ep3 src |
输出是:
1 | // @VAR |
而执行如下命令:
1 | % ep3 src -noprotect |
输出是:
1 | // 100 |
[-no]comment
默认是comment,表示注释也会输出
nocomment,注释不会输出
例:
src:
1 | // this is comment |
执行如下命令:
1 | % ep3 src |
输出是:
1 | //this is comment |
而执行如下命令:
1 | % ep3 src –nocomment |
输出是:
1 | this is content |
-delimeter string
默认是@,可以修改命令的分隔符。
例:
src:
1 | #for i=0 to 1 |
命令:
1 | % ep3 src –delimeter |
输出是:
1 | test |
-define string1=string2
宏定义,和一般语言一样,不举例了。
-include directory
头文件查找目录,和一般语言一样,不举例了。
-output_filename
输出文件名,默认是STDOUT
-module filename
加载module,需要在@INC里找到module.pm。没试过。
-line_comment string
单行注释标识,默认是//
-start_comment string
多行注释起始标识,默认是/*
-end_comment string
多行注释结束标识,默认是*/
例:
src:
1 | ## this is one line comment |
命令:
1 | % ep3 src –line_comment ## -nocomment –start_comment “#*” –end_comment “*#” |
输出是:
1 | this is content |
文本嵌入命令
@define key definition
宏定义,key是一个单独的word,definition可以包含任意字符(甚至空白字符)直到本行结束。
@replace key definition
和define几乎完全一样,除了,key在任何位置都可以被替换,不光是word边界。
@macro key(value[,value]*) definition
和上面两个类似,不同的是,可以支持参数传递。
例:
src:
1 | @define DEF hello |
命令:
1 | %ep3 src |
输出是:
1 | this is hello |
这里发现macro的输出多了个@,也许是个bug。
@eval key expr
支持一个有效的perl表达式
例:
src:
1 | @eval EVAL 1.2+2.3 |
命令:
1 | % ep3 src |
输出是
1 | this is 3.5 |
@include < file> or “file” [condition]
该命令包含文件,“file”在当前目录查找,< file>在所有的include path查找。
还支持使用@mark condition_BEGIN和@mark condition_END指定包含部分内容。
例:
inc:
1 | 1 stuff before |
src:
1 | @include “inc” |
命令:
1 | %ep3 src |
输出:
1 | 2 stuff middle |
@enum a,b,c,d…
枚举类型,abcd会被替换成数字,默认从0开始。如果其中有一个是数字,后面的会从这个数字开始。
例:
src:
1 | @enum a,b,c,d,6,e,f |
命令:
1 | %ep3 src |
输出是
1 | this is 0 1 2 3 6 7 |
@ifdef @ifndef key
条件编译,包括define和replace定义的。
例:
1 | @define DA 1 |
输出是
1 | this is DA |
@if expr
@[elif|elsif] key | expr
@else
@endif
这些和大部分语言类似,不举例了。
@for iter = expr0 to expr1 [delta expr2]
@endfor
循环输出中间的字符,并支持修改步距。
例:
1 | @for k=45.2 to 31.1 delta -3.1 |
输出是
1 | (45.2, 1) |
@comment on|off|default|previous
on:开
off:关
default:修改为命令行的配置
previous:修改为上次的配置
例:
1 | @comment off |
输出是
1 | // comment 2 |
@protect on|off|default|previous
设置protect配置
@ep3 on|off
设置ep3开关
例:
1 | @ep3 off |
输出是
1 | @if 1 |
@perl_begin和@perl_end
@perl_begin和@perl_end支持内嵌脚本,它们之间的code会被当作perl代码来执行,并且可以在普通文本中调用。
1 | @perl_begin |
输出是:
1 | To be sure, x=3.14 and y=6, where x+y=9.14 |
@debug on|off|value
增加debug信息到输出文件。每bit代表一个含义,可以只开相应bit
0x01 1 - primary message
0x02 2 - ep3_process engine
0x04 4 - define(replace, macro, eval, enum)
0x08 8 - include
0x10 16 - if(else, ifdef, etc.)
0x20 32 - perl_begin/end
扩展
EP3是个perl程序,一般放在perl的bin目录下,要直接调用到ep3,需要设好perl的环境变量
bin/ep3也只是例化了下Text::EP3而已,真正的代码在lib/site_perl/5.12.5/Text/EP3.pm里面。
如果我就想输出@for i=0 to 2这行怎么办?
可以用1
@ep3 off
也可以用1
2
3@perl_begin
@> \@for i=0 to 2
@perl_end