我正在嘗試在VHDL中創建一個VGA驅動程序。如何修復此代碼中的時鐘保持?
我打算用640x480 @ 60 Hz,所以我需要25 MHz和31.5 KHz的時鐘。過程由50 MHz時鐘驅動,併產生25 MHz時鐘。在25 MHz時鐘的每個節拍上,h_counter
通過過程h_sync
遞增,當它達到某個值(H_FRONT + H_SYNC - 1
)時,divider_v
過程被觸發並在短時間內將clock_v
設置爲1。
Quartus II的時序分析失敗,並出現一個警告:不能實現最小設置並保持沿着1條路徑的要求時鐘。 編制報告中的時鐘保持部分指出v_counter
的MSB是罪魁禍首,最小松弛時間爲-0.050ns。第二低的鬆弛時間是0.218ns,這很好。
我試圖使用長狀態1爲clock_v
與簡短的0狀態和最小松弛時間增加到-0.019納秒,這仍然是不可接受的。
據我所知,保持時鐘問題意味着輸入在被正確處理之前被改變,所以我試圖讓1和0出現大致相同的時間段。令我驚訝的是,超過40條路徑變成了紅色,同樣的錯誤。
註釋掉v_clock
流程解決了這個問題。
爲什麼MSB的鬆弛時間比其他位高很多?我能做些什麼來解決這個問題?
這裏是我的代碼:
- 來源::
v_counter[9]
- 爲:
v_counter[9]
- 從時鐘:
clock
- 時鐘出現故障路徑的
library ieee; use ieee.std_logic_1164.all; library Famikon; use Famikon.Types.all; use Famikon.VgaNames.all; entity VgaDriver is port ( -- inputs clock_50: in STD_LOGIC; -- 50 MHz reset: in bit; -- '1' resets r, g, b: in screen_pixel; -- bit_vector subtype -- outputs vga_x, vga_y: out hw_coord; -- integer subtype vga_drawing: out bit; hw_r, hw_g, hw_b: out hw_pixel; -- bit_vector subtype vga_hsync, vga_vsync: out bit; vga_blank, vga_clock: out bit ); end entity; architecture Arch of VgaDriver is signal clock_h, clock_v: std_logic; signal h_counter, v_counter: vga_counter; -- integer subtype signal h_coord, v_coord: hw_coord; -- integer subtype signal h_active, v_active: bit; begin -- some irrelevant code -- h_active <= '1' when (h_counter >= H_BLANK) else '0'; v_active <= '1' when (v_counter >= V_BLANK) else '0'; divider_h: process (clock_50) begin if (rising_edge(clock_50)) then clock_h <= not clock_h; end if; end process; divider_v: process (h_counter) begin if (h_counter /= H_FRONT + H_SYNC - 1) then clock_v <= '0'; else clock_v <= '1'; end if; end process; h_clock: process (clock_h, reset) begin if (rising_edge(clock_h)) then if (reset = '1') then h_counter <= 0; elsif (h_counter = H_TOTAL - 1) then h_counter <= 0; else h_counter <= h_counter + 1; end if; end if; end process; v_clock: process (clock_v, reset) begin if (rising_edge(clock_v)) then if (reset = '1') then v_counter <= 0; elsif (v_counter = V_TOTAL - 1) then v_counter <= 0; else v_counter <= v_counter + 1; end if; end if; end process; end architecture;
詳細:
clock
- 要求的保持關係:0.000納秒
- 所需最短時間P2P:0.618納秒
- 實際Shortes P2P時間:0.568納秒
- 最小時差:-0.050納秒
v_counter
是bit_vector(9 downto 0)
。當我使用定位於此路徑上的設計時,Quartus指向v_clock
過程的第一行(其中一個與rising_edge(clock_v)
一致)。
還有一個關於波紋時鐘警告,其中提到的所有h_counter
位,clock_h
和三個門控時鐘:Equal0
,Equal0~1
和Equal0~0
。
與您的問題並不完全相關,但實際上,您需要'640x480 @ 60Hz'的25.175 MHz時鐘[來源](http://tinyvga.com/vga-timing/[email protected])。我建議你使用內部的PLL來產生這個時鐘(如果你有任何可用的話)。 – HeyYO 2014-11-23 00:05:32
VGA的時間容限是根據顯示器的水平和垂直速率定義的。我在一個月前檢查了幾個關於另一個VGA問題的規格,25 MHz似乎讓您在我檢查的顯示器的容差範圍內。 – user1155120 2014-11-23 02:24:56