前几天遇到一个使用情景,需要从一个包含各个读取代码文件路径及名字的文件中把文件路径提取出来,做一个filelist,这里用到了文本的提取和替换,这里做个小总结记录一下。

从网上找了一个作者写的代码用来练习。

module asyn_fifo #(
//parameter declaration
parameter ADDR_WIDTH = 4 ,
parameter DATA_WIDTH = 16 ,
parameter ALMOST_FULL_GAP = 3 ,//将满,离满还有ALMOST_FULL_GAP时,almost_full有效
parameter ALMOST_EMPTY_GAP = 3 ,//将空,离空还有ALMOST_EMPTY_GAP时,almost_empty有效
parameter FIFO_DEEP = 16
)
(
//fifo write
wr_clk ,
wr_en ,
almost_full ,
full ,
wr_data ,
//fifo read
rd_clk ,
rd_en ,
almost_empty,
empty ,
rd_data ,
wr_reset ,
rd_reset
);
1)先思考写时钟方向,首先是写请求,在不满且写使能有效拉高写请求. assign wen = wr_en && (!full)
2)其次是写地址, always @(posedge wr_clk or negedge wr_reset)
if(!wr_reset)
waddr <= {(ADDR_WIDTH+1){1'b0}};
else if(wen)
waddr <= waddr + 1'b1;
else
waddr <= waddr;
3)将写地址转换为格雷码 always @(posedge wr_clk or negedge wr_reset)
if(!wr_reset)
waddr_gray <= {(ADDR_WIDTH + 1){1'b0}};
else
waddr_gray<= waddr^(waddr>>1);
4)将读格雷码转换到写时钟域,准备计算将满和满信号了 always @(posedge wr_clk or negedge wr_reset)
if(!wr_reset) begin
raddr_gray_sync <= {(ADDR_WIDTH+1){1'b0}};
raddr_gray_sync_d1 <= {(ADDR_WIDTH+1){1'b0}};
end
else begin
raddr_gray_sync <= raddr_gray;
raddr_gray_sync_d1 <= raddr_gray_sync;
end
5)将读格雷码转换为二进制(这样有利于将满信号和FIFO usdws(used words,使用了多少字)的计算) integer i;
always @(*)
begin
for(i=0;i<ADDR_WIDTH+1;i=i+1)
raddr_gray2bin = ^(raddr_gray_sync_d1>>i);
end
6)写地址与读地址间隔计算,写了多少个字了 always @(*)begin
if(raddr_gray2bin[ADDR_WIDTH] ^ waddr[ADDR_WIDTH])//二进制扩展位为循环指示位
wr_gap = raddr_gray2bin[ADDR_WIDTH-1:0] - waddr[ADDR_WIDTH-1:0];
else
wr_gap = FIFO_DEEP + raddr_gray2bin - waddr;
end
7)almost full信号产生 always @(posedge wr_clk or negedge wr_reset)begin
if(!wr_reset)
almost_full <= 1'b0;
else begin
if(wr_gap < ALMOST_FULL_GAP)
almost_full <= 1'b1;
else
almost_full <= 1'b0;
end
end
8)full信号产生 always @(posedge wr_clk or negedge wr_reset)begin
if(!wr_reset)
full <= 1'b0;
else
full <= (wr_gap==1)&&wen;
9)再来写读时钟方向,其实与写时钟方向堆成,首先是读请求, assign ren = rd_en &&(!empty);
10)FIFO读地址的产生 always @(posedge rd_clk or negedge rd_reset)
if(!rd_reset)
raddr <= {(ADDR_WIDTH+1){1'b0}};
else if(ren)
raddr <= raddr + 1'b1;
else
raddr <= raddr;
11)读地址转变为读格雷码 always @(posedge rd_clk or negedge rd_reset)
if(!rd_reset)
raddr_gray <= {(ADDR_WIDTH + 1){1'b0}};
else
raddr_gray <= raddr^(raddr>>1);
12)写地址同步到读时钟域 always @(posedge rd_clk or negedge rd_reset)begin
if(!rd_reset) begin
waddr_gray_sync <= {(ADDR_WIDTH+1){1'b0}};
waddr_gray_sync_d1 <= {(ADDR_WIDTH+1){1'b0}};
end
else begin
waddr_gray_sync <= waddr_gray;
waddr_gray_sync_d1 <= waddr_gray_sync;
end
end
13)写地址格雷码变成二进制,便于读格子的计算 integer j;
always @(*)begin
for(j=0;j<ADDR_WIDTH+1;j=j+1)
waddr_gray2bin = ^(waddr_gray_sync_d1>>i);
end
14)读格子的计算—即还有多少数据未读 always @(*)
rd_gap = waddr_gray2bin - raddr;
15)almost_empty信号产生 always @(posedge rd_clk or negedge rd_reset)begin
if(!rd_reset)
almost_empty <= 1'b1;
else begin
if(rd_gap < ALMOST_EMPTY_GAP)
almost_empty <= 1'b1;
else
almost_empty <= 1'b0;
end
end
16)产生empty信号 always @(posedge rd_clk or negedge rd_reset)begin
if(rd_reset)
empty <= 1'b1;//复位了FIFO为空
else
empty <= (rd_gap == 1) & rd_en;
end
17)例化双口RAM,在写请求有效时将数据存放到里面,并在读请求有效时读出数据。 ram ram_inst#(
parameter RAM_WIDTH = 4
)(
.wr_clk(wr_clk),
.addra(wr_addr),
.dina(wr_data),
.wra(wen),
///////
.rd_clk(rd_clk),
.addrb(rd_addr),
.dina(rd_data),
.rdb(ren)
);

