From 210cb9d974fa7bb593ea606394abcdbf7e8b8a0e Mon Sep 17 00:00:00 2001 From: Philip Smart Date: Wed, 23 Oct 2019 14:14:42 +0100 Subject: [PATCH] Tidying --- build/QMV_zpu.qsf | 1 - build/QMV_zpu.qws | Bin 619 -> 0 bytes cpu/zpu_core_evo.vhd | 110 +++++++++---- cpu/zpu_pkg.vhd | 43 +---- cpu/zpu_uart_debug.vhd | 32 +++- devices/sysbus/BRAM/rom_prologue.vhd | 2 +- devices/sysbus/RAM/dpram.vhd | 17 +- devices/sysbus/spi/spi.vhd | 33 +++- devices/sysbus/timer/timer_controller.vhd | 190 +++++++++++++--------- devices/sysbus/uart/uart.vhd | 6 +- zpu_soc.vhd | 41 ++--- zpu_soc_pkg.vhd | 178 +++++--------------- 12 files changed, 315 insertions(+), 338 deletions(-) delete mode 100644 build/QMV_zpu.qws diff --git a/build/QMV_zpu.qsf b/build/QMV_zpu.qsf index d327644..72353ed 100644 --- a/build/QMV_zpu.qsf +++ b/build/QMV_zpu.qsf @@ -359,5 +359,4 @@ set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulati -set_global_assignment -name SLD_FILE db/stp1_auto_stripped.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/build/QMV_zpu.qws b/build/QMV_zpu.qws deleted file mode 100644 index 6306e220d786954fc191f5087bcffbc5b513e82f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 619 zcmbV}F;2rk5JkToij=fS6ch+qNJdEr5_E`yiYh{)M8S3-GGG&oC=e$gci|vuXgLcZ z@Mf?p5EATa_Rp+mXWp*&BQ;}Hmm2C;l}>f9LKEdgC3}goIw?Sp^q^Eb>SLyC4#Ah?FPaM z!URoSb7vkCox@Ny=cgP>j06p+2D2=gq7BGpgYw1ToWCm1ut|4 z{lrqOtOJ|RSk@s&GY~8#QT|hsftf`bXbkJce>(YlP-NYq%HL7R`-a+L%P2OvV^QDn e>hEQ?g4dT>^RKLp)H "", @@ -544,10 +597,10 @@ begin -- Memory transaction processor MXP. ------------------------------------ -- The mxp localises all memory/io operations into a single process. This aids in adaptation to differing bus topolgies as only this process - -- needs updating (the local INSN bus uses BRAM so direct connection). This logic processes a queue of transactions in fifo order and fetches instructions - -- as required.. The processor unit commits requests to the queue and this logic fulfills them. If the CPU is only using one bus for all memory and IO - -- operations then memory transactions in the queue are completed before instruction fetches. If the instruction queue is empty then the processor will - -- stall until instructions are fetched. + -- needs updating (the local INSN bus uses a direct BRAM/ROM connection and bypasses the MXP). This logic processes a queue of transactions in fifo + -- order and fetches instructions as required.. The processor unit commits requests to the queue and this logic fulfills them. If the CPU is only + -- using one bus for all memory and IO operations then memory transactions in the queue are completed before instruction fetches. If the instruction + -- queue is empty then the processor will stall until instructions are fetched. -- MEMXACT: process(CLK, ZPURESET, TOS, NOS, debugState) begin @@ -625,7 +678,7 @@ begin WB_STB_O <= '0'; end if; --- WB_ERR_I needs handling. + -- TODO: WB_ERR_I needs better handling, should retry at least once and then issue a BREAK. if IMPL_USE_WB_BUS = true and WB_ERR_I = '1' then wbXactActive <= '0'; WB_CYC_O <= '0'; @@ -1131,12 +1184,8 @@ begin cacheL2StartAddr <= cacheL2StartAddr + 16; end if; - -- if pc(ADDR_32BIT_RANGE) > cacheL2FetchIdx(ADDR_32BIT_RANGE) and (pc(ADDR_32BIT_RANGE) - cacheL2FetchIdx(ADDR_32BIT_RANGE)) < 256 and cacheL2Full = '1' then - -- cacheL2StartAddr <= cacheL2StartAddr + 256; - -- end if; - -- If the PC goes out of scope of L2 data, reset and start fetching a fresh from the current PC address. - if cacheL2Invalid = '1' then --pc(ADDR_32BIT_RANGE) < cacheL2StartAddr(ADDR_32BIT_RANGE) or ((pc(ADDR_32BIT_RANGE) > cacheL2FetchIdx(ADDR_32BIT_RANGE))) then -- and (pc(ADDR_32BIT_RANGE) - cacheL2FetchIdx(ADDR_32BIT_RANGE)) >= 256) then + if cacheL2Invalid = '1' then cacheL2FetchIdx <= pc(ADDR_32BIT_RANGE) & "00"; cacheL2StartAddr <= pc(ADDR_32BIT_RANGE) & "00"; cacheL2Write <= '0'; @@ -1145,10 +1194,6 @@ begin mxState <= MemXact_Idle; end if; end if; - - -- Do nothing if PC overshoots data we have fetched upto threshold, takes longer to reset and reread and then we waste potential instructions that will be jumped back to. - if pc(ADDR_32BIT_RANGE) >= cacheL2FetchIdx(ADDR_32BIT_RANGE) and (pc(ADDR_32BIT_RANGE) - cacheL2FetchIdx(ADDR_32BIT_RANGE)) < 512 then - end if; end if; end if; end process; @@ -1358,9 +1403,9 @@ begin l1State <= State_PreSetAddr; end case; - -- If there is only a set number of instructions remaining in the cache then we need to creeep the start address forward. - -- We do this to ensure as many past instructions are available for backward jumps which are most common in C. Adjust the threshold - -- if forward jumps are more common. + -- If there is only a set number of instructions remaining in the cache then we need to creep the start address forward so that + -- more instructions are fetched and decoded. We do this to ensure as many past instructions are available for backward jumps which + -- are most common in C. Adjust the threshold if forward jumps are more common. elsif cacheL1InsnAfterPC < 8 and cacheL1Full = '1' then cacheL1StartAddr <= cacheL1StartAddr + 8; end if; @@ -1724,10 +1769,11 @@ begin debugRec.STACK_NOS <= std_logic_vector(muxNOS.word); debugLoad <= '1'; end if; --- --- USE cacheL1InsnAfterPC in this loop to preserve logic. --- Same for extended instructions. --- + + -- TODO: + -- Perhaps use cacheL1InsnAfterPC in this loop to preserve logic. + -- Same for extended instructions. + -- -- 5 Consecutive IM's if cacheL1FetchIdx - pc > 5 and cacheL1(to_integer(pc))(7) = '1' and cacheL1(to_integer(pc)+1)(7) = '1' and cacheL1(to_integer(pc)+2)(7) = '1' and cacheL1(to_integer(pc)+3)(7) = '1' and cacheL1(to_integer(pc)+4)(7) = '1' and cacheL1(to_integer(pc)+5)(7) = '0' then TOS.word(31 downto 0) <= unsigned(cacheL1(to_integer(pc))(3 downto 0)) & unsigned(cacheL1(to_integer(pc)+1)(OPCODE_IM_RANGE)) & unsigned(cacheL1(to_integer(pc)+2)(OPCODE_IM_RANGE)) & unsigned(cacheL1(to_integer(pc)+3)(OPCODE_IM_RANGE)) & unsigned(cacheL1(to_integer(pc)+4)(OPCODE_IM_RANGE)); @@ -2543,6 +2589,7 @@ begin tInsnExec := '1'; -- For instructions which use a parameter, build the value ready for use. + -- TODO: This should be variables to meet the 1 cycle requirement or set during decode. case cacheL1(to_integer(pc)+1)(OPCODE_PARAM_RANGE) is when "00" => insnExParameter <= X"00000000"; when "01" => insnExParameter <= X"000000" & unsigned(cacheL1(to_integer(pc)+2)(OPCODE_RANGE)); @@ -2553,7 +2600,7 @@ begin -- Decode the extended instruction at this point as we have access to 8 future instructions or bytes so can work out what is required and execute. -- 1:0 = 00 means an instruction which operates with a default, byte, half-word or word parameter. ie. Extend,,[,,,] - -- Memory fill instruction. Fill memory starting at address in NOSwith zero, 8 bit, 16 or 32 bit repeating value for TOS bytes. + -- Memory fill instruction. Fill memory starting at address in NOS with zero, 8 bit, 16 or 32 bit repeating value for TOS bytes. if cacheL1(to_integer(pc)+1)(OPCODE_INSN_RANGE) = Opcode_Ex_Fill then end if; @@ -2590,7 +2637,7 @@ begin end if; end if; - -- Breakpoint, this is not a mornal instruction and used by debuggers to suspend a program exection. At the moment + -- Breakpoint, this is not a nornal instruction and used by debuggers to suspend a program exection. At the moment -- this instuction sets the BREAK flag and just continues. when Insn_Break => tInsnExec := '1'; @@ -3202,7 +3249,6 @@ begin debugRec.FMT_PRE_CR <= '1'; debugRec.FMT_SPLIT_DATA <= "01"; if debugPC = debugPC_EndAddr or debugPC_WidthCounter = debugPC_Width-4 then ---if debugPC = debugPC_EndAddr or debugPC = debugPC_WidthdebugPC(4 downto 2) = "111" then debugRec.FMT_POST_CRLF <= '1'; debugPC_WidthCounter <= 0; else diff --git a/cpu/zpu_pkg.vhd b/cpu/zpu_pkg.vhd index 2c09832..99f358f 100644 --- a/cpu/zpu_pkg.vhd +++ b/cpu/zpu_pkg.vhd @@ -117,7 +117,7 @@ package zpu_pkg is --mem_writeMask interrupt_request : in std_logic; interrupt_ack : out std_logic; -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine. - interrupt_done : out std_logic; -- Interrupt service routine completed/done. : out std_logic_vector(wordBytes-1 downto 0); + interrupt_done : out std_logic; -- Interrupt service routine completed/done. break : out std_logic; debug_txd : out std_logic; -- Debug serial output. -- @@ -287,8 +287,10 @@ package zpu_pkg is INT_REQ : in std_logic; INT_ACK : out std_logic; -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine. INT_DONE : out std_logic; -- Interrupt service routine completed/done. - BREAK : out std_logic; - DEBUG_TXD : out std_logic -- Debug serial output. + -- Break and debug signals. + BREAK : out std_logic; -- A break instruction encountered. + CONTINUE : in std_logic; -- When break activated, processing stops. Setting CONTINUE to logic 1 resumes processing with next instruction. + DEBUG_TXD : out std_logic -- Debug serial output. ); end component zpu_core_evo; @@ -319,41 +321,6 @@ package zpu_pkg is ); end component; - component signed_divider is - port ( - clk : in std_logic; - ena : in std_logic; - z : in unsigned(63 downto 0); - d : in unsigned(WORD_32BIT_RANGE); - q : out signed(63 downto 0); - s : out signed(63 downto 0) - ); - end component; - - component unsigned_divider is - port ( - clk : in std_logic; - ena : in std_logic; - z : in unsigned(63 downto 0); - d : in unsigned(WORD_32BIT_RANGE); - q : out unsigned(WORD_32BIT_RANGE); - s : out unsigned(WORD_32BIT_RANGE); - div0 : out std_logic; - ovf : out std_logic - ); - end component; - - component qdiv is - port ( - dividend : in signed(WORD_32BIT_RANGE); - divisor : in signed(WORD_32BIT_RANGE); - start : in std_logic; - clk : in std_logic; - quotient_out : out signed(WORD_32BIT_RANGE); - complete : out std_logic - ); - end component; - ------------------------------------------------------------ -- constants ------------------------------------------------------------ diff --git a/cpu/zpu_uart_debug.vhd b/cpu/zpu_uart_debug.vhd index 40ed60a..155f81c 100644 --- a/cpu/zpu_uart_debug.vhd +++ b/cpu/zpu_uart_debug.vhd @@ -1,10 +1,40 @@ +--------------------------------------------------------------------------------------------------------- +-- +-- Name: zpu_uart_debug.vhd +-- Created: January 2019 +-- Author(s): Philip Smart +-- Description: An extension of the simplistic UART Tx, still fixed at 8N1 with configurable baud rate +-- but adding a debug serialisaztion FSM for output of ZPU runtime data. +-- Credits: Originally using the simplistic UART as a guide, which was written by the following +-- authors:- +-- Philippe Carton, philippe.carton2 libertysurf.fr +-- Juan Pablo Daniel Borgna, jpdborgna gmail.com +-- Salvador E. Tropea, salvador inti.gob.ar +-- Copyright: (c) 2019 Philip Smart +-- +-- History: January 2019 - Initial module written using the simplistic UART as a guide but +-- adding cache and debug serialisation FSM. +-- +--------------------------------------------------------------------------------------------------------- +-- This source file is free software: you can redistribute it and-or modify +-- it under the terms of the GNU General Public License as published +-- by the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This source file is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +--------------------------------------------------------------------------------------------------------- library ieee; library pkgs; library work; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.zpu_pkg.all; ---use work.zpu_soc_pkg.all; -- Based on the simplistic UART, handles 8N1 RS232 Rx/Tx with independent programmable baud rate and selectable FIFO buffers. entity zpu_uart_debug is diff --git a/devices/sysbus/BRAM/rom_prologue.vhd b/devices/sysbus/BRAM/rom_prologue.vhd index 04c0da4..502e700 100644 --- a/devices/sysbus/BRAM/rom_prologue.vhd +++ b/devices/sysbus/BRAM/rom_prologue.vhd @@ -1,7 +1,7 @@ -- ZPU -- -- Copyright 2004-2008 oharboe - �yvind Harboe - oyvind.harboe@zylin.com --- Modified by Alastair M. Robinson for the ZPUFlex project. +-- Modified by Philip Smart 02/2019 for the ZPU Evo implementation. -- -- The FreeBSD license -- diff --git a/devices/sysbus/RAM/dpram.vhd b/devices/sysbus/RAM/dpram.vhd index 6bd162c..339374e 100644 --- a/devices/sysbus/RAM/dpram.vhd +++ b/devices/sysbus/RAM/dpram.vhd @@ -2,7 +2,7 @@ -- -- Name: dpram.vhd -- Created: January 2019 --- Author(s): Altera/Intel - refactored by Philip Smart for the ZPU Evo +-- Author(s): Altera/Intel Quartus II - refactored by Philip Smart for the ZPU Evo -- Description: Dual Port RAM as provided by Altera in the Megafunctions suite. -- -- Credits: @@ -11,19 +11,6 @@ -- History: January 2019 - Initial module taken and refactored, customizing for the ZPU Evo. -- --------------------------------------------------------------------------------------------------------- --- This source file is free software: you can redistribute it and-or modify --- it under the terms of the GNU General Public License as published --- by the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This source file is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . ---------------------------------------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; @@ -164,6 +151,4 @@ BEGIN q_b => sub_wire1 ); - - END SYN; diff --git a/devices/sysbus/spi/spi.vhd b/devices/sysbus/spi/spi.vhd index 22b7b3b..6a0527e 100644 --- a/devices/sysbus/spi/spi.vhd +++ b/devices/sysbus/spi/spi.vhd @@ -1,6 +1,37 @@ -- Adapted by AMR from the Chameleon Minimig cfide.vhd file, -- originally by Tobias Gubener. - +-- +-- 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. +-- +-- -- spi_to_host contains data received from slave device. -- Busy bit now has a signal of its own. diff --git a/devices/sysbus/timer/timer_controller.vhd b/devices/sysbus/timer/timer_controller.vhd index d8ebcbe..0b61772 100644 --- a/devices/sysbus/timer/timer_controller.vhd +++ b/devices/sysbus/timer/timer_controller.vhd @@ -1,3 +1,37 @@ +-- 32bit prescaled Timer +-- +-- Original Author unknown. +-- Updated for ZPU SoC use: Philip Smart, 2019. +-- +-- 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; @@ -8,92 +42,90 @@ library work; entity timer_controller is generic( - prescale : integer := 1; -- Prescale incoming clock - timers : integer := 0 -- This is a power of 2, so zero means 1 counter, 4 means 16 counters... - ); + prescale : integer := 1; -- Prescale incoming clock + timers : integer := 0 -- This is a power of 2, so zero means 1 counter, 4 means 16 counters... + ); port ( - clk : in std_logic; - reset : in std_logic; -- active low + clk : in std_logic; + reset : in std_logic; -- active low - reg_addr_in : in std_logic_vector(7 downto 0); -- from host CPU - reg_data_in: in std_logic_vector(31 downto 0); - reg_rw : in std_logic; - reg_req : in std_logic; + reg_addr_in : in std_logic_vector(7 downto 0); -- from host CPU + reg_data_in : in std_logic_vector(31 downto 0); + reg_rw : in std_logic; + reg_req : in std_logic; - ticks : out std_logic_vector(2**timers-1 downto 0) - ); + ticks : out std_logic_vector(2**timers-1 downto 0) + ); end entity; - + architecture rtl of timer_controller is - constant prescale_adj : integer := prescale-1; - signal prescale_counter : unsigned(15 downto 0); - signal prescaled_tick : std_logic; - type timer_counters is array (2**timers-1 downto 0) of unsigned(31 downto 0); - signal timer_counter : timer_counters; - signal timer_limit : timer_counters; - signal timer_enabled : std_logic_vector(2**timers-1 downto 0); - signal timer_index : unsigned(7 downto 0); + constant prescale_adj : integer := prescale-1; + signal prescale_counter : unsigned(15 downto 0); + signal prescaled_tick : std_logic; + type timer_counters is array (2**timers-1 downto 0) of unsigned(31 downto 0); + signal timer_counter : timer_counters; + signal timer_limit : timer_counters; + signal timer_enabled : std_logic_vector(2**timers-1 downto 0); + signal timer_index : unsigned(7 downto 0); begin - -- Prescaled tick - process(clk, reset) - begin - if reset='0' then - prescale_counter<=(others=>'0'); - elsif rising_edge(clk) then - prescaled_tick<='0'; - prescale_counter<=prescale_counter-1; - if prescale_counter=X"00" then - prescaled_tick<='1'; - prescale_counter<=to_unsigned(prescale_adj,16); - end if; - end if; - end process; + -- Prescaled tick + process(clk, reset) + begin + if reset='0' then + prescale_counter <=(others => '0'); + elsif rising_edge(clk) then + prescaled_tick <='0'; + prescale_counter <=prescale_counter-1; + if prescale_counter=X"00" then + prescaled_tick <='1'; + prescale_counter <=to_unsigned(prescale_adj,16); + end if; + end if; + end process; - -- The timers proper; - process(clk,reset) - begin - if reset='0' then - for I in 0 to (2**timers-1) loop - timer_counter(I)<=(others => '0'); - end loop; - elsif rising_edge(clk) then - ticks<=(others => '0'); - if prescaled_tick='1' then - for I in 0 to (2**timers-1) loop - if timer_enabled(I)='1' then - timer_counter(I)<=timer_counter(I)-1; - if timer_counter(I)=X"00000000" then - timer_counter(I)<=timer_limit(I); - ticks(I)<='1'; - end if; - end if; - end loop; - end if; - end if; - end process; + -- The timers proper; + process(clk,reset) + begin + if reset='0' then + for I in 0 to (2**timers-1) loop + timer_counter(I) <= (others => '0'); + end loop; + elsif rising_edge(clk) then + ticks <= (others => '0'); + if prescaled_tick='1' then + for I in 0 to (2**timers-1) loop + if timer_enabled(I)='1' then + timer_counter(I) <=timer_counter(I)-1; + if timer_counter(I)=X"00000000" then + timer_counter(I)<=timer_limit(I); + ticks(I) <='1'; + end if; + end if; + end loop; + end if; + end if; + end process; - -- Handle CPU access to hardware registers - - process(clk,reset) - begin - if reset='0' then - timer_enabled<=(others => '0'); - elsif rising_edge(clk) then - if reg_req='1' and reg_rw='0' then -- Write access - case reg_addr_in is - when X"00" => - timer_enabled<=reg_data_in(2**timers-1 downto 0); - when X"04" => - timer_index<=unsigned(reg_data_in(7 downto 0)); - when X"08" => - timer_limit(to_integer(timer_index(timers downto 0)))<= - unsigned(reg_data_in(31 downto 0)); - when others => - null; - end case; - end if; - end if; - end process; - + -- Handle CPU access to hardware registers + process(clk,reset) + begin + if reset='0' then + timer_enabled <= (others => '0'); + elsif rising_edge(clk) then + if reg_req='1' and reg_rw='0' then -- Write access + case reg_addr_in is + when X"00" => + timer_enabled <= reg_data_in(2**timers-1 downto 0); + when X"04" => + timer_index <= unsigned(reg_data_in(7 downto 0)); + when X"08" => + timer_limit(to_integer(timer_index(timers downto 0)))<= unsigned(reg_data_in(31 downto 0)); + when others => + null; + end case; + end if; + end if; + end process; + end architecture; diff --git a/devices/sysbus/uart/uart.vhd b/devices/sysbus/uart/uart.vhd index 0d682c9..9d804e3 100644 --- a/devices/sysbus/uart/uart.vhd +++ b/devices/sysbus/uart/uart.vhd @@ -2,10 +2,8 @@ -- -- Name: uart.vhd -- Created: January 2019 --- Author(s): Philip Smart (based on the simplistic UART --- Description: ZPU SOC IOCTL Interface to an Emulator (Sharp MZ series). --- This module interfaces the ZPU IO processor to the Emulator IO Control backdoor --- for updating ROM/RAM, OSD and providing IO services. +-- Author(s): Philip Smart +-- Description: A simplistic UART fixed at 8N1 but with configurable baud rate and RX/TX Fifoś. -- Credits: Originally using the simplistic UART as a guide, which was written by the following -- authors:- -- Philippe Carton, philippe.carton2 libertysurf.fr diff --git a/zpu_soc.vhd b/zpu_soc.vhd index dc110dc..5bcc0c8 100644 --- a/zpu_soc.vhd +++ b/zpu_soc.vhd @@ -4,8 +4,13 @@ -- Created: January 2019 -- Author(s): Philip Smart -- Description: ZPU System On a Chip --- -- This module contains the System on a Chip definition for the ZPU. +-- Itś purpose is to provide a functional eco-system around the ZPU to actually perform +-- real tasks. As a basic, boot and stack RAM, UART I/O and Timers are needed to at least +-- present a monitor via UART for interaction. Upon this can be added an SD card for +-- disk storage using the Fat FileSystem, SPI etc. Also, as the Wishbone interface is +-- used in the Evo CPU, any number of 3rd party device IP Cores can be added relatively +-- easily. -- -- Credits: -- Copyright: (c) 2018 Philip Smart @@ -530,7 +535,8 @@ begin INT_REQ => INT_TRIGGER, INT_ACK => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine. INT_DONE => INT_DONE, -- Interrupt service routine completed/done. - BREAK => open, + BREAK => open, -- A break instruction encountered. + CONTINUE => '1', -- When break activated, processing stops. Setting CONTINUE to logic 1 resumes processing with next instruction. DEBUG_TXD => UART2_TX -- Debug serial output. ); end generate; @@ -613,7 +619,8 @@ begin INT_REQ => INT_TRIGGER, INT_ACK => INT_ACK, -- Interrupt acknowledge, ZPU has entered Interrupt Service Routine. INT_DONE => INT_DONE, -- Interrupt service routine completed/done. - BREAK => open, + BREAK => open, -- A break instruction encountered. + CONTINUE => '1', -- When break activated, processing stops. Setting CONTINUE to logic 1 resumes processing with next instruction. DEBUG_TXD => UART2_TX -- Debug serial output. ); end generate; @@ -647,34 +654,6 @@ begin memBRead => BRAM_DATA_READ ); end generate; --- ZPUDPROMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = true and SOC_IMPL_BRAM = true generate --- ZPUROM : entity work.BootROM --- port map ( --- clk => MEMCLK, --- memAWriteEnable => BRAM_WREN, --- memAAddr => MEM_ADDR(ADDR_BIT_BRAM_32BIT_RANGE), --- memAWrite => MEM_DATA_WRITE, --- memBWriteEnable => '0', --- memBAddr => MEM_ADDR_INSN(ADDR_BIT_BRAM_32BIT_RANGE), --- memBWrite => (others => '0'), --- memARead => BRAM_DATA_READ, --- memBRead => MEM_DATA_READ_INSN --- ); --- end generate; --- ZPUROMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = false and SOC_IMPL_BRAM = true generate --- ZPUROM : entity work.BootROM --- port map ( --- clk => MEMCLK, --- memAWriteEnable => BRAM_WREN, --- memAAddr => MEM_ADDR(ADDR_BIT_BRAM_32BIT_RANGE), --- memAWrite => MEM_DATA_WRITE, --- memBWriteEnable => '0', --- memBAddr => (others => 'X'), --- memBWrite => (others => 'X'), --- memARead => BRAM_DATA_READ, --- memBRead => open --- ); --- end generate; -- Evo system BRAM, dual port to allow for seperate instruction bus read. ZPUDPBRAMEVO : if (ZPU_EVO = 1 or ZPU_EVO_MINIMAL = 1) and SOC_IMPL_INSN_BRAM = true and SOC_IMPL_BRAM = true generate diff --git a/zpu_soc_pkg.vhd b/zpu_soc_pkg.vhd index 5f1c275..bb1bdd5 100644 --- a/zpu_soc_pkg.vhd +++ b/zpu_soc_pkg.vhd @@ -1,37 +1,31 @@ --- ZPU +--------------------------------------------------------------------------------------------------------- -- --- Copyright 2004-2008 oharboe - �yvind Harboe - oyvind.harboe@zylin.com --- Copyright 2018-2019 psmart - Philip Smart --- --- 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. +-- Name: zpu_soc_pkg.vhd +-- Created: January 2019 +-- Author(s): Philip Smart +-- Description: ZPU System On a Chip Configuration +-- +-- This module contains the System on a Chip configuration for the ZPU. +-- +-- Credits: +-- Copyright: (c) 2018 Philip Smart +-- +-- History: January 2019 - Initial creation. +-- +--------------------------------------------------------------------------------------------------------- +-- This source file is free software: you can redistribute it and-or modify +-- it under the terms of the GNU General Public License as published +-- by the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This source file is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +--------------------------------------------------------------------------------------------------------- library ieee; library pkgs; @@ -130,16 +124,12 @@ package zpu_soc_pkg is subtype IO_DECODE_RANGE is natural range maxAddrBit-WB_ACTIVE-1 downto maxIOBit; -- Upper bits in memory defining the IO block within the address space for the EVO cpu IO. All other models use ioBit. -- subtype WB_IO_DECODE_RANGE is natural range maxAddrBit-1 downto maxIOBit; -- Upper bits in memory defining the IO block within the address space for the EVO cpu IO. All other models use ioBit. - -- Start byte address of stack for non-EVO CPU. Point to top of BRAM or a dedicated blcck of RAM - 2*words. Once booted the stack frame can be shifted to any memory location. --- constant spStart : std_logic_vector(maxAddrBit-1 downto 0) := std_logic_vector(to_unsigned((2**(SOC_MAX_ADDR_BRAM_BIT))-8, maxAddrBit)); - -- Device options type CardType_t is (SD_CARD_E, SDHC_CARD_E); -- Define the different types of SD cards. - ------------------------------------------------------------ - -- constants + -- Constants ------------------------------------------------------------ constant YES : std_logic := '1'; @@ -151,17 +141,17 @@ package zpu_soc_pkg is constant HIZ : std_logic := 'Z'; ------------------------------------------------------------ - -- functions + -- Function prototypes ------------------------------------------------------------ -- Find the maximum of two integers. function IntMax(a : in integer; b : in integer) return integer; ------------------------------------------------------------ - -- records + -- Records ------------------------------------------------------------ ------------------------------------------------------------ - -- components + -- Components ------------------------------------------------------------ component dualport_ram is port ( @@ -177,24 +167,6 @@ package zpu_soc_pkg is ); end component; - component cacheL2 is - generic ( - MAX_CACHE_BITS : integer := 12 - ); - port ( - clk : in std_logic; - areset : in std_logic := '0'; - memAWriteEnable : in std_logic; - memAAddr : in std_logic_vector(MAX_CACHE_BITS-3 downto 0); - memAWrite : in std_logic_vector(55 downto 0); - memBWriteEnable : in std_logic; - memBAddr : in std_logic_vector(MAX_CACHE_BITS-3 downto 0); - memBWrite : in std_logic_vector(55 downto 0); - memARead : out std_logic_vector(55 downto 0); - memBRead : out std_logic_vector(55 downto 0) - ); - end component; - component dpram generic ( init_file : string; @@ -222,41 +194,6 @@ package zpu_soc_pkg is ); end component; - component signed_divider is - port ( - clk : in std_logic; - ena : in std_logic; - z : in unsigned(63 downto 0); - d : in unsigned(WORD_32BIT_RANGE); - q : out signed(63 downto 0); - s : out signed(63 downto 0) - ); - end component; - - component unsigned_divider is - port ( - clk : in std_logic; - ena : in std_logic; - z : in unsigned(63 downto 0); - d : in unsigned(WORD_32BIT_RANGE); - q : out unsigned(WORD_32BIT_RANGE); - s : out unsigned(WORD_32BIT_RANGE); - div0 : out std_logic; - ovf : out std_logic - ); - end component; - - component qdiv is - port ( - dividend : in signed(WORD_32BIT_RANGE); - divisor : in signed(WORD_32BIT_RANGE); - start : in std_logic; - clk : in std_logic; - quotient_out : out signed(WORD_32BIT_RANGE); - complete : out std_logic - ); - end component; - component SDCard is generic ( FREQ_G : real := 100.0; -- Master clock frequency (MHz). @@ -287,49 +224,22 @@ package zpu_soc_pkg is ); end component; - component sdram_v is - port ( - -- interface to the MT48LC16M16 chip - sd_clk : in std_logic; -- sdram is accessed at 128MHz - sd_rst : in std_logic; -- reset the sdram controller. - sd_cke : out std_logic; -- clock enable. - sd_dq : inout std_logic_vector(15 downto 0); -- 16 bit bidirectional data bus - sd_addr : out std_logic_vector(12 downto 0); -- 13 bit multiplexed address bus - sd_dqm : out std_logic_vector(1 downto 0); -- two byte masks - sd_ba : out std_logic_vector(1 downto 0); -- two banks - sd_cs_n : out std_logic; -- a single chip select - sd_we_n : out std_logic; -- write enable - sd_ras_n : out std_logic; -- row address select - sd_cas_n : out std_logic; -- columns address select - sd_ready : out std_logic; -- sd ready. - - -- cpu/chipset interface - wb_clk : in std_logic; -- 32MHz chipset clock to which sdram state machine is synchonized - wb_dat_i : in std_logic_vector(31 downto 0); -- data input from chipset/cpu - wb_dat_o : out std_logic_vector(31 downto 0); -- data output to chipset/cpu - wb_ack : out std_logic; - wb_adr : in std_logic_vector(23 downto 0); -- lower 2 bits are ignored. - wb_sel : in std_logic_vector(3 downto 0); - wb_cti : in std_logic_vector(2 downto 0); -- cycle type. - wb_stb : in std_logic; - wb_cyc : in std_logic; -- cpu/chipset requests cycle - wb_we : in std_logic -- cpu/chipset requests write - ); - end component; - end zpu_soc_pkg; +------------------------------------------------------------ +-- Function definitions. +------------------------------------------------------------ package body zpu_soc_pkg is - -- Find the maximum of two integers. - function IntMax(a : in integer; b : in integer) return integer is - begin - if a > b then - return a; - else - return b; - end if; - return a; - end function IntMax; + -- Find the maximum of two integers. + function IntMax(a : in integer; b : in integer) return integer is + begin + if a > b then + return a; + else + return b; + end if; + return a; + end function IntMax; end package body;