+ Post New Thread
Results 1 to 3 of 3
  1. #1
    Member level 1
    Points: 835, Level: 6

    Join Date
    Jun 2009
    Posts
    35
    Helped
    5 / 5
    Points
    835
    Level
    6

    verilog float

    I have a Sine Cosine ROM module which I generated from Matlab using a half-precision function available from the Matlab site. It consists of a 10 bit address space and a 16-bit data bus.



    I am getting extremely large (and incorrect) numbers from the simulation.


    I have pasted an example simulation output.

    # 0.00 radians --> sin = 131072.0000 cos = 1.0000
    # 0.01 radians --> sin = 131072.0000 cos = 1.0000
    # 0.01 radians --> sin = 16777216.0000 cos = 1.0000
    # 0.01 radians --> sin = 16777216.0000 cos = 1.0000

    ...

    # 6.27 radians --> sin = 4261412864.0000 cos = 1.0000
    # 6.27 radians --> sin = 4278190080.0000 cos = 1.0000
    # 6.28 radians --> sin = 4278190080.0000 cos = 1.0000
    # 6.28 radians --> sin = 4294836224.0000 cos = 1.0000

    The testbench contains the main problem inside the monitor statement.

    $monitor ("%1.2f radians --> sin = %1.4f cos = %1.4f", (address * 2 * pi / 1023),
    ((-1)**(sine[15])) * (1'b1 + (sine[9:0] >> 10)) * (2 ** (sine[14:10] - 5'd15)),
    ((-1)**(cosine[15])) * (1'b1 + (cosine[9:0] >> 10)) * (2 ** (cosine[14:10] - 5'd15)) );

    My questions are as follows:

    Is my monitor statement set up correctly to convert from 16-bit floating point to real (x.xxxx format).

    What is the max number of decimal digits that half precision (16 bit floating point) would produce to the right of the decimal point? Since I am dealing with sin and cosine from 0 to 2pi (with a radius of 1) I only need 1 digit to the left.





    I have uploaded my module and test-bench to the following address.

    http://vahejabagchourian.comyr.com/Verilog/

    The individual files are stored at:

    http://vahejabagchourian.comyr.com/Verilog/sync_rom.v
    http://vahejabagchourian.comyr.com/V.../sync_rom_tb.v

    Any help is greatly appreciated.

    Thank You,
    Vahe

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 251,591, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    43,812
    Helped
    13322 / 13322
    Points
    251,591
    Level
    100

    float verilog

    Which result do you expect for sine[9:0] >> 10? It's identical to zero for all values of sine, I think.
    Also sine[14:10] - 5'd15 don't give negative results due to default Verilog data types.


    1 members found this post helpful.

    •   AltAdvertisment

        
       

  3. #3
    Member level 1
    Points: 835, Level: 6

    Join Date
    Jun 2009
    Posts
    35
    Helped
    5 / 5
    Points
    835
    Level
    6

    float in verilog

    Thank you for the help.

    I was able to solve the problem.

    My testbench pasted attached below. The monitor statement and added integer declarations are the important changes I made.


    Thank you once again. I hope this will help some one else facing a similar issue.

    Vahe


    # 0.00 radians --> sin = 0.0000 cos = 1.0000
    # 0.01 radians --> sin = 0.0000 cos = 1.0000
    # 0.01 radians --> sin = 0.0061 cos = 1.0000
    # 0.01 radians --> sin = 0.0061 cos = 1.0000
    # 0.01 radians --> sin = 0.0123 cos = 1.0000
    # 0.02 radians --> sin = 0.0123 cos = 1.0000
    # 0.02 radians --> sin = 0.0184 cos = 1.0000
    # 0.02 radians --> sin = 0.0184 cos = 1.0000
    # 0.02 radians --> sin = 0.0246 cos = 0.9995
    # 0.03 radians --> sin = 0.0246 cos = 0.9995
    # 0.03 radians --> sin = 0.0307 cos = 0.9995
    # 0.04 radians --> sin = 0.0307 cos = 0.9995
    # 0.04 radians --> sin = 0.0368 cos = 0.9995
    # 0.04 radians --> sin = 0.0368 cos = 0.9995
    # 0.04 radians --> sin = 0.0430 cos = 0.9990
    # 0.05 radians --> sin = 0.0430 cos = 0.9990
    # 0.05 radians --> sin = 0.0491 cos = 0.9990

    ...



    # 6.24 radians --> sin = -0.0430 cos = 0.9990
    # 6.24 radians --> sin = -0.0368 cos = 0.9995
    # 6.25 radians --> sin = -0.0368 cos = 0.9995
    # 6.25 radians --> sin = -0.0307 cos = 0.9995
    # 6.26 radians --> sin = -0.0307 cos = 0.9995
    # 6.26 radians --> sin = -0.0246 cos = 0.9995
    # 6.26 radians --> sin = -0.0246 cos = 0.9995
    # 6.26 radians --> sin = -0.0184 cos = 1.0000
    # 6.27 radians --> sin = -0.0184 cos = 1.0000
    # 6.27 radians --> sin = -0.0123 cos = 1.0000
    # 6.27 radians --> sin = -0.0123 cos = 1.0000
    # 6.27 radians --> sin = -0.0061 cos = 1.0000
    # 6.28 radians --> sin = -0.0061 cos = 1.0000
    # 6.28 radians --> sin = -0.0000 cos = 1.0000




    `timescale 1ns / 1ps

    module sync_rom_tb_v;

    // Inputs
    reg clock;
    reg [9:0] address;

    // Outputs
    wire [15:0] sine;
    wire [15:0] cosine;

    real pi = 3.14;


    // Instantiate the Unit Under Test (UUT)
    sync_rom uut (
    .clock(clock),
    .address(address),
    .sine(sine),
    .cosine(cosine)
    );


    integer cosine_significand;
    integer sine_significand;

    integer sine_sign;
    integer cosine_sign;

    integer sine_exponent;
    integer cosine_exponent;

    always @ (sine, cosine)
    begin

    sine_significand = sine[9:0];
    cosine_significand = cosine[9:0];

    sine_sign = sine[15];
    cosine_sign = cosine[15];

    sine_exponent = sine[14:10];
    cosine_exponent = cosine[14:10];

    $monitor ("%1.2f radians --> sin = %1.4f cos = %1.4f", (address * 2 * pi / 1023),
    ((-1)**(sine_sign)) * (1 + ($itor(sine_significand) / 1024)) * ( (sine_exponent < 15) ? (1.0000 / 2 ** (-1*(sine_exponent - 15))) : ( 2 ** (sine_exponent - 15)) ),
    ((-1)**(cosine_sign)) * (1 + ($itor(cosine_significand) / 1024)) * ( (cosine_exponent < 15) ? (1.0000 / 2 ** (-1*(cosine_exponent - 15))) : ( 2 ** (cosine_exponent - 15)) ) );

    end


    initial
    begin
    // Initialize Inputs
    clock = 0;
    address = 0;
    end

    always
    begin
    #50 clock = ~clock;
    end

    integer i;

    always
    begin

    for (i = 0; i < 1024; i=i+1)
    begin
    #100 address = i;
    end


    // Wait 100 ns for global reset to finish
    #100 $finish;

    // Add stimulus here

    end

    endmodule



--[[ ]]--