Subversion Repositories KoE_projects

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. -- ****
  2. -- T80(b) core. In an effort to merge and maintain bug fixes ....
  3. --
  4. --
  5. -- Ver 300 started tidyup
  6. -- MikeJ March 2005
  7. -- Latest version from www.fpgaarcade.com (original www.opencores.org)
  8. --
  9. -- ****
  10. --
  11. -- Z80 compatible microprocessor core, asynchronous top level
  12. --
  13. -- Version : 0247
  14. --
  15. -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
  16. --
  17. -- All rights reserved
  18. --
  19. -- Redistribution and use in source and synthezised forms, with or without
  20. -- modification, are permitted provided that the following conditions are met:
  21. --
  22. -- Redistributions of source code must retain the above copyright notice,
  23. -- this list of conditions and the following disclaimer.
  24. --
  25. -- Redistributions in synthesized form must reproduce the above copyright
  26. -- notice, this list of conditions and the following disclaimer in the
  27. -- documentation and/or other materials provided with the distribution.
  28. --
  29. -- Neither the name of the author nor the names of other contributors may
  30. -- be used to endorse or promote products derived from this software without
  31. -- specific prior written permission.
  32. --
  33. -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  34. -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  35. -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  36. -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
  37. -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  38. -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  39. -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  40. -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  41. -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  42. -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  43. -- POSSIBILITY OF SUCH DAMAGE.
  44. --
  45. -- Please report bugs to the author, but before you do so, please
  46. -- make sure that this is not a derivative work and that
  47. -- you have the latest version of this file.
  48. --
  49. -- The latest version of this file can be found at:
  50. --      http://www.opencores.org/cvsweb.shtml/t80/
  51. --
  52. -- Limitations :
  53. --
  54. -- File history :
  55. --
  56. --      0208 : First complete release
  57. --
  58. --      0211 : Fixed interrupt cycle
  59. --
  60. --      0235 : Updated for T80 interface change
  61. --
  62. --      0238 : Updated for T80 interface change
  63. --
  64. --      0240 : Updated for T80 interface change
  65. --
  66. --      0242 : Updated for T80 interface change
  67. --
  68. --      0247 : Fixed bus req/ack cycle
  69. --
  70. --      0667 : koe - Fixed I/O/memory/int timings
  71.  
  72. library IEEE;
  73. use IEEE.std_logic_1164.all;
  74. use IEEE.numeric_std.all;
  75. use ieee.std_logic_unsigned.all;
  76. use work.T80_Pack.all;
  77.  
  78. entity T80a is
  79.         generic(
  80.                 Mode : integer := 0     -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
  81.         );
  82.         port(
  83.                 RESET_n         : in std_logic;
  84.                 CLK_n           : in std_logic;
  85.                 WAIT_n          : in std_logic;
  86.                 INT_n           : in std_logic;
  87.                 NMI_n           : in std_logic;
  88.                 BUSRQ_n         : in std_logic;
  89.                 M1_n            : out std_logic;
  90.                 MREQ_n          : out std_logic;
  91.                 IORQ_n          : out std_logic;
  92.                 RD_n            : out std_logic;
  93.                 WR_n            : out std_logic;
  94.                 RFSH_n          : out std_logic;
  95.                 HALT_n          : out std_logic;
  96.                 BUSAK_n         : out std_logic;
  97.                 A               : out std_logic_vector(15 downto 0);
  98.                 D               : inout std_logic_vector(7 downto 0);
  99.                 IOcycle                  : out std_logic;
  100.                 MEMcycle                         : out std_logic
  101.         );
  102. end T80a;
  103.  
  104. architecture rtl of T80a is
  105.  
  106.         signal CEN                  : std_logic;
  107.         signal Reset_s              : std_logic;
  108.         signal IntCycle_n   : std_logic;
  109.         signal IORQ                 : std_logic;
  110.         signal NoRead               : std_logic;
  111.         signal Write                : std_logic;
  112.         signal MREQ                 : std_logic;
  113.         signal MReq_Inhibit : std_logic;
  114.         signal Req_Inhibit  : std_logic;
  115.         signal RD                   : std_logic;
  116.         signal MREQ_n_i             : std_logic;
  117.         signal IORQ_n_i             : std_logic;
  118.         signal RD_n_i               : std_logic;
  119.         signal WR_n_i               : std_logic;
  120.         signal RFSH_n_i             : std_logic;
  121.         signal BUSAK_n_i    : std_logic;
  122.         signal A_i                  : std_logic_vector(15 downto 0);
  123.         signal DO                   : std_logic_vector(7 downto 0);
  124.         signal DI_Reg               : std_logic_vector (7 downto 0);        -- Input synchroniser
  125.         signal DI_Reg_buffer        : std_logic_vector (7 downto 0):=b"00000000";  -- koe
  126.         signal buffer_enable                     : std_logic;
  127.         signal Wait_s               : std_logic;
  128.         signal MCycle               : std_logic_vector(2 downto 0);
  129.         signal TState               : std_logic_vector(2 downto 0);
  130.         signal Iorq_wr_res                       : std_logic; -- koe
  131.         signal Iorq_wr_set                       : std_logic; -- koe
  132.         signal IOactive                          : std_logic; -- koe
  133.         signal IntCycleCount                     : std_logic_vector(2 downto 0):=b"000"; -- koe
  134.         signal IORQ_mask0                                : std_logic:='0'; -- koe
  135.         signal IORQ_mask1                                : std_logic:='0'; -- koe
  136.         signal IORQ_mask                                 : std_logic:='0'; -- koe
  137.        
  138. begin
  139.  
  140.         CEN <= '1';
  141.  
  142.         BUSAK_n <= BUSAK_n_i;
  143.         MREQ_n_i <= not MREQ or Req_Inhibit; --or (Req_Inhibit and MReq_Inhibit); !!!koe
  144.         RD_n_i <= not RD or Req_Inhibit;
  145.  
  146.         MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z';
  147.         IORQ_n <= (IORQ_n_i or IORQ_mask) when BUSAK_n_i = '1' else 'Z';
  148.         RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z';
  149.         WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z';
  150.         RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z';
  151.         A <= A_i when BUSAK_n_i = '1' else (others => 'Z');
  152.         D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z');
  153.         IOcycle <= IORQ;
  154.         MEMcycle <= MREQ;
  155.        
  156.         process (RESET_n, CLK_n)
  157.         begin
  158.                 if RESET_n = '0' then
  159.                         Reset_s <= '0';
  160.                 elsif CLK_n'event and CLK_n = '1' then
  161.                         Reset_s <= '1';
  162.                 end if;
  163.         end process;
  164.  
  165.         u0 : T80
  166.                 generic map(
  167.                         Mode => Mode,
  168.                         IOWait => 1)
  169.                 port map(
  170.                         CEN => CEN,
  171.                         M1_n => M1_n,
  172.                         IORQ => IORQ,
  173.                         NoRead => NoRead,
  174.                         Write => Write,
  175.                         RFSH_n => RFSH_n_i,
  176.                         HALT_n => HALT_n,
  177.                         WAIT_n => Wait_s,
  178.                         INT_n => INT_n,
  179.                         NMI_n => NMI_n,
  180.                         RESET_n => Reset_s,
  181.                         BUSRQ_n => BUSRQ_n,
  182.                         BUSAK_n => BUSAK_n_i,
  183.                         CLK_n => CLK_n,
  184.                         A => A_i,
  185.                         DInst => D,
  186.                         DI => DI_Reg,
  187.                         DO => DO,
  188.                         MC => MCycle,
  189.                         TS => TState,
  190.                         IntCycle_n => IntCycle_n);
  191.  
  192.         process (CLK_n)
  193.         begin
  194.                 if CLK_n'event and CLK_n = '0' then
  195.                         Wait_s <= WAIT_n;
  196.                         if TState = "011" and BUSAK_n_i = '1' then
  197.                                 if (MCycle = "001") then DI_Reg <= DI_Reg_buffer;
  198.                                         else    DI_Reg <= to_x01(D);
  199.                                 end if;
  200.                         end if;
  201.                 end if;
  202.         end process;
  203.  
  204.         process (CLK_n, IntCycle_n, TState, BUSAK_n_i, MCycle, WAIT_n, MReq_Inhibit)
  205.         begin
  206.                 if CLK_n'event and CLK_n = '1' then
  207.                         if TState = "010" and BUSAK_n_i = '1' and MCycle = "001" and WAIT_n = '1' and (MReq_Inhibit = '1' or IntCycle_n = '0') then
  208.                                 DI_Reg_buffer <= to_x01(D);
  209.                         end if;
  210.                 end if;
  211.         end process;
  212.        
  213.        
  214.         -- koe
  215.         process (TState,CLK_n)
  216.         begin
  217.                 if (CLK_n'event and CLK_n = '0') then
  218.                         if (TState = "011") then Iorq_wr_res <= '1';
  219.                                 else Iorq_wr_res <= '0';
  220.                         end if;
  221.                 end if;
  222.         end process;
  223.        
  224.         -- koe
  225.         process (TState,IORQ,Write,CLK_n)
  226.         begin
  227.                 if (CLK_n'event and CLK_n = '1') then
  228.                         if (TState = "001" and IORQ = '1' and Write = '1') then Iorq_wr_set <= '1';
  229.                                 else Iorq_wr_set        <= '0';
  230.                         end if;
  231.                 end if;
  232.         end process;
  233.        
  234.         process (Reset_s,Iorq_wr_res,IORQ_n_i,WAIT_n,CLK_n)
  235.         begin
  236.                 if Reset_s = '0' then
  237.                         WR_n_i <= '1';
  238.                                 elsif (Iorq_wr_res = '1') then WR_n_i <= '1'; -- koe
  239.                                 elsif (Iorq_wr_set = '1') then WR_n_i <= '0'; -- koe
  240.                 elsif CLK_n'event and CLK_n = '0' then
  241.                                 if (TState = "010" and WAIT_n = '1') then    -- koe  
  242.                                 WR_n_i <= not Write; end if;
  243.                                 if TState = "011" then      -- koe
  244.                                 WR_n_i <= '1'; end if;
  245.                 end if;
  246.         end process;
  247.  
  248.         process (Reset_s,CLK_n,WAIT_n,MReq_Inhibit,MREQ) -- koe: fixed M1 cycle timings with wait states
  249.         begin
  250.                 if Reset_s = '0' or MREQ = '0' or MReq_Inhibit = '0' then
  251.                         Req_Inhibit <= '0';
  252.                 elsif CLK_n'event and CLK_n = '1' then
  253.                         if MCycle = "001" and TState = "010" and WAIT_n = '1' and MReq_Inhibit = '1' then
  254.                                 Req_Inhibit <= '1';
  255.                 --      else
  256.                 --              Req_Inhibit <= '0';
  257.                         end if;
  258.                 end if;
  259.         end process;
  260.  
  261.         process (Reset_s,CLK_n,WAIT_n,MREQ) -- koe: fixed M1 cycle timings with wait states
  262.         begin
  263.                 if Reset_s = '0' or MREQ = '0' then
  264.                         MReq_Inhibit <= '0';
  265.                 elsif CLK_n'event and CLK_n = '0' then
  266.                         if MCycle = "001" and TState = "010" and WAIT_n = '1' then
  267.                                 MReq_Inhibit <= '1';
  268.                         else
  269.                                 MReq_Inhibit <= '0';
  270.                         end if;
  271.                 end if;
  272.         end process;
  273.  
  274.         -- koe
  275.         process(Reset_s,TState,IORQ,CLK_n)
  276.         begin
  277.                 if (CLK_n'event and CLK_n = '1') then
  278.                         if (TState = b"001" and IORQ = '1') then IOactive <= '1';
  279.                                 else IOactive <= '0';
  280.                         end if;
  281.                 end if;
  282.         end process;   
  283.        
  284.         -- koe INT ACK Cycle IORQ generation fix
  285.         process (CLK_n, IntCycle_n, WAIT_n, MCycle)
  286.         begin
  287.                 if (IntCycle_n = '1') then IntCycleCount(2 downto 0) <= (others => '0'); IORQ_mask0 <= '1';
  288.                         elsif (CLK_n'event and CLK_n = '0') then
  289.                                 if (MCycle = "001") then
  290.                                         if ((IntCycleCount(2 downto 0) < "011") or ((IntCycleCount(2 downto 0) > "010") and (WAIT_n = '1'))) then
  291.                                                 IntCycleCount(2 downto 0) <= IntCycleCount(2 downto 0) + '1';
  292.                                                 if (IntCycleCount(2 downto 0) = "010") then IORQ_mask0 <= '0'; end if;
  293.                                         end if;
  294.                                 end if;
  295.                 end if;
  296.         end process;
  297.         -- koe INT ACK Cycle IORQ generation fix
  298.         process (CLK_n, IntCycle_n, MCycle, IntCycleCount)
  299.         begin
  300.                 if (IntCycle_n = '1') then IORQ_mask1 <= '0';
  301.                         elsif (CLK_n'event and CLK_n = '1') then
  302.                                 if (MCycle = "001") then       
  303.                                         if (IntCycleCount(2 downto 0) = "100") then IORQ_mask1 <= '1'; end if;
  304.                                 end if;
  305.                 end if;
  306.         end process;
  307.         -- koe INT ACK Cycle IORQ generation fix
  308.         IORQ_mask <= not(IntCycle_n) and (IORQ_mask0 or IORQ_mask1);
  309.        
  310.        
  311.         process(Reset_s,IOactive,CLK_n)
  312.         begin
  313.                 if Reset_s = '0' then
  314.                         RD <= '0';
  315.                         IORQ_n_i <= '1';
  316.                         MREQ <= '0';
  317.  
  318.                         elsif (IOactive = '1') then     -- koe
  319.                                 IORQ_n_i <= not IORQ;
  320.                                 if (NoRead = '0') then RD <= not Write; end if;
  321.                                
  322.                 elsif CLK_n'event and CLK_n = '0' then
  323.  
  324.                         if MCycle = "001" then
  325.                                 if TState = "001" then
  326.                                         RD <= IntCycle_n;
  327.                                         MREQ <= IntCycle_n;
  328.                                         IORQ_n_i <= IntCycle_n;
  329.                                 end if;
  330.                                 if TState = "011" then
  331.                                         RD <= '0';
  332.                                         IORQ_n_i <= '1';
  333.                                         MREQ <= '1';
  334.                                 end if;
  335.                                 if TState = "100" then
  336.                                         MREQ <= '0';
  337.                                 end if;
  338.                         else
  339.                                 if TState = "001" and NoRead = '0' then
  340.                                         if (IORQ = '0') then RD <= not Write; end if;
  341.                                         --IORQ_n_i <= not IORQ;
  342.                                         MREQ <= not IORQ;
  343.                                 end if;
  344.                                 if TState = "011" then
  345.                                         RD <= '0';
  346.                                         IORQ_n_i <= '1';
  347.                                         MREQ <= '0';
  348.                                 end if;
  349.                         end if;
  350.                 end if;
  351.         end process;
  352.  
  353. end;
  354.