2016-06-21 24 views
0

Verilogを初めて使用しました。私はここで少し助けが必要です。 私は符号付き整数を表すレジスタ配列reg [32-1:0] outを持っています。 小さい配列は、0と1000の間の数値を保持しますreg [14-1:0] d。私は/を使用して合成可能コードの悪い習慣であることを聞いたVerilogの指数関数的減衰

always @(posedge clk_i) begin 
    out <= $signed(out) * $unsigned(d)/1000; 
end 

:私はこの(クロック・サイクルごとに出てダンピング)のような何かをしたいと思います。そのような指数関数的な減衰を実装する方法を誰にでも教えてもらえますか?

編集: 扱いがはるかに簡単であるため、1000で割って1024で割った値に変更しました。私のコードは次のようになりましたになります。

reg [32-1:0] out; 
reg [32-1:0] in; 
reg [42-1:0] tmp; 
reg [14-1:0] d; 
always @(posedge clk_i) begin 
    tmp = {in,10'd0}; 
    if(tmp[41]==1) begin 
     tmp = $signed(tmp) * -1; 
     tmp = $signed(tmp) >> 10; 
     tmp = $signed(tmp) * $unsigned(d); 
     tmp = $signed(tmp) * -1; 
    end 
    else begin 
     tmp = $signed(tmp) >> 10; 
     tmp = $signed(tmp) * $unsigned(d); 
    end 
    out <= tmp[42-1:10]; 
end 

コードは、シミュレーションで正常に機能しますが、FPGA上で、(outがゼロである)のようなゼロを乗じて中にいるようですか?誰がここで間違っているのか分かっていますか?

+0

Dは整数ではなく固定小数点であると考えてください。これで分数情報を保存できるようになりました。新しいdを「old d/1000」として保存してください。問題は単なる乗算で除算ではありません。 – Morgan

+0

[Verilog:固定小数点](http://stackoverflow.com/a/28383767/97073) – Morgan

+0

私のコードを変更しました。あなたはそれを見てみることができますか? – user2224350

答えて

1

符号付き番号は、符号拡張に符号>>>を使用します。理由が分からない場合は、* -1>>>のような問題が解決されます。より良い精度を維持するためにシフトする前に乗算することも考慮してください。

もやって:

tmp = {in,10'd0}; 
tmp = $signed(tmp) >> 10; 

あなたは0の後、ゼロをシフトアウトとLSBを埋めてきたあまり意味がありません。私はtmpような変数を再利用避け、各セクションの名前が付けられ、サイズの変数を使用することになり

tmp = { {10{in[32-1]}}, in}; 

、これは合成された大きさに影響を与えません。これはMSBが10回複製することができた(>>>に相当)を拡張

ログイン。

+0

問題は別の場所でした。しかし、とにかくありがとう、私はあなたのコードがより良い練習であると思います – user2224350

関連する問題