[1chipMSX]

[HDL] DIP-SW6 = on での 10MHz 動作時に希に起動失敗するのを改善する。[2007/01/08]

原因を調査する。

先の緑LED改造によって、未使用LEDが7つあるので、そこに iSlotBot 信号を出してみる。
この信号は、起動時に '1' になり、IPLROM という wired ROMFPGA内蔵RAM上に確保されたROM のスロットを選択するっぽい。
'1' の時に LED が点灯するので、起動時に1秒くらい点灯して消えた後に MSXロゴが表示される。
IPLROM には 512byte くらいのコードがあるが、どうやらこいつが コンフィグROM から、
BIOS 等の ROMイメージを吸い出して SD-RAM (MSX から見ると似非RAM)へ転送するカラクリらしい。
MSXとして起動する前に、Z80 を起こして、そいつに ROMイメージを転送させる・・面白い仕組みです。

で、起動失敗するケースでは、iSlotBot = '1' のまま固まることが確認出来た。
起動と同時に SDカードを挿入すると、その状態に陥りやすいことも確認した。

10MHz だと IPLROM で固まってしまうケースがあるようなので、IPLROM を実行中だけ強制的に 3.6MHz モードに
する改造を入れてみました。
以下がその修正部分。emsx_top.vhd です。

※今のところ、この改造を入れてから起動失敗を経験してません。


-- pCpuClk <= cpuclk  when SelfMode = '1' and clksel = "00" else
--       clkdiv(0) when SelfMode = '1' and clksel = "01" else
--       clkdiv(1) when SelfMode = '1' and clksel = "10" else
--       clk21m  when SelfMode = '1' and clksel = "11" else 'Z';

 pCpuClk <= cpuclk  when SelfMode = '1' and(clksel = "00" or iSltBot = '1')else
       clkdiv(0) when SelfMode = '1' and clksel = "01" else
       clkdiv(1) when SelfMode = '1' and clksel = "10" else
       clk21m  when SelfMode = '1' and clksel = "11" else 'Z';


IPLROM での動作を 3.6MHz に落とさずに安定動作にする [2007/02/10]

pCpuClk は、FPGA やコンパイラから見れば、単に FPGA外へ出て行く信号でしかありませんが、
実際は基板上で迂回して FPGA のクロック用入力信号に接続されており、それが CPU のクロック入力や、
やカートリッジスロットのクロック出力へ接続されています。
従って、pCpuClk にハザード(ヒゲ)が載ったりするのは好ましくありません。ここへ出す信号は安定して
いなければなりません。
安定させるには、普通は FF で叩きますが、CLK を出すのに、その CLK 自身で動作する FF で叩くことはできません。
従って、FF で叩いた別の信号を、AND ゲート1個あるいは OR ゲート 1個でゲートして出力するのがベストだと思います。
(1chipMSX の場合、89MHz の内部クロックも持っているので、その FF で CLK を叩いても良いかもしれませんが)

clksel を FF にして、クロック選択条件は clksel 決定前に決めてしまいます。
決定された clksel の 1bit だけで出力クロックをゲートすることで綺麗な pCpuClk を得ます。
上の改造と違って、10MHz モードでは 10MHz で IPLROM が動作するので、10MHz モード時の起動が速くなります。

※今のところ、この改造を入れてから起動失敗を経験してません。

 process( reset, clk21m )
 begin
  if( reset = '1' )then
   ff_clksel <= '0';           -- 3.58MHz (standard speed)
  elsif( clk21m'event and clk21m = '0' )then
   if( (cpuclk = '0') and (clkdiv = "00") and (w_10hz = '1') )then
    if( RedMode = '0' )then
     ff_clksel <= '0';         -- 3.58MHz (standard speed)
    else
     ff_clksel <= '1';         -- 10.74MHz (workaround for boot failure)
    end if;
   end if;
  end if;
 end process;

 -- ※FFで叩いた信号 1bitだけで選択すること (pCpuClk にヒゲが出ると不安定になる)
 pCpuClk <= cpuclk   when( ff_clksel = '0' )else
       clkdiv(0);

改造をやりやすくするために、信号名や構造を整理しながら改変しているため、信号名が一部変わっています。
改変後のソース全体は、上に戻って、最新版デザインデータをダウンロードして確認してください。その他の修正も含まれてます。
w_10hz は、フリーランカウンタを見ながら、10hz くらいの周期でパルス(21MHz幅)が出てくる信号です。
ここでは、クロック切り替えスイッチ(DIP-SW6)のチャタリングを防止する目的で使用しています。
また、DIP-SW6 は、MSXとして動作中にも切り替えられるため、何か重い処理の時だけ 10MHz に切り替えて使うことも出来ます。

[▲上へ]