ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

FPGA/CPLD友の会コミュのQ&A

  • mixiチェック
  • このエントリーをはてなブックマークに追加

Q&A

質問掲示板が最近のトピックを見ると無さそうなので作成しました。
よろしくお願いします。

コメント(24)

AlteraのFPGA/CPLDにコンフィギュレーションする場合は
データシートのどこを見ればいいのでしょうか?
http://docs-asia.electrocomponents.com/webdocs/077b/0900766b8077b7aa.pdf
どのピンに何をさせばいいのか皆目見当がつかない状態です。
とっかかりだけでも、ご相談にのって頂けましたら嬉しいです。
デバイスは何を使いたいのかによります。JTAGでISPできるのもあれば、専用の書き込み器が必要なのもあります。専用の書き込み器が必要なのはかなり古いデバイスなので諦めましょう。
ドナーズパパさん、ありがとうございます。
調べてみます。
spartan-3 スターターキットを用いてSRAM(IS61LV25616AL)を制御しようとしています。

動作仕様はADDRESS(all0)に"1010101011110000";を書き込んだ後、同様のアドレスからデータを読み込んで、LEDを点灯させるという仕様のつもりです。。
PS2CK(ライトクロック)は10kHz,SCLK,(リードクロック)は500kHzになります。

実機で実行してみましたが、LEDの目視確認を行っても正常にLEDが点灯しません。
すみませんが、問題がある点がわかりましたらご教授ください。
(参考ソース等ありましたら幸いです。)

###########################
process (SW1,atpdata)begin
case SW1 is
when '1' => LED <= atpdata(15 downto 8);
when '0' => LED <= atpdata(7 downto 0);
when others => LED <= (others => '0');
end case;
end process;


