Search code examples
verilogxilinx-ise

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


I am trying to take the average of 8 8-bit registers. I was able to do it structurally, by having four 8-> 9-bit adders, two 9-> 10 bit adder, and one 10-> 11-bit adder. This works correctly; however, I was curious if there is a better way/ more efficient way to do this.

For the structural way, all I have to do is have the assign a wire from the 10->11 bit adder to the output.

I'm trying to do something like below, but it says

Index <10> is out of range [7:0] for signal . I have it index 10, in case all the registers are large like 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];


Solution

  • One way is to create a sum wire:

    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];