发现为了加深理解,还是需要具体写一下超前进位加法器的原理。
加法器最自然的想法是涟漪加法器,即逐位进行运算。但是,在涟漪加法器中,每一位上都是全加器,需要知道前一位的进位信号后才能进行运算,这样会导致每一位上都累积延迟,最后导致整个涟漪加法器产生较大的延迟。
而超前进位加法器中,利用半加器,可以预先并同时计算每一位的进位信号,这样可以以并行的方式进行计算,从而减少整体加法运算的延迟时间。因此,超前进位加法器相对于涟漪加法器可以获得更好的性能。
先考虑4位加法器。设两数$a_{[3:0]},b_{[3:0]}$相加,结果为$s_{[3:0]}$。设第$i$位(0-based)上向前的进位为$c_{i}$。设输入进位(可以视作$c_{-1}$)为$c_{in}$,输出进位(可以视作$c_3$)为$c_{out}$。
应有(在{0,1}内考虑)
$$\begin{align*}s_i&=a_i+b_i+c_{i-1}\\&=(a_i+b_i)+c_{i-1}\\ \\ c_i&=a_i *b_i+a_i*c_{i-1}+b_i*c_{i-1}\\&=(a_i+b_i)*c_{i-1}+a_i*b_i\end{align*}$$
故记$p_i=a_i+b_i$, $q_i=a_i*b_i$,有
$$\begin{align*}c_i&=a_i*b_i+a_i*c_{i-1}+b_i*c_{i-1}\\&=(a_i+b_i)*c_{i-1}+a_i*b_i\end{align*}$$
故有
$$\begin{align*}c_0&=p_0*c_{in}+g_0\\c_1&=p_1*p_0*c_{in}+p_1*g_0+g_1\\c_2&=p_2*p_1*p_0*c_{in}+p_2*p_1*g_0+p_2*g_1+g_2\\c_{out}&=p_3*p_2*p_1*p_0*c_{in}+p_3*p_2*p_1*g_0+p_3*p_2*g_1+p_3*g_2+g_3\end{align*}$$
然后再考虑16位加法器。当然可以重复上面的做法扩展至16位,但是这会导致电路复杂度急剧增加,扇入过大,导致较大的时延。因此,不妨将每四位封装起来,然后通过数学变形,计算出每四位等效的p和q,然后类似前面的做法,在封装起来的各个4位组之间搭建超前进位加法器,这样就可以完整地实现超前进位加法器了。具体如下:
设两数$a_{[15:0]},b_{[15:0]}$相加,结果为$s_{[15:0]}$。将每4位封装为一组,记作$\tilde{a}_{[3:0]},\tilde{b}_{[3:0]}$。设第$i$个(0-based)4位组上向前的进位为$\tilde{c}_{i}$。设输入进位(可以视作$\tilde{c}_{-1}$)为$\tilde{c}_{in}$,输出进位(可以视作$\tilde{c}_3$)为$\tilde{c}_{out}$。
对于每个4位组,令等效
$$\begin{align*}\tilde{p}&=p_3*p_2*p_1*p_0\\\\\tilde{g}&= p_3*p_2*p_1*g_0+p_3*p_2*g_1+p_3*g_2+g_3\end{align*}$$
则有
$$\begin{align*}c_{out}=\tilde{p}*c_{in}+\tilde{g}\end{align*}$$
故有
$$\begin{align*}\tilde{c}_0&= \tilde{p}_0 *\tilde{c}_{in}+\tilde{g}_0\\\tilde{c}_1&=\tilde{p}_1*\tilde{p}_0*\tilde{c}_{in}+\tilde{p}_1*\tilde{g}_0+\tilde{g}_1\\\tilde{c}_2&=\tilde{p}_2*\tilde{p}_1*\tilde{p}_0*\tilde{c}_{in}+\tilde{p}_2*\tilde{p}_1*\tilde{g}_0+\tilde{p}_2*\tilde{g}_1+\tilde{g}_2\\\tilde{c}_{out}&=\tilde{p}_3*\tilde{p}_2*\tilde{p}_1*\tilde{p}_0*\tilde{c}_{in}+\tilde{p}_3*\tilde{p}_2*\tilde{p}_1*\tilde{g}_0+\tilde{p}_3*\tilde{p}_2*\tilde{g}_1+\tilde{p}_3*\tilde{g}_2+\tilde{g}_3\end{align*}$$
这里的表达式和前面是完全相同的,因此可以以相同的方式在4位组之间搭建起超前进位加法器。用这样的方法,可以拓展至高位数加法器。
另外,在最后一级超前加法器,有$\tilde{c}_{in}=0$,$\tilde{c}_{out}$表示溢出位。