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

guruguru123’s diary

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

Papilio Pro 上にRAMを構成

SDRAMで行き詰っていたところ、ISEのBlock Memory Generatorで内部RAMを作って試してみたらと、アドバイスを頂いたので試してみた。

http://www.hmwr-lsi.co.jp/fpga/fpga_5.htm

こちらのサイトを参考にとりあえず構成をしてみた。

Block Memory Generatorがところどころバージョンアップに伴う変更があり、このサイト通りではなかったものの構成することができた。また、コンポーネントとして組み込むこともできた。

f:id:guruguru123:20161209220727p:plain

f:id:guruguru123:20161209220731p:plain

f:id:guruguru123:20161209220733p:plain

今回構成したのはDual Port RAMだったが、今回用いるのはSingle Port RAMでいいと思う。そこで、次回はSingle Port RAMを構成して動作テストをしていきたい。

SDRAMを用いてのAD9851への書き込み

SDRAMコントローラがとりあえずできたので、以前作ったAD9851ドライブ機構と合わせてみようとした。しかし、以前はVelirog hdlを用いていたため、また、ZPUinoに組み込んでいたため、信号部分等の変更が面倒だった。そこで新しくDDSドライブ部をつくり、組み込んだ。今回は、40bitのデータ生成は考えず(浮動小数点計算をさせるブロックを作っていないため)既存のデータを読み出して書き込むような機能にした。f:id:guruguru123:20161026181347p:plain

周波数設定ワードは32bitだが今回使用するSDRAMは1つのアドレスに16bitまで格納するので、バースト長2で書き込み、読み出しをするようにした。一通り作って出力を確認してみたが正しく動作していない。

考えられる原因はプリチャージ動作の不足かバーストでの動きをきちんと記述できていないかだ。

どこが原因かわからないのでテストベンチを作成した。以下シミュレーション結果。黄色い線までが初期設定、黄色い線より後ろが書き込み、読み出し動作となっている。

これを見る限りでは正しく動作している気がするのだが動いてくれない。

f:id:guruguru123:20161124225728p:plain

f:id:guruguru123:20161124225847p:plain

解決出来次第この記事を更新する。

 

Papilio Pro基板上SDRAMの利用(10)

前回に引き続き、一秒間隔の信号に従ってSDRAMへデータを書き込み、その書き込んだアドレスからデータを読み出す。そのデータをRS232C通信でPC上に表示させ、ここまで終わったら次の立ち上がり信号を待機する。というSDRAMコントローラの製作。f:id:guruguru123:20161020181008p:plain

前回、RS232C部分のエラーを改善したため、今回は各部分を接続して動作させてみた。しかし、SDRAMコントローラの開始、終了とRS232C通信の開始、通信がうまくかみ合っていなかったため、そこの改善からはじめた。無駄にタイミング信号をつけすぎていたため、その辺をまとめて、わかりやすくしたところ正しく動作した。以下は動作させたときのPC表示と入力データ。これを見ると正しく出力を得られていることがわかる。

f:id:guruguru123:20161020181011p:plain

 

しかし、今回は一秒ごとに起動→アクティブ→書き込み→読み出しとしたのでこのままでは高速化は望めない(今回の方式では17clk必要で、0.5μ秒)。これからは、リフレッシュ機能をちゃんと作り、バースト読み出しを2アドレスできるようにする。目標は40bitのデータを1μ秒以下での読み出しだ。

また、データを複数用意して、時間変化に伴ってそれらを書き込むアドレスを変えたときに正しく動作するのかも実験していきたい。

 

 

Papilio Pro基板上SDRAMの利用(9)

前回RS232C通信部は問題ないと書いたが、一秒ごとに出力させるようにタイミング制御を入れたところうまく動作しなかった。そこで、以下のようにプログラムを改変した。

f:id:guruguru123:20161012173839p:plain

startが'1'の間送信部が働き、16bit送信が終わったらstate_fが立ち上がり、startを'0'にする。うまくいかなかった原因は、state_f  <= '1'; を入れる場所を間違えていたことだった。これができたので、後はSDRAMを動作させるだけだ。

また、これのシミュレーション結果を以下に示す。正しく動作していることがわかる。

