2013-12-03 2 views
3

Здесь у меня есть shifter, но с ритуалом теперь он работает только до 3 бит. Я искал, и я не могу понять, как заставить его работать до 8 бит.Как я могу сделать свой Verilog shifter более общим?

module shifter(a,b,out); 
input [7:0] a, b; 
output [7:0] out; 
wire [7:0] out1, out2, out3; 

mux_8b_2to1 first(a[7:0], {a[3:0],a[7:4]}, b[2], out1); 
mux_8b_2to1 second(out1[7:0], {out1[5:0],out1[7:6]}, b[1], out2); 
mux_8b_2to1 third(out2[7:0], {out2[6:0],out2[7]}, b[0], out); 
endmodule 

ответ

0

Я использовал >> и < < операторов для создания synthetizable дизайна с использованием ISEWebPack, как это:

module shifter(
    input wire [7:0] a, 
    input wire [7:0] b, 
    input wire leftright, // 0=shift right, 1=shift left 
    output reg [7:0] out 
    ); 

    always @* begin 
     if (leftright==0) 
     out = a>>b; 
     else 
     out = a<<b; 
    end 
endmodule 

Таким образом, инструмент symthesis будет знать, что вы хотите реализовать оборотень и может использовать свои собственные макросы лучше всего синтезируют его:

Synthesizing Unit <shifter>. 
    Related source file is "shifter.v". 
    Found 8-bit shifter logical right for signal <out$shift0002> created at line 30. 
    Found 8-bit shifter logical left for signal <out$shift0003> created at line 32. 
4

Что у вас есть это 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

Смежные вопросы