我正在研究VHDL設計,我已經開始工作了,但代碼非常醜陋,而且我似乎試圖圍繞語言的設計來實現我的目標,這讓我感覺有點不對勁。我對VHDL相當陌生,但我一直在爲這個項目的小塊工作近一個月,所以我有了一個總體想法。但是,這部分有點複雜。使用rising_edge對非時鐘信號的不良做法是什麼?有替代品嗎?
我需要一個過程,它將在信號的上升沿(END_ADC)後創建一個時鐘週期的長脈衝(LOAD_PULSE),但直到從該信號的最後一個上升沿開始經過4個時鐘週期(END_ADC)或第二個信號(LVAL)的下降沿。
要完成的觀望期,我已經建立了統計微秒和週期,在此定時器模塊:
entity uS_generator is
generic(
Frequency : integer := 66 -- Frequency in MHz
);
Port (
CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
T_CNT : out integer range Frequency downto 1 := 1;
uS_CNT : out integer range 65535 downto 0 := 0
);
end uS_generator;
architecture behavior of uS_generator is
signal T_CNT_INT : integer range Frequency downto 1 := 1; -- Counter for 1 uS
signal uS_CNT_INT : integer range 65535 downto 0 := 0;
begin
COUNT: process(CLK, RESET)
begin
if RESET = '1' then
T_CNT_INT <= 1;
uS_CNT_INT <= 0;
elsif rising_edge(CLK) then
if T_CNT_INT = (Frequency - 1) then -- Increment one clock early so last rising edge sees one uS elapsed.
uS_CNT_INT <= uS_CNT_INT + 1;
T_CNT_INT <= T_CNT_INT + 1;
if uS_CNT_INT = 65535 then
uS_CNT_INT <= 0;
end if;
elsif T_CNT_INT = Frequency then
T_CNT_INT <= 1;
else
T_CNT_INT <= T_CNT_INT + 1;
end if;
end if;
end process COUNT;
T_CNT <= T_CNT_INT;
uS_CNT <= uS_CNT_INT;
end behavior;
我使用設計的脈衝生成部的流程如下:
loadPulseProc: process(PIXEL_CLK, END_ADC, RESET)
begin
if RESET = '1' then
PULSE_FLAG <= '0';
LOAD_PULSE <= '0';
elsif rising_edge(END_ADC) then
PULSE_FLAG <= '1';
end if;
if rising_edge(PIXEL_CLK) then
if PULSE_FLAG = '1' and END_ADC = '1' and LVAL <= '0' and ADC_TMR_T >= 4 and LVAL_TMR_T >= 4 then
LOAD_PULSE <= '1', '0' after PIXEL_CLK_T;
PULSE_FLAG <= '0';
end if;
end if;
end process loadPulseProc;
ADCTimerProc: process(END_ADC, RESET)
begin
if RESET = '1' then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if rising_edge(END_ADC) then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if falling_edge(END_ADC) then
ADC_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
end process ADCTimerProc;
LVALTimerProc: process(LVAL, RESET)
begin
if RESET = '1' then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if rising_edge(LVAL) then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
if falling_edge(LVAL) then
LVAL_TMR_RST <= '1', '0' after PIXEL_CLK_T/10;
end if;
end process LVALTimerProc;
PIXEL_CLK_T是時鐘的週期,15.152ns。
這個設計的工作原理是,仿真表明它按照我的要求工作,但是隻有在避免由於使用falling_edge調用的多個rising_edge而將錯誤分離爲單獨的if語句而導致錯誤發生後纔會發生錯誤。據我讀到的使用rising_edge和falling_edge似乎只保留給時鐘,那麼這只是不好的做法?如何避免這種行爲,但仍然創造相同的輸出?
謝謝!
您的代碼不符合綜合條件,它不會以硬件描述語言描述硬件。在PIXEL_CLK_T/10之後施加的延遲不會被作用,也不會超過信號分配中的一個波形元素。不可能使用兩條邊來控制相同的信號(雙數據速率寄存器是FPGA中的特定I/O單元)。請參閱現在撤消的IEEE Std 1076.6-2004(RTL綜合)或您最喜愛的供應商的綜合文檔。 – user1155120
如果您使用'rising_edge'(或等效的「事件和= 1」形式),您已創建了一個時鐘信號。有時候這是合適的,但通常這是不好的做法(並且您最好重新計時信號,並比較新舊值)。 –