--- /dev/null
+-------------------------------------------------------------------------\r
+--\r
+-- Filename: console_sm_sync_beh.vhd\r
+-- =========\r
+--\r
+-- Short Description:\r
+-- ==================\r
+-- Behavioral implementation of the synchronizer for the cosole mode\r
+-- finite state machine. It synchronizes all signal crossing\r
+-- from the system and the VGA clock domain and vice versa.\r
+--\r
+-------------------------------------------------------------------------\r
+\r
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.textmode_vga_pkg.all;
+use work.textmode_vga_platform_dependent_pkg.all;
+use work.font_pkg.all;
+
+architecture beh of console_sm_sync is
+ type SYNC_STATE_TYPE is (STATE_IDLE, STATE_WAIT_ACK, STATE_FINISHED, STATE_WAIT_ACK_RELEASE);
+ signal sync_state, sync_state_next : SYNC_STATE_TYPE;
+ signal command_req_sync : std_logic_vector(0 to SYNC_STAGES - 1);
+ signal command_req_sys : std_logic;
+ signal ack_sync : std_logic_vector(0 to SYNC_STAGES - 1);
+ signal ack_sys : std_logic;
+ signal command_latched, command_latched_next : std_logic_vector(COMMAND_SIZE - 1 downto 0);
+ signal command_data_latched, command_data_latched_next : std_logic_vector(3 * COLOR_SIZE + CHAR_SIZE - 1 downto 0);
+ signal command_req_next : std_logic;
+begin
+ command_vga <= command_latched;
+ command_data_vga <= command_data_latched;
+ command_req_vga <= command_req_sync(SYNC_STAGES - 1);
+ synchronizer_sys_vga : process(vga_clk, vga_res_n)
+ begin
+ if vga_res_n = '0' then
+ command_req_sync <= (others => '0');
+ elsif rising_edge(vga_clk) then
+ command_req_sync(0) <= command_req_sys;
+ for i in 1 to SYNC_STAGES - 1 loop
+ command_req_sync(i) <= command_req_sync(i - 1);
+ end loop;
+ end if;
+ end process synchronizer_sys_vga;
+
+ ack_sys <= ack_sync(SYNC_STAGES - 1);
+ synchronizer_vga_sys : process(sys_clk, sys_res_n)
+ begin
+ if sys_res_n = '0' then
+ ack_sync <= (others => '0');
+ elsif rising_edge(sys_clk) then
+ ack_sync(0) <= ack_vga;
+ for i in 1 to SYNC_STAGES - 1 loop
+ ack_sync(i) <= ack_sync(i - 1);
+ end loop;
+ end if;
+ end process synchronizer_vga_sys;
+
+ process(sync_state, command_sys, ack_sys)
+ begin
+ sync_state_next <= sync_state;
+
+ case sync_state is
+ when STATE_IDLE =>
+ if command_sys /= COMMAND_NOP then
+ if ack_sys = '0' then
+ sync_state_next <= STATE_WAIT_ACK;
+ else
+ sync_state_next <= STATE_WAIT_ACK_RELEASE;
+ end if;
+ end if;
+ when STATE_WAIT_ACK =>
+ if ack_sys = '1' then
+ sync_state_next <= STATE_FINISHED;
+ end if;
+ when STATE_FINISHED =>
+ sync_state_next <= STATE_IDLE;
+ when STATE_WAIT_ACK_RELEASE =>
+ if ack_sys = '0' then
+ sync_state_next <= STATE_WAIT_ACK;
+ end if;
+ end case;
+ end process;
+
+ process(sync_state, command_latched, command_data_latched, command_sys, command_data_sys)
+ begin
+ command_latched_next <= command_latched;
+ command_data_latched_next <= command_data_latched;
+ command_req_next <= '0';
+ free_sys <= '0';
+
+ case sync_state is
+ when STATE_IDLE =>
+ command_latched_next <= command_sys;
+ command_data_latched_next <= command_data_sys;\r
+ free_sys <= '1';
+ when STATE_WAIT_ACK =>
+ command_req_next <= '1';
+ when STATE_FINISHED =>
+ null;
+ when STATE_WAIT_ACK_RELEASE =>
+ null;
+ end case;
+ end process;
+
+ process(sys_clk, sys_res_n)
+ begin
+ if sys_res_n = '0' then
+ command_latched <= COMMAND_NOP;
+ command_data_latched <= COLOR_BLACK & CHAR_NULL;
+ sync_state <= STATE_IDLE;
+ command_req_sys <= '0';
+ elsif rising_edge(sys_clk) then
+ command_latched <= command_latched_next;
+ command_data_latched <= command_data_latched_next;
+ sync_state <= sync_state_next;
+ command_req_sys <= command_req_next;
+ end if;
+ end process;
+end architecture beh;