Verilogを使ってみる

by K.I
2007/02/04〜

Index


概要


[top]

StarterKIT

RS232C

RS232 port DB9 Spartan3
RXD Pin3 T13
TXD Pin2 R13

スライドスイッチ

Switch SW7 SW6 SW5 SW4 SW3 SW2 SW1 SW0
FPGA Pin K13 K14 J13 J14 H13 H14 G12 F12

プッシュボタン

PushButton BTN3 (UserReset) BTN2 BTN1 BTN0
FPGA Pin L14 L13 M14 M13

LED

LED LED7 LED6 LED5 LED4 LED3 LED2 LED1 LED0
FPGA Pin P11 P12 N12 P13 N14 L12 P14 K12

Clock

Oscillator Source FPGA Pin
50MHz(IC4) T9
Socket(IC8) D9

[top]

Xilinx ISE

プロジェクトを作る

UCFファイル

I/O Name I/O Direction Loc Bank I/O Std.
RXD Input T13 BANK4
TXD Output R13 BANK4

bitファイル

MCSファイルを作る

コンフィグレーションPROMへ書き込み

UCFファイルの書換え

I/O Name I/O Direction Loc Bank I/O Std.
SW Input M13 BANK3
LED Output K12 BANK3

1JTAGを使ってコンフィグレーションPROMに書き込む場合でも、CCLKを選択する。
2何でこんな面倒な仕様なんだろう。。自動的に変換して書けるようにもすれば良いのに。。。
3一度使い方が分かったはずだったんだけど、久しぶりに弄ったら嵌ってしまった。なんて分かり難いツールなんだ。。。

[top]

Verilogでプログラム

カウンタを記述する

テストベンチ

シュミレーション


[top]

UART

分周器

`timescale 1ns / 1ps

module clkgen(rxck, txck, rst, clk);
        output rxck;
        output txck;
        input rst;
        input clk;

        reg rxck;       // alwaysから変化させるので、regとしても指定
        reg txck;
        reg [10:0] rxcount;
        reg [1:0] txcount;

        always @(posedge clk or posedge rst) begin
        // 非同期リセットなので、センシビリティリストにrstを入れる
                if (rst == 1'b1) begin
                        rxcount <= 0;                   // 非同期リセット
                        rxck <= 0;
                end else if (count == 1301) begin       // 1302分周
                        rxcount <= 0;
                        rxck <= 1;
                end else begin
                        rxcount <= count + 1;           // Upカウント
                        rxck <= 0;
                end
        end

        always @(posedge clk or posedge rst) begin
        // 非同期リセットなので、センシビリティリストにrstを入れる
                if (rst == 1'b1) begin
                        txcount <= 0;                   // 非同期リセット
                        txck <= 0;
                end else if (count == 3) begin 
                        txck <= 1;                      // 4分周
                end else if (rxck == 1'b1) begin
                        txcount <= txcount + 1;         // Upカウント
                        txck <= 0;      
                end
        end

endmodule

ノイズ除去回路

`timescale 1ns / 1ps

module ncan(rxd, buf, rst, rxck, clk);
        input rxd;
        output [7:0] buf;
        input rst;
        input rxck;
        input clk;

        reg [7:0] buf;
        wire cont;

        always @(posedge clk or posedge rst) begin
                if (rst == 1'b1) begin
                        buf <= 8'b00000000;     // 非同期リセット
                end else if (rxck == 1'b1) begin
                        buf <= buf >> 1;        // シフト
                        buf[7] <= rxd;
                        buf[4] <= ncout;
                end
        end

        function nc;
                input [2:0] in;
                if (in == 3'b000)
                        nc = 0;                 // 3回連続0で0出力
                else if (in == 3'b111)
                        nc = 1;                 // 3回連続1で1出力
        endfunction

        assign ncout = nc(buf[7:5]);            // これが簡易雑音除去回路ってことで

endmodule

ステートマシン

`timescale 1ns / 1ps

module state(buf, rst, state, rxck, rxck4, clk);
        input [7:0] buf;
        input rst;
        output[3:0] state;
        input rxck;
        output rxck4;
        input clk;

        reg [3:0] state;
        reg [1:0] rxcount4;

        assign start = (buf[3:0] == 4'b0011)?1:0;       // スタートビット検出

        always @(posedge clk or posedge rst) begin
        // 非同期リセットなので、センシビリティリストにrstを入れる
                if (rst == 1'b1) begin
                        rxcount4 <= 0;                  // 非同期リセット
                end else if (rxck == 1 && start == 1) begin 
                        rxcount4 <= 0;                  // startで同期リセット
                end else if (rxck == 1) begin
                        rxcount4 <= txcount4 + 1;       // Upカウント
                end
        end

        assign rxck4 = (rcount4 == 2'b11)?1:0;          // rxck4のタイミングは調整必要かも

        always @(posedge clk or posedge rst) begin
        // 非同期リセットなので、センシビリティリストにrstを入れる
                if (rst == 1'b1) begin
                        state <= 0;                     // 非同期リセット
                        start <= 0;
                end else if (rxck4 == 1'b1 && (start == 1'b1 || state == 4'b1001)) begin 
                        state <= 0;                     // スタートビット検出、状態9で同期リセット
                        start <= 0;
                end else if (rxck4 == 1'b1) begin
                        state <= state + 1;             // Upカウント
                end
        end

endmodule

シリパラ変換


[top]

参考

いろいろ参考にさせて頂いたサイト(感謝)

UARTのコード


[top]

メモ

メタステーブル

リセット回路


4不安定状態が長時間続いたり、発振状態になるかもしれない。
5不安定状態の影響を最小に、短時間で収めたいということだと思う。

[top]

エラー

does not match a known FF or Latch template.">ERROR:Xst:899 - "xxxx.v" line nnn: The logic for does not match a known FF or Latch template.

ERROR:Pack:1107 - Unable to combine the following symbols into a single IOB


[top] [電子工作関連に戻る]

comments powered by Disqus