SSブログ

ふにゃふにゃHDL [HDL]

最近verilogが多いです。好みはVHDLですが。
検証は(system)verilogが使えると便利だと思います。しかしModelSimの混在シミュレーションライセンスなんて持ってるわけもないので(というかAltera Starter Edition、無料、ありがたや)、やるときはどちらかですが。ホントはCが使いたいですけどね~

そんなverilogの妙ながら便利な記述について。
非同期な動作と同期な動作を記述するとき、例えばリセットが2系統あるとき、
always @(posedge a_reset or posedge c_clock) begin
	if (a_reset) begin
		/*非同期リセット処理*/
	end
	else begin
		if (c_reset) begin
			/*同期リセット処理*/
		end
		else begin
			/*同期処理*/
		end
	end
end	
って書いたりします。これは割と普通。VHDLではこんな感じ。
process(a_reset, c_clock)
begin
	if (a_reset = '1') then
		--非同期リセット処理
	elsif (c_clock'event and c_clock = '1') then
		if (c_reset = '1') then
			--同期リセット処理
		else
			--同期処理
		end if;
	end if;
end process;
似てますが、クロックエッジの判定をverilogではalways文で行って、VHDLではif文で行うところが異なります。実はこの書き方、VHDL風に寄せてverilogを書いていて、「非同期処理と同期処理は別ですよ~」って明示するために「a_reset 」のブロックとそれ以外のブロックに大きく分けて書いてます。

けど、verilogはそんな書き方をする必要なかったりします。
always @(posedge a_reset or posedge c_clock) begin
	if (a_reset) begin
		/*非同期リセット処理*/
	end
	else if (c_reset) begin
		/*同期リセット処理*/
	end
	else begin
		/*同期処理*/
	end
end	
非同期処理と同期処理が同じレベルな事に注意。この書き方はVHDLは不許可です。
さらにもし非同期と同期のリセット処理が同じだったら、
always @(posedge a_reset or posedge c_clock) begin
	if (a_reset || c_reset) begin
		/*非同期/同期リセット処理*/
	end
	else begin
		/*同期処理*/
	end
end	
という書き方もできます。条件が増えてもOK。
always @(posedge a_reset or posedge c_clock) begin
	if (a_reset || c_reset) begin
		/*非同期/同期リセット処理*/
	end
	else if (ready) begin
		/*同期処理*/
	end
	else begin
		/*同期処理*/
	end
end	
シミュレーションはもちろん、合成してもちゃんとした回路ができてます(全ての処理系で試した訳では無いですが)。c_resetやready周りに変な回路ができるような様子も無さそうです。

…うわ~きもちわるい!!けど便利w
下の書き方を見ても「?なにがおかしいの?」と思う人がいるかも知れません。一方「ありえねぇ~!」って人もいるかも知れません。両極端になりそう。私は後者に近いです。けど便利なのでこの記述もしちゃいます。
verilogはVHDLに比べ記述が少ないのですが、この辺の緩さが逆に気持ち悪かったりします。

ところで、alwaysの記述で最初納得のいかなかった所は、非同期のa_resetの扱い。
例えばリセットの極性を切り替えるときはどうすれば良いでしょう?
正論理
always @(posedge a_reset or posedge c_clock) begin
	if (a_reset) begin
負論理
always @(negedge a_reset or posedge c_clock) begin
	if (~a_reset) begin
こう書くとシミュレーションできても合成はできない。
always @(a_reset or posedge c_clock) begin
	if (a_reset) begin
反転してから使う。
wire	reset = a_reset ^ pol;
always @(posedge reset or posedge c_clock) begin
	if (reset) begin
レベルセンスの信号なのにエッジを指定する必要がある、というのが腑に落ちません。また、posedge→if (areset)、negedge→if (~areset)、の関係は崩れないので冗長です。これまた気持ち悪い。そういうモノだ、と思うしか無いです。
VHDLでは素直な話です。
generic (
	pol	: std_logic	:= '0'	極性
…
process(a_reset, c_clock)
begin
	if (a_reset = pol) then

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0

実体顕微鏡オーディオ環境 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。