我想设计一个可变移位寄存器向右移位,如下所示:
module sr(N,int,out);
input [2:0] N;
input [7:0] in;
output [7:0] out;
assign out={N'b0,input[7,N]}
endmodule
但是,不幸的是verilog不允许这种写作。N 应该是常数。关于如何从输入中获得移位迭代的任何想法?
我想设计一个可变移位寄存器向右移位,如下所示:
module sr(N,int,out);
input [2:0] N;
input [7:0] in;
output [7:0] out;
assign out={N'b0,input[7,N]}
endmodule
但是,不幸的是verilog不允许这种写作。N 应该是常数。关于如何从输入中获得移位迭代的任何想法?
Verilog 有一个右移运算符,因此您可以简单地编写:
assign out = in >> N;
额外的位会自动用零填充。
如果 和 的大小in
真的out
固定在 8 位,这里是一种简单的方法:
module sr(N, in, out);
input [2:0] N;
input [7:0] in;
output [7:0] out;
assign out = (N == 7) ? {7'b0, in[7:7]} :
(N == 6) ? {6'b0, in[7:6]} :
(N == 5) ? {5'b0, in[7:5]} :
(N == 4) ? {4'b0, in[7:4]} :
(N == 3) ? {3'b0, in[7:3]} :
(N == 2) ? {2'b0, in[7:2]} :
(N == 1) ? {1'b0, in[7:1]} :
in[7:0];
endmodule
这也可以使用always
块内的 case 语句进行编码,如下所示:
reg [7:0] out_reg;
assign out = out_reg;
always @(N or in) begin
case (N)
7 : out_reg <= {7'b0, in[7:7]};
6 : out_reg <= {6'b0, in[7:6]};
5 : out_reg <= {5'b0, in[7:5]};
4 : out_reg <= {4'b0, in[7:4]};
3 : out_reg <= {3'b0, in[7:3]};
2 : out_reg <= {2'b0, in[7:2]};
1 : out_reg <= {1'b0, in[7:1]};
0 : out_reg <= in[7:0];
endcase
end
如果您不想写出所有值,则可以使用for
循环。我不是合成工具如何处理这个问题的专家,但是这个(或类似的东西)应该可以合成。
always @(N or in) begin
for (i = 0; i < 8; i = i + 1) begin
if (i+N < 8) begin
out_reg[i] <= in[i+N];
end else begin
out_reg[i] <= 1'b0;
end
end
end
使用循环对其进行编码的一个优点是它不太容易出现剪切粘贴拼写错误。
更重要的是,如果您想让模块支持输入和输出的通用位宽,您可以使用parameter
模块上的 a 和用于分配的类似循环来实现。