我让这个alu使用左/右移位功能,并且在rd_data2(16位std_logic_vector)上发送了移位量。但是我被迫将其更改为名为“shift”的4位std_logic_vector,现在它不会再转移了。
这是我的代码。我无法弄清楚我哪里出错了。有什么想法吗?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_unsigned.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity alu_v2 is
Port ( rd_data1 : in STD_LOGIC_VECTOR (15 downto 0);
rd_data2 : in STD_LOGIC_VECTOR (15 downto 0);
alu_mode : in STD_LOGIC_VECTOR (2 downto 0);
result : out STD_LOGIC_VECTOR (15 downto 0);
clk : in std_logic;
shift : in std_logic_vector (3 downto 0);
rst : in STD_LOGIC;
z_flag : out STD_LOGIC;
n_flag : out STD_LOGIC);
end alu_v2;
architecture Behavioral of alu_v2 is
begin
process(rd_data1,rd_data2,alu_mode,rst)
variable temp : STD_LOGIC_VECTOR(15 downto 0):=X"0000";
variable m_temp : std_logic_vector(31 downto 0);
begin
if (rst = '1' ) then
n_flag <= '0';
z_flag <= '0';
result <= X"0000";
else if (rst = '0') then
case alu_mode(2 downto 0) is
when "000" => NULL;
when "001" => temp := rd_data1 + rd_data2 ;
when "010" => temp := rd_data1 - rd_data2 ;
when "011" => m_temp := rd_data1 * rd_data2;
temp := m_temp(15 downto 0);
when "100" => temp := rd_data1 NAND rd_data2 ;
when "101" => temp := std_logic_vector(shift_left(unsigned(rd_data1),to_integer(unsigned(shift))));
when "110" => temp := std_logic_vector(shift_right((unsigned(rd_data1)),to_integer(unsigned(shift))));
when "111" => z_flag <= '0';
n_flag <= '0';
when others => NULL;
end case;
if (temp = X"0000" ) then z_flag <= '1';
n_flag <= '0';
end if;
if (temp(15) = '1' ) then n_flag <= '1';
z_flag <= '0';
else if(temp(15) = '0')and(temp > 0) then n_flag <= '0';
z_flag <= '0';
end if;
end if;
end if;
end if;
result <= temp;
end process;
end Behavioral;
答案 0 :(得分:3)
是的,多方面都有问题。首先,即使你有一个时钟输入端口,你的设计也是异步的。这可能是错的。
您应该具有异步重置的同步过程
main_proc: process(rst, clk)
begin
if rst='1' then
-- reset stuff
elsif rising_edge(clk) then
-- do stuff
end if;
end process;
或 - 优选 - 具有同步重置的同步过程
main_proc: process(clk)
begin
if rising_edge(clk) then
if rst='1' then
-- reset stuff
else
-- do stuff
end if;
end if;
end process;
这样,灵敏度列表中缺少信号就不再是问题了。
其次,你的旗帜设置搞砸了。如果alu_mode(2 downto 0)="111"
您首先设置两个标记,但立即覆盖它们if (temp = x"0000" )
或if (temp(15) = '1' )
。之前没有用它们。
尽量避免使用变量。在这种情况下,您可以通过检测流程语句的零和n-flag 来避免变量。
signal result_int : unsigned(result'range) := (others => '0');
begin
-- main_process
result <= std_logic_vector(result_int);
z_flag <= '1' when to_integer(result_int) = 0 else '0';
n_flag <= result_int(result_int'length-1);
第三个else if
- &gt; elsif
...不需要额外的end if;
...如果您输入if rst='1'
,那么您永远不必关注elsif rst='0'
:当然rst='0'
如果&STD_LOGIC_unsigned
#39;不是&#39; 1&#39; ...
最后,请勿使用NUMERIC_STD
包。它没有标准化。您需要的一切都在process(all)
。
P.S。如果您不想担心敏感度列表中缺少信号,可以使用VHDL-2008方法 select ROWNUM "ID","Netzelementtyp","Projekt_ID","Ticket_ID","Netzelement_Nr","Projektart","Statusliste_Status","Statusliste_Ist_Datum","Statusliste_Plan_Datum","Statusliste_Bemerkung" from
(select t."Netzelementtyp",t."Projekt_ID",t."Ticket_ID",t."Netzelement_Nr",t."Projektart",t."Statusliste_Status",t."Statusliste_Ist_Datum",t."Statusliste_Plan_Datum",t."Statusliste_Bemerkung" from table(
EXCELTABLE.GETROWS(
EXCELTABLE.GETFILE('DOC','TicketTracking2.xlsx')
, 'Page1_4'
, ' "Netzelementtyp" number
, "Projekt_ID" number
, "Ticket_ID" varchar2(100)
, "Netzelement_Nr" NUMBER
, "Projektart" varchar2(1000)
, "Statusliste_Status" varchar2(100)
, "Statusliste_Ist_Datum" DATE
, "Statusliste_Plan_Datum" DATE
, "Statusliste_Bemerkung" varchar2(4000)'
, 'A2'
)
) t)
。这将自动包含所有相关信号。您必须在VHDL-2008模式下进行编译才能使其正常工作。
答案 1 :(得分:2)
您的过程敏感度列表中没有“shift”。