2014-10-05 20 views
1

我正在研究一个项目,其中一部分围绕在组合过程中寻找X mod 3和FPGA spartan 3(Xilinx), 。实际上在这个项目中有一些其他的模块,它们在这个ALU模块之前是顺序的。 但在ALU模块内部,不允许使用顺序过程。 所以我试图从here使用一种方法:FPGA spartan 3 - X mod 3在无时钟的组合过程中

这是一个简单的方法来做手工。由于1 = 22模3,因此对于每个正整数我们得到1 = 22n模3。此外,2 = 22n + 1 mod 3 因此,可以通过在奇数位位置计数1位来计算整数是否能被3整除,将该数字乘以2,在偶数位位置处添加1位数的 它们添加到结果和 检查如果结果是被3整除

实施例:57 10 = 。在奇数位置有2位,在偶数位置有2位 。 2 * 2 + 2 = 6可以被3整除。因此,57是可以被3整除的 。

我已经在那里发布了我的代码。问题是,在我串接奇数位,并在两个不同的信号偶数位:

 mod_un_t1 <= A(6) & A(4)& A(2) & A(0); 
     mod_un_t2 <= A(7) & A(5)& A(3) & A(1); 

我失去所有的数据,并没有if语句之后的作品。我用一个测试台模拟了我的代码。但它总是给:

result <= "00000000"; 

我已经测试过它,我发现没有数据将是拼接后传递下去。 我不能使用顺序网络和计数和倒计数方法,或移位寄存器方法,它们都与clk和顺序过程一起工作。

可以在任何一个请帮助我,在我的代码来解决问题,如果任何人有一个更好的方法或更好的实现方式让我通过这个无处!

,这是我的代码:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
Use Ieee.std_logic_unsigned.all; 

entity ALU is 
    port (A   : in std_logic_vector (7 downto 0); -- Input A 
      B   : in std_logic_vector (7 downto 0); -- Input B 
      FN   : in std_logic_vector (3 downto 0); -- ALU functions provided by the ALU_Controller (see the lab manual) 
      result  : out std_logic_vector (7 downto 0); -- ALU output (unsigned binary) 
      overflow : out std_logic;      -- '1' if overflow ocurres, '0' otherwise 
      sign  : out std_logic      -- '1' if the result is a negative value, '0' otherwise 
     ); 
end ALU; 

architecture behavioral of ALU is 

signal mod_un_t1: std_logic_vector (3 downto 0); 
signal mod_un_t2: std_logic_vector (3 downto 0); 
signal mod_un_t3: std_logic_vector (3 downto 0); 
signal mod_un_t4: std_logic_vector (3 downto 0); 
signal mod_unsigned: std_logic_vector (3 downto 0); 

signal mod_si_t1: std_logic_vector (3 downto 0); 
signal mod_si_t2: std_logic_vector (3 downto 0); 
signal mod_si_t3: std_logic_vector (3 downto 0); 
signal mod_si_t4: std_logic_vector (3 downto 0); 
signal mod_signed: std_logic_vector (3 downto 0); 