--ライトカウンタ
process(RESET,sw2_sig,PS2CK,COUNT)begin
if(RESET = '0' )then
COUNT <= "0000";
else
if(sw2_sig= '0')then
COUNT <= "0000";
elsif(PS2CK'event and PS2CK ='0')then
if(COUNT = "1111")then
COUNT <= "0000";
else
COUNT <= COUNT +1;
end if;
end if;
end if;
end process;


続きです。

--ライト動作

process(RESET,PS2CK,COUNT)begin
if(RESET = '0' )then
ADDRESS <= (others => '0');
rfppulse<= '0';
elsif(sw2_sig = '1')then
if(PS2CK'event and PS2CK ='0')then
if(COUNT = "0001")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '1';
we_sig <= '1';
lb_sig <= '1';
ub_sig <= '1';
DATA <= (others => '0');
rfppulse<= '0';
elsif(COUNT = "0010")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '0';
lb_sig <= '0';
ub_sig <= '0';
DATA <= "1010101011110000";
rfppulse<= '0';
elsif(COUNT = "0011")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '0';
lb_sig <= '0';
ub_sig <= '0';
DATA <= "1010101011110000";
rfppulse<= '0';
elsif(COUNT = "0100")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '0';
lb_sig <= '0';
ub_sig <= '0';
DATA <= "1010101011110000";
rfppulse<= '0';
elsif(COUNT = "0101")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '0';
ub_sig <= '0';
DATA <= "1010101011110000";
rfppulse<= '0';
else
ADDRESS <= (others => '0');
oe_sig <= 'Z';
ce_sig <= '0';
we_sig <= 'Z';
lb_sig <= 'Z';
ub_sig <= 'Z';
DATA <= (others => 'Z');
rfppulse<= '1';
end if;
end if;
else
ADDRESS <= (others => 'Z');
oe_sig <= 'Z';
ce_sig <= 'Z';
we_sig <= 'Z';
lb_sig <= 'Z';
ub_sig <= 'Z';
DATA <= (others => 'Z');
rfppulse<= '1';
end if;
end process;
続きです。

--リード動作
process(RESET,SCLK,rcount,sw2_sig,rfppulse)begin
if(RESET = '0' )then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '1';
we_sig <= '1';
lb_sig <= '1';
ub_sig <= '1';
DATA <= (others => '0');
atpdata <= (others => '0');
elsif(sw2_sig = '1')then
if(SCLK'event and SCLK ='0')then
if(rfppulse = '1')then
if(rcount = "0000")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '1';
ub_sig <= '1';
atpdata <= atpdata;
elsif(rcount = "0001")then
ADDRESS <= (others => '0');
oe_sig <= '0';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '0';
ub_sig <= '0';
atpdata <= DATA;
elsif(rcount = "0010")then
ADDRESS <= (others => '0');
oe_sig <= '0';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '0';
ub_sig <= '0';
atpdata <= DATA;
elsif(rcount = "0011")then
ADDRESS <= (others => '0');
oe_sig <= '0';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '0';
ub_sig <= '0';
atpdata <= DATA;
elsif(rcount = "0100")then
ADDRESS <= (others => '0');
oe_sig <= '0';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '0';
ub_sig <= '0';
atpdata <= DATA;
elsif(rcount = "0101")then
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '1';
ub_sig <= '1';
atpdata <= atpdata;
else
ADDRESS <= (others => '0');
oe_sig <= '1';
ce_sig <= '0';
we_sig <= '1';
lb_sig <= '1';
ub_sig <= '1';
atpdata <= atpdata;
end if;
else
ADDRESS <= (others => 'Z');
oe_sig <= 'Z';
ce_sig <= 'Z';
we_sig <= 'Z';
lb_sig <= 'Z';
ub_sig <= 'Z';
DATA <= (others => 'Z');
atpdata <= atpdata;
end if;
end if;
else
ADDRESS <= (others => 'Z');
oe_sig <= 'Z';
ce_sig <= 'Z';
we_sig <= 'Z';
lb_sig <= 'Z';
ub_sig <= 'Z';
DATA <= (others => 'Z');
atpdata <= atpdata;
end if;
end process;
これ全部で一つのソースですか?だとしたら点灯云々の前にコンパイルが通らないと思いますが…。
oe_sigとかce_sigとか複数のprocess文に記述されてる出力信号についてmulti sourceとか言われてると思います。
あと相手がSRAMなのでデータ線以外を'Z'にする必要はありません。
>>[8]
ご指摘ありがとうございます。
すみません、長かったのでSRAM制御部分のみの抜粋になります。

シュミレーションまで実施し、一応LED出力信号に"11110000"が出力されていることを確認していますが、multi接続だったので信号がぶつからないように'Z'で誤魔化したつもり部分は青いです。。

データ線以外を'Z'にする必要がないはおっしゃる通りです;;

他の方からも個別にメッセージをいただいたのですが、
oh!石さんと同様にmulti sourceを指摘されましたので、
諦めてsingle source(って言うのか?)に修正したいと思います。
はじめまして。およよと言います。

FPGAの中でレジスタを生成し、PWM可変できるようにverilog-hdlで記述しています。 (quartus2使用)

コンパイルすると、クリティカルワーニングが出ます。

Critical Warning: Timing requirements for slow timing model timing analysis were not met. See Report window for details.

原因は、リードバックする記述がダメまでは理解しているのですが、
どのようにすれば、改善できるでしょうか?
すみませんが、よろしくお願いします。
-------------------------------------------
module pwm



input _WR,_RD, BL, _RESET, CLK;
inout [15:0] D;
output PWM;

reg [16:0] counter;
reg [4:0] pwm_reg;

/*---- counter ----*/
always @(posedge CLK or posedge ~_RESET) // 66MHz -> 503Hz
begin
if( ~_RESET )
begin
counter <= 17'h00;
end
else
begin
counter <= counter + 17'h01;
end
end

/*---- register ----*/
always @(posedge ~_WR or posedge ~_RESET )
begin
if( ~_RESET )
begin
pwm_reg <= 5'h00;
end
else
if( BL )
begin
pwm_reg <= D[15:11];
end
end

/*---- read back ----*/
assign D[15:11] = ( BL && ~_RD )? pwm_reg : 5'hzz;

/*---- compare ----*/
always @(posedge CLK or posedge ~_RESET )
begin
if( ~_RESET )
begin
PWM <= 1'b0;
end
else
if( pwm_reg > counter[16:12])
begin
PWM <= 1'b1;
end
else
begin
PWM <= 1'b0;
end
end



endmodule
そのままズバリはわかりませんが、
ここはコレじゃなきゃダメですか?

>> always @(posedge ~_WR or posedge ~_RESET )

上位モジュールが不明なので確定はできませんが、
レジスタが非同期になってんじゃないかと思います。

=============================================
/*---- register ----*/
always @(negedge _RESET or posedge CLK ) begin
if( ~_RESET ) begin
pwm_reg <= 5'h00;
end else begin
if( ~_WR & BL ) begin
pwm_reg <= D[15:11];
end
end
end
=============================================

クロックで叩くとレイテンシとかまずかったりします?
>ひろさん
はじめまして。また早急なコメントありがとうございます。

ハードの関係上、always文でライト信号を記載しています。
一応コメントで頂いた記述でトライさせていただきましたが、PWM制御はできているのですが、
レジスタのリードバックができない状態です。

素人なもので恐縮ですが、案を頂けると幸いです。

質問したクリティカルワーニングではPWM制御かつレジスタのリードバックができる状態です。
結論から言うと、
動いてるんならいいんじゃない?
タイミング解析が出来ないという内容なので、望みの動きが確認出来てれば良いかと思います。
(論理設計の後輩がコレを書いてきたら説教ですが冷や汗)

上記踏まえた上でいくつか書きます。
> ハードの関係上、always文でライト信号を記載しています。
ハードの関係というのがどういうものかわかりませんが、非同期が混じると警告は出るかと思います。
他のalways文と同じようにクロックの立ち上がりでpwm_reg が確定するようにしてください。
(_WR の立ち下がりでラッチしたものが即座に端子に出て行くようになっているので…)

あと、書かれていないのでわかりませんが、双方向(inout)のportとなっているDの処理は適切に行われているでしょうか?
(_WR信号と_RD 信号が排他的になっているということを合成Toolに伝える記述ができているかどうかなど。)
=============================================
/*---- read back ----*/
assign D[15:11] = ( {wr_en, rd_en} == 2'b01 )? pwm_reg : 5'hzz;
assign wr_en = (~_WR & BL );
assign rd_en = ( BL & ~_RD );
=============================================
>ひろさん
ありがとうございます。

非同期をやめて、同期で行う+WRとRDの定義すると望みの動きとクリティカルワーニング消えることができました。Dの処理も適切に行い、問題ありません。

色々教えて頂きありがとうございます。
できる限り自分で問題解決できるように頑張ります。
通って良かったです。
(自分もわからなけりゃさっくり聞いちゃいます)

ちなみにこのRTLの入力って、FPGAの端子直結でクロックの立ち上がりエッジ同期ですかね?
その場合、セットアップ/ホールドの値によってはFPGA/対抗装置がともにデータを取りこぼす可能性があります。
対処法としてFPGAの同期をクロックの立ち下がりで取るという方法もありますので、タイムチャートを眺めながらご検討ください。
(PWM制御の機器なら多少取りこぼしても問題になることは少なそうですが、念のため…)

=============================================
//* 立ち上がりエッジ
always @(negedge _RESET or posedge CLK ) begin

//* 立ち下がりエッジ
always @(negedge _RESET or negedge CLK ) begin
=============================================
>ひろさん
ありがとうございます。

実はこの件で、再び悩んでおります・・・。
この仕様ではデータが00で最小、FFで最大になるのですが、
別仕様では00が最大、00で最小になり、ソフトの設定上、統一するために変更してほしいと
依頼があり、データの論理を逆にしました。
すると、PWMが以前より500ms早く立ち上がってしまいました。。。

シーケンスの関係上、PWMを500ms立ち上げるのを遅くしてほしいといわれ、悩んでいます。。。
FPGAが立ち上がると同時にcounterが動く為、結果そうなってしまうのがわかるのですが、
どうすればいいかわからず、苦戦しています。。。

P.S.
FPGAの同期をクロックの立ち下がりで取るという方法もタイムチャートで確認してみます。


今の式は以下のようになります。
-------------------------------------------
module pwm



input _WR,_RD, BL, _RESET, CLK;
inout [15:0] D;
output PWM;

reg [16:0] counter;
reg [4:0] pwm_reg;

wire wr_en
wire rd_en

/*---- counter ----*/
always @(posedge CLK or posedge ~_RESET) // 66MHz -> 503Hz
begin
if( ~_RESET )
begin
counter <= 17'h00;
end
else
begin
counter <= counter + 17'h01;
end
end

/*---- register ----*/
always @(posedge CLK or posedge ~_RESET )
begin
if( ~_RESET )
begin
pwm_reg <= 5'h00;
end
else
if( BL & ~_WR)
begin
pwm_reg <= ~D[15:11]; //DATA値反転
end
end

/*---- read back ----*/
assign D[15:11] = ( {wr_en, rd_en} == 2'b01 )? pwm_reg : 5'hzz;
assign wr_en = ( BL & ~WR );
assign rd_en = ( BL & ~_RD );

/*---- compare ----*/
always @(posedge CLK or posedge ~_RESET )
begin
if( ~_RESET )
begin
PWM <= 1'b0;
end
else
if( pwm_reg > counter[16:12])
begin
PWM <= 1'b1;
end
else
begin
PWM <= 1'b0;
end
end



endmodule
現象が、立ち上がり500[ms]早まるという事だけならば、
自分は、ソフトに500[ms]のwait入れさせます。
(ソフトでやるほうが楽だし速い。)

FPGAでやる場合いろいろ方法はあるでしょうけれど、
その前にいくつか疑問が…

一つはココ
=============================================
pwm_reg <= ~D[15:11]; //DATA値反転
=============================================
Count up -> Count downにしたいんだと思いますが、この部分のbit反転だけで大丈夫?
(ココに出てこないD[10:0]の値との整合性など)

もう一つはココ
=============================================
assign D[15:11] = ( {wr_en, rd_en} == 2'b01 )? pwm_reg : 5'hzz;
=============================================
read back 時にbit反転戻さなくて大丈夫?
ひろさん
おはようございます。
countUPでbit反転は大丈夫でした。

Readbackは戻さないとダメですね。。。
反転した状態で表示出てました。。。

確かにソフトの方が楽なので、そっちも含めて検討します。

でも最悪FPGAだけでもできるように色々頑張ってみます!

ログインすると、残り7件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

FPGA/CPLD友の会 更新情報

FPGA/CPLD友の会のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング