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