1. 32位乘法器(MPY32)介绍
MPY32是不属于CPU的外围模块,这意味着它的活动不会影响CPU活动。乘法器寄存器是外围寄存器,用CPU指令加载和读取。
MPY32支持:
- 无符号乘法
- 有符号乘法
- 累计无符号乘法
- 累计有符号乘法
- 8、16、24、32位运算
- 分数运算
- 8位和16位操作兼容16位硬件乘法器
- 不需要“符号扩展”指令的8位和24位乘法
2. MPY32操作
MPY32支持8位、16位、24位和32位操作数进行无符号乘、有符号乘、无符号乘累积和有符号乘累积操作。操作数的大小由操作数被写入的地址以及是否以字或字节的形式写入来定义。操作的类型是根据第一个操作数写入的地址来选择的。硬件乘法器有两个32位的操作数寄存器 OP1和OP2,以及一个64位的结果寄存器RES0到RES3。为了与16×16硬件乘法器兼容,8位或16位操作的结果可以通过RESLO、RESHI和SUMEXT访问。RESLO存储16×16位结果的低16位,RESHI存储结果的高16位,SUMEXT存储结果信息。
8位或16位操作的结果在三个MCLK周期中即可完成,在写入OP2之后的下一个指令即可取结果,当对结果使用间接寻址时,在结果准备好之前需要NOP指令。24位或32位操作的结果可以在写了OP2或OP2H之后取出,同样,当对结果使用间接寻址时,在结果准备好之前需要NOP指令。下表总结了各种操作数大小结合情况下,64位结果读取时刻:
2.1 操作寄存器
OP1有12个寄存器用来装入数据和乘法模式。将第一个操作数的低位字写入给定的地址,选择要执行的乘法操作类型,但不启动任何操作。
向带32H后缀的高字寄存器写入第二个字时,乘数假设OP1为32位宽,否则,假设OP1为16位。在写入OP2之前写入的最后一个地址定义了第一个操作数的宽度。例如:如果先写MPY32L,再写MPY32H,OP1的数据宽度设置为32位。如果首先写入MPY32H,然后写入MPY32L,乘法器忽略MPY32H,假设OP1为16位,使用写入MPY32L的数据。如果连续操作使用OP1值,则可以在不重新加载OP1的情况下执行重复的乘法操作。执行这些操作并不需要重写OP1值。
将第二个操作数写入OP2将启动16位乘法操作。写入OP2L启动32位宽的乘法操作,乘法器期望一个高的字被写入OP2H。如果不先写OP2L就写OP2H会被忽略。
对于8位或24位操作数,可以使用字节指令访问操作数寄存器。在有符号操作期间使用字节指令访问乘数将自动导致乘法器模块内字节的符号扩展。对于24位操作数,只有高字应该写成字节。如果24位操作数是由寄存器定义的符号扩展的,该寄存器用于将低字写入,因为该寄存器定义了操作是无符号还是有符号的。
当将32位操作数的大小更改为16位时,通过修改操作数大小位或写入相应的操作数寄存器,32位操作数的高字保持不变。在执行16位操作时,高字的内容被忽略。
2.2 结果寄存器
乘法结果总是64位宽,可以通过寄存器RES0到RES3访问。使用有符号操作, MPYS或MACS,结果被适当的符号扩展。如果结果寄存器在MACS操作之前加载了初始值,用户软件必须注意将写入的值正确地扩展到64位。
除了RES0到RES3外,为了兼容16×16硬件乘法器,还可以通过RESLO、RESHI和SUMEXT访问8位或16位操作的32位结果。在这种情况下,结果低寄存器RESLO持有较低的16位计算结果,结果高寄存器RESHI持有较高的16位。RES0和RES1在计算结果的使用和访问上分别与RESLO和RESHI相同。
结果拓展寄存器SUMEXT目录取决于操作模式。如果所有操作数都小于或等于16位,则32位结果用于确定符号和进位。如果其中一个操作数大于16位,则使用64位结果。
MPYC位反映了下表中列出的乘法器进位,因此,如果不选择分数或饱和模式,MPYC位可以作为结果的第33位或第65位。对于MAC或MACS操作,MPYC位反映32位或64位累积的进位,不考虑连续的MAC和MACS操作作为第33位或第65位。
MACS上溢出和下溢出
在MACS模式下,乘法器不会自动检测下溢出或上溢出。例如,输入16位数据,输出32位结果,对于正数的可用范围是0到07FFF FFFFh,对于负数是0FFFF FFFFh到08000 0000h。当两个负数的和在正数的范围内时,就会发生下溢出,当两个正数的和在负数的范围内时,就会发生上溢出。
在上述两种情况下,SUMEXT寄存器都包含结果的符号。MPY32CTL0中的MPYC位可以用于检测溢出情况。如果进位与SUMEXT寄存器所反映的符号不同,则发生溢出。用户软件必须适当地处理这些情况。