【问题标题】:Verilog 'for'-loop returned valuesVerilog 'for' 循环返回值
【发布时间】:2012-11-11 15:54:27
【问题描述】:

我已经写了下面的代码。

我的问题:

在索引 1

它以一些值进入 for 循环。它出现在“if”语句中,正如您所见,每个“if”的最后一条指令类似于“P=....”。

在索引 2(下一步)

它进入'if'语句,但P的值不是来自步骤1,它是初始值。

如何在下一步使用“P”的最后一个值? (索引+1)

module multiplier(prod, a, b, wireP, wireA, wireS);
  output [15:0] prod;
  output [16:0] wireA;
  output [16:0] wireS;
  output [16:0] wireP;
  reg    [15:0] prod;

  input  [7:0] a;
  input  [7:0] b;
  reg   [16:0] P;
  reg   [16:0] S;
  reg   [16:0] A;

  wire [16:0] tempshift;
  reg  [16:0] tempoutshift;

  arithmeticShift shiftP(tempshift,P);

  wire [16:0] tempPS;
  reg  [16:0] tempoutPS;

  carryForPbooth  sumPS(coutPS,tempPS,P,S,0);


  wire [16:0]tempPA;
  reg [16:0]tempoutPA;
  carryForPbooth  sumPA(coutPA,tempPA,P,A,0);

  reg [16:0] regP;
  reg [16:0] regA;
  reg [16:0] regS;
  integer    index;

  always @(*) begin

    A[16:9] = a[7:0];
    A[8:0]  = 9'b000000000;
    S[16:9] = ~a[7:0]+1'b1;
    S[8:0]  = 9'b000000000;
    P[16:9] = 8'b00000000;
    P[8:1]  = b[7:0];
    P[0]    = 1'b0;

    #1 tempoutPS    = tempPS;
    #1 tempoutPA    = tempPA;
    #1 tempoutshift = tempshift;

    for(index = 1; index < 9; index = index + 1) begin
      if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
        #1 tempoutshift = tempshift;
        #1 P            = tempoutshift;
      end
      if(P[1:0] == 2'b01) begin
        #1 tempoutPA    = tempPA;
        #1 P            = tempoutPA;
        #1 tempoutshift = tempshift;
        #1 P            = tempoutshift;
      end
      if(P[1:0] == 2'b10) begin
        #1 tempoutPS    = tempPS;
        #1 P            = tempoutPS;
        #1 tempoutshift = tempshift;
        #1 P            = tempoutshift;
      end
    end

    #1 prod=P[16:1];
  end

  assign wireP = P;
  assign wireS = S;
  assign wireA = A;
endmodule

【问题讨论】:

  • 您有input [7:0] a;reg [16:0] A; 仅按大小写区分变量通常是个坏主意。有些模拟器不区分大小写。
  • 这是一个测试台组件还是 RTL? #1 将无法合成。
  • 这是否意味着在 9 个时钟周期内进行移位和相加乘法?

标签: simulation verilog xilinx


【解决方案1】:

您似乎正在尝试创建一个可综合的移位和相加乘法器架构,其中乘法值是在 9 个时钟周期内计算的。

查看代码并删除一些临时变量,我将其缩减为:

module multiplier(
  input      [7:0]  a,
  input      [7:0]  b,

  output     [15:0] prod,
  output reg [16:0] A,
  output reg [16:0] S,
  output reg [16:0] P
);

  wire [16:0] tempshift;
  arithmeticShift shiftP(tempshift,P);

  wire [16:0] tempPS;
  carryForPbooth  sumPS(coutPS,tempPS,P,S,0);


  wire [16:0] tempPA;
  carryForPbooth sumPA(coutPA,tempPA,P,A,0);

  reg [3:0] index;

  always @(*) begin
    A = {  a, 9'b000000000};
    S = { -a, 9'b000000000} ;// -x => ~x+1
    P = {8'b00000000, b, 1'b0}; 

    for(index = 1; index < 9; index = index + 1) begin
      if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
        #1 P            = tempshift;
      end
      if(P[1:0] == 2'b01) begin
        #1 P            = tempPA;
        #1 P            = tempshift;
      end
      if(P[1:0] == 2'b10) begin
        #1 P            = tempPS;
        #1 P            = tempshift;
      end
    end
  end

  assign prod = P[16:1];
endmodule

我认为你是在使用#1 伪造时钟周期,这只会在模拟器中工作,要么不能合成,要么只有最后一个分配才会生效。

如果这意味着要拆分为 9 个时钟周期,则它需要一个与移位值相关联的计数器,而不是 for 循环。在 Verilog 中,for 循环在编译时展开,并且应该在零时间内执行,除非用作测试台的一部分。

类似于以下的代码段出现了多次。

#1 P            = tempPA;
#1 P            = tempshift;

我认为您正在尝试将值应用于模块,然后使用相同的变量捕获其输出,这很难知道,因为我没有您已实例化的块的接口。如果你想合成你的代码,你不能在 Verilog 中这样做。您应该使用另一个中间变量来连接。

请记住,always @* begin ... end 是组合逻辑,除了计算答案所涉及的涟漪外,没有时间。为了暗示 D-Type 触发器,我们使用:

always @(posedge clk or negedge rst_n) begin
  if (~rst_n) begin
    // Reset conditions
  end
  else begin
    // Next clock conditions
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-25
    • 2016-09-03
    • 2016-08-23
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多