diceを動かしてみましたの続きになります。
やっぱり、7セグLEDの方が雰囲気が出るということで、比叡につないでみました。
![](https://blogimg.goo.ne.jp/user_image/40/c9/ac0d2c04629b360cc8e5cde79f6ec629.jpg)
Spartan-3スタータキットにあわせて、アノードコモンの7セグLEDにしています。
電流制限抵抗は510Ωなので1セグメントあたり3mAくらい流れている計算になります。
ちゃんとデータシート見てないけど、このくらいならたぶん平気かな。
比叡の回路図を見ると電流制限抵抗が120Ωでした。
というわけで、オリジナルのVHDLソースをなるべくそのままVerilogに書き直してみました。(<が全角になっています)
Verilogにはtypeがないのでparameterでごまかしています。
オリジナルと違うのは比叡に合わせてリセットをアクティブローにしているところと、roll_nodeの初期値を1にしたことです。roll_nodeは0のとき、キーが押されていることになるのですが、リセットを押した直後は一瞬だけキーを押したことになるので、リセットのときの初期値を1'b1、つまりキーは押されていない状態にしました。
VHDLはなんでもsignalでいいみたいなんですが、Verilogは状況に応じてwireとregを使い分けないといけないのが面倒です。
VHDLの方は35スライスでしたが、Verilogだと32スライスと3スライス減りました。理由は分かりません。
いい勉強をさせていただきました。
やっぱり、7セグLEDの方が雰囲気が出るということで、比叡につないでみました。
![](https://blogimg.goo.ne.jp/user_image/40/c9/ac0d2c04629b360cc8e5cde79f6ec629.jpg)
Spartan-3スタータキットにあわせて、アノードコモンの7セグLEDにしています。
電流制限抵抗は510Ωなので1セグメントあたり3mAくらい流れている計算になります。
ちゃんとデータシート見てないけど、このくらいならたぶん平気かな。
比叡の回路図を見ると電流制限抵抗が120Ωでした。
というわけで、オリジナルのVHDLソースをなるべくそのままVerilogに書き直してみました。(<が全角になっています)
// dice_top.vhd module dice_top (reset_sw, clk, roll, an_n, a_n, b_n, c_n, d_n, e_n, f_n, g_n, dp_n); input reset_sw; input clk; input roll; output [3:0] an_n; output a_n; output b_n; output c_n; output d_n; output e_n; output f_n; output g_n; output dp_n; wire roll_sig; wire roll_ena; wire [2:0] binary; assign an_n = 4'b1110; assign dp_n = 1'b1; reject_chatter inst_reject_chatter ( .reset_sw(reset_sw), .clk(clk), .roll(roll), .roll_sig(roll_sig), .roll_ena(roll_ena) ); dice_state_machine inst_dice_sm ( .reset_sw(reset_sw), .clk(clk), .roll(roll_sig), .roll_ena(roll_ena), .spots(binary) ); seven_seg_dec inst_seven_seg_dec ( .binary(binary), .a_n(a_n), .b_n(b_n), .c_n(c_n), .d_n(d_n), .e_n(e_n), .f_n(f_n), .g_n(g_n) ); endmodule // reject_chatter.vhd module reject_chatter (reset_sw, clk, roll, roll_sig, roll_ena); input reset_sw; input clk; input roll; output roll_sig; output reg roll_ena; // parameter frequency_KHz = 1; parameter frequency_KHz = 50000; parameter divided_200Hz = frequency_KHz * 5; reg [17:0] sw_cnt; reg [1:0] roll_cnt; reg roll_node; // 200Hz, 5ms always @(posedge clk or negedge reset_sw) if(reset_sw == 1'b0) sw_cnt <= 0; else if(sw_cnt == (divided_200Hz - 1)) sw_cnt <= 0; else sw_cnt <= sw_cnt + 1; always @(posedge clk or negedge reset_sw) if(reset_sw == 1'b0) roll_node <= 1'b1; else if(sw_cnt == (divided_200Hz - 1)) roll_node <= roll; assign roll_sig = roll_node; // 50Hz, 20ms always @(posedge clk or negedge reset_sw) if(reset_sw == 1'b0) begin roll_cnt <= 2'b00; roll_ena <= 1'b0; end else if(sw_cnt == (divided_200Hz - 1)) if(roll_cnt == 2'b11) begin roll_cnt <= 2'b00; roll_ena <= 1'b1; end else begin roll_cnt <= roll_cnt + 1; roll_ena <= 1'b0; end else roll_ena <= 1'b0; endmodule // dice_state_machine.vhd module dice_state_machine (reset_sw, clk, roll, roll_ena, spots); input reset_sw; input clk; input roll; input roll_ena; output reg [2:0] spots; parameter [2:0] st_one = 3'h1, st_two = 3'h2, st_three = 3'h3, st_four = 3'h4, st_five = 3'h5, st_six = 3'h6; reg [2:0] current_state, next_state; always @(posedge clk or negedge reset_sw) if(reset_sw == 1'b0) current_state <= st_one; else current_state <= next_state; always @(current_state, roll, roll_ena) case(current_state) st_one : begin spots = 3'b001; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_two; else next_state = st_one; end st_two : begin spots = 3'b010; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_three; else next_state = st_two; end st_three : begin spots = 3'b011; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_four; else next_state = st_three; end st_four : begin spots = 3'b100; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_five; else next_state = st_four; end st_five : begin spots = 3'b101; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_six; else next_state = st_five; end st_six : begin spots = 3'b110; if(roll == 1'b1 & roll_ena == 1'b1) next_state = st_one; else next_state = st_six; end default : begin spots = 3'b001; next_state = st_one; end endcase endmodule // seven_seg_dec.vhd module seven_seg_dec (binary, a_n, b_n, c_n, d_n, e_n, f_n, g_n); input [2:0] binary; output reg a_n; output reg b_n; output reg c_n; output reg d_n; output reg e_n; output reg f_n; output reg g_n; always @(binary) case(binary) 3'b001: begin // 1 a_n = 1'b1; b_n = 1'b0; c_n = 1'b0; d_n = 1'b1; e_n = 1'b1; f_n = 1'b1; g_n = 1'b1; end 3'b010: begin // 2 a_n = 1'b0; b_n = 1'b0; c_n = 1'b1; d_n = 1'b0; e_n = 1'b0; f_n = 1'b1; g_n = 1'b0; end 3'b011: begin // 3 a_n = 1'b0; b_n = 1'b0; c_n = 1'b0; d_n = 1'b0; e_n = 1'b1; f_n = 1'b1; g_n = 1'b0; end 3'b100: begin // 4 a_n = 1'b1; b_n = 1'b0; c_n = 1'b0; d_n = 1'b1; e_n = 1'b1; f_n = 1'b0; g_n = 1'b0; end 3'b101: begin // 5 a_n = 1'b0; b_n = 1'b1; c_n = 1'b0; d_n = 1'b0; e_n = 1'b1; f_n = 1'b0; g_n = 1'b0; end 3'b110: begin // 6 a_n = 1'b0; b_n = 1'b1; c_n = 1'b0; d_n = 1'b0; e_n = 1'b0; f_n = 1'b0; g_n = 1'b0; end default : begin a_n = 1'b1; b_n = 1'b0; c_n = 1'b0; d_n = 1'b1; e_n = 1'b1; f_n = 1'b1; g_n = 1'b1; end endcase endmodule
Verilogにはtypeがないのでparameterでごまかしています。
オリジナルと違うのは比叡に合わせてリセットをアクティブローにしているところと、roll_nodeの初期値を1にしたことです。roll_nodeは0のとき、キーが押されていることになるのですが、リセットを押した直後は一瞬だけキーを押したことになるので、リセットのときの初期値を1'b1、つまりキーは押されていない状態にしました。
VHDLはなんでもsignalでいいみたいなんですが、Verilogは状況に応じてwireとregを使い分けないといけないのが面倒です。
VHDLの方は35スライスでしたが、Verilogだと32スライスと3スライス減りました。理由は分かりません。
いい勉強をさせていただきました。
>VHDLはなんでもsignalでいいみたいなんですが
が気になってこのあたりを入門書で復習してみました。
VHDLのオブジェクトクラスには「constant」「signal」「
variable」があるとかいてあるんですが、このsignalとvariableのお話とは関係ないでしょうかね?
verilogがよく解ってないのでなんともいえないんですが…
wireとregという文言からするとニュアンスがやっぱりちょっと違う気もする…
確かにsignalで定義したものを合成したときに、レジスタが使われるのか単なる配線になっちゃうのか、よく判んなかったりして混乱した記憶があります。
ロジックIC組み合わせて回路組むときとVHDLで回路書くときでは、そのあたりが全然違う感覚なので戸惑ってしまいます…難しいですね。
私の理解している範囲で話させてください。
まずは、ざっくりverilogのalwaysとVHDLのprocessが対応しています。verilogでは、alwaysの中で代入されるのがreg宣言、alwaysの外で代入されるのがwire宣言します。VHDLではprocessの中で代入されるものも外で代入されるものも、どちらもsignal宣言でいいみたいです。
クロック用のprocess文と組み合わせ回路用のprocess文があるのは、alwaysも一緒です。クロック用のprocess文で代入されるsignalはFFになって、それ以外は配線になります。verilogの場合は、reg宣言はalways文内で代入されることを示しているだけなので、どちらのalwaysで使われるかによってFFになるか配線になるかの場合分けが出てきます。regと書いてあるのにFFにならないのは、なんか変な感じです。
どちらもプログラマの意図を反映していないような気がします。せっかく宣言するのだから、FFにしたいという意図を記述させるようにして、もしFFにならなかったらエラーを出す、という方が安全な気がします。verilogのように形式的に宣言を使い分けるのって、なんか意味がなくて嫌です。逆にVHDLもなんでもかんでもsignalでいいなら宣言する意味ないじゃん、とか思っちゃいます。
センシティビティリストの件でも、プログラマが注意深くならないといけない言語って、結局ミスの元になるので生産性が低くなっちゃいます。このあたりは嫌なところです。verilogの宣言しなくても信号が使えちゃうあたりなんか最悪です。そのあたりはverilog 2001で改善されたので、私はverilog 2001が好きです。
なんか長々とすみません。
もし、さしつかえなければ、ご利用ください。
> http://noritan-micon.blog.so-net.ne.jp/2009-06-11
> HTML文書作成用コード変換器
ありがとうございます。同期版も勉強させていただきます。
ご紹介ありがとうございます。
試しに使ってみました。ちゃんと<が<になってくれました。
ちょっと愚痴。gooブログって、一度セーブすると、せっかく<にしたのが全部<に化けちゃうんです。あっ、間違った、直そうとすると、またソースを貼りなおさないといけないみたいで、もう勘弁してってかんじてす><。
>verilogの場合は、reg宣言はalways文内で代入されることを示しているだけなので、どちらのalwaysで使われるかによってFFになるか配線になるかの場合分けが出てきます。regと書いてあるのにFFにならないのは、なんか変な感じです。
なるほど。verilogとVHDLでは事情の違いはあるにしても、このあたりはなんとなくしっくり来ない感があるっていうことなんでしょうかね…
なんとなく、生成後にどんな回路に変換されるのかが想像しにくいのは困ってしまいますね。何らかの記述をすると明示でいるのだと解り易くていいんですけどね。
現状だと、慣れるしかないのが悲しいところです。HDLも人間が楽できる方向に進化してもらいたいものです。