VHDL代码可以在ModelSim中工作,但不能在FPGA上工作

VHDL代码可以在ModelSim中工作,但不能在FPGA上工作,vhdl,Vhdl,我的VHDL代码在功能上是正确的,在ModelSim中,一切都很好。我测试了很多变体,代码在功能上是正确的 但当我把它放在Altera板上时,它在7段显示器上显示3,但它应该显示0。 如果我将“重置”设置为1,它将完全断开,并且在顶部段中仅显示一条线。 我的输入X、CLK、RESET与开关相连。 加载ist连接到按钮,数字连接到7段显示器 当我切换时钟开关时,它应该有一个时钟信号 以下是我的完整代码: LIBRARY ieee; USE ieee.std_logic_1164.all; USE

我的VHDL代码在功能上是正确的,在ModelSim中,一切都很好。我测试了很多变体,代码在功能上是正确的

但当我把它放在Altera板上时,它在7段显示器上显示3,但它应该显示0。 如果我将“重置”设置为1,它将完全断开,并且在顶部段中仅显示一条线。 我的输入X、CLK、RESET与开关相连。 加载ist连接到按钮,数字连接到7段显示器

当我切换时钟开关时,它应该有一个时钟信号

以下是我的完整代码:

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

我想这与计数和计数器有关。 我也应该意识到这是同步的吗? 数字和无符号真的有那么大的问题吗?我们在大学里就是这样做的。 当我把负载放在滑动开关上时,它会工作吗??? 致意
Adrian你的代码有几个问题。顺便说一句,运行模拟并不意味着您的设计是正确的,因为您可以模拟无法在硬件中实现的操作

以下是问题列表:

不能将开关按钮用作时钟信号。按钮不是时钟源!您可以实现一个信号清除电路,至少是一个去抖动电路,这需要另一个时钟,或者使用clk信号作为启用。 此外,如果连接到外部开关按钮或切换按钮,则每个信号都需要去抖动电路,除非测试板上有去抖动按钮。。。 您的状态机有一个正常的init状态,但是您必须将该状态分配给state,而不是next_state。 您的代码使用std_logic_unsigned,这是过时的。计数器信号应使用数字和无符号类型。 您的代码为COUT引入了一个额外的寄存器,这是有意的吗? PISO进程使用异步负载信号,这在假设FPGA为目标设备的硬件中不受支持。 根据您的合成工具,它可能无法识别FSM,因为您的case语句不适合FSM的模式。 FSM故障可能导致出现固定输出模式。如果您的合成器识别FSM,您可以转到状态图并识别假边或假端子状态。 更多

您的7段解码器是一个组合过程。它无法重置。 此外,该过程对CLK不敏感,只是为了对抗。这会导致模拟和硬件之间的不匹配。综合忽略敏感度列表 如果您修复了此问题,您的模拟应该有另一个行为,如果修复了此问题,则可以作为硬件工作:

FSM


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

以下是问题列表:

不能将开关按钮用作时钟信号。按钮不是时钟源!您可以实现一个信号清除电路,至少是一个去抖动电路,这需要另一个时钟,或者使用clk信号作为启用。 此外,如果连接到外部开关按钮或切换按钮,则每个信号都需要去抖动电路,除非测试板上有去抖动按钮。。。 您的状态机有一个正常的init状态,但是您必须将该状态分配给state,而不是next_state。 您的代码使用std_logic_unsigned,这是过时的。计数器信号应使用数字和无符号类型。 您的代码为COUT引入了一个额外的寄存器,这是有意的吗? PISO进程使用异步负载信号,这在假设FPGA为目标设备的硬件中不受支持。 根据您的合成工具,它可能无法识别FSM,因为您的case语句不适合FSM的模式。 FSM故障可能导致出现固定输出模式。如果您的合成器识别FSM,您可以转到状态图并识别假边或假端子状态。 更多

