🙆

chiselでスーパスカラを実装 その4

2024/08/12に公開

はじめに

前回まででEXステージの並列化ができました。
今回はMEMステージの並列化を行っていきます。

構成

概要

  • 実際にメモリに書き込むMEMユニットを2つ備える
  • EXステージから受け取った2つの信号を、それぞれMEMユニットに割り当てる
  • 両方のユニットが書き込み完了したら「完了信号」を立てる

なお現在はEXステージが2つの信号を同時に渡してくる(信号の選別とタイミング合わせはEXステージ内で行う(前回参照))ので、MEMステージはかなりシンプルになります。

詳細

MEMステージ全体を管理するMemUnitMgrモジュールを作成しました。
内部では以下の構成をとります。

  • EXステージの入力を溜めるバッファ
  • キューの指令をMEMユニットに振り分けるMemInRouter
    • 指令- ユニットのペアを作る
    • 対応するユニットの入力バッファに指令を入れる
  • MEMユニット
    • MemInRouterの出力を溜める入力バッファ
    • 前の指令の実行が終わったら入力バッファからデータを取り出す
    • 2サイクルかけて実行完了する
  • 完了信号
    • 両方のユニットが書き込み完了したら立つ

なお以下は現状では制限事項としました

  • メモリ書き込みしない指令もMEMユニットに接続する
    • 実際に書き込むかはMEMユニットで判断
    • ただし、2サイクル後まで完了しない
    • 今は各ステージの出口で待ち合わせるという仕様にしているので、待ち合わせロジック入れるぐらいならこの方が単純だと考えました。両方が書き込みしない指令だと無駄になりますがまあしょうがないです

テスト

ユニットテスト

    def testFuncFor1In(mgr:MemUnitMgr, mem_wen1: UInt, expectedStart1:Bool, mem_wen2: UInt, expectedStart2:Bool, expectedAllComp:Bool) = {

		mgr.io.inputs(0).pc.poke(4.U)
		mgr.io.inputs(1).pc.poke(8.U)
		mgr.io.inputs(0).mem_wen.poke(mem_wen1)
		mgr.io.inputs(1).mem_wen.poke(mem_wen2)
		mgr.io.prevComplete.poke(true.B)
					
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)

		mgr.clock.step(1)  //MemInRouterが出力
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)
		mgr.io.allExecComplete.expect(false.B)

		mgr.clock.step(1)  //memUnitに入力
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)
		mgr.io.allExecComplete.expect(false.B)

		mgr.clock.step(1)  //MemUnitでの書き込み終了

		mgr.io.outputs(0).execState.execComplete.expect(expectedStart1)
		mgr.io.outputs(1).execState.execComplete.expect(expectedStart2)
		mgr.io.allExecComplete.expect(expectedAllComp)

		mgr.reset.poke(true.B)
		mgr.clock.step(1)
		mgr.reset.poke(false.B)
	}

    "Output signals" should "be correct with 2 valid inputs" in {
    	test(new MemUnitMgr()){ mgr =>
    
    		testFuncFor1In(mgr, MEN_S, true.B, MEN_S, true.B, true.B)
    	}
    }

