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


    目录

    流水线设计思想

    全加器

    非流水线全加器设计

    Verilog设计

    testbench设计

    仿真波形

    RTL视图

    资源使用情况

    流水线加法器设计

    Verilog设计

    testbench设计

    仿真波形

    RTL视图

    资源使用情况

    总结


     

    流水线设计思想

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

    全加器

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

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

    27f894d4eb0d48dab6704c0b6221238e.png

    非流水线全加器设计

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

    Verilog设计

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /* Engineer : Linest-5
    3. /* File : add_no_pipeline.v
    4. /* Create : 2022-09-02 09:29:04
    5. /* Module Name : add_no_pipeline
    6. /* Description : 全加器非流水线设计
    7. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    8. module add_pipeline(
    9. input clk,
    10. input [7:0] a,
    11. input [7:0] b,
    12. input cin,
    13. output reg [7:0] sum,
    14. output reg cout
    15. );
    16. always @(posedge clk) begin
    17. {cout,sum} <= a + b + cin;
    18. end
    19. endmodule

    testbench设计

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /* Engineer : Linest-5
    3. /* File : tb_add_no_pipeline.v
    4. /* Create : 2022-09-02 09:34:46
    5. /* Module Name : tb_add_no_pipeline
    6. /* Description : 全加器非流水线设计仿真模块
    7. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    8. `timescale 1ns/1ps
    9. module tb_add_no_pipeline();
    10. reg clk;
    11. reg [7:0] a;
    12. reg [7:0] b;
    13. reg cin;
    14. wire [7:0] sum;
    15. wire cout;
    16. initial begin
    17. clk = 'd1;
    18. end
    19. always #10 clk = ~clk;
    20. always #20 a <= {$random}%256;
    21. always #20 b <= {$random}%256;
    22. always #20 cin <= {$random}%2;
    23. add_pipeline inst_add_pipeline (
    24. .clk(clk),
    25. .a(a),
    26. .b(b),
    27. .cin(cin),
    28. .sum(sum),
    29. .cout(cout)
    30. );
    31. endmodule

    仿真波形

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

    e184418c727744179240d632c18350a6.png

     

    RTL视图

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

    a9a8d4dff4df4767b5ba4184321758ee.png

    资源使用情况

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

    e4a1286ed3c04347ae6bfed8cb5971c2.png

     

    流水线加法器设计

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

    Verilog设计

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /* Engineer : Linest-5
    3. /* File : add_pipeline.v
    4. /* Create : 2022-09-02 09:25:18
    5. /* Module Name : add_pipeline
    6. /* Description : 全加器的流水线设计
    7. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    8. module add_pipeline(
    9. input clk,
    10. input [7:0] a,
    11. input [7:0] b,
    12. input cin,
    13. output reg [7:0] sum,
    14. output reg cout
    15. );
    16. reg [3:0] a_reg;
    17. reg [3:0] b_reg;
    18. reg [3:0] sum1;
    19. reg cout1;
    20. //计算低四位
    21. always @(posedge clk) begin
    22. {cout1,sum1} <= a[3:0] + b[3:0] + cin;
    23. a_reg <= a[7:4];
    24. b_reg <= b[7:4];
    25. end
    26. //计算高四位
    27. always @(posedge clk) begin
    28. {cout,sum[7:4]} <= a_reg + b_reg + cout1;
    29. sum[3:0] <= sum1;
    30. end
    31. endmodule

    testbench设计

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /* Engineer : Linest-5
    3. /* File : tb_add_pipeline.v
    4. /* Create : 2022-09-02 09:30:52
    5. /* Module Name : tb_add_pipeline
    6. /* Description : 全加器的流水线设计仿真模块
    7. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    8. `timescale 1ns/1ps
    9. module tb_add_pipeline();
    10. reg clk;
    11. reg [7:0] a;
    12. reg [7:0] b;
    13. reg cin;
    14. wire [7:0] sum;
    15. wire cout;
    16. initial begin
    17. clk = 'd1;
    18. end
    19. always #10 clk = ~clk;
    20. always #20 a <= {$random}%256;
    21. always #20 b <= {$random}%256;
    22. always #20 cin <= {$random}%2;
    23. add_pipeline inst_add_pipeline (
    24. .clk(clk),
    25. .a(a),
    26. .b(b),
    27. .cin(cin),
    28. .sum(sum),
    29. .cout(cout)
    30. );
    31. endmodule

    仿真波形

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

    1f909761d16742bea9dd54d804c012bf.png

     

    RTL视图

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

    a4e2788d5494456baa10abee1c5e0f6b.png

    资源使用情况

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

    51abe4f14c944080881d8da7a58a2dd5.png

     

    总结

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

     

  • 相关阅读:
    一次因没有找到iframe元素而怀疑selenium4是不是有问题?
    C++包含整数各位重组
    《大数据之路:阿里巴巴大数据实践》-第1篇 数据技术篇 -第2章 日志采集
    ES系列、Elasticsearch Suggester API(自动补全)
    Dubbo-Dubbo 动态配置中心
    关于EasyExcel的数据导入和单sheet和多sheet导出
    USB转多串口设备固定串口号
    C【整数正序分解】
    WebDAV之葫芦儿·派盘+咕咚云图
    配置spring boot actuator跟踪 http 请求
  • 原文地址:https://blog.csdn.net/m0_61298445/article/details/126683917