Ads

Get STM32 tutorial using HAL at $10 for a limited time!

Thursday, August 11, 2016

Verilog Tutorial 4 - ModelSim - Simplified Floating Point Greater Than Circuit

Real numbers in computer memory can be represented using fixed point or floating point format. For example, 12.2510 in 8-bit fixed point format will be 1100.01002. Actually, in the register, the value is only 1100010010. The radix point (binary point) is an implicit scaling factor which is 2-4. This scaling factor is the same for all values of the same type, and does not change during computation. In floating point format, 12.25 will be represented as 1.225 * 101 (in decimal). Floating point format can be thought of as a kind of scientific notation. The scaling factor in the floating point format is not fixed and can change during computation, so the range in floating point format is much larger than signed integer format. Detailed explanation of fixed point and floating point format is beyond the scope of this tutorial.

In this tutorial, I have implemented a greater than circuit for simplified floating point number. This circuit compares two simplified floating point number and assert output, gt, only when the first number is larger than the second number. Floating point number in this circuit is not conform to the IEEE 754 standard, hence this format is called simplified floating number.


This floating point format has the length of 13-bit and ignore the round-off error. The representation consists of a sign bit, which is indicated the sign of the number (1 for negative), a 4-bit exponent, and 8-bit significant or the fraction. Both exponent and significant are in the unsigned format. The significant has to be normalized or zero. Normalized representation means that the MSB of significant must be 1. Under these assumptions, the largest and smallest magnitudes are 0.11111111 * 21111 and 0.10000000 * 20000. Detailed discussion of this floating point format is explained in this book: FPGA Prototyping by Verilog Examples by Pong P. Chu. In this book, there is also an implementation for simplified floating point adder.

This is some example of numbers in this floating point format:
  • +0.68E0 = +0.10101110 * 20000 = 0 0000 1010 1110
  • +0.68E3 = +0.10101010 * 21010 = 0 1010 1010 1010
  • -0.86E3 = -0.11010111 * 21010 = 1 1010 1101 0111
  • -0.68E4 = -0.11010100 * 21101 = 1 1101 1101 0100
This the code for floating point greater than circuit using behavioral modeling:
module simplified_fp_greater_than
    (
        input wire [12:0] a, b,
        output reg gt
    );

    // Body
    always @*
    begin
        case ({a[12], b[12]})
            2'b01: gt = 1'b1; // a plus, b minus (a > b)
            2'b10: gt = 1'b0; // a minus, b plus (a < b)
            2'b00:   // a plus, b plus  
                begin
                    if (a[11:0] > b[11:0])
                        gt = 1'b1;
                    else
                        gt = 1'b0;
                end
            2'b11:   // a minus, b minus
                begin
                    if (a[11:0] < b[11:0])
                        gt = 1'b1;
                    else
                        gt = 1'b0;
                end
        endcase
    end

endmodule
The input is two 13-bit floating point numbers called a and b. The output is 1-bit signal called gt that will assert if a is greater than b. When a is equal to b, the output gt will not asserted.

This is the code for verify this circuit:
`timescale 1 ns/10 ps

module simplified_fp_greater_than_tb;
    // Signal declaration
    reg [12:0] a_test, b_test;
    wire gt_test;

    // Instantiate the circuit under test
    simplified_fp_greater_than uut
        (.a(a_test), .b(b_test), .gt(gt_test));

    // Test vector generator
    initial
    begin
        // Group 1
        // a = +0.68E3, b = +0.86E3 
        a_test = 13'b0101010101010;
        b_test = 13'b0101011010111;
        # 200;
        // a = -0.68E3, b = +0.86E3
        a_test = 13'b1101010101010;
        b_test = 13'b0101011010111;
        # 200;
        // a = +0.68E3, b = -0.86E3
        a_test = 13'b0101010101010;
        b_test = 13'b1101011010111;
        # 200;
        // a = -0.68E3, b = -0.86E3
        a_test = 13'b1101010101010;
        b_test = 13'b1101011010111;
        # 200;
  
        // Group 2  
        // a = +0.86E3, b = +0.68E3 
        a_test = 13'b0101011010111;
        b_test = 13'b0101010101010;
        # 200;
        // a = -0.86E3, b = +0.68E3
        a_test = 13'b1101011010111;
        b_test = 13'b0101010101010;
        # 200;
        // a = +0.86E3, b = -0.68E3
        a_test = 13'b0101011010111;
        b_test = 13'b1101010101010;
        # 200;
        // a = -0.86E3, b = -0.68E3
        a_test = 13'b1101011010111;
        b_test = 13'b1101010101010;
        # 200;
 
        // Group 3
        // a = +0.68E4, b = +0.86E3
        a_test = 13'b0110111010100;
        b_test = 13'b0101011010111;
        # 200;
        // a = -0.68E4, b = +0.86E3
        a_test = 13'b1110111010100;
        b_test = 13'b0101011010111;
        # 200;
        // a = +0.68E4, b = -0.86E3
        a_test = 13'b0110111010100;
        b_test = 13'b1101011010111;
        # 200;
        // a = -0.68E4, b = -0.86E3
        a_test = 13'b1110111010100;
        b_test = 13'b1101011010111;
        # 200;
 
        // Group 4 
        // a = +0.68E3, b = +0.86E4
        a_test = 13'b0101010101010;
        b_test = 13'b0111010000110;
        # 200;
        // a = -0.68E3, b = +0.86E4
        a_test = 13'b1101010101010;
        b_test = 13'b0111010000110;
        # 200;
        // a = +0.68E3, b = -0.86E4
        a_test = 13'b0101010101010;
        b_test = 13'b1111010000110;
        # 200;
        // a = -0.68E3, b = -0.86E4
        a_test = 13'b1101010101010;
        b_test = 13'b1111010000110;
        # 200;
 
        // Group 5
        // a = +0.68E0, b = +0.86E0
        a_test = 13'b0000010101110;
        b_test = 13'b0000011011100;
        # 200;
        // a = +0.68E0, b = -0.86E0
        a_test = 13'b0000010101110;
        b_test = 13'b1000011011100;
        # 200;

        // Group 6
        // a = +0.68E0, b = +0.68E0
        a_test = 13'b0000010101110;
        b_test = 13'b0000010101110;
        # 200;
        // a = -0.68E0, b = -0.68E0
        a_test = 13'b1000010101110;
        b_test = 13'b1000010101110;
        # 200;

        // Group 7
        // a = +0.00E0, b = +0.00E0
        a_test = 13'b0000000000000;
        b_test = 13'b0000000000000;
        # 200;
        // a = +0.00E0, b = -0.00E0
        a_test = 13'b0000000000000;
        b_test = 13'b1000000000000;
        # 200;

        // Stop simulation
        $stop;
    end
 
endmodule
This is the waveform result from this circuit:


You can download the project file of this circuit from my repository.

4 comments :

  1. Hundreds of penny slots to play and win this autumn. Click here to read the full article.

    ReplyDelete
  2. Strange "water hack" burns 2 lbs in your sleep

    More than 160 thousand women and men are utilizing a simple and secret "liquids hack" to drop 1-2lbs each and every night in their sleep.

    It is scientific and it works all the time.

    This is how you can do it yourself:

    1) Grab a clear glass and fill it half glass

    2) And then follow this awesome hack

    and be 1-2lbs lighter as soon as tomorrow!

    ReplyDelete
  3. मुझे नागिन के पूरे एपिसोड के सभी सीज़न उच्च गुणवत्ता में मिले हैं, कृपया नागिन 6 ऑनलाइन देखने के लिए इस वेबसाइट पर जाएँ नागिन 6

    ReplyDelete