如何添加已在VHDL中串联的两个std_逻辑_向量?

如何添加已在VHDL中串联的两个std_逻辑_向量?,vhdl,hardware,xilinx,hdl,Vhdl,Hardware,Xilinx,Hdl,我正在使用一组特定的函数处理ALU。我想,如果我使用一个额外的位来存储进位,那么加法和位移位部分就会容易得多。我试图将一个额外的位连接到两个8位长的“std_逻辑_向量”。额外的位将在加法中保持进位 然而,当我在一些调试之后运行模拟时,它看起来不像是我用来给s_a和s_b它们的值的行在做任何事情。如果我去掉默认值,它们就会变成空的 我确信这个错误是愚蠢的,我不太熟悉vhdl中的串联工作原理,也许有更好的方法来存储执行,如果有任何帮助,我们将不胜感激 代码: library IEEE; use I

我正在使用一组特定的函数处理ALU。我想,如果我使用一个额外的位来存储进位,那么加法和位移位部分就会容易得多。我试图将一个额外的位连接到两个8位长的“std_逻辑_向量”。额外的位将在加法中保持进位

然而,当我在一些调试之后运行模拟时,它看起来不像是我用来给s_a和s_b它们的值的行在做任何事情。如果我去掉默认值,它们就会变成空的

我确信这个错误是愚蠢的,我不太熟悉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;
试验台:

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;
在VHDL中,在进程挂起之前,不会更新进程中分配的任何信号。因此,例如,s_的值来自这一行:

s_result <= s_a + s_b + s_cin;

并可能使用:=其他=>'0';初始化为零。完全重写代码可能很简单,只需将s_a、s_b赋值移到进程之外,尽管C、Z标志也会出现类似的问题generation@BrianDrummond我本来打算建议把s_a,s_b的任务转移到流程之外,但国旗生成的东西更难改变。还有s_cin,除s_a和s_b外,s_结果和s_豁免。所有依赖于即时更新的变量都可能是进程s1中声明的变量,并且会被夸大为完全重写。
C <= s_result(8);
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';