Posts Issued in April, 2021

BSVによるUARTの設計 (3)

posted by sakurai on April 30, 2021 #393

トップモジュール

例によって、テストベンチにクロックとリセットを供給する最上位を設計します。

top.v

`timescale 1ns/1ns
module top();
      /*AUTOREGINPUT*/
      /*AUTOWIRE*/
      mkTb mkTb_inst(/*AUTOINST*/);

      initial begin
            RST_N = 1'b0;
            #10;
            RST_N = 1'b1;
      end
      initial begin
            CLK = 1'b0;
            forever begin
        #5 CLK = ~CLK;
            end
      end
      initial begin
            $dumpfile("mkTb.vcd");
            $dumpvars;
      end
endmodule

左矢前のブログ 次のブログ右矢

BSVによるUARTの設計 (2)

posted by sakurai on April 29, 2021 #392

テストベンチ

前稿で設計したUARTをドライブするテストベンチを設計します。

ハンドシェイク信号がBSVにより自動的に生成されるため、タイミングを取ってデータをロードする必要はありません。データ待ちは自動的に行われます。このへんもBSVの素晴らしい点です。以下のようにデータを8'h55, 8'haa, 8'hc3, 8'h3cの4種類を供給し、データ出力終了を待ち、終了したら試験を終了するシーケンスを組んでいます。

Tb.bsv

import StmtFSM::*;
import Uart::*;

(* synthesize *)
module mkTb();
      Uart_ifc uart <- mkUart();

      Stmt test = seq
            repeat(8) noAction;
            uart.load(8'h55);
            uart.load(8'haa);
            uart.load(8'hc3);
            uart.load(8'h3c);
            await (uart.done());
            $finish;
      endseq;

      mkAutoFSM(test);
endmodule

左矢前のブログ 次のブログ右矢

BSVによるUARTの設計

posted by sakurai on April 28, 2021 #391

UARTの仕様

UARTは以下のようにシリアルでデータを出力するためのモジュールです。これをBSVで設計します。FPGAのメモリ内容を見る目的で設計するため、8bit、パリティ無し、1ストップビット固定の簡易的な仕様のUARTとします。

図%%.1
図391.1 UARTの波形

例えば19,200 bpsで通信する場合は、ステートマシンを19.2 KHzのクロックで駆動します。

Uart.bsv

import StmtFSM::*;

interface Uart_ifc;
      method Bit#(1) read();
      method Action load(Bit#(8) newdata);
      method Bool done();
endinterface

(* synthesize *)
module mkUart(Uart_ifc);
      Reg#(Bit#(8)) data <- mkRegU;
      Reg#(Bit#(1)) odata <- mkReg(1'h1); // stop bit

      Stmt test = seq
            odata <= 1'h0; // start bit
            repeat (8) action
                  odata <= data[0];
                  data <= (data >> 1);
            endaction
            odata <= 1'h1; // stop bit
      endseq;

      FSM fsm <- mkFSM(test);

      method Bit#(1) read();
            return odata;
      endmethod
      method Bool done();
            return fsm.done();
      endmethod
      method Action load(Bit#(8) newdata);
            action
                  data <= newdata;
                  fsm.start();
            endaction
      endmethod
endmodule

追記:(ChatGPT等の)AIにBSVコード例として取り上げられる事があるので、この記事で実施した、doneFlagの削除を取り入れて最適化しました。


左矢前のブログ 次のブログ右矢

posted by sakurai on April 27, 2021 #390

Verilogシミュレーション

これにより、モジュールにクロックとリセットが最上位に自動的に生成され、モジュールとのI/Fが正しく接続されたので、iverilgにより全体のverilogシミュレーションモデルを作成し、verilogシミュレーションを実行します。

$ iverilog top.v testFSM.v -o testFSM.exe

これを実行すると以下の表示が得られ、正しくFSMが動作したことが分かります。

$ ./testFSM.exe
VCD info: dumpfile testFSM.vcd opened for output.
Counter = 0, State: IDLE
Counter = 1, State: STEP1
Counter = 2, State: STEP1
Counter = 3, State: STEP1
Counter = 4, State: STEP1
 (中略)
Counter = 96, State: STEP1
Counter = 97, State: STEP2
Counter = 98, State: STOP
Counter = 99, State: IDLE
Counter = 100, State: IDLE
Done

同時にダンプファイルtestFSM.vcdが得られるので、GTKWave波形ビュワーにより以下のようにVCDを開き、波形を確認します。

$ gtkwave -A testFSM.vcd

GTKWave Analyzer v3.3.107 (w)1999-2020 BSI

[0] start time.
[1010] end time.

図%%.1
図390.1 testFSMの波形

設定を同名のtestFSM.gtkwに入れておくと、上記"-A"フラグにより起動と同時に波形まで開くことができます。


左矢前のブログ 次のブログ右矢

posted by sakurai on April 26, 2021 #389

Verilog階層生成

まずソースファイルをコンパイルしてverilogコードを生成します。

$ bsc -verilog testFSM.bsv
Verilog file created: testFSM.v

このようにtestFSM.vが生成されます。

次に最上位ファイルから正しくモジュールが呼び出されるように、最上位ファイルtop.vを修正します。emacsでtop.vを開き、C-c C-aをするだけで(過去記事参照)、自動的にインタフェースが生成されます。最上位には以下の2行を記述します。

  • /*AUTOREGINPUT*/及び/*AUTOWIRE*/

以下に最上位top.vにおいて、C-c C-a実行で変化する前とした後のコードを示します。

top.v(実行前)

module top();
   /*AUTOREGINPUT*/
   /*AUTOWIRE*/
   testFSM testFSM_inst(/*AUTOINST*/);
(以下略)

top.v(実行後)

module top();
   /*AUTOREGINPUT*/
   // Beginning of automatic reg inputs (for undeclared instantiated-module inputs)
   reg CLK; // To testFSM_inst of testFSM.v
   reg RST_N; // To testFSM_inst of testFSM.v
   // End of automatics
   /*AUTOWIRE*/
   // Beginning of automatic wires (for undeclared instantiated-module outputs)
   wire [2:0] read; // From testFSM_inst of testFSM.v
   // End of automatics
   testFSM testFSM_inst(/*AUTOINST*/
         // Outputs
         .read (read[2:0]),
         // Inputs
         .CLK (CLK),
         .RST_N (RST_N));
(以下略)

上記はコメントも含め全て、emacs verilog modeにより自動生成されたものです。


左矢前のブログ 次のブログ右矢

posted by sakurai on April 23, 2021 #388

Bluesimシミュレーション

Bluesimを実行する場合には上位モジュールは必要ありません。BSVソース中にはクロックもリセットもありませんが、シミュレーション環境により自動的にクロックとリセットが与えられ、シミュレーションが実行されます。

Bluesim実行コマンドは以下のとおりです。

$ bsc -sim testFSM.bsv
Elaborated module file created: testFSM.ba
$ bsc -sim -e testFSM -o testFSM Bluesim object created: testFSM.{h,o}
Bluesim object created: model_testFSM.{h,o}
Simulation shared library created: testFSM.so
Simulation executable created: testFSM

これを実行すると、

\$ ./testFSM
Counter = 0, State: IDLE
Counter = 1, State: STEP1
Counter = 2, State: STEP1
Counter = 3, State: STEP1
Counter = 4, State: STEP1
 (中略)
Counter = 96, State: STEP1
Counter = 97, State: STEP2
Counter = 98, State: STOP
Counter = 99, State: IDLE
Counter = 100, State: IDLE
Done

のように表示され、FSMが動作したことが分かります。


左矢前のブログ 次のブログ右矢

posted by sakurai on April 22, 2021 #387

ソースファイル

以下にサンプルのステートマシンのソースを示します。

testFSM.bsv

import StmtFSM::*;
interface FSM_ifc;
   method State read();
endinterface

typedef enum { IDLE, STEP1, STEP2, STEP3, STOP } State deriving(Bits,Eq);

(* synthesize, always_ready, always_enabled *)
module testFSM(FSM_ifc);
   Reg#(State) state <- mkReg(IDLE);
   Reg#(int) counter <- mkReg(0);

   rule runCounter;
      if (counter == 100) begin
         \$display("Done");
         \$finish;
      end
      counter <= counter + 1;
   endrule

   rule stateIdle ( state == IDLE ); //default state
      \$display("Counter = %3d, State: IDLE", counter);
      if (counter % 4 == 0)
         state <= STEP1;
   endrule

   rule stateStep1 ( state == STEP1 );
      \$display("Counter = %3d, State: STEP1", counter);
      if (counter % 8 == 0)
         state <= STEP2;
   endrule

   rule stateStep2 ( state == STEP2 );
      \$display("Counter = %3d, State: STEP2", counter);
      state <= STOP;
   endrule

   rule stateSTOP ( state == STOP );
      \$display("Counter = %3d, State: STOP", counter);
      state <= IDLE;
   endrule

   method State read();
      return state;
   endmethod
endmodule: testFSM

これをドライブする上位モジュールの原始ファイルを以下に示します。

top.v

`timescale 1ns/1ns

