我正在实现一个模拟时钟,它将在640x480的vga屏幕上显示小时和分针,时钟以480x480为中心。时钟每分钟更新一次。下面的时序图显示了HSYNC和VSYNC的时序及其相对于26.25MHz时钟的位置。
这是我在VHDL的第一门课程,我想知道我在clock.vhd中缺少什么,以及如何有效地编写测试平台以便我可以获得输出
我有一个名为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;
答案 0 :(得分:1)
如果我正确理解了这个问题,您需要将您的任务分为两个部分。
首先,您需要一种设计,当给定26.25MHz时钟时,将生成HSYNC,VSYNC和视频数据信号,并将其输出到FPGA的引脚上。
其次,您需要使用代表时钟指针图形的像素数据的RGB / YCbCr位图填充该视频数据。该块将接收视频定时信号和时钟,然后填充视频数据。
如何生成时钟指针是一个棘手的部分,我怀疑运行该课程的人正在寻找解决该特定问题的聪明才智。
从小处开始积累。尝试将设计结合在一起以生成定时信号,并在屏幕上放置一个平坦的彩色块或黑白色。可以创建一个测试平台,然后将该像素数据保存到一个可以处理成位图的文件中,这样您就可以在进入硬件之前看到模拟结果。