Verilog,通用加法器树

nij*_*kim 3 verilog

所以,我正在尝试用verilog编写一个加法器树.它的一般部分是它具有可配置数量的要添加的元素和可配置的字大小.但是,我遇到了问题之后的问题,我开始质疑这是解决问题的正确方法.(我将在一个更大的项目中使用它.)绝对有可能只是对加法器树进行硬编码,尽管这会占用很多文本.

所以,我虽然会向你询问堆栈溢出物你对它的看法.这是"做到这一点的方式"吗?我也对不同方法的建议持开放态度.

我还可以提一下,我对verilog很新.

如果有人感兴趣,这是我当前的非工作代码:(我不希望你解决问题;我只是为了方便而展示它.)

module adderTree(
    input clk,
    input [`WORDSIZE * `BANKSIZE - 1 : 0] terms_flat,
    output [`WORDSIZE - 1 : 0] sum
);

genvar i, j;

reg [`WORDSIZE - 1 : 0] pipeline [2 * `BANKSIZE - 1 : 0];   // Pipeline array
reg clkPl = 0;                                              // Pipeline clock

assign sum = pipeline[0];

// Pack flat terms
generate
    for (i = `BANKSIZE; i < 2 * `BANKSIZE; i = i + 1) begin
        always @ (posedge clk) begin
            pipeline[i] <= terms_flat[i * `WORDSIZE +: `WORDSIZE];
            clkPl = 1;
        end
    end
endgenerate

// Add terms logarithmically
generate
    for (i = 0; i < $clog2(`BANKSIZE); i = i + 1) begin
        for (j = 0; j < 2 ** i; j = j + 1) begin
            always @ (posedge clkPl) begin
                pipeline[i * (2 ** i) + j] <= pipeline[i * 2 * (2 ** i) + 2 * j] + pipeline[i * 2 * (2 ** i) + 2 * j + 1];
            end
        end
    end
endgenerate

endmodule
Run Code Online (Sandbox Code Playgroud)

Pet*_*vaz 6

以下是您可能会发现有用的一些注释:

时钟

在您的设计中尽可能少地使用时钟通常是好的(最好只有一个).

在这种特殊情况下,您似乎正在尝试生成新的时钟clkPl,但这不起作用,因为它永远不会返回0.("reg clkPl = 0;"会在时间0将其重置为0,然后设置在"clkPl = 1;"中永久为1.)

您只需更换即可解决此问题

always @ (posedge clkPl)
Run Code Online (Sandbox Code Playgroud)

always @ (posedge clk)
Run Code Online (Sandbox Code Playgroud)

ASSIGNMENTS

仅在组合块中使用阻塞分配以及在时钟块中使用非阻塞是一种好的形式.您正在"打包平面条款"部分中混合阻止和非阻止分配.

由于您不需要clkPl,您只需删除具有阻塞分配的行("clkPl = 1;")

树结构

你的双循环:

for (i = 0; i < $clog2(`BANKSIZE); i = i + 1) begin
    for (j = 0; j < 2 ** i; j = j + 1) begin
        always @ (posedge clkPl) begin
            pipeline[i * (2 ** i) + j] <= pipeline[i * 2 * (2 ** i) + 2 * j] + pipeline[i * 2 * (2 ** i) + 2 * j + 1];
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

看起来它会访问不正确的元素.

例如,对于BANKSIZE = 2 8,**我将计数到7,此时"管道[i*(2**i)+ j]"="管道[7*2**7 + j]"="管道[896 + j]将超出数组的范围.(数组中有2*BANKSIZE = 512个元素.)

我想你真的想要这个结构:

assign sum = pipeline[1];
for (i = 1; i < `BANKSIZE; i = i + 1) begin
    always @ (posedge clk) begin
        pipeline[i] <= pipeline[i*2] + pipeline[i*2 + 1];
        end
    end
Run Code Online (Sandbox Code Playgroud)

较低的延迟

请注意,大多数verilog工具都非常擅长合成多个元素的添加,因此您可能需要考虑在层次结构的每个级别组合更多的术语.

(添加更多的术语成本低于某人可能期望的成本,因为工具可以使用优化,例如进位保存加法器以减少门延迟.)