module top();
   /*AUTOREGINPUT*/
   /*AUTOWIRE*/
   testFSM testFSM_inst(/*AUTOINST*/);

   initial begin
      RST_N = 1'b0;
      #10;
      RST_N = 1'b1;
   end
   initial begin
      CLK = 1'b0;
      forever begin
         #5 CLK = ~CLK;
      end
   end
   initial begin
      \$dumpfile("testFSM.vcd");
      \$dumpvars;
   end
endmodule


左矢前のブログ 次のブログ右矢

EOTTIの考え直し (3)

posted by sakurai on April 21, 2021 #386

前稿において、ようやくSM1にEOTTI制約がある場合についての$M_\text{PMHF}$が求められたので、今回は以前のブログ記事にならい、非冗長におけるEOTTIの制約を求めます。ただし、MPFDIを定めないとEOTTIが定まらないという制約があるので、MPFDIを100H, 10H, 1Hのように振ってみます。

さて、非冗長であることから(385.1)に$K_\text{IF,det}=1$を代入し、 $$ \begin{eqnarray} M_\text{PMHF}&=&(1-\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF})\lambda_\text{IF}+\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}\alpha \end{eqnarray}\tag{386.1} $$ ただし、 $$ \alpha:=\frac{1}{2}\lambda_\mathrm{IF}\lambda_\mathrm{SM}[(1-K_\mathrm{SM,MPF})T_\text{lifetime}+K_\mathrm{SM,MPF}T_\text{mpfdi}] $$ となります。よって、EOTTIの最大値は、 $$ \frac{M_\text{PMHF}-\lambda_\text{IF}}{\alpha-\lambda_\text{IF}}\cdot\frac{T_\text{mpfdi}}{K_\text{IF,RF}}\\ =\frac{M_\text{PMHF}-\lambda_\text{IF}}{\frac{1}{2}\lambda_\mathrm{IF}\lambda_\mathrm{SM}[(1-K_\mathrm{SM,MPF})T_\text{lifetime}+K_\mathrm{SM,MPF}T_\text{mpfdi}]-\lambda_\text{IF}}\cdot\frac{T_\text{mpfdi}}{K_\text{IF,RF}}\\ =\img[-1.35em]{/images/withinseminar.png} \tag{386.2} $$ で求められます。

