Search code examples
verilogfeedbackmux

Feedback on Mux fail to run in Verilog


I am doing the calculation where the output is one of the next input. However the mux output just providing X and causes all the rest calculation to go wrong. How to overcome this issue? Is it due to the clock?

Here is my code:

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

Here is the test bench:

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

Solution

  • The output going X should not cause the rest of the calculation to go wrong, I would say it is the other way around. Having an X inside the module makes the output go X.

    Having a look at your equations you have:

    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
    

    Note that y1, e1, u1 and wk at time zero will be x, as you have not specified reset or initial conditions. I am not sure why you are triggering the flip-flop on both edges of the clock, but it is common to have an active low reset triggered on the negedge.

    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
    

    Once this is taken care of I no longer see x's output from you module.

    On EDA Playground