当前位置: 首页 > news >正文

【Verilog 流水线设计】以全加器为例阐述流水线设计的影响

写在前面

这个系列主要分享常见的 Verilog 设计,同时在牛客网上刷题也分在此系列分享,牛客网上有秋招相关企业真题,可以通过刷题巩固基础,记录自己的学习历程~

附上牛客网直达链接 

☞牛客网刷题直达链接


目录

流水线设计思想

全加器

非流水线全加器设计

Verilog设计

testbench设计

仿真波形

RTL视图

资源使用情况

流水线加法器设计

Verilog设计

testbench设计

仿真波形

RTL视图

资源使用情况

总结


流水线设计思想

关于流水线对于FPGA设计中的作用,既有利也有弊,优点是能够优化时序从而提高系统运行的最大频率,缺点是增加延时,因为流水线的设计思想就是在计算过程中插入寄存器,从而增加了延时,下面就以一个八位全加器的例子去验证以上的论述。

全加器

全加器英语名称为full-adder,是用门电路实现两个二进制数相加并求出和的组合线路,称为一位全加器。一位全加器可以处理低位进位,并输出本位加法进位。多个一位全加器进行级联可以得到多位全加器。

以下为全加器的真值表,可以看到其实和普通的加法没什么差别,就多了一个进位数,直接累加上就行。

非流水线全加器设计

不使用流水线的话,就比较简单粗暴,直接两个加数和进位一同相加得到最终的加法结果和进位值。

Verilog设计

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 

