首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >试图理解Booth的乘法基-4实现

试图理解Booth的乘法基-4实现
EN

Stack Overflow用户
提问于 2015-11-14 17:47:14
回答 1查看 904关注 0票数 1

我试图理解一些用基-4实现描述Booth乘法的VHDL代码。我知道算法是如何工作的,但我似乎不明白代码的某些部分具体做了什么。

以下是整个实现:

代码语言:javascript
运行
复制
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

entity booth_mult is
  port(
    clk             : in std_logic;
    start           : in std_logic;
    n_reset : in std_logic;
    mcand       : in std_logic_vector(15 downto 0);
    mplier      : in std_logic_vector(15 downto 0);
    done        : out std_logic;
      product   : out std_logic_vector(31 downto 0)
    );
end booth_mult;

architecture arch of booth_mult is
    type state_type is(IDLE, BUSY);
    attribute ENUM_ENCODING : string;                                           -- used for explicit state machine encoding
    attribute ENUM_ENCODING of state_type   : type is "01 10";
    signal state_reg, state_next                                : state_type;

    signal q_reg, q_next                                                : unsigned(6 downto 0);
    signal mcand_reg                                                    : std_logic_vector(15 downto 0);                -- registers for the multiplicand
    signal prod_reg, prod_next                              : std_logic_vector(32 downto 0);
    signal result_reg, result_next                          : std_logic_vector(32 downto 0);            -- this holds the result before shift
    signal q_add, q_reset                                           : std_logic;

begin
    -- increment sequential logic on rising clock edge process
    process(clk, n_reset)   
    begin
        if rising_edge(clk) then
            if n_reset = '0' then
                state_reg <= IDLE;
                q_reg <= (others => '0');
                prod_reg <= (others => '0');
            else
                q_reg <= q_next;
                state_reg <= state_next;
                prod_reg <= prod_next(32) & prod_next(32 downto 1);  -- shift prod register each time
                result_reg <= prod_next;
            end if; 
        end if;
    end process;

  -- control unit process
    process(state_reg, q_reg, result_reg, start, prod_reg, mplier, mcand )                  
        begin
            -- initialize signals and no register update
            q_add <= '0';
            q_reset <= '0';
            done <= '0';
            state_next <= state_reg;
            prod_next <= prod_reg;
            result_next <= result_reg;  

            case state_reg is

                when IDLE => 
                    if (start = '1') then   -- load numbers to multiply
                        mcand_reg <= mcand;
                        prod_next(32 downto 17) <= (others => '0');  -- prod_next reg = [0000...0000(mplier)0]
                        prod_next(16 downto 1) <= mplier;
                        prod_next(0) <= '0';
                        state_next <= BUSY;
                    end if;

                when BUSY =>
                    q_add <= '1';
                    if (q_reg = '0' & conv_unsigned(16, 7)(6 downto 1)  and start /= '1') then  -- after 8 clock cycles multiplication is done
                        product <= prod_next(32) & prod_next(32  downto 2);
                        done <= '1' ;
                        q_add <= '0';
                        q_reset <= '1';
                        state_next <= IDLE;
                    end if;
                    -- radix-4 decoding
                    case result_reg(2 downto 0) is     
                        when "001" | "010" =>   -- + mcand
                            prod_next <= ((prod_reg(32) & prod_reg(32 downto 17)) + (mcand_reg(16 - 1) & mcand_reg)) & prod_reg(16 downto 1);
                        when "011" =>                       -- + 2*mcand
                            prod_next <= ((prod_reg(32) & prod_reg(32 downto 17)) + (mcand_reg & '0' )) & prod_reg(16 downto 1);
                        when "100" =>                       -- - 2*mcand
                            prod_next <= ((prod_reg(32) & prod_reg(32 downto 17)) - (mcand_reg & '0' )) & prod_reg(16 downto 1);
                        when "101" | "110" =>   -- - mcand
                            prod_next <= ((prod_reg(32) & prod_reg(32 downto 17)) - (mcand_reg(16 - 1) & mcand_reg)) & prod_reg(16 downto 1); -- 2*mcand
                        when others =>                  -- shift only
                            prod_next <= prod_reg(32) & prod_reg(32 downto 1);
                    end case;

                end case;

    end process;


    -- timer/counter for timed logic
  q_next <= (others => '0') when q_reset = '1' else         -- reset q_next to bottom if q_reset is 1
                   q_reg + 1 when q_add = '1' else                            -- increment q_reg by 1 if q_add is 1
                   q_reg;   


end arch;   

我不明白的是:

  1. if (q_reg = '0' & conv_unsigned(16, 7)(6 downto 1) and start /= '1') then -- after 8 clock cycles multiplication is done。 这句话很明显,但它到底做了些什么呢?conv_unsigned的文档说,它应该将值16返回为大小为7的无符号值(它是)(我猜可能是这样)。conv_usigned0返回的任何内容,难道不只是使整个过程变为0吗?
  2. prod_next <= prod_reg(32) & prod_reg(32 downto 1); 再一次提到这一评论,这应该是一个转变。我所了解的实际情况是,prod_reg寄存器的第32位与第32位和第1位之间的同一寄存器的每一位一起编辑,然后分配给prod_next。这到底有什么变化?

代码在测试时工作,所以这是我缺乏VHDL知识的一个问题,所以如果问题是愚蠢的,请原谅我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-14 17:59:03

要回答Q1:'&‘是连接操作符,所以'0' & seven_bit_number生成一个8位数。

因此,整个表达式'0' & conv_unsigned(16, 7)(6 downto 1)B"001000",或8.我认为.

这是一场模糊的VHDL竞赛吗?这种与类型系统的艰苦斗争通常意味着你遗漏了一些东西,或者设计有一些严重的错误。

我会删除这些非标准库:

代码语言:javascript
运行
复制
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;

为了支持该标准,请使用ieee.numeric_std.all;并简单地编写

代码语言:javascript
运行
复制
if q_reg = 8 and start /= '1' then

请注意,现在这个令人费解的评论不仅是有意义的,而且是多余的。

(可能还会有其他非标准库依赖项需要清理,因此这是否真正值得由您来完成)。

在Q2上有一个小提示:操作不是移位:它似乎是一个有符号扩展的移位,所以里面可能有有符号的数字。同样,如果适当的话,让prod_next成为一个numeric_std.signed,就可以清楚地知道到底发生了什么,偿还了一些技术债务。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33711412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档