verilog中关于并行处理的心得
第一次写博客,只为分享。还望各位看官不吝赐教。
作为初学者,对硬件语言的并行和顺行处理搞不清楚,我也为此也费了不少功夫,解释起来也很简单,并行就是同时进行,顺行就是顺序进行,可是真要用起来,不花点功夫是不会用的。
先看个简单的,网上别人举得例子,相信大家一分钟就能看懂;
这是最简单的赋值语句,能看懂,说明你了解并行的概念,下面我们深入一点。
废话不说直接上干货
先看一小段代码
module bingxing(clock,rst,a,b,c,d,e);
input clock,rst;
output a,b,c,d,e;
reg a,b,c,d,e;
always@(posedge clock)
begin
if(rst==1)
a<=0;
else
begin
a=~a;
b=~a;
c=~b;
end
end
always@(posedge clock)
begin
d=~c;
end
always@(posedge clock)
begin
e=~d;
end
endmodule
这段代码非常简单,输入时钟信号clock和复位信号rst,输出a,b,c,d,e。 复位时,使a=0;当clock上升沿到来时执行取反操作,a对自己取反,对a取反的结果赋值给b,对b取反的结果赋值给c,对c取反的结果赋值给d,对d取反的结果赋值给e。但不同的是,程序分为三个块(三个always),每个块之间都是并行处理,第一个块中的三条取反操作时顺序处理。那么问题来了,如果a,b,c,d,e的初值均为0,当第一个clock上升沿到来时,输出分别是多少,第二个clock上升沿到来时,又是多少,直到第n个。
这个时候有的同学不淡定了,开始拿出笔算了,如果你的计算结果a,b,c,d,e依次是:第1个clock上升沿输出是10101,第二个是01010,第三个..........,原因很简单,依次取反嘛,我只能告诉你,你算错了。
看看我的仿真结果吧是,如下图:
第一个时钟周期内先给了一个复位信号,想让a的初值是0(其实后来我才发现,这一步完全没有必要,从图可看出所有的变量初值系统默认是0)。在一个时钟周期内由于复位信号的存在,a,b,c就不用看了,d和e同时反转,并且朝同一方向,都变成了1,而不是像我们yy的那样一个1一个0(因为我们始终认为e是d的反转,所以两个变量应该始终保持一个1一个0的状态),我们yy的不对,是因为没有搞明白并行的深刻含义。我们都知道两个always块之间是并行关系,所以e的反转和d的反转是同时发生的,也就是并行发生,d的取反的对象是此时刻之前的c的值,而e的取反的对象是此时刻之前的d的值,注意!!!重要的话说三遍,e的取反的对象是此时刻之前的d的值,e的取反的对象是此时刻之前的d的值,e的取反的对象是此时刻之前的d的值!!!也就是说并行处理的对象的值都是此时刻之前的值,c在此时刻之前是0,所以d取反后是1;d在此时刻之前是0,所以e取反后的值是1。。。
第二个上升沿到来后,d和c又同时为1(我为什么想到了拼刺刀)了,并没有因为d=~c而使c和d一个0一个1(好和谐啊,有守门的有射门的)。而a,,b,c从第二个周期开始时钟保持101或者010的造型,是因为a=~a;b=~a;c=~b;这三条语句是顺序处理的,因为这个缘故不管程序怎么改,a和b始终互反,b和c一样。
累死我了,如果还没懂,请看下图,这是上面代码的RTL图
看到这么多框框和线线,别害怕,五个框框分别是对a,b,c,d,e取反,为了简化问题,我们只看d~reg0和e~reg0两个框框,这两个框框分别代表d=~c和e=~d这两个并行语句,每个并行的块或者语句对应到实际电路中都是一个器件,每个器件的工作状态是独立的,它的输出只和它的输入有关,它和其他器件之间的唯一关系就是:我的输出正好是你的输入或者我的出入正好是你的输出。正是因为每个器件都独立的工作,所以他们可以在同一时刻做自己的工作,因此是并行的。看看上图,假设他们都是上升沿触发(实际也是),当clock的上升沿来临时,每个器件都在做自己的工作,他们的输入是上升沿来临时输入变量对应的寄存器中的值,也就是上个上升沿结束后寄存器个更新值。
说一千到一万,顺行就是流水线,前面的工序没完,后面没法干。并行就是多条流水线,大家各干各,不影响。
verilog中关于并行处理的心得相关推荐
- verilog中define、parameter、localparam的区别
Verilog代码可移植性设计 1. 参数定义 localparam,实例代码如下: module tm1( clk,rst_n, pout ); input clk; input rst ...
- verilog中数组的定义_开源仿真工具Icarus Verilog中的verilog parser
前面提到用flex和bison开处理命令行参数,回顾一下:开源仿真工具Icarus Verilog中的命令行参数处理方法. 那么Verilog的parser又是怎么实现的呢?简单地说,与做命令行参数的 ...
- FPGA的设计艺术(18)如何使用Verilog中的数组对存储器进行建模?
前言 Verilog中的二维数组很有用,可以使用for以及generate for配合二维数组进行使用,可以代替大量寄存器的场合,其实大量同类寄存器可以使用存储器进行代替,Verilog中可以使用二维 ...
- Verilog初级教程(21)Verilog中的延迟控制语句
文章目录 前言 正文 延迟控制语句 事件控制语句 Named Events Event or operator 往期回顾 参考资料及推荐关注 前言 Verilog中的延迟控制有两种类型–延迟和事件表达 ...
- Verilog初级教程(20)Verilog中的`ifdef 条件编译语句
文章目录 前言 正文 语法 示例 Testbench文件 往期回顾 参考资料及推荐关注 前言 `ifdef条件编译语句在逻辑设计中还是很常见的,但也常见一些滥用的情况,这应该避免. 应该在什么情况下使 ...
- Verilog初级教程(15)Verilog中的阻塞与非阻塞语句
文章目录 前言 正文 阻塞赋值 非阻塞赋值 往期回顾 参考资料以及推荐关注 前言 本文通过仿真的方式,形象的说明阻塞赋值以及非阻塞赋值的区别,希望和其他教程相辅相成,共同辅助理解. 正文 阻塞赋值 阻 ...
- Verilog初级教程(14)Verilog中的赋值语句
文章目录 前言 正文 合理的左值 过程性赋值(Procedural assignment) 连续赋值 过程连续性赋值 往期回顾 前言 何为赋值语句?即将值放到线网或者变量上,这种操作称为赋值,英文:a ...
- Verilog初级教程(12)Verilog中的generate块
文章目录 前言 正文 generate for generate if generate case 参考资料 本系列博文 前言 verilog中的generate块可以称为生成块,所谓生成,可以理解为 ...
- Verilog初级教程(11)Verilog中的initial块
文章目录 前言 正文 语法格式 initial块是用来干什么的? initial块何时开始又何时结束? 一个模块中允许有多少个initial块? 参考资料 写在最后 前言 仿真中通常会依次执行一组Ve ...
最新文章
- 学习练习SQL的数据库employee文件
- 「走过」微软、优步,老工程师告诉你哪些数据结构和算法最重要
- python打印小数
- 【实习】今日头条【抖音火山】后台开发实习生
- 推荐一款最好的服务器备份软件
- [云炬创业学笔记]第二章决定成为创业者测试5
- [转]Error: SQL BPA command line has encountered a problem and needs to close
- Visual Studio 2017 15.3 已发布,增加.NET Core 2 支持
- 诺基亚宣布与博通合作开发5G芯片 包括定制处理器
- Java编写编译native方法
- python无法显示饼图
- 戳这里,誉天胡老师教你如何备考 HCIE-Datacom!考试通关so easy!
- linux安装源文件出现错误,编译安装源码时出现错误的解决方法
- CF1111C Creative Snap
- pandas自动化实战小任务1--对excel表格分 供应商 付款年月 进行汇总(涉及根据即有相同也有不同的index的表格合并)公司的数据
- 木棍游戏(深搜 模板
- 【Zeekr_Tech】整车OTA概述
- 【MATLAB】读取和写入文本文件
- Github上开源项目readme里好看的高大上的有趣的徽章从何而来
- 用计算机怎么计算表格的平均数,excel工作表如何快速计算平均值的标准偏差?...