2016-01-30 16 views
0

我試圖做浮點加法和減法。我的指南是由Cavanagh編寫的一本書「計算機算術和Verilog HDL基礎知識」。在模塊內部,他使用一個代碼來對齊指數,如下所示。在「while」中使用非常量值,給了我這個錯誤,我該怎麼辦?

always @ (oper_1 or oper_2) 
    begin 


    exp_a = oper_1 [31:24]; 
    exp_b = oper_2 [31:24]; 


    fract_a = oper_1 [23:0]; 
    fract_b = oper_2 [23:0]; 


    // bias exponents 


    exp_a_bias = exp_a + 8'b0111_1111; 
    exp_b_bias = exp_b + 8'b0111_1111; 


// align fractions 


if (exp_a_bias < exp_b_bias) 
ctrl_align = exp_b_bias - exp_a_bias; 

while (ctrl_align) 
begin 
fract_a = fract_a >> 1; 
exp_a_bias = exp_a_bias + 1; 
ctrl_align = ctrl_align - 1; 
end 


    if (exp_b_bias < exp_a_bias) 
    ctrl_align = exp_a_bias - exp_b_bias; 

    while (ctrl_align) // heres comes the troubles 
    begin 
    fract_b = fract_b >> 1; 
    exp_b_bias = exp_b_bias + 1; 
    ctrl_align = ctrl_align - 1; 
    end 

的Quartus II給我以下錯誤:

錯誤(10119):在ADD_SUB_FLO.v Verilog HDL語言Loop語句錯誤(40):環與非恆定循環條件必須在250次迭代

終止

我搜索了,似乎Quartus不能確定「ctrl_align」的大小是多少,所以它不會合成。的Quartus網站說我可以編輯.qsf文件,但我不能在我的文件中找到任何

set_global_assignment -name VERILOG_NON_CONSTANT_LOOP_LIMIT 300

而且,我莫名其妙地感動,這本書教一個錯誤的那一步代碼,不能同步,我也希望解決問題而不是解決方法,我該怎麼辦?我嘗試更改爲'For',但它給出了錯誤: 錯誤(10170):ADD_SUB_FLO.v(44)附近的文本「>」出現Verilog HDL語法錯誤;錯誤消息10170:期待「=」 我認爲或者雖然它並不重要,因爲它似乎問題是系統需要預先知道邊界,但這是爲了計算。

for (i=ctrl_align,i>0,i=i-1) 
     begin 
      fract_a = fract_a >> 1; 
      exp_a_bias = exp_a_bias + 1; 
     end 
+2

該書教授模擬代碼,但不教授合成代碼。您需要重構代碼,以便它不使用while循環,例如一個for循環(因爲它們有一個上限)。 Btw第31位是符號位,它不是有偏指數的一部分。小數部分只有23位。 – Paebbels

回答

1

正如之前的評論所述,這是不可合成的Verilog。你正在逐步思考。您不需要for循環或while循環,基本上,您想要fract_*移位,exp_*_bias增量,並且ctrl_align在初始加載後遞減。

有三種狀態:

  1. 一個裝載狀態,其中ctrl_align = exp_b_bias - exp_a_bias
  2. 一個計數狀態,其中ctrl_align遞減和正確fract_轉移
  3. 一個狀態,其中ctr_align == 0且輸出有效

使用一個簡單的狀態機來跟蹤這一點,然後使用case語句爲每個網絡選擇正確的分配。

例如:

always @(posedge clk) begin 
    // Should include a reset 
    case(state): 
    LOAD:begin 
     ctr_align <= (exp_a_bias < exp_b_bias)? exp_b_bias - exp_a_bias : exp_a_bias - exp_b_bias; 
    end 
    COUNT:begin 
     ctrl_align <= ctrl_align - 8'd1; 
     fract_a <= (exp_a_bias < exp_b_bias)? fract_a >> 1 : fract_a; 
     fract_b <= (exp_b_bias < exp_a_bias)? fract_b >> 1 : fract_b; 
    end 
    DONE: ctrl_align <= ctrl_align 
    default: ctrl_align <= 0; // latches inferred for fract_* 

沒有檢查語法,並有一些推斷的鎖存器,但是這應該給你它的要點。狀態機應該很簡單,只需要幾條語句。

希望有幫助!

相關問題