head 1.12; access; symbols rel_1_1:1.12 rel_1_0:1.12 rel_0_6_1_beta:1.10 rel_0_6__beta:1.9 rel_0_6_beta:1.9 rel_0_5_beta:1.6 rel_0_4_beta:1.4 rel_0_3_beta:1.4 rel_0_2_beta:1.4 rel_0_1_beta:1.4; locks; strict; comment @# @; 1.12 date 2006.07.14.01.04.35; author arniml; state Exp; branches; next 1.11; commitid 58a744b6eda24567; 1.11 date 2006.06.20.00.46.38; author arniml; state Exp; branches; next 1.10; commitid 33a74497456c4567; 1.10 date 2005.11.01.21.24.21; author arniml; state Exp; branches; next 1.9; commitid 64824367dd024567; 1.9 date 2005.06.11.10.08.43; author arniml; state Exp; branches; next 1.8; commitid 459c42aab8184567; 1.8 date 2005.06.09.22.15.10; author arniml; state Exp; branches; next 1.7; commitid 723442a8bf654567; 1.7 date 2005.05.04.20.12.36; author arniml; state Exp; branches; next 1.6; commitid 283342792c7e4567; 1.6 date 2004.10.25.20.31.12; author arniml; state Exp; branches; next 1.5; 1.5 date 2004.10.25.19.35.41; author arniml; state Exp; branches; next 1.4; 1.4 date 2004.04.24.23.44.25; author arniml; state Exp; branches; next 1.3; 1.3 date 2004.04.18.18.56.23; author arniml; state Exp; branches; next 1.2; 1.2 date 2004.03.28.12.55.06; author arniml; state Exp; branches; next 1.1; 1.1 date 2004.03.23.21.31.52; author arniml; state Exp; branches; next ; desc @@ 1.12 log @Fix bug report "Deassertion of PROG too early" PROG is deasserted at end of XTAL3 now @ text @------------------------------------------------------------------------------- -- -- The Clock Control unit. -- Clock States and Machine Cycles are generated here. -- -- $Id: clock_ctrl.vhd,v 1.11 2006/06/20 00:46:38 arniml Exp $ -- -- Copyright (c) 2004, 2005, Arnim Laeuger (arniml@@opencores.org) -- -- All rights reserved -- -- Redistribution and use in source and synthezised forms, with or without -- modification, are permitted provided that the following conditions are met: -- -- Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- -- Redistributions in synthesized form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution. -- -- Neither the name of the author nor the names of other contributors may -- be used to endorse or promote products derived from this software without -- specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- -- Please report bugs to the author, but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- -- The latest version of this file can be found at: -- http://www.opencores.org/cvsweb.shtml/t48/ -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use work.t48_pack.all; entity t48_clock_ctrl is generic ( -- divide XTAL1 by 3 to derive Clock States xtal_div_3_g : integer := 1 ); port ( clk_i : in std_logic; xtal_i : in std_logic; xtal_en_i : in boolean; res_i : in std_logic; en_clk_i : in boolean; xtal3_o : out boolean; t0_o : out std_logic; multi_cycle_i : in boolean; assert_psen_i : in boolean; assert_prog_i : in boolean; assert_rd_i : in boolean; assert_wr_i : in boolean; mstate_o : out mstate_t; second_cycle_o : out boolean; ale_o : out boolean; psen_o : out boolean; prog_o : out boolean; rd_o : out boolean; wr_o : out boolean ); end t48_clock_ctrl; library ieee; use ieee.numeric_std.all; architecture rtl of t48_clock_ctrl is -- The three XTAL1 cycles. signal xtal_q : unsigned(1 downto 0); signal xtal1_s, xtal2_s, xtal3_s : boolean; signal x1_s, x2_s, x3_s : std_logic; signal t0_q : std_logic; -- The five clock states. signal mstate_q : mstate_t; signal ale_q : boolean; signal psen_q : boolean; signal prog_q : boolean; signal rd_q : boolean; signal wr_q : boolean; -- The Machine Cycle marker. signal second_cycle_q : boolean; signal multi_cycle_q : boolean; begin ----------------------------------------------------------------------------- -- Verify the generics ----------------------------------------------------------------------------- -- pragma translate_off -- XTAL1 divide by 3 -------------------------------------------------------- assert (xtal_div_3_g = 1) or (xtal_div_3_g = 0) report "xtal_div_3_g must be either 1 or 0!" severity failure; -- pragma translate_on ----------------------------------------------------------------------------- -- Divide XTAL1 by 3 to derive Clock States. ----------------------------------------------------------------------------- use_xtal_div: if xtal_div_3_g = 1 generate xtal: process (res_i, xtal_i) begin if res_i = res_active_c then xtal_q <= TO_UNSIGNED(0, 2); t0_q <= '0'; elsif xtal_i'event and xtal_i = clk_active_c then if xtal_en_i then if xtal_q < 2 then xtal_q <= xtal_q + 1; else xtal_q <= TO_UNSIGNED(0, 2); end if; if xtal3_s then t0_q <= '1'; else t0_q <= '0'; end if; end if; end if; end process xtal; x1_s <= '1' when xtal_q = 0 and xtal_en_i else '0'; x2_s <= '1' when xtal_q = 1 and xtal_en_i else '0'; x3_s <= '1' when xtal_q = 2 and xtal_en_i else '0'; t0_o <= t0_q; end generate; ----------------------------------------------------------------------------- -- XTAL1 is used directly for Clock States. ----------------------------------------------------------------------------- no_xtal_div: if xtal_div_3_g = 0 generate xtal_q <= TO_UNSIGNED(0, 2); x1_s <= '1' when xtal_en_i else '0'; x2_s <= '1' when xtal_en_i else '0'; x3_s <= '1' when xtal_en_i else '0'; t0_o <= xtal_i; end generate; -- And finally the boolean flags -------------------------------------------- xtal1_s <= to_boolean(x1_s); xtal2_s <= to_boolean(x2_s); xtal3_s <= to_boolean(x3_s); ----------------------------------------------------------------------------- -- Process external_signal -- -- Purpose: -- Control signals ALE, PSEN, PROG and RD/WR are generated here. -- external_signals: process (res_i, xtal_i) begin if res_i = res_active_c then ale_q <= false; psen_q <= false; prog_q <= false; rd_q <= false; wr_q <= false; elsif xtal_i'event and xtal_i = clk_active_c then case mstate_q is when MSTATE5 => -- RD, WR are set at the end of XTAL2 of first machine cycle if xtal2_s and not second_cycle_q then if assert_rd_i then rd_q <= true; end if; if assert_wr_i then wr_q <= true; end if; end if; when MSTATE1 => if xtal3_s then psen_q <= false; end if; when MSTATE2 => if xtal3_s then -- RD, WR are removed at the end of XTAL3 of second machine cycle rd_q <= false; wr_q <= false; -- so is PROG prog_q <= false; end if; when MSTATE3 => -- ALE is set at the end of XTAL3 of every machine cycle if xtal3_s then ale_q <= true; end if; when MSTATE4 => if xtal3_s then -- PSEN is set at the end of XTAL3 if assert_psen_i then psen_q <= true; end if; end if; -- PROG is set at the end of XTAL3 if xtal3_s and multi_cycle_q and not second_cycle_q and assert_prog_i then prog_q <= true; end if; -- ALE is removed at the end of XTAL2 of every machine cycle if xtal2_s then ale_q <= false; end if; when others => -- recover when states are out of sync ale_q <= false; psen_q <= false; prog_q <= false; rd_q <= false; wr_q <= false; end case; end if; end process external_signals; -- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Process states -- -- Purpose: -- The Clock State controller. -- states: process (res_i, clk_i) begin if res_i = res_active_c then -- Reset machine state to MSTATE3 -- This allows a proper instruction fetch for the first real instruction -- after reset. -- The MSTATE3 is part of a virtual NOP that has no MSTATE1 and MSTATE2. mstate_q <= MSTATE3; elsif clk_i'event and clk_i = clk_active_c then if en_clk_i then case mstate_q is when MSTATE5 => mstate_q <= MSTATE1; when MSTATE1 => mstate_q <= MSTATE2; when MSTATE2 => mstate_q <= MSTATE3; when MSTATE3 => mstate_q <= MSTATE4; when MSTATE4 => mstate_q <= MSTATE5; when others => -- recover when states are out of sync mstate_q <= MSTATE1; -- pragma translate_off assert false report "Encoding of Clock States failed!" severity error; -- pragma translate_on end case; end if; end if; end process states; -- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Process machine_cycle -- -- Purpose: -- Keep track of machine cycles. -- Basically, this means to differ between first and second cycle. -- machine_cycle: process (res_i, clk_i) variable state2_v, state5_v : boolean; begin if res_i = res_active_c then multi_cycle_q <= false; second_cycle_q <= false; elsif clk_i'event and clk_i = clk_active_c then if en_clk_i then state2_v := mstate_q = MSTATE2; state5_v := mstate_q = MSTATE5; -- multi cycle information is delivered in State 2 from the decoder if state2_v and multi_cycle_i then multi_cycle_q <= true; end if; -- mark second machine cycle if multi_cycle_q and state5_v then second_cycle_q <= true; end if; -- reset at end of second machine cycle if state5_v and (multi_cycle_q and second_cycle_q) then multi_cycle_q <= false; second_cycle_q <= false; end if; end if; end if; end process machine_cycle; -- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Output assignments ----------------------------------------------------------------------------- xtal3_o <= xtal3_s; mstate_o <= mstate_q; second_cycle_o <= second_cycle_q; ale_o <= ale_q; psen_o <= psen_q; prog_o <= prog_q; rd_o <= rd_q; wr_o <= wr_q; end rtl; ------------------------------------------------------------------------------- -- File History: -- -- $Log: clock_ctrl.vhd,v $ -- Revision 1.11 2006/06/20 00:46:38 arniml -- new input xtal_en_i gates xtal_i base clock -- -- Revision 1.10 2005/11/01 21:24:21 arniml -- * shift assertion of ALE and PROG to xtal3 -- * correct change of revision 1.8 -- -- Revision 1.9 2005/06/11 10:08:43 arniml -- introduce prefix 't48_' for all packages, entities and configurations -- -- Revision 1.8 2005/06/09 22:15:10 arniml -- Use en_clk_i instead of xtal3_s for generation of external signals. -- This is required when the core runs with full xtal clock instead -- of xtal/3 (xtal_div_3_g = 0). -- -- Revision 1.7 2005/05/04 20:12:36 arniml -- Fix bug report: -- "Wrong clock applied to T0" -- t0_o is generated inside clock_ctrl with a separate flip-flop running -- with xtal_i -- -- Revision 1.6 2004/10/25 20:31:12 arniml -- remove PROG and end of XTAL2, see comment for details -- -- Revision 1.5 2004/10/25 19:35:41 arniml -- deassert rd_q, wr_q and prog_q at end of XTAL3 -- -- Revision 1.4 2004/04/24 23:44:25 arniml -- move from std_logic_arith to numeric_std -- -- Revision 1.3 2004/04/18 18:56:23 arniml -- reset machine state to MSTATE3 to allow proper instruction fetch -- after reset -- -- Revision 1.2 2004/03/28 12:55:06 arniml -- move code for PROG out of if-branch for xtal3_s -- -- Revision 1.1 2004/03/23 21:31:52 arniml -- initial check-in -- ------------------------------------------------------------------------------- @ 1.11 log @new input xtal_en_i gates xtal_i base clock @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.10 2005/11/01 21:24:21 arniml Exp $ a232 8 if xtal2_s then -- PROG is removed at the end of XTAL2 of second machine cycle -- according to the user manual, PROG should be removed at the -- end of XTAL3 but this would raise the need to change P2 at -- XTAL1 or XTAL2 -> introduction of inter-xtal timing in -- the rest of the core. prog_q <= false; end if; d237 2 d404 3 @ 1.10 log @* shift assertion of ALE and PROG to xtal3 * correct change of revision 1.8 @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.9 2005/06/11 10:08:43 arniml Exp $ d62 1 d142 12 a153 5 if xtal_q < 2 then xtal_q <= xtal_q + 1; else xtal_q <= TO_UNSIGNED(0, 2); end if; a154 4 if xtal3_s then t0_q <= '1'; else t0_q <= '0'; a157 1 d161 1 a161 1 when xtal_q = 0 else d164 1 a164 1 when xtal_q = 1 else d167 1 a167 1 when xtal_q = 2 else d179 6 a184 2 x1_s <= '1'; x2_s <= '1'; d186 1 a186 1 when en_clk_i else d410 4 @ 1.9 log @introduce prefix 't48_' for all packages, entities and configurations @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.8 2005/06/09 22:15:10 arniml Exp $ d178 3 a180 1 x3_s <= '1'; d221 1 a221 1 if en_clk_i then -- equivalent to xtal3_s d234 1 a234 1 if en_clk_i then -- equivalent to xtal3_s d241 2 a242 2 -- ALE is set at the end of XTAL2 of every machine cycle if xtal2_s then d247 1 a247 1 if en_clk_i then -- equivalent to xtal3_s d255 3 a257 3 -- PROG is set at the and of XTAL2 if xtal2_s and multi_cycle_q and not second_cycle_q and assert_prog_i then d403 3 @ 1.8 log @Use en_clk_i instead of xtal3_s for generation of external signals. This is required when the core runs with full xtal clock instead of xtal/3 (xtal_div_3_g = 0). @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.7 2005/05/04 20:12:36 arniml Exp $ d52 1 a52 1 entity clock_ctrl is d80 1 a80 1 end clock_ctrl; d86 1 a86 1 architecture rtl of clock_ctrl is d401 5 @ 1.7 log @Fix bug report: "Wrong clock applied to T0" t0_o is generated inside clock_ctrl with a separate flip-flop running with xtal_i @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.6 2004/10/25 20:31:12 arniml Exp $ d219 1 a219 1 if xtal3_s then d232 1 a232 1 if xtal3_s then d245 1 a245 1 if xtal3_s then d401 6 a425 1 -- @ 1.6 log @remove PROG and end of XTAL2, see comment for details @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.5 2004/10/25 19:35:41 arniml Exp $ d8 1 a8 1 -- Copyright (c) 2004, Arnim Laeuger (arniml@@opencores.org) d65 1 d97 2 d138 1 d147 6 d166 1 d179 1 d401 3 @ 1.5 log @deassert rd_q, wr_q and prog_q at end of XTAL3 @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.4 2004/04/24 23:44:25 arniml Exp $ d211 9 a219 1 when MSTATE2 => a223 2 -- PROG is removed at the and of XTAL3 of second machine cycle prog_q <= false; d389 3 @ 1.4 log @move from std_logic_arith to numeric_std @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.3 2004/04/18 18:56:23 arniml Exp $ d212 1 a212 1 if xtal2_s then d383 3 @ 1.3 log @reset machine state to MSTATE3 to allow proper instruction fetch after reset @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.2 2004/03/28 12:55:06 arniml Exp $ d83 1 a83 1 use ieee.std_logic_arith.all; d134 1 a134 1 xtal_q <= CONV_UNSIGNED(0, 2); d140 1 a140 1 xtal_q <= CONV_UNSIGNED(0, 2); d163 1 a163 1 xtal_q <= CONV_UNSIGNED(0, 2); d383 4 @ 1.2 log @move code for PROG out of if-branch for xtal3_s @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.1 2004/03/23 21:31:52 arniml Exp $ d272 5 a276 1 mstate_q <= MSTATE1; d350 1 a350 2 (not multi_cycle_q or (multi_cycle_q and second_cycle_q)) then d383 3 @ 1.1 log @initial check-in @ text @d6 1 a6 1 -- $Id: clock_ctrl.vhd,v 1.9 2004/03/21 11:39:32 arnim Exp $ d233 1 a233 5 -- PROG is set at the and of XTAL2 if xtal2_s and multi_cycle_q and not second_cycle_q and assert_prog_i then prog_q <= true; end if; d235 4 d379 4 a382 1 -- $Log$ @