begin 
    process (FN, A, B , result_tmp) 
    begin 
     result <= (others => '0'); 
     mod_un_t1 <= (others => '0'); 
     mod_un_t2 <= (others => '0'); 
     mod_un_t3 <= (others => '0'); 
     mod_un_t4 <= (others => '0'); 
     mod_unsigned <= (others => '0'); 
     mod_si_t1 <= (others => '0'); 
     mod_si_t2 <= (others => '0'); 
     mod_si_t3 <= (others => '0'); 
     mod_si_t4 <= (others => '0'); 
     mod_signed <= (others => '0'); 

     if (FN = "0100") then -- Unsigned (A) mod 3 
      mod_un_t1 <= A(6) & A(4)& A(2) & A(0); 
      mod_un_t2 <= A(7) & A(5)& A(3) & A(1); 

      if(mod_un_t1= "1111") then 
       mod_un_t3 <= "1000"; 
      elsif(mod_un_t1 = "1110" or mod_un_t1 = "1101" or mod_un_t1 = "1011" or mod_un_t1 = "0111") then 
       mod_un_t3 <= "0110"; 
      elsif(mod_un_t1 = "1100" or mod_un_t1 = "1010" or mod_un_t1 = "1001" or mod_un_t1 = "0110" or mod_un_t1 = "0101" or mod_un_t1 = "0011") then 
       mod_un_t3 <= "0100"; 
      elsif(mod_un_t1 = "0001" or mod_un_t1 = "0010" or mod_un_t1 = "0100" or mod_un_t1 = "1000") then 
       mod_un_t3 <= "0010"; 
      elsif (mod_un_t1 = "0000") then 
       mod_un_t3 <= "0000"; 
      end if; 

      if (mod_un_t2 = "1111") then 
       mod_un_t4 <= "0100"; 
      elsif (mod_un_t2 = "1110" or mod_un_t2 = "1101" or mod_un_t2 = "1011" or mod_un_t2 = "0111") then 
       mod_un_t4 <= "0011"; 
      elsif(mod_un_t2 = "1100" or mod_un_t2 = "1010" or mod_un_t2 = "1001" or mod_un_t2 = "0110" or mod_un_t2 = "0101" or mod_un_t2 = "0011") then 
       mod_un_t4 <= "0010"; 
      elsif(mod_un_t2 = "0001" or mod_un_t2 = "0010" or mod_un_t2 = "0100" or mod_un_t2 = "1000") then 
       mod_un_t4 <= "0001"; 
      elsif(mod_un_t2 = "0000") then 
       mod_un_t4 <= "0000"; 
      end if; 

      mod_unsigned <= mod_un_t3 + mod_un_t4; 

      if (mod_unsigned = "0010" or mod_unsigned = "0101" or mod_unsigned ="0111" or mod_unsigned = "1010") then 
       result <= "00000001"; 
      elsif (mod_unsigned = "0001" or mod_unsigned = "0100" or mod_unsigned = "1000" or mod_unsigned = "1011") then 
       result <= "00000010"; 
      elsif (mod_unsigned = "0000" or mod_unsigned = "0011" or mod_unsigned = "0110" or mod_unsigned = "1001") then 
       result <= "00000000"; 
      end if; 
     end if; 

    end process; 
end behavioral; 

回答

1

,似乎并没有把作业从工艺灵敏度列表中缺少的信号。否则它们可能是变量,允许在当前模拟周期内使用它们而不产生增量循环,因为信号分配直到结束或当前模拟周期才生效。

候选人变量似乎是:

signal mod_un_t1: std_logic_vector (3 downto 0); 
signal mod_un_t2: std_logic_vector (3 downto 0); 
signal mod_un_t3: std_logic_vector (3 downto 0); 
signal mod_un_t4: std_logic_vector (3 downto 0); 
signal mod_unsigned: std_logic_vector (3 downto 0); 

signal mod_si_t1: std_logic_vector (3 downto 0); 
signal mod_si_t2: std_logic_vector (3 downto 0); 
signal mod_si_t3: std_logic_vector (3 downto 0); 
signal mod_si_t4: std_logic_vector (3 downto 0); 
signal mod_signed: std_logic_vector (3 downto 0); 

这些声明可以改变对象类变量并移动到处理(begin之前)。它们的信号分配(<=)将切换到变量分配(:=)。

您可以简单地将那些出现在灵敏度列表中的赋值右侧,但这会导致额外的增量循环。

如果有理由让他们保持信号,您可以考虑将您的流程分为多个流程和/或其他并发语句。

灵敏度列表中有一个result_tmp,在您显示的代码中没有声明或赋值。

...你能举个简单的例子把流程分成多个流程和/或其他并发语句吗?

