I want to implement a reciprical block on Verilog that will later be synthesized on an FPGA. The input should be a signed 32 bit wordlength with a 16 bit fraction length. The output should have the same format.
Example
input : x ---> output ---> 1/x
I have solved the problem using the inbuilt IP core divider. I'm wondering if there is an elegant/altenative way of solving this by for example by bit shifting or 2's complement with some xor grinds.
I have used the IP core to implement the inverse as it says in the manual but for some reason that i don't really understand the result is wrong and it needs to be shifted to the left by 1. For example; Reciprical of 1 gives 0.5 . Reciprical of 2 gives 1.
Below is a section from the manual and my testbench code
Test bench
module reciprical_tb;
// Inputs
reg clk;
reg [1:0] dividend;
reg [31:0] divisor;
// Outputs
wire rfd;
wire [1:0] quotient;
wire [31:0] fractional;
// Instantiate the Unit Under Test (UUT)
reciprical uut (
.rfd(rfd),
.clk(clk),
.dividend(dividend),
.quotient(quotient),
.divisor(divisor),
.fractional(fractional)
);
// clock
always begin
#5 clk = ~clk;
end
initial begin
// Initialize Inputs
clk = 0;
dividend = 2'b1; // 1
divisor = 2**16;; // = 1 when fraction length is 16bit
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here :: Inverse of 2 should give 0.5
//$display("inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional); //gives zero
$monitor("inv(%d) => q = %d || inv = %b", divisor>>>16,fractional>>>16, fractional); //gives a wrong answer by a factor of 2
// Using the monitor i get inv(1) = 0.5 instead of 1.
#100;
end
endmodule
Manual section (page 4):
... The divider can be used to implement the reciprocal of X; that is the 1/X function. To do this, the dividend bit width is set to 2 and fractional mode is selected. The dividend input is then tied to 01 for both unsigned or signed operation, and the X value is provided via the divisor input.