2011-06-11 71 views
3

我需要以Verilog一個rightrotate功能對於32位輸入,因爲它沒有被定義爲操作員(X >>> Y)。定義rightrotate功能與非固定旋轉長度

它是由手容易rightrotate例如輸入:

wire [31:0] test = 32'd12345; 
wire [31:0] rotated_1 = {test[0:0],test[31:1]}; 
wire [31:0] rotated_3 = {test[2:0],test[31:3]}; 

如預期測試平臺的輸出:

original: 00000000000000000011000000111001 
rotate_1: 10000000000000000001100000011100 
rotate_3: 00100000000000000000011000000111 

我們看到,一個函數旋轉(INP,X)應該工作像這樣:

function rotate; 
    input [31:0] inp; 
    input [4:0] x; 
    begin 
     rotate = {inp[x-1:0],inp[31:x]}; 
    end 
endfunction 

問題是:x不恆定,所以它不編譯。要用[a:b]指定範圍,a和b必須是常數。

一個解決方案似乎可以用參數:

function rotate; 
    parameter integer x = 1; 
    input [31:0] inp; 
    begin 
     rotate = {inp[x-1:0],inp[31:x]}; 
    end 
endfunction 

那麼,它編譯,但不同的模塊,你可以用一個變化的參數是這樣

param_module #(3) pm_inst(...); 

實例,即做不適用於功能。事實上,從閱讀的Verilog grammar,我看不到的方式在所有指定參數:

<function_call> 
::= <name_of_function> (<expression> <,<expression>>*) 

我與defparam實驗只能用模塊,功能不工作。

由於參數化宏在Verilog中不存在,我應該如何實現旋轉函數而不用爲每個可能的旋轉聲明一個? - 我需要很多人:-(

像這樣通過連接數據的兩個副本和轉移:)

function rotate1... 
function rotate2... 
function rotate3... 
... 

回答

5

用戶可以模擬一個旋轉:

function [31:0] rotate (input [31:0] data, input [4:0] shift); 
reg [63:0] tmp; 
begin 
    tmp = {data, data} >> shift; 
    rotate = tmp[31:0]; 
end 
endfunction 
+0

與手動旋轉相比,這種解決方案效率不高,因爲數據翻倍了嗎? – namor 2011-06-11 20:13:47

+0

你是如何使用這個功能的?如果你用'shift'參數的一個常量來調用它,那麼任何體面的綜合工具都會傳播常量並簡化實現以進行一點排列。如果「shift」參數佔用了32個可能值的有限子集,那麼直接將它們混合起來可能會更好。如果'shift'可以是32個值中的任何一個,那麼這將比一個天真的32×32多路複用器更好。結果取決於你的綜合工具的性能。一個好的工具將把這個函數的不受限制的使用映射到一個圓形的32位桶式移位器,這正是你想要的。 – Andy 2011-06-11 20:57:58

+0

謝謝了,這解決了我的問題!我是Verilog/FPGA編程的新手,不知道這些技巧是否得到了優化。 – namor 2011-06-11 23:30:32

0

Aloha!

簡單的解決方案是在輸入的0-31步中使用固定旋轉的MUX,然後使用x作爲val你打開。

爲了高效實施,請查看桶式移位器。根據每個多路複用器的控制位,使用5個2-1 32位多路複用器對輸入進行16,8,4,2,1步(針對多路複用器0,1,2,3,4)進行鏈移位。