流水线设计,将组合逻辑按时序拆分,是优化时序的一种方法
版本一
一、功能要求
-
内容:实现一个四输入的乘法器,实现电路结构s = a * b * c * d
-
要求:
a. 可以连续计算(即每个时钟都可以输入数据,运算的结果也能连续输出)
b. 只有输出才用到D触发器
二、端口和波形图
module mul4 (
input wire clk ,
input wire rst_n ,
input wire vld_in ,
input wire [ 3: 0] a ,
input wire [ 3: 0] b ,
input wire [ 3: 0] c ,
input wire [ 3: 0] d ,
output reg [15: 0] dout ,
output reg [ 3: 0] vld_out
);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
vld_out <= 1'b0;
else
vld_out <= vld_in;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
dout <= 0;
else
dout <= a * b * c * d;
endmodule
生成RTL图
经过三个mul
版本二
一、功能要求
-
内容:改变版本一的电路结构,优化成s = (a * b) * (c * d)
-
要求:
a. 可以连续计算(即每个时钟都可以输入数据,运算的结果也能连续输出)
b. 只有输出才用到D触发器
module mul4_2 (
input wire clk ,
input wire rst_n ,
input wire vld_in ,
input wire [ 3: 0] a ,
input wire [ 3: 0] b ,
input wire [ 3: 0] c ,
input wire [ 3: 0] d ,
output reg [15: 0] dout ,
output reg [ 3: 0] vld_out
);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
vld_out <= 1'b0;
else
vld_out <= vld_in;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
dout <= 0;
else
dout <= (a*b) * (c*d);
endmodule
生成RTL图
经过两个mul
版本三
一、功能要求
-
内容:以流水线的设计方法实现4输入的乘法器
-
要求:
寄存器之间仅包含一个乘法器(两级流水线。每次输入有效(vld_in = 1)后的第二个时钟周期输出有效(vld_out = 1),并由dout输出结果)
module mul4_3 (
input wire clk ,
input wire rst_n ,
input wire vld_in ,
input wire [ 3: 0] a ,
input wire [ 3: 0] b ,
input wire [ 3: 0] c ,
input wire [ 3: 0] d ,
output reg [15: 0] dout ,
output reg [ 3: 0] vld_out
);
reg vld_in_ff0;
reg [ 7: 0] s1;
reg [ 7: 0] s2;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
vld_in_ff0 <= 1'b0;
else
vld_in_ff0 <= vld_in;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
vld_out <= 1'b0;
else
vld_out <= vld_in_ff0;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
dout <= 0;
else
dout <= s1 * s2;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
s1 <= 0;
else
s1 <= a * b;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
s2 <= 0;
else
s2 <= c * d;
endmodule
生成RTL图
经过一个mul
版本四
一、功能要求
-
内容:以流水线的设计方法实现4输入的乘法器
-
要求:
a. 不能用乘法器,要用加法器和选择器来代替
b. 寄存器之间至多只有一个加法器+一个选择器
c. 流水线级数不限定
d. 要求能连续运算
只实现了四级流水的4x4乘法器
module tool_mul_4x4 (
input wire clk ,
input wire rst_n ,
input wire vld_in ,
input wire [ 3: 0] a ,
input wire [ 3: 0] b ,
output wire [ 7: 0] dout ,
output wire vld_out
);
reg [ 3: 0] a1;
reg [ 3: 0] a2;
reg [ 3: 0] a3;
reg [ 2: 0] b1;
reg [ 1: 0] b2;
reg b3;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
begin
a1 <= 0;
a2 <= 0;
a3 <= 0;
end
else
begin
a1 <= a;
a2 <= a1;
a3 <= a2;
end
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
begin
b1 <= 0;
b2 <= 0;
b3 <= 0;
end
else
begin
b1 <= b [3:1];
b2 <= b1[2:1];
b3 <= b2[1:1];
end
reg [ 7: 0] sum1;
reg [ 7: 0] sum2;
reg [ 7: 0] sum3;
reg [ 7: 0] sum4;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
sum1 <= 0;
else
sum1 <= (b[0] ? a : 0);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
sum2 <= 0;
else
sum2 <= sum1 + (b1[0] ? {a1, 1'b0} : 0);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
sum3 <= 0;
else
sum3 <= sum2 + (b2[0] ? {a2, 2'b0} : 0);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
sum4 <= 0;
else
sum4 <= sum3 + (b3 ? {a3, 3'b0} : 0);
reg vld_in1;
reg vld_in2;
reg vld_in3;
reg vld_in4;
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
begin
vld_in1 <= 0;
vld_in2 <= 0;
vld_in3 <= 0;
vld_in4 <= 0;
end
else
begin
vld_in1 <= vld_in;
vld_in2 <= vld_in1;
vld_in3 <= vld_in2;
vld_in4 <= vld_in3;
end
assign vld_out = vld_in4;
assign dout = sum4;
endmodule
补充一下流水线加法器: 阻塞流水线实现加法器.