110 lines
3.6 KiB
Markdown
110 lines
3.6 KiB
Markdown
@[TOC](verilog-mode中的AUTO_TEMPLATE)
|
||
对于Verilog-mode中的模块例化,在使用AUTOINST机制时,一般都不是单独使用的,因为它默认是端口名和连接的名字都是一样的;
|
||
但是我们基本是有所改动的,所以需要使用AUTO_TEMPLATE来进行基于正则表达式的替换;
|
||
|
||
# AUTO_TEMPLATE
|
||
## 正则表达式匹配
|
||
### $.*$(即\(.*\))--需要进行转义一下
|
||
被$xx$包裹的部分会被记录,后续通过\1,\2来引用;
|
||
```
|
||
自动连接未明确列出的端口,保留原始名称。
|
||
示例:
|
||
若模板为 .$.*$ (\1[]),则:
|
||
|
||
端口 .data_in → 生成 .data_in(data_in[])
|
||
端口 .enable → 生成 .enable(enable[])
|
||
```
|
||
|
||
Demo:
|
||
/* mcu_crg AUTO_TEMPLATE (
|
||
.i_scan_mode (1'b0),
|
||
.i_scan_rst_n (1'b1),
|
||
.o_\(.*\) (\1[]), //这样是方便是捕获得到的 \1
|
||
);*/
|
||
|
||
```
|
||
|
||
### \1
|
||
尽量便面硬编码,自动匹配;
|
||
在正则表达式 $ $ 中,\1 表示引用 第一个捕获组 匹配到的内容,\2 表示第二个捕获组,以此类推;
|
||
| 输入字符串 | 正则$.*$ | 捕获组\1内容 |
|
||
|-----------|---------|------------ |
|
||
| “data_in” | $.*$ | data_in |
|
||
| "addr_bus" | $.*$_bus | addr |
|
||
|"ctrl[3]" | $.*$$$.*$$ | ctrl |
|
||
|
||
Demo:
|
||
```verilog
|
||
/* xxx AUTO_TEMPLATE (
|
||
.hclk (mcu_mtrx_clk),
|
||
.hresetn (mcu_mtrx_rst_n),
|
||
.hgrant (1'b1),
|
||
.hbusreq (),
|
||
.hlock (),
|
||
.hresp1 ({1'b0,hresp_ahb_m5}),
|
||
.hresp2 ({1'b0,hresp_ahb_m6}),
|
||
.$h.*$1 (\1_ahb_m5[]),
|
||
.$h.*$2 (\1_ahb_m6[]),
|
||
.hsel (hselx_ahb_s7),
|
||
.hready_resp (hreadyout_ahb_s7),
|
||
.$h.*$ (\1_ahb_s7[]),
|
||
.debug_.* (),
|
||
.int_.* (),
|
||
); */
|
||
|
||
```
|
||
**.debug_.* () 和 .int_.* () 的作用就是明确不连接所有调试和中断信号**。这是Verilog-mode中处理未使用端口的标准化做法,既避免冗余代码,又保证工具链解析的清晰性。
|
||
* 正则捕获组:
|
||
$h.*$:匹配以 h 开头的信号名(如 haddr),通过 \1 动态引用。
|
||
示例:.$h.*$1 (\1_ahb_m5[]) → 若匹配 haddr1,则生成 .haddr1(haddr_ahb_m5[])
|
||
|
||
* 空连接与常量
|
||
hgrant (1'b1):直接绑定常量高电平。
|
||
hbusreq ():悬空不连接。
|
||
|
||
* 通配符忽略
|
||
debug_.* ():忽略所有 debug_ 开头的信号。
|
||
int_.* ():忽略所有 int_ 开头的信号。
|
||
|
||
|
||
### [0-9]
|
||
|
||
```verilog
|
||
.gather_info_$[0-9]+$ (gather_node_y_\1_info[]),
|
||
.gather_intr_mask_$[0-9]+$ (gather_node_y_\1_intr_mask[]),
|
||
```
|
||
进行映射连接
|
||
|
||
### 输入接0,输出悬空
|
||
```verilog
|
||
.noc_ndma_r1_* (*if (equal vl-dir "input") "'0\"" "\"")")
|
||
```
|
||
匹配目标: 所有以 .noc_ndma_r1_ 开头的端口(如 .noc_ndma_r1_data、.noc_ndma_r1_en)。
|
||
条件逻辑: 如果端口方向是 input,则将其连接为 **常量 '0**(即接地)。否则(output 或 inout),悬空不连接("")。
|
||
```verilog
|
||
/* 提取信号名前缀并复用 */
|
||
.$.*$_req (\1_ack[]) // 将 "mem_req" 映射为 ".mem_req(mem_ack[])"
|
||
```
|
||
|
||
```verilog
|
||
.spi_\(.*\) ( @"(if(equal vl-dir \\"input\\") \\"xxx_spi_s_\1[]\\" \\"xxx_spi_s_\1[]\\" )" )
|
||
```
|
||
匹配规则:当是input端口时候,匹配什么;当是output端口时候,匹配什么;
|
||
|
||
|
||
## AUTO_TEMPLATE 联合AUTOINST使用
|
||
记住AUTO_TEMPLATE只是基于正则表达式的字符替换,一定是要出发AUTOINST才能进行例化模块使用;
|
||
给出示例模板:
|
||
```verilog
|
||
//==S1
|
||
/* moduleNmae AUTO_TEMPLATE "u_moduleName"(
|
||
//==表达式规则
|
||
); */
|
||
|
||
//==S2
|
||
moduleNmae u_moduleName (/*AUTOINST*/);
|
||
|
||
//==S3
|
||
按键"\a" 看看有无报错;
|
||
|
||
``` |