シミュレーション実施時に不定値が伝播したと書きましたが,SOPC上でのIPコアの設定が一部まずかったのが要因のようです.
結論に至る前に,そもそもPLLが安定するまでの間はどうなっているのかという疑問を払拭するために調べてみました.
そのメモをここに掲載しておきます.
前回の記事で注目していたのは,SOPC上でインスタンス化した,PLLとDDRSDRAM(HP)コントローラでした.それぞれについて確認しましょう.
資料の読み取りは,[Q2HB]PLLを参照ください.
仕様書にSOPC全域にリセット要求を発します,と明記してありました.
DDRSDRAM(HP)のreset_request_n信号をどのように処理しているかを確認する.SOPC Builderが作ったファイルを開いて,DDR moduleのインスタンス化コードを参照し,そこから当該信号がどのnetにぶら下がっているかを確認する.
ddrsdram_s1_arbitratorに入力されているだけだったので,該当モジュールを見る.
module ddrsdram_s1_arbitrator (
input ddrsdram_s1_resetrequest_n;
output ddrsdram_s1_resetrequest_n_from_sa;
wire ddrsdram_s1_resetrequest_n_from_sa;
//assign ddrsdram_s1_resetrequest_n_from_sa = ddrsdram_s1_resetrequest_n
// so that symbol knows where to group signals which may go to master only, which is an e_assign
assign ddrsdram_s1_resetrequest_n_from_sa = ddrsdram_s1_resetrequest_n;
ddrsdram_s1_resetrequest_n_from_saへ常時代入されていることがわかる.インスタンス化しているところに戻ると,この出力信号を束ねているところがある.
//reset sources mux, which is an e_mux
assign reset_n_sources = ~(~reset_n |
0 |
0 |
cpu_jtag_debug_module_resetrequest_from_sa |
cpu_jtag_debug_module_resetrequest_from_sa |
0 |
~ddrsdram_s1_resetrequest_n_from_sa |
~ddrsdram_s1_resetrequest_n_from_sa |
0 |
pll0_s1_resetrequest_from_sa |
pll0_s1_resetrequest_from_sa);
reset_n_sourcesが,システム全体のリセット要求が無いことを確認する信号になっている模様(未検証).
//reset is asserted asynchronously and deasserted synchronously
Nios2_NoDDR_reset_SysClk_domain_synch_module Nios2_NoDDR_reset_SysClk_domain_synch
(
.clk (SysClk),
.data_in (1'b1),
.data_out (SysClk_reset_n),
.reset_n (reset_n_sources)
);
//reset is asserted asynchronously and deasserted synchronously
Nios2_NoDDR_reset_osc_clk_domain_synch_module Nios2_NoDDR_reset_osc_clk_domain_synch
(
.clk (osc_clk),
.data_in (1'b1),
.data_out (osc_clk_reset_n),
.reset_n (reset_n_sources)
);
osc_clk(FPGA外部からの唯一のクロック)を用いて,非同期リセット+同期リセット解除の信号SysClk_reset_n・osc_clk_reset_nを生成する.clock domainが複数存在するが,それぞれで同期化して出力している.
このリセット信号を誰が使っているのかを見ていくと...
ddrsdram the_ddrsdram (
.soft_reset_n (osc_clk_reset_n)
pll0_s1_arbitrator the_pll0_s1
.reset_n (osc_clk_reset_n)
Nios2_NoDDR_clock_0_out_arbitrator the_Nios2_NoDDR_clock_0_out
.reset_n (osc_clk_reset_n)
ということで,各IPのリセット要求が解除されるまではシステムが停止する仕様になっています.DDR-SDRAMについては,PLL安定するまではリセット要求を出します.また,PLLのリセットを行わない,PHYだけのリセット要求入力に,同期化したシステムリセット要求信号が入ります.リセット解除の同期化は,どちらが先になるのかわからないので,厳密には一番遅い周期にあわせたウェイトを入れてやる必要があるのかもしれません.FIFOにリクエストを積み上げるのであれば,リセットタイミングが多少ずれても,Power on reset直後の値さえ合致していれば,レイテンシが少しかさむだけで問題なく動くでしょう.
IP側でPLL発振安定までの間に不定値が伝播するような問題はない.
→PLL lock待ちの回路も自作は不要.
ただし,ALTPLLの"locked"信号を出力する設定にしておくことが必要!!そのほか,ResetRequest信号が出ているIPについては,その出力を有効にしておく必要があるでしょう(未確認).
シミュレーション実施時には,PLL側の"locked"信号を出していなかったので,システムリセットがネゲートされていたと考えられます.
正しく?設定をすると,問題なくModelSIM WEB editionでFunction Simulationの実行ができました.