【发布时间】: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声明将其延迟一些,但没有效果。