2015-12-10 2 views
0

Я реализую аналоговые часы, которые будут отображать часовую и минутную стрелку на экране VGA 640x480 с тактовой частотой с разрешением 480x480. Часы будут обновляться раз в минуту. Временная диаграмма ниже показывает время для HSYNC и VSYNC и их положение относительно часов с частотой 26,25 МГц.Логика для FPGA для вывода аналоговых часов на экране VGA

Это мой первый курс в VHDL, Я хочу знать, что мне не хватает в clock.vhd и как эффективно писать испытательный стенд таким образом я могу получить выход

Timing Diagram

I есть отдельный компонент, называемый counter.vhd, который дважды создается в clock.vhd, один - как горизонтальный счетчик, а другой - как вертикальный счетчик.

Вот мой код для counter.vhd, clock.vhd и моего testbench, который не является полным.

Counter.vhd

entity counter is 
Port (clk : STD_LOGIC; 
     reset : STD_LOGIC; 
         ena : STD_LOGIC; 
         rollover_out : STD_LOGIC; 
         address : STD_LOGIC_VECTOR(7 downto 0); 
         sync : STD_LOGIC 
        ); 

-- Generics 
generic (count_value :=800; 
        sync_start :=10; 
        sync_end :=20 
        ); 
end counter; 

architecture Behavioral of counter is 

signal temp : STD_LOGIC_VECTOR(9 downto 0); -- counts to 800 

