VHDL:如何延迟VGA信号?

时间:2016-06-16 11:24:58

标签: vhdl delay vga

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

据我教授告诉我,问题是由于信号(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;

阵列(颜色)有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 - line / front porch

cstVerPW - 行/脉冲宽度

cstVerBP - 行/后廊

cstVerTotSize - 行数/总帧数

HBLold - 用于下降沿检测

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

1 个答案:

答案 0 :(得分:0)

由于您说您实施了一个周期延迟,请尝试更多周期延迟,例如:

-Wno-sign-compare

如果您想要更干净的代码,您可以使用FOR循环将任意信号延迟任意数量的循环,例如

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;

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