在 Verilog 中对 Mux 的反馈失败 运行
Feedback on Mux fail to run in Verilog
我正在进行计算,其中输出是下一个输入之一。然而,多路复用器输出仅提供 X 并导致所有其余计算出错。如何克服这个问题?是时钟原因吗?
这是我的代码:
module all2(input sel,clk,
input signed [15:0]x,d,
output signed [15:0]w,e,y);
localparam u = 16'd2;
wire [15:0]w1;
reg [15:0]y1,e1,u1,wk;
assign w = wk;
assign e = e1;
assign y = y1;
assign w1 = (sel)?wk:16'd0;
always @(posedge clk or negedge clk)
y1 <= x * w1;
always @(posedge clk or negedge clk)
e1 <= d - y1;
always @(posedge clk or negedge clk)
u1 <= e1 * x * u;
always @(posedge clk or negedge clk)
wk <= u1 + w1;
endmodule
这里是测试台:
module all2_tb();
reg sel, clk;
reg signed [15:0] x, d;
wire signed [15:0] w, e, y;
all2 U1(.sel(sel),.clk(clk),.x(x),.d(d),.w(w),.e(e),.y(y));
initial begin
clk = 1'b0;
forever
#1 clk = ~clk;
end
initial begin
sel <= 1'b0;
x <= 16'd0;
d <= 16'd0;
#2;
sel <= 1'b1;
x <= 16'd1;
d <= 16'd2;
#1;
x <= 16'd3;
d <= 16'd4;
#1;
x <= 16'd5;
d <= 16'd6;
#1;
$stop;
end
endmodule
X 的输出不应该导致其余的计算出错,我会说它是相反的。在模块中有一个 X 会使输出变为 X。
看看你的方程你有:
w = wk;
e = e1;
y = y1;
w1 = (sel)?wk:16'd0;
always @(posedge clk or negedge clk) begin
y1 <= x * w1;
e1 <= d - y1;
u1 <= e1 * x * u;
wk <= u1 + w1;
end
请注意,y1
、e1
、u1
和 wk
在零时间将是 x
,因为您没有指定重置或初始条件.我不确定你为什么要在时钟的两个边沿触发触发器,但在负边沿触发低电平有效复位是很常见的。
always @(posedge clk or negedge rst_n) begin //<- negedge rst_n
if (~rst_n) begin
y1 <= 'd0;
e1 <= 'd0;
u1 <= 'd0;
wk <= 'd0;
end
else begin
y1 <= x * w1;
e1 <= d - y1;
u1 <= e1 * x * u;
wk <= u1 + w1;
end
end
一旦解决了这个问题,我就再也看不到你模块的 x 输出了。
我正在进行计算,其中输出是下一个输入之一。然而,多路复用器输出仅提供 X 并导致所有其余计算出错。如何克服这个问题?是时钟原因吗?
这是我的代码:
module all2(input sel,clk,
input signed [15:0]x,d,
output signed [15:0]w,e,y);
localparam u = 16'd2;
wire [15:0]w1;
reg [15:0]y1,e1,u1,wk;
assign w = wk;
assign e = e1;
assign y = y1;
assign w1 = (sel)?wk:16'd0;
always @(posedge clk or negedge clk)
y1 <= x * w1;
always @(posedge clk or negedge clk)
e1 <= d - y1;
always @(posedge clk or negedge clk)
u1 <= e1 * x * u;
always @(posedge clk or negedge clk)
wk <= u1 + w1;
endmodule
这里是测试台:
module all2_tb();
reg sel, clk;
reg signed [15:0] x, d;
wire signed [15:0] w, e, y;
all2 U1(.sel(sel),.clk(clk),.x(x),.d(d),.w(w),.e(e),.y(y));
initial begin
clk = 1'b0;
forever
#1 clk = ~clk;
end
initial begin
sel <= 1'b0;
x <= 16'd0;
d <= 16'd0;
#2;
sel <= 1'b1;
x <= 16'd1;
d <= 16'd2;
#1;
x <= 16'd3;
d <= 16'd4;
#1;
x <= 16'd5;
d <= 16'd6;
#1;
$stop;
end
endmodule
X 的输出不应该导致其余的计算出错,我会说它是相反的。在模块中有一个 X 会使输出变为 X。
看看你的方程你有:
w = wk;
e = e1;
y = y1;
w1 = (sel)?wk:16'd0;
always @(posedge clk or negedge clk) begin
y1 <= x * w1;
e1 <= d - y1;
u1 <= e1 * x * u;
wk <= u1 + w1;
end
请注意,y1
、e1
、u1
和 wk
在零时间将是 x
,因为您没有指定重置或初始条件.我不确定你为什么要在时钟的两个边沿触发触发器,但在负边沿触发低电平有效复位是很常见的。
always @(posedge clk or negedge rst_n) begin //<- negedge rst_n
if (~rst_n) begin
y1 <= 'd0;
e1 <= 'd0;
u1 <= 'd0;
wk <= 'd0;
end
else begin
y1 <= x * w1;
e1 <= d - y1;
u1 <= e1 * x * u;
wk <= u1 + w1;
end
end
一旦解决了这个问题,我就再也看不到你模块的 x 输出了。