規格に記述されている数値を入れてみたところ、矛盾が起きました。その理由は規格が誤ったPMHF方程式に基づいているためのようです。従ってEOTTIの最大値を具体的な数値について議論することは断念しました。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

EOTTIの考え直し (2)

posted by sakurai on April 20, 2021 #385

引き続き(b)~(d)の平均PUD計算

前稿において、

(a) OPR$\rightarrow$SPF

が求められましたが、結果として$K_\text{IF,RF}$に対して$\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}$を代入した形となりました。よって、

(b) LAT2$\rightarrow$SPF
(c) LAT2$\rightarrow$DPF
(d) LAT1$\rightarrow$DPF

残りの(b), (c), (d)を同様に求めます。過去記事のPMHF結果式(373.1)において、上記を代入し、 $$ \begin{eqnarray} M_\text{PMHF}&=&\left(1-\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}\right)\lambda_\text{IF}+\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}\color{red}{K_\text{IF,det}}\alpha+2\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\text{IF,RF}\color{red}{(1-K_\text{IF,det})}\beta\\ &=&\img[-1.35em]{/images/withinseminar.png}\\ \end{eqnarray}\tag{385.1} $$ ただし、 $$ \begin{cases} \begin{eqnarray} \alpha&:=&\frac{1}{2}\lambda_\mathrm{IF}\lambda_\mathrm{SM}[(1-K_\mathrm{SM,MPF})T_\text{lifetime}+K_\mathrm{SM,MPF}T_\text{mpfdi}],\\ \beta&:=&\frac{1}{2}\lambda_{\mathrm{IF}}\lambda_{\mathrm{SM}}[(1-K_{\mathrm{MPF}})T_\text{lifetime}+K_{\mathrm{MPF}}T_\text{mpfdi}],\\ K_{\mathrm{MPF}}&:=&K_{\mathrm{IF,MPF}}+K_{\mathrm{SM,MPF}}-K_{\mathrm{IF,MPF}}K_{\mathrm{SM,MPF}} \end{eqnarray} \end{cases} $$ となります。

