Vhdl 为什么我的输出是间歇性的?

Vhdl 为什么我的输出是间歇性的?,vhdl,fpga,Vhdl,Fpga,我最近得到了Altera DE0纳米板,并成功地实现了计数器和状态机等基本功能。我现在正试图在棋盘的内置LED上实现一个1D游戏,它工作正常,但有一个问题 我希望游戏状态以1Hz或任意快的速度更新,这个程序就是这么做的,只是它也以相同的频率闪烁LED,所以LED在显示下一个状态之前会空白半秒。我不知道代码有什么问题,但我怀疑是我处理1Hz时钟边缘的方式导致了这个问题 以下是代码的当前版本: ---------------------------------- -- Library De

我最近得到了Altera DE0纳米板,并成功地实现了计数器和状态机等基本功能。我现在正试图在棋盘的内置LED上实现一个1D游戏,它工作正常,但有一个问题

我希望游戏状态以1Hz或任意快的速度更新,这个程序就是这么做的,只是它也以相同的频率闪烁LED,所以LED在显示下一个状态之前会空白半秒。我不知道代码有什么问题,但我怀疑是我处理1Hz时钟边缘的方式导致了这个问题

以下是代码的当前版本:

----------------------------------
--      Library Declaration     --
----------------------------------
-- Like any other programming language, we should declare libraries

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

----------------------------------
--      Entity Declaration      --
----------------------------------
-- Here we specify all input/output ports

entity blinking_led is
    port(
        clk_50mhz : in std_logic ;
        reset_btn : in std_logic;
        green_leds : out unsigned(7 downto 0) := "11111111"
    );
end entity;

----------------------------------
--  Architecture Declaration    --
----------------------------------
--  here we put the description code of the design

architecture behave of blinking_led is

-- signal declaration

constant CLK_SPD : integer := 50000000;
constant N : integer := 8;

signal LED_init : unsigned(7 downto 0) := "00100100"; 
signal clk_1hz : std_logic ;
signal scaler : integer range 0 to 25000000 ;
signal out_register : unsigned(7 downto 0) := LED_init;
signal out_register_old : unsigned(7 downto 0) := "00000000";

begin

-- this process is used to scale down the 50mhz frequency
-- In reality, clk_1hz is not periodic but i used it to get 2 clock cycle by second ( 2 rising edge ).
-- 50 mhz means 50 000 000 cycle in one second : 
-- by using the scaler , i will have 2 cycle by second so that led will be on 1/2 s and off 1/2 s

    clk_1hz_process : process( clk_50mhz , reset_btn )
    begin
        if (reset_btn = '0') then 
            clk_1hz <= '0';
            scaler <= 0;
        elsif(rising_edge(clk_50mhz)) then 
            if (scaler < CLK_SPD/2) then 
                scaler <= scaler + 1 ;
                clk_1hz <= '0';
            else
                scaler <= 0;
                clk_1hz <= '1';
            end if;
        end if;
    end process clk_1hz_process;

    next_gen : process (clk_1hz,reset_btn, out_register, out_register_old)
    variable neighbours : std_logic_vector(1 downto 0);
    variable rand_temp : std_logic_vector(N-1 downto 0) := (N-1 => '1',others => '0');
    variable temp : std_logic := '0'; --(others => '0');

    begin
        --green_leds <= LED_init;
        if (reset_btn = '0') then 
            --green_leds <= LED_init;
            elsif clk_1hz'event and clk_1hz = '1' then

                out_register_old <= out_register;

                --Game rules:
                --Cells are connected on a N-entry long ring, so the first entry has its last as a neighbor and v/v
                --0 neighbors: no action
                --1 neighbor:  cell is born/stays alive
                --2 neighbors: cell dies

                for I in 0 to (N-1) loop
                    if(I = 0) then
                        neighbours := out_register_old(N-1) & out_register_old(I+1);
                    elsif(I > 0 and I < (N-1)) then
                        neighbours := out_register_old(I-1) & out_register_old(I+1);
                    elsif(I = N-1) then
                        neighbours := out_register_old(I-1) & out_register_old(0);
                    end if;

                    case neighbours is 
                        when "00" => out_register(I) <= out_register_old(I);
                        when "01" => out_register(I) <= '1';
                        when "10" => out_register(I) <= '1';
                        when "11" => out_register(I) <= '0';
                        when others => report "unreachable" severity failure;
                    end case;
                end loop;

                --PRNG for game reset logic 
                temp := rand_temp(N-1) xor rand_temp(N-2);
                rand_temp(N-1 downto 1) := rand_temp(N-2 downto 0);
                rand_temp(0) := temp;
--                  
--              if(out_register = 0) then
--                  --reset to random vector
--                  --out_register <= unsigned(rand_temp);
--                  out_register <= LED_init;
--              end if; 
--              
--              if(out_register = out_register_old) then 
--                  --stalemate, prepare to reset
--                  out_register <= "00000000"; 
--              end if;
--              
            end if;     
            green_leds <= out_register;
    end process next_gen;

    end behave;

我对我的VHDL已经生疏了,所以非常感谢您的帮助

据我所知,clk_1hz实际上在一秒内有两个高脉冲
   green_leds <= out_register;

似乎位于错误的位置。

虽然它可能工作,但不应使用派生信号作为时钟,而应使用clk_50mhz至out,并使用clk_1hz作为选通信号。此外,在clk_1hz_过程中异步使用重置_btn一次,在下一代中同步使用重置_btn一次,这也可能导致一些有趣的效果

next_gen : process 
-- ...
begin
    if(rising_edge(clk_50mhz)) then 
        if (reset_btn = '0') or (out_register = 0) then 
            -- synchronous reset and check for empty state in one
            out_register <= ...;
        elsif (clk_1hz = '1') then
             -- the main logic here
            out_register <= ...;
        else
            -- nothing happens here
        end if;
    end if;
end process;

-- output assignment
green_leds  <= out_register;

但最重要的是,你试图在同一个循环中使用out_register_old,你也将其分配出去,我不知道什么是生活的游戏,所以我不确定这应该如何表现。然而,在我看来,您可能误解了信号和变量之间的区别,并且out_register_hold应该是一个变量,或者不完全使用。