练习1-将作者写的步骤文字,即x)开头的文字提取出来

使用v/pattern/d来实现,这个命令的意思是将匹配pattern的行提取出来,其中pattern就是你定义的匹配模式,如下图所示。其中^代表匹配行首,\d代表匹配一个数字,这样我们就完成了提取。那如果我想删除掉这些而只保留代码呢?

:v/^\d/d

我们使用g/pattern/d来实现,这个命令的意思是将匹配pattern的行删除而保留其他。

:g/^\d/d

以此类推,重点是会写pattern,这里有个作者已经总结的很好了,可以参考这个作者的总结,已经总结很全了。 https://blog.csdn.net/lazyclough/article/details/6193398

练习3-获取该模块的信号列表(先提取再替换)

第一步:

可以看出信号列表都是以,结尾,除了最后一个,所以可以先复制最后一个信号,然后使用如下命令开始提取。

:v/.*,/d

其中.*分别代表任意字符,任意多个,“,”就是匹配“,”,得到了如下代码。

第二步:

可以看到,还有些以“.”开头的和以“parameter”开头的我们不需要,所以可以使用如下命令去除(这个时候代码已经很少了其实可以用“ndd”删除n行,或者鼠标选中按“d”的方法来操作了,但这里是为了做练习,所以不用它们):

:g/^\s\s\./d

其中^匹配行首,\s\s匹配两个空格,也可以用\s{2},{2}代表匹配两次,.匹配“.”,然后代码如下。

然后输入命令

:g/parameter/d

得到如下代码

第三步:

然后我们需要将“,”全部去除,使用替换命令:range s/pattern/new string/command(其实这列逗号排列是整齐的,可以用列操作很方便的删除,但是我们为了练习)。

:%s/,//g

其中range的%代表全局匹配替换,也可以用行号来指定匹配替换的范围,g代表匹配到的全部替换,gc代表全部替换但是每次替换前要询问。得到的代码如下:



到这里基本就完成了,采用列操作或者上述办法去除掉开头的空格,再把之前复制的最后一个信号复制上去就完成任务。