您的7段解码器是一个组合过程。它无法重置。 此外,该过程对CLK不敏感,只是为了对抗。这会导致模拟和硬件之间的不匹配。综合忽略敏感度列表 如果您修复了此问题,您的模拟应该有另一个行为,如果修复了此问题,则可以作为硬件工作:

FSM


Paebbels已经描述了代码的许多问题。还请检查合成工具的警告。它们通常指示合成器实际输出不同于VHDL中描述的逻辑的位置

我怀疑你又犯了两个错误 与VHDL直接相关的ot:

您的7段显示控制线似乎处于低活动状态,因为按“重置”时,您只能看到一个活动段。这与您在本例中通过将计数器重置为000指定的向量1111110中的唯一零相匹配。 但即使在这种情况下,启发的部分应该是在中间而不是在顶部。因此,您的pin分配顺序似乎与此相反。
Paebbels已经描述了代码的许多问题。还请检查合成工具的警告。它们通常指示合成器实际输出不同于VHDL中描述的逻辑的位置

我怀疑您还犯了另外两个与VHDL无关的错误:

您的7段显示控制线似乎处于低活动状态,因为按“重置”时,您只能看到一个活动段。这与您在本例中通过将计数器重置为000指定的向量1111110中的唯一零相匹配。 但即使在这种情况下,启发的部分应该是在中间而不是在顶部。因此,您的pin分配顺序似乎与此相反。

我添加了一个FSM示例,它结合了您的两个进程。我添加了一个FSM示例,它结合了您的两个进程,即我的两个进程STATE_CAL和STATE_Y?有必要问so='1'而不是='0'吗。但再次感谢,我今天的时间有限,但我将在明天试一试,希望明天也能从您那里得到一些反馈。so='0'分支使用默认赋值处理。我会纠正我的复制粘贴错误。VHDL有一个9值逻辑,您不想对每个值进行测试:。好的,我看看明天是否完成,非常感谢。privatemessage不存在堆栈溢出的可能性,或者^^它是否检测到FSM代码模式应该对生成的逻辑没有影响。其他几点更重要,所以+1。好了,现在是同步的,我觉得我的网表看起来不错。FSM也被软件识别,看起来应该是这样的。我在第一篇文章中提出了新版本的代码,并对其提出了一些问题。这就是我的两个过程STATE_CAL和STATE_Y。但是你为什么不考虑ELSIF?有必要问so='1'而不是='0'吗。但再次感谢,我今天的时间有限,但我将在明天试一试,希望明天也能从您那里得到一些反馈。so='0'分支使用默认赋值处理。我会纠正我的复制粘贴错误。VHDL有一个9值逻辑,您不想对每个值进行测试:。好的,我看看明天是否完成,非常感谢。privatemessage不存在堆栈溢出的可能性,或者^^它是否检测到FSM代码模式应该对生成的逻辑没有影响。其他几点更重要,所以+1。好了,现在是同步的,我觉得我的网表看起来不错。FSM也被软件识别,看起来应该是这样的。我在第一篇文章中提出了新版本的代码,并提出了一些问题。我是如何使其处于低活动状态的?通常它应该是高活性的,还是我弄错了?附言:现在正在放映的是中间部分。我刚刚把6降到0变成了0到6。@DaPole然后只分配倒装的位:0000001。是的,我这样做了,现在它在开始时显示了0,这只是一个需要更多知识的问题。我是在决定它是高/低激活状态,还是仅仅是如何控制板?软件还是预定义了其他内容?@DaPole它由您的董事会定义。请看一下董事会手册。在7段显示说明中,应说明控件处于低激活状态。我是如何使其处于低激活状态的?通常它应该是高活性的,还是我弄错了?附言:现在正在放映的是中间部分。我刚刚把6降到0变成了0到6。@DaPole然后只分配倒装的位:0000001。是的,我这样做了,现在它在开始时显示了0,这只是一个需要更多知识的问题。我是在决定它是高/低激活状态,还是仅仅是如何控制板?软件还是预定义了其他内容?@DaPole它由您的董事会定义。请看一下董事会手册。在7段显示说明中,应说明控件处于低激活状态。
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;