Verilog: creating many registers of varying length

2019-08-26 00:29发布

问题:

In a module I would like to make many registers of varying length, and send information between those registers each clock cycle. Specifically, I am trying to create a module which adds all the elements in a list efficiently by adding their elements pairwise into a new list, then continuing until there is one element.

Something like the following, where the input represents 4 lists of length 16 of 8 bit integers (this code passes synthesis and implementation, although I have not tested it so I'm not completely sure it does what I want):

module math_op #(
    parameter listlength=16,
    parameter numlists=4,
    parameter bits=8
    )(
    input clk,
    input [bits*listlength*numlists-1:0] addthese,
    output reg [bits*numlists-1:0] add
    );

    integer k;
    integer j;
    reg [bits*listlength/2-1:0] sum1[numlists-1:0];
    reg [bits*listlength/4-1:0] sum2[numlists-1:0];
    reg [bits*listlength/8-1:0] sum3[numlists-1:0];



    always @(posedge clk) begin
        for(k=0; k<numlists; k=k+1)
            for(j=0; j<listlength/2; j=j+1) begin
                sum1[k][bits*j +: bits]=addthese[2*bits*j+k*bits*listlength +: bits]+addthese[bits*2*j+bits+k*listlength +: bits];
            end
        for(k=0; k<numlists; k=k+1)
            for(j=0; j<listlength/4; j=j+1) begin
                sum2[k][bits*j +: bits]=sum1[k][2*bits*j +: bits]+sum1[k][2*bits*j+bits +: bits];
            end
        for(k=0; k<numlists; k=k+1)
            for(j=0; j<listlength/8; j=j+1) begin
                sum3[k][bits*j +: bits]=sum2[k][2*bits*j +: bits]+sum2[k][2*bits*j+bits +: bits];
            end
        for(k=0; k<numlists; k=k+1) begin
            add[k*bits +: bits]=sum3[k][0 +: bits]+sum3[k][bits +: bits];
        end
    end
endmodule

I would like to be able to quickly change the code to add different length lists. For example, I would like to be able to change 'listlength' to 32, and have the code compile to create an extra register (i.e. add another pairwise add step so the output remains the same length). If I change 'listlength' to 8192, the corresponding number of registers should be created to pairwise add down to the correct length output.

Based on a small amount of research, it seems what I'm looking for is the generate/genvar command in verilog. However, all the examples of generate that I have found simply create instances of modules, not registers, and I'm not even sure if its possible to have a variable created in one loop of the generate command reference another.

Basically, I don't really understand how to use the generate command, nor am I completely sure that is the command I'm looking for. Suggestions?

标签: verilog fpga