我怎样才能让我的 verilog 移位器更通用? [英] How can i make my verilog shifter more general?

查看:36
本文介绍了我怎样才能让我的 verilog 移位器更通用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里我有一个移位器,但现在它最多只能用于 3 位.我一直在寻找,但我不知道如何使它最多支持 8 位.

Here i have a shifter but as of rite now it only works for up to 3 bits. I've been looking and i can't find out how to make it work for up to 8 bits.

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

推荐答案

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

What you have is a Barrel Shifter. Two ways to make it more generic are make it a functional model (still synthesis-able) or structural model with a generate block. Both approaches follow IEEE Std 1364-2001 (aka Verilog-2001).

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

The functional generic approach for a barrel shifter only needs a down-shifter. The general function is out = {in,in} >> (WIDTH-shift) where leftover bits can be ignored. To protect for double-roll (i.e. shift > WIDTH ), use the mod operator on the shift (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

桶形移位器的结构通用方法需要一个生成块.generate 块中的 for 循环将在编译时解开,而不是像 always 块中的 for 循环那样运行时.为了保持通用性,2 对 1 多路复用器具有参数化宽度.仅供参考,您也可以将 generate 块与功能代码一起使用,例如注释掉 mux_2to1 实例并取消注释它下面的赋值语句.通过阅读了解有关 generate 块的更多信息IEEE Std 1800-2012 §27. 生成构造.

The structural generic approach for a barrel shifter needs a generate block. The for loop in the generate block will unravel at compile time, not run time like a for loop like in an always block. To keep it generic also have have the 2-to-1 mux have a parametrized width. FYI, you can use the generate block with functional code too, for example comment out the mux_2to1 instantiation and uncomment the assign statement below it. Learn more about the generate block by reading IEEE Std 1800-2012 § 27. Generate constructs.

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 多路复用器,而纯函数方法将取决于优化器的质量.

Both examples are functionally equivalent and synthesize provided CTRL is less than or equal to the ceiling of log2(WIDTH). Synthesis will likely give different results. The generate method will exclusively use 2-to-1 muxes while the pure functional method will depend on the quality of the optimizer.

工作示例@http://www.edaplayground.com/s/6/500

这篇关于我怎样才能让我的 verilog 移位器更通用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