解析计算机体系结构中的MACs实现

乘法运算是数学中重要的基本算术运算,乘法累加操作(multiply and accumulate operations.MAC)在数字信号处理中被广泛应用,比如,FFT,DFT,卷积计算,甚至是微控制器的ALU中的通用计算单元都能见到它的身影。在DSP应用中,比通用处理器更加侧重MACs的设计,MACs的逻辑实现通常是数字电路设计中Critical path的主要贡献方,设计的好坏决定了PPA,本文试图从软件视角搞清楚MACs是什么以及如何工作的。

设计原理

MACs顶层实现方框图如下,其中的operand_1 和 operand_2是32位输入操作数,MACs操作的结果通过64位的Result pin输出,内部的64位加法器将乘法器的输出作为第一个操作数,与存储在内部的第二个加法操作数相加,第二个操作数的来源一般是上一个周期的Result结果,得到Result输出和进位信号Carry.

一个用VHDL实现的MACs单元逻辑:

  1 LIBRARY ieee;
  2 USE ieee.std_logic_1164.ALL;
  3 USE ieee.numeric_std.ALL;
  4
  5 ENTITY mac IS
  6         GENERIC (n   :   INTEGER := 4); --define X and Y size
  7         PORT (
  8                 ck  : IN  STD_LOGIC;
  9                 rst : IN  STD_LOGIC;
 10                 X   : IN  SIGNED (n-1 DOWNTO 0); --n
 11                 Y   : IN  SIGNED (n-1 DOWNTO 0); --n
 12                 A   : OUT SIGNED ((2+2*n)-1 DOWNTO 0)  --2+2n (include two leading bits for overflow)
 13         );
 14 END mac;
 15
 16 ARCHITECTURE hdl OF mac IS
 17         SIGNAL acc : SIGNED ((2+2*n)-1 DOWNTO 0) := (OTHERS => '0'); --2+2n
 18
 19 BEGIN
 20
 21         PROCESS (ck)
 22         BEGIN
 23                 IF rising_edge(ck) THEN
 24                         IF rst ='0' THEN --reset accumulator at low
 25                                 acc <= (OTHERS => '0');
 26                         ELSE
 27                                 acc <= acc + shift_left(X * Y, 1);
 28                         END IF;
 29                 END IF;
 30         END PROCESS;
 31
 32         A <= acc;
 33 END hdl;

这段代码对应的电路逻辑如下图所示,acc作为输出的同时,又通过一条反馈回路喂给加法器,作为其中一个操作数进行下次累加计算,所以叫做累加器-MACs.

Vedic Multiplier 电路实现

数字电路的设计中,内蕴了深刻的递归和同构的思想,当问题在不同层面具有相同的结构时,可以通过将复杂问题逐层递归分解,找到最小的问题可解决结构,再最小结构层面上把问题解决,然后再以此为基础,再按照分解的逆向过程逐步解决高层问题,最终得到整个问题的解,同样道理,构造32 \times 32 MACs,可以从最简单的2 \times 2乘法器开始构造。

采用Vedic算法的2 \times 2乘法器原理如下:

对应的数字电路实现如下图所示:

基于2 \times 2 multiplier,可实现4 \times 4的verdic multiplier

基于4 \times 4 multiplier,可实现8 \times 8的verdic multiplier

基于8 \times 8 multiplier,可实现16 \times 16的verdic multiplier

基于16 \times 16 multiplier,可实现32 \times 32的verdic multiplier

至此,32 \times 32的乘法器构造完成,下面需要构造加法器。


加法器有很多,下面方框图表示的是使用超前进位加法器的一个完整的MACs单元实现:

累加器的典型应用就是矩阵乘法,以点乘为例说明multiplier, adder 以及accumulator的作用:

计算向量\vec{a}\vec{b}的点积,结果存在result里面

\vec{a}=\begin{bmatrix} a_1\\ a_2\\ \vdots \\ a_n \end{bmatrix}

\vec{b}=\begin{bmatrix} b_1\\ b_2\\ \vdots \\ b_n \end{bmatrix}

result = \vec{a}^T\vec{b} = a_1b_1 + a_2b_2+\cdots+a_nb_n

用程序表示就是:

u64 adder(u64 m, u64 n)
{
     return m + n;
}

u64 multiplier(u32 m, u32 n)
{
    return m*n;
}

u64 macs(u32 operand_1, u32 operand_2)
{
    accumulator = 0;
    result = 0;
    
    temp1 = multiplier(operand_1, operand_2);
    carrier, accumulator = adder(temp1, accumulator);
    
    result = accumulator;

    return result, carrier;
}

void dotproduct(u32*a, u32*b)
{
    for(i = 0; i < n; i ++)
    {
        result = macs(a[i], b[i]);
    } 
}

经常在一些DSP芯片Spec中看到的指标,比如每时钟周期执行8个32 \times 32MACs操作,1632 \times 16MACs操作等等,本质上表示DSP的微架构内实现了几个这样的MACs单元。

MIPS处理器MACs指令的实现:

MIPS中,乘累加,乘累减指令共有4条,包括:madd, maddu, msub, msubu.

其中

madd rs, rt.

指令作用为:

\mathbf{\{HI,LO\}\leftarrow \{HI,LO\}+rs\times rt}

将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数进行乘法运算,运算结果与{HI,LO}相加,相加的结果保存到{HI,LO} 中,此处{HI,LO}表示HI,LO寄存器连接形成64位数.

maddu rs, rt.

和madd的唯一区别是rs,rt中的值作为无符号数.

msub rs, rt

\mathbf{\{HI,LO\}\leftarrow \{HI,LO\}-rs\times rt}

将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数进行乘法运算,然后使用{HI,LO}减去乘法结果,相减的结果保存到{HI,LO} 中.

msubu rs, rt

和msub rs, rt的唯一区别是寄存器中的值是无符号数.


结束!

猜你喜欢

转载自blog.csdn.net/tugouxp/article/details/113832291