Defining a rightrotate function with non-fixed rotation length
I need a rightrotate function in Verilog for 32-Bit inputs, since it is not defined as an operator (x >>> y).
It is easy rightrotate such input by hand:
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]};
The output of a testbench is as expected:
original: 00000000000000000011000000111001
rotate_1: 10000000000000000001100000011100
rotate_3: 00100000000000000000011000000111
We see, that a function rotate(inp,x) should work like this:
function rotate;
input [31:0] inp;
input [4:0] x;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
Problem is: x is no constant, so it doesn't compile. To specify a range with [a:b], both a 开发者_运维百科and b have to be constants.
A solution seems to be using parameters:
function rotate;
parameter integer x = 1;
input [31:0] inp;
begin
rotate = {inp[x-1:0],inp[31:x]};
end
endfunction
Well, it does compile, but unlike modules, which you can instantiate with a changed parameter like this
param_module #(3) pm_inst(...);
,that does not work with functions. In fact, from reading the grammar of Verilog, I cannot see a way at all to specify the parameter:
<function_call>
::= <name_of_function> ( <expression> <,<expression>>* )
My experiments with defparam only worked with modules, not functions.
Since parametrized macros do not exist in Verilog either, how should i implement the rotate function without declaring one for each possible rotation? - and i need lots of them :-(
(Not like this:)
function rotate1...
function rotate2...
function rotate3...
...
You can simulate a rotate by concatenating two copies of the data and shifting:
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
Aloha!
The simple solution is to use a MUX with fixed rotation in 0-31 steps of the input and then use x as the value to switch on.
For an efficient implementation take a look at the barrel shifter. Using five 2-1 32-bit MUXes in chain shifting the input either 16, 8, 4, 2, 1 steps (for mux 0, 1, 2, 3, 4) or not based on the control bit for each mux.
精彩评论