前几天遇到一个使用情景,需要从一个包含各个读取代码文件路径及名字的文件中把文件路径提取出来,做一个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. errgroup的常见误用

    errgroup想必稍有经验的golang程序员都应该听说过,实际项目中用过的也应该不在少数.它和sync.WaitGroup类似,都可以发起执行并等待一组协程直到所有协程运行结束.除此之外errgr ...

  2. 机器学习算法(四): 基于支持向量机的分类预测(SVM)

    机器学习算法(四): 基于支持向量机的分类预测 本项目链接:https://www.heywhale.com/home/column/64141d6b1c8c8b518ba97dcc 1.相关流程 支 ...

  3. 8.1 TEB与PEB概述

    在开始使用TEB/PEB获取进程或线程ID之前,我想有必要解释一下这两个名词,PEB指的是进程环境块(Process Environment Block),用于存储进程状态信息和进程所需的各种数据.每 ...

  4. 驱动开发:运用VAD隐藏R3内存思路

    在进程的_EPROCESS中有一个_RTL_AVL_TREE类型的VadRoot成员,它是一个存放进程内存块的二叉树结构,如果我们找到了这个二叉树中我们想要隐藏的内存,直接将这个内存在二叉树中抹去,其 ...

  5. Web服务器实现|基于阻塞队列线程池的Http服务器|线程控制|Http协议

    基于阻塞队列生产者消费者模型线程池的多线程Web服务器 代码地址:WebServer_GitHub_Addr README 摘要 本实验通过C++语言,实现了一个基于阻塞队列线程池的多线程Web服务器 ...

  6. CF678F Lena and Queries题解

    题目链接:CF 或者 洛谷 可以看到查询和插入就是李超线段树的基本操作,但在原有基础上多了一个删除操作,李超线段树不支持删除操作,但支持可撤销和可持久化,所以我们容易想到外层再套一个线段树分治即可.本 ...

  7. 零基础入门学习Java课堂笔记 ——day02

    流程控制 1.Scanner对象 来源:java.util.Scanner 我们可以通过Scanner类来获取用户的输入输出 用户交互Scanner 通过new关键词创建Scanner对象 Scann ...

  8. Acwing 800.数组元素的目标和,双指针初步

    Acwing 800.数组元素的目标和 给定升序的有序数组A(长度为n),B(长度为m)以及目标值x,求出满足\(A[i] + B[j] = x\)的数对\((i,j)\),题目保证仅有 唯一解 输入 ...

  9. SOCKS5协议解析

    socks的官方文档:https://www.ietf.org/rfc/rfc1928.txt 本文改变其他作者之手,在原文基础上加入客户端的编写,完善了服务端代码,原文是Linux端的程序代码,本文 ...

  10. Go语言核心36讲(Go语言实战与应用十)--学习笔记

    32 | context.Context类型 我们在上篇文章中讲到了sync.WaitGroup类型:一个可以帮我们实现一对多 goroutine 协作流程的同步工具. 在使用WaitGroup值的时 ...