Posts Tagged with "Design"

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.
posted by sakurai on December 5, 2022 #563

bsimシミュレーション

このソースに対して、以下のようにコンパイル、bsimシミュレーションを実行します。太字が入力部分です。

$ bsc -sim Tb.bsv; bsc -sim -e mkTb -o mkTb.exe
Elaborated module file created: mkTb.ba
Bluesim object created: mkTb.{h,o}
Bluesim object created: model_mkTb.{h,o}
Simulation shared library created: mkTb.exe.so
Simulation executable created: mkTb.exe
$ ./mkTb.exe -V
------
------
pc_if = 0000
------
pc_if = 0004
pc_id = 0000
------
pc_if = 0008
pc_id = 0004
pc_ex = 0000
------
pc_if = 000c
pc_id = 0008
pc_ex = 0004
pc_ma = 0000
------
pc_if = 0010
pc_id = 000c
pc_ex = 0008
pc_ma = 0004
pc_wb = 0000
------
pc_if = 0014
pc_id = 0010
pc_ex = 000c
pc_ma = 0008
pc_wb = 0004

のように正しくパイプラインが動作しました。また、gtkwaveで取得したタイムチャートを図563.1に示します。

図%-%.1
図563.1 PCパイプラインタイムチャート

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

posted by sakurai on December 3, 2022 #562

BSVのFIFO調査

BSVにおいて、パイプラインレジスタとしてFIFOを使用できるか調査します。まず、PCパイプラインを設計します。PCパイプラインとは、各ステージのPCを保持することで、例えば各ステージにおいてEIT(例外、割り込み、トラップ)が起きた場合、EITが起こった命令アドレスをハンドラに正しく伝えるためのものです。

Tb.bsv

  import FIFO::*;

  (* synthesize *)
  module mkTb (Empty);

     Reg#(int) pc    <- mkReg(0);
     FIFO#(int) ifs    <- mkFIFO;
     FIFO#(int) ids    <- mkFIFO;
     FIFO#(int) exs    <- mkFIFO;
     FIFO#(int) mas    <- mkFIFO;
     FIFO#(int) wbs    <- mkFIFO;

     // <PC>
     rule pc_stage;
        if (pc > 100) $finish(0);
        $display("------");
        ifs.enq(pc);
        pc <= pc + 4;
     endrule

     // <IF>
     rule if_stage;
        let pc_if = ifs.first; ifs.deq;
        $display (" pc_if = %04h", pc_if);
        ids.enq (pc_if);
     endrule

     // <ID>
     rule id_stage;
        let pc_id = ids.first; ids.deq;
        $display (" pc_id = %04h", pc_id);
        exs.enq (pc_id);
     endrule

     // <EX>
     rule ex_stage;
        let pc_ex = exs.first; exs.deq;
        $display (" pc_ex = %04h", pc_ex);
        mas.enq (pc_ex);
     endrule

     // <MA>
     rule ma_stage;
        let pc_ma = mas.first; mas.deq;
        $display (" pc_ma = %04h", pc_ma);
        wbs.enq (pc_ma);
     endrule

     // <WB>
     rule wb_stage;
        let pc_wb = wbs.first; wbs.deq;
        $display (" pc_wb = %04h", pc_wb);
     endrule

  endmodule: mkTb

ここで、<PC>は入力レジスタは無いため、ここではFIFOは使用しません(が、後で検討します)。単にPCレジスタを設置するだけです。これは<PC>(PCステージ)のPCということになります。通常はPC<=PC+4ですが、分岐時等ではオフセットが足されます。

各ステージでは、入力されたPCをデキューし、表示し、サイクルの終わりで次のステージにそのPCをエンキューします。

図%-%.1
図562.1 FIFOのDequeuとEnqueueの関係
従って、同一サイクルでエンキューしたものをデキューする(バイパス、パススルー)ことはできません。

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

posted by sakurai on December 2, 2022 #561

画面の縦横の入れ替えの変更

過去記事において、本来VRAMの読み出しアドレスのxとyを入れ替えるつもりが、たまたまwrite側のアドレスマルチプレクサが目につき、それを流用しました。が、動作的な欠点が目立ちました。具体的には、画面書き換えの途中で切り替えると、縦図形と横図形が混在したり、初期画面を動的に準備する負担が大きくなっていました。

これを本来のread側アドレスマルチプレクサに変更します。ただし、write側マルチプレクサに追加してread側マルチプレクサの増設が必要になります。

write側アドレスマルチプレクサは名前をWriteMuxに変更しましたが、元の単なるセレクタに戻しました。新たにReadMuxモジュールを設置し、読み出し側アドレスのxとyを入れ替えます。実際にはyはx(a[7:0])をそのまま用い、xはy(a[15:8])を256から引いたものを用います。

