开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