Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error(xxxxxxxxxxxxxxxxxxxxxxx) in Division output using the following testbench #24

Closed
ANWESH009 opened this issue Jan 5, 2021 · 7 comments

Comments

@ANWESH009
Copy link

testbench:-
`timescale 1ns / 1ps

module Divider_tb;

reg clk, rst;
reg [31:0] input_a;
reg input_a_stb;
reg [31:0] input_b;
reg input_b_stb;
reg output_z_ack;
//reg s_input_a_ack,s_input_b_ack;

wire input_a_ack;
wire input_b_ack;
wire [31:0] output_z;
wire output_z_stb;

Flaoting_32_Divider uut(

    .input_a(input_a),
    .input_b(input_b),
    .input_a_stb(input_a_stb),
    .input_b_stb(input_b_stb),
    //.s_input_a_ack(s_input_a_ack),
    //.s_input_b_ack(s_input_b_ack),
    .output_z_ack(output_z_ack),
    .clk(clk),
    .rst(rst),
   
    .output_z(output_z),
    .output_z_stb(output_z_stb),
    .input_a_ack(input_a_ack),
    .input_b_ack(input_b_ack)
    );

 always #5 clk=~clk;

 initial begin
 
         clk= 1'b0;
       
        end

initial
begin

rst=1'b1;
input_a_stb=1'b1;
input_b_stb=1'b1;
output_z_ack=1'b0;
//s_input_a_ack=1'b1;
//s_input_b_ack=1'b1;

#1 rst=1'b0;
#2 input_a=32'b01000010101101101011000000000000;

#1 input_b=32'b00111110000101000000000000000000;
//#2 s_input_a_ack=1'b1;
//#5 s_input_b_ack=1'b0;
end

initial
begin
$monitor("time=",$time,"input_a =%b,input_b=%b,output_z=%b",input_a,input_b,output_z);
end

endmodule

output:-
time= 0
input_a=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
input_b=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
time= 3
input_a =01000010101101101011000000000000,
input_b=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
time= 4
input_a=01000010101101101011000000000000,
input_b=00111110000101000000000000000000,
output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Screenshot

@dawsonjon
Copy link
Owner

Hi,

Thanks for your comment. Please could you check that the divider is properly bound? At first glance, I would say that the component instance should be divider uut(...); rather than Flaoting_32_Divider uut(...); (unless you have changed the name). This might explain why you are getting Xs.

If that doesn't help, perhaps as a next step you could add the state signal from the divider to your waveform? This will help to see how far through the process the divider has got.

Thanks
Jon

@ANWESH009
Copy link
Author

I had already changed the name of the instance part. but this is not the problem.
The problem or the doubt which I have is in the s_input_a_ack part which is showing xxxxxxxxxxxxxx. This is causing the output z to be xxxxxxxxxxxxxxxxxxxx.
I also tried with various other examples still it is not responding. Kindly help me out.......

@dawsonjon
Copy link
Owner

Ok, I tried running your testbench and I can see the problem now. These components use a synchronous reset, so there needs to be at least one rising edge of the clock while the reset is high. I changed #1 rst=1'b0; to #20 rst=1'b0; and it all started working.
Hope this helps
Jon

@ANWESH009
Copy link
Author

I have changed that time accrding to u and ran the following divider code and the module but still it gave the same err.

divider code

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 20.12.2020 01:16:37
// Design Name:
// Module Name: Flaoting_32_Divider
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

module divider(
input_a,
input_b,
input_a_stb,
input_b_stb,
output_z_ack,
clk,
rst,
output_z,
output_z_stb,
input_a_ack,
input_b_ack);

input clk;
input rst;

input [31:0] input_a;
input input_a_stb;
output input_a_ack;

input [31:0] input_b;
input input_b_stb;
output input_b_ack;

output [31:0] output_z;
output output_z_stb;
input output_z_ack;

reg s_output_z_stb;
reg [31:0] s_output_z;
reg s_input_a_ack;
reg s_input_b_ack;

reg [3:0] state;
parameter get_a = 4'd0,
get_b = 4'd1,
unpack = 4'd2,
special_cases = 4'd3,
normalise_a = 4'd4,
normalise_b = 4'd5,
divide_0 = 4'd6,
divide_1 = 4'd7,
divide_2 = 4'd8,
divide_3 = 4'd9,
normalise_1 = 4'd10,
normalise_2 = 4'd11,
round = 4'd12,
pack = 4'd13,
put_z = 4'd14;

reg [31:0] a, b, z;
reg [23:0] a_m, b_m, z_m;
reg [9:0] a_e, b_e, z_e;
reg a_s, b_s, z_s;
reg guard, round_bit, sticky;
reg [50:0] quotient, divisor, dividend, remainder;
reg [5:0] count;

always @(posedge clk)
begin

case(state)

  get_a:
  begin
    s_input_a_ack <= 1;
    if (s_input_a_ack && input_a_stb) begin
      a <= input_a;
      s_input_a_ack <= 0;
      state <= get_b;
    end
  end

  get_b:
  begin
    s_input_b_ack <= 1;
    if (s_input_b_ack && input_b_stb) begin
      b <= input_b;
      s_input_b_ack <= 0;
      state <= unpack;
    end
  end

  unpack:
  begin
    a_m <= a[22 : 0];
    b_m <= b[22 : 0];
    a_e <= a[30 : 23] - 127;
    b_e <= b[30 : 23] - 127;
    a_s <= a[31];
    b_s <= b[31];
    state <= special_cases;
  end

  special_cases:
  begin
    //if a is NaN or b is NaN return NaN 
    if ((a_e == 128 && a_m != 0) || (b_e == 128 && b_m != 0)) begin
      z[31] <= 1;
      z[30:23] <= 255;
      z[22] <= 1;
      z[21:0] <= 0;
      state <= put_z;
      //if a is inf and b is inf return NaN 
    end else if ((a_e == 128) && (b_e == 128)) begin
      z[31] <= 1;
      z[30:23] <= 255;
      z[22] <= 1;
      z[21:0] <= 0;
      state <= put_z;
    //if a is inf return inf
    end else if (a_e == 128) begin
      z[31] <= a_s ^ b_s;
      z[30:23] <= 255;
      z[22:0] <= 0;
      state <= put_z;
       //if b is zero return NaN
      if ($signed(b_e == -127) && (b_m == 0)) begin
        z[31] <= 1;
        z[30:23] <= 255;
        z[22] <= 1;
        z[21:0] <= 0;
        state <= put_z;
      end
    //if b is inf return zero
    end else if (b_e == 128) begin
      z[31] <= a_s ^ b_s;
      z[30:23] <= 0;
      z[22:0] <= 0;
      state <= put_z;
    //if a is zero return zero
    end else if (($signed(a_e) == -127) && (a_m == 0)) begin
      z[31] <= a_s ^ b_s;
      z[30:23] <= 0;
      z[22:0] <= 0;
      state <= put_z;
       //if b is zero return NaN
      if (($signed(b_e) == -127) && (b_m == 0)) begin
        z[31] <= 1;
        z[30:23] <= 255;
        z[22] <= 1;
        z[21:0] <= 0;
        state <= put_z;
      end
    //if b is zero return inf
    end else if (($signed(b_e) == -127) && (b_m == 0)) begin
      z[31] <= a_s ^ b_s;
      z[30:23] <= 255;
      z[22:0] <= 0;
      state <= put_z;
    end else begin
      //Denormalised Number
      if ($signed(a_e) == -127) begin
        a_e <= -126;
      end else begin
        a_m[23] <= 1;
      end
      //Denormalised Number
      if ($signed(b_e) == -127) begin
        b_e <= -126;
      end else begin
        b_m[23] <= 1;
      end
      state <= normalise_a;
    end
  end

  normalise_a:
  begin
    if (a_m[23]) begin
      state <= normalise_b;
    end else begin
      a_m <= a_m << 1;
      a_e <= a_e - 1;
    end
  end

  normalise_b:
  begin
    if (b_m[23]) begin
      state <= divide_0;
    end else begin
      b_m <= b_m << 1;
      b_e <= b_e - 1;
    end
  end

  divide_0:
  begin
    z_s <= a_s ^ b_s;
    z_e <= a_e - b_e;
    quotient <= 0;
    remainder <= 0;
    count <= 0;
    dividend <= a_m << 27;
    divisor <= b_m;
    state <= divide_1;
  end

  divide_1:
  begin
    quotient <= quotient << 1;
    remainder <= remainder << 1;
    remainder[0] <= dividend[50];
    dividend <= dividend << 1;
    state <= divide_2;
  end

  divide_2:
  begin
    if (remainder >= divisor) begin
      quotient[0] <= 1;
      remainder <= remainder - divisor;
    end
    if (count == 49) begin
      state <= divide_3;
    end else begin
      count <= count + 1;
      state <= divide_1;
    end
  end

  divide_3:
  begin
    z_m <= quotient[26:3];
    guard <= quotient[2];
    round_bit <= quotient[1];
    sticky <= quotient[0] | (remainder != 0);
    state <= normalise_1;
  end

  normalise_1:
  begin
    if (z_m[23] == 0 && $signed(z_e) > -126) begin
      z_e <= z_e - 1;
      z_m <= z_m << 1;
      z_m[0] <= guard;
      guard <= round_bit;
      round_bit <= 0;
    end else begin
      state <= normalise_2;
    end
  end

  normalise_2:
  begin
    if ($signed(z_e) < -126) begin
      z_e <= z_e + 1;
      z_m <= z_m >> 1;
      guard <= z_m[0];
      round_bit <= guard;
      sticky <= sticky | round_bit;
    end else begin
      state <= round;
    end
  end

  round:
  begin
    if (guard && (round_bit | sticky | z_m[0])) begin
      z_m <= z_m + 1;
      if (z_m == 24'hffffff) begin
        z_e <=z_e + 1;
      end
    end
    state <= pack;
  end

  pack:
  begin
    z[22 : 0] <= z_m[22:0];
    z[30 : 23] <= z_e[7:0] + 127;
    z[31] <= z_s;
    if ($signed(z_e) == -126 && z_m[23] == 0) begin
      z[30 : 23] <= 0;
    end
    //if overflow occurs, return inf
    if ($signed(z_e) > 127) begin
      z[22 : 0] <= 0;
      z[30 : 23] <= 255;
      z[31] <= z_s;
    end
    state <= put_z;
  end

  put_z:
  begin
    s_output_z_stb <= 1;
    s_output_z <= z;
    if (s_output_z_stb && output_z_ack) begin
      s_output_z_stb <= 0;
      state <= get_a;
    end
  end

endcase

if (rst == 1) begin
  state <= get_a;
  s_input_a_ack <= 0;
  s_input_b_ack <= 0;
  s_output_z_stb <= 0;
end

end
assign input_a_ack = s_input_a_ack;
assign input_b_ack = s_input_b_ack;
assign output_z_stb = s_output_z_stb;
assign output_z = s_output_z;

endmodule

testbench
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 20.12.2020 01:20:00
// Design Name:
// Module Name: Divider_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////

module Divider_tb;

reg clk, rst;
reg [31:0] input_a;
reg input_a_stb;
reg [31:0] input_b;
reg input_b_stb;
reg output_z_ack;
//reg s_input_a_ack,s_input_b_ack;

wire input_a_ack;
wire input_b_ack;
wire [31:0] output_z;
wire output_z_stb;

divider uut(

.input_a(input_a),
.input_b(input_b),
.input_a_stb(input_a_stb),
.input_b_stb(input_b_stb),
//.s_input_a_ack(s_input_a_ack),
//.s_input_b_ack(s_input_b_ack),
.output_z_ack(output_z_ack),
.clk(clk),
.rst(rst),

.output_z(output_z),
.output_z_stb(output_z_stb),
.input_a_ack(input_a_ack),
.input_b_ack(input_b_ack)
);

always #5 clk=~clk;

initial begin

     clk= 1'b0;
   
    end

initial
begin

rst=1'b1;
input_a_stb=1'b1;
input_b_stb=1'b1;
output_z_ack=1'b0;
//s_input_a_ack=1'b1;
//s_input_b_ack=1'b1;

#20 rst=1'b0;
#2 input_a=32'b01000010101101101011000000000000;

#1 input_b=32'b00111110000101000000000000000000;
//#2 s_input_a_ack=1'b1;
//#5 s_input_b_ack=1'b0;
end
initial
begin
$monitor("time=",$time,"input_a =%b,input_b=%b,output_z=%b",input_a,input_b,output_z);
end

endmodule

@dawsonjon
Copy link
Owner

Hi,

I pasted your code into my sim (icarus verilog), and is seems to be working OK for me.

I got this output ...

time=                   0input_a =xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,input_b=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
time=                  22input_a =01000010101101101011000000000000,input_b=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
time=                  23input_a =01000010101101101011000000000000,input_b=00111110000101000000000000000000,output_z=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
time=                1165input_a =01000010101101101011000000000000,input_b=00111110000101000000000000000000,output_z=01000100000111100000000000000000

And here's a screenshot of the waveform...

screenshot

Please could you double check:

  • That the changed code compiled correctly
  • That the reset signal is high for the first couple of clock cycles
  • Has the sim run long enough to produce a result?

It might be worth monitoring state in the sim to check on progress.

Thanks
Jon

@ANWESH009
Copy link
Author

Actually i was trying it in xilinx vivado. But later i tried it in iverilog i found it working. Thank you for your help.Extremely obliged.

@dawsonjon
Copy link
Owner

Happy to help
Thanks
Jon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants