2012-04-10 35 views
3

我在Verilog中設計了一些硬件,但爲了保持靈活性,我使用參數來設置寬度,以便在不修改代碼的情況下根據需要修改寬度。我遇到的一個問題是在一段代碼中,我希望能夠並行寫入多個單元。在Verilog中使用for循環選擇位參數

parameter DATA_WIDTH = 16; 
parameter BUFFER_SIZE = 16; 
parameter LOAD_WIDTH = DATA_WIDTH*BUFFER_SIZE; 

input [LOAD_WIDTH-1:0] i_load_data; 

reg [DATA_WIDTH-1:0] r_data_buf[BUFFER_SIZE-1:0]; 

... 

[email protected](posedge clk) begin 
.... 
    else if (i_load_flag) begin 
     for(i = 0; i < BUFFER_SIZE; i = i + 1) 
      r_data_buf[i] <= i_load_data[i * BUFFER_SIZE + BUFFER_SIZE - 1:i * BUFFER_SIZE]; 
    end 
end 

我需要保留r_data_buf作爲數組,因爲數據必須被讀取。我也不清楚爲什麼verilog不喜歡這個代碼,因爲在編譯時所有東西都是常量,或者我可以如何修復它並仍然得到我想要的行爲。

+0

它可能會幫助,如果你可以說並不喜歡的Verilog(錯誤訊息?合成失敗?模擬失敗?),但僅僅基於猜測,我認爲大多數合成器都會將這樣的陣列實現爲RAM或閂鎖陣列,並且通常不能同時寫入多個位置。 (只有一條addr /數據總線進入內存,所以你不能在同一個週期內塞入兩個寫入數據)。 – Tim 2012-04-10 18:25:48

回答

7

Verilog編譯器不高興,因爲它看到了i和x依賴於參數的i_load_data [x:y],所以它擔心這可能導致寬度變化(儘管在你的情況下是不可能的)。

有幾個簡單的方法來解決這個問題:

  1. 使用+:操作員指定的寬度。 (我也將BUFFER_SIZE更改爲DATA_WIDTH,因爲它看起來像一個錯字。)在這種形式中,您給出了LSB的索引以及您希望選擇的數據的寬度。

    r_data_buf[i] <= i_load_data[i * DATA_WIDTH +: DATA_WIDTH]; 
    
  2. 使用一個額外的for循環設置每一位單獨

    for(i = 0; i < BUFFER_SIZE; i = i + 1) 
    begin 
        for(j = 0; j < DATA_WIDTH; j = j + 1) 
        begin 
         r_data_buf[i][j] <= i_load_data[i * DATA_WIDTH + j]; 
        end 
    end 
    
+1

1完全解決了我的問題。我從來沒有見過這種語法,但它絕對有用。另外,是的,那是一個錯字。 – ras2124 2012-04-10 19:40:16

+1

樂意幫忙:)您也可能對類似運算符感興趣 - :您可以在其中給出MSB的索引和數據的寬度。在這種情況下,它不是很好,因爲你會寫「i_load_data [i * DATA_WIDTH + DATA_WIDTH-1 - :DATA_WIDTH]」 – 2012-04-10 21:19:16