Root square VHDL code
Published: 2023-09-03 10:50:30

Hello,
I was trying to implement a root square algorithm in VHDL code but I've encountered some issues and I'm stuck, the point is that the result is always showing me a zero and I didn't get where is the problem.
Here is my VHDL code using FSM to calculate the root square using successive approximation algorithm:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity racine_carree_algo1 is
	generic(len_a : integer := 4);
	port(	
		clk		: in std_logic;
		reset, debut	: in std_logic;
		A		: in std_logic_vector(2*len_a-1 downto 0);
		resultat	: out std_logic_vector(len_a-1 downto 0);
		fini 		: out std_logic);
end entity;
architecture a1 of racine_carree_algo1 is
type state_type is (wt, init, cal, state_fini);
signal etat : state_type;
begin
process(clk,reset)
	variable X,A_tmp	: std_logic_vector(2*len_a-1 downto 0);
	variable Z,V		: std_logic_vector(len_a-1 downto 0);
	variable counter	: integer := len_a;
	begin
		if (reset = '1') then
			etat <= wt;
			counter := len_a;
		else
			if(rising_edge(clk)) then
				case etat is
					when wt =>
						if (debut = '1') then
							etat <= init;
						end if;
					when init =>
						A_tmp := A;
						fini <= '0';
						X := ((2*len_a-2)  => '1', others => '0');
						V := ((len_a-2)  => '1', others => '0');
						Z := ((len_a-1)  => '1', others => '0');
						etat <= cal;
						counter := len_a;
					when cal =>
						if (X > A) then
							X := X + V * (V - (Z(len_a-2 downto 0) & '0')); 
							Z := Z - V;
						else
							X := X + V * (V + (Z(len_a-2 downto 0) & '0'));
							Z := Z + V;
						end if;
						V := '0' & V(len_a-1 downto 1);
						counter := counter - 1;
						if (counter > 0) then
							etat <= cal;
						else
							etat <= state_fini;
						end if;
					when state_fini =>
						if ((signed(signed('0' & X) - signed('0' & A_tmp))) >0) then
							resultat <= Z - 1;
						else
							resultat <= Z;
						end if;
						fini <= '1';
						if (debut = '0') then
							etat <= wt;
						end if;
					end case;
				end if;
			end if;
	end process;
end architecture;

And here you can find the test bench that I'm using to simulate it:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;
entity racine_algo1_tb is
	generic (len_a : integer := 32);
end entity;
architecture tb_a1 of racine_algo1_tb is
constant T			: time := 5 ps;
signal clk, reset, debut, fini 	: std_logic;
signal A 			: std_logic_vector(2*len_a-1 downto 0);
signal resultat			: std_logic_vector(len_a-1 downto 0);
	component racine_carree_algo1 is 
	generic(len_a : integer);
	port(
		clk		: in std_logic;
		reset, debut	: in std_logic;
		A 		: in std_logic_vector(2*len_a-1 downto 0);
		resultat 	: out std_logic_vector(len_a-1 downto 0);
		fini 		: out std_logic);
	end component;
begin
C1: racine_carree_algo1
	generic map (len_a => len_a)
	port map (
		clk	=> clk,
		reset	=> reset,
		debut	=> debut,
		fini	=> fini,
		A	=> A,
		resultat=> resultat);
process
begin
	clk <= '0';
	wait for T/2;
	clk <= '1';
	wait for T/2;
end process;
	reset <= '1', '0' after T/2;
	debut <= '0', '1' after T, '0' after 149*T, '1' after 151*T;
	A <=  std_logic_vector(to_unsigned(121, (2*len_a))) after T/2, std_logic_vector(to_unsigned(15, (2*len_a))) after 150*T;
end tb_a1;

Thank you for your help in advance,

Djamal