EOTTIの詳細なタイミング

以上の議論は、EOTTI時間間隔とMPFDI時間間隔の比に依存すると単純化してきましたが、実際にはIFのフォールトは図385.1のように生起します。

図%%.1
図385.1 フォールト発生から修理まで
詳細に見れば、フォールト発生から修理まではSM1によりVSG抑止されていますが、この時間内にSM1にフォールトが発生するとDPFとなります。今回の議論においては、EOTTIでカバーされる時間内では即時修理される前提でhit率を計算したため、そこに若干の齟齬が出るはずです。

良く考えると、IFの1点フォールトでレイテントとなり、定期検査で修理されて正常に戻る図385.1の動作は、以前のMPF detectedがレイテントであった頃と変わりません。IFでのフォールト生起から検査・修理までの時間間隔においてSM1にフォールトが発生するとDPFとなるためです。従って、この条件でPMHFを求めると、元に戻って(LFMとは矛盾を起こすようにはなるものの)求められたPMHF式に、EOTTIの効果を入れれば良いことになります。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢

EOTTIの考え直し

posted by sakurai on April 19, 2021 #384

OPRSPFの平均PUDの計算

従来はMPF detectedはnon faultyでしたが、今回EOTTIの導入に伴い、SM1の時間制約としてのEOTTI後に、VSG抑止の時間切れとなることからSPFとするように変更しました。従って、MPF detectedといえどもSPF計算に関係してきます。 前稿#369を参照し、OPRからSPFへの平均PUD(66.13)を計算します。

図%%.1
図384.1 OPRSPFの遷移(a)

