7セグLEDのダイナミック点灯でも使用した1KHzのタイミングを作るfreqdiv.vhdというモジュールを以前作成した。これはgeneric mapに動作周波数をkHz単位で書くと自動的に1kHzごとにイネーブル信号を出力する。
動作周波数によっては用意したカウンタのカウント値をオーバーしてしまうので、その時はstd_logic_vectorのビット幅を手で変更しなければ、ならなくなっていた。
ソースを示すと、
-- Frequncy Divider for Dynamic Lighting
-- 1KHz clock
-- マスタークロックを1KHzのlighting_enaに分周します。
-- クロック周波数をclk_frequencyにKHz単位で設定してください。defaultで25MHzです。
-- lcntが16ビットになっているので、clk_frequencyが65536以上の場合はビットを増やしてください。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity FreqDiv is
generic(
clk_frequency : integer := 50000 -- KHz
);
port(
clk, reset : in std_logic;
lighting_ena : out std_logic
);
end FreqDiv;
architecture RTL of FreqDiv is
signal lcnt : std_logic_vector(
15 downto 0);
begin
process(reset, clk) begin -- Lighting frequency is 1KHz
if reset='1' then
lcnt <= (others => '0');
elsif clk'event and clk='1' then
if lcnt = conv_std_logic_vector(clk_frequency,
16 ) then
lcnt <= (others => '0');
else
lcnt <= lcnt + 1;
end if;
end if;
end process;
lighting_ena <= '1' when lcnt = conv_std_logic_vector(clk_frequency,
16 ) else '0';
end RTL;
signal lcnt : std_logic_vector(15 downto 0);で15 downto 0になっているが、66MHzになると16 downto 0にしなければいけない。最初から16 downto 0にすれば良いという選択肢もあるが美しくない。log2を使えればエレガントに書く事が出来る。
そこで、依然買ってもらった
VHDLの本 をよく読んで見ると。log2(x)はmath_realパッケージをuseすると使えるようだ。だが、xはrealなので、integerをrealに変換しなければいけない。log2(x)はrealなので、またintegerに変換して使う。
変更したソースは
-- Frequncy Divider for Dynamic Lighting
-- 1KHz clock
-- マスタークロックを1KHzのlighting_enaに分周します。
-- クロック周波数をclk_frequencyにKHz単位で設定してください。defaultで50MHzです。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
entity FreqDiv is
generic(
clk_frequency : integer := 50000 -- KHz
);
port(
clk, reset : in std_logic;
lighting_ena : out std_logic
);
end FreqDiv;
architecture RTL of FreqDiv is
signal lcnt : std_logic_vector(
integer(log2(real(clk_frequency)))-1 downto 0);
begin
process(reset, clk) begin -- Lighting frequency is 1KHz
if reset='1' then
lcnt <= (others => '0');
elsif clk'event and clk='1' then
if lcnt = conv_std_logic_vector(clk_frequency,
integer(log2(real(clk_frequency))) ) then
lcnt <= (others => '0');
else
lcnt <= lcnt + 1;
end if;
end if;
end process;
lighting_ena <= '1' when lcnt = conv_std_logic_vector(clk_frequency,
integer(log2(real(clk_frequency))) ) else '0';
end RTL;
ModelSimでシミュレーションすると、clk_frequencyを25000にすると15bitのlcntになり、66000にすると17bitのlcntになることが確認できた。やった出来た!!!エレガントに書く事が出来たと喜んだ。
実際にXSTで論理合成して、念のためView RTL Schematicで確認してみると、あれ?lcntカウンタが16ビットのはずなのに15ビットしかない???
View RTL Shematicで見たfreqdiv.vhdのRTL図はこれ
念のため、Synplify Proで論理合成してみると、ちゃんと16ビットのlcntカウンタが合成されている。
Synplify ProのRTL Schematicのlcntはこれ
XSTの合成結果はModelSimの結果やSynplify Proの合成結果と違うようだ。
Synplify Proで合成した物をコンフィギュレーションすると、SW0~4を31にするとちらつくが、XSTでやるとちらつかない。オシロで測ると1個当たり350us位になっているようだ。
もしかしたらrealからintegerに変換する時の丸め方が違うかもしれない。それでソースを変更してやってみた。
-- Frequncy Divider for Dynamic Lighting
-- 1KHz clock
-- マスタークロックを1KHzのlighting_enaに分周します。
-- クロック周波数をclk_frequencyにKHz単位で設定してください。defaultで50MHzです。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
entity FreqDiv is
generic(
clk_frequency : integer := 50000 -- KHz
);
port(
clk, reset : in std_logic;
lighting_ena : out std_logic
);
end FreqDiv;
architecture RTL of FreqDiv is
signal lcnt : std_logic_vector(
integer(log2(real(clk_frequency))) downto 0);
begin
process(reset, clk) begin -- Lighting frequency is 1KHz
if reset='1' then
lcnt <= (others => '0');
elsif clk'event and clk='1' then
if lcnt = conv_std_logic_vector(clk_frequency,
integer(log2(real(clk_frequency)))+1 ) then
lcnt <= (others => '0');
else
lcnt <= lcnt + 1;
end if;
end if;
end process;
lighting_ena <= '1' when lcnt = conv_std_logic_vector(clk_frequency,
integer(log2(real(clk_frequency)))+1 ) else '0';
end RTL;
これだと、XSTもSynplify Proも両方コンフィギュレーションして確かめてみた結果OKだった。Synplify Proの方はlcntカウンタが17ビットになっているが、最上位ビットは0の時にlighting_enaが0になるようにしてある。これは後でオプティマイズされるだろう。
これで大丈夫だけど、丸め方の違いを覚えておかないとModelSimでOKだと思って1ビット幅を削ってしまった時にXSTで動かないということがありえる。これではまずいのでやめることにした。
というわけで、今回のソースコード・エレガント化計画は挫折してしまった。計算の丸め方のオプションが各ソフトにないのであろうか、知っている方がいらっしゃったらご一報ください。
2005年10月31日 11:47 |
VHDLの書き方
| トラックバック:0
| コメント:3
今日は親子レクで
つくばへリポート を見に行った。
最初に格納庫の中で、災害救助の方法などを見せてもらった。
次に結構近くで見ている所で、ヘリのエンジンスタート。ジェットタービンが回って、ローターがまわりだす。一段と騒音が高くなり、勢いよくローターがまわるが、まだ風はあまり来ない。
そのうちローターのピッチを変えたらしく。風が凄くなった。浮き上がる時は、凄い風でかぶっていた帽子を飛ばされてしまった。こんなに近くでヘリの離陸を見たのは初めて。いい経験が出来た。
その後、ヘリで実際の災害救助を見せてもらった。先生が被害者になって、実際にヘリに吊り上げられた。結構怖かったそうである。ホバーリングしてるヘリに吊り上げられる時には、離陸を見ていた時よりさらに凄い風だったそうだ。
面白かった。行ってよかった。
2005年10月30日 19:58 |
日記
| トラックバック:0
| コメント:0
今日、TX(ツクバ・エキスプレス、鉄道)と武蔵野線を乗り継いで、ディズニーランドに行ってきました。
今まで、鉄道でディズニーランドに行ったことはありません。TXも開通したことですし今回初めて行ってきました。子供たちもTXの快適性とスピードに驚いた様子。武蔵野線よりもずっと早くてゆれませんでした。当たり前ですが。
今日ディズニーランドに行ったのは、ハロウィンフェアが終わってしまうからだそうです。
朝10時30分ころついたのですが、午後から雨の予報だというのに人がいっぱいでした。プーさんのハニーハントのファストパスも午後7時30~8時30分というありさま。(ファストパスを持っているとすぐ乗れます)
しょうがないので、ホーンテッドマンションは並んで乗りました。なんと2時間10分待ち。さすがに待っているのが飽きました。息子は折った足がまだ痛いらしく、痛いと言っているので、ポップコーン入れを椅子にして座ってました。なぜ、そんなにホーンテッドマンションに並ぶかというと、ハロウィン特別バージョンなんだそうです。何が特別なんだと乗り物に乗ってみてみると、確かにかぼちゃのお面が置いてあったのですが、それかな?
雨も降ったりやんだり、なかなかユウツな一日だったけど。子供らが喜んでくれたのがよかったかな。
でも、私は歩いた時に、風景を楽しめ、ゆったりできるディズニーシーのほうが好きです。ディズニーランドはせまっくるしい。。。
かぼちゃのお面(ジャック オウ ランターン)の飾りがいっぱい。
建物にもいっぱいかぼちゃが。
ホーンテッドマンションの入り口もハロウィンの飾りが。
2005年10月29日 23:47 |
日記
| トラックバック:0
| コメント:0
昨日の7セグメントLEDを何個ダイナミック点灯できるか?では、7セグLED1個当たり1msにするところ500usにしてしまったので、1msに修正した。
プロジェクトを
ここ に置きます。今回のはちらつくので昨日のより面白い。
SW0~SW4を16(十進)(つまりダイナミック点灯LED20個)くらいから、ちらつきが目立ち始める。この時点で20ms、50Hz間隔でリフレッシュ。
SW0~SW4を31(十進)にするとめちゃくちゃちらつく。
明るさは昨日と同様だと思う。
ちなみに電圧は、7セグLEDが点灯している時に、コモンアノードのトランジスタのコレクタが2.5V、7セグLEDのカソードが0.8V、カソード(セグメント)へのFPGAの出力が0.1V。よって7セグLEDのVfは1.7V。
100オームの抵抗の両端は0.7Vなので、電流は0.7V/100オーム=7mA。8セグメント点いてるときのトランジスタのコレクタ電流は7mA * 8seg = 56mA。
となる。
次に電圧波形。
トランジスタのコレクタ電圧。GNDは下から2メモリ目。電圧軸は1V/1目盛り。時間軸は500us/1目盛り。waitが0の場合(SW0~SW4が0)
7セグLEDのカソード(セグメント)のどこか。GNDは下から2メモリ目。電圧軸は1V/1目盛り。時間軸は1ms/1目盛り。waitが4の場合(SW0~SW4が4)
7セグLEDのカソード(セグメント)のどこか。GNDは下から2メモリ目。電圧軸は1V/1目盛り。時間軸は5ms/1目盛り。waitが31の場合(SW0~SW4が31)
時間軸が遅いので、最初が写真に写らないで切れてます。
昨日やってみるといっていた出力ピンをCMOS出力にするというのは、やってみたらコンパイル途中でプレーサーに蹴られました。セレクトIOのルールに違反するそうです。
----------------------------
トリビアに出してみようか?
7セグメントLEDを何個ダイナミック点灯できるか?
あなたは何個点灯までゆるせますか?100人に聞いてみました。
これじゃ、トリビアの種かな? まあ、こんなマニアックなことトリビアで取り上げられることも無いだろうけど。楽しめた。
2005年10月27日 22:58 |
FPGAリテラシー及びチュートリアル
| トラックバック:0
| コメント:4
キコさんのブログでバック・ツウ・ザ・フューチャーのデロリアンの制御パネルを作るというのがあった。 7セグメントLEDを13個ダイナミック点灯するそうだが、普通の回路で何個ダイナミック点灯して、普通に見えるか常々疑問に思っていた。そこでスパルタン3スタータキットでやってみた。
スパルタン3スタータキットでは4個の7セグメントLEDが搭載されている。私は、一個当たり
1ms (500us)で合計
4ms (2ms)でダイナミック点灯している。SW0~SW4のスイッチで設定したバイナリ数だけLEDを消灯して、またLEDをつけるループに入るようにした。こんな感じ
上図中で”SW0~3で指定した任意の数”を”SW0~4”に読み替えてください。
最初にSW0~SW4を0にしてみた。普通のダイナミック点灯。
次にSW0~SW4を4にしてみた。8個分のダイナミック点灯。
SW0~SW4を9にしてみた。13個分のダイナミック点灯。
最大値のSW0~SW4を31(十進)にしてみた。35個分のダイナミック点灯。
見た感じは4個は明るい。8個は少し暗くなった。8個でもライトを当てると少し暗い。昼間明るい所で見るとすると6個くらいか?
13個はちょっと暗い。暗いところならばOKかも? 35個はめちゃんこ暗い。
スパルタン3スタータキットの7セグメントLEDの回路。(ユーザーズマニュアルより転載)
出力3.3Vで、ざっくりVfを2Vとすると、セグメントあたり13mA。10mAくらいかな。
出力はディフォルトなのでLVTTL。CMOSのほうが良かったか?
もっと明るくなるかな?
明日やってみよう。
とりあえず、私の基準では8個くらいがいいかなと思う。明るい所で見るなら6個くらい。
Xilinx ISE7.1SP4のプロジェクトを
ここ においておくので興味のある方はどうぞ。保証はないです。VHDLですが。。。
2005年10月26日 20:16 |
FPGAリテラシー及びチュートリアル
| トラックバック:0
| コメント:7
昨日、首筋や肩が凝って、頭も痛くなったので、マッサージに行ってきた。
肩こりがひどいのでいろいろ試してみたことがある。カイロや中国整体、整形外科。
カイロはぼきぼきと骨を正常な位置に戻す整体だ。そこではマッサージもやってくれた。カイロはやったときは、背筋が伸びた気がして良いかなと思ったが、すぐ後に子供を抱いたら、背中全体が痛くなり、その日は寝ていた。後でカイロのお兄さんに電話で聞くと、2日くらいは安静にしていなくてはだめなそうだ。骨を正常に戻しても筋肉も付き方がおかしいので、だめなのかも。
カイロでは(だけじゃないかもしれないが)施術台というのかな。顔の形に穴が開いたベットに顔を入れてやってもらうのだが、顔に体重がかかって、顔が痛くなった。それで1ヶ月くらい痛かった。もう少し通えといわれたが、これで懲りてもう行かなかった。
中国整体は多分中国人の人が何か普通の民家のようなところでやっていた。もうよくおぼえていないが、結構気持ちよかった。足とかもマッサージしてもらった。回数券を買って、頻繁に通えといわれた。何か儲け主義のようなのでやめた。
整形外科に行くと、はり薬と筋弛緩剤をくれたりするだけ。マッサージもあることはあるが、あまりやってくれない。後は電気びりびり。あまり効かない。頻繁に行って、リハビリで電気とマッサージをやってもらえばいいのかも。でも、そんな暇はない。
今のマッサージは近所の部落のおじさんだ。別に通えと強制されることもないし、気が楽である。マッサージは免許制で免許をもっているし、免許がないカイロや中国整体よりも安心だそうだ。腕も悪くないと思う。痛いところを直接もまずに周りから、徐々に攻めるのがコツみたいだ。調子悪い時に気ままに通っている。一回3,500円で、30~40分くらいだ。
やはりModelSimでデバックしている時が一番肩に効く気がする。目の疲れが肩に来るのだろう。
みなさん肩こりはどうでしょうか?
2005年10月25日 09:01 |
日記
| トラックバック:0
| コメント:2
今日はうちの奥さんがミニバスの審判で行っちゃったので、午後に一番下の娘とチョウチョ公園に行ってきた。
チョウチョ公園というのは俗称で正式には小貝川ふれあい公園というそうです。
公式ページ 。なぜチョウチョ公園と呼ぶかというと、建物がおおむらさきというチョウチョの形をしているから。
いろいろな遊具もあるし、家からそんなに遠くないし、良く行く公園。
いろんな滑り台がある。
パークゴルフもある。今日は来週大会があるからか、盛況だった。
バーベキュー場もあるが、そこではどんぐりが沢山拾える。どんぐりを沢山拾ってきた。ネックレスやブレスレットにするそうだ。
こっちも丘を登ったり降りたりして運動になった。
2005年10月23日 17:33 |
日記
| トラックバック:0
| コメント:2
今、フリースケールのPowerPCのセミナに行って帰ってきたところ。
セミナが行われた目黒雅叙園は本当に凄い所だった。ドームの中にかやぶき屋根の日本家屋が作ってあった。滝もあって、ドームの中にあった池には鯉が泳いでいた。別世界にきたみたい。
これは3階から下を見た所。オープンレストランが見える。これドームの中。
ドームの中にかやぶき屋根の日本家屋が作ってあった。
よく見ると奥に滝が見える。
PowerPCは今まで使っていたが、なんとなく使っていたことや、名前は知っていたが機能がわからいことがわかった。とてもためになった。
やはり今度はMPXバスで作るほうが良さそう。
キャッシュオンのメモリ領域に読み書き方法も教えてもらった。例えばPCIボード上にCPUとメモリが載っていて、CPUがそのメモリをデータキャッシュオンで使っている時、PCIバス越しにホストCPUがメモリに読み書きする場合である。PCIボード上のCPUがデータキャッシュをオンしていると、メモリ上に最新データが無く、キャッシュ上にだけある場合がある。
キャッシュオンのメモリ領域に書き込むには、CPUのキャッシュをインバリデートしなくてはいけないし、読み込むときはCPUのキャッシュからキャストアウトしてもらわなければいけないので、面倒である。
バススヌープを利用してうまくやらなければ。。。
2005年10月20日 21:38 |
その他のFPGAの話題
| トラックバック:0
| コメント:2
スパルタン3スターターボード で遅延を測ってみた。
チップはXC3S200-4FT256。50MHzのクロックをそのままA1コネクタの5番ピン(N7)に出力したものと、10段ディレイを通してA1コネクタの7番ピン(T8)に出力したものを比べてみた。
N7へ出力するまでの遅延はタイミングアナライザで7.018ns、一方T8へ出力するまでの遅延はタイミングアナライザで15.322ns。その差8.304ns。
ビットファイルを流し込んで、実際のボードでN7とT8間のクロックの時間差を測定してみた。そうすると5.8ns、T8の方が遅れているようだ。
理論値は測定値に対して143%、逆は70%。かなり差がある。いろいろひっくるめての値だが、同じ比率で動作が速いとすると、15nsで動くとタイミングアナライザが言っている回路が10.5nsで動くということになる。かなり速い。
本当にこのくらいが実力値なのだろうか? スパルタン3はかなり余裕があるということになる。
2005年10月18日 12:32 |
その他のFPGAの話題
| トラックバック:0
| コメント:2
間違って、タイミング制約が厳しくPlace & Routeが配線できないで、仮に配線したものでタイミングを見ていました。修正します。
------------------
mfreemanさんのページ で今話題のFPGA内遅延素子の話題を載せていた。それによるとスパルタン3-400-5で4段のBUFプリミティブのディレイを入れると遅延は1.5ns程度だそうだ。タイミングアナライザで公式ディレイを確かめてみた。
ソースはmfreemanさんのソースを丸ごとそのまま、遅らす信号を入力ポートにして、遅れた信号を出力ポートとした。(3段ディレイ入り)入力ポートと出力ポートは、チップ上で隣のパッドとした。(FT256パッケージでC9とD9)
まずは何もタイミング制約を加えずにコンパイル。タイミングアナライザで見てみると、
Maximum delay is 7.982ns.
--------------------------------------------------------------------------------
Delay: 7.982ns (data path)
Source: in_port (PAD)
Destination: out_port (PAD)
Data Path Delay: 7.982ns (Levels of Logic = 5)
Constraint Improvement Wizard
Data Path: in_port to out_port
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tiopi 1.686 in_port
in_port_IBUF
net (fanout=1) 0.428 DIN_1
Tilo 0.529 u1
net (fanout=1) 0.211 DOUT_1
Tilo 0.529 u2
net (fanout=1) 0.060 DOUT_2
Tilo 0.479 u3
net (fanout=1) 0.266 DOUT_3
Tioop 3.794 out_port_OBUF
out_port
---------------------------- ---------------------------
Total
7.982ns (7.017ns logic, 0.965ns route) (87.9% logic, 12.1% route)
次にディレイを抜いて、IN-OUT直結にする
Maximum delay is 5.766ns.
--------------------------------------------------------------------------------
Delay: 5.766ns (data path)
Source: in_port (PAD)
Destination: out_port (PAD)
Data Path Delay: 5.766ns (Levels of Logic = 2)
Constraint Improvement Wizard
Data Path: in_port to out_port
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tiopi 1.686 in_port
in_port_IBUF
net (fanout=1) 0.286 out_port_OBUF
Tioop 3.794 out_port_OBUF
out_port
---------------------------- ---------------------------
Total
5.766ns (5.480ns logic, 0.286ns route) (95.0% logic, 5.0% route)
3段ディレイ回路のタイミングアナライザにより遅延の保証値は
2.216ns 。これをmfreemanさんの実測地1.5nsと比べてみると
147% になる。これを見ると保証値は実測値の1.5倍になっているので、周期で2/3倍になるということ。つまり15nsが10nsになるので、66MHzのつもりが100MHzで動いちゃったということになら良いよね~!!
でも、結構差がある。
次に、タイミング制約をかけてみる。入力ポートから出力ポートまで7.4ns。
タイミング制約は、
INST "in_port" TNM = "in_port"; INST "out_port" TNM = "out_port"; TIMESPEC "TS_inout" = FROM "in_port" TO "out_port" 7.4 ns; 3段ディレイ入りは、
Maximum delay is 7.837ns.
--------------------------------------------------------------------------------
Delay: 7.837ns (data path)
Source: in_port (PAD)
Destination: out_port (PAD)
Data Path Delay: 7.837ns (Levels of Logic = 5)
Constraint Improvement Wizard
Data Path: in_port to out_port
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tiopi 1.686 in_port
in_port_IBUF
net (fanout=1) 0.294 DIN_1
Tilo 0.529 u1
net (fanout=1) 0.014 DOUT_1
Tilo 0.479 u2
net (fanout=1) 0.296 DOUT_2
Tilo 0.479 u3
net (fanout=1) 0.266 DOUT_3
Tioop 3.794 out_port_OBUF
out_port
---------------------------- ---------------------------
Total 7.837ns (6.967ns logic, 0.870ns route)
(88.9% logic, 11.1% route)
と少しばかり速くなっている。しかし、DOUT_1が0.014nsなのに、DOUT_2が0.296nsもかかっているのはなぜ?同じようなルートなのに。。。FPGA Editorで見たインスタンスの配置はこれ。
IN-OUT直結は、
Maximum delay is 5.766ns.
--------------------------------------------------------------------------------
Delay: 5.766ns (data path)
Source: in_port (PAD)
Destination: out_port (PAD)
Data Path Delay: 5.766ns (Levels of Logic = 2)
Constraint Improvement Wizard
Data Path: in_port to out_port
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tiopi 1.686 in_port
in_port_IBUF
net (fanout=1) 0.286 out_port_OBUF
Tioop 3.794 out_port_OBUF
out_port
---------------------------- ---------------------------
Total 5.766ns (5.480ns logic, 0.286ns route)
(95.0% logic, 5.0% route)
こっちは同じ。FPGA Editorで見たインスタンスの配置はこれ。
さて、差は7.837-5.766=
2.071ns 。実測値1.5nsの
138% 。タイミングアナライザで保証された最大遅延が15nsならば11nsで動くという分けだ。66MHzが92MHzくらい。少し短縮したが、まだまだ離れている感じ。
最後におまけ。今までは、OUTポートのスルーレートはSLOWだったがFASTにしてやってみた。タイミング制約はあり。
3段ディレイ入り
Maximum delay is 5.314ns.
--------------------------------------------------------------------------------
Delay: 5.314ns (data path)
Source: in_port (PAD)
Destination: out_port (PAD)
Data Path Delay: 5.314ns (Levels of Logic = 5)
Constraint Improvement Wizard
Data Path: in_port to out_port
Delay type Delay(ns) Logical Resource(s)
---------------------------- -------------------
Tiopi 1.686 in_port
in_port_IBUF
net (fanout=1) 0.294 DIN_1
Tilo 0.529 u1
net (fanout=1) 0.014 DOUT_1
Tilo 0.479 u2
net (fanout=1) 0.296 DOUT_2
Tilo 0.479 u3
net (fanout=1) 0.266 DOUT_3
Tioop 1.271 out_port_OBUF
out_port
---------------------------- ---------------------------
Total
5.314ns (4.444ns logic, 0.870ns route) (83.6% logic, 16.4% route)
やはり格段に速くなった。出力バッファの遅延時間は3.794-1.271=
2.523ns も違う。
東エレのDDR SDRAM2セミナでも、LUTを遅延素子としてデータを遅延するやり方が紹介されていたし、やはりこういうやり方もありなんだと思った。でも、確実に遅延を調整するにはやはりFloorplannerで位置固定が望ましいのであろう。。。
後で自分でも遅延を測定して、タイミングアナライザの値と比べてみたい。
2005年10月14日 21:28 |
FPGAチップ内の配線方法
| トラックバック:0
| コメント:6
ハードウェア記述言語(HDL)初心者にコーチしていると、いろいろ凄い記述に出会う。
ソフトウェアは学んでいても、ハードウェアは余りやってこなかった人々なので、VHDLを書いても自由に書いてしまうのだ。
私は、回路図からHDLに移行したので、実際の回路のイメージをHDLで表すように書いてきたが、やはり思考過程が全然違うようだ。
ちゃんとFFと推定されるように、セレクタとして働くように記述を直してやるが、そういうことをしていると、いまさらながら、HDLの記述のほんの一部だけしか使っていないんだな、と感じる。当たり前のように、論理合成ツールに回路を推定させるような記述をしてきたが、それに縛られているんだなということが感じられてとても新鮮だった。
そして問題は、そういう記述をしてもシミュレーターが一見正しいようなタイミングチャートを返してしまうことがあることだ。そのような記述をしても、論理合成ツールが頑張って、クロックで同期しないいろんなラッチをLUTで生成して、でっち上げてしまうこともある。その場合、水晶発信器の周波数が50MHzなので、20nsで動作するところ、150nsなどとタイミングレーポートされる時もある。
型にはめるのが安全だが、惜しいような気もする。時々、”そうか、こういうふうに書いても大丈夫なのか”と思う時もあるし。
自分でもテストベンチを書いているときは、動作周波数も考えなくて良いし、とてものびのび書いている気がする。
2005年10月14日 06:03 |
その他のFPGAの話題
| トラックバック:0
| コメント:2
昨日は2日連続お出かけだったので、発明工夫展にはやめました。
私だけがロボコン決勝を見に行った。少しみていたら飽きたので、職場に行って、仕事を少しやった。家でやっていると、1画面しかなくて不便だが、職場では2画面なので仕事がはかどる。
今日は、DDR SDRAMコントローラがPCIクロック(66MHz)の2倍で動くかどうかを確かめた。
まずは、DDR SDRAMコントローラがPCIクロック(66MHz)の2倍で動く様に戻して、コンパイル。やはりタイミング制約を満足しない。
DDRCLKとDDRCLK180度のクロックスキューが最大2.3ns位ある。これじゃ、3.75 - 2.3 = 1.45nsしか余裕が無いので、無理そう。(しかし、何でこんなにクロックスキューが大きいんだろう、ツールがつながっているスライスは同じくらいのスキューにするとか、もっとうまくやって欲しい)
それじゃというので、DDRCLKとDDRCLK180度クロックをDDRCLKに一本化する。
DDRCLK180 <= not DDRCLK; にする。こうすると、スライスには、クロックを反転するインバータが入っているので、クロックラインがDDRCLKに一本化される。DDRCLK180クロックを使う所は、クロックを反転して使うからである。
図はVirtex2のデータシートより転載。クロックをスライス内で反転するインバータがある。上のように書くと、DDRCLK180を使用するスライスはクロックをインバートして使う(と思う)。必ずDCMのDUTY_CYCLE_CORRECTIONをTRUEにしておいたほうが良いと思う。(ディフォルトでTRUEなので心配ないかもしれないが。。。)
これでも、まだタイミング違反は50以上ある。
そのため、Timing AnalyzerからクロスプローブするためにFloorplannerを起動し、Place & Route後の配置をコピーした。
1.Timing Analyzerからクリティカルパスをダブルクリックして、Floorplannerにクリティカルパスを表示する。
2.クリティカルパスが短くなるように、配置を移動する。
1.2.の手順をコンパイルで様子を見ながら、70回以上繰り返すと、タイミング違反が3個くらいになって、タイミング違反の度合いもわずかになった。もういい加減飽きたので、今日はこの辺で終了。このくらいならば、大丈夫だと思うので、確かめてみることにする。
bitファイルを作って、確かめてみる。
何か、電源ONして、最初にbitファイルをロードした時がおかしい時がある。それから、パソコンをリブートすると大丈夫なようだ。まだ、試行回数が少ないので、明日確かめる。
水晶で133MHzを供給して確かめてみたくなった。
水晶はボードの製造元で分けてくれるそうだ。良かった。感謝。
mfreemanさん、教えていただいて、ありがとうございました。基板を作る時は、表面実装品になると思うので、参考になりました。
2005年10月11日 11:29 |
DDR SDRAMコントローラ
| トラックバック:0
| コメント:2
今日は、つくば科学フェスティバルに行ってきた、つくば市内の小学校、中学校、研究所がいろんな出し物を出してきている。いろんな科学的な体験、工作等が出来る。
KEKのページ 、
つくば市教育委員会のページ 、参照。
毎年、行っているがなかなか面白い。今回は子供たちの行っている小学校の出し物もあって、先生方と6年生が頑張ってやっていた。娘の行っている中学校も担任が来ていた。
いろいろ興味深いブースが会ったが、中でも森林研は面白かった。
いろいろな動物の毛皮を展示してあって触れた。かもしか、しか、きつね、くまなどなど、狐以外は毛が硬かった。
木のブロックも展示してあって、重さを確かめられるようになっていた。バルサは一番軽く、黒檀などは重かった。バットを作るタモも思ったより軽かった。なかなか普段木の重さを比べたことが無いので、面白かった。
いろんな木の葉を使って、しおりを作るのもやっていた。
こんな感じで木の葉がおいてある。
で作ったしおりがこれ。早い話が木の葉をパウチっ子でパウチ。
後、ホバークラフト、燃料電池車、太陽電池車、ラジオの製作、ロジック回路の製作、スライム、紙飛行機、ポンポン船、ブーメランなどいろいろあったが、大体、小中学生向きだ。
うちの子供らも、アンモナイトの化石のキャスト(複製)を型をとって、石膏で作った。完成品がこれ。
一日楽しめた。
明日は、科学技術週間ということでイベントが多いので、またまた発明工夫展とかに行くかも。
2005年10月09日 20:33 |
日記
| トラックバック:0
| コメント:0
今日は大学の学園祭に行って、
ロボットコンテスト を見に行った。一番下の娘と息子と見に行ったので、なかなか落ち着かない。2日後に決勝なので、今度は1人で見に行きたい。
ロボットの完成度は見た限りではいまいちだった。ちゃんと缶や木片をフィールドに拾いにいけないものも多かった。決勝は高度なロボットが見られることだろう。
その後、せっかくなので構内を案内して、中庭の学園祭の会場に行ってみた。模擬店がいっぱいあったが、珍しい食べ物はない。メインの会場に行くと、沖縄の食べ物とか、広島お好み焼きや東南アジアの食べ物とかがあって楽しめるが、雨がふっていたせいもあって、やめて帰ってきた。
2005年10月08日 19:23 |
日記
| トラックバック:0
| コメント:0
今日は教訓をいくつか。他山の石としてください。
DDR SDRAMコントローラはデータや制御信号(DQS等)を入出力ともIOBのDDRレジスタにマップしないと実現はおぼつかない。
セミナ に行った時にIOBにマップしないでも大丈夫な方法も教えてもらったが、基本的にはIOBのレジスタを使ったほうが安全。
今日、チップスコープの結果を見て、どうもおかしいと思って調べてみた。FPGA Editorで見ると、IOBにマップされているはずのレジスタがIOBの外に出ていた。これじゃ、だめだ。IOBに入っていると思って、制約もかけていなかった。
原因は、
1.MAPのプロパティ中の"Pack I/O Registers/Latches into IOBs"プロパティを"For Inputs and Outputs"にしておいて、IOBに入るように推定されるようにしておいてもIOB入らない事があった。
これは制約で直接指定した。このように
INST "U_ddr_cont_inf/DDR_CONT/read_data_module_inst/dq_rise[*]" IOB = TRUE; 2.Virtex2のIOBは、入力用FF、出力用FFのリセットが共通になっている。出力がDDRレジスタ・プリミティブを使用していて、IOBの入力用FFにする予定のHDL記述のリセットと異なると、当然ながらIOBの入力用FFは使用されない。そういう場合は入力用FFのリセットが削除できるので削除したらOKとなった。
3.出力のトライステート・バッファの制御はFFからの出力で皆さん制御していると思います。それをIOBに入れたかったがDQS用の制御FFが入ってなかった。これもVirtex2のIOBの制限で、出力FFのクロックと出力トライステート・バッファ制御用FFのクロックは同一でなければならなかったようだ。
クロックが違っているので、IOBに入れるのは無理となった。これは、MAXDELAY制約をそのネットに加えて、良しとした。
(FPGA EditorでIOBを見ると構造が良くわかると思います。)
この3つを厳密に適用したら、大丈夫になったようだ。まだ火曜日に再度やってみるまで安心できないかもしれないが、今日のところは単発アクセスは完璧だ。バースト・アクセスは、今の回路では検証できないので保留。単発が完璧でチップスコープが使えれば、バーストの検証も難しくないと思われる。だが、現在の動作周波数は83MHzである。これを133.33MHzまで上げなくては。。。
http://marsee101.blog19.fc2.com/blog-entry-32.html でカスケード接続DCMがおかしいと書いたが、もしかすると大丈夫だったかもしれない。もう一度確かめる予定。
133MHz水晶は、DVIボードの製造元に売ってくれるかどうか問い合わせ中。あっても悪いことは無いので、購入したい。
2005年10月07日 14:46 |
FPGAチップ内の配線方法
| トラックバック:0
| コメント:0
今回の回路はPlacer Cost Table(Place & Routeのプロパティの中)を変更すると、動作周波数違反が、がらがら変わったり、ホールドタイム・バイオレーションが出たり、本当に暴れる回路だった。
FPGAチップはXC2V6000-5FF1517。スライス占有率で11%ほどしか使ってない回路だ。
MAPリポートの一部を示す。
Logic Utilization:
Number of Slice Flip Flops: 3,197 out of 67,584 4%
Number of 4 input LUTs: 1,806 out of 67,584 2%
Logic Distribution:
Number of occupied Slices: 4,029 out of 33,792 11%
Total Number 4 input LUTs: 4,235 out of 67,584 6%
Number used as logic: 1,806
Number used as a route-thru: 258
Number used for Dual Port RAMs: 1,820
(Two LUTs used per Dual Port RAM)
Number used as Shift registers: 351
Number of bonded IOBs: 194 out of 1,104 17%
IOB Flip Flops: 13
IOB Dual-Data Rate Flops: 148
Number of Block RAMs: 19 out of 144 13%
Number of GCLKs: 8 out of 16 50%
Number of DCMs: 3 out of 12 25%
Number of BSCANs: 1 out of 1 100%
一番大きいのが、LUTを使用した分散RAM。
こういう大きなFPGAの一部を使う場合は、少なくともエリア制約を作って適用しないと、うまく行かないのだろうか?
P&Rが迷ってしまうことがあるのかもしれない。
どなたか発表できる事例があれば教えてください。
チップスコープをかけると動作がおかしくなると言う現象は、よく聞くし、私も経験したことがる。チップスコープを入れるとうまく動くことがあると言うのも。
それは、制約が足りないのかもしれないが、うまく動作したチップスコープが入っていないコンパイル結果をfloorplannerでロジックセルを固定する。そして、チップスコープをかければ、少なくとも基本動作がおかしくなることはないはずである。チップスコープが動かないことはあるかもしれないが。。。
2005年10月07日 09:34 |
FPGAチップ内の配線方法
| トラックバック:0
| コメント:0
DDR SDRAMコントローラについて書くのも何回目だが分からないほど書いてきた。
でも、XilinxのツールISEやFloorplannerについての理解は深まってきたような気がする。こんどはFPGA Editorをマスターしたいと思っている。
DDR SDRAMコントローラを実装する基板は、以前にも書いたことがあるが東京エレクトロンデバイス製の
DVI評価ボード だ。なかなかうまく動作しない。
現在、DDRのクロックは66MHzPCIクロックを2倍にして使用しているが、以前も違うボードで、DCMをカスケード接続した場合におかしかった経験がある。(使用チップは同じVirtex2)
DVI評価ボードには、166MHzの水晶発振器が載っているので、ここからクロックをもらおうと思ったが、今の回路だと133MHzが限界で、166MHzで動きそうもない。(floorplannerでがちがちに固めればOKかもしれないけど、そこまでやりたくない)
166MHzを2分周して、83MHzで動作させることにした。
floorplannerでDDR SDRAM周りの回路とPCI周りの回路をエリア制約を作って、ISEでコンパイル。そうすると、PCI回路関係の入出力ポートのセットアップ時間とクロックからの出力時間がぜんぜんだめ。Place&Routeにお任せだと、DCMの場所が悪いみたい。(プリミティブのエリア制約はしていない)
DCMの位置をPCIクロックの近くに固定して、コンパイル。今度はタイミング制約がうまいこと満足した。動作周波数が低いということがあるけどまあ良かった。
これで試してみると、読み書きできる番地が違っているけど、(PCI回路のバグ?)DDR SDRAMに読み書きできる。
どうなっているかみるために、チップスコープを入れて、コンパイル。出来上がったので、やってみるとチップスコープでちゃんと波形が見られる。DDR SDRAMに読み書きもOK。以前はチップスコープでちゃんと波形が見られなかったので、本当によかった。
動作周波数が低くなったからか、エリア制約でちゃんとした配置になったからか、分からないが、デバックできる体制になったことは良かった。思えば長い回り道だったようだ。
今度は、133MHzの水晶発振器に交換して、やってみたいが、なかなか売っていないみたい。業者に、頼んであるが2,3日返事がない。いろいろ探し回らなくては。。。
2005年10月06日 13:44 |
DDR SDRAMコントローラ
| トラックバック:0
| コメント:4
今度は回路ブロックごとにエリアを制約するやり方を勉強。
オートルータで自動配線した結果を見ると、かなりばらばらに配置されている。それでは制限を満たすことが難しいと思われるため回路ブロックごとに領域を決められたら成績が良くなるはずだ。
やり方は、
1.ISEのProcess View -> Translate -> Floorplan Designをダブルクリック。
2.Floorplannerが起動
(ここからXilinxのソフトウェアマニュアルを転載)
3.[Design Hierarchy] ウィンドウで階層グループを選択します。
4.[Floorplan] → [Assign Area Constraint] をクリックします。
5.[Editable Floorplan] ウィンドウで、エリア制約を設定する位置にマウスをドラッグして矩形ボックスを描画します。ボックス内にあるすべてのタイルがエリア制約の対象となります。 エリア制約は、エリア グループに設定された RANGE 制約として UCF に書き込まれます。
(転載終わり)
エリア制約をかけたところ。
UCFファイルに書かれた制約。
INST "U_pci2pcicont" AREA_GROUP = "AG_U_pci2pcicont" ; AREA_GROUP "AG_U_pci2pcicont" RANGE = SLICE_X105Y146:SLICE_X175Y33 ; AREA_GROUP "AG_U_pci2pcicont" RANGE = RAMB16_X4Y5:RAMB16_X4Y17, RAMB16_X5Y5:RAMB16_X5Y17 ; INST "U_ddr_cont_inf" AREA_GROUP = "AG_U_ddr_cont_inf" ; AREA_GROUP "AG_U_ddr_cont_inf" RANGE = SLICE_X1Y191:SLICE_X104Y114 ; AREA_GROUP "AG_U_ddr_cont_inf" RANGE = RAMB16_X0Y15:RAMB16_X0Y23, RAMB16_X1Y15:RAMB16_X1Y23, RAMB16_X2Y15:RAMB16_X2Y23, RAMB16_X3Y15:RAMB16_X3Y23 ; これでセーブして、コンパイルする。
これで、指定した領域に回路ブロックがアサインされる。
アサインされたあとのFloorplanはこれ。
これでタイミング制約が満足できない場合は、Floorplannerの使い方覚書1で、もう一度クリティカルパスをつぶす。エリア制約がかけてあれば、オートルートしてもましだと思う。(確認はしてないけど)
2005年10月03日 20:46 |
Floorplannerの使い方
| トラックバック:0
| コメント:0
Floorplannerの使い方を勉強中。でその覚書。
5年ほど前、ALTERAのFLEX10Kシリーズで開発していた。使用ツールはMAX+PLUS2だった。動作周波数を満たすことがなかなか難しかったので、フロアプランを使用していた。クリティカルパスを表示して、遅延が大きいLEを同じROWや、同じLABへ移動していた。
その様な使い方をISEでやってみた。
まずはISEでコンパイル。
Process View - Implement Design - Place & Route - Generate Post-Place & Route Static Timing - Analyze Post-Place & Route Static Timing(Timing Analyzer) をダブルクリックして、Timing Analyzerを起動。
Timinig Analyzerが起動する。一番左の時計マークのアイコン"Analyze against Timing Constrains"をクリックする。そうするとあらかじめUCFで制約をかけたパスについてタイミング解析をする。タイミングを満たしていないパスは
赤 で表示される。
Timing Analyzer画面の左側のペインの"Timing Constrains"の左の四角で囲ったプラスをクリックすると、制約ごとのタイミング解析結果を展開して表示する。その時に、タイミングを満たしていないパスは
赤 で表示される。
さらにその制約(ここでは
TS_clk = PERIOD TIMEGRP" の部分)の左の四角で囲ったプラスをクリックすると、一番遅延が大きいパス(クリティカルパス)から表示される。ここでもタイミング制約を満足していないパスは
赤 で表示される。
でクリティカルパスを確認。
Timing AnalyzerでViewメニューから
Floorplanner for crossprobing を選択し、Floorplannerを起動。Timing Analyzerでクリティカルパスの中の一番遅延の大きいネットをFloorplannerで観察する。”net (fanout=9) 2.960 core_mem_wb_dff8_q<4>”をダブルクリックして、Floorplannerを見るとダブルクリックしたネットが表示されている。
FloorplannerでFloorplanメニューから
Replace All with placement を選ぶと、UCF Flowの方に前にPlace & Routeした配置をコピーすることが出来る。UCF Flowでロジックセルをマウスクリックで移動することが出来る。
図は選んだロジックセルを移動している所、線はロジックセルへの接続状況を表す。当然ながら、クリティカルパスの線が短くなるように配置する。
これでセーブすると、Floorplanが.fnfファイルへ、制約が.ucfへ書き込まれる。追加される制約は次のようなもの。
INST "core_Inst_alu__n010657_SW01" LOC = "SLICE_X5Y23" ; INST "core_Inst_pc_lib_etemp21" LOC = "SLICE_X25Y27" ; INST "core_Inst_pc_lib_dtemp<7>1111" LOC = "SLICE_X25Y32" ; つまり、どのインスタンスをどこに配置というのが全て書いてある。
これでも一度Place & Routeを実行して、まだだめだったら、もう一度やり直す。
2005年10月02日 10:26 |
Floorplannerの使い方
| トラックバック:0
| コメント:0