Un enfoque simple es la bisección de intervalos.
Aquí hay un pseudocódigo. Supongo que la división por 2 rondas hacia cero. El resultado final también se redondeará hacia cero. Supongo que tanto la entrada como la salida están en 16.16 puntos fijos (al volver a leer su pregunta, observé que especificó la ubicación del punto decimal para la salida pero no para la entrada)
low = 0.0
high = 256.0
in = (value you want to square root)
epsilon = (smallest value you can represent)
do {
mid = (high + low) / 2
multresult = (mid * mid)
if (multresult <= in) low = mid
if (multreslut >= in) high = mid
} while ((high - low) > epsilon)
result = low
Hay dos maneras en que esto puede terminar. O encuentra la respuesta exacta o el intervalo se reduce a épsilon.
Debería ser lo suficientemente fácil como para implementar esto como una máquina de estado verilog.
- La división por 2 es solo un pequeño cambio.
- La multiplicación de puntos fijos es bastante fácil. Simplemente haga un entero multiplicado seguido de mover bits alrededor. Solo asegúrese de que su multiplicador sea lo suficientemente amplio para que las cosas no se desborden.
- La suma, resta y comparación de puntos fijos son lo mismo que la resta y comparación de suma de números enteros.