やかんです。
前回記事でとりあえず書いてみた順序機械のコードについてアプデした上で、乗算器の実装に取り掛かります。
前回記事↓
前回書いたコード
超シンプルな順序機械を試しに書いてみました。コード再掲↓
module order_machine(
input wire clk, rst,
output wire[3:0] x
);
reg[0:0] state;
reg[3:0] x;
always @(posedge clk) begin
if(rst) begin
state <= 1'b0;
x <= 4'b0000;
end else begin
if(x == 0) state <= 1'b0;
if(x == 15) state <= 1'b1;
if(state == 1'b0) begin
x <= x + 4'b0001;
end else begin
x <= x - 4'b0001;
end
end
end
assign x = x;
endmodule
添削してもらいました。
東大工学部電子情報学科の友達に添削してもらいました。
ありがたすぎる。
まじでありがとう。天才だ。
出力をwireからregに変える
記述の中で、xという出力ポートを宣言しています。この時、xの値はモジュール内の演算に使用するので、wire型は不適切ですね。
モジュール内で使用する値についてはモジュール内のレジスタに格納したくなります。
1bitのレジスタ宣言は[0:0]つけない方が自然
これはもう先人の教えに従いましょう。
ということで、いかが修正済みのコード。
module order_machine(
input wire clk, rst,
output reg[3:0] x
);
reg state;
always @(posedge clk) begin
if(rst) begin
state <= 1'b0;
x <= 4'b0000;
end else begin
if(x == 0) state <= 1'b0;
if(x == 15) state <= 1'b1;
if(state == 1'b0) begin
x <= x + 4'b0001;
end else begin
x <= x - 4'b0001;
end
end
end
endmodule
重ね重ね、まじでありがとうマイフレンド。
ちょっとした気づき
実装の中で、「1クロックで何を行いたいのか」っていうのが大事なのでは、と思いました。
例えば、状態の更新と値の演算は1つのクロックで行うのか、あるいはクロックを分けて2クロックで行うのかどうか。
この辺まで含めてしっかり考えておけば、実装の際に躓きそうになる小石をあらかじめ取り除いておくことができそうな気がしています。
と考えると、シングルサイクルプロセッサというのは、1つの命令を実行するという複数ステップからなる処理を1つのクロックで行うわけですから、そりゃ複雑になるよねと実感するわけです。
妥当な気づきかわかりませんが。
ということで、こちらの記事は終了とします。最後までお読みいやだき、ありがとうございます。