always块和组合模块中求和结果的区别

difference between the result of the sum in the always block and combinational module

我正在尝试设计一个管道和一个具有资源共享的模块,以比较 synthesize.the 管道中的已用资源量工作正常,但我在资源共享方面遇到问题。在下面的代码中,在状态 s3、s4、s5、s6 中,As、Bs、Cs、Ds、Es 寄存器将相加,结果将在寄存器 fx 中。在相同的状态下,组合加法器模块的结果将存储在寄存器测试中。但价值观不同,我不明白为什么。 我想做的是求解一个微分方程。我通过加法和移位操作避免常量乘法,并使用 cordic 作为 de 的指数部分。 抱歉英语不好,提前谢谢你;

module topmodule (clk,v1,v2,one,zero,clk_data);
input clk;
output one,zero,clk_data;
output  reg signed [41:0] v1;
output  reg signed [41:0] v2;
parameter [41:0]  el    = - 42'b000000000000100011010011001000000000000000;  
parameter [41:0]  vt    = - 42'b000000000000011001001100110000000000000000;  
parameter [41:0]  I0    =   42'b000000000110010000000000000000000000000000; 
parameter [41:0]  b     =   42'b000000000000101000000000000000000000000000; 
parameter [41:0]  xin   = - 42'b000000000000011111000000000000000000000000; 
parameter [41:0]  yin   =   42'b000000000000000000000000000000000000000000; 
parameter [41:0]  zeroa =   42'b000000000000000000000000000000000000000000;
parameter [41:0]  onea  =   42'b000000000000000000100000000000000000000000; 
parameter [41:0]  xr    = - 42'b000000000000010111010110011000000000000000; 
reg signed [10:0]  roundint   =   7'b0000000;
reg signed [10:0]  iek   =   7'b0000001;
reg signed [41:0] x;
reg signed [41:0] y;
reg signed [41:0] fx;
reg signed [41:0] shifted2;
reg signed [41:0] xminusel;
reg signed [41:0] xminusvt;
reg signed [41:0] xminusvtdelta;
reg signed [41:0] dx;
reg signed [41:0] dy;
reg signed [41:0] dxdt;
reg signed [41:0] dydt;
reg signed [41:0] z;
reg signed [41:0] intx;
reg signed [41:0] absx;
reg signed [41:0] As;
reg signed [41:0] Bs;
reg signed [41:0] Cs;
reg signed [41:0] Ds;
reg signed [41:0] Es;
reg signed [41:0] Fsx;
reg signed [41:0] test;
wire signed [41:0] Asw;
wire signed [41:0] Bsw;
wire signed [41:0] Csw;
wire signed [41:0] Dsw;
wire signed [41:0] Esw;
wire signed [41:0] fxw;
   wire [3:0] p_s;
   reg [3:0] n_s=4'b0000;  
   parameter s0 =4'b0000; 
   parameter s1 =4'b0001;
   parameter s2 =4'b0010;
   parameter s3 =4'b0011;
   parameter s4 =4'b0100;
   parameter s5 =4'b0101;
   parameter s6 =4'b0110;
   parameter s7 =4'b0111;
   parameter s8 =4'b1000;
   parameter s9 =4'b1001;
   parameter s10=4'b1010;
   parameter s11=4'b1011;
   parameter s12=4'b1100;
   parameter s13loop=4'b1101;
ADD A1(.fxw(fxw),.As(As),.Bs(Bs),.Cs(Cs),.Ds(Ds),.Es(Es));
  assign p_s=n_s;
  assign zero=1'b0;
  assign one=1'b1;
  assign clk_data=clk;
always @(posedge clk)
begin
  case (p_s)
       s0:
       begin
       x=xin;
       y=yin;
     n_s<=s1;
       end
    s1:
       begin
       shifted2=onea;
       fx=onea;
       iek   =   7'b0000000;
       xminusvt=x-vt;
       xminusvtdelta={xminusvt>>>1} ;
       n_s<=s2;
       if (xminusvtdelta<0)
         begin
           absx=~xminusvtdelta;
           absx=absx+1;
         end
       else
         begin
           absx=xminusvtdelta;
         end
       end
       s2:
       begin
      intx={12'b000000000000,absx[30:18],17'b00000000000000000};
       roundint=absx[30:24];
       if(xminusvtdelta<=0)
       begin
       z=xminusvtdelta+ intx;
       end
     else
       begin
       z=xminusvtdelta- intx;
     end
       shifted2=shifted2>>>1;
       n_s<=s3;
       end
     s3:
       begin
        if ( shifted2 < z )
          begin
        z=z-shifted2;
        As=fx;
        Bs={fx>>>1};
        Cs={fx>>>3};
        Ds={fx>>>6};
        Es={fx>>>7};
        fx=As+Bs+Cs+Ds+Es;
     Fsx=fx;
     test<=fxw; 
    end
      shifted2=shifted2>>>1;      
       n_s<=4;
       end
       s4:
       begin
        if ( shifted2 < z )
          begin  
        z=z-shifted2;

            As=fx;
        Bs={fx>>>2};
        Cs={fx>>>5};
        Ds={fx>>>9};
        Es=0;
        fx=As+Bs+Cs+Ds+Es;  
              Fsx=fx;
              test<=fxw;
    end
       shifted2=shifted2>>>1;      
       n_s<=s5;
       end
       s5:
       begin
        if ( shifted2 < z )
          begin
        z=z-shifted2;
            As=fx;
        Bs={fx>>>3};
        Cs={fx>>>7};
        Ds=0;
        Es=0;
        fx=As+Bs+Cs+Ds+Es;
               Fsx=fx;
               test<=fxw;     
    end
       shifted2=shifted2>>>1;       
       n_s<=s6;
       end
     s6:
       begin
        if ( shifted2 < z )
          begin
        z=z-shifted2;
                As=fx;
        Bs={fx>>>4};
        Cs={fx>>>9};
        Ds=0;
        Es=0;
        fx=As+Bs+Cs+Ds+Es;
        test<=fxw;
                Fsx=fx;
    end
       shifted2=shifted2>>>1;

       n_s<=s8;
       end
       s8:
       begin
          if(iek<=roundint)
          begin
            n_s<=s13loop;        
             end
            else
              begin

                n_s<=s9;
         end  
         xminusel=x-el;

       end       
         s13loop:
         begin
