【问题标题】:FPGA spartan 3 - X mod 3 inside combinatorial process without clockFPGA spartan 3 - X mod 3 内部没有时钟的组合过程
【发布时间】:2014-10-05 23:00:31
【问题描述】:

我正在开展一个项目,其中一部分围绕着寻找 X mod 3 和 FPGA spartan 3 (Xilinx), 在组合过程中。 事实上,在这个项目中,在这个 ALU 模块之前还有一些其他的模块是顺序的。 但在 ALU 模块内部,不允许使用顺序处理。 所以我尝试使用here中的一种方法:

这是一种简单的手动操作方法。由于 1 = 22 mod 3,我们得到 1 = 每个正整数 22n mod 3。此外 2 = 22n+1 mod 3。 因此,可以通过计数来确定一个整数是否可以被 3 整除 奇数位位置的 1 位,将此数字乘以 2,添加 偶数位位置的 1 位的数量将它们添加到结果中,并且 检查结果是否能被 3 整除。

示例:5710=1110012。奇数位有 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;

【问题讨论】:

    标签: vhdl fpga modelsim xilinx-ise


    【解决方案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 之前)。它们的信号分配 (&lt;=) 将切换为变量分配 (:=)。

    您可以简单地将出现在作业右侧的那些显示在敏感度列表中,但这会导致额外的增量周期。

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

    敏感列表中有一个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;
    

    【讨论】:

    • @David Koontz,您的回答给出了我需要的结果。非常感谢。这真的是一个很大的帮助。顺便说一句,result_tmp 用于我设计的 ALU 中的另一个算术运算。
    • @David Koontz,您能否也举一个简短的例子来将进程分解为多个进程和/或其他并发语句??
    • 请注意,您没有完全覆盖 if 语句条件中的二进制值,这意味着推断锁存器。
    • 我应该怎么做?你的意思是我最好选择 when/case 或 when/select 或者我应该为我的结果分配一个虚拟值并在所有 if 语句的末尾添加一个 else ??
    猜你喜欢
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 2017-10-16
    • 2011-12-14
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多