VHDL:如何在进程中使用CLK和重置

VHDL:如何在进程中使用CLK和重置,vhdl,Vhdl,我已经为spartan 3E板的VGA控制器编写了VHDL代码。该代码模拟并运行良好,无需下面代码中的重置和clk过程。但在插入进程(重置、clk)后,h_计数和v_计数计数器停止计数,并被驱动到模拟中未定义的XXXXX。我哪里做错了。该代码在没有clk、reset过程(用粗体注释的过程)的情况下运行良好,我也在harware上测试了该代码 VGA控制器的代码 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;

我已经为spartan 3E板的VGA控制器编写了VHDL代码。该代码模拟并运行良好,无需下面代码中的重置和clk过程。但在插入进程(重置、clk)后,h_计数和v_计数计数器停止计数,并被驱动到模拟中未定义的XXXXX。我哪里做错了。该代码在没有clk、reset过程(用粗体注释的过程)的情况下运行良好,我也在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;
IEEE库;
使用IEEE.STD_LOGIC_1164.ALL;
使用IEEE.NUMERIC_STD.ALL;
实体vga_控制器为
端口(时钟:输入输出标准逻辑;
clk_50:标准逻辑中;
hsync,vsync:输出标准逻辑;
视频开启:输出标准逻辑;
x_pos,y_pos:out标准逻辑向量(9到0);
sw:std_逻辑_向量(2到0):=“100”;
rgb:out标准逻辑向量(2到0)
);
终端控制器;
vga_控制器的结构是
信号h_计数,v_计数:无符号(9到0):=(其他=>'0');
开始
--分频器从Spartan 3E的50 MHz时钟获得25 MHz时钟**
freq_dividr:实体work.t_ff端口图(clk_50,clk);
--如果我删除这个过程,一切正常。为什么**
过程(时钟、复位)
开始
如果重置='1',则
h_计数“0”);
v_计数“0”);

视频\u on您应该只驱动来自一个进程的信号。只要将重置功能放入计数器进程中,它就会工作。例如:

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;
它更清晰,也不容易出错


最后,我将
clk'事件和clk=1更改为更现代的方式,
rissing\u edge(clk)
。它应该不会有太大的区别(除非在模拟中的某些情况下),但是
上升沿
内置了一些额外的检查,以确保您确实有一个边缘。

一个信号不能有多个驱动器。如果没有
(clk,reset)
进程,则
hcount
vcount
信号仅由一个进程驱动。但是,当您添加
(clk,reset)
进程时,它有并发驱动程序。

大多数VHDL书籍只解释语法规则:(.有解决此类实际问题的可靠VHDL书籍吗?您能推荐一本吗?我使用了“使用VHDL的RTL硬件设计”Pong P.Chu previousl:此外,Xilinx有大量白皮书,描述了FPGA使用的各个方面。可以在这里找到:谢谢bhai!(印度的bro))@sonicwave:答案很好-我可以鼓励您编辑它以使用
if rising_edge(clk)然后
而不是显式测试事件和级别-这是更现代的习惯用法。关于异步与同步重置的讨论在这里是离题的。关于这一点存在着广泛的矛盾意见。这个问题与OP的问题无关。大多数VHDL书籍只解释语法规则:(.是否有解决此类实际问题的可靠VHDL书籍?您能推荐一本吗?是的,您可以为一个信号提供多个驱动程序(如果数据类型已解决;这可用于建模三态总线).但是,通常情况下,你不应该有多个驱动程序,因为你不是在尝试对一个三态总线建模。@Philippe:三态信号可以有多个驱动程序,这是对的。但这与OP的问题无关。他的代码中的问题是两个驱动程序驱动相同的(非三态)信号-所以模拟器会把它放在“X”上。请你重新格式化你的代码,这样它就不会每隔一行出现错误了?然后按它应该的方式放缩进!
process(clk)
begin
  if(rising_edge(clk)) then
    if(h_count = 799) then
    (...)