$$ \begin{eqnarray} \left\{ \begin{array}{l} x&\Leftarrow&256-y \\ y&\Leftarrow&x \end{array} \right. \end{eqnarray} $$

図561.1に改造後のブロック図を示します。

図%%.1
図561.1 VRAMモジュール

以下にBSVソースを示します。処理はwrite側で実施した入れ替えとほとんど同様です。

ReadMux.bsv:

// アドレス型の定義
typedef Bit#(16) Addr_t;

// マルチプレクサのインタフェース定義
interface ReadMux_ifc;
   (* prefix="" *)
   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
endinterface

// マルチプレクサの実装
(* synthesize, always_ready = "outp", no_default_clock, no_default_reset *)
module mkReadMux(ReadMux_ifc);

   // 出力アドレスを生成するメソッド
   method Addr_t outp(Bool sel, Addr_t a);
      // xa: aの下位8ビット
      Bit#(8) xa = a[7:0];
      // yax: aの上位8ビットから算出
      Int#(10) yax = 256 - signExtend(unpack(a[15:8]));
      // ya: yaxを8ビットにトリミング
      Bit#(8) ya = truncate(pack(yax));

      // selがTrueなら加工したアドレスを返す
      if (sel) return {xa, ya};
      // selがFalseなら元のアドレスをそのまま返す
      else return a; 
   endmethod

endmodule

この変更により、ボード上のdip swを切り替えることで、リアルタイムに画面の縦横変換ができるようになりました。


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

posted by sakurai on December 1, 2022 #560

show_fields.blade.phpの修正

後半のビューの修正です。showアクションの2次ビューであるshow_field.blade.phpを修正します。修正前はcategory_idは数字になっています。

      <p>{{ $doc->category_id }}</p>

このビューの画面表示です。

図%%.1
図560.1 showアクション初期画面

これを次のように修正します。indexアクションと同様の修正であり、categoryを全て集めておき、category_idにより表を引きます。

      <p>{{ $categories[$doc->category_id] }}</p>

このビューの画面表示です。

図%%.2
図560.2 showアクション修正後画面

これによりlaravelのスキャフォールディング修正は全て完了しました。


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

posted by sakurai on November 30, 2022 #559

DocController show()の修正

最後にshow()の修正です。前半がコントローラの修正、後半がビューの修正です。

まずコントローラの標準に生成されたコードは、

    public function show($id)
    {
        
$doc $this->docRepository->find($id);
        if (empty(
$doc)) {
            
Flash::error('Doc not found');
            return 
redirect(route('docs.index'));
        }
        return 
view('docs.show')->with('doc'$doc);
    }

ですが、これを次のように2行修正します。

      public function show($id)
      {
          
$doc $this->docRepository->find($id);
          
$categories Category::all()->pluck('name','id');
          if (empty(
$doc)) {
              
Flash::error('Doc not found');
              return 
redirect(route('docs.index'));
          }
          return view('docs.show'compact('doc''categories'));
      }

リレーション先のメンバを全て集めてビューに渡しています。


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

posted by sakurai on November 29, 2022 #558

field.blade.phpの修正

後半のビューの修正です。fieldビューは、createアクションとeditアクションの2次ビューでありファイルはfield.blade.phpです。以下に修正する行を示します。

      {!! Form::number('category_id'null, ['class' => 'form-control']) !!}

このビューの画面表示です。

図%%.1
図558.1 createアクション初期画面

標準で生成されたコードでは、図558.1のとおりcategory_idとして数字を入力するフォームが生成されますが、これを次のように修正します。

      {!! Form::select('category_id'$categoriesnull, ['class'=>'form-control']) !!}

このビューの画面表示です。Form::selectによりdropDownListのフォームが生成されます。

図%%.2
図558.2 createアクション修正後画面

ビューが共通であるため、editアクションも同様な画面表示となります。


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

posted by sakurai on November 28, 2022 #557

DocController edit()の修正

app/Http/Controllers/DocController.php内のeditアクションの修正です。同じく前半がコントローラの修正、後半がビューの修正です。

標準ではコントローラのコードは、

      public function edit($id)
      {
          
$doc $this->docRepository->find($id);
          if (empty(
$doc)) {
              
Flash::error('Doc not found');
              return 
redirect(route('docs.index'));
          }
          return 
view('docs.edit')->with('doc'$doc);
      }

と生成されますが、これを次のように修正します。

      public function edit($id)
      {
          
$doc $this->docRepository->find($id);
          
$categories Category::all()->pluck('name','id');
          if (empty(
$doc)) {
              
Flash::error('Doc not found');
              return 
redirect(route('docs.index'));
          }
          return 
view('docs.edit'compact('doc''categories'));
      }

'doc'と'categories'という2つの変数をedit1次ビューに渡します。実際の作業は2次ビューであるfieldが実行します。

DocController create()の修正

引き続きcreateアクションの修正を行います。editもcreateもビューは同じなので、併せて前半のコントローラの修正を行います。

標準ではコントローラのコードは

      public function create()
      {
         return 
view('docs.create');
      }

と生成されますが、これを次のように修正します。先に示したようにeditアクションとビューを兼用しているため、$idをダミーで渡します。

      public function create()
      {
         
$doc null;

         $categories Category::all()->pluck('name','id');
         return view('docs.create',compact('doc','categories'));
      }

editアクションと同様、、'doc'と'categories'という2つの変数をcreate1次ビューに渡します。実際の作業は2次ビューであるfieldが実行します。


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

posted by sakurai on November 25, 2022 #556

table.blade.phpの修正

次に後半のビューの修正を行います。修正するファイルはindex()アクションの2次ビューであり、ファイルはtable.blade.phpです。修正する行は以下の2行です。

        <th>Category Id</th>
       :
            <
td>{{ $doc->category_id ;}}</td>

このビューの修正する前の画面表示です。

図%%.1
図556.1 indexアクション初期画面

図556.1ではCategory idが数字となっていますが、これを次のように修正します。

        <th>Category</th>
       :
            <
td>{{ $categories[$doc->category_id] }}</td>

このビューの画面表示です。図556.2のようにcategoryが名称に変化しました。

図%%.2
図556.2 indexアクション修正後画面

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

posted by sakurai on November 24, 2022 #555

DocController index()の修正

yiiと異なり、外部テーブルを認識できないため、コントローラの修正も必要になってきます。前半がコントローラの修正、後半がビューの修正となります。

前半のコントローラの修正としてapp/Http/Controllers/DocController.php内のindexアクションの修正を行います。

    public function index(Request $request)
    {
        
$docs $this->docRepository->all();
        return 
view('docs.index')
            ->
with('docs'$docs);
    }

となっているところを修正します。

まずモデルの定義が必要です。

use App\Models\Category;

次に外部テーブルの要素が必要なので、categoriesに要素を全部集めてビューに渡します。

    public function index(Request $request)
    {
        
$docs $this->docRepository->all();
        
$categories Category::all()->pluck('name','id');
        return 
view('docs.index',compact('docs','categories'));
    }

ここでpluck()compact()の説明をします。pluck()は、all()で集めたモデルのオブジェクトの集合に対して、シンプルに'id'をキーにした'name'をバリューとするarrayを作成するメソッドです。

次に、compact()は例えば'doc'という変数名をキーにしてdocオブジェクトをバリューとするarrayを作成します。この場合は'doc'と'categories'という2つの変数をビューに渡します。このビューへの変数を渡す手法はyiiと全く同じです。


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

posted by sakurai on November 21, 2022 #554

リレーション定義

コードを見ると、app/Models/Category.phpにおいては、

    public function docs()
    {
        return 
$this->hasMany(AppModelsDoc::class, 'category_id');
    }

これは、A category has many docsと読みます。1対nの関係です。また、app/Models/Doc.phpでは、

    public function category()
    {
        return 
$this->belongsTo(AppModelsCategory::class, 'category_id');
    }

とあり、これはA doc belongs to a categoryと読みます。n対1の関係です。

リレーションを辿る方法

yiiのように、ドット記述だけでリレーションを辿るようなうまい方法はなさそうですが、

$doc->category_id

のようにインデックス値は得られるので、$categories配列に全てのメンバを集めるというひと手間かけた上で

$categories[$doc->category_id]

のように表を引いて名前への変換を行います。

コントローラ、ビューの対応表

以下に画面、コントローラ中のアクション、ビューの対応表を示します。これに従い、それぞれのアクション及びビューを修正します。コントローラはapp/Http/Controllers/DocController.phpであり、ビューは全て、resources/views/docs/の下にあります。修正はコントローラとビューの両方について行います。

表554.1 画面、アクション、ビューの対応表
アイコン コントローラ内
メソッド(アクション)
1次ビューファイル
(黄色がアクションに対応)
2次ビューファイル
一覧表示 index() index.blade.php table.blade.php
fig554-1.png create() create.blade.php fields.blade.php
fig554-2.png show() show.blade.php show_fields.blade.php
fig554-3.png edit() edit.blade.php fields.blade.php


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


ページ: