私はVHDLデザインに取り組んでいますが、コードはかなり醜いです。私の目標を達成するために言語の設計を回避しようとしているようですが、何かが間違っているように感じます。私はVHDLについてはかなり新しいですが、プロジェクトの小規模なチャンクには1ヶ月近く取り組んでいるので、一般的な考え方があります。しかし、この部分はもう少し複雑です。rising_edgeを非クロック信号の悪い習慣で使用していますか?代わりがありますか?
信号の立ち上がりエッジ(END_ADC)後に1クロック周期の長いパルス(LOAD_PULSE)を生成するプロセスが必要ですが、その信号の最新の立ち上がりエッジ(END_ADC)から4クロックが経過するまでは発生しません第2の信号(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です。
このデザインでは、必要なときにシミュレーションが実行されることが示されていますが、raise_edge呼び出しの複数のrising_edgeを使用することによるエラーの回避が重要な場合にのみ、私がrising_edgeとfalling_edgeを使って読んだ限り、時計用にしか予約されていないようです。この動作を回避するにはどうすれば同じ出力を作成できますか?
ありがとうございます!
コードは合成可能ではありません。ハードウェア記述言語のハードウェアは記述されていません。「PIXEL_CLK_T/10後」によって課される遅延は、信号割り当てにおいて1つ以上の波形要素に対して作用されず、また、複数の波形要素でもない。両方のエッジを使用して同じ信号を制御することはできません(ダブルデータレートレジスタはFPGAの特定のI/Oセルです)。現在廃止されているIEEE Std 1076.6-2004(RTL合成)またはお好みのベンダーの合成ドキュメントを参照してください。 – user1155120
'rising_edge'(または'イベントと= 1 'の同等の形式)を使用すると、クロック信号が作成されます。これは適切な場合もありますが、しばしば悪い習慣です(信号を再クロッキングし、新しい値と古い値を比較する方が良いでしょう)。 –