« M5Stamp-PICO Arduino Install | トップページ | M5Paper Arduino Install »

2021年12月13日 (月)

verilog事始め(sample#4 @Gowin RUNBER board)

2021/12/13
初版

verilog事始め(sample#4 @Gowin RUNBER board)

verilog事始め(sample#4 @Gowin RUNBER board)

概要

本記事は「verilog事始め(Gowin RUNBER board で始める)」の続きとしてverilogの追加サンプルを紹介したものである。

sample#4(stopwatch)

例として、sample#3をベースに以下を追加して、stopwatchを実現する。
(一部、インタフェースの付録のものを参考にした)

top_stopwatch.v

module top_stopwatch ( input clk, input [7:0] sw, input [7:0] btn, output [7:0] seg, output [3:0] seg_dig, output [7:0] led ); wire rst, key1, key2; wire tgl, zrst; // all LEDs off // assign led = 8'b0000_0000; // for binary to BCD convert reg [3:0] ones, tens, huns, thous; integer i; wire [7:0] seg_a, seg_b, seg_c, seg_d; wire [3:0] a, b, c, d; reg [3:0] tim_a, tim_b, tim_c, tim_d; reg [15:0] timer_count; assign a = {sw[0],sw[1],sw[2],sw[3]}; assign b = {sw[4],sw[5],sw[6],sw[7]}; assign c = ~{btn[0],btn[1],btn[2],btn[3]}; assign d = ~{btn[4],btn[5],btn[6],btn[7]}; wire clk0_1s; clkdiv(.clk(clk), .rst(1'b0), .max(24'd119999_99), .tc(clk0_1s)); debounce dbnc_1 (.clk(clk), .rst(rst), .key_in(btn[0]), .key_out(key1)); debounce dbnc_2 (.clk(clk), .rst(rst), .key_in(btn[7]), .key_out(key2)); toggle tgl_2 (.clk(clk), .rst(rst), .in(key2), .out(tgl)); assign led[3] = ~key1; // for debug assign zrst = ~key1; assign led[7] = ~tgl; // for debug always @ (posedge(clk0_1s)) begin if (tgl == 1'b1) begin timer_count = timer_count + 1; end else begin if (zrst == 1'b1) begin timer_count = 16'd00; end end //<<--------------------------------------------------- // binary to BCD convert // algorithm reference: // https://bravo-fpga.blogspot.com/2010/10/bin2bcd_29.html //reg [3:0] ones, tens, huns, thous; //integer i; thous = 0; huns = 0; tens = 0; ones = 0; for(i=15; i>=0; i=i-1) begin {thous, huns, tens, ones} = {thous[2:0],huns,tens,ones,timer_count[i]}; if(ones >= 5 && i > 0) ones = ones + 3; if(tens >= 5 && i > 0) tens = tens + 3; if(huns >= 5 && i > 0) huns = huns + 3; if(thous >= 5 && i > 0) thous = thous + 3; end //>>--------------------------------------------------- // case1: binary to BCD tim_a <= thous; tim_b <= huns; tim_c <= tens; tim_d <= ones; // case2: hex counter /* tim_a <= timer_count[15:12]; tim_b <= timer_count[11:8]; tim_c <= timer_count[7:4]; tim_d <= timer_count[3:0]; */ end /* always */ drv7seg seg_1 (.in(tim_a), .dp(1'b0), .seg(seg_a)); // leftmost digit drv7seg seg_2 (.in(tim_b), .dp(1'b0), .seg(seg_b)); drv7seg seg_3 (.in(tim_c), .dp(1'b1), .seg(seg_c)); drv7seg seg_4 (.in(tim_d), .dp(1'b0), .seg(seg_d)); mux7seg mux7seg_1 ( .clk(clk), .seg_a(seg_a), .seg_b(seg_b), .seg_c(seg_c), .seg_d(seg_d), .seg(seg), .seg_dig(seg_dig) ); endmodule

debounce.v

module debounce ( input clk, input rst, input key_in, output key_out ); //reg [3:0] key_n; reg [7:0] key_n; wire clk400Hz; clkdiv clkdiv_1 (.clk(clk), .rst(rst), .max(2999), .tc(clk400Hz)); always @(posedge(clk400Hz) or posedge(rst)) begin if (rst == 1'b1) begin key_n = 4'd0; end else begin key_n[7] <= key_n[6]; key_n[6] <= key_n[5]; key_n[5] <= key_n[4]; key_n[4] <= key_n[3]; // key_n[3] <= key_n[2]; key_n[2] <= key_n[1]; key_n[1] <= key_n[0]; key_n[0] <= key_in; end end assign key_out = & key_n; // key_n[1] | key_n[2] | key_n[3] endmodule

toggle.v

module toggle ( input clk, rst, in, output reg out ); reg prev_in; always @(posedge rst or posedge clk) begin if (rst == 1'b1) begin out <= 1'b0; prev_in <= 1'b0; end else begin prev_in <= in; if ({prev_in, in} == 2'b10) out <= ~out; else out <= out; end end /* always */ endmodule

仕様:

stopwatch (1)最右端のボタンは、start/stopになっており、トグルになっている。 (2)最左端のボタンは、resetになっており、stop状態で押すと、カウンターがゼロになる。 (3)7セグメントLEDの最右端は、0.1秒のカウンターになっている。 課題: ・7セグメント表示のリフレッシュタイミングが不適切なようで、  最右端の7セグメントLEDは、スムーズに表示できていない。 ・タイマー精度は、あまり高くない。 ・bib2bcdは、moduleのままでは、文法エラーで組み込むことができなかったので、  top_stopwatch.vの本体に組み込んだ。

参照情報

verilog samples:
神のBIN2BCD
【問題1】 Verilog HDLをマスターしよう!!
【問題2】 4ビット加算器をVerilog HDLで記述しよう
【問題11】 パラメタライズによる回路の記述
Verilog Full Adder

ボード関係:
Gowin RUNBER FPGA Development Board
RUNBER Development Board - Hardware Instructions
RUNBER Development Board - Instructions for Experiments
Gowin_device&Software User Guide
Gowin_RUNBER_BOARD Source Code
Runber_Development_Board_Schematics
GOWIN RUMBERのLチカを階層に分割してみる

linuxツール関係:
GOWIN GW1N-UV4LQ144C6/I5を動かす

verilog関係:
Verilog-HDL入門
Verilog入門(alwaysなど)
Getting Started with a free Verilog Simulator
Icarus Verilog - Getting Started
Icarus Verilogの導入とAND回路のシミュレーション
Icarus Verilogコンパイラを使う

Tools関連:
Analyzer Oscilloscopeの使い方
Tang Nanoで内部信号のモニタリング

以上

|

« M5Stamp-PICO Arduino Install | トップページ | M5Paper Arduino Install »

verilog」カテゴリの記事

コメント

この記事へのコメントは終了しました。