iek=iek+1;
 if(xminusvtdelta>0)
                begin
        fx={ fx >>>10}+{fx>>>9}+{fx>>>8}+{fx>>>7}+{fx>>>6}+{fx>>>4}+{fx>>>3}+{fx>>>1}+{fx<<<1} ;
          end
        else
        begin 
         fx={ fx  >>>7}+{ fx  >>>6}+{ fx  >>>5}+{ fx  >>>4}+{ fx  >>>2} ; 
         end         
 n_s<=s8;        
nd

       s9:
       begin
     dx=-{ xminusel>>>5}-{xminusel>>>4}-{xminusel>>>3}-{xminusel>>>2}+{fx>>>4}+{fx>>>3}+{fx>>>2}+{ fx  >>>1}  +{ I0  >>>6} -{ y  >>>6}  ; 
      dy={xminusel<<<2}-{y}; 
       n_s<=s10;
       end

       s10:
       begin
       dxdt={dx>>>15}+{dx>>>13}+{dx>>>12}+{dx>>>11}+{dx>>>10}+{dx>>>9} ; 
       dydt={dy >>>15}+{dy>>>14};       
       n_s<=s11;
       end
       s11:
       begin
      x=x+dxdt;
      y=y+dydt;
       n_s<=s12;
       end
       s12:
       begin
       if (x>=0)
       begin
       x=xr;
       y=y+b;
       end
       v1=x;
       v2=y;
       n_s<=s1;
       end
 endcase
   end
 endmodule

加法器模块是

module ADD(fxw,As,Bs,Cs,Ds,Es);
    output  [41:0] fxw;
    input [41:0] As;
    input  [41:0] Bs;
    input  [41:0] Cs;
    input  [41:0] Ds;
    input  [41:0] Es;
 assign fxw=As+Bs+Cs+Ds+Es;   
endmodule

但在相同状态s3,s4.s5,s6下的仿真结果中fxw和Fsx的值相同但test不同

simulation result

虽然您没有提供有关模拟结果的确切内容以及它们与您想要的结果有何不同的所有详细信息,但我可以看到您的代码中存在一个重大错误,可能会导致您出现意外行为体验。您在单个时钟 always 块中混合使用非阻塞分配 (<=) 和阻塞分配 (=)。我不太清楚你在做什么,因为你的一些代码没有显示,但如果你想让一些东西组合起来,你不应该把它们放在一个时钟块中。将组合逻辑与寄存器分开,还要确保了解要存储的内容以及组合逻辑要产生的结果(注意,我只是猜测其中的一些,但有些使用阻塞赋值,而它们应该是使用 NBA 的寄存器):

always @(posedge clk) begin
  case (p_s)
    ...
    s3: begin
      if (shifted2 < z) begin
        z <= z - shifted2; 

        // Note that As, Bs... are all dependent on fx which in turn is dependent on As, Bs... so one of these NEEDS to be stored in a register to break the combinational loop
        As <= fx;
        Bs <= fx >>> 1;
        Cs <= fx >>> 3;
        Ds <= fx >>> 6;
        Es <= fx >>> 7;

        // If you want Fsx and test to match, you must have them both update at the same time, before you had Fsx getting its value from the sum of the values of As, Bs... that were just generated while test would get the value from the sum of the previous values of As, Bs...
        Fsx <= fx;
        test <= fxw;
      end
      shifted2 <= shifted2 >>> 1;
      n_s <= s4; // You had 4, but I assume this should be s4
    end
    ...
  endcase
end

// Note, you could use an assign for this, but just to illustrate the point
always @(*) begin
  fx = 0; // Need a value for fx when state ISNT s3 or s4, this is combinational logic after all
  if ((p_s == s3) || (p_s == s4)) begin
    fx = As + Bs + Cs + Ds + Es;
  end
end