MEN_Sはメモリ書き込み有を表すenumです。設計通りの周期で完了信号が変化することを確認しています。

    def testFuncFor2ValidIn(mgr:MemUnitMgr, mem_wen1_1: UInt, mem_wen1_2: UInt, mem_wen2_1: UInt, mem_wen2_2: UInt) = {

		mgr.io.inputs(0).pc.poke(4.U)
		mgr.io.inputs(1).pc.poke(8.U)
		mgr.io.inputs(0).mem_wen.poke(mem_wen1_1)
		mgr.io.inputs(1).mem_wen.poke(mem_wen1_2)
		mgr.io.prevComplete.poke(true.B)
					
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)

		mgr.clock.step(1)  //MemInRouterが出力
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)
		mgr.io.allExecComplete.expect(false.B)

		//次の指令
		mgr.io.inputs(0).pc.poke(12.U)
		mgr.io.inputs(1).pc.poke(16.U)
		mgr.io.inputs(0).mem_wen.poke(mem_wen2_1)
		mgr.io.inputs(1).mem_wen.poke(mem_wen2_2)
		mgr.io.prevComplete.poke(true.B)

		mgr.clock.step(1)  //memUnitに入力
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)
		mgr.io.allExecComplete.expect(false.B)

		mgr.clock.step(1)  //MemUnitでの書き込み終了

		mgr.io.outputs(0).execState.execComplete.expect(true.B)
		mgr.io.outputs(1).execState.execComplete.expect(true.B)
		mgr.io.allExecComplete.expect(true.B)
		
		mgr.clock.step(1)  //memUnitに入力 2つ目  1つ目の終了を待つので1サイクル余分にかかる
		mgr.io.outputs(0).execState.execComplete.expect(false.B)
		mgr.io.outputs(1).execState.execComplete.expect(false.B)
		mgr.io.allExecComplete.expect(false.B)

		mgr.clock.step(1)  //MemUnitでの書き込み終了 2つ目

		mgr.io.outputs(0).execState.execComplete.expect(true.B)
		mgr.io.outputs(1).execState.execComplete.expect(true.B)
		mgr.io.allExecComplete.expect(true.B)

		mgr.reset.poke(true.B)
		mgr.clock.step(1)
		mgr.reset.poke(false.B)
	}

    "Output signals" should "be correct with 1 invalid and 1 valid inputs" in {
    	test(new MemUnitMgr()){ mgr =>
    
    		testFuncFor1In(mgr, MEN_X, false.B, MEN_S, true.B, true.B)
    	}
    }

連続して指令が来る場合の対応もテストします。

全体のテスト

システム全体の挙動もテストします。
printf関数を使って各ステージが処理するpcとfetch_idを出力しました。

