library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity X_O is generic (n : positive := 3); port( Rst_n, clk : in std_logic; D_in : in std_logic_vector (1 downto 0); Stts : out std_logic_vector (1 downto 0) := "00"); end entity; architecture X_O_arc of X_O is type state_type is (IDLE, X_chk, O_chk, tmp_draw); -- makes type of 2 bits signal cur_st, nxt_st : state_type := IDLE; signal memory_last_row : std_logic_vector (0 to 2*n-1) ; -- because D_in has 2 bits the memory needs to be 2*D_in signal changed_chk : std_logic_vector (0 to n-1) ; signal C : integer := 0; -- counter of the coulmn position signal tmp_Stts : std_logic_vector (1 downto 0) := "00"; begin main_process: process(clk) begin for i in 0 to n-1 loop -- row loop if (clk'event and clk='1') then cur_st <= nxt_st; if (Rst_n='0') then -- reset operation cur_st <= IDLE; memory_last_row <= (others => '0'); C <= 0; tmp_Stts <= "00"; end if; if i > 0 then changed_chk(C) <= ( D_in(1) XOR memory_last_row(2*C) ) AND ( D_in(0) XOR memory_last_row(2*C+1) ); end if; memory_last_row(2*C) <= D_in(1); memory_last_row(2*C+1) <= D_in(0); if i = n-1 and tmp_Stts = "00" then -- COULMN check if changed_chk(C) = '0' and D_in = "01" then tmp_Stts <= "01"; elsif changed_chk(C) = '0' and D_in = "10" then tmp_Stts <= "10"; end if; end if; if D_in = "11" and tmp_Stts = "00" then -- ROW check if cur_st = X_chk then tmp_Stts <= "01"; elsif cur_st = O_chk then tmp_Stts <= "10"; else -- tmp_draw situation if i = n-1 then tmp_Stts <= "11"; else cur_st <= IDLE; end if; end if; end if; if D_in = "11" then C <= 0; elsif C < n-1 then C <= C + 1; end if; end if; end loop; end process; Stts <= tmp_Stts; ROW_process_comb : process (D_in, cur_st) -- row fsm begin nxt_st <= cur_st; --default case cur_st is when tmp_draw => nxt_st <= tmp_draw; when IDLE => case D_in is when "00" => nxt_st <= tmp_draw; when "01" => nxt_st <= X_chk; when "10" => nxt_st <= O_chk; when others => nxt_st <= IDLE; end case; when X_chk => case D_in is when "-0" => nxt_st <= tmp_draw; when others => nxt_st <= X_chk; end case; when O_chk => case D_in is when "0-" => nxt_st <= tmp_draw; when others => nxt_st <= O_chk; end case; end case; end process; end architecture; library ieee; use ieee.std_logic_1164.all; use std.env.all; entity X_O_SDU is generic (n : positive := 3); port( Rst_n, clk : out std_logic; D_in : out std_logic_vector (1 downto 0)); end entity; architecture behave of X_O_SDU is constant CCT : time := 10 ns; signal clk_sig : std_logic := '1'; begin clk_sig <= not (clk_sig) after CCT/2; clk <= clk_sig; process begin Rst_n <= '0'; D_in <= "00"; -- initialization wait until falling_edge(clk_sig); wait until falling_edge(clk_sig); Rst_n <= '1'; for i in 1 to n-1 loop -- case in which O (10) wins [row] for j in 1 to n loop D_in <= "00"; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); end loop; for j in 1 to n loop D_in <= "10"; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); Rst_n <= '0'; wait until falling_edge(clk_sig); Rst_n <= '1'; for i in 1 to n-1 loop -- case in which X (01) wins [row] for j in 1 to n loop D_in <= "00"; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); end loop; for j in 1 to n loop D_in <= "01"; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); Rst_n <= '0'; wait until falling_edge(clk_sig); Rst_n <= '1'; for i in 1 to n loop -- case in which O (10) wins [coulmn] for j in 1 to n loop if j = 1 then D_in <= "10"; else D_in <= "01"; end if; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); end loop; wait until falling_edge(clk_sig); Rst_n <= '0'; wait until falling_edge(clk_sig); Rst_n <= '1'; for i in 1 to n loop -- case in which X (01) wins [coulmn] for j in 1 to n loop if j = 1 then D_in <= "01"; else D_in <= "10"; end if; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); end loop; wait until falling_edge(clk_sig); Rst_n <= '0'; wait until falling_edge(clk_sig); Rst_n <= '1'; for i in 1 to n-1 loop -- case of draw for j in 1 to n loop D_in <= "00"; wait until falling_edge(clk_sig); end loop; D_in <= "11"; wait until falling_edge(clk_sig); end loop; for j in 1 to n-1 loop D_in <= "01"; wait until falling_edge(clk_sig); end loop; D_in <= "10"; wait until falling_edge(clk_sig); D_in <= "11"; wait until falling_edge(clk_sig); Rst_n <= '0'; wait until falling_edge(clk_sig); wait until falling_edge(clk_sig); stop (0); end process; end architecture; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity X_O_tb is end entity; architecture struct of X_O_tb is constant n : positive := 3; signal clk, Rst_n : std_logic; signal D_in , Stts : std_logic_vector (1 downto 0); begin DUT : entity work.X_O generic map (n => n) port map (clk => clk, Rst_n => Rst_n, D_in => D_in, Stts => Stts); SDU : entity work.X_O_SDU generic map (n => n) port map (clk => clk, Rst_n => Rst_n, D_in => D_in); end architecture;