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不同
虽然您没有提供有关模拟结果的确切内容以及它们与您想要的结果有何不同的所有详细信息,但我可以看到您的代码中存在一个重大错误,可能会导致您出现意外行为体验。您在单个时钟 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
我正在尝试设计一个管道和一个具有资源共享的模块,以比较 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不同
虽然您没有提供有关模拟结果的确切内容以及它们与您想要的结果有何不同的所有详细信息,但我可以看到您的代码中存在一个重大错误,可能会导致您出现意外行为体验。您在单个时钟 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