/* Engineer    : Linest-5                                                        
/* File        : add_no_pipeline.v                                                         
/* Create      : 2022-09-02 09:29:04
                                           
/* Module Name : add_no_pipeline                                                  
/* Description : 全加器非流水线设计                                                                         
                                                                              

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module add_pipeline(
    input             clk,
    input [7:0]       a,
    input [7:0]       b,
    input             cin,
    output reg [7:0]  sum,
    output reg        cout
);


always @(posedge clk) begin
    {cout,sum} <= a + b + cin;
end

endmodule 

testbench设计

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 

/* Engineer    : Linest-5                                                         
/* File        : tb_add_no_pipeline.v                                                         
/* Create      : 2022-09-02 09:34:46
                                                 
/* Module Name : tb_add_no_pipeline                                                  
/* Description : 全加器非流水线设计仿真模块                                                                                                                  
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

`timescale 1ns/1ps
module tb_add_no_pipeline();

reg           clk;
reg  [7:0]    a;
reg  [7:0]    b;
reg           cin;
wire [7:0]    sum;
wire          cout;

initial begin
clk = 'd1;
end

always #10 clk = ~clk;
always #20 a   <= {$random}%256;
always #20 b   <= {$random}%256;
always #20 cin <= {$random}%2;

add_pipeline inst_add_pipeline (
.clk(clk), 
.a(a), 
.b(b), 
.cin(cin), 
.sum(sum), 
.cout(cout)
);

endmodule

仿真波形

可以很清晰的看到,加数为237和140,相加为377,这超过了8位最大值,因此需要进一位,最终加法结果为sum = 377-255 = 122,进位cout = 1,并且只使用了一拍时钟周期就得到了结果。

RTL视图

从RTL图中可以看到结构很简单,两个加法器并对输出结果打一拍即可。

资源使用情况

可以看到LUT使用了8个,触发器使用了9个。

流水线加法器设计

这里使用一级流水设计方法,即将a、b 8位加法拆分开计算,分别计算a、b 的低四位和高四位,将最终的结果拼接在一起即得到最终的计算结果。

Verilog设计

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 

/* Engineer    : Linest-5                                                         
/* File        : add_pipeline.v                                                         
/* Create      : 2022-09-02 09:25:18
                                               
/* Module Name : add_pipeline                                                  
/* Description : 全加器的流水线设计                                                                         

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

module add_pipeline(
    input             clk,
    input [7:0]       a,
    input [7:0]       b,
    input             cin,
    output reg [7:0]  sum,
    output reg        cout
);
reg  [3:0]        a_reg;
reg  [3:0]        b_reg;
reg  [3:0]        sum1;
reg               cout1;

//计算低四位
always @(posedge clk) begin
    {cout1,sum1} <= a[3:0] + b[3:0] + cin;
    a_reg        <= a[7:4];
    b_reg        <= b[7:4];
end

//计算高四位
always @(posedge clk) begin
    {cout,sum[7:4]}  <= a_reg + b_reg + cout1;
    sum[3:0]         <= sum1;
    
end

endmodule 

testbench设计

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ 

/* Engineer    : Linest-5                                                         
/* File        : tb_add_pipeline.v                                                         
/* Create      : 2022-09-02 09:30:52
                                                
/* Module Name : tb_add_pipeline                                                  
/* Description : 全加器的流水线设计仿真模块                                                                         

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

`timescale 1ns/1ps
module tb_add_pipeline();

reg           clk;
reg  [7:0]    a;
reg  [7:0]    b;
reg           cin;
wire [7:0]    sum;
wire          cout;

initial begin
clk = 'd1;
end

always #10 clk = ~clk;
always #20 a   <= {$random}%256;
always #20 b   <= {$random}%256;
always #20 cin <= {$random}%2;


add_pipeline inst_add_pipeline (
.clk(clk), 
.a(a), 
.b(b), 
.cin(cin), 
.sum(sum), 
.cout(cout)
);

endmodule

仿真波形

可以看到和非流水线设计的仿真图形不同的是,加法结果需两个时钟周期才能出结果,结果也是正确的,这与前面说的一致。

RTL视图

从RTL图可以看到,相比较非流水线的RTL图,流水线设计的全加器使用的资源明显更多,在计算链上插入了红框中的寄存器,这样可以一定程度上优化时序并提高系统的最大工作频率值。

资源使用情况

与非流水线设计的相比,LUT同样使用了8个,但是触发器个数却是其2倍多,这就是流水线设计的弊端,尤其是大位宽的计算,更是资源消耗成倍的增加,这就是有得必有失。

总结

流水线设计在FPGA中应用得很广泛,至于什么时候选择使用流水线设计:当资源充足的情况下,需要提高系统运行速率,这时就可以使用流水线的设计,这是用资源换速率的案例,当然使用的流水线的部分计算延时也会增加,但能提高整体系统的运行速率,这点延迟可以忽略不计。

相关文章:

  • spring boot 使用Mybatis-plus的查询方法
  • nginx中root和alias的区别
  • pytorch深度学习训练模板
  • 【Qt+FFMPEG】 - 封装 解码音视频 线程
  • Arduino框架下最便宜的开发芯片-CH552初探
  • Java高并发编程实战5,异步注解@Async自定义线程池
  • 前端进阶——ES6
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • 【Python+大数据】第一天:安装VMware及Centos,配置虚拟机网络,学习Linux命令。研究生开学10天的感受。
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • JAVA代码操作HDFS
  • web前端开发基础教程一
  • 原子尺度仿真对材料设计效率的提升,是未来材料研发的关键核心竞争力
  • CDH 10Cloudera Manager Kerberos安装配置CA配置(markdown新版三)
  • RedHat7无法安装Telnet
  • 345-反转字符串中的元音字母
  • Kibana配置logstash,报表一体化
  • Linux Process Manage
  • maven工程打包jar以及java jar命令的classpath使用
  • React as a UI Runtime(五、列表)
  • RxJS: 简单入门
  • 初识 webpack
  • 后端_MYSQL
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • kubernetes资源对象--ingress
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 湖北分布式智能数据采集方法有哪些?
  • 进程与线程(三)——进程/线程间通信
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • #Linux(权限管理)
  • (+4)2.2UML建模图
  • (Java)【深基9.例1】选举学生会
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Matlab)使用竞争神经网络实现数据聚类
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (五)Python 垃圾回收机制
  • /etc/fstab 只读无法修改的解决办法
  • /proc/interrupts 和 /proc/stat 查看中断的情况
  • @Autowired多个相同类型bean装配问题
  • @javax.ws.rs Webservice注解
  • [ 蓝桥杯Web真题 ]-Markdown 文档解析
  • [autojs]autojs开关按钮的简单使用
  • [BZOJ2208][Jsoi2010]连通数
  • [C++]二叉搜索树
  • [C++核心编程](四):类和对象——封装
  • [CF407E]k-d-sequence
  • [codevs 1296] 营业额统计
  • [DevEpxress]GridControl 显示Gif动画
  • [element-ui] el-dialog 中的内容没有预先加载,因此无法获得内部元素的ref 的解决方案
  • [iOS]随机生成UUID通用唯一识别码
  • [Latex学习笔记]数学公式基本命令
  • [LeetCode] Copy List with Random Pointer 拷贝带有随机指针的链表
  • [LeetCode] Max Points on a Line