Im trying to program a 16 bit hardware divider (with only the first 4 bits being integer). When I try to synthesize it, Xilinx ISE gives me this error Signal NS cannot be synthesized, bad synchronous description. I can't figure out how to fix it. The following is my code if anyone can help: (btw I dont expect the logic to work yet)
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity divider is port(
dividend : in std_logic_vector(15 downto 0);
divisor : in std_logic_vector(15 downto 0);
start : in std_logic;
clk : in std_logic;
quotient : out std_logic_vector(15 downto 0);
done : out std_logic);
end divider;
architecture RTL of divider is
type statetype is (INIT,ALIGNDIVISOR,DIVIDE,ALIGNQUOTIENT);
signal PS,NS : statetype := INIT;
signal s_remainder,s_divisor,s_quotient : std_logic_vector(15 downto 0);
signal divisor_align_count, quotient_count, align_quotient_count : integer;
begin
quotient <= s_quotient;
sync: process(CLK)
begin
if rising_edge(CLK) then
PS<=NS;
end if;
end process;
comb: process(PS,dividend,divisor,start,s_remainder,s_divisor,s_quotient,
divisor_align_count, quotient_count, align_quotient_count)
begin
case PS is
when INIT =>
if rising_edge(start) then --Begin divide sequence
NS<=ALIGNDIVISOR;
s_remainder <= dividend;
s_divisor <= divisor;
s_quotient <= (others=>'0');
divisor_align_count <= 0;
quotient_count <= 15;
done <= '0';
else
NS<=INIT;
end if;
when ALIGNDIVISOR =>
if s_remainder = x"0000" then --Check for 0 dividend
NS<=ALIGNQUOTIENT;
s_quotient <= x"0000";
elsif s_divisor = x"0000" then --Check for 0 divisor
NS<=ALIGNQUOTIENT;
s_quotient <= x"FFFF";
elsif s_divisor = x"1000" then --Check for 1 divisor
NS<=ALIGNQUOTIENT;
s_quotient <= s_remainder;
elsif s_divisor(15) /= '1' then
divisor_align_count <= divisor_align_count + 1;
s_divisor <= s_divisor(14 downto 0) & '0'; --Align divisor to the left side of the register
NS<=ALIGNDIVISOR;
else
align_quotient_count <= 3 - divisor_align_count;
NS<=DIVIDE;
end if;
when DIVIDE =>
if s_remainder = x"0000" then
NS<=ALIGNQUOTIENT;
elsif s_divisor > s_remainder then
s_quotient(quotient_count) <= '0';
NS<=DIVIDE;
else
s_quotient(quotient_count) <= '1';
s_remainder <= s_remainder - s_divisor;
NS<=DIVIDE;
end if;
quotient_count <= quotient_count - 1;
s_divisor <= '0' & s_divisor(15 downto 1); --Right shift divisor
when ALIGNQUOTIENT =>
if align_quotient_count /= 0 then
s_quotient <= '0' & s_quotient(15 downto 1); --Right shift quotient
align_quotient_count <= align_quotient_count - 1;
NS<= ALIGNQUOTIENT;
else
NS<=INIT;
DONE<= '1';
end if;
when others =>
null;
end case;
end process;
end RTL;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity divider is port(
dividend : in std_logic_vector(15 downto 0);
divisor : in std_logic_vector(15 downto 0);
start : in std_logic;
clk : in std_logic;
quotient : out std_logic_vector(15 downto 0);
done : out std_logic);
end divider;
architecture RTL of divider is
type statetype is (INIT,ALIGNDIVISOR,DIVIDE,ALIGNQUOTIENT);
signal PS,NS : statetype := INIT;
signal s_remainder,s_divisor,s_quotient : std_logic_vector(15 downto 0);
signal divisor_align_count, quotient_count, align_quotient_count : integer;
begin
quotient <= s_quotient;
sync: process(CLK)
begin
if rising_edge(CLK) then
PS<=NS;
end if;
end process;
comb: process(PS,dividend,divisor,start,s_remainder,s_divisor,s_quotient,
divisor_align_count, quotient_count, align_quotient_count)
begin
case PS is
when INIT =>
if rising_edge(start) then --Begin divide sequence
NS<=ALIGNDIVISOR;
s_remainder <= dividend;
s_divisor <= divisor;
s_quotient <= (others=>'0');
divisor_align_count <= 0;
quotient_count <= 15;
done <= '0';
else
NS<=INIT;
end if;
when ALIGNDIVISOR =>
if s_remainder = x"0000" then --Check for 0 dividend
NS<=ALIGNQUOTIENT;
s_quotient <= x"0000";
elsif s_divisor = x"0000" then --Check for 0 divisor
NS<=ALIGNQUOTIENT;
s_quotient <= x"FFFF";
elsif s_divisor = x"1000" then --Check for 1 divisor
NS<=ALIGNQUOTIENT;
s_quotient <= s_remainder;
elsif s_divisor(15) /= '1' then
divisor_align_count <= divisor_align_count + 1;
s_divisor <= s_divisor(14 downto 0) & '0'; --Align divisor to the left side of the register
NS<=ALIGNDIVISOR;
else
align_quotient_count <= 3 - divisor_align_count;
NS<=DIVIDE;
end if;
when DIVIDE =>
if s_remainder = x"0000" then
NS<=ALIGNQUOTIENT;
elsif s_divisor > s_remainder then
s_quotient(quotient_count) <= '0';
NS<=DIVIDE;
else
s_quotient(quotient_count) <= '1';
s_remainder <= s_remainder - s_divisor;
NS<=DIVIDE;
end if;
quotient_count <= quotient_count - 1;
s_divisor <= '0' & s_divisor(15 downto 1); --Right shift divisor
when ALIGNQUOTIENT =>
if align_quotient_count /= 0 then
s_quotient <= '0' & s_quotient(15 downto 1); --Right shift quotient
align_quotient_count <= align_quotient_count - 1;
NS<= ALIGNQUOTIENT;
else
NS<=INIT;
DONE<= '1';
end if;
when others =>
null;
end case;
end process;
end RTL;