CPU設計実習(授業用) - 4章 CDECvのデータパス部の構成と動作

# 4章 CDECvのデータパス部の構成と動作

本章ではCDECvのデータパス部の回路構成について説明します。
また、制御部から送られてくる制御信号によって、データバス部の動作がどのように制御されるのかを確認します。

## データパス部の構成

CDECvのデータパス部の全体構成を図4.1に示します。
図4.1ではデータをやり取りする主要なデータ線のみを示しており、制御信号やクロックなどの信号線は省略しています。

CDECvのデータパス部の特徴は、1本の8ビットのデータバスXbusを中心として構成されている点です。
このXbusを介して、データのやり取りが行われます。

データパス部には、プログラムカウンタ(PC)、汎用レジスタ(A, B, C)、フラグレジスタ(FLG)からなるレジスタセットとメモリ(256Byte)が含まれます。
さらに、算術論理演算を行うためのALUと、レジスタセット以外の各種レジスタが含まれています。

ALUには2章で説明した図2.8に示したものを利用します。
このALUは4ビットの制御信号により表2.5のように様々な演算機能を切り替えることができます。

レジスタセット以外に用いられている補助レジスタとしては、WDR(Write Data Register)、MAR(Memory Address Register)、T(Temporary register)、R(Result register)、I(Instruction register)があります。
これらはすべて8ビットのレジスタです。
このうち、WDRはメモリへの書き込みデータ、MARはメモリのアドレス指定を保持するためのレジスタです。
TレジスタはALUで2項演算を行う際に用いられます。
RレジスタはALUで実行された演算結果を保持するレジスタです。
Iレジスタは機械語命令の先頭バイトを格納するレジスタで、実行中の機械語命令の情報を制御部へ伝達します。

