2016-06-21 139 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 

我heared,使用/是不好的做法綜合代碼。任何人都可以告訴我如何實現這種指數衰減?

編輯: 我改變了除以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:fixed-point](http://stackoverflow.com/a/28383767/97073) – Morgan

+0

我改變了我的代碼。你可以看看嗎? – user2224350

回答

1

簽名的數字應該使用>>>來簽名擴展。不知道爲什麼你需要做* -1也許>>>將解決這個問題。爲了保持更好的精度,還應考慮在換檔前進行倍增

也做的:

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

並沒有什麼太大的意義已填充爲0的最低有效位,則零移出。

註冊延伸(相當於>>>)這可能是MSB重複10次:

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

我將避免重新使用的變量等tmp並命名併爲每個部分尺寸的變量的使用,這不會影響合成的尺寸。

+0

問題在其他地方。但是,無論如何,我想你的代碼是更好的做法 – user2224350