はじめに:この章の内容は主に、Vivadoで Verilog 言語を使用した回路設計、シミュレーション、合成、およびダウンロードを説明することです。
例:カウンター
- 特徴: Xilinx Artix-7 XC7A35Tチップを使用
- コンフィギュレーション方法: USB-JTAG/SPI フラッシュ
- 最大 100MHz の内部クロック速度
- メモリ: 2Mbit SRAM N25Q064A SPI Flash (サンプル画像の旧モデルは N25Q032A)
- 汎用IO: スイッチ: x8LED: x16ボタン: x5DIP: x8 汎用拡張IO: 32pin
- オーディオおよびビデオ/ディスプレイ: 7 セグメント デジタル チューブ: x8 VGA ビデオ出力インターフェイス オーディオ オーディオ インターフェイス
- 通信インターフェース: UART: USB to UART Bluetooth: Bluetooth モジュール
- アナログ インターフェイス: DAC: 8 ビット分解能 XADC: 2 ウェイ 12 ビット 1Msps ADC
目次
0x00 D フリップフロップを使用してリング カウンタ (自己循環シフト レジスタ) を構築します
Ⅰ. 前提知識
0x00 D フリップフロップを使用してリング カウンタ (自己循環シフト レジスタ) を構築します
下図はDフリップフロップを使用して構成したカウンタ回路で、A、B、C、Dを初期値1000に設定し、CPをシングルパルスカウントに接続するとワンホットカウントが実現できます。
リングカウンターの原理
参照手順は以下の通りです。
module circle_counter(rst_n, clk, cnt );
parameter CNT_SIZE = 8;
input rst_n;
input clk;
output [CNT_SIZE-1 : 0] cnt;
reg [CNT_SIZE-1 : 0] cnt;
always@(posedge clk)
if(!rst_n)
cnt <= 8'b0000_0001; //初始值
else
cnt <= {cnt[0],cnt[CNT_SIZE-1 : 1]};//注意是循环移位,而非简单的移位
//cnt <= cnt>>1;
Endmodule
下の図では、上記の回路が 74LS10 3 入力 NAND ゲートで変更されており、初期値が 0000 の場合、次の CP パルスでカウンタ状態が自動的に 1000 にジャンプします。
あなたの起業経験を要約してください。(注: 74LS10 には NOT ゲートとして機能するゲートがあります)
セルフスタートリングカウンター
参照手順は次のとおりです。
module circle_counter(rst_n, clk, cnt );
parameter CNT_SIZE = 8;
input rst_n;
input clk;
output [CNT_SIZE-1 : 0] cnt;
reg [CNT_SIZE-1 : 0] cnt;
always@(posedge clk)
if(!rst_n)
cnt <= 8'b0000_0001; //初始值
else
cnt <= {cnt[0],cnt[CNT_SIZE-1 : 1]};//注意是循环移位,而非简单的移位
//cnt <= cnt>>1;
Endmodule
上記のコードは単なる単純な実装であり、自己起動の問題についてはあまり考慮せずに、リング カウンタの動作方法をシミュレートしています。
リングカウンタは、機能上ワンホット(ワンホットコード)カウンタとも呼ばれ、出力の1状態がカウントを示します。
主な欠点は、回路の状態を効果的に利用できないことであり、n ビットに対して、利用されない状態が 2n-n 個存在します。アプリケーションでは、この種のカウンタはステート マシンの状態コーディングによく使用されます。たとえば、4 ビット ワンホット カウンタのカウント シーケンスは、0001-0010-0100-1000 サイクルです。したがって、ほとんどの場合、この種のカウンターはカウンターとは呼ばれず、一種の状態エンコーディングと呼ばれます。
セルフスタート(無効な状態から有効な状態に自動的に遷移し、有効なサイクルに入る)が可能な回路を設計したい場合は、追加実験のステートマシン設計の実験内容を参考にして実現してください。状態ロジックを変更することによって、本質的には、無効な状態の二次状態を変更し、アクティブにすることです。
0x01 ツイストリングカウンター(ジョンソンカウンター)
基本原理: 初期状態を設定し、最上位ビットを反転し、それをシフトによって得られる最下位ビットの入力として使用します。
図に示すように:
ツイストリングカウンタ原理の模式図
参照コード:
module john_counter(rst_n, clk, cnt );
parameter CNT_SIZE = 4;
input rst_n;
input clk;
output [CNT_SIZE-1 : 0] cnt;
reg [CNT_SIZE-1 : 0] cnt;
always@(posedge clk)
if(!rst_n)
cnt <= 4'b0000 ; //初始值
else
cnt <= {~cnt[0],cnt[CNT_SIZE-1 : 1]}; //注意是循环移位,而非简单的移位
endmodule
Ⅱ. Verilog の実装:
0x00 リングカウンター
設計コード:
module circle_counter(rst_n, clk, cnt );
parameter CNT_SIZE = 8;
input rst_n;
input clk;
output [CNT_SIZE-1 : 0] cnt;
reg [CNT_SIZE-1 : 0] cnt;
always@(posedge clk)
if(!rst_n)
cnt <= 8'b0000_0001;
else
cnt <= {cnt[0],cnt[CNT_SIZE-1 : 1]};
endmodule
シミュレーションコード:
module test();
reg rst_n,clk;
wire [7:0]cnt;
circle_counter uut(.rst_n(rst_n),. clk(clk),. cnt(cnt));
initial begin
clk = 'b0;
rst_n = 'b0;
# 10
rst_n = 'b1;
# 2000
$finish;
end
always #5 clk = ~clk;
endmodule
シミュレーション波形図:
0x01 ツイストリングカウンター
ドキュメントのデザイン:
module john_counter(rst_n, clk, cnt );
parameter CNT_SIZE = 4;
input rst_n;
input clk;
output [CNT_SIZE-1 : 0] cnt;
reg [CNT_SIZE-1 : 0] cnt;
always@(posedge clk)
if(!rst_n)
cnt <= 4'b0000 ;
else
cnt <= {~cnt[0],cnt[CNT_SIZE-1 : 1]};
endmodule
シミュレーションファイル:
module tb_john_counter();
reg clk, rst_n;
wire [3:0] cnt;
john_counter uut(.rst_n(rst_n),. clk(clk),. cnt(cnt));
initial begin
clk = 'b0;
rst_n = 'b0;
# 10
rst_n = 'b1;
# 2000
$finish;
end
always #5 clk = ~clk;
Endmodule
シミュレーション波形図: