第十章 如何编写和验证简单的纯组合逻辑模块
关于这一章,我唯一想总结一下的就是流水线的设计,书上没有范例,上网上搜索了一下,关于4位全加器的流水线设计大部分都不正确,后来终于找到了一个和我理解一样的人的博客(tengjingshu)在此谢过,如有版权问题,务必及时通知,但是他的pipeline_add模块中采用阻塞赋值,显然是不对的,应该采用非阻塞赋值,我将他的例程稍作修改引用如下:
流水线4位(4bit)加法器
代码如下:
modulepipeline_add(a,b,cin,cout,sum,clk);
input[3:0] a,b;
input clk,cin;
output[3:0]sum;
output cout;
reg[3:0] tempa,tempb;
reg tempci;
reg cout;
reg firstco;
reg[1:0] firstsum;
reg[2:0] firsta,firstb; //空出fista[2]、firstn[2]放进位
reg[3:0] sum;
always@(posedge clk)
begin
tempa<=a; //输入数据缓存
tempb<=b;
tempci<=cin;
end
always@(posedge clk)
begin
{firstco,firstsum}<=tempa[1:0]+tempb[1:0]+tempci; //第一级加(低2位)
firsta<=tempa[3:2]; //未参加计算的数据缓存
firstb<=tempb[3:2];
end
always@(posedge clk)
begin
{cout,sum}<={firsta[2:0]+firstb[2:0]+firstco,firstsum}; //第二级加(高2位)
end
endmodule
顶层测试模块代码
`timescale 1ns/1ps
module pipeline_add_test;
reg [3:0] a =4'b0000;
reg [3:0] b =4'b0000;
reg cin = 1'b0;
wire cout;
wire [3:0] sum;
reg clk = 1'b0;
parameter PERIOD= 200;
parameter realDUTY_CYCLE = 0.5;
parameter OFFSET= 100;
initial // Clock process for clk
begin
#OFFSET;
forever
begin
clk= 1'b0;
#(PERIOD-(PERIOD*DUTY_CYCLE))clk = 1'b1;
#(PERIOD*DUTY_CYCLE);
end
end
pipeline_add UUT(
.a(a),
.b(b),
.cin(cin),
.cout(cout),
.sum(sum),
.clk(clk));
initial begin
// ------------- CurrentTime: 100ns
#100;
cin= 1'b1;
// -------------------------------------
//------------- Current Time: 185ns
#85;
a= 4'b0010;
b= 4'b0011;
// -------------------------------------
//------------- Current Time: 385ns
#200;
a= 4'b0100;
b= 4'b0010;
// -------------------------------------
//------------- Current Time: 585ns
#200;
cin= 1'b0;
a= 4'b1010;
b= 4'b0011;
// -------------------------------------
//------------- Current Time: 785ns
#200;
a= 4'b1011;
b= 4'b1010;
// -------------------------------------
//------------- Current Time: 985ns
#200;
a= 4'b1111;
b= 4'b1110;
// -------------------------------------
//------------- Current Time: 1185ns
#200;
a= 4'b1101;
b= 4'b0100;
// -------------------------------------
//------------- Current Time: 1585ns
#400;
a= 4'b0011;
// -------------------------------------
//------------- Current Time: 1785ns
#200;
b= 4'b1101;
// -------------------------------------
//------------- Current Time: 1985ns
#200;
cin= 1'b1;
a= 4'b0101;
b= 4'b1111;
// -------------------------------------
//------------- Current Time: 2385ns
#400;
a= 4'b0100;
b= 4'b1101;
// -------------------------------------
end
endmodule
看懂这个例程,也就理解了流水线编程~~~