0

有人能告诉我这个电路是如何增加 h_count_reg 和 v_count_reg 的吗?我真的没有看到它。另外,输出被完全缓冲是什么意思?只是延迟了一个像素?也没有真正看到。谢谢!

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity vgaController 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 vgaController; architecture Behavioral of vgaController is -- VGA 640 -by - 480 sync p a r a m e t e r s constant HD: integer:=640; --horizontal display area constant HF: integer:=16 ; --h. front porch constant HB: integer:=48 ; --h. back porch constant HR: integer:=96 ; --h. retrace "Sync Pulse" constant VD: integer:=480; -- vertical display area constant VF: integer:=10 ; -- v. front porch constant VB: integer:=33 ; -- v. back porch constant VR: integer:=2 ; -- v. retrace "sync pulse" -- mod-2 counter signal mod2_reg, mod2_next : std_logic;--mod-2 counter to generate the 25-MHz enable tick -- sync counters, two counters for the horizontal and vertical scans signal v_count_reg, v_count_next : unsigned(9 downto 0); signal h_count_reg, h_count_next : unsigned(9 downto 0); --To remove --potential glitches, output buffers are inserted for the hsync and vsync signals. This leads --to a one-clock-cycle delay. add a similar buffer for the rgb signal in the pixel --generation circuit to compensate for the delay. -- output buffer signal v_sync_reg, h_sync_reg: std_logic; signal v_sync_next ,h_sync_next : std_logic; --status signal signal h_end , v_end , pixel_tick: std_logic; 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 <='0'; h_sync_reg <='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; --mod-2 circuit to generate 25 MHz enable tick mod2_next <= not mod2_reg; -- 25 MHz pixel tick pixel_tick <= '1' when mod2_reg = '1' else '0'; --status h_end <= --end of horizonal counter '1' when h_count_reg = (HD+HF+HB+HR-1) else --799 '0'; v_end <= --end of vertial counter '1' when v_count_reg = (VD+VF+VB+VR-1) else --524 '0'; -- mod-800 horizontal sync counter process(h_count_reg,h_end,pixel_tick) begin if (pixel_tick='1') then --25 MHz 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; -- mode-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; -- horizontal and vertial sync, buffered to avoid glitch h_sync_next <= '1' when (h_count_reg >= (HD+HF)) --656 and (h_count_reg <= (HD+HF+HR-1)) else --751 '0'; v_sync_next <= '1' when (v_count_reg >= (VD+VF)) --490 and (v_count_reg <= (VD+VF+VR-1)) else --491 '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;

4

3 回答 3

1

垂直和水平计数器分布在两个进程中:

--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   <='0';
            h_sync_reg   <='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;

在 elsif 条件下,计数器从v_count_next和加载h_count_next,它们是在两个不同的过程中产生的:

-- mod-800 horizontal sync counter
process(h_count_reg,h_end,pixel_tick)
    begin
        if (pixel_tick='1') then --25 MHz 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;

-- mode-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;

(现在您可以想象实际标记过程语句是一个好主意)。

至于“缓冲”:

--To remove
--potential glitches, output buffers are inserted for the hsync and vsync signals. This leads
--to a one-clock-cycle delay. add a similar buffer for the rgb signal in the pixel
--generation circuit to compensate for the delay.
-- output buffer
signal v_sync_reg, h_sync_reg: std_logic;
signal v_sync_next ,h_sync_next : std_logic;
--status signal
signal h_end , v_end , pixel_tick: std_logic;

这些是上述--register过程中的最后两个任务。从评论来看,触发器的一个时钟延迟是为了消除由关系运算符引起的组合故障:

h_sync_next <=
    '1' when (h_count_reg >= (HD+HF))  --656
          and (h_count_reg <= (HD+HF+HR-1)) else --751
    '0';

v_sync_next <=
    '1' when (v_count_reg >= (VD+VF))  --490
         and (v_count_reg <= (VD+VF+VR-1)) else --491
    '0';
于 2014-11-11T23:42:03.210 回答
1

只是出于兴趣,这是对上述内容的单进程重构。

它要短得多,至少在我看来,更容易理解、修改和正确。带有不必要信号的多个琐碎过程只是为了在它们之间进行通信而使设计变得模糊(正如您所指出的!) - 并为错误提供了肥沃的滋生地。

一个警告:我尚未验证这是您设计的精确实现;如果您选择使用它,那将是您的责任。

欢迎发表意见。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity vgaController 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 vgaController;

architecture Behavioral of vgaController is
-- VGA 640 -by - 480 sync  p a r a m e t e r s
constant HD: integer:=640; --horizontal display area
constant HF: integer:=16 ; --h. front porch
constant HB: integer:=48 ; --h. back porch
constant HR: integer:=96 ; --h. retrace "Sync Pulse" 
constant VD: integer:=480; -- vertical display area
constant VF: integer:=10 ; -- v. front porch
constant VB: integer:=33 ; -- v. back porch
constant VR: integer:=2  ; -- v. retrace "sync pulse"
-- derived constants to make code clearer
constant H_Last       : integer := HD+HF+HB+HR-1;
constant H_Sync_First : integer := HD+HF;
constant H_Sync_Last  : integer := HD+HF+HR-1;
constant V_Last       : integer := VD+VF+VB+VR-1;
constant V_Sync_First : integer := VD+VF;
constant V_Sync_Last  : integer := VD+VF+VR-1;

-- sync counters,  two counters for the horizontal and vertical scans
signal v_count : unsigned(9 downto 0);
signal h_count : unsigned(9 downto 0);

--status signal
signal pixel_tick: std_logic;

begin
    --register
    process(clk,reset)
        begin
            if (reset='1') then
                pixel_tick   <= '0';
                v_count      <= (others=>'0');
                h_count      <= (others=>'0');
                vsync       <= '0';
                hsync       <= '0';
            elsif(clk'event and clk='1')then
                pixel_tick     <= not pixel_tick;

                -- H and V pixel counters
                if pixel_tick = '1' then
                   if h_count = h_last then
                      h_count <= (others=>'0');
                      -- and start the next line
                      if v_count = v_last then
                         v_count <= (others=>'0');
                      else
                         v_count <= v_count + 1;
                      end if;
                   else
                      h_count <= h_count + 1;
                   end if;
                end if;

                -- default assignments for sync
                hsync <= '0';
                vsync <= '0';
                -- H and V sync pulses
                if h_count >= H_Sync_First and h_count <= H_Sync_Last then
                   hsync <= '1';
                end if;
                if v_count >= V_Sync_First and v_count <= V_Sync_Last then
                   vsync <= '1';
                end if;
            end if;
    end process;

    --video on/off ... was unregistered so I'll leave it that way
    video_on <= '1' when (h_count < HD) and (v_count < VD) else '0';

    --output signals 
    pixel_x <= std_logic_vector(h_count);
    pixel_y <= std_logic_vector(v_count);
    p_tick <= pixel_tick;

end Behavioral;
于 2014-11-12T11:04:28.963 回答
0

需要缓冲区(寄存器是一个更好的名称,因为它不是输出缓冲区)——不仅是为了抑制毛刺——而且是为了确保每个引脚(v_sync、h_sync 和颜色)的输出延迟时间相等。如果您在下游输出缓冲区之前不使用寄存器,您将在屏幕上获得糟糕的色彩效果。

请注意,您的 x,y 坐标计数器电路寻址的是下一个像素,而不是当前像素。因此,计数器值和 h/v_sync 之间必须存在延迟,具体取决于计数器 -> 获取像素信息 -> 像素颜色输出之间的延迟。

于 2014-11-13T09:03:37.143 回答