Aarchitecture foo of ALU is 

    signal mod_un_t1: std_logic_vector (3 downto 0); 
    signal mod_un_t2: std_logic_vector (3 downto 0); 
    signal mod_un_t3: std_logic_vector (3 downto 0); 
    signal mod_un_t4: std_logic_vector (3 downto 0); 
    signal mod_unsigned: std_logic_vector (3 downto 0); 

    signal mod_si_t1: std_logic_vector (3 downto 0); 
    signal mod_si_t2: std_logic_vector (3 downto 0); 
    signal mod_si_t3: std_logic_vector (3 downto 0); 
    signal mod_si_t4: std_logic_vector (3 downto 0); 
    signal mod_signed: std_logic_vector (3 downto 0); 
    -- dummy 
    signal result_tmp: std_logic_vector(7 downto 0); 

begin 

    -- Concurrent signal assignments - these are just wires 
    mod_un_t1 <= A(6) & A(4)& A(2) & A(0); 
    mod_un_t2 <= A(7) & A(5)& A(3) & A(1); 

UNPROC1: 
    process (FN, mod_un_t1) 
    begin 
    if FN = "0100" then 
     case mod_un_t1 is 
      when "0000" => 
       mod_un_t3 <= "0000"; 
      when "0001" | "0010" | "0100" | "1000" => 
       mod_un_t3 <= "0010"; 
      when "1100" | "1010" | "1001" | "0110" => 
       mod_un_t3 <= "0100"; 
      when "1110" | "1101" | "1011" | "0111" => 
       mod_un_t3 <= "0100"; 
      when others => 
      end case; 
    else 
    -- 
    end if; 
end process; 

UNPROC2: 
    process (FN, mod_un_t2) 
    begin 
    if FN = "0100" then 
     if mod_un_t2 = "1111" then 
      mod_un_t4 <= "0100"; 
     elsif mod_un_t2 = "1110" or mod_un_t2 = "1101" or mod_un_t2 = "1011" or mod_un_t2 = "0111" then 
      mod_un_t4 <= "0011"; 
     elsif mod_un_t2 = "1100" or mod_un_t2 = "1010" or mod_un_t2 = "1001" or mod_un_t2 = "0110" or mod_un_t2 = "0101" or mod_un_t2 = "0011" then 
      mod_un_t4 <= "0010"; 
     elsif mod_un_t2 = "0001" or mod_un_t2 = "0010" or mod_un_t2 = "0100" or mod_un_t2 = "1000" then 
      mod_un_t4 <= "0001"; 
     elsif mod_un_t2 = "0000" then 
      mod_un_t4 <= "0000"; 
     end if; 
    else 
     -- 
    end if; 
end process; 

ALU_PROC: -- keep all the arithemetic operations in one process 
    process (FN, mod_un_t3, mod_un_t4) 
    begin 
     if FN = "0100" then 
      mod_unsigned <= mod_un_t3 + mod_un_t4; 
     else 

     end if; 
    end process; 

OUT_PROC: -- keep all the result assignment in one process 
process (FN, mod_unsigned) 
    begin 
     if FN = "0100" then 
      if mod_unsigned = "0010" or mod_unsigned = "0101" or mod_unsigned ="0111" or mod_unsigned = "1010" then 
       result <= "00000001"; 
      elsif mod_unsigned = "0001" or mod_unsigned = "0100" or mod_unsigned = "1000" or mod_unsigned = "1011" then 
       result <= "00000010"; 
      elsif mod_unsigned = "0000" or mod_unsigned = "0011" or mod_unsigned = "0110" or mod_unsigned = "1001" then 
       result <= "00000000"; 
      else 
      -- 
      end if; 
     end if; 
    end process; 

end architecture foo; 
+0

@戴维·孔茨,你的回答给了想象中的那么我需要的结果。非常感谢。这真的是一个很大的帮助。顺便说一句,result_tmp用于我设计的ALU中的另一个算术运算。 – MAP 2014-10-06 03:55:40

+0

@David Koontz,你能不能请一个简短的例子把进程分解成多个进程和/或其他并发语句? – MAP 2014-10-06 03:59:28

+0

请注意,if语句条件中的二进制值没有完全覆盖,这意味着推断的锁存器。 – user1155120 2014-10-06 05:19:15