user777304
user777304

Reputation: 455

Sum of Values based on bits enabled Verilog

I am new to Verilog, I was trying to write a simple code but I am not sure how to do it in a expert way. I have a 12 bit register "data", each bit of that register have a specific value. e.g.

Bit 0 = 12;
Bit 1 = 16;
Bit 2 = 33;
......
Bit 11 = 180;

Now if any bit of "data" register is 1 then the result should be the sum of all value that coresponds to that bit value. e.g.

data = 12'b100000000101
result = 225 (180+33+12)

Right now i am checking each bit of data, if it is 1 then i register that corresponding value and add it to previous registered value. This method takes number of cycles. How can i do it in a fast way in verilog.

thank you

Upvotes: 0

Views: 1353

Answers (2)

Sourabh
Sourabh

Reputation: 674

you can try something like below :-

    reg [15:0] sum;
    always @(*)begin    
       for (i=0;i<12;i++)begin
         if (data[i]) 
         sum = sum+Bit[i];
       end //for
    end //always
    assign finalSum = |data ? finalSum: 'h0;

Upvotes: 0

wilcroft
wilcroft

Reputation: 1635

It depends on what you mean by "fast". Presumably you mean time, but remember that time=cycles/frequency - reducing the number of cycles will often reduce the maximum frequency your circuit can operate at.

For example, here's a circuit that does the entire add in one cycle:

always@(*) begin
    tempsum = 0;
    tempsum = tempsum + (data[0]? 12:0);
    tempsum = tempsum + (data[1]? 16:0);
    tempsum = tempsum + (data[2]? 33:0);
    //...
end
always@(posedge clock)
    result <= tempsum;

If you synthesized this circuit, you'd see a long chain of adders. In could calculate the result in a single cycle, but would have a long critical path, and therefore have a lower fMax. Whether this would be "faster" is impossible to know until you synthesize it (there are too many factors to guess).

A better multi-cycle approach could be to use a tree, i.e.:

reg [31:0] sum [29:0];
always @ (posedge clock) begin
    // level 0
    sum[0] <= (data[0]? 12:0) + (data[1]? 16:0);
    sum[1] <= (data[2]? 33:0) + (data[3]? 40:0);
  // ...
    sum[15] <=  (data[30]? 160:0) + (data[31]? 180:0);
    // level 1
    sum[16] <= sum [0] + sum [1];
    sum[17] <= sum [2] + sum [3];
  // ...
    sum[23] <= sum [14] + sum [15];
    // level 2
    sum[24] <= sum [16] + sum [17];
    sum[25] <= sum [18] + sum [19];
  // ...
    // level 3
    sum[28] <= sum [24] + sum [25];
    sum[29] <= sum [26] + sum [27];

    result <= sum [28] + sum [29];
end

All that said, ultimately the "fastest" approach will also depend on the other requirements of your system, what you're implementing it on, etc.

Upvotes: 1

Related Questions