![datapath_sketch.png](https://qiita-image-store.s3.amazonaws.com/0/25656/d342405b-7ff5-927e-a40c-4749f18bcc0b.png)

<図4.1 CDECvデータパス部の構成>

## 制御信号の働き

3章で説明したように、データパス部の動作は制御部から送られてくる制御信号により制御されます。
CDECvの制御信号には3章の表3.1に示したものがあります。
以下では、これらの制御信号によってデータパス部でのデータのやり取りがどのように制御されるのかを、データパス部の回路構造と合わせて説明します。
なお、煩雑を避けるため、回路図ではレジスタやメモリに供給されるクロック信号clockの信号線は省略します。
すべてのレジスタとメモリにはクロックclockが共通に供給されており、clockの立ち上がりのタイミングでデータの読出しや書き込みが行われることに注意してください。

### Xbusを介したデータ転送 (制御信号: xsrc[2:0], xdst[2:0])

図4.1から見て取れるように、Xbusには6個のレジスタ PC, A, B, C, FLG, Rの出力(レジスタのq端子)とメモリの読出しデータの出力RDが接続されています。
また、Xbuxからは8個のレジスタ PC, A, B, C, I, WDR, MAR, Tの入力端子(レジスタのd端子)へ共通に接続されています。
これらの間でのデータ転送はXbusを介して行われます。

CDECvでは、Xbusを介したデータ転送は、データ転送元(データの読出し元)とデータ転送先レジスタ(データの書き込み先)をそれぞれ1つ選択して行われます。
制御部からの制御信号 xsrc[2:0] と xdst[2:0] はそれぞれ、データ転送元とデータ転送先レジスタを選択します。

制御信号 xsrc によりどのデータ転送元が選択されるかを表4.1に、制御信号 xdst によりどのデータ転送先が選択されるのかを表4.2に示します。


<表4.1 制御信号xsrc/データ転送元の対応>

| xsrc[2:0] | データ転送元 |
|-----------|-------|
| 000       | PC    |
| 001       | A     |
| 010       | B     |
| 011       | C     |
| 100       | R     |
| 101       | RD    |
| 110       | FLG   |
| 111       | 0xFF (定数値) |


<表4.2 制御信号xdst/データ転送先レジスタの対応>

| xdst[2:0] | データ転送元 |
|-----------|-------|
| 000       | PC    |
| 001       | A     |
| 010       | B     |
| 011       | C     |
| 100       | MAR   |
| 101       | WDR   |
| 110       | T     |
| 111       | I     |


データ転送元を選択する回路は図4.2のようにマルチプレクサを用いて構成されます。
制御信号xsrc[2:0]として000が与えられているときは、プログラムカウンタPCが保持してるデータが選択され、Xbusに出力されます。

データ転送先レジスタを選択する回路は図4.3のようにラインデコーダを用いて構成されます。
8個のレジスタの入力(レジスタのd端子)にはXbusが共通して入力されています。
制御信号xdst[2:0]として100が与えられているときは、MARの書き込み許可weが1となり、他のレジスタの書き込み許可weは0となります。
この状況でclockの立ち上がりが入るとXbusに出ているデータがMARに書き込まれます。

![xsrc.png](https://qiita-image-store.s3.amazonaws.com/0/25656/edc6c80f-9f81-3e3d-87b2-70471bebf13d.png)

<図4.2 データ転送元の選択回路>


![xdst.png](https://qiita-image-store.s3.amazonaws.com/0/25656/d33eabec-e6f7-9fb3-128b-6752912c3514.png)

<図4.3 データ転送先レジスタの選択回路>


図4.4にプログラムカウンタPCからMARへデータが転送される様子を示したタイムチャートを示します。
データ転送元を選択する制御信号 xsrc[2:0] が000となっている間は、PCに保持されているデータがXbusに出力されます。
また、制御信号 xdst[2:0] が100となっている間はMARの書き込み許可が与えられています。
この間にclockの立ち上がりが入るとXbusに出ているデータ(すなわちPCのデータ)がMARに書き込まれます。
このようにしてPCからMARへのデータ転送(PC->MAR)が実現されます。

なお、CDECvのデータパス部でのレジスタの書き込みはクロック信号clockの立ち上がりのタイミングで行われますが、制御信号は半クロックずらして与えられるものとします。
このことにより、制御信号が安定している状況で確実にデータ転送を行うことができます。


![PC_to_MAR.png](https://qiita-image-store.s3.amazonaws.com/0/25656/20906389-92a0-908a-4b17-f3efa4b3ffed.png)

<図4.4 Xbusを介したデータ転送(PC->MAR)>


### メモリへのアクセス (制御信号: MEMwe)

メモリへのアクセスには、図4.5のように、2つの補助レジスタMARとWDR、1ビットの制御信号MEMweが関与します。
MARはアクセスするメモリのアドレスを保持するためのレジスタで、MARの出力はメモリのMA端子に接続されています。
WDRはMARで指定されたアドレスへ書き込みを行うデータを保持しておくレジスタで、WDRの出力はメモリのWD端子へ接続されています。
制御部からの制御信号MEMweは、メモリの書き込み許可(we)を与えます。
メモリからの出力データRDは図4.2に示したようにマルチプレクサを介してXbusへ接続されています。


![MEMwe.png](https://qiita-image-store.s3.amazonaws.com/0/25656/6e3e2ec8-5702-c3fa-3478-c1d594ec5aa8.png)

<図4.5 メモリへのアクセス回路>


図4.6にメモリの読出しシーケンスの例を示します。
ここではメモリの0x03番地RAM[0x03]に格納されているデータ0x83を読み出している状況を表しています。
まずアクセスしたいアドレス0x03をMARへ転送します。
先に説明したように、MARへの書き込みはclockの立ち上がりのタイミングで行われることに注意してください。
MARの値が確定されたのち、clockの立ち上がりがメモリに入ると、RAM[0x03]の値0x83がRDへ転送され出力されます。


![timechart_memory_read.png](https://qiita-image-store.s3.amazonaws.com/0/25656/8c37bbe4-92e4-cadf-b459-cec3ef2e113b.png)

<図4.6 メモリの読出しシーケンス>


図4.7はメモリへの書き込みシーケンスを示したものです。
アドレス0xA1番地RAM[0xA1]に、データ0x12を書き込む状況を表しています。
まず、MARにアドレス0xA1、WDRに書き込みたいデータ0x12を転送します。
MARとWDRの確定に2クロック必要とされることに注意してください（順番はどちらが先でも大丈夫です）。
MARとWDRの値が確定した段階で、メモリの書き込み許可MEMweをアクティブにします。
この間にclockの立ち上がりが入ると、WDRのデータがメモリの0xA1番地へ書き込まれます。


![timechart_memory_write.png](https://qiita-image-store.s3.amazonaws.com/0/25656/345098a4-97cf-c454-8065-6743769b0249.png)

<図4.7 メモリの書き込みシーケンス>


### 算術論理演算の実行 (制御信号: aluop[3:0], Rwe, FLGwe)

算術論理演算は図4.8に示すように、ALUを中心として、補助レジスタのTレジスタとRレジスタ、およびFLGレジスタから構成される回路で実行されます。
ALUは2章の図2.8に示したものを使用します。
制御信号としてはALUの機能を選択する4ビットのaluop[3:0]と、Rレジスタの書き込み許可Rwe、FLGレジスタの書き込み許可FLGweが関係します。

ALUの8ビットの入力端子aとbにはそれぞれXbusとTレジスタの出力が接続されます。
TレジスタはALUで2項演算を行う際に一方の演算対象を格納するために用いられます(もう一方の演算対象はXbusから読みだされます)。

ALUにおいてどのような演算を行うのかは、制御部からの制御信号aluop[3:0]によって決定されます。
表4.3のALUの機能表を参照してください。

ALUの演算結果が出力される8ビットの端子resultはRレジスタの入力端子に接続されます。
制御信号RweはRレジスタの書き込み許可信号です。
Rweが1のときにclockの立ち上がりが入るとALUの演算結果がRレジスタに書き込まれます。

ALUの演算結果に依存して出力されるサインフラグS、ゼロフラグZ、キャリーフラグCyをまとめたフラグ信号SZCy[2:0]は、フラグレジスタFLGの対応するビットFLG[3:1]に接続されます。
制御信号FLGweはFLGレジスタの書き込み許可信号です。
FLGweが1のときにclockの立ち上がりが入るとフラグ信号がFLGレジスタに書き込まれます。
FLGレジスタの出力のうちキャリーフラグを表すFLG[1]は、ALUのCy_in端子に接続されます。

RレジスタとFLGレジスタの出力は、図4.2に示すようにマルチプレクサを介してXbusへ接続されます。

![aluop.png](https://qiita-image-store.s3.amazonaws.com/0/25656/099ce7d0-809c-1b4b-5a5a-1b66ff241028.png)

<図4.8 算術論理演算を実行する回路>

<表4.3 ALUの機能表(2章 表2.5 再掲)>

| aluop[3:0] | 演算　(resultへの出力) |
|-------|------|
|  0000 |    a |
|  0001 |    b |
|  0010 |    ~a (bitwise not) |
|  0011 |    ~b (bitwise not) |
|  0100 | a & b (bitwise and) |
|  0101 | a \| b (bitwise or)  |
|  0110 | a ^ b (bitwise exclusive or) |
|  0111 | 8'b0000_0000 |
|  1000 | a + 1 |
|  1001 | a - 1 |
|  1010 | a + b |
|  1011 | a - b |
|  1100 | a + b + Cy_in (add with carry)       |
|  1101 | a - b - Cy_in (subtract with borrow) |
|  1110 | a << 1 (shift left)                  |
|  1111 | a >> 1 (logical shift right)         |



## データパス部から制御部へ送られる信号　(I[7:0], SZCy[2:0])

制御部で生成される制御信号は実行する命令によって変わってきます。
そのためデータパス部からは、機械語の命令コードやフラグ信号を制御部へ送ってやる必要があります。

図4.9のように、IレジスタとフラグレジスタFLG[3:1]は、それぞれI[7:0]、SZCy[2:0]として制御部に送られます。

Iレジスタには実行中の命令コード(の先頭バイト)が保持されますので、制御部はI[7:0]を参照することで、現在どの命令を実行しているのかを知ることができます。
また、フラグを表す信号SZCy[2:0]は、条件分岐を実現するために利用されます。


![I_SZCy.png](https://qiita-image-store.s3.amazonaws.com/0/25656/c5dc664d-8676-dab8-4857-e7d4a425c3f2.png)

<図4.9 制御部への信号>