vim技巧--提取文本与文本替换的更多相关文章

  1. vim技巧4 删除/保留文本中匹配行

    vim技巧:如何删除/保留文本中特定的行呢? <ol><a href="/ss/ss/www"> show invisibles</a> < ...

  2. 最佳vim技巧

    最佳vim技巧----------------------------------------# 信息来源----------------------------------------www.vim ...

  3. vim技巧:折叠快捷键

    vim技巧:折叠快捷键 以前用的挺熟的,一段时间不用了,快捷键又忘了,不得不重新再看手册,今天专门整理一下,以后查找起来也比较方便. zc 折叠,只折叠最外层的折叠zC 对所在范围内所有嵌套的折叠点进 ...

  4. Vim技巧之四大模式_普通模式

    Vim技巧之四大模式_普通模式 一见不钟情的普通模式 普通模式以下的强悍操作 什么是操作符 什么是动作命令 误操作怎么办 那种操作更划算 普通模式下的神奇大招 Vim技巧之四大模式_普通模式 众所周知 ...

  5. Vim技巧之四大模式_插入模式

    Vim技巧之四大模式_插入模式 在插入模式中及时更正错误 插入-普通模式 在插入模式模式以下直接粘贴指定寄存器的内容 插入模式中做运算 用字符编码插入很常使用字符 替换已有的文本 Vim技巧之四大模式 ...

  6. Shell基础(六):使用awk提取文本、awk处理条件、awk综合脚本应用、awk流程控制、awk扩展应用

    一.使用awk提取文本 目标: 本案例要求使用awk工具完成下列过滤任务: 1> 练习awk工具的基本用法    2> 提取本机的IP地址.根分区使用率    3> 格式化输出/et ...

  7. 如何使用免费PDF控件从PDF文档中提取文本和图片

             如何使用免费PDF控件从PDF文档中提取文本和图片 概要 现在手头的项目有一个需求是从PDF文档中提取文本和图片,我以前也使用过像iTextSharp, PDFBox 这些免费的PD ...

  8. Jsoup提取文本时保留标签

    使用Jsoup来对html进行处理比较方便,你可能会用它来提取文本或清理html标签.如果你想提取文本时保留标签,可以使用Jsoup.clean方法,参数为html及标签白名单: Jsoup.clea ...

  9. 用ABBYY提取文本和表格的方法

    在ABBYY FineReader 12 OCR文字识别软件中,有一个插件ABBYY Screenshot Reader,通常情况下与ABBYY FineReader 12一起安装到计算机中,它是一款 ...

  10. vimcommandfilepatchcmdfold VIM技巧之分隔窗口 一级精华

    VIM技巧之分隔窗口 分类: 技术2010-07-08 09:57 754人阅读 评论(1) 收藏 举报   同时显示两个不同的文件, 或者同时查看同一个文件的两个不同位置, 或者是同步显示两个文件的 ...

随机推荐

  1. 遥感图像处理笔记之【U-Net for Semantic Segmentation on Unbalanced Aerial Imagery】

    遥感图像处理学习(5) 前言 遥感系列第5篇.遥感图像处理方向的学习者可以参考或者复刻 本文初编辑于2023年12月15日 2024年1月24日搬运至本人博客园平台 文章标题:U-Net for Se ...

  2. uni-app接口请求封装

    首先根目录下新建文件夹取名随意,这里我取名common(意为:常见的.共有的) 然后新建request.js文件,贴入以下代码 let server_url = ''; //请求根路径(服务器地址) ...

  3. unordered_map模拟实现|STL源码剖析系列|开散列

    博主很久没有更新过STL源码剖析这个系列的文章了,主要是因为大部分STL常用的容器,博主都已经发过文章了,今天博主带着大家把哈希表也模拟实现一下. 前言 那么这里博主先安利一下一些干货满满的专栏啦! ...

  4. P10114 [LMXOI Round 1] Size 题解

    题目链接:[LMXOI Round 1] Size 挺有意思的诈骗题,其实这类题都喜欢批一个外壳,例如数据范围提示之类的.记得以前遇到的很多诈骗题,有一道 cf 的高分题,问的是区间出现次数的次数 \ ...

  5. 19.1 DLL基础--《Windows核心编程》

    Windows 中最重要的三个DLL是: Kernel32.dll:包含的函数用来管理内存.进程以及线程 User32.dll:包含的函数用来执行和用户界面相关的任务 GDI32.dll:包含的函数用 ...

  6. 《ASP.NET Core 与 RESTful API 开发实战》-- (第9章)-- 读书笔记(上)

    第 9 章 测试和文档 9.1 测试 测试是软件生命周期中的一个非常重要的阶段,对于保证软件的可靠性具有极其重要的意义 常见的测试方法有很多,根据不同的维度,可以把测试方法分为不同的类别 从观察结构的 ...

  7. SP9494 ZSUM - Just Add It 题解

    题目传送门 前置知识 快速幂 解法 推式子: \(\begin{aligned} Z_n+Z_{n-1}-2Z_{n-2}&=(Z_n-Z_{n-2})+(Z_{n-1}-Z_{n-2}) \ ...

  8. Linux进程通信 | 消息队列

    什么是消息队列? 假设你是一个快递员,你需要将货物从一个仓库运到另一个仓库.但是你发现自己的时间不够用,需要另外请一个人来帮忙.那么,你们之间如何进行协作呢? 一种方式是直接将货物全部交给对方,但这样 ...

  9. 用ELK分析每天4亿多条腾讯云MySQL审计日志(2)--EQL

    上一篇介绍了用ELK分析4亿多条审计日志过程,现在介绍如何用Python3分析ES的程序 需要分析的核心库审计数据: 1,950多张表,几十个账号, 2,5种操作类型(select,update,in ...

  10. Java操作EasyExcel实现导入导出入门

    介绍 EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单.节省内存著称.EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从 ...