Что у вас есть это Barrel Shifter. Два способа сделать его более общим - сделать его функциональной моделью (все еще синтезирующей) или структурной моделью с генерирующим блоком. Оба подхода следуют IEEE Std 1364-2001 (aka Verilog-2001).
Функциональный общий подход для баррель-переключателя требует только устройства с понижающим переключением. Общая функция - out = {in,in} >> (WIDTH-shift)
, где оставшиеся биты можно игнорировать. Для защиты двойного рулона (т. Е. Сдвига> WIDTH) используйте оператор мод в сдвиге (WIDTH-(shift%WIDTH)
).
module barrel_shifter_functional #(parameter CTRL=3, parameter WIDTH=CTRL**2)
(input wire [WIDTH-1:0] in,
input wire [ CTRL-1:0] shift,
output wire [WIDTH-1:0] out);
assign out = {2{in}} >> (WIDTH-(shift%WIDTH));
endmodule
Структурный общий подход для баррель-переключателя нуждается в генерации блока. Цикл for в геневом блоке будет распутываться во время компиляции, а не на время выполнения, как цикл for, как в всегда блоке. Чтобы сохранить его общий, также имеют муфту 2 к 1, имеющую параметризованную ширину. FYI, вы также можете использовать блок генерации с функциональным кодом, например, закомментируйте экземпляр mux_2to1
и раскомментируйте оператор присваивания под ним. Подробнее о генерации блока, прочитав IEEE Std 1800-2012 § 27. Сгенерируйте конструкции.
module barrel_shifter_structeral #(parameter CTRL=3, parameter WIDTH=CTRL**2)
(input wire [WIDTH-1:0] in,
input wire [ CTRL-1:0] shift,
output wire [WIDTH-1:0] out);
wire [WIDTH-1:0] tmp [CTRL:0];
assign tmp[CTRL] = in;
assign out = tmp[0];
genvar i;
generate
for (i = 0; i < CTRL; i = i + 1) begin : mux
mux_2to1 #(.WIDTH(WIDTH)) g(
.in0(tmp[i+1]),
.in1({tmp[i+1][WIDTH-(2**i)-1:0],tmp[i+1][WIDTH-1:WIDTH-(2**i)]}),
.sel(shift[i]),
.out(tmp[i]));
// assign tmp[i] = shift[i] ? {tmp[i+1][WIDTH-(2**i)-1:0],tmp[i+1][WIDTH-1:WIDTH-(2**i)]} : tmp[i+1];
end : mux
endgenerate
endmodule
module mux_2to1 #(parameter WIDTH=8)
(input wire [WIDTH-1:0] in0, in1,
input wire sel,
output wire [WIDTH-1:0] out);
assign out = sel ? in1 : in0;
endmodule
Оба примера функционально эквивалентны и синтезировать при условии, CTRL
меньше или равна потолка log2 (WIDTH
). Синтез, скорее всего, даст разные результаты. Метод генерации будет использовать только мультиплексоры 2 к 1, в то время как чисто функциональный метод будет зависеть от качества оптимизатора.
Рабочий пример @http://www.edaplayground.com/s/6/500