• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:verilog 符号付加減算(最上位符号拡張)について教えてください)

Verilog符号付加減算(最上位符号拡張)について教えてください

このQ&Aのポイント
  • Verilog初心者のため、2の補数形式の符号付加減乗算器を作成していますが、符号拡張の方法がわかりません。
  • 問題の箇所では{16{a[0]},a}や{16{a[0]},b}という表現がエラーになってしまいます。
  • どうやったら最上位ビットを増やすことができるのか教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

1です。 ちょっと意地悪な物言いでしたね。ゴメンナサイ。 例えば4bitの符号を8bitに拡張するときは、結局のところ {a[3],a[3],a[3],a[3],a[3],a[2],a[1],a[0]}と左側にどんどん一番左のbit(MSB)を加えていけばよいのです。 これを見やすく書いたのが { {4{a[3]}},a[3:0] }ということですよね。 加減算は符号拡張して左右のbit幅さえ合わせておけば問題なく演算できます。 q[32:0] = (aを33bitに符号拡張) + (bを33bitに符号拡張); です。aもbもqも同じbit幅にするのです。これだと溢れるような気がするかもしれませんが、こうしないと符号付加減算はおかしな事になります。 乗算はもっと面倒で、 wire absa[bit幅は考えてね],absb[bit幅は考えてね]; absa = a[MSB] ? (~a[MSB以外])+1 : a[MSB以外]; absb = b[MSB] ? (~b[MSB以外])+1 : b[MSB以外]; として absa*absb を演算し、最後にaとbの符号に応じてまた符号反転してください。 こういう書き方だと、実際のハードウェアに即してない気がするかもしれませんが(実際のハードは大抵符号付乗算器マクロを持っているので)、 コンパイラは優秀なもので、ちゃんと判断してマクロを割り当ててくれます。

sususun
質問者

補足

ありがとうございます!bit拡張はうまく行きました!! しかし乗算でかなり引っかかっていました(--;)1日つぶれです… いまはわからず下記のように書いていますが上位ビットが計算さません。(TT) ---------------------------------------------------------------- assign q =(c == 3'b000)?{{16{a[15]}},a}+{{16{b[15]}},b}: (c == 3'b001)?{{16{a[15]}},a}-{{16{b[15]}},b}: (c == 3'b010)?{a[15]^b[15],((a[14:0])*(b[14:0]))}: (c == 3'b011)?{{16{1'b1}},~a}: (c == 3'b100)?{{16{1'b1}},~b}: : : --------------------------------------------------------------- これの「 {{16{a[15]}} 」のところを33bitなので「 {{17{a[15]}} 」とすればいいわけですね。これはすぐにうまく行きそうです!!(^^) 乗算に関しては… やはり時間がかかりそうです。いま2度読んでみましたが理解できません。 absについてあしたよく調べてみます!! ありがとうございますm(_ _)m

その他の回答 (2)

回答No.2

1です。 以前の質問に要求仕様がありますね。33bit幅の出力、というわけですね。 入出力にレジスタ、って書いてありますよ。レジスタっていうのは曖昧な表現でどうとでも取れるのですが、恐らくFFのことでしょう。 外側でFFつけてください。kadai点数もらえませんよ。 33bit出力というのが非常に意地悪なところですね。 手抜きをすればどうという事はありませんが、冗長になるので点数は下がります(要するにほとんど意味の無いbitがあります)。 現実には「コンパイラが最適化するので手抜きできるところは手抜きをする」が正解ですが、大学の課題じゃそうもいかないでしょう。 しかし、仕事といいながら kadai って・・・

sususun
質問者

お礼

早速のご回答ありがとうございます。 仕事で与えられた課題です^^;大学生じゃありません。 悪しからず FFではないらしいです。記述の途中経過を見せたところ assign文でいいようなので。

回答No.1

{{16{a[0]}},a[15:0]} のように、括弧を追加してください。 {16{a[0]}} というように、bitの繰り返し記述の外側が {}で囲まれてないと文法エラーです。たしか。 あと、どのようなものをお考えか判りませんが通常符号拡張はMSBです。 a[15]ではないですか? それから拡張が16bit+16bitで32bitしかありません。1bit足りていませんね。 それよりも、乗算 * は、符号つきだと意図した演算にはならなと思います。たぶん。 絶対値をとって乗算し、符号付きに直す、というのが常道です。 符号同士の演算ははxorで判りますので。 あと、16bit signed x 16bit signed は 最大で31bit signedですね。 33bitも必要ないです。(要求仕様が33bitなのかもしれませんが) 以上はverilog1995まででの話です。2001は符号付きの型があります。 ※頭で考えただけで確認はしておりません。勘違い等があればゴメンナサイ

sususun
質問者

お礼

{{16{a[0]}},a[15:0]} なるほど、このように書けばいいわけですね!! {}が足りていませんでしたか。 あと「a[15]ではないですか?」ですが 知りませんでした(^^)ありがとうございます 以下については半分理解できますが、書けるかどうか心配です がんばってみます!! 環境はverilog1995だと思います。 そこまで気を使っていただいてありがとうございました m(_ _)m

関連するQ&A

専門家に質問してみよう