我正在尝试创建一个简单的可合成模块,该模块将输出的位随机映射到输入的位而不重复。例如,对于8位输入/输出这样的事情:
module Scrambler(in, out);
parameter WIDTH = 8;
input wire [WIDTH-1:0] in;
output wire [WIDTH-1:0] out;
assign out[0] = in[6];
assign out[1] = in[5];
assign out[2] = in[3];
assign out[3] = in[7];
assign out[4] = in[1];
assign out[5] = in[4];
assign out[6] = in[0];
assign out[7] = in[2];
endmodule
我想用一个生成块替换一系列的assign语句,这样可以完全参数化输入/输出的宽度。我只是想不出只在合成时创建一系列循环随机值的方法。合成后,映射永远不需要改变。
感谢您的帮助!
答案 0 :(得分:0)
您需要的是Random Permutation。
您可以尝试实现它的方式如下:
wire [7:0] inp;
reg [7:0] outp;
...
always @*
begin : random_permutator
integer i;
integer permutation [0:7];
// here is some algorithm that generates your permutation into the array permutation[]
...
for(i=0;i<8;i=i+1)
outp[permutation[i]] = inp[i];
end
如果您的算法是静态的,即每次运行都会生成相同的结果(您可能需要在此处实现自己的伪随机生成器,而不是依赖$random
),一个好的合成工具将正确实现它。
答案 1 :(得分:0)
使用错误的工具,例如尝试用螺丝刀的screwdriver子钉子。使用锤子,例如Perl的以下几行(或您自己选择的锤子):
use List::Util qw(shuffle);
my $n = shift() - 1;
my @arr = shuffle(0 .. $n);
print "assign out[$_] = in[$arr[$_]];\n" for 0 .. $n;
我们都使用自动生成的Verilog代码。没什么两样只需将输出复制并粘贴到您的Verilog文件中即可。