如何在VERILOG中删除不需要的输出?

时间:2018-11-12 16:53:58

标签: verilog hardware-acceleration register-transfer-level

我正在研究非常大的模块,其中的乘法器和加法器模块只是一小部分,但这将有助于我在这里表达我的问题。

RTL代码:

module mul_and_add #(parameter BITS = 32,
parameter SHIFT = 15
)

(
  clk,
  i_multiplicand,
  i_multiplier,
  i_adder,
  o_result
);

input clk;
input signed  [BITS-1:0]    i_multiplicand;
input signed  [BITS-1:0]    i_multiplier;
input signed  [BITS-1:0]    i_adder;
output signed [BITS-1:0]    o_result;

reg signed    [2*BITS-1:0]  mul_result;
reg signed    [BITS:0]      add_result;
wire signed   [BITS-1:0]    o_result;

always @(posedge clk)

begin

mul_result <= i_multiplicand * i_multiplier;
add_result <=  i_adder + (mul_result >> SHIFT);

end

assign o_result = add_result[BITS-1:0];

endmodule

TB代码:

module tb_mul_and_add (
                        );

parameter BITS = 32;

reg  clk;
reg  signed [ BITS - 1 : 0 ] i_multiplicand;
reg  signed [ BITS - 1 : 0 ] i_multiplier;
reg  signed [ BITS - 1 : 0 ] i_adder;

wire signed [ BITS - 1 : 0 ] o_result;

mul_and_add mul_and_add_i (
    .clk(clk),
    .i_multiplicand(i_multiplicand),
    .i_multiplier(i_multiplier),
    .i_adder(i_adder),
    .o_result(o_result)
                  );

parameter CLKPERIODE = 10;

initial clk = 1'b1;
always #(CLKPERIODE/2) clk = !clk;

initial begin
  i_multiplicand =  32'h00010000;
  i_multiplier =    32'h00010000;
  i_adder =     32'h00010000;
  #30
  i_multiplicand = 32'h00008000;
  i_multiplier = 32'h00010000;
  i_adder = 32'h00020000;
  #70
  $finish();
end

endmodule

输出:Cadence SimVision

Output from Cadence SimVision

用红色矩形标记的数据是我要删除的不需要的数据,因为当我多次使用此模块时,在正确的数据之前有很多不需要的数据。因此,当我必须整理数据以绘制图形时,要经历很多工作。

那么,有什么魔术可以消除不需要的数据呢?

此外,如果您有更好的优化想法或任何批评,请随时与我们分享。

谢谢。

1 个答案:

答案 0 :(得分:1)

更改RTL代码以使mul_result成为导线,而不是为计算延迟一个周期:

wire signed   [2*BITS-1:0]  mul_result = i_multiplicand * i_multiplier;
always @(posedge clk) begin
    add_result <= i_adder + (mul_result >> SHIFT);
end

更改TB代码以使输入更改与时钟沿对齐,并使用非阻塞分配来避免竞争情况:

initial begin
  i_multiplicand =  32'h00010000;
  i_multiplier =    32'h00010000;
  i_adder =     32'h00010000;
  repeat (3) @(posedge clk);
  i_multiplicand <= 32'h00008000;
  i_multiplier <= 32'h00010000;
  i_adder <= 32'h00020000;
  #70
  $finish();
end

作为编码样式说明,您可以通过使用ANSI模块端口来减少混乱:

module mul_and_add #(
    parameter BITS  = 32,
    parameter SHIFT = 15
)
(
   input clk,
   input signed  [BITS-1:0] i_multiplicand,
   input signed  [BITS-1:0] i_multiplier,
   input signed  [BITS-1:0] i_adder,
   output signed [BITS-1:0] o_result
);

reg signed    [BITS:0]      add_result;
wire signed   [2*BITS-1:0]  mul_result = i_multiplicand * i_multiplier;
always @(posedge clk) begin
    add_result <= i_adder + (mul_result >> SHIFT);
end

assign o_result = add_result[BITS-1:0];

endmodule