--------
if_reg_pc: 0x00000000
id_reg_pc: 0x00000000
id_inst: 0x0000000000000013
fetch_id:           0
***dec***
dec_out0.pc: 0x00000000
dec_out1.pc: 0x00000000
dec_out0.fetch_id: 0x00000000
dec_out1.fetch_id: 0x00000000
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000000
hr_1_out.pc: 0x00000000
hr_0_out.exefun_0: 0x00
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000000
hr_1_out.fetch_id: 0x00000000
***SecondDecoder***
dec2_0_out.pc: 0x00000000
dec2_1_out._pc: 0x00000000
dec2_0_out.fetch_id: 0x00000000
dec2_1_out.fetch_id: 0x00000000
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000000
ex1_router.pc: 0x00000000
ex0_router.fetch_id: 0x00000000
ex1_router.fetch_id: 0x00000000
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000000
ex0_unit_in.fetch_id: 0x00000000
ex1_unit_in.fetch_id: 0x00000000
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000000
ex0_unit_out.fetch_id: 0x00000000
ex1_unit_out.fetch_id: 0x00000000
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000008
id_reg_pc: 0x00000000
id_inst: 0x0020059300300513
fetch_id:           1
***dec***
dec_out0.pc: 0x00000000
dec_out1.pc: 0x00000004
dec_out0.fetch_id: 0x00000001
dec_out1.fetch_id: 0x00000001
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x01
***HazardResolver***
hr_0_out.pc: 0x00000000
hr_1_out.pc: 0x00000000
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000000
hr_1_out.fetch_id: 0x00000000
***SecondDecoder***
dec2_0_out.pc: 0x00000000
dec2_1_out._pc: 0x00000000
dec2_0_out.fetch_id: 0x00000000
dec2_1_out.fetch_id: 0x00000000
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000000
ex1_router.pc: 0x00000000
ex0_router.fetch_id: 0x00000000
ex1_router.fetch_id: 0x00000000
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000000
ex0_unit_in.fetch_id: 0x00000000
ex1_unit_in.fetch_id: 0x00000000
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000000
ex0_unit_out.fetch_id: 0x00000000
ex1_unit_out.fetch_id: 0x00000000
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000010
id_reg_pc: 0x00000008
id_inst: 0x00a5863300000013
fetch_id:           2
***dec***
dec_out0.pc: 0x00000008
dec_out1.pc: 0x0000000c
dec_out0.fetch_id: 0x00000002
dec_out1.fetch_id: 0x00000002
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x01
***HazardResolver***
hr_0_out.pc: 0x00000000
hr_1_out.pc: 0x00000004
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x01
hr_0_out.fetch_id: 0x00000001
hr_1_out.fetch_id: 0x00000001
***SecondDecoder***
dec2_0_out.pc: 0x00000000
dec2_1_out._pc: 0x00000000
dec2_0_out.fetch_id: 0x00000000
dec2_1_out.fetch_id: 0x00000000
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000000
ex1_router.pc: 0x00000000
ex0_router.fetch_id: 0x00000000
ex1_router.fetch_id: 0x00000000
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000000
ex0_unit_in.fetch_id: 0x00000000
ex1_unit_in.fetch_id: 0x00000000
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000000
ex0_unit_out.fetch_id: 0x00000000
ex1_unit_out.fetch_id: 0x00000000
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000018
id_reg_pc: 0x00000010
id_inst: 0x00000513c0001073
fetch_id:           3
***dec***
dec_out0.pc: 0x00000010
dec_out1.pc: 0x00000014
dec_out0.fetch_id: 0x00000003
dec_out1.fetch_id: 0x00000003
dec_out0.exe_fun: 0x12
dec_out1.exe_fun: 0x01
***HazardResolver***
hr_0_out.pc: 0x00000008
hr_1_out.pc: 0x0000000c
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x01
hr_0_out.fetch_id: 0x00000002
hr_1_out.fetch_id: 0x00000002
***SecondDecoder***
dec2_0_out.pc: 0x00000000
dec2_1_out._pc: 0x00000004
dec2_0_out.fetch_id: 0x00000001
dec2_1_out.fetch_id: 0x00000001
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000000
ex1_router.pc: 0x00000000
ex0_router.fetch_id: 0x00000000
ex1_router.fetch_id: 0x00000000
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000000
ex0_unit_in.fetch_id: 0x00000000
ex1_unit_in.fetch_id: 0x00000000
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000000
ex0_unit_out.fetch_id: 0x00000000
ex1_unit_out.fetch_id: 0x00000000
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000020
id_reg_pc: 0x00000018
id_inst: 0x0000000000000013
fetch_id:           4
***dec***
dec_out0.pc: 0x00000018
dec_out1.pc: 0x0000001c
dec_out0.fetch_id: 0x00000004
dec_out1.fetch_id: 0x00000004
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000010
hr_1_out.pc: 0x00000014
hr_0_out.exefun_0: 0x12
hr_1_out.exefun_1: 0x01
hr_0_out.fetch_id: 0x00000003
hr_1_out.fetch_id: 0x00000003
***SecondDecoder***
dec2_0_out.pc: 0x00000008
dec2_1_out._pc: 0x0000000c
dec2_0_out.fetch_id: 0x00000002
dec2_1_out.fetch_id: 0x00000002
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000000
ex1_router.pc: 0x00000004
ex0_router.fetch_id: 0x00000001
ex1_router.fetch_id: 0x00000001
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000000
ex0_unit_in.fetch_id: 0x00000000
ex1_unit_in.fetch_id: 0x00000000
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000000
ex0_unit_out.fetch_id: 0x00000000
ex1_unit_out.fetch_id: 0x00000000
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000028
id_reg_pc: 0x00000020
id_inst: 0x0000000000000013
fetch_id:           5
***dec***
dec_out0.pc: 0x00000020
dec_out1.pc: 0x00000024
dec_out0.fetch_id: 0x00000005
dec_out1.fetch_id: 0x00000005
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000018
hr_1_out.pc: 0x0000001c
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000004
hr_1_out.fetch_id: 0x00000004
***SecondDecoder***
dec2_0_out.pc: 0x00000010
dec2_1_out._pc: 0x00000014
dec2_0_out.fetch_id: 0x00000003
dec2_1_out.fetch_id: 0x00000003
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000008
ex1_router.pc: 0x0000000c
ex0_router.fetch_id: 0x00000002
ex1_router.fetch_id: 0x00000002
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000004
ex0_unit_in.fetch_id: 0x00000001
ex1_unit_in.fetch_id: 0x00000001
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000004
ex0_unit_out.fetch_id: 0x00000001
ex1_unit_out.fetch_id: 0x00000001
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000030
id_reg_pc: 0x00000028
id_inst: 0x0000000000000013
fetch_id:           6
***dec***
dec_out0.pc: 0x00000028
dec_out1.pc: 0x0000002c
dec_out0.fetch_id: 0x00000006
dec_out1.fetch_id: 0x00000006
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000020
hr_1_out.pc: 0x00000024
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000005
hr_1_out.fetch_id: 0x00000005
***SecondDecoder***
dec2_0_out.pc: 0x00000018
dec2_1_out._pc: 0x0000001c
dec2_0_out.fetch_id: 0x00000004
dec2_1_out.fetch_id: 0x00000004
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000000
mem0_inBuf.fetch_id: 0x00000000
mem1_inBuf.fetch_id: 0x00000000
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000010
ex1_router.pc: 0x00000014
ex0_router.fetch_id: 0x00000003
ex1_router.fetch_id: 0x00000003
***EX Unit***
ex0_unit_in.pc: 0x00000000
ex1_unit_in.pc: 0x00000004
ex0_unit_in.fetch_id: 0x00000001
ex1_unit_in.fetch_id: 0x00000001
ex0_unit_out.pc: 0x00000000
ex1_unit_out.pc: 0x00000004
ex0_unit_out.fetch_id: 0x00000001
ex1_unit_out.fetch_id: 0x00000001
ex0_unit.complete: 0x1
ex1_unit.complete: 0x1
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000000
ex0_sige_in.fetch_id: 0x00000000
ex1_sige_in.fetch_id: 0x00000000
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000038
id_reg_pc: 0x00000030
id_inst: 0x0000000000000013
fetch_id:           7
***dec***
dec_out0.pc: 0x00000030
dec_out1.pc: 0x00000034
dec_out0.fetch_id: 0x00000007
dec_out1.fetch_id: 0x00000007
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000028
hr_1_out.pc: 0x0000002c
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000006
hr_1_out.fetch_id: 0x00000006
***SecondDecoder***
dec2_0_out.pc: 0x00000020
dec2_1_out._pc: 0x00000024
dec2_0_out.fetch_id: 0x00000005
dec2_1_out.fetch_id: 0x00000005
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000004
mem0_inBuf.fetch_id: 0x00000001
mem1_inBuf.fetch_id: 0x00000001
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000018
ex1_router.pc: 0x0000001c
ex0_router.fetch_id: 0x00000004
ex1_router.fetch_id: 0x00000004
***EX Unit***
ex0_unit_in.pc: 0x00000008
ex1_unit_in.pc: 0x0000000c
ex0_unit_in.fetch_id: 0x00000002
ex1_unit_in.fetch_id: 0x00000002
ex0_unit_out.pc: 0x00000008
ex1_unit_out.pc: 0x0000000c
ex0_unit_out.fetch_id: 0x00000002
ex1_unit_out.fetch_id: 0x00000002
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000004
ex0_sige_in.fetch_id: 0x00000001
ex1_sige_in.fetch_id: 0x00000001
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000040
id_reg_pc: 0x00000038
id_inst: 0x0000000000000013
fetch_id:           8
***dec***
dec_out0.pc: 0x00000038
dec_out1.pc: 0x0000003c
dec_out0.fetch_id: 0x00000008
dec_out1.fetch_id: 0x00000008
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000030
hr_1_out.pc: 0x00000034
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000007
hr_1_out.fetch_id: 0x00000007
***SecondDecoder***
dec2_0_out.pc: 0x00000028
dec2_1_out._pc: 0x0000002c
dec2_0_out.fetch_id: 0x00000006
dec2_1_out.fetch_id: 0x00000006
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000000
mem1_inBuf.pc: 0x00000004
mem0_inBuf.fetch_id: 0x00000001
mem1_inBuf.fetch_id: 0x00000001
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000020
ex1_router.pc: 0x00000024
ex0_router.fetch_id: 0x00000005
ex1_router.fetch_id: 0x00000005
***EX Unit***
ex0_unit_in.pc: 0x00000008
ex1_unit_in.pc: 0x0000000c
ex0_unit_in.fetch_id: 0x00000002
ex1_unit_in.fetch_id: 0x00000002
ex0_unit_out.pc: 0x00000008
ex1_unit_out.pc: 0x0000000c
ex0_unit_out.fetch_id: 0x00000002
ex1_unit_out.fetch_id: 0x00000002
ex0_unit.complete: 0x1
ex1_unit.complete: 0x1
***Signal Extract***
ex0_sige_in.pc: 0x00000000
ex1_sige_in.pc: 0x00000004
ex0_sige_in.fetch_id: 0x00000001
ex1_sige_in.fetch_id: 0x00000001
ex_sige.complete: 0x1
--------
if_reg_pc: 0x00000048
id_reg_pc: 0x00000040
id_inst: 0x0000000000000013
fetch_id:           9
***dec***
dec_out0.pc: 0x00000040
dec_out1.pc: 0x00000044
dec_out0.fetch_id: 0x00000009
dec_out1.fetch_id: 0x00000009
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000038
hr_1_out.pc: 0x0000003c
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000008
hr_1_out.fetch_id: 0x00000008
***SecondDecoder***
dec2_0_out.pc: 0x00000030
dec2_1_out._pc: 0x00000034
dec2_0_out.fetch_id: 0x00000007
dec2_1_out.fetch_id: 0x00000007
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000008
mem1_inBuf.pc: 0x0000000c
mem0_inBuf.fetch_id: 0x00000002
mem1_inBuf.fetch_id: 0x00000002
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000004
mem0_inRouter.fetch_id: 0x00000001
mem1_inRouter.fetch_id: 0x00000001
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000000
mem0_unit.fetch_id: 0x00000000
mem1_unit.fetch_id: 0x00000000
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000000
mem0_out.fetch_id: 0x00000000
mem1_out.fetch_id: 0x00000000
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000028
ex1_router.pc: 0x0000002c
ex0_router.fetch_id: 0x00000006
ex1_router.fetch_id: 0x00000006
***EX Unit***
ex0_unit_in.pc: 0x00000010
ex1_unit_in.pc: 0x00000014
ex0_unit_in.fetch_id: 0x00000003
ex1_unit_in.fetch_id: 0x00000003
ex0_unit_out.pc: 0x00000010
ex1_unit_out.pc: 0x00000014
ex0_unit_out.fetch_id: 0x00000003
ex1_unit_out.fetch_id: 0x00000003
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000008
ex1_sige_in.pc: 0x0000000c
ex0_sige_in.fetch_id: 0x00000002
ex1_sige_in.fetch_id: 0x00000002
ex_sige.complete: 0x0
--------
if_reg_pc: 0x00000050
id_reg_pc: 0x00000048
id_inst: 0x0000000000000013
fetch_id:          10
***dec***
dec_out0.pc: 0x00000048
dec_out1.pc: 0x0000004c
dec_out0.fetch_id: 0x0000000a
dec_out1.fetch_id: 0x0000000a
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000040
hr_1_out.pc: 0x00000044
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x00000009
hr_1_out.fetch_id: 0x00000009
***SecondDecoder***
dec2_0_out.pc: 0x00000038
dec2_1_out._pc: 0x0000003c
dec2_0_out.fetch_id: 0x00000008
dec2_1_out.fetch_id: 0x00000008
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000008
mem1_inBuf.pc: 0x0000000c
mem0_inBuf.fetch_id: 0x00000002
mem1_inBuf.fetch_id: 0x00000002
***MEM InRouter***
mem0_inRouter.pc: 0x00000000
mem1_inRouter.pc: 0x00000000
mem0_inRouter.fetch_id: 0x00000000
mem1_inRouter.fetch_id: 0x00000000
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000004
mem0_unit.fetch_id: 0x00000001
mem1_unit.fetch_id: 0x00000001
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000004
mem0_out.fetch_id: 0x00000001
mem1_out.fetch_id: 0x00000001
mem_out.complete: 0x0
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000030
ex1_router.pc: 0x00000034
ex0_router.fetch_id: 0x00000007
ex1_router.fetch_id: 0x00000007
***EX Unit***
ex0_unit_in.pc: 0x00000010
ex1_unit_in.pc: 0x00000014
ex0_unit_in.fetch_id: 0x00000003
ex1_unit_in.fetch_id: 0x00000003
ex0_unit_out.pc: 0x00000010
ex1_unit_out.pc: 0x00000014
ex0_unit_out.fetch_id: 0x00000003
ex1_unit_out.fetch_id: 0x00000003
ex0_unit.complete: 0x1
ex1_unit.complete: 0x1
***Signal Extract***
ex0_sige_in.pc: 0x00000008
ex1_sige_in.pc: 0x0000000c
ex0_sige_in.fetch_id: 0x00000002
ex1_sige_in.fetch_id: 0x00000002
ex_sige.complete: 0x1
--------
if_reg_pc: 0x00000058
id_reg_pc: 0x00000050
id_inst: 0x0000000000000013
fetch_id:          11
***dec***
dec_out0.pc: 0x00000050
dec_out1.pc: 0x00000054
dec_out0.fetch_id: 0x0000000b
dec_out1.fetch_id: 0x0000000b
dec_out0.exe_fun: 0x01
dec_out1.exe_fun: 0x00
***HazardResolver***
hr_0_out.pc: 0x00000048
hr_1_out.pc: 0x0000004c
hr_0_out.exefun_0: 0x01
hr_1_out.exefun_1: 0x00
hr_0_out.fetch_id: 0x0000000a
hr_1_out.fetch_id: 0x0000000a
***SecondDecoder***
dec2_0_out.pc: 0x00000040
dec2_1_out._pc: 0x00000044
dec2_0_out.fetch_id: 0x00000009
dec2_1_out.fetch_id: 0x00000009
***MEM***
***MEM Input Buffer***
mem0_inBuf.pc: 0x00000010
mem1_inBuf.pc: 0x00000014
mem0_inBuf.fetch_id: 0x00000003
mem1_inBuf.fetch_id: 0x00000003
***MEM InRouter***
mem0_inRouter.pc: 0x00000008
mem1_inRouter.pc: 0x0000000c
mem0_inRouter.fetch_id: 0x00000002
mem1_inRouter.fetch_id: 0x00000002
***MEM Unit***
mem0_unit.pc: 0x00000000
mem1_unit.pc: 0x00000004
mem0_unit.fetch_id: 0x00000001
mem1_unit.fetch_id: 0x00000001
***MEM Out***
mem0_out.pc: 0x00000000
mem1_out.pc: 0x00000004
mem0_out.fetch_id: 0x00000001
mem1_out.fetch_id: 0x00000001
mem_out.complete: 0x1
***EX***
***EX Cmnd Router***
ex0_router.pc: 0x00000038
ex1_router.pc: 0x0000003c
ex0_router.fetch_id: 0x00000008
ex1_router.fetch_id: 0x00000008
***EX Unit***
ex0_unit_in.pc: 0x0000001c
ex1_unit_in.pc: 0x00000004
ex0_unit_in.fetch_id: 0x00000004
ex1_unit_in.fetch_id: 0x00000001
ex0_unit_out.pc: 0x0000001c
ex1_unit_out.pc: 0x00000004
ex0_unit_out.fetch_id: 0x00000004
ex1_unit_out.fetch_id: 0x00000001
ex0_unit.complete: 0x0
ex1_unit.complete: 0x0
***Signal Extract***
ex0_sige_in.pc: 0x00000010
ex1_sige_in.pc: 0x00000014
ex0_sige_in.fetch_id: 0x00000003
ex1_sige_in.fetch_id: 0x00000003
ex_sige.complete: 0x0
--------

(MEMとEXの順番が逆になってしまっていますが)
各指令が順々に処理されていくのが分かります。

なお、今はまだレジスタへのライトバックができていないので、演算結果は正しくありません。

最後に

いよいよあと1ステージ、レジスタへのライトバック(WB)です。
コードは以下です。
https://github.com/mr16048/mycpu/tree/superscala_MEM

Discussion