繁体   English   中英

VHDL代码可在ModelSim中使用,但不能在FPGA上使用

[英]VHDL code works in ModelSim but not on FPGA

我的VHDL代码功能正确,在ModelSim中一切正常。 我测试了许多变体,并且代码在功能上是正确的。

但是,当我将其放在Altera板上时,它在7段显示器上显示为“ 3”,但应该显示为“ 0”。 如果我将RESET设置为“ 1”,它将完全中断,并且仅在顶部显示一行。 我的输入X,CLK,RESET连接到开关。 LOAD ist连接到按钮,DIGIT连接到7段显示器。

当我旋转CLK开关时,它应该有一个时钟信号。

这是我的完整代码:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY seqdec IS
PORT    (   X:          IN      std_logic_vector(15 DOWNTO 0);
            CLK:        IN      std_logic;
            RESET:  IN      std_logic;
            LOAD:       IN      std_logic;
            DIGIT:  OUT std_logic_vector(6 DOWNTO 0) := "1111110";
            Y:          OUT std_logic);
END seqdec;

ARCHITECTURE SEQ OF seqdec IS
TYPE        statetype IS (s0, s1, s2, s3, s4);
SIGNAL  state: statetype:=s0;
SIGNAL  next_state: statetype;
SIGNAL  counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL  temp:   std_logic_vector(15 DOWNTO 0):= (OTHERS => '0');
SIGNAL  so:     std_logic := 'U';

-------------------Aktualisierung des Zustandes--------------------------------
    BEGIN
    STATE_AKT: PROCESS (CLK, RESET)
        BEGIN   
            IF RESET = '1' THEN     
                state <= s0;
            ELSIF CLK = '1' AND CLK'event THEN
                state <= next_state ;
            END IF;
        END PROCESS STATE_AKT;

---------------------Counter---------------------------------------------------
    COUNT:  PROCESS (state, RESET)
        BEGIN   
            IF (RESET = '1') THEN   
                counter <= (OTHERS => '0');
            ELSIF (state = s4) THEN
                counter <= counter + '1';
            END IF;
    END PROCESS COUNT;