f:id:guruguru123:20161012174049p:plain

Papilio Pro基板上SDRAMの利用(8)

とりあえずこんな感じに組み込んでみた。今回はあまり速度は考えず、一秒間隔で書き込み、そのままそのアドレスを読み出しをする。読み出しが終わったらRS232Cのブロックにデータを渡してPCと通信させる。コンパイルまで終わったが、シリアルコンソールに出力がされなかった。そこで別々にどこが動いていないのか確認してみた。

f:id:guruguru123:20160930180940p:plain

まず前に作ったRS232C通信機構を崩して作成したRS232C送信ブロック。16bitの0000010100000101をデータとして入力すると以下のように表示された。よってここは問題ない。

f:id:guruguru123:20160930180947p:plain

今回は、ここまでの確認で終了。おそらく、時間経過しているのにSDRAMのリフレッシュがされていないのが原因だと思う。

以下RS232C通信部分。

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
--ボーレート230400:137
--115200:276
--9600:3332
entity rs232c is
port(
--resetb : in std_logic;
clk : in std_logic;
--tx : in std_logic;
rx : out std_logic;
txd : in std_logic_vector(15 downto 0);
state : in std_logic
);
end rs232c;

architecture Behavioral of rs232c is
signal data : std_logic_vector(15 downto 0):= (others => '0');
signal counter : std_logic_vector(11 downto 0):=(others => '0');
signal current_bit : std_logic_vector(4 downto 0):=(others => '0');

signal state2 : std_logic;
signal start : std_logic;

begin
--data <= txd;
process(clk,state)
begin
if falling_edge(state) then
start <= '1';
end if;

--if start = '1' then
if rising_edge(clk) then
if counter = 3332 then
counter <= (others => '0');
if current_bit = "10100" then
current_bit <= "00000";
start <= '0';
else
current_bit <= current_bit + '1';
end if;
else
case current_bit is
when "00000" => rx <= '0';
when "00001" => rx <= data(8);
when "00010" => rx <= data(9);
when "00011" => rx <= data(10);
when "00100" => rx <= data(11);
when "00101" => rx <= data(12);
when "00110" => rx <= data(13);
when "00111" => rx <= data(14);
when "01000" => rx <= data(15);
when "01001" => rx <= '1';
when "01010" => rx <= '0';
when "01011" => rx <= data(0);
when "01100" => rx <= data(1);
when "01101" => rx <= data(2);
when "01110" => rx <= data(3);
when "01111" => rx <= data(4);
when "10000" => rx <= data(5);
when "10001" => rx <= data(6);
when "10010" => rx <= data(7);
when "10011" => rx <= '1';
when others => null;
end case;
counter <= counter + 1;
end if;
end if;
--end if;
end process;

process(state) begin
if rising_edge(state) then
data <= "0000010100000101";--txd;
end if;
end process;

end Behavioral;

Papilio Pro基板上SDRAMの利用(7)

前回は起動からアクティブまで遷移するものを作った。今回はそこから書き込みをしてそのまま連続で読み出しをするものを作った。以下シミュレーションのキャプチャである。図を見るとアクティブであるときに、書き込みリクエストがあると書き込みサイクルへと移行していることがわかる。読み出しまで終わったら最初に戻り、アクティブ状態で待機まで行う。次は実機に書き込みをしていきたい。また、RS232C通信をするプログラムを以前作ったので、それを用いて書き込み、読み出しができているか確認できるようにしていきたい。

f:id:guruguru123:20160928141622p:plain

Papilio Pro基板上SDRAMの利用(6)

前回まで作っていたものを改めてみたところ、ステートマシンとして記述していたつもりが状態判定部分が機能しておらず、正しく動作していなかったことがわかった。

そこで、とりあえず起動からアクティブまでを新しく作り直した。前回まではテストベンチを作成していなかったが(作るべきであった)、今回は反省してテストベンチを作った。シュミレーションをしてみたところ、状態遷移が確認できた。下図においてcmdが今回状態遷移させる目標である。

これから、また読み出しと書き込みをできるようにしていきたい。

f:id:guruguru123:20160913164442p:plain