VHDLとVerilog(2)

VHDLとVerilog(2)

VHDLとVerilog(1)の続きです。どっちでも良いとはいえ、実際のVHDLやVerilogを見てみるのが一番です。

 この回路を実際にVHDLとVerilogで設計してみます。

VHDL

 上の回路図に記入してある赤丸はwireとregに合わせてあります。実際のVHDLと見比べてみてください。

--  TITLE:					"datasel.vhd"
--  MODULE NAME:			datasel
--  PROJECT CODE:			
--  AUTHOR:					 (****@nakaharagiken.com)
--  CREATION DATE:			2020.1.1
--  SOURCE:            		
--  LICENSE:           		Copyright (c) 2020 nakaharagiken All rights reserved. 
--  DESCRIPTION:            2系統の信号から1系統を選択。レジスタ付き
--  NOTES TO USER:			入力信号は予めチャタリング処理しておくこと
--  SOURCE CONTROL:			
--  REVISION HISTORY:  	    v0.1	2020.1.2	First edition
--
--
--
--
--
--
--
--
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity datasel is
port (
	clock:				in	std_logic;						-- system clock
	nreset:				in	std_logic;						-- asynchronous reset 				____reset___|~~~normal~~~
	enable:				in	std_logic;						-- enable							________|~enable~|_______
	SwitchIn_A:			in	std_logic;						-- 入力ピンからの信号A 				
	SwitchIn_B:			in	std_logic;						-- 入力ピンからの信号B				
	input_sel:			in	std_logic;						-- 入力ピンからのセレクト信号		___input_A__|~~input_B~~~
	output_ans:			out	std_logic						-- A/B選択結果信号,レジスタ付き
);
end entity datasel;

architecture rtl of datasel is

---------------------------------------------------------------
-- SIGNALS
---------------------------------------------------------------
signal	wInputSeldA:		std_logic;						
signal	wInputSeldB:		std_logic;						
signal	wnInputSel:			std_logic;						
signal	wSeldSignal:		std_logic;						
signal	rSeldSignal:		std_logic;						-- セレクタ後のレジスタ

begin

wnInputSel <= not input_sel;
wInputSeldA <= SwitchIn_A and input_sel;
wInputSeldB <= SwitchIn_B and wnInputSel;
wSeldSignal <= wInputSeldA or wInputSeldB;



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

output_ans <= rSeldSignal;


end architecture rtl;

Verilog

//  TITLE:					"datasel.v"
//  MODULE NAME:			datasel
//  PROJECT CODE:			
//  AUTHOR:					 (****@nakaharagiken.com)
//  CREATION DATE:			2020.1.1
//  SOURCE:            		
//  LICENSE:           		Copyright (c) 2020 nakaharagiken All rights reserved. 
//  DESCRIPTION:            2系統の信号から1系統を選択。レジスタ付き
//  NOTES TO USER:			入力信号は予めチャタリング処理しておくこと
//  SOURCE CONTROL:			
//  REVISION HISTORY:  	    v0.1	2020.1.2	First edition
//
//
//
//
//
//
//
//
`timescale 1ns/1ps

module datasel(
	clock,							//	in	system clock
	nreset,							//	in	asynchronous reset 				____reset___|~~~normal~~~
	enable,							//	in	enable							________|~enable~|_______
	SwitchIn_A,						//	in	入力ピンからの信号A 				
	SwitchIn_B,						//	in	入力ピンからの信号B				
	input_sel,						//	in	入力ピンからのセレクト信号		___input_A__|~~input_B~~~
	output_ans,						//	out	A/B選択結果信号,レジスタ付き
);

input	clock;						//	in	system clock
input	nreset;						//	in	asynchronous reset 				____reset___|~~~normal~~~
input	enable;						//	in	enable							________|~enable~|_______
input	SwitchIn_A;					//	in	入力ピンからの信号A 				
input	SwitchIn_B;					//	in	入力ピンからの信号B				
input	input_sel;					//	in	入力ピンからのセレクト信号		___input_A__|~~input_B~~~
output	output_ans;					//	out	A/B選択結果信号,レジスタ付き

///////////////////////////////////////////////////////////////
// SIGNALS
///////////////////////////////////////////////////////////////
wire	wInputSeldA;
wire	wInputSeldB;
wire	wnInputSel;
wire	wSeldSignal;
reg		rSeldSignal;					// セレクタ後のレジスタ

assign	wnInputSel = ~input_sel;
assign	wInputSeldA = SwitchIn_A &amp; input_sel;
assign	wInputSeldB = SwitchIn_B &amp; wnInputSel;
assign	wSeldSignal = wInputSeldA | wInputSeldB;

//////////////////////////////////////////
// rSeldSignal レジスタ
//////////////////////////////////////////
always @ (posedge  clock, negedge nreset) begin
	if (!nreset) begin
		rSeldSignal <= 1'b0;
	end else begin
		if (enable == 1'b1) begin
			rSeldSignal <= wSeldSignal;
		end
	end
end

assign	output_ans = rSeldSignal;

endmodule

 以上のように、VHDLやVerilogで書かれた回路図のことを、コードとかソースコードとか言います。このあたりはソフトウェアと同じですね。

 ソースコードの詳細説明はまたの機会にしますが、今回はVHDLとVerilogの違いを見てください。VerilogはソフトウェアのPascal言語に似ていると思います。もっとも、Pascal言語がほとんど見なくなっていますので、初心者には同じに見えるかも知れません。
 論理式の書き方はVHDLの方が読みやすいと思います。

 VHDLとVerilogは細かい構文が違いますが、考え方は一緒です。wireとregの宣言部分が大きく違う所です。

 よく、VHDLは型が厳格で、Verilogの方が曖昧。という説明をする人がいますが、wireとregという観点から見ると、Verilogの方が厳格です。このwireとregを厳格に区別できるので、意図せずにラッチになる危険性はVerilogの方が低いと言えます。
 ただし、VHDLでも最近のコンパイラは優秀ですので、意図しないラッチはコンパイルでワーニングを出してくれるので、言語の選定基準にはしない方が良いと思います。

 何度もwireとregにこだわって説明しているのには、訳があります。回路図の最後にregを置いていますが、FPGAを使ったデジタル回路はこのように、regを意識して挿入する必要があります。このような設計をクロック同期設計といいます。

 クロック同期設計は昨今のデジタル回路設計において必須の技術です。反対語として、非同期設計というのがありますが、今は非同期設計をすることはまず無いと思って良いでしょう。

 「regを意識して挿入する」ということは、「DFFを意識して挿入する」ということです。このことを忘れないでください。

 VHDLとVerilogの比較はあまり意味がないので、流れにまかせて学習すればよいでしよう。最初に買った本がVHDLだったとか、先輩から見せてもらったコードがVerilogだった。という理由でスタートしている方がほとんどだと思います。