Verilog'for'循环返回值

时间:2012-11-11 15:54:27

标签: simulation verilog xilinx

我写了下面的代码。

我的问题:

索引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

1 个答案:

答案 0 :(得分:0)

看起来您正在尝试创建可合成的Shift和Add乘数架构,其中乘法值计算超过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