diff options
-rw-r--r-- | zpu/hdl/example/sim_small_fpga_top.vhd | 308 | ||||
-rw-r--r-- | zpu/hdl/example/sim_small_fpga_top_noint.vhd | 277 | ||||
-rw-r--r-- | zpu/hdl/example_medium/sim_fpga_top.vhd | 339 | ||||
-rw-r--r-- | zpu/hdl/zpu4/core/zpu_config.vhd | 116 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/clocks.vhd | 418 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/io.vhd | 191 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/timer.vhd | 102 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/trace.vhd | 106 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/txt_util.vhd | 852 | ||||
-rw-r--r-- | zpu/hdl/zpu4/src/zpuio.vhd | 424 |
10 files changed, 1482 insertions, 1651 deletions
diff --git a/zpu/hdl/example/sim_small_fpga_top.vhd b/zpu/hdl/example/sim_small_fpga_top.vhd index 8054489..909ea21 100644 --- a/zpu/hdl/example/sim_small_fpga_top.vhd +++ b/zpu/hdl/example/sim_small_fpga_top.vhd @@ -30,178 +30,168 @@ -- -- The views and conclusions contained in the software and documentation -- are those of the authors and should not be interpreted as representing --- official policies, either expressed or implied, of the ZPU Project.-------------------------------------------------------------------------------- +-- official policies, either expressed or implied, of the ZPU Project. +-------------------------------------------------------------------------------- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; +library ieee; +use ieee.std_logic_1164.all; use ieee.numeric_std.all; ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - library work; use work.zpu_config.all; use work.zpupkg.all; + entity fpga_top is end fpga_top; -architecture behave of fpga_top is - - -signal clk : std_logic; - -signal areset : std_logic := '1'; - - -component zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end component; - - - - - -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal enable : std_logic; - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - -signal io_busy : std_logic; - -signal io_mem_read : std_logic_vector(wordSize-1 downto 0); -signal io_mem_writeEnable : std_logic; -signal io_mem_readEnable : std_logic; - - -signal dram_ready : std_logic; -signal io_ready : std_logic; -signal io_reading : std_logic; -signal interruptcounter : unsigned(15 downto 0); -signal interrupt : std_logic; +architecture behave of fpga_top is -signal break : std_logic; + signal clk : std_logic; + + signal areset : std_logic := '1'; + + + component zpu_io is + generic ( + log_file: string := "log.txt" + ); + port ( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); + end component; + + + signal mem_busy : std_logic; + signal mem_read : std_logic_vector(wordSize-1 downto 0); + signal mem_write : std_logic_vector(wordSize-1 downto 0); + signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); + signal mem_writeEnable : std_logic; + signal mem_readEnable : std_logic; + signal mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal enable : std_logic; + + signal dram_mem_busy : std_logic; + signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_writeEnable : std_logic; + signal dram_mem_readEnable : std_logic; + signal dram_mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal io_busy : std_logic; + + signal io_mem_read : std_logic_vector(wordSize-1 downto 0); + signal io_mem_writeEnable : std_logic; + signal io_mem_readEnable : std_logic; + + signal dram_ready : std_logic; + signal io_ready : std_logic; + signal io_reading : std_logic; + signal interruptcounter : unsigned(15 downto 0); + signal interrupt : std_logic; + + signal break : std_logic; begin - zpu: zpu_core port map ( - clk => clk , - reset => areset, - enable => enable, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => interrupt, - break => break); - - - ioMap: zpu_io port map ( - clk => clk, - areset => areset, - busy => io_busy, - writeEnable => io_mem_writeEnable, - readEnable => io_mem_readEnable, - write => mem_write, - read => io_mem_read, - addr => mem_addr(maxAddrBit downto minAddrBit) - ); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); - io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy; - - - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(dram_mem_read, dram_ready, io_ready, io_mem_read) - begin - mem_read <= (others => 'U'); - if dram_ready='1' then - mem_read <= dram_mem_read; - end if; - - if io_ready='1' then - mem_read <= (others => '0'); - mem_read <= io_mem_read; - end if; - end process; - - - - io_ready <= (io_reading or io_mem_readEnable) and not io_busy; - - memoryControlSync: - process(clk, areset) - begin - if areset = '1' then - enable <= '0'; - io_reading <= '0'; - dram_ready <= '0'; - - interruptcounter <= to_unsigned(0, 16); - interrupt <= '0'; - - elsif (clk'event and clk = '1') then - enable <= '1'; - io_reading <= io_busy or io_mem_readEnable; - dram_ready<=dram_mem_readEnable; - - -- keep interrupt signal high for 16 cycles - interruptcounter <= interruptcounter + 1; - if (interruptcounter < 16) then - report "Interrupt asserted!" severity note; - interrupt <='1'; - else - interrupt <='0'; - end if; - end if; - end process; - - -- wiggle the clock @ 100MHz - clock : PROCESS - begin - clk <= '0'; - wait for 5 ns; - clk <= '1'; - wait for 5 ns; - areset <= '0'; - end PROCESS clock; - - -end behave; + zpu: zpu_core + port map ( + clk => clk, + reset => areset, + enable => enable, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => interrupt, + break => break + ); + + + ioMap: zpu_io + port map ( + clk => clk, + areset => areset, + busy => io_busy, + writeEnable => io_mem_writeEnable, + readEnable => io_mem_readEnable, + write => mem_write, + read => io_mem_read, + addr => mem_addr(maxAddrBit downto minAddrBit) + ); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); + io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); + mem_busy <= io_busy; + + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol: process(dram_mem_read, dram_ready, io_ready, io_mem_read) + begin + mem_read <= (others => 'U'); + if dram_ready='1' then + mem_read <= dram_mem_read; + end if; + + if io_ready='1' then + mem_read <= (others => '0'); + mem_read <= io_mem_read; + end if; + end process; + + + io_ready <= (io_reading or io_mem_readEnable) and not io_busy; + + memoryControlSync: process(clk, areset) + begin + if areset = '1' then + enable <= '0'; + io_reading <= '0'; + dram_ready <= '0'; + + interruptcounter <= to_unsigned(0, 16); + interrupt <= '0'; + + elsif rising_edge(clk) then + enable <= '1'; + io_reading <= io_busy or io_mem_readEnable; + dram_ready <= dram_mem_readEnable; + + -- keep interrupt signal high for 16 cycles + interruptcounter <= interruptcounter + 1; + if (interruptcounter < 16) then + report "Interrupt asserted!" severity note; + interrupt <='1'; + else + interrupt <='0'; + end if; + end if; + end process; + + -- wiggle the clock @ 100MHz + clock: process + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + areset <= '0'; + end process clock; + + +end architecture behave; diff --git a/zpu/hdl/example/sim_small_fpga_top_noint.vhd b/zpu/hdl/example/sim_small_fpga_top_noint.vhd index 1a83131..23b92cc 100644 --- a/zpu/hdl/example/sim_small_fpga_top_noint.vhd +++ b/zpu/hdl/example/sim_small_fpga_top_noint.vhd @@ -32,162 +32,153 @@ -- are those of the authors and should not be interpreted as representing -- official policies, either expressed or implied, of the ZPU Project. -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; +library ieee; +use ieee.std_logic_1164.all; use ieee.numeric_std.all; ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; - library work; use work.zpu_config.all; use work.zpupkg.all; + entity fpga_top is end fpga_top; -architecture behave of fpga_top is - - -signal clk : std_logic; - -signal areset : std_logic := '1'; - - -component zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end component; - - +architecture behave of fpga_top is -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal enable : std_logic; - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - -signal io_busy : std_logic; - -signal io_mem_read : std_logic_vector(wordSize-1 downto 0); -signal io_mem_writeEnable : std_logic; -signal io_mem_readEnable : std_logic; - - -signal dram_ready : std_logic; -signal io_ready : std_logic; -signal io_reading : std_logic; - - + signal clk : std_logic; + + signal areset : std_logic := '1'; + + + component zpu_io is + generic ( + log_file: string := "log.txt" + ); + port ( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); + end component; + + + signal mem_busy : std_logic; + signal mem_read : std_logic_vector(wordSize-1 downto 0); + signal mem_write : std_logic_vector(wordSize-1 downto 0); + signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); + signal mem_writeEnable : std_logic; + signal mem_readEnable : std_logic; + signal mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal enable : std_logic; + + signal dram_mem_busy : std_logic; + signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_writeEnable : std_logic; + signal dram_mem_readEnable : std_logic; + signal dram_mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal io_busy : std_logic; + + signal io_mem_read : std_logic_vector(wordSize-1 downto 0); + signal io_mem_writeEnable : std_logic; + signal io_mem_readEnable : std_logic; + + signal dram_ready : std_logic; + signal io_ready : std_logic; + signal io_reading : std_logic; + + signal break : std_logic; -signal break : std_logic; begin - zpu: zpu_core port map ( - clk => clk , - reset => areset, - enable => enable, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => '0', - break => break); - - - ioMap: zpu_io port map ( - clk => clk, - areset => areset, - busy => io_busy, - writeEnable => io_mem_writeEnable, - readEnable => io_mem_readEnable, - write => mem_write, - read => io_mem_read, - addr => mem_addr(maxAddrBit downto minAddrBit) - ); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); - io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy; - - - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(dram_mem_read, dram_ready, io_ready, io_mem_read) - begin - mem_read <= (others => 'U'); - if dram_ready='1' then - mem_read <= dram_mem_read; - end if; - - if io_ready='1' then - mem_read <= (others => '0'); - mem_read <= io_mem_read; - end if; - end process; - - - - io_ready <= (io_reading or io_mem_readEnable) and not io_busy; - - memoryControlSync: - process(clk, areset) - begin - if areset = '1' then - enable <= '0'; - io_reading <= '0'; - dram_ready <= '0'; - - elsif (clk'event and clk = '1') then - enable <= '1'; - io_reading <= io_busy or io_mem_readEnable; - dram_ready<=dram_mem_readEnable; - end if; - end process; - - -- wiggle the clock @ 100MHz - clock : PROCESS - begin - clk <= '0'; - wait for 5 ns; - clk <= '1'; - wait for 5 ns; - areset <= '0'; - end PROCESS clock; - - -end behave; + zpu: zpu_core + port map ( + clk => clk, + reset => areset, + enable => enable, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => '0', + break => break + ); + + + ioMap: zpu_io + port map ( + clk => clk, + areset => areset, + busy => io_busy, + writeEnable => io_mem_writeEnable, + readEnable => io_mem_readEnable, + write => mem_write, + read => io_mem_read, + addr => mem_addr(maxAddrBit downto minAddrBit) + ); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); + io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); + mem_busy <= io_busy; + + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol: process(dram_mem_read, dram_ready, io_ready, io_mem_read) + begin + mem_read <= (others => 'U'); + if dram_ready='1' then + mem_read <= dram_mem_read; + end if; + + if io_ready='1' then + mem_read <= (others => '0'); + mem_read <= io_mem_read; + end if; + end process; + + + + io_ready <= (io_reading or io_mem_readEnable) and not io_busy; + + memoryControlSync: process(clk, areset) + begin + if areset = '1' then + enable <= '0'; + io_reading <= '0'; + dram_ready <= '0'; + + elsif rising_edge(clk) then + enable <= '1'; + io_reading <= io_busy or io_mem_readEnable; + dram_ready <= dram_mem_readEnable; + end if; + end process; + + -- wiggle the clock @ 100MHz + clock: process + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + areset <= '0'; + end process clock; + + +end architecture behave; diff --git a/zpu/hdl/example_medium/sim_fpga_top.vhd b/zpu/hdl/example_medium/sim_fpga_top.vhd index a0819de..962caad 100644 --- a/zpu/hdl/example_medium/sim_fpga_top.vhd +++ b/zpu/hdl/example_medium/sim_fpga_top.vhd @@ -1,33 +1,46 @@ -------------------------------------------------------------------------------- --- Company: --- Engineer: +-- ZPU -- --- Create Date: 20:15:31 04/14/05 --- Design Name: --- Module Name: fpga_top - behave --- Project Name: --- Target Device: --- Tool versions: --- Description: --- --- Dependencies: +-- Copyright 2004-2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com +-- +-- The FreeBSD license +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: -- --- Revision: --- Revision 0.01 - File Created --- Additional Comments: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary 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. -- +-- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``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 +-- ZPU PROJECT 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. +-- +-- The views and conclusions contained in the software and documentation +-- are those of the authors and should not be interpreted as representing +-- official policies, either expressed or implied, of the ZPU Project. -------------------------------------------------------------------------------- -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; ----- Uncomment the following library declaration if instantiating ----- any Xilinx primitives in this code. ---library UNISIM; ---use UNISIM.VComponents.all; +library ieee; +use ieee.std_logic_1164.all; library work; use work.zpu_config.all; + entity fpga_top is end fpga_top; @@ -36,150 +49,146 @@ use work.zpupkg.all; architecture behave of fpga_top is -signal clk : std_logic; - -signal areset : std_logic := '1'; - - -component zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end component; - - - - - -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal enable : std_logic; - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - -signal io_busy : std_logic; - -signal io_mem_read : std_logic_vector(wordSize-1 downto 0); -signal io_mem_writeEnable : std_logic; -signal io_mem_readEnable : std_logic; - - -signal dram_ready : std_logic; -signal io_ready : std_logic; -signal io_reading : std_logic; - - -signal break : std_logic; + signal clk : std_logic; + + signal areset : std_logic := '1'; + + + component zpu_io is + generic ( + log_file: string := "log.txt" + ); + port ( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); + end component; + + + signal mem_busy : std_logic; + signal mem_read : std_logic_vector(wordSize-1 downto 0); + signal mem_write : std_logic_vector(wordSize-1 downto 0); + signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); + signal mem_writeEnable : std_logic; + signal mem_readEnable : std_logic; + signal mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal enable : std_logic; + + signal dram_mem_busy : std_logic; + signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_writeEnable : std_logic; + signal dram_mem_readEnable : std_logic; + signal dram_mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + + signal io_busy : std_logic; + + signal io_mem_read : std_logic_vector(wordSize-1 downto 0); + signal io_mem_writeEnable : std_logic; + signal io_mem_readEnable : std_logic; + + signal dram_ready : std_logic; + signal io_ready : std_logic; + signal io_reading : std_logic; + + signal break : std_logic; begin - zpu: zpu_core port map ( - clk => clk , - reset => areset, - enable => enable, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => '0', - break => break); - - dram_imp: dram port map ( - clk => clk , - areset => areset, - mem_busy => dram_mem_busy, - mem_read => dram_mem_read, - mem_write => mem_write, - mem_addr => mem_addr(maxAddrBit downto 0), - mem_writeEnable => dram_mem_writeEnable, - mem_readEnable => dram_mem_readEnable, - mem_writeMask => mem_writeMask); - - - ioMap: zpu_io port map ( - clk => clk, - areset => areset, - busy => io_busy, - writeEnable => io_mem_writeEnable, - readEnable => io_mem_readEnable, - write => mem_write(wordSize-1 downto 0), - read => io_mem_read, - addr => mem_addr(maxAddrBit downto minAddrBit) - ); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); - io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy or dram_mem_busy or io_busy; - - - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(dram_mem_read, dram_ready, io_ready, io_mem_read) - begin - mem_read <= (others => 'U'); - if dram_ready='1' then - mem_read <= dram_mem_read; - end if; - - if io_ready='1' then - mem_read <= io_mem_read; - end if; - end process; - - - io_ready <= (io_reading or io_mem_readEnable) and not io_busy; - - memoryControlSync: - process(clk, areset) - begin - if areset = '1' then - enable <= '0'; - io_reading <= '0'; - dram_ready <= '0'; - elsif (clk'event and clk = '1') then - enable <= '1'; - io_reading <= io_busy or io_mem_readEnable; - dram_ready<=dram_mem_readEnable; - - end if; - end process; - - -- wiggle the clock @ 100MHz - clock : PROCESS - begin - clk <= '0'; - wait for 5 ns; - clk <= '1'; - wait for 5 ns; - areset <= '0'; - end PROCESS clock; - - -end behave; + + zpu: zpu_core + port map ( + clk => clk, + reset => areset, + enable => enable, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => '0', + break => break + ); + + dram_imp: dram + port map ( + clk => clk , + areset => areset, + mem_busy => dram_mem_busy, + mem_read => dram_mem_read, + mem_write => mem_write, + mem_addr => mem_addr(maxAddrBit downto 0), + mem_writeEnable => dram_mem_writeEnable, + mem_readEnable => dram_mem_readEnable, + mem_writeMask => mem_writeMask + ); + + + ioMap: zpu_io + port map ( + clk => clk, + areset => areset, + busy => io_busy, + writeEnable => io_mem_writeEnable, + readEnable => io_mem_readEnable, + write => mem_write(wordSize-1 downto 0), + read => io_mem_read, + addr => mem_addr(maxAddrBit downto minAddrBit) + ); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_mem_writeEnable <= mem_writeEnable and mem_addr(ioBit); + io_mem_readEnable <= mem_readEnable and mem_addr(ioBit); + mem_busy <= io_busy or dram_mem_busy or io_busy; + + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol: process(dram_mem_read, dram_ready, io_ready, io_mem_read) + begin + mem_read <= (others => 'U'); + if dram_ready='1' then + mem_read <= dram_mem_read; + end if; + + if io_ready='1' then + mem_read <= io_mem_read; + end if; + end process; + + + io_ready <= (io_reading or io_mem_readEnable) and not io_busy; + + memoryControlSync: process(clk, areset) + begin + if areset = '1' then + enable <= '0'; + io_reading <= '0'; + dram_ready <= '0'; + elsif rising_edge(clk) then + enable <= '1'; + io_reading <= io_busy or io_mem_readEnable; + dram_ready <= dram_mem_readEnable; + end if; + end process; + + -- wiggle the clock @ 100MHz + clock : process + begin + clk <= '0'; + wait for 5 ns; + clk <= '1'; + wait for 5 ns; + areset <= '0'; + end process clock; + + +end architecture behave; diff --git a/zpu/hdl/zpu4/core/zpu_config.vhd b/zpu/hdl/zpu4/core/zpu_config.vhd index b29c561..c678044 100644 --- a/zpu/hdl/zpu4/core/zpu_config.vhd +++ b/zpu/hdl/zpu4/core/zpu_config.vhd @@ -1,58 +1,58 @@ --- ZPU --- --- Copyright 2004-2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com --- --- The FreeBSD license --- --- Redistribution and use in source and binary forms, with or without --- modification, are permitted provided that the following conditions --- are met: --- --- 1. Redistributions of source code must retain the above copyright --- notice, this list of conditions and the following disclaimer. --- 2. Redistributions in binary 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. --- --- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``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 --- ZPU PROJECT 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. --- --- The views and conclusions contained in the software and documentation --- are those of the authors and should not be interpreted as representing --- official policies, either expressed or implied, of the ZPU Project. - - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -package zpu_config is - - -- generate trace output or not. - constant Generate_Trace : boolean := false; - constant wordPower : integer := 5; - -- during simulation, set this to '0' to get matching trace.txt - constant DontCareValue : std_logic := 'X'; - -- Clock frequency in MHz. - constant ZPU_Frequency : std_logic_vector(7 downto 0) := x"64"; - -- This is the msb address bit. bytes=2^(maxAddrBitIncIO+1) - constant maxAddrBitIncIO : integer := 15; - constant maxAddrBitBRAM : integer := 14; - - -- start byte address of stack. - -- point to top of RAM - 2*words - constant spStart : std_logic_vector(maxAddrBitIncIO downto 0) := - std_logic_vector(to_unsigned((2**(maxAddrBitBRAM+1))-8, maxAddrBitIncIO+1)); - -end zpu_config; +-- ZPU
+--
+-- Copyright 2004-2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com
+--
+-- The FreeBSD license
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+--
+-- 1. Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary 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.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE ZPU PROJECT ``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
+-- ZPU PROJECT 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.
+--
+-- The views and conclusions contained in the software and documentation
+-- are those of the authors and should not be interpreted as representing
+-- official policies, either expressed or implied, of the ZPU Project.
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package zpu_config is
+
+ -- generate trace output or not.
+ constant Generate_Trace : boolean := false;
+ constant wordPower : integer := 5;
+ -- during simulation, set this to '0' to get matching trace.txt
+ constant DontCareValue : std_logic := 'X';
+ -- Clock frequency in MHz.
+ constant ZPU_Frequency : std_logic_vector(7 downto 0) := x"64";
+ -- This is the msb address bit. bytes=2^(maxAddrBitIncIO+1)
+ constant maxAddrBitIncIO : integer := 15;
+ constant maxAddrBitBRAM : integer := 14;
+
+ -- start byte address of stack.
+ -- point to top of RAM - 2*words
+ constant spStart : std_logic_vector(maxAddrBitIncIO downto 0) :=
+ std_logic_vector(to_unsigned((2**(maxAddrBitBRAM+1))-8, maxAddrBitIncIO+1));
+
+end zpu_config;
diff --git a/zpu/hdl/zpu4/src/clocks.vhd b/zpu/hdl/zpu4/src/clocks.vhd index 704d790..67433be 100644 --- a/zpu/hdl/zpu4/src/clocks.vhd +++ b/zpu/hdl/zpu4/src/clocks.vhd @@ -1,246 +1,198 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; +library ieee; +use ieee.std_logic_1164.all; + +library unisim; +use unisim.vcomponents.ibufg; +use unisim.vcomponents.srl16; +use unisim.vcomponents.dcm; +use unisim.vcomponents.bufg; -library UNISIM; -use UNISIM.vcomponents.all; entity clocks is - port ( areset : in std_logic; - cpu_clk_p : in std_logic; - sdr_clk_fb_p : in std_logic; - cpu_clk : out std_logic; - cpu_clk_2x : out std_logic; - cpu_clk_4x : out std_logic; - ddr_in_clk : out std_logic; - ddr_in_clk_2x : out std_logic; - locked : out std_logic_vector(2 downto 0)); -end clocks; + port ( + areset : in std_logic; + cpu_clk_p : in std_logic; + sdr_clk_fb_p : in std_logic; + cpu_clk : out std_logic; + cpu_clk_2x : out std_logic; + cpu_clk_4x : out std_logic; + ddr_in_clk : out std_logic; + ddr_in_clk_2x : out std_logic; + locked : out std_logic_vector(2 downto 0) + ); +end entity clocks; architecture behave of clocks is -signal low : std_logic; + signal low : std_logic; + -- + signal cpu_clk_in : std_logic; + signal sdr_clk_fb_in : std_logic; + -- + signal dcm_cpu1 : std_logic; + signal dcm_cpu2 : std_logic; + signal dcm_cpu2_dum : std_logic; + signal dcm_cpu4 : std_logic; + signal dcm_ddr2 : std_logic; + signal dcm_ddr2_2x : std_logic; + -- + signal cpu_clk_int : std_logic; + signal cpu_clk_2x_int : std_logic; + signal cpu_clk_2x_dum_int : std_logic; + signal cpu_clk_4x_int : std_logic; + signal ddr_in_clk_int : std_logic; + signal ddr_in_clk_2x_int : std_logic; + -- + signal dcm1_locked_del : std_logic; + signal dcm2_locked_del : std_logic; + signal dcm2_reset : std_logic; + signal dcm3_reset : std_logic; + -- + signal locked_int : std_logic_vector(2 downto 0); + signal del_addr : std_logic_vector(3 downto 0); + +begin -signal cpu_clk_in : std_logic; -signal sdr_clk_fb_in : std_logic; + low <= '0'; + del_addr <= "1111"; + -- + cpu_clk <= cpu_clk_int; + cpu_clk_2x <= cpu_clk_2x_int; + cpu_clk_4x <= cpu_clk_4x_int; + ddr_in_clk <= ddr_in_clk_int; + ddr_in_clk_2x <= ddr_in_clk_2x_int; + locked <= locked_int; -signal dcm_cpu1 : std_logic; -signal dcm_cpu2 : std_logic; -signal dcm_cpu2_dum : std_logic; -signal dcm_cpu4 : std_logic; -signal dcm_ddr2 : std_logic; -signal dcm_ddr2_2x : std_logic; -signal cpu_clk_int : std_logic; -signal cpu_clk_2x_int : std_logic; -signal cpu_clk_2x_dum_int : std_logic; -signal cpu_clk_4x_int : std_logic; -signal ddr_in_clk_int : std_logic; -signal ddr_in_clk_2x_int : std_logic; + cpu_ibufg : ibufg + port map ( + O => cpu_clk_in, + I => cpu_clk_p + ); -signal dcm1_locked_del : std_logic; -signal dcm2_locked_del : std_logic; -signal dcm2_reset : std_logic; -signal dcm3_reset : std_logic; + sdr_fb_ibufg : ibufg + port map ( + O => sdr_clk_fb_in, + I => sdr_clk_fb_p + ); -signal locked_int : std_logic_vector(2 downto 0); -signal del_addr : std_logic_vector(3 downto 0); + dcm2_rst : srl16 + generic map ( + init => x"0000" + ) + port map ( + Q => dcm1_locked_del, + A0 => del_addr(0), + A1 => del_addr(1), + A2 => del_addr(2), + A3 => del_addr(3), + CLK => cpu_clk_int, + D => locked_int(0) + ); -begin + dcm2_reset <= not(dcm1_locked_del); + + dcm3_rst : srl16 + generic map ( + init => x"0000" + ) + port map ( + Q => dcm2_locked_del, + A0 => del_addr(0), + A1 => del_addr(1), + A2 => del_addr(2), + A3 => del_addr(3), + CLK => cpu_clk_int, + D => locked_int(1) + ); + + dcm3_reset <= not(dcm2_locked_del); + + cpu1_dcm : + dcm generic map ( + clkin_period => 15.625, -- Specify period of input clock + factory_jf => X"8080" -- FACTORY JF Values + ) + port map ( + clk0 => dcm_cpu1, -- 0 degree DCM CLK ouptput + clk2x => dcm_cpu2, -- 2X DCM CLK output + locked => locked_int(0), -- DCM LOCK status output + clkfb => cpu_clk_int, -- DCM clock feedback + clkin => cpu_clk_in, -- Clock input (from IBUFG, BUFG or DCM) + psclk => low, -- Dynamic phase adjust clock input + psen => low, -- Dynamic phase adjust enable input + psincdec => low, -- Dynamic phase adjust increment/decrement + rst => areset -- DCM asynchronous reset input + ); + + cpu2_dcm : dcm + generic map ( + clkin_period => 7.8125, -- Specify period of input clock + factory_jf => X"8080" -- FACTORY JF Values + ) + port map ( + clk0 => dcm_cpu2_dum, -- 0 degree DCM CLK ouptput + clk2x => dcm_cpu4, -- 2X DCM CLK output + locked => locked_int(1), -- DCM LOCK status output + clkfb => cpu_clk_2x_dum_int, -- DCM clock feedback + clkin => cpu_clk_2x_int, -- Clock input (from IBUFG, BUFG or DCM) + psclk => low, -- Dynamic phase adjust clock input + psen => low, -- Dynamic phase adjust enable input + psincdec => low, -- Dynamic phase adjust increment/decrement + rst => dcm2_reset -- DCM asynchronous reset input + ); + + ddr_read_dcm : dcm + generic map ( + clkin_period => 7.8125, -- Specify period of input clock + clkout_phase_shift => "FIXED", -- Specify phase shift of NONE, FIXED or VARIABLE + factory_jf => X"8080", -- FACTORY JF Values + phase_shift => 103 -- Amount of fixed phase shift from -255 to 255 + ) + port map ( + clk0 => dcm_ddr2, -- 0 degree DCM CLK ouptput + clk2x => dcm_ddr2_2x, -- 2X DCM CLK output + locked => locked_int(2), -- DCM LOCK status output + clkfb => ddr_in_clk_int, -- DCM clock feedback + clkin => sdr_clk_fb_in, -- Clock input (from IBUFG, BUFG or DCM) + psclk => low, -- Dynamic phase adjust clock input + psen => low, -- Dynamic phase adjust enable input + psincdec => low, -- Dynamic phase adjust increment/decrement + rst => dcm3_reset -- DCM asynchronous reset input + ); + + cpu1 : bufg + port map ( + I => dcm_cpu1, + O => cpu_clk_int + ); + + cpu2 : bufg + port map ( + I => dcm_cpu2, + O => cpu_clk_2x_int + ); + + cpu2_dum : bufg + port map ( + i => dcm_cpu2_dum, + o => cpu_clk_2x_dum_int + ); + + cpu4 : bufg + port map ( + i => dcm_cpu4, + o => cpu_clk_4x_int + ); + + ddr_clk : bufg port map ( + i => dcm_ddr2, + o => ddr_in_clk_int + ); + + ddr_clk_2x : bufg port map ( + i => dcm_ddr2_2x, + o => ddr_in_clk_2x_int + ); - low <= '0'; - del_addr <= "1111"; - - cpu_clk <= cpu_clk_int; - cpu_clk_2x <= cpu_clk_2x_int; - cpu_clk_4x <= cpu_clk_4x_int; - ddr_in_clk <= ddr_in_clk_int; - ddr_in_clk_2x <= ddr_in_clk_2x_int; - locked <= locked_int; - - - CPU_IBUFG: - IBUFG port map ( - O => cpu_clk_in, - I => cpu_clk_p); - - SDR_FB_IBUFG: - IBUFG port map ( - O => sdr_clk_fb_in, - I => sdr_clk_fb_p); - - dcm2_rst: - SRL16 generic map ( - INIT => X"0000") - port map ( - Q => dcm1_locked_del, - A0 => del_addr(0), - A1 => del_addr(1), - A2 => del_addr(2), - A3 => del_addr(3), - CLK => cpu_clk_int, - D => locked_int(0)); - - dcm2_reset <= not(dcm1_locked_del); - - dcm3_rst: - SRL16 generic map ( - INIT => X"0000") - port map ( - Q => dcm2_locked_del, - A0 => del_addr(0), - A1 => del_addr(1), - A2 => del_addr(2), - A3 => del_addr(3), - CLK => cpu_clk_int, - D => locked_int(1)); - - dcm3_reset <= not(dcm2_locked_del); - - cpu1_dcm: - DCM generic map ( - CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 - CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 - CLKFX_MULTIPLY => 4, -- Can be any integer from 1 to 32 - CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature - CLKIN_PERIOD => 15.625, -- Specify period of input clock - CLKOUT_PHASE_SHIFT => "NONE", -- Specify phase shift of NONE, FIXED or VARIABLE - CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE, 1X or 2X - DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or - -- an integer from 0 to 15 - DFS_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for frequency synthesis - DLL_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for DLL - DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE - FACTORY_JF => X"8080", -- FACTORY JF Values - PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 255 - STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE - port map ( - CLK0 => dcm_cpu1, -- 0 degree DCM CLK ouptput - CLK180 => open, -- 180 degree DCM CLK output - CLK270 => open, -- 270 degree DCM CLK output - CLK2X => dcm_cpu2, -- 2X DCM CLK output - CLK2X180 => open, -- 2X, 180 degree DCM CLK out - CLK90 => open, -- 90 degree DCM CLK output - CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) - CLKFX => open, -- DCM CLK synthesis out (M/D) - CLKFX180 => open, -- 180 degree CLK synthesis out - LOCKED => locked_int(0), -- DCM LOCK status output - PSDONE => open, -- Dynamic phase adjust done output - STATUS => open, -- 8-bit DCM status bits output - CLKFB => cpu_clk_int, -- DCM clock feedback - CLKIN => cpu_clk_in, -- Clock input (from IBUFG, BUFG or DCM) - PSCLK => low, -- Dynamic phase adjust clock input - PSEN => low, -- Dynamic phase adjust enable input - PSINCDEC => low, -- Dynamic phase adjust increment/decrement - RST => areset); -- DCM asynchronous reset input - - cpu2_dcm: - DCM generic map ( - CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 - CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 - CLKFX_MULTIPLY => 4, -- Can be any integer from 1 to 32 - CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature - CLKIN_PERIOD => 7.8125, -- Specify period of input clock - CLKOUT_PHASE_SHIFT => "NONE", -- Specify phase shift of NONE, FIXED or VARIABLE - CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE, 1X or 2X - DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or - -- an integer from 0 to 15 - DFS_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for frequency synthesis - DLL_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for DLL - DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE - FACTORY_JF => X"8080", -- FACTORY JF Values - PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 255 - STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE - port map ( - CLK0 => dcm_cpu2_dum, -- 0 degree DCM CLK ouptput - CLK180 => open, -- 180 degree DCM CLK output - CLK270 => open, -- 270 degree DCM CLK output - CLK2X => dcm_cpu4, -- 2X DCM CLK output - CLK2X180 => open, -- 2X, 180 degree DCM CLK out - CLK90 => open, -- 90 degree DCM CLK output - CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) - CLKFX => open, -- DCM CLK synthesis out (M/D) - CLKFX180 => open, -- 180 degree CLK synthesis out - LOCKED => locked_int(1), -- DCM LOCK status output - PSDONE => open, -- Dynamic phase adjust done output - STATUS => open, -- 8-bit DCM status bits output - CLKFB => cpu_clk_2x_dum_int, -- DCM clock feedback - CLKIN => cpu_clk_2x_int, -- Clock input (from IBUFG, BUFG or DCM) - PSCLK => low, -- Dynamic phase adjust clock input - PSEN => low, -- Dynamic phase adjust enable input - PSINCDEC => low, -- Dynamic phase adjust increment/decrement - RST => dcm2_reset); -- DCM asynchronous reset input - - ddr_read_dcm: - DCM generic map ( - CLKDV_DIVIDE => 2.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5 - -- 7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0 - CLKFX_DIVIDE => 1, -- Can be any interger from 1 to 32 - CLKFX_MULTIPLY => 4, -- Can be any integer from 1 to 32 - CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature - CLKIN_PERIOD => 7.8125, -- Specify period of input clock - CLKOUT_PHASE_SHIFT => "FIXED", -- Specify phase shift of NONE, FIXED or VARIABLE --- CLKOUT_PHASE_SHIFT => "NONE", -- Specify phase shift of NONE, FIXED or VARIABLE - CLK_FEEDBACK => "1X", -- Specify clock feedback of NONE, 1X or 2X - DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or - -- an integer from 0 to 15 - DFS_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for frequency synthesis - DLL_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for DLL - DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE - FACTORY_JF => X"8080", -- FACTORY JF Values - PHASE_SHIFT => 103, -- Amount of fixed phase shift from -255 to 255 --- PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 255 - STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM LOCK, TRUE/FALSE - port map ( - CLK0 => dcm_ddr2, -- 0 degree DCM CLK ouptput - CLK180 => open, -- 180 degree DCM CLK output - CLK270 => open, -- 270 degree DCM CLK output - CLK2X => dcm_ddr2_2x, -- 2X DCM CLK output - CLK2X180 => open, -- 2X, 180 degree DCM CLK out - CLK90 => open, -- 90 degree DCM CLK output - CLKDV => open, -- Divided DCM CLK out (CLKDV_DIVIDE) - CLKFX => open, -- DCM CLK synthesis out (M/D) - CLKFX180 => open, -- 180 degree CLK synthesis out - LOCKED => locked_int(2), -- DCM LOCK status output - PSDONE => open, -- Dynamic phase adjust done output - STATUS => open, -- 8-bit DCM status bits output - CLKFB => ddr_in_clk_int, -- DCM clock feedback - CLKIN => sdr_clk_fb_in, -- Clock input (from IBUFG, BUFG or DCM) - PSCLK => low, -- Dynamic phase adjust clock input - PSEN => low, -- Dynamic phase adjust enable input - PSINCDEC => low, -- Dynamic phase adjust increment/decrement - RST => dcm3_reset); -- DCM asynchronous reset input - - cpu1: - BUFG port map ( - I => dcm_cpu1, - O => cpu_clk_int); - - cpu2: - BUFG port map ( - I => dcm_cpu2, - O => cpu_clk_2x_int); - - cpu2_dum: - BUFG port map ( - I => dcm_cpu2_dum, - O => cpu_clk_2x_dum_int); - - cpu4: - BUFG port map ( - I => dcm_cpu4, - O => cpu_clk_4x_int); - - ddr_clk: - BUFG port map ( - I => dcm_ddr2, - O => ddr_in_clk_int); - - ddr_clk_2x: - BUFG port map ( - I => dcm_ddr2_2x, - O => ddr_in_clk_2x_int); - -end behave;
\ No newline at end of file +end architecture behave; diff --git a/zpu/hdl/zpu4/src/io.vhd b/zpu/hdl/zpu4/src/io.vhd index f05b29b..56c7fb5 100644 --- a/zpu/hdl/zpu4/src/io.vhd +++ b/zpu/hdl/zpu4/src/io.vhd @@ -8,117 +8,112 @@ library work; use work.zpu_config.all; use work.zpupkg.all; use work.txt_util.all; - -entity zpu_io is - generic ( - log_file: string := "log.txt" - ); - port( - clk : in std_logic; - areset : in std_logic; - busy : out std_logic; - writeEnable : in std_logic; - readEnable : in std_logic; - write : in std_logic_vector(wordSize-1 downto 0); - read : out std_logic_vector(wordSize-1 downto 0); - addr : in std_logic_vector(maxAddrBit downto minAddrBit) - ); -end zpu_io; - - -architecture behave of zpu_io is +entity zpu_io is + generic ( + log_file : string := "log.txt" + ); + port( + clk : in std_logic; + areset : in std_logic; + busy : out std_logic; + writeEnable : in std_logic; + readEnable : in std_logic; + write : in std_logic_vector(wordSize-1 downto 0); + read : out std_logic_vector(wordSize-1 downto 0); + addr : in std_logic_vector(maxAddrBit downto minAddrBit) + ); +end entity zpu_io; -signal timer_read : std_logic_vector(7 downto 0); ---signal timer_write : std_logic_vector(7 downto 0); -signal timer_we : std_logic; -signal serving : std_logic; +architecture behave of zpu_io is -file l_file : TEXT open write_mode is log_file; -constant lowAddrBits: std_logic_vector(minAddrBit-1 downto 0) := (others=>'0'); -constant tx_full: std_logic := '0'; -constant rx_empty: std_logic := '1'; + signal timer_read : std_logic_vector(7 downto 0); + signal timer_we : std_logic; + -- + signal serving : std_logic; + -- + file l_file : text open write_mode is log_file; + constant lowAddrBits : std_logic_vector(minAddrBit-1 downto 0) := (others => '0'); + constant tx_full : std_logic := '0'; + constant rx_empty : std_logic := '1'; begin - - timerinst: timer port map ( - clk => clk, - areset => areset, - we => timer_we, - din => write(7 downto 0), - adr => addr(4 downto 2), - dout => timer_read); - - busy <= writeEnable or readEnable; - timer_we <= writeEnable and addr(12); - - process(areset, clk) - variable taddr : std_logic_vector(maxAddrBit downto 0); - -- pragma translate_off - variable line_out : line := new string'(""); - variable char : character; - -- pragma translate_on - begin - taddr := (others => '0'); - taddr(maxAddrBit downto minAddrBit) := addr; - - if (areset = '1') then --- timer_we <= '0'; - elsif (clk'event and clk = '1') then --- timer_we <= '0'; - if writeEnable = '1' then - -- external interface (fixed address) - --<JK> extend compare to avoid waring messages - if ("1" & addr & lowAddrBits)=x"80a000c" then - -- Write to UART - report "Write to UART[0]" & " :0x" & hstr(write); + + timerinst : timer + port map ( + clk => clk, + areset => areset, + we => timer_we, + din => write(7 downto 0), + adr => addr(4 downto 2), + dout => timer_read + ); + + busy <= writeEnable or readEnable; + timer_we <= writeEnable and addr(12); + + process(areset, clk) + variable taddr : std_logic_vector(maxAddrBit downto 0); + -- pragma translate_off + variable line_out : line := new string'(""); + variable char : character; + -- pragma translate_on + begin + taddr := (others => '0'); + taddr(maxAddrBit downto minAddrBit) := addr; + + if (areset = '1') then + elsif (clk'event and clk = '1') then + if writeEnable = '1' then + -- external interface (fixed address) + --<JK> extend compare to avoid waring messages + if ("1" & addr & lowAddrBits) = x"80a000c" then + -- Write to UART + report "Write to UART[0]" & " :0x" & hstr(write); -- pragma translate_off - char := character'val(to_integer(unsigned(write))); + char := character'val(to_integer(unsigned(write))); if char = lf then - std.textio.writeline( l_file, line_out); + std.textio.writeline(l_file, line_out); else - std.textio.write( line_out, char); + std.textio.write(line_out, char); end if; -- pragma translate_on - elsif addr(12)='1' then - report "Write to TIMER" & " :0x" & hstr(write); --- report "xxx" severity failure; --- timer_we <= '1'; + elsif addr(12) = '1' then + report "Write to TIMER" & " :0x" & hstr(write); - else - + else + report "Illegal IO write @" & "0x" & hstr(taddr) severity warning; - end if; - - end if; - read <= (others => '0'); - if (readEnable = '1') then - --<JK> extend compare to avoid waring messages - if ("1" & addr & lowAddrBits)=x"80a000c" then - report "Read UART[0]"; - read(8) <= not tx_full; -- output fifo not full - read(9) <= not rx_empty; -- receiver not empty - elsif ("1" & addr & lowAddrBits)=x"80a0010" then - report "Read UART[1]"; - read(8) <= not rx_empty; -- receiver not empty - read(7 downto 0) <= (others => '0'); - elsif addr(12)='1' then - report "Read TIMER"; - read(7 downto 0) <= timer_read; - elsif addr(11)='1' then - report "Read ZPU Freq"; - read(7 downto 0) <= ZPU_Frequency; - else - report "Illegal IO read @" & "0x" & hstr(taddr) severity warning; - end if; - end if; - end if; - end process; - - -end behave; - + end if; + + end if; + read <= (others => '0'); + if (readEnable = '1') then + --<JK> extend compare to avoid waring messages + if ("1" & addr & lowAddrBits) = x"80a000c" then + report "Read UART[0]"; + read(8) <= not tx_full; -- output fifo not full + read(9) <= not rx_empty; -- receiver not empty + elsif ("1" & addr & lowAddrBits) = x"80a0010" then + report "Read UART[1]"; + read(8) <= not rx_empty; -- receiver not empty + read(7 downto 0) <= (others => '0'); + elsif addr(12) = '1' then + report "Read TIMER"; + read(7 downto 0) <= timer_read; + elsif addr(11) = '1' then + report "Read ZPU Freq"; + read(7 downto 0) <= ZPU_Frequency; + else + report "Illegal IO read @" & "0x" & hstr(taddr) severity warning; + end if; + end if; + end if; + end process; + +end architecture behave; + diff --git a/zpu/hdl/zpu4/src/timer.vhd b/zpu/hdl/zpu4/src/timer.vhd index c60c172..d6d9358 100644 --- a/zpu/hdl/zpu4/src/timer.vhd +++ b/zpu/hdl/zpu4/src/timer.vhd @@ -1,61 +1,61 @@ library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; - + entity timer is - port( - clk : in std_logic; - areset : in std_logic; - we : in std_logic; - din : in std_logic_vector(7 downto 0); - adr : in std_logic_vector(2 downto 0); - dout : out std_logic_vector(7 downto 0)); -end timer; - - -architecture behave of timer is + port( + clk : in std_logic; + areset : in std_logic; + we : in std_logic; + din : in std_logic_vector(7 downto 0); + adr : in std_logic_vector(2 downto 0); + dout : out std_logic_vector(7 downto 0) + ); +end entity timer; -signal sample : std_logic; -signal reset : std_logic; +architecture behave of timer is -signal cnt : unsigned(63 downto 0); -signal cnt_smp : std_logic_vector(63 downto 0); + signal sample : std_logic; + signal reset : std_logic; + -- + signal cnt : unsigned(63 downto 0); + signal cnt_smp : std_logic_vector(63 downto 0); begin - reset <= '1' when (we = '1' and din(0) = '1') else '0'; - sample <= '1' when (we = '1' and din(1) = '1') else '0'; - - process(clk, areset) -- Carry generation - begin - if areset = '1' then - cnt <= (others => '0'); - cnt_smp <= (others => '0'); - elsif (clk'event and clk = '1') then - cnt <= cnt + 1; - if sample = '1' then --- report "sampling" severity failure; - cnt_smp <= std_logic_vector(cnt); - end if; - end if; - end process; - - - process(cnt_smp, adr) - begin - case adr is - when "000" => dout <= cnt_smp(7 downto 0); - when "001" => dout <= cnt_smp(15 downto 8); - when "010" => dout <= cnt_smp(23 downto 16); - when "011" => dout <= cnt_smp(31 downto 24); - when "100" => dout <= cnt_smp(39 downto 32); - when "101" => dout <= cnt_smp(47 downto 40); - when "110" => dout <= cnt_smp(55 downto 48); - when others => dout <= cnt_smp(63 downto 56); - end case; - end process; - - -end behave; - + reset <= '1' when (we = '1' and din(0) = '1') else '0'; + sample <= '1' when (we = '1' and din(1) = '1') else '0'; + + process(clk, areset) -- Carry generation + begin + if areset = '1' then + cnt <= (others => '0'); + cnt_smp <= (others => '0'); + elsif rising_edge(clk) then + cnt <= cnt + 1; + if sample = '1' then +-- report "sampling" severity failure; + cnt_smp <= std_logic_vector(cnt); + end if; + end if; + end process; + + + process(cnt_smp, adr) + begin + case adr is + when "000" => dout <= cnt_smp(7 downto 0); + when "001" => dout <= cnt_smp(15 downto 8); + when "010" => dout <= cnt_smp(23 downto 16); + when "011" => dout <= cnt_smp(31 downto 24); + when "100" => dout <= cnt_smp(39 downto 32); + when "101" => dout <= cnt_smp(47 downto 40); + when "110" => dout <= cnt_smp(55 downto 48); + when others => dout <= cnt_smp(63 downto 56); + end case; + end process; + + +end architecture behave; + diff --git a/zpu/hdl/zpu4/src/trace.vhd b/zpu/hdl/zpu4/src/trace.vhd index 00ac3a8..01678c8 100644 --- a/zpu/hdl/zpu4/src/trace.vhd +++ b/zpu/hdl/zpu4/src/trace.vhd @@ -42,76 +42,66 @@ library work; use work.zpu_config.all; use work.zpupkg.all; use work.txt_util.all; - - -entity trace is - generic ( - log_file: string := "trace.txt" - ); - port( - clk : in std_logic; - begin_inst : in std_logic; - pc : in std_logic_vector(maxAddrBitIncIO downto 0); - opcode : in std_logic_vector(7 downto 0); - sp : in std_logic_vector(maxAddrBitIncIO downto 2); - memA : in std_logic_vector(wordSize-1 downto 0); - memB : in std_logic_vector(wordSize-1 downto 0); - busy : in std_logic; - intSp : in std_logic_vector(stack_bits-1 downto 0) - ); -end trace; - - -architecture behave of trace is - - -file l_file : TEXT open write_mode is log_file; -begin +entity trace is + generic ( + log_file : string := "trace.txt" + ); + port( + clk : in std_logic; + begin_inst : in std_logic; + pc : in std_logic_vector(maxAddrBitIncIO downto 0); + opcode : in std_logic_vector(7 downto 0); + sp : in std_logic_vector(maxAddrBitIncIO downto 2); + memA : in std_logic_vector(wordSize-1 downto 0); + memB : in std_logic_vector(wordSize-1 downto 0); + busy : in std_logic; + intSp : in std_logic_vector(stack_bits-1 downto 0) + ); +end entity trace; --- write data and control information to a file +architecture behave of trace is + + file l_file : text open write_mode is log_file; -receive_data: process +begin -variable l: line; -variable t : std_logic_vector(wordSize-1 downto 0); -variable t2 : std_logic_vector(maxAddrBitIncIO downto 0); -variable counter : unsigned(63 downto 0); - - - -begin + -- write data and control information to a file + receive_data : process + variable l : line; + variable t : std_logic_vector(wordSize-1 downto 0); + variable t2 : std_logic_vector(maxAddrBitIncIO downto 0); + variable counter : unsigned(63 downto 0); + begin - t:= (others => '0'); - t2:= (others => '0'); + t := (others => '0'); + t2 := (others => '0'); -counter := (others => '0'); - -- print header for the logfile - print(l_file, "#pc,opcode,sp,top_of_stack "); - print(l_file, "#----------"); - print(l_file, " "); + counter := (others => '0'); - wait until clk = '1'; - wait until clk = '0'; + -- print header for the logfile + print(l_file, "#pc,opcode,sp,top_of_stack "); + print(l_file, "#----------"); + print(l_file, " "); - while true loop + wait until clk = '1'; + wait until clk = '0'; - counter := counter + 1; - if begin_inst = '1' then - t(maxAddrBitIncIO downto 2):=sp; - t2:=pc; - print(l_file, "0x" & hstr(t2) & " 0x" & hstr(opcode) & " 0x" & hstr(t) & " 0x" & hstr(memA) & " 0x" & hstr(memB) & " 0x" & hstr(intSp) & " 0x" & hstr(std_logic_vector(counter))); - end if; - - wait until clk = '0'; - - end loop; + while true loop - end process receive_data; + counter := counter + 1; + if begin_inst = '1' then + t(maxAddrBitIncIO downto 2) := sp; + t2 := pc; + print(l_file, "0x" & hstr(t2) & " 0x" & hstr(opcode) & " 0x" & hstr(t) & " 0x" & hstr(memA) & " 0x" & hstr(memB) & " 0x" & hstr(intSp) & " 0x" & hstr(std_logic_vector(counter))); + end if; + wait until clk = '0'; + + end loop; + end process receive_data; +end architecture behave; -end behave; - diff --git a/zpu/hdl/zpu4/src/txt_util.vhd b/zpu/hdl/zpu4/src/txt_util.vhd index 6432294..4dca901 100644 --- a/zpu/hdl/zpu4/src/txt_util.vhd +++ b/zpu/hdl/zpu4/src/txt_util.vhd @@ -36,586 +36,504 @@ library ieee; use ieee.std_logic_1164.all; use std.textio.all; -library work; package txt_util is -- prints a message to the screen - procedure print(text: string); + procedure print(text : string); -- prints the message when active -- useful for debug switches - procedure print(active: boolean; text: string); + procedure print(active : boolean; text : string); -- converts std_logic into a character - function chr(sl: std_logic) return character; + function chr(sl : std_logic) return character; -- converts std_logic into a string (1 to 1) - function str(sl: std_logic) return string; + function str(sl : std_logic) return string; -- converts std_logic_vector into a string (binary base) - function str(slv: std_logic_vector) return string; + function str(slv : std_logic_vector) return string; -- converts boolean into a string - function str(b: boolean) return string; + function str(b : boolean) return string; -- converts an integer into a single character -- (can also be used for hex conversion and other bases) - function chr(int: integer) return character; + function chr(int : integer) return character; -- converts integer into string using specified base - function str(int: integer; base: integer) return string; + function str(int : integer; base : integer) return string; -- converts integer to string, using base 10 - function str(int: integer) return string; + function str(int : integer) return string; -- convert std_logic_vector into a string in hex format - function hstr(slv: std_logic_vector) return string; + function hstr(slv : std_logic_vector) return string; -- functions to manipulate strings ----------------------------------- -- convert a character to upper case - function to_upper(c: character) return character; + function to_upper(c : character) return character; -- convert a character to lower case - function to_lower(c: character) return character; + function to_lower(c : character) return character; -- convert a string to upper case - function to_upper(s: string) return string; + function to_upper(s : string) return string; -- convert a string to lower case - function to_lower(s: string) return string; + function to_lower(s : string) return string; + + - - -- functions to convert strings into other formats -------------------------------------------------- - + -- converts a character into std_logic - function to_std_logic(c: character) return std_logic; - + function to_std_logic(c : character) return std_logic; + -- converts a string into std_logic_vector - function to_std_logic_vector(s: string) return std_logic_vector; + function to_std_logic_vector(s : string) return std_logic_vector; + - -- file I/O ----------- - - -- read variable length string from input file - procedure str_read(file in_file: TEXT; - res_string: out string); - - -- print string to a file and start new line - procedure print(file out_file: TEXT; - new_string: in string); - - -- print character to a file and start new line - procedure print(file out_file: TEXT; - char: in character); - -end txt_util; - + -- read variable length string from input file + procedure str_read(file in_file : text; res_string : out string); + -- print string to a file and start new line + procedure print(file out_file : text; new_string : in string); -package body txt_util is + -- print character to a file and start new line + procedure print(file out_file : text; char : in character); +end package txt_util; - -- prints text to the screen - procedure print(text: string) is - variable msg_line: line; - begin - write(msg_line, text); - writeline(output, msg_line); - end print; +package body txt_util is + -- prints text to the screen + procedure print(text : string) is + variable msg_line : line; + begin + write(msg_line, text); + writeline(output, msg_line); + end procedure print; - -- prints text to the screen when active + -- prints text to the screen when active + procedure print(active : boolean; text : string) is + begin + if active then + print(text); + end if; + end procedure print; - procedure print(active: boolean; text: string) is - begin - if active then - print(text); - end if; - end print; + -- converts std_logic into a character + function chr(sl : std_logic) return character is + variable c : character; + begin + case sl is + when 'U' => c := 'U'; + when 'X' => c := 'X'; + when '0' => c := '0'; + when '1' => c := '1'; + when 'Z' => c := 'Z'; + when 'W' => c := 'W'; + when 'L' => c := 'L'; + when 'H' => c := 'H'; + when '-' => c := '-'; + end case; + return c; + end function chr; - -- converts std_logic into a character - function chr(sl: std_logic) return character is - variable c: character; - begin - case sl is - when 'U' => c:= 'U'; - when 'X' => c:= 'X'; - when '0' => c:= '0'; - when '1' => c:= '1'; - when 'Z' => c:= 'Z'; - when 'W' => c:= 'W'; - when 'L' => c:= 'L'; - when 'H' => c:= 'H'; - when '-' => c:= '-'; - end case; - return c; - end chr; - - - - -- converts std_logic into a string (1 to 1) - - function str(sl: std_logic) return string is - variable s: string(1 to 1); + -- converts std_logic into a string (1 to 1) + function str(sl : std_logic) return string is + variable s : string(1 to 1); begin s(1) := chr(sl); return s; - end str; + end function str; + -- converts std_logic_vector into a string (binary base) + -- (this also takes care of the fact that the range of + -- a string is natural while a std_logic_vector may + -- have an integer range) + function str(slv : std_logic_vector) return string is + variable result : string (1 to slv'length); + variable r : integer; + begin + r := 1; + for i in slv'range loop + result(r) := chr(slv(i)); + r := r + 1; + end loop; + return result; + end function str; - -- converts std_logic_vector into a string (binary base) - -- (this also takes care of the fact that the range of - -- a string is natural while a std_logic_vector may - -- have an integer range) - - function str(slv: std_logic_vector) return string is - variable result : string (1 to slv'length); - variable r : integer; - begin - r := 1; - for i in slv'range loop - result(r) := chr(slv(i)); - r := r + 1; - end loop; - return result; - end str; - - - function str(b: boolean) return string is + function str(b : boolean) return string is + begin + if b then + return "true"; + else + return "false"; + end if; + end function str; + + + -- converts an integer into a character + -- for 0 to 9 the obvious mapping is used, higher + -- values are mapped to the characters A-Z + -- (this is usefull for systems with base > 10) + -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) + function chr(int : integer) return character is + variable c : character; begin - if b then - return "true"; - else - return "false"; - end if; - end str; - - - -- converts an integer into a character - -- for 0 to 9 the obvious mapping is used, higher - -- values are mapped to the characters A-Z - -- (this is usefull for systems with base > 10) - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function chr(int: integer) return character is - variable c: character; - begin case int is - when 0 => c := '0'; - when 1 => c := '1'; - when 2 => c := '2'; - when 3 => c := '3'; - when 4 => c := '4'; - when 5 => c := '5'; - when 6 => c := '6'; - when 7 => c := '7'; - when 8 => c := '8'; - when 9 => c := '9'; - when 10 => c := 'A'; - when 11 => c := 'B'; - when 12 => c := 'C'; - when 13 => c := 'D'; - when 14 => c := 'E'; - when 15 => c := 'F'; - when 16 => c := 'G'; - when 17 => c := 'H'; - when 18 => c := 'I'; - when 19 => c := 'J'; - when 20 => c := 'K'; - when 21 => c := 'L'; - when 22 => c := 'M'; - when 23 => c := 'N'; - when 24 => c := 'O'; - when 25 => c := 'P'; - when 26 => c := 'Q'; - when 27 => c := 'R'; - when 28 => c := 'S'; - when 29 => c := 'T'; - when 30 => c := 'U'; - when 31 => c := 'V'; - when 32 => c := 'W'; - when 33 => c := 'X'; - when 34 => c := 'Y'; - when 35 => c := 'Z'; - when others => c := '?'; + when 0 => c := '0'; + when 1 => c := '1'; + when 2 => c := '2'; + when 3 => c := '3'; + when 4 => c := '4'; + when 5 => c := '5'; + when 6 => c := '6'; + when 7 => c := '7'; + when 8 => c := '8'; + when 9 => c := '9'; + when 10 => c := 'A'; + when 11 => c := 'B'; + when 12 => c := 'C'; + when 13 => c := 'D'; + when 14 => c := 'E'; + when 15 => c := 'F'; + when 16 => c := 'G'; + when 17 => c := 'H'; + when 18 => c := 'I'; + when 19 => c := 'J'; + when 20 => c := 'K'; + when 21 => c := 'L'; + when 22 => c := 'M'; + when 23 => c := 'N'; + when 24 => c := 'O'; + when 25 => c := 'P'; + when 26 => c := 'Q'; + when 27 => c := 'R'; + when 28 => c := 'S'; + when 29 => c := 'T'; + when 30 => c := 'U'; + when 31 => c := 'V'; + when 32 => c := 'W'; + when 33 => c := 'X'; + when 34 => c := 'Y'; + when 35 => c := 'Z'; + when others => c := '?'; end case; return c; - end chr; - - - - -- convert integer to string using specified base - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function str(int: integer; base: integer) return string is - - variable temp: string(1 to 10); - variable num: integer; - variable abs_int: integer; - variable len: integer := 1; - variable power: integer := 1; - - begin + end function chr; - -- bug fix for negative numbers - abs_int := abs(int); - num := abs_int; - - while num >= base loop -- Determine how many - len := len + 1; -- characters required - num := num / base; -- to represent the - end loop ; -- number. - - for i in len downto 1 loop -- Convert the number to - temp(i) := chr(abs_int/power mod base); -- a string starting - power := power * base; -- with the right hand - end loop ; -- side. - - -- return result and add sign if required - if int < 0 then - return '-'& temp(1 to len); - else - return temp(1 to len); - end if; - - end str; - - - -- convert integer to string, using base 10 - function str(int: integer) return string is + -- convert integer to string using specified base + -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) + function str(int : integer; base : integer) return string is + variable temp : string(1 to 10); + variable num : integer; + variable abs_int : integer; + variable len : integer := 1; + variable power : integer := 1; + begin - begin + -- bug fix for negative numbers + abs_int := abs(int); - return str(int, 10) ; + num := abs_int; - end str; + while num >= base loop -- Determine how many + len := len + 1; -- characters required + num := num / base; -- to represent the + end loop; -- number. + for i in len downto 1 loop -- Convert the number to + temp(i) := chr(abs_int/power mod base); -- a string starting + power := power * base; -- with the right hand + end loop; -- side. + -- return result and add sign if required + if int < 0 then + return '-'& temp(1 to len); + else + return temp(1 to len); + end if; - -- converts a std_logic_vector into a hex string. - function hstr(slv: std_logic_vector) return string is - variable hexlen: integer; - variable longslv : std_logic_vector(67 downto 0) := (others => '0'); - variable hex : string(1 to 16); - variable fourbit : std_logic_vector(3 downto 0); - begin - hexlen := (slv'left+1)/4; - if (slv'left+1) mod 4 /= 0 then - hexlen := hexlen + 1; - end if; - longslv(slv'left downto 0) := slv; - for i in (hexlen -1) downto 0 loop - fourbit := longslv(((i*4)+3) downto (i*4)); - case fourbit is - when "0000" => hex(hexlen -I) := '0'; - when "0001" => hex(hexlen -I) := '1'; - when "0010" => hex(hexlen -I) := '2'; - when "0011" => hex(hexlen -I) := '3'; - when "0100" => hex(hexlen -I) := '4'; - when "0101" => hex(hexlen -I) := '5'; - when "0110" => hex(hexlen -I) := '6'; - when "0111" => hex(hexlen -I) := '7'; - when "1000" => hex(hexlen -I) := '8'; - when "1001" => hex(hexlen -I) := '9'; - when "1010" => hex(hexlen -I) := 'A'; - when "1011" => hex(hexlen -I) := 'B'; - when "1100" => hex(hexlen -I) := 'C'; - when "1101" => hex(hexlen -I) := 'D'; - when "1110" => hex(hexlen -I) := 'E'; - when "1111" => hex(hexlen -I) := 'F'; - when "ZZZZ" => hex(hexlen -I) := 'z'; - when "UUUU" => hex(hexlen -I) := 'u'; - when "XXXX" => hex(hexlen -I) := 'x'; - when others => hex(hexlen -I) := '?'; - end case; - end loop; - return hex(1 to hexlen); - end hstr; + end function str; + -- convert integer to string, using base 10 + function str(int : integer) return string is + begin + return str(int, 10); + end function str; - -- functions to manipulate strings - ----------------------------------- + -- converts a std_logic_vector into a hex string. + function hstr(slv : std_logic_vector) return string is + variable hexlen : integer; + variable longslv : std_logic_vector(67 downto 0) := (others => '0'); + variable hex : string(1 to 16); + variable fourbit : std_logic_vector(3 downto 0); + begin + hexlen := (slv'left+1)/4; + if (slv'left+1) mod 4 /= 0 then + hexlen := hexlen + 1; + end if; + longslv(slv'left downto 0) := slv; + for i in (hexlen -1) downto 0 loop + fourbit := longslv(((i*4)+3) downto (i*4)); + case fourbit is + when "0000" => hex(hexlen -I) := '0'; + when "0001" => hex(hexlen -I) := '1'; + when "0010" => hex(hexlen -I) := '2'; + when "0011" => hex(hexlen -I) := '3'; + when "0100" => hex(hexlen -I) := '4'; + when "0101" => hex(hexlen -I) := '5'; + when "0110" => hex(hexlen -I) := '6'; + when "0111" => hex(hexlen -I) := '7'; + when "1000" => hex(hexlen -I) := '8'; + when "1001" => hex(hexlen -I) := '9'; + when "1010" => hex(hexlen -I) := 'A'; + when "1011" => hex(hexlen -I) := 'B'; + when "1100" => hex(hexlen -I) := 'C'; + when "1101" => hex(hexlen -I) := 'D'; + when "1110" => hex(hexlen -I) := 'E'; + when "1111" => hex(hexlen -I) := 'F'; + when "ZZZZ" => hex(hexlen -I) := 'z'; + when "UUUU" => hex(hexlen -I) := 'u'; + when "XXXX" => hex(hexlen -I) := 'x'; + when others => hex(hexlen -I) := '?'; + end case; + end loop; + return hex(1 to hexlen); + end function hstr; - -- convert a character to upper case - function to_upper(c: character) return character is - variable u: character; + -- functions to manipulate strings + ----------------------------------- + -- convert a character to upper case + function to_upper(c : character) return character is + variable u : character; begin + case c is + when 'a' => u := 'A'; + when 'b' => u := 'B'; + when 'c' => u := 'C'; + when 'd' => u := 'D'; + when 'e' => u := 'E'; + when 'f' => u := 'F'; + when 'g' => u := 'G'; + when 'h' => u := 'H'; + when 'i' => u := 'I'; + when 'j' => u := 'J'; + when 'k' => u := 'K'; + when 'l' => u := 'L'; + when 'm' => u := 'M'; + when 'n' => u := 'N'; + when 'o' => u := 'O'; + when 'p' => u := 'P'; + when 'q' => u := 'Q'; + when 'r' => u := 'R'; + when 's' => u := 'S'; + when 't' => u := 'T'; + when 'u' => u := 'U'; + when 'v' => u := 'V'; + when 'w' => u := 'W'; + when 'x' => u := 'X'; + when 'y' => u := 'Y'; + when 'z' => u := 'Z'; + when others => u := c; + end case; + return u; + end function to_upper; - case c is - when 'a' => u := 'A'; - when 'b' => u := 'B'; - when 'c' => u := 'C'; - when 'd' => u := 'D'; - when 'e' => u := 'E'; - when 'f' => u := 'F'; - when 'g' => u := 'G'; - when 'h' => u := 'H'; - when 'i' => u := 'I'; - when 'j' => u := 'J'; - when 'k' => u := 'K'; - when 'l' => u := 'L'; - when 'm' => u := 'M'; - when 'n' => u := 'N'; - when 'o' => u := 'O'; - when 'p' => u := 'P'; - when 'q' => u := 'Q'; - when 'r' => u := 'R'; - when 's' => u := 'S'; - when 't' => u := 'T'; - when 'u' => u := 'U'; - when 'v' => u := 'V'; - when 'w' => u := 'W'; - when 'x' => u := 'X'; - when 'y' => u := 'Y'; - when 'z' => u := 'Z'; - when others => u := c; - end case; - - return u; - - end to_upper; - - - -- convert a character to lower case - - function to_lower(c: character) return character is - - variable l: character; + -- convert a character to lower case + function to_lower(c : character) return character is + variable l : character; begin + case c is + when 'A' => l := 'a'; + when 'B' => l := 'b'; + when 'C' => l := 'c'; + when 'D' => l := 'd'; + when 'E' => l := 'e'; + when 'F' => l := 'f'; + when 'G' => l := 'g'; + when 'H' => l := 'h'; + when 'I' => l := 'i'; + when 'J' => l := 'j'; + when 'K' => l := 'k'; + when 'L' => l := 'l'; + when 'M' => l := 'm'; + when 'N' => l := 'n'; + when 'O' => l := 'o'; + when 'P' => l := 'p'; + when 'Q' => l := 'q'; + when 'R' => l := 'r'; + when 'S' => l := 's'; + when 'T' => l := 't'; + when 'U' => l := 'u'; + when 'V' => l := 'v'; + when 'W' => l := 'w'; + when 'X' => l := 'x'; + when 'Y' => l := 'y'; + when 'Z' => l := 'z'; + when others => l := c; + end case; + return l; + end function to_lower; - case c is - when 'A' => l := 'a'; - when 'B' => l := 'b'; - when 'C' => l := 'c'; - when 'D' => l := 'd'; - when 'E' => l := 'e'; - when 'F' => l := 'f'; - when 'G' => l := 'g'; - when 'H' => l := 'h'; - when 'I' => l := 'i'; - when 'J' => l := 'j'; - when 'K' => l := 'k'; - when 'L' => l := 'l'; - when 'M' => l := 'm'; - when 'N' => l := 'n'; - when 'O' => l := 'o'; - when 'P' => l := 'p'; - when 'Q' => l := 'q'; - when 'R' => l := 'r'; - when 'S' => l := 's'; - when 'T' => l := 't'; - when 'U' => l := 'u'; - when 'V' => l := 'v'; - when 'W' => l := 'w'; - when 'X' => l := 'x'; - when 'Y' => l := 'y'; - when 'Z' => l := 'z'; - when others => l := c; - end case; - - return l; - - end to_lower; - - - - -- convert a string to upper case - function to_upper(s: string) return string is + -- convert a string to upper case + function to_upper(s : string) return string is + variable uppercase : string (s'range); + begin - variable uppercase: string (s'range); + for i in s'range loop + uppercase(i) := to_upper(s(i)); + end loop; + return uppercase; - begin + end function to_upper; - for i in s'range loop - uppercase(i):= to_upper(s(i)); - end loop; - return uppercase; - end to_upper; + -- convert a string to lower case + function to_lower(s : string) return string is + variable lowercase : string (s'range); + begin + for i in s'range loop + lowercase(i) := to_lower(s(i)); + end loop; + return lowercase; + end function to_lower; - -- convert a string to lower case + -- functions to convert strings into other types + ------------------------------------------------ - function to_lower(s: string) return string is + -- converts a character into a std_logic + function to_std_logic(c : character) return std_logic is + variable sl : std_logic; + begin + case c is + when 'U' => + sl := 'U'; + when 'X' => + sl := 'X'; + when '0' => + sl := '0'; + when '1' => + sl := '1'; + when 'Z' => + sl := 'Z'; + when 'W' => + sl := 'W'; + when 'L' => + sl := 'L'; + when 'H' => + sl := 'H'; + when '-' => + sl := '-'; + when others => + sl := 'X'; + end case; + return sl; + end function to_std_logic; - variable lowercase: string (s'range); - begin + -- converts a string into std_logic_vector + function to_std_logic_vector(s : string) return std_logic_vector is + variable slv : std_logic_vector(s'high-s'low downto 0); + variable k : integer; + begin + k := s'high-s'low; + for i in s'range loop + slv(k) := to_std_logic(s(i)); + k := k - 1; + end loop; + return slv; + end function to_std_logic_vector; - for i in s'range loop - lowercase(i):= to_lower(s(i)); - end loop; - return lowercase; - end to_lower; + -- file I/O + ------------- + -- read variable length string from input file + procedure str_read(file in_file : text; res_string : out string) is + variable l : line; + variable c : character; + variable is_string : boolean; + begin + readline(in_file, l); + -- clear the contents of the result string + for i in res_string'range loop + res_string(i) := ' '; + end loop; + -- read all characters of the line, up to the length + -- of the results string + for i in res_string'range loop + read(l, c, is_string); + res_string(i) := c; + if not is_string then -- found end of line + exit; + end if; + end loop; + end procedure str_read; + + + -- print string to a file + procedure print(file out_file : text; new_string : in string) is + variable l : line; + begin + write(l, new_string); + writeline(out_file, l); + end procedure print; --- functions to convert strings into other types + -- print character to a file and start new line + procedure print(file out_file : text; char : in character) is + variable l : line; + begin + write(l, char); + writeline(out_file, l); + end procedure print; --- converts a character into a std_logic -function to_std_logic(c: character) return std_logic is - variable sl: std_logic; + -- appends contents of a string to a file until line feed occurs + -- (LF is considered to be the end of the string) + procedure str_write(file out_file : text; new_string : in string) is begin - case c is - when 'U' => - sl := 'U'; - when 'X' => - sl := 'X'; - when '0' => - sl := '0'; - when '1' => - sl := '1'; - when 'Z' => - sl := 'Z'; - when 'W' => - sl := 'W'; - when 'L' => - sl := 'L'; - when 'H' => - sl := 'H'; - when '-' => - sl := '-'; - when others => - sl := 'X'; - end case; - return sl; - end to_std_logic; - - --- converts a string into std_logic_vector - -function to_std_logic_vector(s: string) return std_logic_vector is - variable slv: std_logic_vector(s'high-s'low downto 0); - variable k: integer; -begin - k := s'high-s'low; - for i in s'range loop - slv(k) := to_std_logic(s(i)); - k := k - 1; - end loop; - return slv; -end to_std_logic_vector; - - - - - - ----------------- --- file I/O -- ----------------- - - - --- read variable length string from input file - -procedure str_read(file in_file: TEXT; - res_string: out string) is - - variable l: line; - variable c: character; - variable is_string: boolean; - - begin - - readline(in_file, l); - -- clear the contents of the result string - for i in res_string'range loop - res_string(i) := ' '; - end loop; - -- read all characters of the line, up to the length - -- of the results string - for i in res_string'range loop - read(l, c, is_string); - res_string(i) := c; - if not is_string then -- found end of line - exit; - end if; - end loop; - -end str_read; - - --- print string to a file -procedure print(file out_file: TEXT; - new_string: in string) is - - variable l: line; - - begin - - write(l, new_string); - writeline(out_file, l); - -end print; - - --- print character to a file and start new line -procedure print(file out_file: TEXT; - char: in character) is - - variable l: line; - - begin - - write(l, char); - writeline(out_file, l); - -end print; - - - --- appends contents of a string to a file until line feed occurs --- (LF is considered to be the end of the string) - -procedure str_write(file out_file: TEXT; - new_string: in string) is - begin - - for i in new_string'range loop - print(out_file, new_string(i)); - if new_string(i) = LF then -- end of string - exit; - end if; - end loop; - -end str_write; - - - - -end txt_util; - + for i in new_string'range loop + print(out_file, new_string(i)); + if new_string(i) = LF then -- end of string + exit; + end if; + end loop; + end procedure str_write; +end package body txt_util; diff --git a/zpu/hdl/zpu4/src/zpuio.vhd b/zpu/hdl/zpu4/src/zpuio.vhd index 2c7fd41..9ca9050 100644 --- a/zpu/hdl/zpu4/src/zpuio.vhd +++ b/zpu/hdl/zpu4/src/zpuio.vhd @@ -1,232 +1,218 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.STD_LOGIC_UNSIGNED.ALL; +library ieee; +use ieee.std_logic_1164.all; library work; use work.zpu_config.all; use work.zpupkg.all; entity zpuio is - port ( areset : in std_logic; - cpu_clk : in std_logic; - clk_status : in std_logic_vector(2 downto 0); - cpu_din : in std_logic_vector(15 downto 0); - cpu_a : in std_logic_vector(20 downto 0); - cpu_we : in std_logic_vector(1 downto 0); - cpu_re : in std_logic; - cpu_dout : inout std_logic_vector(15 downto 0)); + port ( + areset : in std_logic; + cpu_clk : in std_logic; + clk_status : in std_logic_vector(2 downto 0); + cpu_din : in std_logic_vector(15 downto 0); + cpu_a : in std_logic_vector(20 downto 0); + cpu_we : in std_logic_vector(1 downto 0); + cpu_re : in std_logic; + cpu_dout : inout std_logic_vector(15 downto 0) + ); end zpuio; architecture behave of zpuio is -signal timer_read : std_logic_vector(7 downto 0); ---signal timer_write : std_logic_vector(7 downto 0); -signal timer_we : std_logic; - - -signal io_busy : std_logic; -signal io_read : std_logic_vector(7 downto 0); ---signal io_write : std_logic_vector(7 downto 0); -signal io_addr : std_logic_vector(maxAddrBit downto minAddrBit); -signal io_writeEnable : std_logic; -signal Enable : std_logic; - -signal din : std_logic_vector(7 downto 0); -signal dout : std_logic_vector(7 downto 0); -signal adr : std_logic_vector(15 downto 0); -signal break : std_logic; -signal we : std_logic; -signal re : std_logic; - - --- uart forwarding... - -signal uartTXPending : std_logic; -signal uartTXCleared : std_logic; -signal uartData : std_logic_vector(7 downto 0); - -signal readingTimer : std_logic; - - - - -signal mem_busy : std_logic; -signal mem_read : std_logic_vector(wordSize-1 downto 0); -signal mem_write : std_logic_vector(wordSize-1 downto 0); -signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); -signal mem_writeEnable : std_logic; -signal mem_readEnable : std_logic; -signal mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - -signal dram_mem_busy : std_logic; -signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); -signal dram_mem_writeEnable : std_logic; -signal dram_mem_readEnable : std_logic; -signal dram_mem_writeMask: std_logic_vector(wordBytes-1 downto 0); - - - ---signal io_mem_read : std_logic_vector(7 downto 0); ---signal io_mem_writeEnable : std_logic; ---signal io_mem_readEnable : std_logic; -signal io_readEnable : std_logic; - - -signal dram_read : std_logic; - - + signal timer_read : std_logic_vector(7 downto 0); + signal timer_we : std_logic; + -- + signal io_busy : std_logic; + signal io_read : std_logic_vector(7 downto 0); + signal io_addr : std_logic_vector(maxAddrBit downto minAddrBit); + signal io_writeEnable : std_logic; + signal Enable : std_logic; + -- + signal din : std_logic_vector(7 downto 0); + signal dout : std_logic_vector(7 downto 0); + signal adr : std_logic_vector(15 downto 0); + signal break : std_logic; + signal we : std_logic; + signal re : std_logic; + -- + -- uart forwarding... + signal uartTXPending : std_logic; + signal uartTXCleared : std_logic; + signal uartData : std_logic_vector(7 downto 0); + -- + signal readingTimer : std_logic; + -- + -- + signal mem_busy : std_logic; + signal mem_read : std_logic_vector(wordSize-1 downto 0); + signal mem_write : std_logic_vector(wordSize-1 downto 0); + signal mem_addr : std_logic_vector(maxAddrBitIncIO downto 0); + signal mem_writeEnable : std_logic; + signal mem_readEnable : std_logic; + signal mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + -- + signal dram_mem_busy : std_logic; + signal dram_mem_read : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_write : std_logic_vector(wordSize-1 downto 0); + signal dram_mem_writeEnable : std_logic; + signal dram_mem_readEnable : std_logic; + signal dram_mem_writeMask : std_logic_vector(wordBytes-1 downto 0); + -- + signal io_readEnable : std_logic; + -- + signal dram_read : std_logic; begin - io_addr <= mem_addr(maxAddrBit downto minAddrBit); - - timerinst: timer port map ( - clk => cpu_clk, - areset => areset, - we => timer_we, - din => mem_write(7 downto 0), - adr => io_addr(4 downto 2), - dout => timer_read); - - zpu: zpu_core port map ( - clk => cpu_clk , - areset => areset, - in_mem_busy => mem_busy, - mem_read => mem_read, - mem_write => mem_write, - out_mem_addr => mem_addr, - out_mem_writeEnable => mem_writeEnable, - out_mem_readEnable => mem_readEnable, - mem_writeMask => mem_writeMask, - interrupt => '0', - break => break); - - -ram_imp: dram port map ( - clk => cpu_clk , - areset => areset, - mem_busy => dram_mem_busy, - mem_read => dram_mem_read, - mem_write => mem_write, - mem_addr => mem_addr(maxAddrBit downto 0), - mem_writeEnable => dram_mem_writeEnable, - mem_readEnable => dram_mem_readEnable, - mem_writeMask => mem_writeMask); - - - - fauxUart: - process(cpu_clk, areset) - begin - if areset = '1' then - io_busy <= '0'; - uartTXPending <= '0'; - timer_we <= '0'; - io_busy <= '0'; - uartData <= x"58"; -- 'X' - readingTimer <= '0'; - elsif (cpu_clk'event and cpu_clk = '1') then - timer_we <= '0'; - io_busy <= '0'; - if uartTXCleared = '1' then - uartTXPending <= '0'; - end if; - - if io_writeEnable = '1' then - if io_addr=x"2028003" then - -- Write to UART - uartData <= mem_write(7 downto 0); - uartTXPending <= '1'; - io_busy <= '1'; - elsif io_addr(12)='1' then - timer_we <= '1'; - io_busy <= '1'; - else --- report "Illegal IO write" severity failure; - end if; - end if; - if (io_readEnable = '1') then - if io_addr=x"2028003" then - io_read <= (0=>'1', -- recieve empty - 1 => uartTXPending, -- tx full - others => '0'); - io_busy <= '1'; - elsif io_addr(12)='1' then - readingTimer <= '1'; - io_busy <= '1'; - elsif io_addr(11)='1' then - io_read <= ZPU_Frequency; - io_busy <= '1'; - else --- report "Illegal IO read" severity failure; - end if; - - else - if (readingTimer = '1') then - readingTimer <= '0'; - io_read <= timer_read; - io_busy <= '0'; - else - io_read <= (others => '1'); - end if; - end if; - end if; - end process; - - - forwardUARTOutputToARM: - process(cpu_clk, areset) - begin - if areset = '1' then - uartTXCleared <= '0'; - elsif (cpu_clk = '1' and cpu_clk'event) then - if cpu_we(0) = '1' and cpu_a(3 downto 1) = "000" then - uartTXCleared <= cpu_din(0); - else - uartTXCleared <= uartTXCleared; - end if; - end if; - end process; - - cpu_dout(7 downto 0) <= uartData when (cpu_re = '1' and cpu_a(3 downto 1) = "001") else (others => 'Z'); - cpu_dout <= (0 => uartTXPending, others => '0') when (cpu_re = '1' and cpu_a(3 downto 1) = "000") else (others => 'Z'); - - dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); - dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); - io_writeEnable <= mem_writeEnable and mem_addr(ioBit); --- io_readEnable <= mem_readEnable and mem_addr(ioBit); - mem_busy <= io_busy or dram_mem_busy or dram_read or io_readEnable; - - -- Memory reads either come from IO or DRAM. We need to pick the right one. - memorycontrol: - process(cpu_clk, areset) - begin - if areset = '1' then - dram_read <= '0'; - io_readEnable <= '0'; - - - elsif (cpu_clk'event and cpu_clk = '1') then - mem_read <= (others => '0'); - if mem_addr(ioBit)='0' and mem_readEnable='1' then - dram_read <= '1'; - end if; - if dram_read='1' and dram_mem_busy='0' then - dram_read <= '0'; - mem_read <= dram_mem_read; - end if; - - if mem_addr(ioBit)='1' and mem_readEnable='1' then - io_readEnable <= '1'; - end if; - if io_readEnable='1' and io_busy='0' then - io_readEnable <= '0'; - mem_read(7 downto 0) <= io_read; - end if; - - end if; - end process; - - -end behave; + io_addr <= mem_addr(maxAddrBit downto minAddrBit); + + timerinst : timer + port map ( + clk => cpu_clk, + areset => areset, + we => timer_we, + din => mem_write(7 downto 0), + adr => io_addr(4 downto 2), + dout => timer_read + ); + + zpu : zpu_core + port map ( + clk => cpu_clk , + areset => areset, + in_mem_busy => mem_busy, + mem_read => mem_read, + mem_write => mem_write, + out_mem_addr => mem_addr, + out_mem_writeEnable => mem_writeEnable, + out_mem_readEnable => mem_readEnable, + mem_writeMask => mem_writeMask, + interrupt => '0', + break => break + ); + + + ram_imp : dram + port map ( + clk => cpu_clk, + areset => areset, + mem_busy => dram_mem_busy, + mem_read => dram_mem_read, + mem_write => mem_write, + mem_addr => mem_addr(maxAddrBit downto 0), + mem_writeEnable => dram_mem_writeEnable, + mem_readEnable => dram_mem_readEnable, + mem_writeMask => mem_writeMask + ); + + + fauxUart : process(cpu_clk, areset) + begin + if areset = '1' then + io_busy <= '0'; + uartTXPending <= '0'; + timer_we <= '0'; + io_busy <= '0'; + uartData <= x"58"; -- 'X' + readingTimer <= '0'; + elsif rising_edge(cpu_clk) then + timer_we <= '0'; + io_busy <= '0'; + if uartTXCleared = '1' then + uartTXPending <= '0'; + end if; + + if io_writeEnable = '1' then + if io_addr = x"2028003" then + -- Write to UART + uartData <= mem_write(7 downto 0); + uartTXPending <= '1'; + io_busy <= '1'; + elsif io_addr(12) = '1' then + timer_we <= '1'; + io_busy <= '1'; + else + -- report "Illegal IO write" severity failure; + end if; + end if; + if (io_readEnable = '1') then + if io_addr = x"2028003" then + io_read <= (0 => '1', -- recieve empty + 1 => uartTXPending, -- tx full + others => '0'); + io_busy <= '1'; + elsif io_addr(12) = '1' then + readingTimer <= '1'; + io_busy <= '1'; + elsif io_addr(11) = '1' then + io_read <= ZPU_Frequency; + io_busy <= '1'; + else + -- report "Illegal IO read" severity failure; + end if; + + else + if (readingTimer = '1') then + readingTimer <= '0'; + io_read <= timer_read; + io_busy <= '0'; + else + io_read <= (others => '1'); + end if; + end if; + end if; + end process; + + + forwardUARTOutputToARM : process(cpu_clk, areset) + begin + if areset = '1' then + uartTXCleared <= '0'; + elsif rising_edge(cpu_clkt) then + if cpu_we(0) = '1' and cpu_a(3 downto 1) = "000" then + uartTXCleared <= cpu_din(0); + else + uartTXCleared <= uartTXCleared; + end if; + end if; + end process; + + cpu_dout(7 downto 0) <= uartData when (cpu_re = '1' and cpu_a(3 downto 1) = "001") else (others => 'Z'); + cpu_dout <= (0 => uartTXPending, others => '0') when (cpu_re = '1' and cpu_a(3 downto 1) = "000") else (others => 'Z'); + + dram_mem_writeEnable <= mem_writeEnable and not mem_addr(ioBit); + dram_mem_readEnable <= mem_readEnable and not mem_addr(ioBit); + io_writeEnable <= mem_writeEnable and mem_addr(ioBit); + mem_busy <= io_busy or dram_mem_busy or dram_read or io_readEnable; + + -- Memory reads either come from IO or DRAM. We need to pick the right one. + memorycontrol : process(cpu_clk, areset) + begin + if areset = '1' then + dram_read <= '0'; + io_readEnable <= '0'; + + elsif rising_edge(cpu_clk) then + mem_read <= (others => '0'); + if mem_addr(ioBit) = '0' and mem_readEnable = '1' then + dram_read <= '1'; + end if; + if dram_read = '1' and dram_mem_busy = '0' then + dram_read <= '0'; + mem_read <= dram_mem_read; + end if; + + if mem_addr(ioBit) = '1' and mem_readEnable = '1' then + io_readEnable <= '1'; + end if; + if io_readEnable = '1' and io_busy = '0' then + io_readEnable <= '0'; + mem_read(7 downto 0) <= io_read; + end if; + + end if; + end process; + + +end architecture behave; |