デジタル回路のスイッチ入力の同期化

デジタル回路のスイッチ入力の同期化

 引き続きデジタル回路へのスイッチ入力を考えます。設計の方針は決まったので、ブロック図を描いてみます。

 このように簡単な回路設計でもブロック図を描くというのは非常に大切です。これが設計資料として残っていれば、あとからソースコードをメンテナンスする人はかなり助けになるでしょう。

 ブロック図について説明します。プログラムではフロー図などで全体の構造を示しますが、電子回路の場合それに相当するのがブロック図です。ブロック図は基本的に左から右に信号が流れるように描きます。

 左端の非同期入力であるクロック信号を右端の同期化されたパルス信号として生成します。今回は1回のスイッチ操作で1パルス出力するようにします。

 今回のブログでは黄色で示したところを設計します。

 非同期であるスイッチの信号を同期化するにあたり、一番簡単な方法はFPGAのクロックでDFFを通すことです。この事をエンジニア同士の会話では「クロックで叩く」といいます。ただし、非同期の信号なのでDFFのセットアップ、ホールドを満足していない可能性もあります。このことをメタステーブルといいます。

 メタステーブル対策ではメタステーブルを最小限に抑える。という設計をします。具体的にはDFFを何段か重ねてクロックで叩きます。このようにDFFを何段か重ねることをシフトレジスタといいます。

 シフトレジスタを使ったメタステーブル対策の回路を次に示します。回路図の中の各名称とVHDL、Verilogの各名称を合わせてありますので、信号の流れを読み取ってみてください。

  シフトレジスタは非常に重要な回路なのでこれを機会に習得してください。今回は2つのDFFでシフトレジスタを作っています。2つのDFFなので2ビットのシフトレジスタになります。「2ビットシフトレジスタ」というのは上の回路図で見た方が分かりやすいかも知れません。8個繋がっていたら8ビットのシフトレジスタという事になります。ランダマイザという回路の元になる回路です。

--  TITLE:					"Synchronizing.vhd"
--  MODULE NAME:			datasel
--  PROJECT CODE:			
--  AUTHOR:					Norio Nakahara (****@nakaharagiken.com)
--  CREATION DATE:			2020.1.1
--  SOURCE:            		
--  LICENSE:           		Copyright (c) 2020 nakaharagiken All rights reserved. 
--  DESCRIPTION:            メタステーブル対策 DFF-DFF
--  NOTES TO USER:			出力は2クロック遅延
--  SOURCE CONTROL:			
--  REVISION HISTORY:  	    v0.1	2020.1.2	First edition
--
--
--
--	indata -> DFF -> DFF -> outdata
--
--
--
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;


entity Synchronizing is
port (
	clock:				in	std_logic;						-- system clock
	nreset:				in	std_logic;						-- asynchronous reset 				____reset___|~~~normal~~~
	enable:				in	std_logic;						-- enable							________|~enable~|_______
	indata:				in	std_logic;						-- 入力信号
	outdata:			out	std_logic						-- 出力信号
);
end entity Synchronizing;

architecture rtl of Synchronizing is

---------------------------------------------------------------
-- SIGNALS
---------------------------------------------------------------
signal	rDFF_1st:		std_logic;						-- 第一弾のDFF シフトレジスタ
signal	rDFF_2nd:		std_logic;						-- 第二弾のDFF シフトレジスタ


begin

------------------------------------------
-- 2bit シフトレジスタ
------------------------------------------
process (clock,nreset) begin
	if nreset = '0' then									-- リセット初期化
		rDFF_1st <= '0';
		rDFF_2nd <= '0';
	elsif clock' event and clock = '1' then					-- clock 立ち上がり指示
		if (enable ='1') then								-- イネーブル
			rDFF_1st <= indata;
			rDFF_2nd <= rDFF_1st;
		end if;
	end if;
end process;

outdata <= rDFF_2nd;


end architecture rtl;

