『FPGAボードで学ぶVerilog HDL』 (11) 第4章「180秒タイマを作る」2(前編)

「『FPGAボードで学ぶVerilog HDL』 (10) 第4章「180秒タイマを作る」」(前編)(後編)
第4章の動作確認と自分なりの Verilog HDL の書き換えを行なった。
今回は、秒数の10進数の各桁を保持・ダウンカウントするのではなく、
秒数そのものを保持・ダウンカウントしてその秒数を10進数として出力する構造に書き換えてみた。

画像


動作環境

  • Windows XP
  • ザイリンクス ISE WebPACK 9.1i
  • 『FPGAボードで学ぶVerilog HDL』付属FPGAボード
  • RS-232C ケーブル(ストレート全結線) オス、メスタイプ
  • 5.1V 400mAのACアダプター(KENWOOD ポータブルCDプレーヤー付属)


Verilog HDL 記述の書き換え


ちょっと考えてみると、第4章の記述は秒数の各桁の値を保持してダウンカウントしていく構造になっていた。
TTL や CMOS などのディジタル回路設計だとそういう構成にするのはごく自然だと思うのだが、
ソフトウェアの高級言語で記述する場合は、そういう書き方はしなさそうに思った。

そこで、秒数そのものを保持・ダウンカウントしてその秒数を10進数として出力する構造に書き換えてみた。
(書き換え自体は勉強のためであって、元のダウンカウンターの構造が変だと思っているわけではない)

最初、10進数への変換として除算と剰余演算子を使用してみた。
さすがに使えないようで、以下のエラーが発生

Operator / is only supported when the second operand is a power of 2.
Operator % is only supported when the second operand is a power of 2.

条件分岐で除算・剰余演算をすることにした。

fsm.v

module fsm(
clk,
reset,
start_i,
tim_zero,
pulse_1sec,
start_o,
timeout
);

input clk;
input reset;
input start_i;
input tim_zero;
input pulse_1sec;
output reg start_o;
output reg timeout;

always @( posedge clk )
begin
if (reset == 1'b1) begin
start_o <= 1'b0;
timeout <= 1'b0;
end else begin
if (start_i == 1'b1) begin
start_o <= 1'b1;
end else begin
if (tim_zero == 1'b1 && pulse_1sec == 1'b1) begin
timeout <= 1'b1;
end
end
end
end

endmodule


pulse1sec.v

module pulse1sec(
clk,
reset,
start,
sec1,
sec1_counter
);

input clk;
input reset;
input start;
output reg sec1;
output reg [31:0] sec1_counter;

parameter [31:0] param_1second = 32'h01F78A40;

always @(posedge clk)
begin
if (reset) begin
sec1_counter <= 32'b0;
sec1 <= 1'b0;
end else begin
if (start) begin
if (sec1_counter == param_1second) begin
sec1_counter <= 32'b0;
sec1 <= 1'b1;
end else begin
sec1_counter <= sec1_counter + 1;
sec1 <= 1'b0;
end
end
end
end

endmodule


down_time.v

module down_time(
clk,
reset,
enable,
out
);

parameter init = 180;
input clk;
input reset;
input enable;
output reg [7:0] out;

always @(posedge clk) begin
if (reset == 1'b1) begin
out <= init;
end else begin
if (enable == 1'b1) begin
out <= out - 1;
end
end
end

endmodule


bin2dec100.v

module bin2dec100(
TIME,
timeout,
out,
remainder
);

input [7:0] TIME;
input timeout;
output [3:0] out;
output [7:0] remainder;

assign out = timeout ? 4'b1111 :
(TIME >= 100) ? 1 : 0;
assign remainder = (TIME >= 100) ? TIME - 100 : TIME;

endmodule


bin2dec10.v(function 文などでも書けたようだ)

module bin2dec10(
TIME,
timeout,
out,
remainder
);

input [7:0] TIME;
input timeout;
output [3:0] out;
output [3:0] remainder;

assign out = timeout ? 4'b1111 :
(TIME >= 90) ? 9 :
(TIME >= 80) ? 8 :
(TIME >= 70) ? 7 :
(TIME >= 60) ? 6 :
(TIME >= 50) ? 5 :
(TIME >= 40) ? 4 :
(TIME >= 30) ? 3 :
(TIME >= 20) ? 2 :
(TIME >= 10) ? 1 : 0;
assign remainder = (TIME >= 90) ? TIME - 90 :
(TIME >= 80) ? TIME - 80 :
(TIME >= 70) ? TIME - 70 :
(TIME >= 60) ? TIME - 60 :
(TIME >= 50) ? TIME - 50 :
(TIME >= 40) ? TIME - 40 :
(TIME >= 30) ? TIME - 30 :
(TIME >= 20) ? TIME - 20 :
(TIME >= 10) ? TIME - 10 : TIME;

endmodule


書くスペースがなくなったので、
「『FPGAボードで学ぶVerilog HDL』 (11) 第4章「180秒タイマを作る」2(後編)」に続く

この記事へのコメント

この記事へのトラックバック

  • エアマックス 95

    Excerpt: 『FPGAボードで学ぶVerilog HDL』 (11) 第4章「180秒タイマを作る」2(前編) のりつぐのメモ/ウェブリブログ Weblog: エアマックス 95 racked: 2013-07-10 05:22