読者です 読者をやめる 読者になる 読者になる

guruguru123’s diary

かなり雑な作業日記です。

AD9851へのドライブ(2)

前回のAD9851への書き込み信号が連続して出力されてしまう問題(waitの状態に移行してくれない)の解決策が思い浮かばなかったため、問題を洗い出すためにシミュレーションをしてみた。以下がその結果。f:id:guruguru123:20170510161150p:plain

すると、シミュレーション上ではstate_nがいったん書き込みが終わると、次のリクエスト信号まで一定の値を保持しており、waitの状態を保っていることがわかる。これより、リクエスト信号に何らかの問題があると考えた。

 

リクエスト信号の生成は以下のように行っていた。見直してみたら、これでは0.5秒間リクエスト信号が'1'のまま保持されてしまうことに気がついた。また、RAMに対するリクエスト信号もここで生成しているため、RAMは動作をしているが、これも見直しが必要であると考えた。

process (clk,state_con,counter) begin
if clk' event and clk = '1' then
if counter = 8000000 then
counter <= (others => '0');
if state_con = "00001" then
state_con <= "00010";
elsif state_con = "00011" then
state_con <= "00100";
elsif state_con = "00101" then
state_con <= "00110";
elsif state_con = "00111" then
state_con <= "01000";
elsif state_con = "01001" then
state_con <= "00000";
else
state_con <= state_con+ '1';
end if;
else
counter <= counter + '1';
end if;
end if;
end process;

OUTPUT: process(state_con) begin
ram_req_w <= '0';
ram_req_r1 <= '0';
ram_req_r2 <= '0';
ram_req_r3 <= '0';
ram_req_r4 <= '0';
dds_req <= '0';
case state_con is
when "00001" =>
ram_req_w <= '1';
dds_req <= '0';
when "00011" =>
ram_req_r1 <= '1';
dds_req <= '1';
when "00101" =>
ram_req_r2 <= '1';
dds_req <= '1';
when "00111" =>
ram_req_r3 <= '1';
dds_req <= '1';
when "01001" =>
ram_req_r4 <= '1';
dds_req <= '1';
when others =>
null;
end case;
end process;

 

リクエストが'1'のとき状態遷移が始まるようにしているため、これでは繰り返し出力されてしまう。そこで以下のように変更した(変更無しの部分は省略)

process (clk,state_con,counter) begin
if clk' event and clk = '1' then
if state_con = "0001" then
state_con <= "0010";
elsif state_con = "0011" then
state_con <= "0100";
elsif state_con = "0101" then
state_con <= "0110";
elsif state_con = "0111" then
state_con <= "1000";
elsif state_con = "1001" then
state_con <= "0000";
end if;

if counter = 8000000 then
counter <= (others => '0');
state_con <= state_con+ '1';
else
counter <= counter + '1';
end if;
end if;
end process;

すると繰り返しがなくなったが、RAMからのデータ読み出しが行われなくなってしまった。これは、データ読み出しから出力の遅延をうまく組み込めていなかったことが原因であった。32bitデータ読み出しの出力にイネーブルをつけていたが、これを外して解決した。

変更前data_out <= data_o1 when r_o = '1' else     変更後data_out<= data_o;
         (others => '-') when r_o = '0';

 

これらを改善してFPGAに書き込みを行ったところ、AD9851の出力が時間変化していることが確認できた。

このAD9851の出力の変更を外部スイッチなどから行えるようにしていきたい。