四分之一平方乘法器(全变量乘法器)
下面是对ALTERA关于乘法器的资料中对全变量乘法器的翻译:
英文水平有限,还请多指教,希望大家多留言,我们可以讨论一下:
全变量乘法器
全变量乘法器是输出和系数在第个时钟都可变的乘法器,全变量乘法器的分部结果存放在RAM块中,设计是基于代数表
(a + b)2-(a - b)2 = 4ab;
所以 a*b=[(a + b)2-(a - b)2]/4;
a和b都是乘法器的变量输入。
图21给出了用RAM LUT实现的用该等式表达的全变量乘法运算器,它用到两个单独的RAM块,分别来存储(a + b)2/4
和(a - b)2/4的运算结果,两个存储块的地址(a + b) 和(a - b)被预先运算出来;最终的运算结果是通过把两个
RAM块中读出的数据相减得到的。全变量乘法器可以在第个时钟获得一次输入,需要三个时钟完出最终的运算,
图21给出了实现两个8位数据输入的乘法器。每个RAM 块有一个8位的数据输入16位的数据输出和9位的地址线,
因此,对每一个RAM块的输出结果需要两个M4K RAM块配置成256 x 16(29 = 512个地址),在这个乘法
器模型中,输入数据的宽度直接影响到使用的RAM块的数量。
图22给出了图21中给出例子的仿真结果:
表32和表33给出了Stratix II、Stratix器件各自实现图21中给出的例子,两个8位输入全变量乘法器的结果,全变量乘法器适用于输
入位宽和系数都不是很大的低分辨率乘法器。因为当输入和系数的位数都比较大时,与别的等宽度的变量软乘法器模型相比,全变量乘
法器的实现需要需要大量的存储块资源。
表32
表33
以下是实现的程序:
library LPM;
use lpm.lpm_components.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity mul is
generic ( width1 : integer := 8;
width2 : integer :=16);
port(
clk : in std_logic;
dataa : in std_logic_vector(7 downto 0);
datab : in std_logic_vector(7 downto 0);
result : out std_logic_vector(15 downto 0)
);
end mul;
architecture behaver of mul is
signal add_result : std_logic_vector (8 downto 0);
signal sub_result : std_logic_vector (8 downto 0);
signal add_rom_result : std_logic_vector (15 downto 0);
signal sub_rom_result : std_logic_vector (15 downto 0);
signal final_result : std_logic_vector(15 downto 0);
begin
add :lpm_add_sub
generic map(
lpm_width => width1,
lpm_representation => "unsigned",
lpm_direction => "add")
port map (
dataa => dataa,
datab => datab,
result => add_result(7 downto 0),
overflow => add_result(8));
sub : lpm_add_sub
generic map(
lpm_width => width1,
lpm_representation => "unsigned",
lpm_direction => "sub")
port map (
dataa => dataa,
datab => datab,
result => sub_result(7 downto 0),
overflow => sub_result(8));
add_rom : lpm_rom
generic map(
lpm_width => 16,
lpm_widthad => 9,
lpm_file => "add.mif")
port map(
address => add_result,
inclock => clk,
outclock => clk,
q => add_rom_result);
sub_rom : lpm_rom
generic map(
lpm_width => 16,
lpm_widthad => 9,
lpm_file => "sub.mif")
port map(
address => sub_result,
inclock => clk,
outclock => clk,
q => sub_rom_result);
sub1 : lpm_add_sub
generic map(
lpm_width => width2,
lpm_representation => "unsigned",
lpm_direction => "sub")
port map(
dataa => add_rom_result,
datab => sub_rom_result,
result => result);
--result <= final_result;
end behaver;
以下为仿真结果: