如何让我的verilog移位器更通用?

时间:2013-12-03 17:08:53

标签: verilog

这里我有一个移位器但是现在它只适用于最多3位。我一直在寻找,我无法找到如何让它工作高达8位。

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

2 个答案:

答案 0 :(得分:4)

你拥有的是Barrel Shifter。使其更通用的两种方法是使其成为功能模型(仍然是可合成的)或具有生成块的结构模型。两种方法都遵循IEEE Std 1364-2001(又名Verilog-2001)。

桶形移位器的功能通用方法只需要一个向下移位器。一般函数是out = {in,in} >> (WIDTH-shift),其中可以忽略剩余的位。要保护双掷(即shift> gt WIDTH),请在班次(WIDTH-(shift%WIDTH))上使用mod运算符。

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循环将在编译时解开,而不像在always块中那样像for循环一样运行。为了保持通用性,2-to-mux具有参数化宽度。 仅供参考,你也可以使用带有功能代码的generate块,例如注释掉mux_2to1实例化并取消注释它下面的assign语句。通过阅读{{3>了解有关生成块的更多信息。 }§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)的上限。合成可能会给出不同的结果。 generate方法将专门使用2对1多路复用器,而纯函数方法将取决于优化器的质量。

工作示例@ IEEE Std 1800-2012

答案 1 :(得分:0)

我使用了&gt;&gt;和&lt;&lt;运算符使用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.