OpenCores

Fixed Point Math Library for Verilog

qadd.v

A simple combinational addition module.  

sum = addend + addend

Input format: 
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Inputs:
     a - addend 1
     b - addend 2

Output format:
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Output:
     c - result
	 
NOTE:  There is no error detection for an overflow.  It is up to the designer 
         to ensure that an overflow cannot occur!!

Example usage:
     qadd #(Q,N) my_adder(
          .a(addend_a),
          .b(addend_b),
          .c(result)
	  );
	 
For subtraction, set the sign bit for the negative number. (subtraction is 
the addition of a negative, right?)

qmult.v

A simple combinational multiplication module.  

Input format: 
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Inputs:
     i_multiplicand - multiplicand
     i_multiplier   - multiplier

Output format:
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Output:
     o_result - result
     ovr      - overflow flag
	 
NOTE:  This module assumes a system that supports the synthesis of 
       combinational multipliers.  If your device/synthesizer does not 
       support this for your particular application, then use the 
       "qmults.v" module.

NOTE:  Notice that the output format is identical to the input format!  To 
       properly use this module, you need to either ensure that you maximum 
       result never exceeds the format, or incorporate the overflow flag 
       into your design

Example usage:
     qmult #(Q,N) my_multiplier(
          .i_multiplicand(multiplicand),
          .i_multiplier(multiplier),
          .o_result(result),
	  .ovr(overflow_flag)
	  );

qmults.v

A multi-clock multiplication module that uses a left-shift and add algorithm.
		   
result = multiplicand x multiplier

Input format: 
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Inputs:
     i_multiplicand - multiplicand
	 i_multiplier   - multiplier
	 i_start        - Start flag; set this bit high ("1") to start the
                          operation when the last operation is completed.  This 
                          bit is ignored until o_complete is asserted.
	 i_clk          - input clock; internal workings occur on the rising edge

Output format:
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Output:
     o_result_out - result
	 o_complete   - computation complete flag; asserted ("1") when the 
	                operation is completed
	 o_overflow   - overflow flag; asserted ("1") to indicate that an 
	                overflow has occurred.
	 
NOTE:  This module is "time deterministic ." - that is, it should always 
       take the same number of clock cycles to complete an operation, 
       regardless of the inputs (N+1 clocks)

NOTE:  Notice that the output format is identical to the input format!  To 
       properly use this module, you need to either ensure that you maximum 
       result never exceeds the format, or incorporate the overflow flag 
       into your design

Example usage:
     qmults #(Q,N) my_multiplier(
          .i_multiplicand(multiplicand),
          .i_multiplier(multiplier),
	  .i_start(start),
	  .i_clk(clock),
          .o_result(result),
	  .o_complete(done),
	  .o_overflow(overflow_flag)
	  );
	 
The qmults.v module begins computation when the start conditions are met: 
     o_complete == 1'b1;
     i_start == 1'b1;

qdiv.v

A multi-clock division module that uses a right-shift and add algorithm.

quotient = dividend / divisor

Input format: 
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Inputs:
     i_dividend  - dividend
	 i_divisor   - divisor
	 i_start     - Start flag; set this bit high ("1") to start the
                       operation when the last operation is completed.  This 
                       bit is ignored until o_complete is asserted.
	 i_clk       - input clock; internal workings occur on the rising edge

Output format:
|1|<- N-Q-1 bits ->|<--- Q bits -->|
|S|IIIIIIIIIIIIIIII|FFFFFFFFFFFFFFF|

Output:
     o_quotient_out - result
     o_complete     - computation complete flag; asserted ("1") when the 
                      operation is completed
     o_overflow     - overflow flag; asserted ("1") to indicate that an 
                      overflow has occurred.
	 
NOTE:  This module is "time deterministic ." - that is, it should always 
       take the same number of clock cycles to complete an operation, 
       regardless of the inputs (N+Q+1 clocks)

NOTE:  Notice that the output format is identical to the input format!  To 
       properly use this module, you need to either ensure that you maximum 
       result never exceeds the format, or incorporate the overflow flag 
       into your design

Example usage:
     qdiv #(Q,N) my_divider(
          .i_dividend(dividend),
          .i_divisor(divisor),
	  .i_start(start),
	  .i_clk(clock),
          .o_quotient_out(result),
	  .o_complete(done),
	  .o_overflow(overflow_flag)
	  );
	 
The qdiv.v module begins computation when the start conditions are met: 
     o_complete == 1'b1;
     i_start == 1'b1;

For some more info on how this module works, check out the video at the link below:
Binary Fixed-Point Division by Tom Burke