Я упростил некоторые правила для ясности, но вот подробности.
В утверждении
Y = {S[i - 1:0], S[63:i]};
у вас есть объединение двух сигналов, каждый с константойВыбор части.Выбор константной части имеет вид
идентификатор [constant_expression: constant_expression]
, но ваш код использует переменную для первого выражения.Как вы видели, это недопустимо, но вы правы в том, что есть способы избежать ввода большого оператора case.Вместо этого вы можете использовать индексированную часть select.Они имеют вид
идентификатор [выражение +: константа_выражение]
идентификатор [выражение -: константа_экспрессия]
Этиконструкции гарантируют, что ширина результирующего сигнала будет постоянной, независимо от переменной на левой стороне.
wire [HIGH_BIT:LOW_BIT] signalAdd,signaSub;
signalAdd[some_expression +: some_range];
signalSub[some_expression -: some_range];
//Resolves to
signalAdd[some_expression + (some_range - 1) : some_expression];
signalSub[some_expression : some_expression - (some_range - 1)];
//The location of the high value depends on how the signal was declared:
wire [15: 0] a_vect;
wire [0 :15] b_vect;
a_vect[0 +: 8] // a_vect[7 : 0]
b_vect[0 +: 8] // b_vect[0 : 7]
Вместо того, чтобы пытаться построить один сигнал из двух выбранных частей, вы можете просто расширить входной сигналдо 128 бит, и используйте переменную часть, выбираемую из этого.
wire [63:0] data_in,data_out;
wire [127:0] data_in_double;
wire [5:0] select;
//Concatenate the input signal
assign data_in_double = {data_in,data_in};
//The same as signal[select + 63 : select]
assign data_out = data_in_double[select+63-:64];
Другой подход, который вы можете использовать, - генерировать циклы.Это более общий подход к репликации кода на основе переменной.Он гораздо менее эффективен, поскольку генерирует 4096 сигналов.
wire [63:0] data_in,data_out;
wire [127:0] data_in_double;
wire [5:0] select;
wire [63:0] array [0:63];
genver i;
//Concatenate the input signal
assign data_in_double = {data_in,data_in};
for(i=0;i<64;i=i+1)
begin : generate_loop
//Allowed since i is constant when the loop is unrolled
assign array[i] = data_in_double[63+i:i];
/*
Unrolls to
assign array[0] = data_in_double[63:0];
assign array[1] = data_in_double[64:1];
assign array[2] = data_in_double[65:2];
...
assign array[63] = data_in_double[127:64];
*/
end
//Select the shifted value
assign data_out = array[select];