热度 16
2012-2-21 21:19
1946 次阅读|
1 个评论
所谓流水线的概念可能大家都不陌生,通俗的讲就是本来是一条龙服务的,现在将整个环节分割成几小段,然后让这几个分段同时开始各自的工作,最后将这些小段连接成整体,这样便提高了系统的运行速度,提高了效率。 因此,流水线加法器只是将大串的数据相加修改为小段数据相加,而这个加数和被加数的分段可以自由分配的。以下是我自己实验的42位数据相加,是带符号位的,也就是符号数,我分为3段11位相加和一段9位相加。 值得注意的是前三段中相加时候要扩展一位进位,可以直接在数据前加一位0,但是在最后一段的相加中我们需要将最高的符号位扩展一次,以免加到溢出,同时可以保留符号结果。 以下是verilog代码: module pipl_add(clk,rst, add_a,add_b, add_out); input clk; input rst; input add_a; input add_b; output add_out; //为保证不溢出,相加结果扩展一位; reg sum1; reg sum2; reg sum3; reg add_out; //中间寄存的数据 reg add_tmpa3,add_tmpb3; reg add_tmpa2,add_tmpb2; reg add_tmpa1,add_tmpb1; always@(posedge clk or negedge rst) begin if(!rst) sum1 = 0; else begin sum1 = {1'b0,add_a } + {1'b0,add_b }; add_tmpa1 = add_a ; add_tmpb1 = add_b ; //储存未计算的数据 end end always@(posedge clk or negedge rst) begin if(!rst) sum2 = 0; else begin sum2 = {{1'b0,add_tmpa1 }+{1'b0,add_tmpb1 }+sum1 ,sum1 };// add_tmpa2 = add_tmpa1 ; add_tmpb2 = add_tmpb1 ; //储存未计算的数据 end end always@(posedge clk or negedge rst) begin if(!rst) sum3 = 0; else begin sum3 = {{1'b0,add_tmpa2 }+{1'b0,add_tmpb2 }+sum2 ,sum2 };// add_tmpa3 = add_tmpa2 ; add_tmpb3 = add_tmpb2 ; //储存未计算的数据 end end always@(posedge clk or negedge rst) begin if(!rst) add_out = 0; else add_out = {{add_tmpa3 ,add_tmpa3 }+{add_tmpb3 ,add_tmpb3 }+sum3 ,sum3 };// end endmodule modelsim仿真结果: 以上是综合后仿真,也就是门级仿真的结果。从数据中可以看出总体延时了3个时钟,之后数据开始显现正确结果。