//  TITLE:					"Synchronizing.v"
//  MODULE NAME:			datasel
//  PROJECT CODE:			
//  AUTHOR:					Norio Nakahara (****@nakaharagiken.com)
//  CREATION DATE:			2020.1.1
//  SOURCE:            		
//  LICENSE:           		Copyright (c) 2020 nakaharagiken All rights reserved. 
//  DESCRIPTION:            メタステーブル対策 DFF-DFF
//  NOTES TO USER:			出力は2クロック遅延
//  SOURCE CONTROL:			
//  REVISION HISTORY:  	    v0.1	2020.1.2	First edition
//
//
//
//	indata -> DFF -> DFF -> outdata
//
//
//
//
`timescale 1ns/1ps


module Synchronizing(
	clock,							//	in	system clock
	nreset,							//	in	asynchronous reset 				____reset___|~~~normal~~~
	enable,							//	in	enable							________|~enable~|_______
	indata,							//	in	入力信号
	outdata							//	out	出力信号
);

input	clock;						//	in	system clock
input	nreset;						//	in	asynchronous reset 				____reset___|~~~normal~~~
input	enable;						//	in	enable							________|~enable~|_______
input	indata;						//	in	入力信号
output	outdata;					//	out	出力信号

///////////////////////////////////////////////////////////////
// SIGNALS
///////////////////////////////////////////////////////////////
reg		rDFF_1st;					// 第一弾のDFF シフトレジスタ
reg		rDFF_2nd;					// 第二弾のDFF シフトレジスタ



//////////////////////////////////////////
// 2bit シフトレジスタ
//////////////////////////////////////////
always @ (posedge  clock, negedge nreset) begin
	if (!nreset) begin
		rDFF_1st <= 1'b0;
		rDFF_2nd <= 1'b0;
	end else begin
		if (enable == 1'b1) begin		// イネーブル
			rDFF_1st <= indata;
			rDFF_2nd <= rDFF_1st;
		end
	end
end

assign outdata = rDFF_2nd;


endmodule

 VHDLとVerilogの両方で記述しました。VHDLで50行目からシフトレジスタの記述です。rDFF_1stとrDFF_2ndが数珠つなぎになっているのがわかると思います。

 enable信号が入っていて、今回は’1’固定で使うことになりますが、シフトレジスタではenable信号を使ってON/OFFすることが多いので、記述しています。このenableのON/OFFで信号を動かしたりと止めたりするのが同期設計では大切になります。

 このように非同期信号を同期化するには、数ビットのシフトレジスタを通してメタステーブル対策を行います。一般的には2~3ビットにすることが多いようです。

 ブロック図にて、同期化回路の後に同期微分回路があるので、本当はこの同期化回路は必要ありません。同期微分回路の中に2ビットのシフトレジスタが入るので、必然的にメタステーブル対策となるからです。今回は同期微分を説明する前にシフトレジスタとメタステーブルの解説を一緒に別にしたかったので、分けています。

 もし、スイッチにRCフィルタを入れてチャタリングを除去しているとか、同期微分回路を入れないで、スイッチの信号を直接使いたい。等の場合には、このメタステーブル対策のシフトレジスタは有効ですので、このような設計の考え方がある。というのは覚えておいてください。

 メタステーブルは実はFPGAへの非同期入力だけで起こるわけではありません。FPGAの内部でも起こります。最近のFPGAは規模が大きくなり、一つのFPGAに何本ものクロックが入力される事が少なくありません。

 このように一つのFPGAに何通かのクロックが入力されていると、それらが同期していない場合があります。この異なるクロックを全く別系統で動作させる事ができれば問題ないのですが、CPUからの命令をこれらに配分するなどの理由でどうしても別クロックの回路同士を接続しなくはならない場面に遭遇します。

 この時に、受ける側の回路で今回のメタステーブル対策を行うようにします。そのような配慮が安定した回路動作につながります。