Search code examples
verilogfpgahdl

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


Solution

  • 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.