您如何 select 寄存器表达式中的一系列位?

How do you select a range of bits from an expression of registers?

我正在尝试取 8 个 8 位寄存器的平均值。通过使用四个 8-> 9 位加法器、两个 9-> 10 位加法器和一个 10-> 11 位加法器,我能够在结构上做到这一点。这工作正常;但是,我很好奇是否有更好的方法/更有效的方法来做到这一点。

对于结构方式,我所要做的就是从 10->11 位加法器到输出分配一条线。

我正在尝试执行如下操作,但它显示

索引 <10> 超出信号范围 [7:0]。 我有它的索引 10,以防所有寄存器都像 255 这样大。

module avg( 
    num_in, 
    clk,
    rs,
    ave8
  ) ;
  input clk ;
  input rs;
  input [7:0] num_in ;
  output [7:0] ave8 ;
  reg [7:0] registers [7:0] ;

always @(posedge clk) begin
      
        if(rs) begin
         registers[0] <= 0;
         registers[1] <= 0;
         registers[2] <= 0;
         registers[3] <= 0;
         registers[4] <= 0;
         registers[5] <= 0;
         registers[6] <= 0;
         registers[7] <= 0;
      end 
    
      
     registers[0] <= num_in;
    registers[1] <= registers[0];
    registers[2] <= registers[1];
    registers[3] <= registers[2];
    registers[4] <= registers[3];
    registers[5] <= registers[4];
    registers[6] <= registers[5];
    registers[7] <= registers[6];   


  end

// This assign function is what I am focused on.
    assign ave8 = {registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7]}[10:3];

一种方法是创建 sum 线:

wire [10:0] sum = registers[0] + registers[1] + registers[2] + registers[3] + registers[4] + registers[5] + registers[6] + registers[7];
assign ave8 = sum[10:3];

我建议使用 for 循环:

module avg(
  input [7:0] num_in ,
  input clk ,
  input rs ,
  output reg [7:0] ave
);
  parameter SIZE = 8;
  reg [7:0] registers [SIZE-1:0] ;
  reg [10:0] accumulator;
  integer i;

always @(posedge clk) begin
      if(rs)
        for(i=0;i<SIZE;i=i+1)
          registers[i] <= 0;
      registers[0] <= num_in;
      for(i=1;i<SIZE;i=i+1)
        registers[i] <= registers[i-1];
      accumulator = 0;
      for(i=0;i<SIZE;i=i+1)
        accumulator = accumulator + registers[i];
      ave <= accumulator/SIZE;
  end
endmodule

用 ISE 支持的 SystemVerilog 编写会容易得多:

module avg(
  input [7:0] num_in ,
  input clk ,
  input rs ,
  output logic [7:0] ave
);
  parameter SIZE = 8;
  logic [7:0] registers [SIZE] ;

always @(posedge clk) begin
    if(rs)
      registers = '{default:0};
    registers <= {num_in, registers[1:$size(registers)-1]};
    ave <= registers.sum() with (int'(item))/SIZE;
  end
endmodule