---------------------------------------------------------- -- Mobile User Master Clock Controller -- Author : Ai Hua -- Date : March 30, 2001 -- Filename : musr_clk_master.vhd -- Architecture : Behavioral -- Description : This entity is the core controller -- which control all the timing realtion -- of sending a frame -- Total logic cells used: 40/1152 ( 3%) ---------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library work; use work.CDMA_pkg.all; entity musr_clk_master is generic (num_device : positive := 9); port ( resetn, sys_clk : in std_logic; key_in : in std_logic; maintain_cycle : in std_logic; channel_ready : in std_logic; -- tell the keypad component that new key_in can be handled again. -- it 's used to close present process in all the other component. work_period_over : out std_logic; keypad_clk_en : out std_logic; frame_builder_clk_en : out std_logic; parallel_to_serial_load, parallel_to_serial_clk_en : out std_logic; spreading_load, spreading_clk_en : out std_logic; sync_code_load, sync_code_clk_en : out std_logic; busy : out std_logic ); end musr_clk_master; architecture behavioral of musr_clk_master is signal temp_clk_en, temp_load : std_logic; signal temp_d, temp_q : std_logic_vector(9 downto 0); signal temp_keypad_clk_en, temp_keypad_clk_en1 : std_logic; signal temp_frame_builder_clk_en : std_logic; signal temp_sync_code_load : std_logic; signal temp_sync_code_clk_en : std_logic; signal temp_parallel_to_serial_load : std_logic; signal temp_parallel_to_serial_clk_en : std_logic; signal temp_parallel_to_serial_clk_en1 : std_logic; signal temp_spreading_load, temp_spreading_over : std_logic; signal temp_spreading_clk_en : std_logic; signal temp_clear_data : std_logic; signal temp_work_period_over : std_logic; signal tmp_in, tmp_out : std_logic_vector(num_device-1 downto 0 ); signal not_busy, temp_busy : std_logic; type working_state is (waiting, before_working, working, after_working); signal state : working_state; type spreading_state is (waiting, spreading); signal Is_spreading : spreading_state; begin temp_d <= (others => '0'); temp_clk_en <= '1'; temp_load <= key_in or maintain_cycle; -- comes from kaypad and frame_builder. -- only valid a 25M clock period. -- control the beginning of every work cycle period. -- but the next valid period should be after the -- old frame was transmitted. -- the accurate time limits between two key_in valid -- period can be caculated! -- *** very important!!! *** clock_counter : work_period_clocker generic map (datawidth => clock_counter_datawidth) PORT map ( clk => sys_clk, resetn => resetn, clk_en => temp_clk_en, load => temp_load, d => temp_d, q => temp_q ); -- keypad_clk_en is set to valid at 4th 25M clock period for 3 periods. with temp_q select temp_keypad_clk_en1 <= '1' when "0000001001", '0' when others; temp_keypad_clk_en <= temp_keypad_clk_en1 and channel_ready; -- frame_builder_clk_en is set to valid at 8th 25M clock period for 3 periods. with temp_q select temp_frame_builder_clk_en <= '1' when "0000001010", '0' when others; with temp_q select temp_sync_code_load <= '1' when "0000000001", '0' when others; with temp_q select temp_sync_code_clk_en <= '1' when "0000000101", '1' when "0000001001", '1' when "0000001101", '1' when "0000010001", '1' when "0000010101", '1' when "0000011001", '1' when "0000011101", '0' when others; -- transmitter_clk_en is set to valid at 11th 25M clock period for 3 periods. with temp_q select temp_parallel_to_serial_load <= '1' when "0000100001", '0' when others; with temp_q select temp_spreading_load <= '1' when "0000100001", '0' when others; with temp_q select temp_spreading_over <= '1' when "0110011101", '0' when others; with temp_q select temp_clear_data <= '1' when "0110100001", '0' when others; -- work_period_over is set to valid at 416th 25M clock period for 3 periods. with temp_q select temp_work_period_over <= '1' when "0110100001", '0' when others; Check_spreading_state : process begin wait until sys_clk'event and sys_clk = '1'; if resetn = '0' then Is_spreading <= waiting; else case Is_spreading is when waiting => if (temp_spreading_load = '1' and temp_busy = '1') then Is_spreading <= spreading; else Is_spreading <= waiting; end if; when spreading => if temp_spreading_over = '1' then Is_spreading <= waiting; else Is_spreading <= spreading; end if; end case; end if; end process Check_spreading_state; with Is_spreading select temp_spreading_clk_en <= (not temp_q(1)) and temp_q(0) when spreading, '0' when others; with Is_spreading select temp_parallel_to_serial_clk_en1 <= (not temp_q(4)) and (not temp_q(3)) and (not temp_q(2)) and (not temp_q(1)) and temp_q(0) when spreading, '0' when others; temp_parallel_to_serial_clk_en <= temp_parallel_to_serial_clk_en1 or temp_clear_data; tmp_in <= temp_keypad_clk_en & temp_frame_builder_clk_en & temp_sync_code_load & temp_sync_code_clk_en & temp_parallel_to_serial_load & temp_parallel_to_serial_clk_en & temp_spreading_load & temp_spreading_clk_en & temp_work_period_over; not_busy <= not temp_busy; registerout : myflipflops Generic map (datawidth => num_device ) port map ( clk => sys_clk, clearn => temp_busy, enable => temp_clk_en, d => tmp_in, q => tmp_out ); keypad_clk_en <= tmp_out(8); frame_builder_clk_en <= tmp_out(7); sync_code_load <= tmp_out(6); sync_code_clk_en <= tmp_out(5); parallel_to_serial_load <= tmp_out(4); parallel_to_serial_clk_en <= tmp_out(3); spreading_load <= tmp_out(2); spreading_clk_en <= tmp_out(1); work_period_over <= tmp_out(0); process (sys_clk, resetn) begin wait until sys_clk'event and sys_clk = '1'; if resetn = '0' then state <= waiting; else case state is when waiting => if temp_load = '0' then state <= before_working; else state <= waiting; end if; when before_working => if temp_load = '0' then state <= before_working; else state <= working; end if; when working => if temp_work_period_over = '0' then state <= working; else state <= after_working; end if; when after_working => if temp_load = '0' then state <= before_working; else state <= waiting; end if; end case; end if; end process; with state select temp_busy <= '1' when working, '1' when after_working, '0' when others; busy <= temp_busy; end behavioral;