VHDL shift_left / shift_right停止工作

时间:2018-02-21 11:09:32

标签: vhdl bit-shift

我让这个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;

2 个答案:

答案 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”。