如何添加两个已在VHDL中连接的std_logic_vector?

时间:2018-02-07 06:50:29

标签: vhdl hardware xilinx hdl

我正在使用一组功能来处理ALU。我认为如果我使用额外的位来存储执行,则添加和位移部分会更容易。我正在尝试将一个额外的位连接到两个8位长的'std_logic_vector'。额外的位将保留执行中的执行。

然而,当我在一些调试后运行模拟时,它看起来不像我曾经给过s_a和fen的行,它们的值正在做任何事情。如果我要取出默认值,它们就会变空。

我确定错误是愚蠢的,我不熟悉vhdl中的连接是如何工作的,也许这是存储执行的更好方法,任何帮助都会受到赞赏。

代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity ALU is
    Port ( 
            A       : in std_logic_vector(7 downto 0);
            B       : in std_logic_vector(7 downto 0);
            SEL     : in std_logic_vector(3 downto 0);
            Cin     : in std_logic;
            Result  : out std_logic_vector(7 downto 0);
            C       : out std_logic;
            Z       : out std_logic);

end ALU;

architecture Behavioral of ALU is

signal s_result: unsigned(8 downto 0) := "000000000";
signal s_cin: unsigned(8 downto 0) := "000000000";
signal s_a: unsigned(8 downto 0) := "000000000";
signal s_b: unsigned(8 downto 0) := "000000000";
signal s_exempt: std_logic := '0';

begin

s1: process(A, B, SEL, CIN)
    begin

        s_a <= ('0' & unsigned(A));
        s_b <= ('0' & unsigned(B));
        s_cin(0) <= Cin;
        s_exempt <= '0';

        case SEL is
          when "0000" =>   
            s_result <= s_a + s_b;
            C <= s_result(8);
          when "0001" =>                    --ADDc Add with carry
            s_result <= s_a + s_b + s_cin;
            C <= s_result(8);
          when "0010" =>                    --SUB
            if(s_a > s_b) then
                s_result <= s_a - s_b;
                C <= '0';
            else
                s_result <= s_b - s_a;
                C <= '1';
            end if;
          when "0011" =>                    --SUBc Subtract with carry

            if(s_a > (s_b + s_cin)) then
              s_result <= s_a - s_b - s_cin;
              C <= '0';
            else
              s_result <= s_b - s_a - s_cin;
              C <= '1';
            end if;
          when "0100" =>                    --CMP  Compare both values              
            if(s_a > s_b) then
                C <= '0';
                Z <= '0';  
            elsif(s_a = s_b) then
                Z <= '1';
                C <= '0';         
            else
                C <= '1';
                Z <= '1';
            end if;
            s_exempt <= '1';     
          when "0101" =>                    --AND
            s_result <= s_a AND s_b;
            C <= '0';
          when "0110" => Z<= '1';           --OR
            s_result <= s_a OR s_b;
            C <= '0';
          when "0111" =>                    --EXOR
            s_result <= s_a XOR s_b;
            C <= '0';
          when "1000" =>                    --TEST, comparator, flag change ONLY
            if((s_a AND s_b) = "000000000") 
                then
                    C <= '0';
                    Z <= '1';
            else
                C <= '0';
                Z <= '0';
            end if;
          when "1001" =>                    --LSL Left shift
            s_result <= s_a sll 1;
            C <= s_result(8);
          when "1010" =>                    --LSR RIght shift
            C <= s_a(0);
            s_result <= s_a srl 1;
          when "1011" => Z<= '1';           --ROL Rotate Left
            s_result <= s_a sll 1;
            C <= s_result(8);
            s_result(0) <= s_result(8);
          when "1100" => Z<= '1';           --ROR Rotate Right
            C <= s_a(0);
            s_result <= s_a srl 1;
            s_result(0) <= s_a(0);
          when "1101" =>                    --ASR Arithemetic Roation
            C <= s_a(0);
            s_result <= s_a srl 1;
            s_result(8) <= s_a(7);
          when "1110" =>                    --MOV Moves data into result
            s_result <= s_b;
            s_exempt <= '1';
          when others => 
            s_result <= "000000000";
            s_exempt <= '1';
            Z <= '0';
            C <= '0';
        end case;

        if(s_exempt = '0') -- Checks Result for 0 if hasn't been found
            then 
                 if(s_result(7 downto 0) = "00000000") 
                    then 
                        Z <= '1';
                 else Z <= '0';
                 end if;
        end if;

       Result <= std_logic_vector(s_result(7 downto 0)); 

    end process; 

end Behavioral;

TESTBENCH:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity simulation is
end simulation;

architecture Behavioral of simulation is

    COMPONENT ALU
        Port ( 
               A         : in std_logic_vector(7 downto 0);
               B         : in std_logic_vector(7 downto 0);
               SEL        : in std_logic_vector(3 downto 0);
               Cin        : in std_logic;
               Result    : out std_logic_vector(7 downto 0);
               C         : out std_logic;
               Z        : out std_logic
          );
    END COMPONENT;

    signal A : std_logic_vector(7 downto 0) := "00000000";
    signal B : std_logic_vector(7 downto 0) := "00000000";
    signal SEL : std_logic_vector(3 downto 0) := "0000";
    signal Cin : std_logic;
    signal Result : std_logic_vector(7 downto 0) := "00000000";
    signal C: std_logic := '0';
    signal Z: std_logic := '0';

    begin

        uut: ALU PORT MAP (
            A => A,
            B => B,
            SEL => SEL,
            Cin => Cin,
            Result => Result,
            C => C,
            Z => Z
        );

        stim_proc: process
        begin
            A <= "00000001";
            B <= "00100001";
            SEL <= "0000";
            Cin <= '1';
            wait for 10ns;
            wait;
        end process;
end Behavioral;

1 个答案:

答案 0 :(得分:1)

在流程暂停之前,VHDL流程中分配的任何信号都不会更新。因此,例如,此行中s_result的值:

s_result <= s_a + s_b + s_cin;
执行此行时

不会更新:

C <= s_result(8);

您需要了解 delta延迟,然后一旦完成,您将需要重写代码。

VHDL是硬件描述语言。您正在设计硬件,而不是编写软件。例如,您对所有信号的初始化将不会在硬件中实现,这意味着您的模拟可能与您的硬件表现不同:

signal s_result: unsigned(8 downto 0) := "000000000";
signal s_cin: unsigned(8 downto 0) := "000000000";
signal s_a: unsigned(8 downto 0) := "000000000";
signal s_b: unsigned(8 downto 0) := "000000000";
signal s_exempt: std_logic := '0';