在Verilog中将整数分配给reg

在Verilog中将整数分配给reg,verilog,Verilog,我对这个Verilog代码有问题。基本上,它不允许我执行Y=3'di语句。基本上,我希望Y等于I。我敢肯定问题出在I。那么,有没有办法在Verilog中实现这一点?另外,W是一个8位的输入(换句话说,W[7:0]) 谢谢 您可以使用括号选择位 for (i = 7; i >= 0; i = i - 1) begin if(W[i]) Y = i[2:0]; end 但是如果i被声明为整数,则它甚至没有必要。它需要多少位自动放入Y,而您只需要LSB。您可能希望在此处使用case语句

我对这个Verilog代码有问题。基本上,它不允许我执行
Y=3'di
语句。基本上,我希望
Y
等于
I
。我敢肯定问题出在
I
。那么,有没有办法在Verilog中实现这一点?另外,
W
是一个8位的输入(换句话说,
W[7:0]


谢谢

您可以使用括号选择位

for (i = 7; i >= 0; i = i - 1)
begin
    if(W[i]) Y = i[2:0];
end

但是如果
i
被声明为整数,则它甚至没有必要。它需要多少位自动放入
Y
,而您只需要LSB。

您可能希望在此处使用
case
语句:

case (1'b1)
  W[0]: Y=3'd0;
  W[1]: Y=3'd1;
  W[2]: Y=3'd2;
  W[3]: Y=3'd3;
  W[4]: Y=3'd4;
  W[5]: Y=3'd5;
  W[6]: Y=3'd6;
  W[7]: Y=3'd7;
  default: Y=3'd0; // to avoid inferring a latch when W==8'd0
endcase

这使代码的读者更清楚地看到优先级。

我发现使用状态机执行“for循环”例程更好。 大概是这样的:

module yourthing(clk, W, i, Y)
input clk;
input [7:0] W;
output [2:0] Y;
reg [2:0] i;  

always@(posedge clk) begin  
  if(reset) begin  
   i = 3'd7;
   Y = 3'd0;
  end

  else begin
    case(i)
      3'd7 : begin
               if(W[i]) Y = i;
               i = 3'd6;
             end
      3'd6 : begin
               if(W[i]) Y = i;
               i = 3'd5;
             end
      3'd5 : begin
               if(W[i]) Y = i;
               i = 3'd4;
             end
      3'd4 : begin
               if(W[i]) Y = i;
               i = 3'd3;
             end
      3'd3 : begin
               if(W[i]) Y = i;
               i = 3'd2;
             end
      3'd2 : begin
               if(W[i]) Y = i;
               i = 3'd1;
             end
      3'd1 : begin
               if(W[i]) Y = i;
               i = 3'd0;
             end
      3'd0 : begin
               if(W[i]) Y = i;
               i = 3'd7;
             end
    endcase
  end
endmodule

希望这有助于…

什么是
W
Y
的定义?输入[7:0]W,输出注册表[2:0]Y这只是混淆和不可扩展。我无法通过代码审查。我很想看看您认为更好的方法。正如我所说的,我使用的
case
方法使优先级对读者来说是显而易见的,IMO比上面的
for
循环方法清楚得多,每个循环方法都可能对Y进行多个赋值,每个后续赋值都会覆盖以前的赋值。在随意阅读代码时,这很容易被忽略,特别是对于经验较少的工程师。在退出条件为
i>=0的循环中意外使用无符号变量是这种方法的另一个常见缺陷;可伸缩性设计只适用于可能需要伸缩的事物,并且在绝对必要时只会损害清晰性,这里的情况并非如此。我发现令人困惑的是在case语句中有一个常量,变量作为每个case的标签。那只会让我的脑子乱跳,我得想想你做了什么。我宁愿使用
如果(W[0])Y=3'd0行,这将是最后的最高优先级。这种顺序往往是很多RTL的规则,所以我在这方面没有问题。不过比这更好的是Jeff给出的循环版本。它的阅读量少,简单,可以参数化,所以我只需要写一次。是的,它只有3位宽,但你已经是11行对4行了。再加上一位,你就有19位了。不管你个人是否觉得
case(1'b1)
令人困惑,这是一个常见的Verilog习惯用法。例如,分别参见斯图尔特·萨瑟兰(Stuart Sutherland)和克里夫·卡明斯(Cliff Cummings)的第4.3节和第7节,他们都曾在IEEE的Verilog工作组工作多年,但情况并非如此。这将需要多个时钟周期。
module yourthing(clk, W, i, Y)
input clk;
input [7:0] W;
output [2:0] Y;
reg [2:0] i;  

always@(posedge clk) begin  
  if(reset) begin  
   i = 3'd7;
   Y = 3'd0;
  end

  else begin
    case(i)
      3'd7 : begin
               if(W[i]) Y = i;
               i = 3'd6;
             end
      3'd6 : begin
               if(W[i]) Y = i;
               i = 3'd5;
             end
      3'd5 : begin
               if(W[i]) Y = i;
               i = 3'd4;
             end
      3'd4 : begin
               if(W[i]) Y = i;
               i = 3'd3;
             end
      3'd3 : begin
               if(W[i]) Y = i;
               i = 3'd2;
             end
      3'd2 : begin
               if(W[i]) Y = i;
               i = 3'd1;
             end
      3'd1 : begin
               if(W[i]) Y = i;
               i = 3'd0;
             end
      3'd0 : begin
               if(W[i]) Y = i;
               i = 3'd7;
             end
    endcase
  end
endmodule