Last update $Id$
(c) 2007 BakaOyaji
インストラクションレジスタの設計
まずは、図6のブロックダイアグラムのなかのインストラクションレ
ジスタです。この部分の働きはプログラムメモリから読み出されたデータ(すなわち次に実行する命令)を保持しておくことです。ただし、分岐が起きるとき
や、SKIP系の命令でSKIPする場合は、データをゼロクリア(フラッシュ動作)することで、該当するサイクルではNOPを実行させます。
フラッシュ動作する具体的な場合は、
- GOTO命令
- CALL命令,Return系命令
- SKIP系の命令
- 割り込み
です。GOTO、CALL、Return系の命令は命令自体分岐なので、命令をデコードするだけで次のサイクルが強制的にNOPになることがわかります
が、あとの2つはCPU内
の他のモジュールの状態に依存します。そこで、GOTOとCALLのみ内部でデコードして、インストラクションレジスタ自身でNOPにしてしまいます。残
りは、外部入力でNOPにします。
SYNOPSIS yap16_ir モジュール
|
|
input clk_i |
クロック入力
|
input por_i |
パワーオンリセット
|
input [(`YAP16_INST_WIDTH -1):0] code_data_i |
プログラムメモリからのデータ入力
|
input skip_i |
強制SKIP入力// skip |
output [(`YAP16_INST_WIDTH -1):0] instruction_o |
各部への命令出力 |
output flush_o |
フラッシュ発生(未使用)
|
//
// Instruction register
// force_nop_i signal will override the instruction fetched
// to NOP. This is used for inserting dummy cycle
// at skip, branch, call and 1st stage of interrupt services
//
// Instruction register
// (c) 2007 BakaOyaji
// $Id
//
`include "yap16_def.h"
`include "yap16_instructions.h"
module yap16_ir(
input clk_i,
input por_i ,
input [(`YAP16_INST_WIDTH -1):0] code_data_i ,
input skip_i , // skip , overriding the instruction fetched to NOP
output [(`YAP16_INST_WIDTH -1):0] instruction_o, // the instruction to execute
output flush_o
);
reg [(`YAP16_INST_WIDTH -1):0] instruction ;
reg force_nop ;
assign instruction_o = instruction ;
assign flush_o = force_nop | skip_i | por_i ;
always@ * begin
force_nop <= 1'b0 ;
(* parallel_case *)
casex( instruction )
`YAP16_INST_GOTO,
`YAP16_INST_CALL,
`YAP16_INST_RETURN,
`YAP16_INST_RETFIE,
`YAP16_INST_RETLW : begin
force_nop <= 1'b1 ;
end
default : begin
force_nop <= 1'b0 ;
end
endcase
end // always
always@( posedge clk_i ) begin
if( flush_o ) begin
// instruction <= `Inst_NOP ;
instruction <= 'b00_0000_0000_0000 ;
end // if
else begin
instruction <= code_data_i ;
end // else
end // always
endmodule // yap16_ir
// EOF yap16_ir.v
モジュールの主要な部分は2つのalwaysブロックで構成されています。最初のものが、GOTO、CALL,RETURN系の命令のデコードをしていま
す。2番目は、インストラクションレジスタそのものと、強制NOPの機能を実装しています。2番めのalwaysブロックで、強制NOPのために、
instruction <= 'b00_0000_0000_0000 ;
という記述があります。論理合成の結果だけを考えれば、
instruction <= `Inst_NOP ;
としたほうが回路は小さくなる可能性があります。理由は、`Inst_NOPの
定義はは、前のページに書いたように、14'b00_0000_0xx0_0000
なのでxの部分は、Don'tCareで1でも0でも構わないならば、論理合成のツールは回路規模を最小にできるほうを選択するからです(大体は0になる
のですが)。
ただ、実際にシミュレーションを実行してみると、xが表示されるのは何かと鬱陶しいのでここでは、素直に「全ビット0」にしています。(この話は
Verilogの小ネタで独立させたほうがいいかも)
<<前に戻る Index へ 次へ>>