【问题标题】:VHDL: How do I delay VGA signals?VHDL:如何延迟 VGA 信号?
【发布时间】:2016-06-16 11:24:57
【问题描述】:

我正在使用 Basys3 FPGA,并且我有一个测试模式生成器,它在监视器上显示一组图像。问题是,每张图像都有“故障”,这意味着每条水平线中的第一个像素是前一行的像素。例如,如果我有一个黑白屏幕,上半部分为白色,下半部分为黑色,那么第一条黑线中的第一个像素将是白色的。基本上,看起来整个第一垂直列向下移动了一个像素。

根据教授的说法,问题是由于信号(h_sync、v_sync、RGB)不同步,h_sync 和 v_sync 提前 1 位,由于延迟选择图像时的 RGB 信号。通过选择,我的意思是,我有 4 个活动开关(基于它们的 ON/OFF 状态)以“二进制方式”选择图像。 (例:4个开关处于0101状态,则显示第5幅图像。0011状态,显示第3幅图像,依此类推。)

这是选择的代码:

type Colors is array (0 to 15) of STD_LOGIC_VECTOR (7 downto 0);
signal redArr   : Colors;
signal greenArr : Colors;
signal blueArr  : Colors;

process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if flagAV = '1' then
        RED <= redArr (conv_integer (SW));
        GREEN <= greenArr (conv_integer (SW));
        BLUE <= blueArr (conv_integer (SW));
    else
        RED <= "00000000";
        GREEN <= "00000000";
        BLUE <= "00000000";
    end if;
LED <= SW;
end if;
end process;

数组 (Colors) 有 16 个元素,因为我有 16 个图像,因此 4 个开关 (SW) 足以显示所有这些元素。我使用每种颜色 8 位。 flagAV 只是为了检查我是否是活跃区域。

我有一个单独的模块 (VGADraw) 用于选择图像,还有一个模块 (VGADrive),我在其中定义 H/V 同步、H/V 空白信号。然后使用来自 VGADrive 的 H/V 空白信号将计数器内置在图像选择模块中。

VGADrive 中定义的 H/V 同步和空白信号:

HorizontalSync: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if (inCntHor = RES.cstHorFP + RES.cstHorAL - 1) then
        inHS <= '0';
    elsif (inCntHor = RES.cstHorFP + RES.cstHorAL + RES.cstHorPW - 1) then
        inHS <= '1';
    end if;
end if;
end process;

HorizontalBlanking: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if (inCntHor = RES.cstHorAL - 1) then
        inHBL <= '1';
    elsif (inCntHor = RES.cstHorTotSize - 1) then
        inHBL <= '0';
    end if;
end if;
end process;

VerticalSync: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if (inCntVer = RES.cstVerFP + RES.cstVerAL - 1) then
        inVS <= '0';
    elsif (inCntVer < RES.cstVerFP + RES.cstVerAL + RES.cstVerPW - 1) then
        inVS <= '1';
    end if;       
end if;
end process;

VerticalBlanking: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if (inCntVer = RES.cstVerAL - 1) then
        inVBL <= '1';
    elsif (inCntVer = RES.cstVerTotSize - 1) then
        inVBL <= '0';
    end if;
end if;
end process;

使用消隐信号的图像选择模块 (VGADraw) 中内置的计数器:

VerticalCounter: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    HBLold <= HBL;
    if HBL = '0' and HBLold = '1' then
        if VBL = '1' then
            incntVer <= 0;
        else
            incntVer <= incntVer + 1;
        end if;          
    end if;        
end if;
end process;

HorizontalCounter: process (CLK)
begin
if (CLK'EVENT and CLK = '1') then
    if HBL = '1' then
        incntHor <= 0;
    else
        incntHor <= incntHor + 1;
    end if;
end if;
end process;

cstHorAL - 像素/活动线

cstHorFP - 像素/前廊

cstHorPW - 像素/脉冲宽度

cstHorBP - 像素/后廊

cstHorTotSize - 像素/总行数

cstVerAL - 行/活动行

cstVerFP - 线条/前廊

cstVerPW - 线数/脉冲宽度

cstVerBP - 线条/后廊

cstVerTotSize - 行数/总帧数

HBLold - 用于下降沿检测

我的问题是,如何将 h_sync 和 v_sync 信号延迟 1 位,以便正确显示图像而不会移动第一个像素,我应该在哪个模块中执行此操作?

【问题讨论】:

  • 您正在询问有关未出现在已发布代码中的信号的问题。所以你只能期待一个模糊的答案;这将是:只需在像上面这样的时钟进程中分配它们。 (哦,使用rising_edge 函数而不是搞乱低级事件属性)。
  • 事实是,我不知道该贴哪部分代码,完整的代码太多了。但我将添加定义同步、空白和计数器信号的序列。
  • 我想我是按你说的那样实现的,“失真”似乎变小了。但仍有细柱故障。还有什么我可以做的吗?我尝试使用after 声明将其延迟一些,但没有效果。

标签: vhdl delay vga


【解决方案1】:

既然你说你实现了一个周期延迟,请尝试更多的周期延迟,例如:

process(CLK) is
begin
  if rising_edge(CLK) then
    a_q <= a;
    a_q_q <= a_q;
    a_q_q_q <= a_q_q;
    -- etc
  end if;
end process;

如果您想要更简洁的代码,您可以使用 FOR 循环来延迟任何信号,如您想要的任意多个周期,例如

-- In Architecture
constant num_cycles : INTEGER := 3;
signal   a_v : std_logic_vector(num_cycles downto 0);

begin
  a_v(0) <= a;
  process(CLK) is
  begin
    if rising_edge(CLK) then
      for i in 0 to num_cycles loop
        a_v(i+1) <= a_v(i);
      end loop;
    end if;
  end process;
end architecture;

在这种情况下,a 可以是 h_sync 或 v_sync。 num_cycles 是您想要延迟的周期数。 a_v 是一个向量。要使用延迟信号,只需使用 a_v(num_cycles)

【讨论】:

  • 或者你可以用更少的代码来做。而不是a_v(0) &lt;= a,消除for循环并执行a_v &lt;= a_v(num_cycles-1 downto 0) &amp; a;
  • 所以据我了解,我将a_v &lt;= a_v(num_cycles-1 downto 0) &amp; a 放在 if 子句中,消除了 for 循环?
  • 我的延迟信号在哪里?还在一个?还是会在 a_v(num_cycles) 中?
  • 没有。它将在 a_v(num_cycles) 中
  • 好的,我试试看。非常感谢你们的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
相关资源
最近更新 更多