0

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
Jack93
  • 21
  • 1
  • 4
  • 13
  • 1
    If you explain more about the algorithm and about what exactly you want from the output, it would be easier to answer. – Amir Mar 12 '15 at 11:22
  • @Amir, at first the w1 is 0 then it go with the formula as shown above then get new w1. The new w1 is use in the next calculation. – Jack93 Mar 12 '15 at 12:26

1 Answers1

2

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

Morgan
  • 19,934
  • 8
  • 58
  • 84
  • your solution have solve the issue of input X condition but the output of mux (W) fail to run. Any idea to solve that? – Jack93 Mar 12 '15 at 09:13
  • On each clock rising edge 4 operations are executed. But when `rst_n` is high, because the parameters (`y1`, `e1`, `u1`, `wk`) are updated consecutively, 4 cycles is needed to `w` be ready. So after changing the inputs wait for 4 cycles to see the final result (`w`). I confirm this answer (@Morgan). – Amir Mar 12 '15 at 13:37
  • @Amir, so mean that I cannot achieve getting 4 (y1, e1 , u1, wk) at 1 cycle right? I need wait 4 cycle to get the correct wk and then can implement it on the next y1 at the 5th cycle. – Jack93 Mar 12 '15 at 14:14
  • `y1` after 1 cycle, `e1` after 2 cycles, `u1` after 3 cycles and `wk` after 4 cycles have the expected value. You can draw the schematic of your design to better understand. – Amir Mar 12 '15 at 15:28
  • @Jack93 I agree with Amir because (y1, e1, u1, wk) are flip-flops forming a chain it takes 4 clock cycles for an input to reach the output. You may want to start a new question about the equation your trying to perform, showing what you have tried and why it is wrong (4 cycle latency). – Morgan Mar 12 '15 at 16:48
  • @Morgan, by adding the delay on the cases, it works well. Thanks for the help. By the way, your code in the EDA playground there is a line call as $dumpfile("dump.vcd"); $dumpvars;. If I wish to dump the answer in the e1, how should i able to change it. – Jack93 Mar 13 '15 at 03:32
  • @Jack93 `$dumpvars` will record all signals, to record only part of the hierarchy you can use `$dumpvars(depth, hierarchy)` eg `$dumpvars(1, all2_tb.U1);` – Morgan Mar 13 '15 at 08:08