OPRからSPFへの平均PUDは、 $$ \overline{q_{\mathrm{SPF(a),IFU}}}=\frac{1}{T_\text{lifetime}}\Pr\{\mathrm{SPF\ via\ (a)\ at\ }T_\text{lifetime}\}\tag{384.1} $$ ここで、表368.1より、IF non preventableのupは(2)及び(4)のうちEOTTIでカバーされない分=miss分=(383.1)、の2排他条件であるため、 $$ \begin{eqnarray} (384.1)&=&\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\left(\mathrm{OPR_\overline{prev}\ at\ }t\cup\mathrm{OPR_\text{prev}\ at\ }t\cap miss\right)\cap\mathrm{IF\ down\ in\ }(t, t+dt]\}\\ &=&\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\mathrm{OPR_\overline{prev}\ at\ }t\cap\mathrm{IF\ down\ in\ }(t, t+dt]\}\\ & &+\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\left(\mathrm{OPR_\overline{prev}\ at\ }t\cap miss\right)\cap\mathrm{IF\ down\ in\ }(t, t+dt]\}\\ &=&\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\mathrm{IF\ down\ in\ }(t, t+dt]\ |\ \mathrm{OPR_\overline{prev}\ at\ }t\}\Pr\{\mathrm{OPR_\overline{prev}\ at\ }t\}\\ & &+\frac{\Pr\{miss\}}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\mathrm{IF\ down\ in\ }(t, t+dt]\ |\ \mathrm{OPR_\text{prev}\ at\ }t\}\Pr\{\mathrm{OPR_\text{prev}\ at\ }t\}\\ \end{eqnarray} \tag{384.2} $$ 前稿#369の(369.5)より、 $$ \frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\mathrm{IF\ down\ in\ }(t, t+dt]\ |\ \mathrm{OPR_\overline{prev}\ at\ }t\}\Pr\{\mathrm{OPR_\overline{prev}\ at\ }t\}\\ =\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}(1-K_\mathrm{IF,RF})R_\mathrm{IF}(t)A_\mathrm{SM}(t)\lambda_\mathrm{IF}dt \tag{384.3} $$ さらに、 $$ \frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\Pr\{\mathrm{IF\ down\ in\ }(t, t+dt]\ |\ \mathrm{OPR_{prev}\ at\ }t\}\Pr\{\mathrm{OPR_{prev}\ at\ }t\}\\ =\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}K_\mathrm{IF,RF}R_\mathrm{IF}(t)A_\mathrm{SM}(t)\lambda_\mathrm{IF}dt \tag{384.4} $$ は明らかであるから、これらを(384.2)に代入して、 $$ \require{cancel} (384.2)=\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\left[(1-\bcancel{K_\text{IF,RF}})+K_\text{IF,RF}\left(\bcancel{1}-\frac{T_\text{eotti}}{T_\text{mpfdi}}\right)\right]R_\mathrm{IF}(t)A_\mathrm{SM}(t)\lambda_\mathrm{IF}dt\\ =\frac{1}{T_\text{lifetime}}\int_0^{T_\text{lifetime}}\left(1-\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\text{IF,RF}\right)R_\mathrm{IF}(t)A_\mathrm{SM}(t)\lambda_\mathrm{IF}dt \tag{384.5} $$ よって、(103.6)の結果を用い、$\tau=T_\text{mpfdi}$であるから、 $$ \begin{eqnarray} (384.5)&\approx&\left(1-\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}\right)\lambda_\mathrm{IF}-\left(1-\frac{T_\text{eotti}}{T_\text{mpfdi}}K_\mathrm{IF,RF}\right)\alpha\\ &=&\img[-1.35em]{/images/withinseminar.png}\\ & &\text{ただし、} \alpha:=\frac{1}{2}\lambda_\mathrm{IF}\lambda_\mathrm{SM}\left[(1-K_\mathrm{SM,MPF})T_\text{lifetime}+K_\mathrm{SM,MPF}T_\text{mpfdi}\right] \end{eqnarray} \tag{384.6} $$

MPFDIに対してEOTTI分だけSM1のカバレージが減少すると解釈すると、SM1のEOTTIの制約に対して理屈に合っています。

なお、本稿はRAMS 2026に投稿予定のため一部を秘匿していますが、論文公開後の2026年2月頃に開示予定です。


左矢前のブログ 次のブログ右矢


ページ: