目錄
- 題目:
- 時序分析:時鐘頻率為50MHz
- 數據1: a=10, b=20, c=30, d=40, e=2
- 數據2: a=5, b=15, c=25, d=35, e=3
- 數據3: a=8, b=12, c=16, d=24, e=4
- 流水線效率分析
題目:
??????verilog中,y=(a+b+c+d)*e,時鐘頻率為50Mhz,用流水線的形式表示,并說明運算完需要多少ns?
圖片幫助理解:T1-T4只能做1輛車,但是T4后,每個時鐘周期就能做一輛車(如果沒有流水線,就每做1輛車都需要4個T的時間)
??????在Verilog中,將表達式 y=(a+b+c+d)*e 用流水線形式實現,可以分為多個階段,每個階段對應一個時鐘周期。
??????流水線設計可以提高電路的吞吐量,但會增加延遲(latency)。下面是具體實現及時序分析。
流水線實現:
??????將該表達式分為3個流水線階段:
- 第一階段:計算 a+b 和 c+d
- 第二階段:計算 (a+b)+(c+d)
- 第三階段:計算 ((a+b)+(c+d))*e
代碼實現:
module pipeline_mult (input wire clk, // 時鐘信號,50MHzinput wire rst_n, // 復位信號,低電平有效input wire [7:0] a, // 假設都是8位輸入input wire [7:0] b,input wire [7:0] c, input wire [7:0] d,input wire [7:0] e,output reg [15:0] y // 輸出可能需要更寬的位寬
);// 第一級流水線寄存器reg [8:0] sum_ab; // a+b的結果,需要多一位防止溢出reg [8:0] sum_cd; // c+d的結果reg [7:0] e_reg1; // 保存e的值傳遞到下一級// 第二級流水線寄存器reg [9:0] sum_abcd; // (a+b)+(c+d)的結果reg [7:0] e_reg2; // 保存e的值傳遞到下一級// 第一級流水線always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsum_ab <= 9'b0;sum_cd <= 9'b0;e_reg1 <= 8'b0;end else beginsum_ab <= a + b;sum_cd <= c + d;e_reg1 <= e; // 將e傳遞到下一級endend// 第二級流水線always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsum_abcd <= 10'b0;e_reg2 <= 8'b0;end else beginsum_abcd <= sum_ab + sum_cd;e_reg2 <= e_reg1; // 將e傳遞到下一級endend// 第三級流水線 - 最終結果always @(posedge clk or negedge rst_n) beginif (!rst_n) beginy <= 16'b0;end else beginy <= sum_abcd * e_reg2; // 最終的乘法計算endendendmodule
時序分析:時鐘頻率為50MHz
意味著時鐘周期為:
??????T = 1/f = 1/(50*10^6) = 20 ns
在這個流水線設計中:
??????第一個輸入需要經過3個時鐘周期(3級流水線)才能產生有效輸出;單次計算的延遲(latency)為:3 * 20 ns = 60 ns ;但一旦流水線填滿,之后每個時鐘周期都會產生一個新的結果(吞吐量為每20ns一個結果) 。因此,對于單個計算實例,從輸入到計算完成需要60 ns的時間。但是流水線的優勢在于可以同時處理多個計算實例,每20 ns就能輸出一個結果。
給小白,解釋一下這個疑問:
Clock : |ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|ˉ|_|
Time (ns) : 0 20 40 60 80 100 120 140 160 180 200 220輸入數據:
a : |10 | 5| 8| | | | | | | | | | | | |
b : |20 | 15| 12| | | | | | | | | | | | |
c : |30 | 25| 16| | | | | | | | | | | | |
d : |40 | 35| 24| | | | | | | | | | | | |
e : | 2 | 3| 4| | | | | | | | | | | | |第一級流水線:
sum_ab : | | 30| 20| 20| | | | | | | | | | | |
sum_cd : | | 70| 60| 40| | | | | | | | | | | |
e_reg1 : | | 2| 3| 4| | | | | | | | | | | |第二級流水線:
sum_abcd : | | |100| 80| 60| | | | | | | | | | |
e_reg2 : | | | 2| 3| 4| | | | | | | | | | |輸出結果:
y : | | | |200|240|240| | | | | | | | | |↑ ↑ ↑數據1 數據2 數據3
看完這2個圖,你應該大致明白了,不明白的話,繼續看下面這個分析:
詳細時序分析:
數據1: a=10, b=20, c=30, d=40, e=2
- 時鐘周期1 (0-20ns):
- 輸入數據: a=10, b=20, c=30, d=40, e=2
- 寄存器尚未更新
- 時鐘周期2 (20-40ns):
- 第一級流水線:
- sum_ab = 10 + 20 = 30
- sum_cd = 30 + 40 = 70
- e_reg1 = 2
- 其他級別未更新
- 時鐘周期3 (40-60ns):
- 第二級流水線:
- sum_abcd = 30 + 70 = 100
- e_reg2 = 2
- 第三級流水線尚未更新
- 時鐘周期4 (60-80ns):
- 輸出結果:
- y = 100 * 2 = 200 (實例1的最終結果)
數據2: a=5, b=15, c=25, d=35, e=3
- 時鐘周期2 (20-40ns):
- 輸入數據: a=5, b=15, c=25, d=35, e=3
- 寄存器尚未更新
- 時鐘周期3 (40-60ns):
- 第一級流水線:
- sum_ab = 5 + 15 = 20
- sum_cd = 25 + 35 = 60
- e_reg1 = 3
- 其他級別未更新
- 時鐘周期4 (60-80ns):
- 第二級流水線:
- sum_abcd = 20 + 60 = 80
- e_reg2 = 3
- 第三級流水線尚未更新
- 時鐘周期5 (80-100ns):
- 輸出結果:
- y = 80 * 3 = 240 (數據2的最終結果)
數據3: a=8, b=12, c=16, d=24, e=4
- 時鐘周期3 (40-60ns):
- 輸入數據: a=8, b=12, c=16, d=24, e=4
- 寄存器尚未更新
- 時鐘周期4 (60-80ns):
- 第一級流水線:
- sum_ab = 8 + 12 = 20
- sum_cd = 16 + 24 = 40
- e_reg1 = 4
- 其他級別未更新
- 時鐘周期5 (80-100ns):
- 第二級流水線:
- sum_abcd = 20 + 40 = 60
- e_reg2 = 4
- 第三級流水線尚未更新
- 時鐘周期6 (100-120ns):
- 輸出結果:
- y = 60 * 4 = 240 (數據3的最終結果)
流水線效率分析
- 延遲 (Latency):
- 每個計算實例從輸入到輸出需要3個時鐘周期 = 60 ns
- 吞吐量 (Throughput):
- 流水線滿載后,每20 ns產生一個結果
- 3個計算實例總共需要時間 = 60 ns (首個結果) + 40 ns (接下來2個結果) = 100 ns
- 如果是沒有流水線的設計,需要 3 * 60 ns = 180 ns
- 性能提升:
- 流水線設計對于處理大量連續數據時,性能提升明顯
- 在這個例子中,處理3個連續實例的時間從180 ns減少到了100 ns,提升約44%
這種波形圖清晰地展示了流水線的工作原理,顯示了每個計算實例如何逐級推進,最終產生結果,以及多個實例如何在流水線中重疊執行,提高總體處理效率。