首页 文章

N位串行加法器/减法器VHDL

提问于
浏览
0

我正在尝试用VHDL实现一个串行加法器/减法器,我之前已经完成了纹波传输方式,但现在我应该通过使用一个完整的加法器单元而不是N个单元来实现相同的功能 . 我必须将位从向量移位到完整的加法器/减法器并将结果存储在另一个向量中,我也只是移动索引...它背后的逻辑很容易理解,你只需要一个计数器索引等 . 但我显然遇到了问题,因为我可能还在想太多软件编程,我猜...

我遇到的问题是当计数器进入过程时计数器立即增加到1,这样当我尝试添加向量a = 0101 0101和b = 1010 1010时,我得到y = 1111 111X而carrys = 0000 000X . 我试图开始将结果存储在index_counter - 1,因为索引在第一个时钟周期跳转到1,但后来我在模拟中遇到致命错误...

我一直试图解决这个问题几个小时,似乎无法弄清楚如何做到这一点,所以你能看一看,看看我能做些什么来解决它?非常感谢!

我确实有饱和和溢出的信号,我将在稍后实现,但它们目前尚未真正使用,所以不要担心它们 .

如果您想知道为什么我按照我的方式完成它,设计不应该在加/减完成之前更新最终结果 .

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

entity serial_adder_subtracter_saturate is
    generic (WIDTH : INTEGER := 8);
    port (a : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
          b : IN STD_LOGIC_VECTOR(WIDTH-1 downto 0);
          saturate : IN STD_LOGIC := '0';
          add_sub : IN STD_LOGIC := '1';
          clk : IN STD_LOGIC;
          start : IN STD_LOGIC;
          reset : IN STD_LOGIC;
          y : OUT STD_LOGIC_VECTOR(WIDTH-1 downto 0);
          overflow : OUT STD_LOGIC;
          finished : OUT STD_LOGIC);
end serial_adder_subtracter_saturate;

ARCHITECTURE behavior OF serial_adder_subtracter_saturate is

component bitAdder is
port(a : IN STD_LOGIC;
     b : IN STD_LOGIC;
     cin : IN STD_LOGIC;
     add_sub : IN STD_LOGIC;
     y : OUT STD_LOGIC;
     cout : OUT STD_LOGIC);
end component;

signal carry : STD_LOGIC_VECTOR (WIDTH-1 downto 0); -- hold the carry outs from the adders
signal temp_sum : STD_LOGIC_VECTOR (WIDTH-1 downto 0);
signal o_flow : STD_LOGIC;      -- internal overflow signal so I can read it in the process

signal a_temp : STD_LOGIC;
signal b_temp : STD_LOGIC;
signal y_temp : STD_LOGIC;
signal cin_temp : STD_LOGIC; 
signal cout_temp : STD_LOGIC;

begin 
AddSub: bitAdder 
    port map(a => a_temp, 
             b => b_temp, 
             cin => cin_temp, 
             add_sub => add_sub, 
              y => y_temp, 
             cout => cout_temp);

    o_flow <= carry(WIDTH-1) XOR carry(WIDTH-2);

test: process(clk)
variable index_counter : integer range 0 to (WIDTH) := 0;
begin
    if rising_edge(clk) then
        if reset = '1' then
            index_counter := 0;
            carry <= (others => '0');
            temp_sum <= (others => '0');
            finished <= '0';
        elsif reset = '0' AND start = '1' then
            if index_counter = (WIDTH) then
                finished <= '1';
                y <= temp_sum;
            else
                if index_counter = 0 then
                    cin_temp <= NOT add_sub;
                else
                    cin_temp <= carry(index_counter);
                end if;

                a_temp <= a(index_counter);
                b_temp <= b(index_counter);
                carry(index_counter) <= cout_temp;
                temp_sum(index_counter) <= y_temp;

                index_counter := index_counter + 1;
            end if;             
        end if;
    end if;
end process;
end behavior;

以下是完整的加法器/减法器如何查看感兴趣的内容:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;

ENTITY bitAdder IS
    PORT (a: IN STD_LOGIC;
          b: IN STD_LOGIC;
          cin: IN STD_LOGIC;
          add_sub : IN STD_LOGIC;
          y: OUT STD_LOGIC;
          cout: OUT STD_LOGIC);
END bitAdder;

ARCHITECTURE behavior OF bitAdder IS
signal b_sig : STD_LOGIC := '1';
BEGIN
    b_sig <= not b when add_sub = '0' else
                 b;             -- b_sig <= add_sub XOR b;
    y <= a XOR b_sig XOR cin;
    cout <= (a AND b_sig) OR 
            (b_sig AND cin) OR 
            (a AND cin);
END behavior;

1 回答

  • 1

    我没有尝试调试这个,但我认为这是一个时间问题:

    在第一个上升时钟边沿,您定义加法器的两个输入 and 注册之前定义的加法器's outputs (which are X at this point, because its inputs weren't .

    将结果存储在 index_counter - 1 的想法是正确的,但是你需要注意不要试图将结果存储在不存在的寄存器中,例如 carry(-1)temp_sum(-1) . 例如,您可以使用 if index_counter > 0 .

    类似地,您需要在计算结束时再允许一个周期,或者将最后一个结果位直接分配给 y 输出,否则您将错过最后一个结果位 .

    希望有所帮助!

相关问题