定义旋转长度不固定的 rightrotate 函数
我需要 Verilog 中的 rightrotate 函数用于 32 位输入,因为它没有定义为运算符 (x >>> y)。
手动右旋转这样的输入很容易:
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的语法,我看不到一种方法 all 来指定参数:
<function_call>
::= <name_of_function> ( <expression> <,<expression>>* )
我对 defparam 的实验仅适用于模块,不是功能。
由于 Verilog 中也不存在参数化宏,我应该如何实现旋转函数而不为每个可能的旋转声明一个? - 而且我需要很多这样的宏:-
(((不是 像这样:)
function rotate1...
function rotate2...
function rotate3...
...
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...
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以通过连接数据的两个副本并移位来模拟旋转:
You can simulate a rotate by concatenating two copies of the data and shifting:
阿罗哈!
简单的解决方案是使用输入的固定轮换为 0-31 步长的 MUX,然后使用 x 作为打开的值。
为了高效实施,请查看桶形移位器。使用五个 2-1 32 位 MUX,根据每个多路复用器的控制位,将输入链式移位 16、8、4、2、1 步(对于多路复用器 0、1、2、3、4)或不进行移位。
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.