-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
    PISO:       PROCESS (CLK, LOAD, X)
        BEGIN
            IF (LOAD = '1') THEN
                temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
            ELSIF (CLK'event and CLK='1') THEN
                so <= temp(15);
                temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
                temp(0) <= '0';
            END IF;
        END PROCESS PISO;

-------------------Zustandsabfrage und Berechnung------------------------------
    STATE_CAL: PROCESS (so,state)
        BEGIN

            next_state <= state;
            Y <= '0';

            CASE state IS
                WHEN s0 =>  
                    IF so = '1' THEN 
                        next_state <= s0  ;
                    END IF;

                WHEN s1 =>  
                    IF so = '1' THEN 
                        next_state <= s1;
                    END IF;

                WHEN s2 =>  
                    IF so = '0' THEN 
                        next_state <= s3 ;
                    END IF;

                WHEN s3 =>  
                    IF so = '0' THEN 
                        next_state <= s0 ;
                    ELSE
                        next_state <= s4 ;
                    END IF;

                WHEN s4 =>  
                    Y <= '1';
                    IF so = '0' THEN 
                        next_state <= s0;
                    ELSE
                        next_state <= s2 ;
                    END IF;

                WHEN OTHERS => NULL;
            END CASE;
        END PROCESS STATE_CAL;

-------------------7 Segment---------------------------------------------------
    SEVEN_SEG: PROCESS (counter)
        BEGIN
            CASE counter IS
                WHEN "000" => DIGIT <= "1111110";
                WHEN "001" => DIGIT <= "0110000";
                WHEN "010" => DIGIT <= "1101101";
                WHEN "011" => DIGIT <= "1111001";
                WHEN "100" => DIGIT <= "0110011";
                WHEN "101" => DIGIT <= "1011011";
                WHEN OTHERS => NULL;
            END CASE;
        END PROCESS SEVEN_SEG;


END SEQ;

我已经对VHDL感到陌生,并且可以肯定它必须在时间上做些什么,因为功能部分应该不错,如前所述。

希望有一些提示,技巧甚至解决方案。

编辑:没有加载的新代码,这是一个有效的主意吗? (除非整个代码在FPGA上不起作用。...)

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY seqdec IS
PORT    (   X:          IN      std_logic_vector(15 DOWNTO 0);
            CLK:        IN      std_logic;
            RESET:  IN      std_logic;
            LOAD:       IN      std_logic;
            DIGIT:  OUT std_logic_vector(0 TO 6) := "0000001";
            Y:          OUT std_logic);
END seqdec;

ARCHITECTURE SEQ OF seqdec IS
TYPE        statetype IS (s0, s1, s2, s3, s4);
SIGNAL  state: statetype:=s0;
SIGNAL  next_state: statetype;
SIGNAL  counter: std_logic_vector(2 DOWNTO 0) :="000" ;
SIGNAL  temp:   std_logic_vector(15 DOWNTO 0):= (OTHERS => '0');
SIGNAL  so:     std_logic := 'U';

-------------------Aktualisierung des Zustandes--------------------------------
    BEGIN
    STATE_AKT: PROCESS (CLK, RESET)
        BEGIN   
            IF RESET = '1' THEN     
                state <= s0;
            ELSIF CLK = '1' AND CLK'event THEN
                state <= next_state ;
            END IF;
        END PROCESS STATE_AKT;

---------------------Counter---------------------------------------------------
    COUNT:  PROCESS (state, RESET)
        BEGIN   
            IF (RESET = '1') THEN   
                counter <= (OTHERS => '0');
            ELSIF (state = s4) THEN
                counter <= counter + '1'; 
            END IF;
    END PROCESS COUNT;

-------------------PiSo für die Eingabe des zu Prüfenden Vektors---------------
    PISO:       PROCESS (CLK, LOAD, X)
        BEGIN
            IF (CLK'event and CLK='1') THEN 
                IF (LOAD = '1') THEN 
                    temp(15 DOWNTO 0) <= X(15 DOWNTO 0);
                ELSE
                    so <= temp(15);
                    temp(15 DOWNTO 1) <= temp(14 DOWNTO 0);
                    temp(0) <= '0';
                END IF;
            END IF;
        END PROCESS PISO;

-------------------Zustandsabfrage und Berechnung------------------------------
    STATE_CAL: PROCESS (so,state)
        BEGIN

            next_state <= state;
            Y <= '0';

            CASE state IS
                WHEN s0 =>  
                    IF so = '1' THEN 
                        next_state <= s1  ;
                    END IF;

                WHEN s1 =>  
                    IF so = '1' THEN 
                        next_state <= s2;
                    END IF;

                WHEN s2 =>  
                    IF so = '0' THEN 
                        next_state <= s3 ;
                    END IF;

                WHEN s3 =>  
                    IF so = '0' THEN 
                        next_state <= s0 ;
                    ELSE
                        next_state <= s4 ;
                    END IF;

                WHEN s4 =>  
                    Y <= '1';
                    IF so = '0' THEN 
                        next_state <= s0;
                    ELSE
                        next_state <= s2 ;
                    END IF;

                WHEN OTHERS => NULL;
            END CASE;
        END PROCESS STATE_CAL;

-------------------7 Segment---------------------------------------------------
    SEVEN_SEG: PROCESS (counter)
        BEGIN
            CASE counter IS
                WHEN "000" => DIGIT <= "0000001";
                WHEN "001" => DIGIT <= "1001111";
                WHEN "010" => DIGIT <= "0010010";
                WHEN "011" => DIGIT <= "0000110";
                WHEN "100" => DIGIT <= "1001100";
                WHEN "101" => DIGIT <= "0100100";
                WHEN OTHERS => DIGIT <= "0000001";
            END CASE;
        END PROCESS SEVEN_SEG;


END SEQ;

编辑:这是我的版本。 无论我做什么,它仍将显示为“ 0”。

  • 我认为这与COUNT和counter有关。
  • 我也应该意识到这是同步的吗?
  • 数字和无符号真的是个大问题吗? 我们是在大学里那样做的。
  • 当我将LOAD放到滑动开关上时,它将起作用吗???

最好的问候阿德里安

您的代码有几个问题。 顺便说一句。 运行中的仿真并不意味着您的设计是正确的,因为您可以仿真无法在硬件中实现的动作。

这里是问题列表:

  • 您不能将开关按钮用作时钟信号。 按钮不是时钟源! 您可以实施信号清除电路(至少是去抖动电路,这需要另一个时钟),或者将clk信号用作使能信号。
  • 此外,如果您的每个信号连接到外部开关按钮或切换按钮,则都需要一个去抖动电路,除非您的测试板具有去抖动的按钮...
  • 您的状态机具有初始化状态(可以),但是您必须将状态分配给state而不是next_state
  • 您的代码使用的std_logic_unsigned已过时。 您应将numeric_stdunsigned类型用作counter信号。
  • 您的代码为此引入了一个额外的COUT寄存器吗?
  • 您的PISO进程使用异步LOAD信号,硬件不支持此信号(假设以FPGA作为目标设备)。
  • 根据您的综合工具,它可能无法识别FSM,因为您的case语句不适合FSM的模式。
  • FSM故障可能导致看到固定的输出模式。 如果合成器识别出FSM,则可以转到状态图并识别错误的边沿或错误的终端状态。

更多 ...

  • 您的7段解码器是一个组合过程。 无法重置。
  • 此外,此过程对CLK不敏感,仅对counter敏感。 这会导致仿真和硬件之间的不匹配。 (综合忽略灵敏度列表)

如果您修复此错误,则模拟应具有其他行为,如果已修复,则可以作为硬件工作:)。

FSM

STATE_CAL : process(state, so)
begin
  -- Standardzuweisungen
  next_state  <= state;  -- Bleib im Zustand falls in CASE nichts abweichendes bestimmt wird
  Y <= '0';

  -- Zustandswechsel
  CASE state IS
    WHEN s0 =>
      IF (so = '1' THEN 
        next_state <= s1;
      END IF;

     WHEN s1 =>
       IF (so = '1') THEN
         next_state <= s2;
       END IF;

     WHEN s2 =>
       IF (so = '0') THEN
         next_state <= s3;
       END IF;

     WHEN s3 =>
       IF (so = '0') THEN
         next_state <= s0;
       else
         next_state <= s4;
       END IF;

     WHEN s4 =>
       Y <= '1'; -- Moore-Ausgabe
       IF (so = '0') THEN
         next_state <= s0;
       else
         next_state <= s2;
       END IF;

  END CASE;
END PROCESS;

Paebbels已经描述了您的代码的许多问题。 请同时检查综合工具的警告。 它们通常指示合成器实际在何处输出与您在VHDL中描述的逻辑不同的逻辑。

我怀疑您犯了另外两个与VHDL不直接相关的错误:

  • 您的7段显示控制行似乎处于低激活状态,因为当您按RESET时,您只能看到一个活动段。 这与您在这种情况下分配的向量"1111110"唯一的零匹配(通过将counter "1111110""000" )。
  • 但是即使在这种情况下,被启发的部分也应该位于中间而不是顶部。 因此,您的针脚分配似乎是相反的顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM