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