我为斯巴达3E板编写了VGA控制器的VHDL代码.代码模拟并且在没有下面代码中的重置和clk过程的情况下运行良好.但是在插入进程(reset,clk)之后,h_count和v_count计数器停止计数并在模拟中被驱动为未定义的XXXXX.我哪里错了.代码工作完美,没有clk,重置过程(粗体注释),我也测试了harware上的代码.
VGA控制器的代码
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity vga_controller is
port(clk : inout std_logic;
clk_50 : in std_logic;
hsync, vsync : out std_logic;
video_on : out std_logic;
x_pos, y_pos : out std_logic_vector(9 downto 0);
sw : in std_logic_vector(2 downto 0) := "100";
rgb : out std_logic_vector(2 downto 0)
);
end vga_controller;
architecture Behavioral of vga_controller is
signal h_count, v_count : unsigned(9 downto 0) := (others => '0');
begin
-- Frequency divider to get 25 MHz clk from 50 MHz clock of Spartan 3E **
freq_dividr : entity work.t_ff port map(clk_50, clk);
-- If i remove this process everyting works fine. Why ????**
process(clk, reset)
begin
if reset = '1' then
h_count <= (others => '0');
v_count <= (others => '0');
video_on <= '0';
elsif clk'event and clk = '1' then
h_count <= h_count;
v_count <= v_count;
end if;
end process;
process(clk) -- Process for horizontal counter
begin
if clk'event and clk = '1' then
if h_count = 799 then
h_count <= (others => '0');
else
h_count <= h_count + 1;
end if;
end if;
end process;
process(clk) -- Process for vertical counter
begin
if clk'event and clk = '1' and h_count = 799 then
if v_count = 524 and h_count = 799 then
v_count <= (others => '0');
else
v_count <= v_count + 1;
end if;
end if;
end process;
hsync <= '0' when (h_count >= 656 and h_count <= 751) else '1';
vsync <= '0' when (v_count >= 490 and v_count <= 491) else '1';
video_on <= '1' when (h_count <= 649 and v_count <= 479) else '0';
rgb <= sw when (h_count <= 649 and v_count <= 479) else "000";
x_pos <= std_logic_vector(h_count);
y_pos <= std_logic_vector(v_count);
end Behavioral;
Run Code Online (Sandbox Code Playgroud)
son*_*ave 10
您应该只从一个进程驱动信号.只需将您的重置功能放入计数器进程,它就可以正常工作.例如:
process(clk) -- Process for horizontal counter
begin
if(rising_edge(clk)) then
if(rst = '1') then
h_count <= 0;
else
if h_count = 799 then
h_count <= (others => '0');
else
h_count <= h_count + 1;
end if;
end if;
end if;
end process;
Run Code Online (Sandbox Code Playgroud)
其他几点说明:
如您所见,我在上面的代码段中使用了同步重置.除非您绝对需要异步重置,否则请使用同步重置.它有助于合成器,因为有一些使用异步复位不可用的特殊结构,它有助于在设计变大时防止出现问题(并且由于信号偏斜,触发器突然开始在不同时间重置).
此外,不要在时钟进程的初始if语句中检查除边(或重置)之外的任何内容.对于您的垂直计数器,您需要检查h_count = 799.请执行以下操作:
process(clk)
begin
if(rising_edge(clk)) then
if(h_count = 799) then
(...)
Run Code Online (Sandbox Code Playgroud)
它更清晰,而且不容易出错.
作为最后一件事,我已经改变clk'event and clk=1了更现代的方式,rising_edge(clk).它应该没有多大区别(除非在模拟中的某些特定情况下),但rising_edge内置了一些额外的检查以确保您确实有优势.