2012-04-03 3 views
5

나는 스파르탄 3E 보드 용 VGA 컨트롤러 용 VHDL 코드를 작성했습니다. 이 코드는 아래 코드에서 리셋 및 clk 프로세스없이 원활하게 시뮬레이션되고 작동합니다. 그러나 프로세스 (reset, clk)를 삽입 한 후 h_count 및 v_count 카운터는 계산을 중지하고 시뮬레이션에서 정의되지 않은 XXXXX로 구동됩니다. 나는 어디로 잘못 가고있어. 이 코드는 clk, reset 프로세스 (굵게 표시된 주석 처리)없이 완벽하게 작동합니다. 또한 코드를 harware에서도 테스트했습니다.VHDL : 과정에서 CLK 및 RESET 사용 방법

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; 
+1

코드를 다시 포맷하여 다른 모든 라인이 일치하지 않도록 할 수 있습니까? 들여 쓰기를해야합니다! –

답변

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; 

다른 몇 가지주의 사항 : 예를 들어

당신이 볼 수 있듯이, 나는 위의 코드에서 동기식 리셋을 사용했습니다. 비동기식 재설정이 절대적으로 필요한 경우가 아니면 동기식 재설정을 사용하십시오. 비동기 리셋을 사용하여 사용할 수없는 특수한 구조가 있기 때문에 신디사이저의 도움이됩니다. 설계가 커지면 문제를 예방할 수 있습니다 (또한 신호 왜곡으로 인해 플립 플롭이 갑자기 다른 시간에 재설정되기 시작합니다).

또한 클록 된 프로세스의 초기 if 문에서 에지 이외의 항목을 확인하지 마십시오.

process(clk) 
begin 
    if(rising_edge(clk)) then 
    if(h_count = 799) then 
    (...) 

훨씬 선명하고 오류에 관해서는 경향이 아니다 : 당신의 수직 카운터 위해 당신은 = 799가 대신 다음을 수행 h_count에 대한 검사를해야합니다.

마지막으로, clk'event and clk=1을보다 현대적인 방법으로 변경했습니다 (rising_edge(clk)). 시뮬레이션에서 특정 Cicomstances가 아니라면 큰 차이가 없어야하지만, rising_edge에는 몇 가지 추가 검사가 내장되어 실제로 가장자리가 있는지 확인합니다.

+0

대부분의 VHDL 서적은 구문 규칙 만 설명합니다 :(. 이러한 실용적인 문제를 해결할 수있는 견고한 VHDL 서적이 있습니까? 하나 제안 해 주시겠습니까? – Sumanth

+0

Pong P. Chu의 "VHDL을 사용한 RTL 하드웨어 설계"를 사용했습니다. 이전 : http://www.amazon.com/RTL-Hardware-Design-Using-VHDL/dp/0471720925 또한 자일링스는 FPGA 사용의 다양한 측면을 설명하는 많은 백서를 보유하고 있으며, 여기에 : http://www.xilinx.com/support/documentation/white_papers.htm – sonicwave

+0

감사합니다 bhai! (힌디어 (인도) 형제) – Sumanth

0

하나의 신호에 대해 여러 드라이버를 사용할 수 없습니다. (clk, reset) 프로세스가없는 경우 hcountvcount 신호는 각각 하나의 프로세스에 의해 구동됩니다. 그러나 (clk, reset) 프로세스를 추가하면 동시 드라이버가 있습니다.

+0

대부분의 VHDL 서적은 구문 규칙 만 설명합니다 : (.) ​​이런 실질적인 문제를 해결하는 견고한 VHDL 서적이 있습니까? 하나만 제안 해 주시겠습니까? – Sumanth

+1

예, 하나의 신호에 대해 여러 개의 드라이버가있을 수 있습니다 (데이터 유형이 해결 된 경우). 이것은 tri-state 버스를 모델링하는 데 사용될 수 있습니다.)하지만 tri-state 버스를 모델링하려고하지 않기 때문에 대개 여러 개의 드라이버를 사용할 필요가 없습니다. – Philippe

+0

@Philippe : 운전자가 두 명 이상인데 OP의 문제와 관련이 없다. 그의 코드에서 문제는 두 명의 운전자가 동일한 (비 삼중) 신호를 구동한다는 것이다. 그래서 시뮬레이터는이를 'X'에 놓을 것이다. – bmk