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?)
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) );
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;
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