process (clk, reset) 
    if (reset = 0) then 
    temp <="000000"; 
    sync <='1'; 
    rollover_out <='0'; 
    else (clk'event & clk = 1); 
    rollover_out <='0'; 
    temp <= temp+"000000"; 
      if (temp = count_value - 1) then 
      temp <="000000" 
      rollover_out <= '1'; 
      end if; 
      if (sync_start = temp) then 
      sync <= '0'; 
      end if; 
      if (sync_end = temp) then 
      sync <= '1'; 
      end if; 
    end if; 
end process; 

address <= temp (8 downto 1); 

begin 
    -- 800 horizontal sync counter 
    process(h_count_reg,h_end,pixel_tick) 
      begin 
        if (pixel_tick = '1') then -- 25MHz tick 
          if (h_end='1') then 
            h_count_next <= (others => '0'); 
          else 
            h_count_next <= h_count_reg+1; 
          end if; 
        else 
          h_count_next <= h_count_reg; 
        end if; 
    end process; 

    -- 525 vertical sync counter 
    process(v_count_reg,h_end,v_end,pixel_tick) 
      begin 
        if (pixel_tick = '1') and (h_end = '1') then 
          if (v_end = '1') then 
            v_count_next <= (others => '0'); 
          else 
            v_count_next <= v_count_reg+1; 
          end if; 
        else 
          v_count_next <= v_count_reg; 
        end if; 
    end process; 

end Behavioral; 

clock.vhd

entity clock is 
Port (clk : in STD_LOGIC; 
     reset : in STD_LOGIC; 
     hsync : out STD_LOGIC; 
     vsync : out STD_LOGIC; 
     video_on : out STD_LOGIC; 
         p_tick : out STD_LOGIC; 
     pixel_x : out STD_LOGIC_VECTOR(9 downto 0); 
     pixel_y : out STD_LOGIC_VECTOR(9 downto 0) 
        ); 
end clock; 

architecture Behavioral of clock is 
-- VGA 640x480 sync parameters 
constant HD: integer:=640; -- horizontal display area 
constant HF: integer:=16; -- horizontal front porch 
constant HB: integer:=48; -- horizontal back porch 
constant HR: integer:=96; -- horizontal retrace "sync pulse" 
constant VD: integer:=480; -- vertical display area 
constant VF: integer:=10; -- vertical front porch 
constant VB: integer:=33; -- vertical back porch 
constant VR: integer:=2; -- vertical retrace "sync pulse" 

-- mod2 counter to generate a 25MHz enable tick 
signal mod2_reg : std_logic; 
signal mod2_next : std_logic; 

-- sync counters for the horizontal and vertical scans 
signal v_count_reg : unsigned(9 downto 0); 
signal v_count_next : unsigned(9 downto 0); 
signal h_count_reg : unsigned(9 downto 0); 
signal h_count_next : unsigned(9 downto 0); 

-- output buffer 
signal v_sync_reg : unsigned(9 downto 0); 
signal h_sync_reg : unsigned(9 downto 0); 
signal v_sync_next : unsigned(9 downto 0); 
signal h_sync_next : unsigned(9 downto 0); 

-- status signal 
signal h_end : std_logic; 
signal v_end : std_logic; 
signal pixel_tick : std_logic; 

component counter 
generic (count_value :=800; 
        sync_start :=10; 
        sync_end :=20 
        ); 
Port     (clk : STD_LOGIC; 
    reset : STD_LOGIC; 
        ena : STD_LOGIC; 
        rollover_out : std_logic; 
    sync : STD_LOGIC; 
        address : std_logic_vector(9 downto 0) 
        ); 

signal carry : std_logic;       
end component; 

horizontal: counter 
generic map (count_value :=800; 
          sync_start :=10; 
          sync_end :=20 
          );           
PORT MAP (clk <= clk; 
        reset <= reset; 
        ena <= '1'; 
        rollover_out <= carry; 
        sync <= hsync 
        address <= open 
        ); 

vertical: counter 
generic map (count_value :=525; 
          sync_start := 2; 
          sync_end := 4 
          ); 
Port map (clk <= clk; 
        reset <= reset; 
        ena <= carry; 
        rollover_out <= open; 
        sync <= vsync;   
        address <= open 
        );       

begin 
    -- register 
    process(clk,reset) 
      begin 
        if (reset='1') then 
          mod2_reg <= '0'; 
          v_count_reg <=(others=>'0'); 
          h_count_reg <=(others=>'0'); 
          v_sync_reg <=(others=>'0'); 
          h_sync_reg <=(others=>'0'); 
        elsif(clk' event and clk='1') then 
          mod2_reg <= mod2_next; 
          v_count_reg <= v_count_next; 
          h_count_reg <= h_count_next; 
          v_sync_reg <= v_sync_next; 
          h_sync_reg <= h_sync_next; 
        end if; 
    end process; 

    -- mod2 circuit to generate 25MHz enable tick 
    mod2_next <= not mod2_reg; 

    -- 25MHz pixel tick 
    pixel_tick <= '1' when mod2_reg = '1' else '0'; 

    -- status 
    h_end <= -- end of horizontal counter 
      '1' when h_count_reg = (HD+HF+HB+HR-1) else --799 
      '0'; 
    v_end <= -- end of vertical counter 
      '1' when v_count_reg = (VD+VF+VB+VR-1) else --524 
      '0'; 

    -- video on/off 
    video_on <= '1' when (h_count_reg < HD) and (v_count_reg < VD) else '0'; 

    -- output signals 
    hsync <= h_sync_reg; 
    vsync <= v_sync_reg;   
    pixel_x <= std_logic_vector(h_count_reg); 
    pixel_y <= std_logic_vector(v_count_reg); 
    p_tick <= pixel_tick; 

end Behavioral; 

испытательный стенд

ENTITY clock_tb IS 
END clock_tb; 

ARCHITECTURE behavior OF clock_tb IS 

-- Component Declaration for the Unit Under Test (UUT) 

COMPONENT clock 
PORT(
    clk : IN std_logic; 
    reset : IN std_logic; 
    hsync : OUT std_logic; 
    vsync : OUT std_logic; 
    video_on : OUT std_logic; 
    p_tick : OUT std_logic; 
    pixel_x : OUT std_logic_vector(9 downto 0); 
    pixel_y : OUT std_logic_vector(9 downto 0) 
    ); 
END COMPONENT; 


--Inputs 
signal clk : std_logic := '0'; 
signal reset : std_logic := '0'; 

    --Outputs 
signal hsync : std_logic; 
signal vsync : std_logic; 
signal video_on : std_logic; 
signal p_tick : std_logic; 
signal pixel_x : std_logic_vector(9 downto 0); 
signal pixel_y : std_logic_vector(9 downto 0); 

-- Clock period definitions 
constant clk_period : time := 10 ns; 

BEGIN 

    -- Instantiate the Unit Under Test (UUT) 
uut: clock PORT MAP (
     clk => tb_clk, 
     reset => tb_reset, 
     hsync => tb_hsync, 
     vsync => tb_vsync, 
     video_on => tb_video_on, 
     p_tick => tb_p_tick, 
     pixel_x => tb_pixel_x, 
     pixel_y => tb_pixel_y 
    ); 

-- Clock process definitions 
clk_process :process 
begin 
      clk <= '0'; 
      wait for clk_period/2; 
      clk <= '1'; 
      wait for clk_period/2; 
end process; 


-- Stimulus process 
stim_proc: process 
begin     
    -- hold reset state for 100 ns. 
      wait for 100 ns;   

    wait for clk_period*10; 

    -- insert stimulus here 

    wait; 
end process; 

END; 
+1

В чем вопрос? См. Http://stackoverflow.com/help/mcve – Ian

+0

И почему вы хотите сосредоточить его в нижней части экрана? –

+0

@BrianDrummond нет особой причины, это просто ограничение дизайна. – zubinp

ответ

1

Если я правильно понял вопрос правильно, необходимо сегментировать свою задачу на две части.

Сначала вам нужна конструкция, которая при заданном такте 26,25 МГц будет генерировать сигналы HSYNC, VSYNC и видеоданных, которые будут выводиться на контакты FPGA.

Во-вторых, вам необходимо заполнить эти видеоданные растровым изображением RGB/YCbCr с пиксельными данными, которые представляют собой графику для часов. Этот блок будет принимать сигналы синхронизации видео и часы, а затем заполнять видеоданные.

Как вы создаете часовые руки - это сложная часть, и я подозреваю, что человек, выполняющий курс, ищет какую-то изобретательность, чтобы решить эта конкретная проблема.

Начать небольшие и наращивать. Попытайтесь собрать проект, чтобы генерировать сигналы синхронизации и нанести на экран плоский блок цвета или черно-белый. Можно создать тестовый стенд, который затем сохранит данные пикселя в файле, который может быть обработан в растровое изображение, чтобы вы могли видеть, какой результат будет в симуляции, прежде чем вы перейдете на аппаратное обеспечение.

Смежные вопросы