OpenCores
URL https://opencores.org/ocsvn/t80/t80/trunk

Subversion Repositories t80

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 46 to Rev 47
    Reverse comparison

Rev 46 → Rev 47

/trunk/sim/rtl_sim/bin/RX_Cmd1.txt Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/sim/rtl_sim/bin/RX_Cmd1.txt Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/sim/rtl_sim/bin/compile.do =================================================================== --- trunk/sim/rtl_sim/bin/compile.do (revision 46) +++ trunk/sim/rtl_sim/bin/compile.do (nonexistent) @@ -1,18 +0,0 @@ -vcom ../../../rtl/vhdl/T80_Pack.vhd -vcom ../../../rtl/vhdl/T80_MCode.vhd -vcom ../../../rtl/vhdl/T80_ALU.vhd -vcom ../../../rtl/vhdl/T80_Reg.vhd -vcom ../../../rtl/vhdl/T80.vhd -vcom ../../../rtl/vhdl/T80a.vhd -vcom ../../../rtl/vhdl/T80s.vhd -vcom ../../../rtl/vhdl/T16450.vhd -vcom ../../../rtl/vhdl/SSRAM2.vhd -vcom ../../../bench/vhdl/MonZ80.vhd -vcom ../../../rtl/vhdl/DebugSystem.vhd -93 -vcom ../../../bench/vhdl/ROM80.vhd -vcom ../../../bench/vhdl/StimLog.vhd -93 -vcom ../../../bench/vhdl/AsyncLog.vhd -93 -vcom ../../../bench/vhdl/AsyncStim.vhd -93 -vcom ../../../bench/vhdl/SRAM.vhd -93 -vcom ../../../bench/vhdl/TestBench.vhd -93 -vcom ../../../bench/vhdl/DebugSystem_TB.vhd -93 Index: trunk/sw/xrom.cpp =================================================================== --- trunk/sw/xrom.cpp (revision 46) +++ trunk/sw/xrom.cpp (nonexistent) @@ -1,414 +0,0 @@ -// -// Xilinx VHDL ROM generator -// -// Version : 0244 -// -// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -// -// All rights reserved -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// Redistributions in 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. -// -// Neither the name of the author nor the names of other contributors may -// be used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Please report bugs to the author, but before you do so, please -// make sure that this is not a derivative work and that -// you have the latest version of this file. -// -// The latest version of this file can be found at: -// http://www.opencores.org/cvsweb.shtml/t51/ -// -// Limitations : -// Not all address/data widths produce working code -// Requires stl to compile -// -// File history : -// -// 0220 : Initial release -// -// 0221 : Fixed block ROMs with partial bytes -// -// 0241 : Updated for WebPack 5.1 -// -// 0244 : Added -n option and component declaration -// - -#include -#include -#include -#include - -using namespace std; - -#if !(defined(max)) && _MSC_VER - // VC fix - #define max __max -#endif - -int main (int argc, char *argv[]) -{ - cerr << "Xilinx VHDL ROM generator by Daniel Wallner. Version 0244\n"; - - try - { - unsigned long aWidth; - unsigned long dWidth; - unsigned long select = 0; - unsigned long length = 0; - char z = 0; - - if (argc < 4) - { - cerr << "\nUsage: xrom
\n"; - cerr << "\nThe options can be:\n"; - cerr << " -[decimal number] = SelectRAM usage in 1/16 parts\n"; - cerr << " -z = use tri-state buses\n"; - cerr << " -n [decimal size] = limit rom size\n"; - cerr << "\nExample:\n"; - cerr << " xrom Test_ROM 13 8 -6\n\n"; - return -1; - } - - int result; - - result = sscanf(argv[2], "%lu", &aWidth); - if (result < 1) - { - throw "Error in address bits argument!\n"; - } - - result = sscanf(argv[3], "%lu", &dWidth); - if (result < 1) - { - throw "Error in data bits argument!\n"; - } - - int argument = 4; - - while (argument < argc) - { - char tmpC = 0; - unsigned long tmpL = 0; - - result = sscanf(argv[argument], "%c%lu", &tmpC, &tmpL); - if (result < 1 || tmpC != '-' ) - { - throw "Error in options!\n"; - } - - if (result < 2) - { - sscanf(argv[argument], "%c%c", &tmpC, &tmpC); - if (tmpC != 'z' && tmpC != 'n') - { - throw "Unkown option!\n"; - } - if (tmpC == 'z') - { - z = tmpC; - } - else - { - argument++; - - if (argument == argc) - { - throw "No memory size argument!\n"; - } - - result = sscanf(argv[argument], "%lu", &tmpL); - if (!result) - { - throw "Memory size not a number!\n"; - } - length = tmpL; - } - } - else - { - select = tmpL; - } - argument++; - } - - unsigned long selectIter = 0; - unsigned long blockIter = 0; - unsigned long bytes = (dWidth + 7) / 8; - - if (!select) - { - blockIter = ((1UL << aWidth) + 511) / 512; - if (length && length < blockIter * 512) - { - blockIter = (length + 511) / 512; - } - } - else if (select == 16) - { - selectIter = ((1UL << aWidth) + 15) / 16; - if (length && length < selectIter * 16) - { - selectIter = (length + 15) / 16; - } - } - else - { - blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512; - selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16; - } - - unsigned long blockTotal = ((1UL << aWidth) + 511) / 512; - if (length && length < blockTotal * 512) - { - blockTotal = (length + 511) / 512; - } - - if (length) - { - if (length > selectIter * 16) - { - blockIter -= ((1UL << aWidth) + 511) / 512 - blockTotal; - } - else - { - blockIter = 0; - } - } - if (length && !blockIter && length < selectIter * 16) - { - selectIter = (length + 15) / 16; - } - - cerr << "Creating ROM with " << selectIter * bytes; - cerr << " RAM16X1S and " << blockIter * bytes << " RAMB4_S8\n"; - - printf("-- This file was generated with xrom written by Daniel Wallner\n"); - printf("\nlibrary IEEE;"); - printf("\nuse IEEE.std_logic_1164.all;"); - printf("\nuse IEEE.numeric_std.all;"); - printf("\n\nentity %s is", argv[1]); - printf("\n\tport("); - printf("\n\t\tClk\t: in std_logic;"); - printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1); - printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1); - printf("\n\t);"); - printf("\nend %s;", argv[1]); - printf("\n\narchitecture rtl of %s is", argv[1]); - - if (selectIter) - { - printf("\n\tcomponent RAM16X1S"); - printf("\n\t\tport("); - printf("\n\t\t\tO : out std_ulogic;"); - printf("\n\t\t\tA0 : in std_ulogic;"); - printf("\n\t\t\tA1 : in std_ulogic;"); - printf("\n\t\t\tA2 : in std_ulogic;"); - printf("\n\t\t\tA3 : in std_ulogic;"); - printf("\n\t\t\tD : in std_ulogic;"); - printf("\n\t\t\tWCLK : in std_ulogic;"); - printf("\n\t\t\tWE : in std_ulogic);"); - printf("\n\tend component;\n"); - } - if (blockIter) - { - printf("\n\tcomponent RAMB4_S8"); - printf("\n\t\tport("); - printf("\n\t\t\tDO : out std_logic_vector(7 downto 0);"); - printf("\n\t\t\tADDR : in std_logic_vector(8 downto 0);"); - printf("\n\t\t\tCLK : in std_ulogic;"); - printf("\n\t\t\tDI : in std_logic_vector(7 downto 0);"); - printf("\n\t\t\tEN : in std_ulogic;"); - printf("\n\t\t\tRST : in std_ulogic;"); - printf("\n\t\t\tWE : in std_ulogic);"); - printf("\n\tend component;\n"); - } - - if (selectIter > 0) - { - printf("\n\tsignal A_r: unsigned(A'range);"); - } - if (selectIter > 1) - { - printf("\n\ttype sRAMOut_a is array(0 to %d) of std_logic_vector(D'range);", selectIter - 1); - printf("\n\tsignal sRAMOut : sRAMOut_a;"); - printf("\n\tsignal siA_r : integer;"); - } - if (selectIter && blockIter) - { - printf("\n\tsignal sD : std_logic_vector(D'range);"); - } - if (blockIter == 1) - { - printf("\n\tsignal bRAMOut : std_logic_vector(%d downto 0);", bytes * 8 - 1); - } - if (blockIter > 1) - { - printf("\n\ttype bRAMOut_a is array(%d to %d) of std_logic_vector(%d downto 0);", blockTotal - blockIter, blockTotal - 1, bytes * 8 - 1); - printf("\n\tsignal bRAMOut : bRAMOut_a;"); - printf("\n\tsignal biA_r : integer;"); - if (!selectIter) - { - printf("\n\tsignal A_r : unsigned(A'left downto 9);"); - } - } - if (selectIter && blockIter) - { - printf("\n\tsignal bD : std_logic_vector(D'range);"); - } - - printf("\nbegin"); - - if (selectIter > 0 || blockIter > 1) - { - printf("\n\tprocess (Clk)"); - printf("\n\tbegin"); - printf("\n\t\tif Clk'event and Clk = '1' then"); - if (!selectIter) - { - printf("\n\t\t\tA_r <= unsigned(A(A'left downto 9));"); - } - else - { - printf("\n\t\t\tA_r <= unsigned(A);"); - } - printf("\n\t\tend if;"); - printf("\n\tend process;"); - } - - if (selectIter == 1) - { - printf("\n\n\tsG1: for I in 0 to %d generate", dWidth - 1); - printf("\n\t\tS%s : RAM16X1S\n\t\t\tport map (", argv[1]); - if (blockIter) - { - printf("s"); - } - printf("WE => '0', WCLK => '0', D => '0', O => D(I), A0 => A_r(0), A1 => A_r(1), A2 => A_r(2), A3 => A_r(3));"); - printf("\n\tend generate;"); - } - if (selectIter > 1) - { - printf("\n\n\tsiA_r <= to_integer(A_r(A'left downto 4));"); - printf("\n\n\tsG1: for I in 0 to %d generate", selectIter - 1); - printf("\n\t\tsG2: for J in 0 to %d generate", dWidth - 1); - printf("\n\t\t\tS%s : RAM16X1S\n\t\t\t\tport map (WE => '0', WCLK => '0', D => '0', O => sRAMOut(I)(J), A0 => A_r(0), A1 => A_r(1), A2 => A_r(2), A3 => A_r(3));", argv[1]); - printf("\n\t\tend generate;"); - if (z == 'z') - { - printf("\n\t\t"); - if (blockIter) - { - printf("s"); - } - printf("D <= sRAMOut(I) when siA_r = I else (others => 'Z');"); - } - printf("\n\tend generate;"); - if (z != 'z') - { - printf("\n\n\tprocess (siA_r, sRAMOut)\n\tbegin\n\t\t"); - if (blockIter) - { - printf("s"); - } - printf("D <= sRAMOut(0);"); - printf("\n\t\tfor I in 1 to %d loop", selectIter - 1); - printf("\n\t\t\tif siA_r = I then\n\t\t\t\t"); - if (blockIter) - { - printf("s"); - } - printf("D <= sRAMOut(I);\n\t\t\tend if;"); - printf("\n\t\tend loop;\n\tend process;"); - } - } - - if (blockIter == 1) - { - printf("\n\n\tbG1: for J in 0 to %d generate", bytes - 1); - printf("\n\t\tB%s : RAMB4_S8", argv[1]); - printf("\n\t\t\tport map (DI => \"00000000\", EN => '1', RST => '0', WE => '0', CLK => Clk, ADDR => A(8 downto 0), DO => bRAMOut(7 + 8 * J downto 8 * J));", argv[1]); - printf("\n\tend generate;"); - printf("\n\n\t"); - if (selectIter) - { - printf("b"); - } - printf("D <= bRAMOut(D'range);"); - } - if (blockIter > 1) - { - printf("\n\n\tbiA_r <= to_integer(A_r(A'left downto 9));"); - printf("\n\n\tbG1: for I in %d to %d generate", blockTotal - blockIter, blockTotal - 1); - printf("\n\t\tbG2: for J in 0 to %d generate", bytes - 1); - printf("\n\t\t\tB%s : RAMB4_S8\n\t\t\t\tport map (DI => \"00000000\", EN => '1', RST => '0', WE => '0', CLK => Clk, ADDR => A(8 downto 0), DO => bRAMOut(I)(7 + 8 * J downto 8 * J));", argv[1]); - printf("\n\t\tend generate;"); - if (z == 'z') - { - printf("\n\t\t"); - if (selectIter) - { - printf("b"); - } - printf("D <= bRAMOut(I) when biA_r = I else (others => 'Z');"); - } - printf("\n\tend generate;"); - if (z != 'z') - { - printf("\n\n\tprocess (biA_r, bRAMOut)\n\tbegin\n\t\t"); - if (selectIter) - { - printf("b"); - } - printf("D <= bRAMOut(%d)(D'range);", blockTotal - blockIter); - printf("\n\t\tfor I in %d to %d loop", blockTotal - blockIter + 1, blockTotal - 1); - printf("\n\t\t\tif biA_r = I then\n\t\t\t\t"); - if (selectIter) - { - printf("b"); - } - printf("D <= bRAMOut(I)(D'range);\n\t\t\tend if;"); - printf("\n\t\tend loop;\n\tend process;"); - } - } - - if (selectIter && blockIter) - { - printf("\n\n\tD <= bD when A_r(A'left downto 9) >= %d else sD;", blockTotal - blockIter); - } - - printf("\nend;\n"); - - return 0; - } - catch (string error) - { - cerr << "Fatal: " << error; - } - catch (const char *error) - { - cerr << "Fatal: " << error; - } - return -1; -} Index: trunk/sw/sine.bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/sw/sine.bin =================================================================== --- trunk/sw/sine.bin (revision 46) +++ trunk/sw/sine.bin (nonexistent)
trunk/sw/sine.bin Property changes : Deleted: svn:mime-type ## -1 +0,0 ## -application/octet-stream \ No newline at end of property Index: trunk/sw/hex2rom.cpp =================================================================== --- trunk/sw/hex2rom.cpp (revision 46) +++ trunk/sw/hex2rom.cpp (nonexistent) @@ -1,962 +0,0 @@ -// -// Binary and intel/motorola hex to VHDL ROM converter -// -// Version : 0244 -// -// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -// -// All rights reserved -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// Redistributions in 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. -// -// Neither the name of the author nor the names of other contributors may -// be used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -// Please report bugs to the author, but before you do so, please -// make sure that this is not a derivative work and that -// you have the latest version of this file. -// -// The latest version of this file can be found at: -// http://www.opencores.org/cvsweb.shtml/t51/ -// -// Limitations : -// No support for wrapped intel segments -// Requires stl to compile -// -// File history : -// -// 0146 : Initial release -// -// 0150 : Added binary read -// -// 0208 : Changed some errors to warnings -// -// 0215 : Added support for synchronous ROM -// -// 0220 : Changed array ROM format, added support for Xilinx .UCF generation -// -// 0221 : Fixed small .UCF generation for small ROMs -// -// 0244 : Added Leonardo .UCF option -// - -#include -#include -#include -#include - -using namespace std; - -#if !(defined(max)) && _MSC_VER - // VC fix - #define max __max -#endif - -class MemBlock -{ -public: - unsigned long m_startAddress; - vector m_bytes; -}; - -class File -{ -public: - explicit File(const char *fileName, const char *mode) - { - m_file = fopen(fileName, mode); - if (m_file != NULL) - { - return; - } - string errorStr = "Error opening "; - errorStr += fileName; - errorStr += "\n"; - throw errorStr; - } - - ~File() - { - fclose(m_file); - } - - // Read binary file - void ReadBin(unsigned long limit) - { - m_top = 0; - - m_chunks.push_back(MemBlock()); - m_chunks.back().m_startAddress = 0; - - cerr << "Reading binary file\n"; - - int tmp = fgetc(m_file); - - while (!feof(m_file)) - { - m_chunks.back().m_bytes.push_back(tmp); - - if (m_chunks.back().m_bytes.size() > limit + 1) - { - m_chunks.back().m_bytes.pop_back(); - m_top = m_chunks.back().m_bytes.size() - 1; - cerr << "Ignoring data above address space!\n"; - cerr << " Limit: " << limit << "\n"; - return; - } - - tmp = fgetc(m_file); - } - - m_top = m_chunks.back().m_bytes.size() - 1; - - if (!m_chunks.back().m_bytes.size()) - { - cerr << "No data!\n"; - - m_chunks.pop_back(); - } - } - - // Read hex file - void ReadHex(unsigned long limit) - { - char szLine[1024]; - bool formatDetected = false; - bool intel; - bool endSeen = false; - bool linear = true; // Only used for intel hex - unsigned long addressBase = 0; // Only used for intel hex - unsigned long dataRecords = 0; // Only used for s-record - while (!feof(m_file)) - { - if (fgets(szLine, 1024, m_file) == 0) - { - if (ferror(m_file)) - { - throw "Error reading input!\n"; - } - continue; - } - - if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) - { - szLine[strlen(szLine) - 1] = 0; - } - - if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) - { - szLine[strlen(szLine) - 1] = 0; - } - - if (strlen(szLine) == 1023) - { - throw "Hex file lines to long!\n"; - } - // Ignore blank lines - if (szLine[0] == '\n') - { - continue; - } - // Detect format and warn if garbage lines are found - if (!formatDetected) - { - if (szLine[0] != ':' && szLine[0] != 'S') - { - cerr << "Ignoring garbage line!\n"; - continue; - } - if (szLine[0] == 'S') - { - intel = false; - cerr << "Detected S-Record\n"; - } - else - { - intel = true; - cerr << "Detected intel hex file\n"; - } - formatDetected = true; - } - else if ((intel && szLine[0] != ':') || - (!intel && szLine[0] != 'S')) - { - cerr << "Ignoring garbage line!\n"; - continue; - } - - if (endSeen) - { - throw "Hex line after end of file record!\n"; - } - - if (intel) - { - unsigned long dataBytes; - unsigned long startAddress; - unsigned long type; - if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3) - { - throw "Hex line beginning corrupt!\n"; - } - // Check line length - if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0) - { - throw "Hex line length incorrect!\n"; - } - // Check line checksum - unsigned char checkSum = 0; - unsigned long tmp; - for (unsigned int i = 0; i <= dataBytes + 4; ++i) - { - if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1) - { - throw "Hex line data corrupt!\n"; - } - checkSum += tmp; - } - if (checkSum != 0) - { - throw "Hex line checksum error!\n"; - } - - switch (type) - { - case 0: - // Data record - if (!linear) - { - // Segmented - unsigned long test = startAddress; - test += dataBytes; - if (test > 0xffff) - { - throw "Can't handle wrapped segments!\n"; - } - } - if (!m_chunks.size() || - m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != - addressBase + startAddress) - { - m_chunks.push_back(MemBlock()); - m_chunks.back().m_startAddress = addressBase + startAddress; - } - { - unsigned char i = 0; - for (i = 0; i < dataBytes; ++i) - { - sscanf(&szLine[9 + i * 2], "%2lx", &tmp); - if (addressBase + startAddress + i > limit) - { - cerr << "Ignoring data above address space!\n"; - cerr << "Data address: " << addressBase + startAddress + i; - cerr << " Limit: " << limit << "\n"; - if (!m_chunks.back().m_bytes.size()) - { - m_chunks.pop_back(); - } - continue; - } - m_chunks.back().m_bytes.push_back(tmp); - } - } - break; - - case 1: - // End-of-file record - if (dataBytes != 0) - { - cerr << "Warning: End of file record not zero length!\n"; - } - if (startAddress != 0) - { - cerr << "Warning: End of file record address not zero!\n"; - } - endSeen = true; - break; - - case 2: - // Extended segment address record - if (dataBytes != 2) - { - throw "Length field must be 2 in extended segment address record!\n"; - } - if (startAddress != 0) - { - throw "Address field must be zero in extended segment address record!\n"; - } - sscanf(&szLine[9], "%4lx", &startAddress); - addressBase = startAddress << 4; - linear = false; - break; - - case 3: - // Start segment address record - if (dataBytes != 4) - { - cerr << "Warning: Length field must be 4 in start segment address record!\n"; - } - if (startAddress != 0) - { - cerr << "Warning: Address field must be zero in start segment address record!\n"; - } - if (dataBytes == 4) - { - unsigned long ssa; - char ssaStr[16]; - sscanf(&szLine[9], "%8lx", &ssa); - sprintf(ssaStr, "%08X\n", ssa); - cerr << "Segment start address (CS/IP): "; - cerr << ssaStr; - } - break; - - case 4: - // Extended linear address record - if (dataBytes != 2) - { - throw "Length field must be 2 in extended linear address record!\n"; - } - if (startAddress != 0) - { - throw "Address field must be zero in extended linear address record!\n"; - } - sscanf(&szLine[9], "%4lx", &startAddress); - addressBase = ((unsigned long)startAddress) << 16; - linear = true; - break; - - case 5: - // Start linear address record - if (dataBytes != 4) - { - cerr << "Warning: Length field must be 4 in start linear address record!\n"; - } - if (startAddress != 0) - { - cerr << "Warning: Address field must be zero in start linear address record!\n"; - } - if (dataBytes == 4) - { - unsigned long lsa; - char lsaStr[16]; - sscanf(&szLine[9], "%8lx", &lsa); - sprintf(lsaStr, "%08X\n", lsa); - cerr << "Linear start address: "; - cerr << lsaStr; - } - break; - - default: - cerr << "Waring: Unknown record found!\n"; - } - } - else - { - // S-record - unsigned long count; - char type; - if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2) - { - throw "Hex line beginning corrupt!\n"; - } - // Check line length - if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0) - { - throw "Hex line length incorrect!\n"; - } - // Check line checksum - unsigned char checkSum = 0; - unsigned long tmp; - for (unsigned int i = 0; i < count + 1; ++i) - { - if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1) - { - throw "Hex line data corrupt!\n"; - } - checkSum += tmp; - } - if (checkSum != 255) - { - throw "Hex line checksum error!\n"; - } - - switch (type) - { - case '0': - // Header record - { - char header[256]; - unsigned char i = 0; - for (i = 0; i + 3 < count; ++i) - { - sscanf(&szLine[8 + i * 2], "%2lx", &tmp); - header[i] = tmp; - } - header[i] = 0; - if (i > 0) - { - cerr << "Module name: " << header << "\n"; - } - } - break; - - case '1': - case '2': - case '3': - // Data record - { - dataRecords++; - unsigned long startAddress; - if (type == '1') - { - sscanf(&szLine[4], "%4lx", &startAddress); - } - else if (type == '2') - { - sscanf(&szLine[4], "%6lx", &startAddress); - } - else - { - sscanf(&szLine[4], "%8lx", &startAddress); - } - - if (!m_chunks.size() || - m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != - startAddress) - { - m_chunks.push_back(MemBlock()); - m_chunks.back().m_startAddress = startAddress; - } - unsigned char i = 0; - for (i = (type - '1'); i + 3 < count; ++i) - { - sscanf(&szLine[8 + i * 2], "%2lx", &tmp); - if (startAddress + i > limit) - { - cerr << "Ignoring data above address space!\n"; - cerr << "Data address: " << startAddress + i; - cerr << " Limit: " << limit << "\n"; - if (!m_chunks.back().m_bytes.size()) - { - m_chunks.pop_back(); - } - continue; - } - m_chunks.back().m_bytes.push_back(tmp); - } - } - break; - - case '5': - // Count record - { - unsigned long address; - sscanf(&szLine[4], "%4lx", &address); - if (address != dataRecords) - { - throw "Wrong number of data records!\n"; - } - } - break; - - case '7': - case '8': - case '9': - // Start address record - cerr << "Ignoring start address record!\n"; - break; - - default: - cerr << "Unknown record found!\n"; - } - } - } - if (intel && !endSeen) - { - cerr << "No end of file record!\n"; - } - if (!m_chunks.size()) - { - throw "No data in file!\n"; - } - vector::iterator vi; - m_top = 0; - for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) - { - m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1); - } - } - - // Rather inefficient this one, fix sometime - bool GetByte(const unsigned long address, unsigned char &chr) - { - vector::iterator vi; - - for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) - { - if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address) - { - break; - } - } - if (vi == m_chunks.end()) - { - return false; - } - chr = vi->m_bytes[address - vi->m_startAddress]; - return true; - } - - bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str) - { - bool ok = false; - long i; - unsigned char chr; - unsigned long data = 0; - unsigned long tmp; - - if (lEndian) - { - for (i = 0; i < (bits + 7) / 8; ++i) - { - ok |= GetByte(address + i, chr); - tmp = chr; - data |= tmp << (8 * i); - } - } - else - { - for (i = 0; i < (bits + 7) / 8; ++i) - { - ok |= GetByte(address + i, chr); - tmp = chr; - data |= tmp << (8 * ((bits + 7) / 8 - i - 1)); - } - } - - if (!ok) - { - return false; - } - - unsigned long mask = 1; - - str = ""; - for (i = 0; i < bits; i++) - { - if (data & mask) - { - str.insert(0,"1"); - } - else - { - str.insert(0,"0"); - } - mask <<= 1; - } - return true; - } - - FILE *Handle() { return m_file; }; - vector m_chunks; - unsigned long m_top; -private: - FILE *m_file; -}; - - -int main (int argc, char *argv[]) -{ - cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0244\n"; - - try - { - unsigned long aWidth; - unsigned long dWidth; - char endian; - char O = 0; - - if (!(argc == 4 || argc == 5)) - { - cerr << "\nUsage: hex2rom [-b] \n"; - cerr << "\nIf the -b option is specified the file is read as a binary file\n"; - cerr << "Hex input files must be intel hex or motorola s-record\n"; - cerr << "\nThe format string has the format AEDOS where:\n"; - cerr << " A = Address bits\n"; - cerr << " E = Endianness, l or b\n"; - cerr << " D = Data bits\n"; - cerr << " O = ROM type: (one optional character)\n"; - cerr << " z for tri-state output\n"; - cerr << " a for array ROM\n"; - cerr << " s for synchronous ROM\n"; - cerr << " u for XST ucf\n"; - cerr << " l for Leonardo ucf\n"; - cerr << " S = SelectRAM usage in 1/16 parts (only used when O = u)\n"; - cerr << "\nExample:\n"; - cerr << " hex2rom test.hex Test_ROM 18b16z\n\n"; - return -1; - } - - string inFileName; - string outFileName; - - unsigned long bytes; - unsigned long select = 0; - - if (argc == 5) - { - if (strcmp(argv[1], "-b")) - { - throw "Error in arguments!\n"; - } - } - - int result; - - result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select); - if (result < 3) - { - throw "Error in output format argument!\n"; - } - - if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u' && O != 'l')) - { - throw "Error in output format argument!\n"; - } - inFileName = argv[argc - 3]; - outFileName = argv[argc - 2]; - - bytes = (dWidth + 7) / 8; - - File inFile(inFileName.c_str(), "rb"); - - if (argc == 4) - { - inFile.ReadHex((1UL << aWidth) * bytes - 1); - } - else - { - inFile.ReadBin((1UL << aWidth) * bytes - 1); - } - - string line; - - unsigned long words = 1; - unsigned long i = inFile.m_top; - i /= bytes; - - while (i != 0) - { - i >>= 1; - words <<= 1; - } - - if (O != 'u' && O != 'l') - { - printf("-- This file was generated with hex2rom written by Daniel Wallner\n"); - printf("\nlibrary IEEE;"); - printf("\nuse IEEE.std_logic_1164.all;"); - printf("\nuse IEEE.numeric_std.all;"); - printf("\n\nentity %s is", outFileName.c_str()); - printf("\n\tport("); - if (O == 'z') - { - printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1); - printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1); - } - if (O == 's') - { - printf("\n\t\tClk\t: in std_logic;", dWidth - 1); - } - printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1); - printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1); - printf("\n\t);"); - printf("\nend %s;", outFileName.c_str()); - printf("\n\narchitecture rtl of %s is", outFileName.c_str()); - if (!O) - { - printf("\nbegin"); - printf("\n\tprocess (A)"); - printf("\n\tbegin"); - printf("\n\t\tcase to_integer(unsigned(A)) is"); - } - else if (O == 's') - { - printf("\n\tsignal A_r : std_logic_vector(%d downto 0);", aWidth - 1); - printf("\nbegin"); - printf("\n\tprocess (Clk)"); - printf("\n\tbegin"); - printf("\n\t\tif Clk'event and Clk = '1' then"); - printf("\n\t\t\tA_r <= A;"); - printf("\n\t\tend if;"); - printf("\n\tend process;"); - printf("\n\tprocess (A_r)"); - printf("\n\tbegin"); - printf("\n\t\tcase to_integer(unsigned(A_r)) is"); - } - else - { - printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1); - printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1); - printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'("); - } - - string str; - string strDC; - for (i = 0; i < dWidth; i++) - { - strDC.insert(0, "-"); - } - for (i = 0; i < words; i++) - { - if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str)) - { - str = strDC; - } - if (!O || O == 's') - { - if (inFile.m_top / bytes >= i) - { - printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str()); - printf("\t-- 0x%04X", i * bytes); - } - } - else - { - printf("\n\t\t\"%s", str.c_str()); - if (i != words - 1) - { - printf("\","); - } - else - { - printf("\");"); - } - printf("\t-- 0x%04X", i * bytes); - } - } - - if (!O || O == 's') - { - printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str()); - printf("\n\t\tend case;"); - printf("\n\tend process;"); - } - else - { - printf("\nbegin"); - if (O == 'z') - { - printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');"); - } - else - { - printf("\n\tD <= ROM(to_integer(unsigned(A)));"); - } - } - printf("\nend;\n"); - } - else - { - unsigned long selectIter = 0; - unsigned long blockIter = 0; - - if (!select) - { - blockIter = ((1UL << aWidth) + 511) / 512; - } - else if (select == 16) - { - selectIter = ((1UL << aWidth) + 15) / 16; - } - else - { - blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512; - selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16; - } - - cerr << "Creating .ucf file with " << selectIter * bytes; - cerr << " LUTs and " << blockIter * bytes << " block RAMs\n"; - - unsigned long blockTotal = ((1UL << aWidth) + 511) / 512; - - printf("# This file was generated with hex2rom written by Daniel Wallner\n"); - - for (i = 0; i < selectIter; i++) - { - unsigned long base = i * 16 * bytes; - unsigned long j; - unsigned char c; - unsigned long pos; - - // Check that there is any actual data in segment - bool init = false; - for (pos = 0; pos < bytes * 16; pos++) - { - init = inFile.GetByte(base + pos, c); - if (init) - { - break; - } - } - - if (init) - { - for (j = 0; j < dWidth; j++) - { - unsigned long bitMask = 1; - unsigned long bits = 0; - - for (pos = 0; pos < 16; pos++) - { - unsigned long addr; - - if (endian = 'l') - { - addr = base + bytes * pos + j / 8; - } - else - { - addr = base + bytes * pos + bytes - j / 8 - 1; - } - - c = 0; - inFile.GetByte(addr, c); - if (c & (1 << (j % 8))) - { - bits |= bitMask; - } - bitMask <<= 1; - } - - if (O == 'u') - { - if (selectIter == 1) - { - printf("\nINST *s%s%d INIT = %04X;", outFileName.c_str(), j, bits); - } - else - { - printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits); - } - } - else - { - if (selectIter == 1) - { - printf("\nINST *sG1_%d_S%s INIT = %04X;", j, outFileName.c_str(), bits); - } - else - { - printf("\nINST *sG1_%d_sG2_%d_S%s INIT = %04X;", i, j, outFileName.c_str(), bits); - } - } - } - } - } - - for (i = blockTotal - blockIter; i < blockTotal; i++) - { - unsigned long j; - for (j = 0; j < bytes; j++) - { - unsigned long k; - for (k = 0; k < 16; k++) - { - unsigned long base = i * 512 * bytes + k * 32 * bytes; - unsigned char c; - unsigned long pos; - - // Check that there is any actual data in segment - bool init = false; - for (pos = 0; pos < 32; pos++) - { - init = inFile.GetByte(base + bytes * pos + j, c); - if (init) - { - break; - } - } - - if (init) - { - if (O == 'u') - { - if (blockIter == 1) - { - printf("\nINST *b%s%d INIT_%02X = ", outFileName.c_str(), j, k); - } - else - { - printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k); - } - } - else - { - if (blockIter == 1) - { - printf("\nINST *bG1_%d_B%s INIT_%02X = ", j, outFileName.c_str(), k); - } - else - { - printf("\nINST *bG1_%d_bG2_%d_B%s INIT_%02X = ", i, j, outFileName.c_str(), k); - } - } - for (pos = 0; pos < 32; pos++) - { - unsigned long addr; - - if (endian = 'l') - { - addr = base + bytes * (31 - pos) + j; - } - else - { - addr = base + bytes * (31 - pos) + bytes - j - 1; - } - - c = 0; - inFile.GetByte(addr, c); - printf("%02X", c); - } - printf(";"); - } - } - } - } - printf("\n"); - } - return 0; - } - catch (string error) - { - cerr << "Fatal: " << error; - } - catch (const char *error) - { - cerr << "Fatal: " << error; - } - return -1; -} Index: trunk/syn/xilinx/run/t80_leo.bat =================================================================== --- trunk/syn/xilinx/run/t80_leo.bat (revision 46) +++ trunk/syn/xilinx/run/t80_leo.bat (nonexistent) @@ -1,8 +0,0 @@ -cd ..\out - -spectrum -file ..\bin\t80.tcl -move exemplar.log ..\log\t80_leo.srp - -cd ..\run - -t80 t80_leo.edf xc2s200-pq208-5
trunk/syn/xilinx/run/t80_leo.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/run/t80.bat =================================================================== --- trunk/syn/xilinx/run/t80.bat (revision 46) +++ trunk/syn/xilinx/run/t80.bat (nonexistent) @@ -1,44 +0,0 @@ -set name=t80 -rem set target=xc2v250-cs144-6 -rem set target=xcv300e-pq240-8 -set target=xc2s200-pq208-5 - -if "%2" == "" goto default -set target=%2 -:default - -cd ..\out - -if "%1" == "" goto xst - -set name=t80_leo - -copy ..\bin\t80_leo.pin %name%.ucf - -ngdbuild -p %target% %1 %name%.ngd - -goto builddone - -:xst - -copy ..\bin\%name%.pin %name%.ucf - -xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp -ngdbuild -p %target% %name%.ngc - -:builddone - -move %name%.bld ..\log - -map -p %target% -cm speed -c 100 -tx on -o %name%_map %name% -move %name%_map.mrp ..\log\%name%.mrp - -par -ol 3 -t 1 %name%_map -w %name% -move %name%.par ..\log - -trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf - -bitgen -w %name% -move %name%.bgn ..\log - -cd ..\run
trunk/syn/xilinx/run/t80.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/run/t80debugxr_leo.bat =================================================================== --- trunk/syn/xilinx/run/t80debugxr_leo.bat (revision 46) +++ trunk/syn/xilinx/run/t80debugxr_leo.bat (nonexistent) @@ -1,10 +0,0 @@ -cd ..\out - -hex2rom ..\..\..\sw\monitorxr.hex MonZ80 11b8s > ..\src\MonZ80_leo.vhd - -spectrum -file ..\bin\t80debugxr.tcl -move exemplar.log ..\log\t80debugxr_leo.srp - -cd ..\run - -t80debugxr t80debugxr_leo.edf xc2s200-pq208-5
trunk/syn/xilinx/run/t80debugxr_leo.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/run/t80debugxr.bat =================================================================== --- trunk/syn/xilinx/run/t80debugxr.bat (revision 46) +++ trunk/syn/xilinx/run/t80debugxr.bat (nonexistent) @@ -1,46 +0,0 @@ -set name=t80debugxr -rem set target=xc2v250-cs144-6 -rem set target=xcv300e-pq240-8 -set target=xc2s200-pq208-5 - -if "%2" == "" goto default -set target=%2 -:default - -cd ..\out - -if "%1" == "" goto xst - -set name=t80debugxr_leo - -copy ..\bin\t80debugxr_leo.pin %name%.ucf - -ngdbuild -p %target% %1 %name%.ngd - -goto builddone - -:xst - -xrom MonZ80 11 8 > ..\src\MonZ80.vhd -hex2rom ..\..\..\sw\monitorxr.hex MonZ80 11b8u > MonZ80.ini -copy ..\out\MonZ80.ini + ..\bin\%name%.pin %name%.ucf - -xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp -ngdbuild -p %target% %name%.ngc - -:builddone - -move %name%.bld ..\log - -map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% -move %name%_map.mrp ..\log\%name%.mrp - -par -ol 3 -t 1 %name%_map -w %name% -move %name%.par ..\log - -trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf - -bitgen -w %name% -move %name%.bgn ..\log - -cd ..\run
trunk/syn/xilinx/run/t80debugxr.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/run/t80debug_leo.bat =================================================================== --- trunk/syn/xilinx/run/t80debug_leo.bat (revision 46) +++ trunk/syn/xilinx/run/t80debug_leo.bat (nonexistent) @@ -1,10 +0,0 @@ -cd ..\out - -hex2rom ..\..\..\sw\monitor.hex MonZ80 11b8s > ..\src\MonZ80_leo.vhd - -spectrum -file ..\bin\t80debug.tcl -move exemplar.log ..\log\t80debug_leo.srp - -cd ..\run - -t80debug t80debug_leo.edf xc2s200-pq208-5
trunk/syn/xilinx/run/t80debug_leo.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/run/t80debug.bat =================================================================== --- trunk/syn/xilinx/run/t80debug.bat (revision 46) +++ trunk/syn/xilinx/run/t80debug.bat (nonexistent) @@ -1,46 +0,0 @@ -set name=t80debug -rem set target=xc2v250-cs144-6 -rem set target=xcv300e-pq240-8 -set target=xc2s200-pq208-5 - -if "%2" == "" goto default -set target=%2 -:default - -cd ..\out - -if "%1" == "" goto xst - -set name=t80debug_leo - -copy ..\bin\t80debug.pin %name%.ucf - -ngdbuild -p %target% %1 %name%.ngd - -goto builddone - -:xst - -xrom MonZ80 11 8 > ..\src\MonZ80.vhd -hex2rom ..\..\..\sw\monitor.hex MonZ80 11b8u > MonZ80.ini -copy ..\out\MonZ80.ini + ..\bin\%name%.pin %name%.ucf - -xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp -ngdbuild -p %target% %name%.ngc - -:builddone - -move %name%.bld ..\log - -map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% -move %name%_map.mrp ..\log\%name%.mrp - -par -ol 3 -t 1 %name%_map -w %name% -move %name%.par ..\log - -trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf - -bitgen -w %name% -move %name%.bgn ..\log - -cd ..\run
trunk/syn/xilinx/run/t80debug.bat Property changes : Deleted: svn:executable ## -1 +0,0 ## -* \ No newline at end of property Index: trunk/syn/xilinx/bin/t80_leo.pin =================================================================== --- trunk/syn/xilinx/bin/t80_leo.pin (revision 46) +++ trunk/syn/xilinx/bin/t80_leo.pin (nonexistent) @@ -1,14 +0,0 @@ -#NET "clk" TNM_NET = "clk"; -#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; - -# Leonardo -#NET "Clk" LOC = "P77"; -#NET "Reset_n" LOC = "P133"; -#NET "Port_D(0)" LOC = "P98"; -#NET "Port_D(1)" LOC = "P96"; - -# XST -#NET "clk" LOC = "P77"; -#NET "reset_n" LOC = "P133"; -#NET "port_d<0>" LOC = "P98"; -#NET "port_d<1>" LOC = "P96"; Index: trunk/syn/xilinx/bin/t80.pin =================================================================== --- trunk/syn/xilinx/bin/t80.pin (revision 46) +++ trunk/syn/xilinx/bin/t80.pin (nonexistent) @@ -1,14 +0,0 @@ -#NET "clk" TNM_NET = "clk"; -#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; - -# Leonardo -#NET "Clk" LOC = "P77"; -#NET "Reset_n" LOC = "P134"; -#NET "Port_D(0)" LOC = "P98"; -#NET "Port_D(1)" LOC = "P96"; - -# XST -#NET "clk" LOC = "P77"; -#NET "reset_n" LOC = "P134"; -#NET "port_d<0>" LOC = "P98"; -#NET "port_d<1>" LOC = "P96"; Index: trunk/syn/xilinx/bin/t80debugxr_leo.pin =================================================================== --- trunk/syn/xilinx/bin/t80debugxr_leo.pin (revision 46) +++ trunk/syn/xilinx/bin/t80debugxr_leo.pin (nonexistent) @@ -1,41 +0,0 @@ -#NET "clk" TNM_NET = "clk"; -#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; - -NET "Clk" LOC = "P77"; -NET "Reset_n" LOC = "P152"; -NET "NMI_n" LOC = "P135"; -NET "RXD0" LOC = "P89"; -NET "TXD0" LOC = "P94"; -NET "RXD1" LOC = "P98"; -NET "TXD1" LOC = "P96"; -NET "DTR1" LOC = "P82"; -NET "OE_n" LOC = "P31"; -NET "WE_n" LOC = "P17"; -NET "RAMCS_n" LOC = "P36"; -NET "ROMCS_n" LOC = "P14"; -NET "PGM_n" LOC = "P9"; -NET "A(0)" LOC = "P42"; -NET "A(1)" LOC = "P37"; -NET "A(2)" LOC = "P35"; -NET "A(3)" LOC = "P33"; -NET "A(4)" LOC = "P30"; -NET "A(5)" LOC = "P27"; -NET "A(6)" LOC = "P23"; -NET "A(7)" LOC = "P21"; -NET "A(8)" LOC = "P22"; -NET "A(9)" LOC = "P24"; -NET "A(10)" LOC = "P34"; -NET "A(11)" LOC = "P29"; -NET "A(12)" LOC = "P18"; -NET "A(13)" LOC = "P20"; -NET "A(14)" LOC = "P15"; -NET "A(15)" LOC = "P16"; -NET "A(16)" LOC = "P10"; -NET "D(0)" LOC = "P44"; -NET "D(1)" LOC = "P46"; -NET "D(2)" LOC = "P48"; -NET "D(3)" LOC = "P49"; -NET "D(4)" LOC = "P47"; -NET "D(5)" LOC = "P45"; -NET "D(6)" LOC = "P43"; -NET "D(7)" LOC = "P41"; Index: trunk/syn/xilinx/bin/t80debugxr.pin =================================================================== --- trunk/syn/xilinx/bin/t80debugxr.pin (revision 46) +++ trunk/syn/xilinx/bin/t80debugxr.pin (nonexistent) @@ -1,41 +0,0 @@ -#NET "clk" TNM_NET = "clk"; -#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; - -NET "clk" LOC = "P77"; -NET "reset_n" LOC = "P152"; -NET "nmi_n" LOC = "P135"; -NET "rxd0" LOC = "P89"; -NET "txd0" LOC = "P94"; -NET "rxd1" LOC = "P98"; -NET "txd1" LOC = "P96"; -NET "dtr1" LOC = "P82"; -NET "oe_n" LOC = "P31"; -NET "we_n" LOC = "P17"; -NET "ramcs_n" LOC = "P36"; -NET "romcs_n" LOC = "P14"; -NET "pgm_n" LOC = "P9"; -NET "a<0>" LOC = "P42"; -NET "a<1>" LOC = "P37"; -NET "a<2>" LOC = "P35"; -NET "a<3>" LOC = "P33"; -NET "a<4>" LOC = "P30"; -NET "a<5>" LOC = "P27"; -NET "a<6>" LOC = "P23"; -NET "a<7>" LOC = "P21"; -NET "a<8>" LOC = "P22"; -NET "a<9>" LOC = "P24"; -NET "a<10>" LOC = "P34"; -NET "a<11>" LOC = "P29"; -NET "a<12>" LOC = "P18"; -NET "a<13>" LOC = "P20"; -NET "a<14>" LOC = "P15"; -NET "a<15>" LOC = "P16"; -NET "a<16>" LOC = "P10"; -NET "d<0>" LOC = "P44"; -NET "d<1>" LOC = "P46"; -NET "d<2>" LOC = "P48"; -NET "d<3>" LOC = "P49"; -NET "d<4>" LOC = "P47"; -NET "d<5>" LOC = "P45"; -NET "d<6>" LOC = "P43"; -NET "d<7>" LOC = "P41"; Index: trunk/syn/xilinx/bin/t80.scr =================================================================== --- trunk/syn/xilinx/bin/t80.scr (revision 46) +++ trunk/syn/xilinx/bin/t80.scr (nonexistent) @@ -1,7 +0,0 @@ -run --ifn ../bin/t80.prj --ifmt VHDL --ofn ../out/t80.ngc --ofmt NGC -p xc2s200-pq208-5 --opt_mode Speed --opt_level 2 Index: trunk/syn/xilinx/bin/t80debugxr.scr =================================================================== --- trunk/syn/xilinx/bin/t80debugxr.scr (revision 46) +++ trunk/syn/xilinx/bin/t80debugxr.scr (nonexistent) @@ -1,7 +0,0 @@ -run --ifn ../bin/t80debugxr.prj --ifmt VHDL --ofn ../out/t80debugxr.ngc --ofmt NGC -p xc2s200-pq208-5 --opt_mode Speed --opt_level 2 Index: trunk/syn/xilinx/bin/t80debug.tcl =================================================================== --- trunk/syn/xilinx/bin/t80debug.tcl (revision 46) +++ trunk/syn/xilinx/bin/t80debug.tcl (nonexistent) @@ -1,44 +0,0 @@ -set process "5" -set part "2s200pq208" -set tristate_map "TRUE" -set opt_auto_mode "TRUE" -set opt_best_result "29223.458000" -set dont_lock_lcells "auto" -set input2output "30.000000" -set input2register "20.000000" -set register2output "20.000000" -set register2register "40.000000" -set wire_table "xis215-5_avg" -set encoding "auto" -set edifin_ground_port_names "GND" -set edifin_power_port_names "VCC" -set edif_array_range_extraction_style "%s\[%d:%d\]" - -set_xilinx_eqn - -load_library xis2 - -read -technology xis2 { -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd -../../../rtl/vhdl/T16450.vhd -../src/MonZ80_leo.vhd -../../../rtl/vhdl/SSRAMX.vhd -../../../rtl/vhdl/DebugSystem.vhd -} - -pre_optimize - -optimize -hierarchy=auto - -optimize_timing - -report_area - -report_delay - -write t80debug_leo.edf Index: trunk/syn/xilinx/bin/t80.prj =================================================================== --- trunk/syn/xilinx/bin/t80.prj (revision 46) +++ trunk/syn/xilinx/bin/t80.prj (nonexistent) @@ -1,6 +0,0 @@ -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd Index: trunk/syn/xilinx/bin/t80debugxr.prj =================================================================== --- trunk/syn/xilinx/bin/t80debugxr.prj (revision 46) +++ trunk/syn/xilinx/bin/t80debugxr.prj (nonexistent) @@ -1,9 +0,0 @@ -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd -../../../rtl/vhdl/T16450.vhd -../src/MonZ80.vhd -../../../rtl/vhdl/DebugSystemXR.vhd Index: trunk/syn/xilinx/bin/t80debug.pin =================================================================== --- trunk/syn/xilinx/bin/t80debug.pin (revision 46) +++ trunk/syn/xilinx/bin/t80debug.pin (nonexistent) @@ -1,11 +0,0 @@ -#NET "clk" TNM_NET = "clk"; -#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; - -NET "clk" LOC = "P77"; -NET "reset_n" LOC = "P152"; -NET "nmi_n" LOC = "P135"; -NET "rxd0" LOC = "P89"; -NET "txd0" LOC = "P94"; -NET "rxd1" LOC = "P98"; -NET "txd1" LOC = "P96"; -NET "dtr1" LOC = "P82"; Index: trunk/syn/xilinx/bin/t80debug.scr =================================================================== --- trunk/syn/xilinx/bin/t80debug.scr (revision 46) +++ trunk/syn/xilinx/bin/t80debug.scr (nonexistent) @@ -1,7 +0,0 @@ -run --ifn ../bin/t80debug.prj --ifmt VHDL --ofn ../out/t80debug.ngc --ofmt NGC -p xc2s200-pq208-5 --opt_mode Speed --opt_level 2 Index: trunk/syn/xilinx/bin/t80debug.prj =================================================================== --- trunk/syn/xilinx/bin/t80debug.prj (revision 46) +++ trunk/syn/xilinx/bin/t80debug.prj (nonexistent) @@ -1,10 +0,0 @@ -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd -../../../rtl/vhdl/T16450.vhd -../src/MonZ80.vhd -../../../rtl/vhdl/SSRAMX.vhd -../../../rtl/vhdl/DebugSystem.vhd Index: trunk/syn/xilinx/bin/t80.tcl =================================================================== --- trunk/syn/xilinx/bin/t80.tcl (revision 46) +++ trunk/syn/xilinx/bin/t80.tcl (nonexistent) @@ -1,40 +0,0 @@ -set process "5" -set part "2s200pq208" -set tristate_map "TRUE" -set opt_auto_mode "TRUE" -set opt_best_result "29223.458000" -set dont_lock_lcells "auto" -set input2output "30.000000" -set input2register "20.000000" -set register2output "20.000000" -set register2register "40.000000" -set wire_table "xis215-5_avg" -set encoding "auto" -set edifin_ground_port_names "GND" -set edifin_power_port_names "VCC" -set edif_array_range_extraction_style "%s\[%d:%d\]" - -set_xilinx_eqn - -load_library xis2 - -read -technology xis2 { -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd -} - -pre_optimize - -optimize -area -hierarchy=auto -pass 1 -pass 2 -pass 3 -pass 4 - -optimize_timing - -report_area - -report_delay - -write t80_leo.edf Index: trunk/syn/xilinx/bin/t80debugxr.tcl =================================================================== --- trunk/syn/xilinx/bin/t80debugxr.tcl (revision 46) +++ trunk/syn/xilinx/bin/t80debugxr.tcl (nonexistent) @@ -1,43 +0,0 @@ -set process "5" -set part "2s200pq208" -set tristate_map "TRUE" -set opt_auto_mode "TRUE" -set opt_best_result "29223.458000" -set dont_lock_lcells "auto" -set input2output "30.000000" -set input2register "20.000000" -set register2output "20.000000" -set register2register "40.000000" -set wire_table "xis215-5_avg" -set encoding "auto" -set edifin_ground_port_names "GND" -set edifin_power_port_names "VCC" -set edif_array_range_extraction_style "%s\[%d:%d\]" - -set_xilinx_eqn - -load_library xis2 - -read -technology xis2 { -../../../rtl/vhdl/T80_Pack.vhd -../../../rtl/vhdl/T80_MCode.vhd -../../../rtl/vhdl/T80_ALU.vhd -../../../rtl/vhdl/T80_RegX.vhd -../../../rtl/vhdl/T80.vhd -../../../rtl/vhdl/T80s.vhd -../../../rtl/vhdl/T16450.vhd -../src/MonZ80_leo.vhd -../../../rtl/vhdl/DebugSystemXR.vhd -} - -pre_optimize - -optimize -hierarchy=auto - -optimize_timing - -report_area - -report_delay - -write t80debugxr_leo.edf Index: trunk/bench/vhdl/StimLog.vhd =================================================================== --- trunk/bench/vhdl/StimLog.vhd (revision 46) +++ trunk/bench/vhdl/StimLog.vhd (nonexistent) @@ -1,142 +0,0 @@ --- --- File I/O test-bench utilities --- --- Version : 0146 --- --- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; - -package StimLog is - - component AsyncStim - generic( - FileName : string; - Baud : integer; - InterCharDelay : time := 0 ns; - Bits : integer := 8; -- Data bits - Parity : boolean := false; -- Enable Parity - P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity - ); - port( - TXD : out std_logic - ); - end component; - - component AsyncLog - generic( - FileName : string; - Baud : integer; - Bits : integer := 8; -- Data bits - Parity : boolean := false; -- Enable Parity - P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity - ); - port( - RXD : in std_logic - ); - end component; - - component BinaryStim - generic( - FileName : string; - Bytes : integer := 1; -- Number of bytes per word - LittleEndian : boolean := true -- Byte order - ); - port( - Rd : in std_logic; - Data : out std_logic_vector(Bytes * 8 - 1 downto 0) - ); - end component; - - component BinaryLog - generic( - FileName : string; - Bytes : integer := 1; -- Number of bytes per word - LittleEndian : boolean := true -- Byte order - ); - port( - Clk : in std_logic; - En : in std_logic; - Data : in std_logic_vector(Bytes * 8 - 1 downto 0) - ); - end component; - - component I2SStim is - generic( - FileName : string; - Bytes : integer := 2; -- Number of bytes per word (1 to 4) - LittleEndian : boolean := true -- Byte order - ); - port( - BClk : in std_logic; - FSync : in std_logic; - SData : out std_logic - ); - end component; - - component I2SLog is - generic( - FileName : string; - Bytes : integer := 2; -- Number of bytes per word - LittleEndian : boolean := true -- Byte order - ); - port( - BClk : in std_logic; - FSync : in std_logic; - SData : in std_logic - ); - end component; - - component IntegerLog is - generic( - FileName : string - ); - port( - Clk : in std_logic; - En : in std_logic; - Data : in integer - ); - end component; - -end; Index: trunk/bench/vhdl/AsyncLog.vhd =================================================================== --- trunk/bench/vhdl/AsyncLog.vhd (revision 46) +++ trunk/bench/vhdl/AsyncLog.vhd (nonexistent) @@ -1,124 +0,0 @@ --- --- Asynchronous serial input with binary file log --- --- Version : 0146 --- --- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity AsyncLog is - generic( - FileName : string; - Baud : integer; - Bits : integer := 8; -- Data bits - Parity : boolean := false; -- Enable Parity - P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity - ); - port( - RXD : in std_logic - ); -end AsyncLog; - -architecture behaviour of AsyncLog is - - function to_char( - constant Byte : std_logic_vector(7 downto 0) - ) return character is - begin - return character'val(to_integer(unsigned(Byte))); - end function; - - signal Baud16 : std_logic := '0'; - - -- Receive signals - signal Bit_Phase : unsigned(3 downto 0) := "0000"; - signal RX_ShiftReg : std_logic_vector(Bits - 1 downto 0) := (others => '0'); - signal RX_Bit_Cnt : integer := 0; - signal ParTmp : boolean; - -begin - - Baud16 <= not Baud16 after 1000000000 ns / 32 / Baud; - - process (Baud16) - type ChFile is file of character; - file OutFile : ChFile open write_mode is FileName; - begin - if Baud16'event and Baud16 = '1' then - if RX_Bit_Cnt = 0 and (RXD = '1' or Bit_Phase = "0111") then - Bit_Phase <= "0000"; - else - Bit_Phase <= Bit_Phase + 1; - end if; - if RX_Bit_Cnt = 0 then - if Bit_Phase = "0111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - end if; - ParTmp <= false; - elsif Bit_Phase = "1111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - if (RX_Bit_Cnt = Bits + 1 and not Parity) or - (RX_Bit_Cnt = Bits + 2 and Parity) then -- Stop bit - RX_Bit_Cnt <= 0; - assert RXD = '1' - report "Framing error" - severity error; - write(OutFile, to_char(RX_ShiftReg(7 downto 0))); - elsif RX_Bit_Cnt = Bits + 1 and Parity then -- Parity bit - assert ParTmp xor (RXD = '1') = P_Odd_Even_n - report "Parity error" - severity error; - else - ParTmp <= ParTmp xor (RXD = '1'); - RX_ShiftReg(Bits - 2 downto 0) <= RX_ShiftReg(Bits - 1 downto 1); - RX_ShiftReg(Bits - 1) <= RXD; - end if; - end if; - end if; - end process; - -end; - Index: trunk/bench/vhdl/TestBench.vhd =================================================================== --- trunk/bench/vhdl/TestBench.vhd (revision 46) +++ trunk/bench/vhdl/TestBench.vhd (nonexistent) @@ -1,125 +0,0 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use work.StimLog.all; - -entity TestBench is -end entity TestBench; - -architecture behaviour of TestBench is - - signal M1_n : std_logic; - signal MREQ_n : std_logic; - signal IORQ_n : std_logic; - signal RD_n : std_logic; - signal WR_n : std_logic; - signal RFSH_n : std_logic; - signal HALT_n : std_logic; - signal WAIT_n : std_logic := '1'; - signal INT_n : std_logic := '1'; - signal NMI_n : std_logic := '1'; - signal RESET_n : std_logic; - signal BUSRQ_n : std_logic := '1'; - signal BUSAK_n : std_logic; - signal CLK_n : std_logic := '0'; - signal A : std_logic_vector(15 downto 0); - signal D : std_logic_vector(7 downto 0); - - signal UART_D : std_logic_vector(7 downto 0); - signal BaudOut : std_logic; - signal TXD : std_logic; - signal RXD : std_logic; - signal CTS : std_logic := '0'; - signal DSR : std_logic := '0'; - signal RI : std_logic := '1'; - signal DCD : std_logic := '0'; - - signal IOWR_n : std_logic; - signal ROMCS_n : std_logic; - signal RAMCS_n : std_logic; - signal UARTCS_n : std_logic; - -begin - - Reset_n <= '0', '1' after 1 us; - - -- 16 MHz clock - CLK_n <= not CLK_n after 31.25 ns; - - IOWR_n <= WR_n or IORQ_n; - ROMCS_n <= A(15) or MREQ_n; - RAMCS_n <= not A(15) or MREQ_n; - UARTCS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1'; - - -- NMI - NMI_n <= not D(0) when IOWR_n'event and IOWR_n = '1' and A(7 downto 0) = "00001000"; - -- INT - INT_n <= not D(1) when IOWR_n'event and IOWR_n = '1' and A(7 downto 0) = "00001000"; - - as : AsyncStim generic map(FileName => "../../../bench/vhdl/ROM80.vhd", InterCharDelay => 100 us, Baud => 1000000, Bits => 8) - port map(RXD); - - al : AsyncLog generic map(FileName => "RX_Log.txt", Baud => 1000000, Bits => 8) - port map(TXD); - - u0 : entity work.T80a - port map( - RESET_n, - CLK_n, - WAIT_n, - INT_n, - NMI_n, - BUSRQ_n, - M1_n, - MREQ_n, - IORQ_n, - RD_n, - WR_n, - RFSH_n, - HALT_n, - BUSAK_n, - A, - D); - - u1 : entity work.ROM80 - port map( - CE_n => ROMCS_n, - OE_n => RD_n, - A => A(14 downto 0), - D => D); - - u2 : entity work.SRAM - generic map( - AddrWidth => 15) - port map( - CE_n => RAMCS_n, - OE_n => RD_n, - WE_n => WR_n, - A => A(14 downto 0), - D => D); - - D <= UART_D when UARTCS_n = '0' and RD_n = '0' else "ZZZZZZZZ"; - u3 : entity work.T16450 - port map( - MR_n => Reset_n, - XIn => CLK_n, - RClk => BaudOut, - CS_n => UARTCS_n, - Rd_n => RD_n, - Wr_n => IOWR_n, - A => A(2 downto 0), - D_In => D, - D_Out => UART_D, - SIn => RXD, - CTS_n => CTS, - DSR_n => DSR, - RI_n => RI, - DCD_n => DCD, - SOut => TXD, - RTS_n => open, - DTR_n => open, - OUT1_n => open, - OUT2_n => open, - BaudOut => BaudOut, - Intr => open); - -end; Index: trunk/bench/vhdl/DebugSystem_TB.vhd =================================================================== --- trunk/bench/vhdl/DebugSystem_TB.vhd (revision 46) +++ trunk/bench/vhdl/DebugSystem_TB.vhd (nonexistent) @@ -1,73 +0,0 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use work.StimLog.all; - -entity DebugSystem_TB is -end entity DebugSystem_TB; - -architecture behaviour of DebugSystem_TB is - - signal Reset_n : std_logic; - signal Clk : std_logic := '0'; - signal NMI_n : std_logic := '1'; - - signal TXD0 : std_logic; - signal RTS0 : std_logic; - signal DTR0 : std_logic; - signal RXD0 : std_logic; - signal CTS0 : std_logic := '0'; - signal DSR0 : std_logic := '0'; - signal RI0 : std_logic := '1'; - signal DCD0 : std_logic := '0'; - - signal TXD1 : std_logic; - signal RTS1 : std_logic; - signal DTR1 : std_logic; - signal RXD1 : std_logic; - signal CTS1 : std_logic := '0'; - signal DSR1 : std_logic := '0'; - signal RI1 : std_logic := '1'; - signal DCD1 : std_logic := '0'; - -begin - - ni : entity work.DebugSystem - port map( - Reset_n => Reset_n, - Clk => Clk, - NMI_n => NMI_n, - RXD0 => RXD0, - CTS0 => CTS0, - DSR0 => DSR0, - RI0 => RI0, - DCD0 => DCD0, - RXD1 => RXD1, - CTS1 => CTS1, - DSR1 => DSR1, - RI1 => RI1, - DCD1 => DCD1, - TXD0 => TXD0, - RTS0 => RTS0, - DTR0 => DTR0, - TXD1 => TXD1, - RTS1 => RTS1, - DTR1 => DTR1); - - as0 : AsyncStim generic map(FileName => "../../../bench/vhdl/ROM80.vhd", InterCharDelay => 0 us, Baud => 115200, Bits => 8) - port map(RXD0); - - al0 : AsyncLog generic map(FileName => "RX_Log0.txt", Baud => 115200, Bits => 8) - port map(TXD0); - - as1 : AsyncStim generic map(FileName => "RX_Cmd1.txt", InterCharDelay => 0 us, Baud => 115200, Bits => 8) - port map(RXD1); - - al1 : AsyncLog generic map(FileName => "RX_Log1.txt", Baud => 115200, Bits => 8) - port map(TXD1); - - Reset_n <= '0', '1' after 1 us; - - -- 18 MHz clock - Clk <= not Clk after 27 ns; - -end; Index: trunk/bench/vhdl/SRAM.vhd =================================================================== --- trunk/bench/vhdl/SRAM.vhd (revision 46) +++ trunk/bench/vhdl/SRAM.vhd (nonexistent) @@ -1,92 +0,0 @@ --- --- Simple SRAM model without timing --- --- Version : 0247 --- --- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity SRAM is - generic( - AddrWidth : integer := 16; - DataWidth : integer := 8 - ); - port( - CE_n : in std_logic; - OE_n : in std_logic; - WE_n : in std_logic; - A : in std_logic_vector(AddrWidth - 1 downto 0); - D : inout std_logic_vector(DataWidth - 1 downto 0) - ); -end SRAM; - -architecture behaviour of SRAM is - - type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); - signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); - - signal Write : std_logic; - signal D_del : std_logic_vector(7 downto 0); - -begin - - Write <= '1' when CE_n = '0' and WE_n = '0' else '0'; - D_del <= D after 1 ns; - - process (Write) - begin - if Write'event and Write = '0' then - RAM(to_integer(unsigned(A))) <= D_del; - end if; - end process; - - D <= RAM(to_integer(unsigned(A))) --- pragma translate_off - when OE_n = '0' and CE_n = '0' and WE_n = '1' and not is_x(A) else (others => 'Z') --- pragma translate_on - ; - -end; Index: trunk/bench/vhdl/AsyncStim.vhd =================================================================== --- trunk/bench/vhdl/AsyncStim.vhd (revision 46) +++ trunk/bench/vhdl/AsyncStim.vhd (nonexistent) @@ -1,115 +0,0 @@ --- --- Asynchronous serial generator with input from binary file --- --- Version : 0146 --- --- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity AsyncStim is - generic( - FileName : string; - Baud : integer; - InterCharDelay : time := 0 ns; - Bits : integer := 8; -- Data bits - Parity : boolean := false; -- Enable Parity - P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity - ); - port( - TXD : out std_logic - ); -end AsyncStim; - -architecture behaviour of AsyncStim is - - signal TX_ShiftReg : std_logic_vector(Bits - 1 downto 0); - signal TX_Bit_Cnt : integer range 0 to 15 := 0; - signal ParTmp : boolean; - -begin - - process - type ChFile is file of character; - file InFile : ChFile open read_mode is FileName; - variable Inited : boolean := false; - variable CharTmp : character; - variable IntTmp : integer; - begin - if not Inited then - Inited := true; - TXD <= '1'; - end if; - wait for 1000000000 ns / Baud; - TX_Bit_Cnt <= TX_Bit_Cnt + 1; - case TX_Bit_Cnt is - when 0 => - TXD <= '1'; - wait for InterCharDelay; - when 1 => -- Start bit - read(InFile, CharTmp); - IntTmp := character'pos(CharTmp); - TX_ShiftReg(Bits - 1 downto 0) <= std_logic_vector(to_unsigned(IntTmp, Bits)); - TXD <= '0'; - ParTmp <= P_Odd_Even_n; - when others => - TXD <= TX_ShiftReg(0); - ParTmp <= ParTmp xor (TX_ShiftReg(0) = '1'); - TX_ShiftReg(Bits - 2 downto 0) <= TX_ShiftReg(Bits - 1 downto 1); - if (TX_Bit_Cnt = Bits + 1 and not Parity) or - (TX_Bit_Cnt = Bits + 2 and Parity) then -- Stop bit - TX_Bit_Cnt <= 0; - end if; - if Parity and TX_Bit_Cnt = Bits + 2 then - if ParTmp then - TXD <= '1'; - else - TXD <= '0'; - end if; - end if; - end case; - end process; - -end; Index: trunk/rtl/vhdl/T80_MCode.vhd =================================================================== --- trunk/rtl/vhdl/T80_MCode.vhd (revision 46) +++ trunk/rtl/vhdl/T80_MCode.vhd (nonexistent) @@ -1,1934 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0211 : Fixed IM 1 --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0235 : Added IM 2 fix by Mike Johnson --- --- 0238 : Added NoRead signal --- --- 0238b: Fixed instruction timing for POP and DJNZ --- --- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes --- --- 0242 : Fixed I/O instruction timing, cleanup --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_MCode is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic - ); -end T80_MCode; - -architecture rtl of T80_MCode is - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; --- constant aNone : std_logic_vector(2 downto 0) := "000"; --- constant aXY : std_logic_vector(2 downto 0) := "001"; --- constant aIOA : std_logic_vector(2 downto 0) := "010"; --- constant aSP : std_logic_vector(2 downto 0) := "011"; --- constant aBC : std_logic_vector(2 downto 0) := "100"; --- constant aDE : std_logic_vector(2 downto 0) := "101"; --- constant aZI : std_logic_vector(2 downto 0) := "110"; - - function is_cc_true( - F : std_logic_vector(7 downto 0); - cc : bit_vector(2 downto 0) - ) return boolean is - begin - if Mode = 3 then - case cc is - when "000" => return F(7) = '0'; -- NZ - when "001" => return F(7) = '1'; -- Z - when "010" => return F(4) = '0'; -- NC - when "011" => return F(4) = '1'; -- C - when "100" => return false; - when "101" => return false; - when "110" => return false; - when "111" => return false; - end case; - else - case cc is - when "000" => return F(6) = '0'; -- NZ - when "001" => return F(6) = '1'; -- Z - when "010" => return F(0) = '0'; -- NC - when "011" => return F(0) = '1'; -- C - when "100" => return F(2) = '0'; -- PO - when "101" => return F(2) = '1'; -- PE - when "110" => return F(7) = '0'; -- P - when "111" => return F(7) = '1'; -- M - end case; - end if; - end; - -begin - - process (IR, ISet, MCycle, F, NMICycle, IntCycle) - variable DDD : std_logic_vector(2 downto 0); - variable SSS : std_logic_vector(2 downto 0); - variable DPair : std_logic_vector(1 downto 0); - variable IRB : bit_vector(7 downto 0); - begin - DDD := IR(5 downto 3); - SSS := IR(2 downto 0); - DPair := IR(5 downto 4); - IRB := to_bitvector(IR); - - MCycles <= "001"; - if MCycle = "001" then - TStates <= "100"; - else - TStates <= "011"; - end if; - Prefix <= "00"; - Inc_PC <= '0'; - Inc_WZ <= '0'; - IncDec_16 <= "0000"; - Read_To_Acc <= '0'; - Read_To_Reg <= '0'; - Set_BusB_To <= "0000"; - Set_BusA_To <= "0000"; - ALU_Op <= "0" & IR(5 downto 3); - Save_ALU <= '0'; - PreserveC <= '0'; - Arith16 <= '0'; - IORQ <= '0'; - Set_Addr_To <= aNone; - Jump <= '0'; - JumpE <= '0'; - JumpXY <= '0'; - Call <= '0'; - RstP <= '0'; - LDZ <= '0'; - LDW <= '0'; - LDSPHL <= '0'; - Special_LD <= "000"; - ExchangeDH <= '0'; - ExchangeRp <= '0'; - ExchangeAF <= '0'; - ExchangeRS <= '0'; - I_DJNZ <= '0'; - I_CPL <= '0'; - I_CCF <= '0'; - I_SCF <= '0'; - I_RETN <= '0'; - I_BT <= '0'; - I_BC <= '0'; - I_BTR <= '0'; - I_RLD <= '0'; - I_RRD <= '0'; - I_INRC <= '0'; - SetDI <= '0'; - SetEI <= '0'; - IMode <= "11"; - Halt <= '0'; - NoRead <= '0'; - Write <= '0'; - - case ISet is - when "00" => - ------------------------------------------------------------------------------- --- --- Unprefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is --- 8 BIT LOAD GROUP - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- LD r,r' - Set_BusB_To(2 downto 0) <= SSS; - ExchangeRp <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => - -- LD r,n - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => - -- LD r,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => - -- LD (HL),r - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110110" => - -- LD (HL),n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00001010" => - -- LD A,(BC) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00011010" => - -- LD A,(DE) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00111010" => - if Mode = 3 then - -- LDD A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end if; - when "00000010" => - -- LD (BC),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00010010" => - -- LD (DE),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110010" => - if Mode = 3 then - -- LDD (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - end if; - --- 16 BIT LOAD GROUP - when "00000001"|"00010001"|"00100001"|"00110001" => - -- LD dd,nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1000"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1001"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "00101010" => - if Mode = 3 then - -- LDI A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD HL,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; - when others => null; - end case; - end if; - when "00100010" => - if Mode = 3 then - -- LDI (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD (nn),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "0101"; -- L - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "0100"; -- H - when 5 => - Write <= '1'; - when others => null; - end case; - end if; - when "11111001" => - -- LD SP,HL - TStates <= "110"; - LDSPHL <= '1'; - when "11000101"|"11010101"|"11100101"|"11110101" => - -- PUSH qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 2 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 3 => - Write <= '1'; - when others => null; - end case; - when "11000001"|"11010001"|"11100001"|"11110001" => - -- POP qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1011"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - IncDec_16 <= "0111"; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "0111"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - --- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP - when "11101011" => - if Mode /= 3 then - -- EX DE,HL - ExchangeDH <= '1'; - end if; - when "00001000" => - if Mode = 3 then - -- LD (nn),SP - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "1000"; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "1001"; - when 5 => - Write <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EX AF,AF' - ExchangeAF <= '1'; - end if; - when "11011001" => - if Mode = 3 then - -- RETI - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - I_RETN <= '1'; - SetEI <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EXX - ExchangeRS <= '1'; - end if; - when "11100011" => - if Mode /= 3 then - -- EX (SP),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - Read_To_Reg <= '1'; - Set_BusA_To <= "0101"; - Set_BusB_To <= "0101"; - Set_Addr_To <= aSP; - when 3 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - TStates <= "100"; - Write <= '1'; - when 4 => - Read_To_Reg <= '1'; - Set_BusA_To <= "0100"; - Set_BusB_To <= "0100"; - Set_Addr_To <= aSP; - when 5 => - IncDec_16 <= "1111"; - TStates <= "101"; - Write <= '1'; - when others => null; - end case; - end if; - --- 8 BIT ARITHMETIC AND LOGICAL GROUP - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- ADD A,r - -- ADC A,r - -- SUB A,r - -- SBC A,r - -- AND A,r - -- OR A,r - -- XOR A,r - -- CP A,r - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- ADD A,(HL) - -- ADC A,(HL) - -- SUB A,(HL) - -- SBC A,(HL) - -- AND A,(HL) - -- OR A,(HL) - -- XOR A,(HL) - -- CP A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - when others => null; - end case; - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- ADD A,n - -- ADC A,n - -- SUB A,n - -- SBC A,n - -- AND A,n - -- OR A,n - -- XOR A,n - -- CP A,n - MCycles <= "010"; - if MCycle = "010" then - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - end if; - when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => - -- INC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - when "00110100" => - -- INC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => - -- DEC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0010"; - when "00110101" => - -- DEC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - ALU_Op <= "0010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - --- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS - when "00100111" => - -- DAA - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - ALU_Op <= "1100"; - Save_ALU <= '1'; - when "00101111" => - -- CPL - I_CPL <= '1'; - when "00111111" => - -- CCF - I_CCF <= '1'; - when "00110111" => - -- SCF - I_SCF <= '1'; - when "00000000" => - if NMICycle = '1' then - -- NMI - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - TStates <= "100"; - Write <= '1'; - when others => null; - end case; - elsif IntCycle = '1' then - -- INT (IM 2) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - LDZ <= '1'; - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - TStates <= "100"; - Write <= '1'; - when 4 => - Inc_PC <= '1'; - LDZ <= '1'; - when 5 => - Jump <= '1'; - when others => null; - end case; - else - -- NOP - end if; - when "01110110" => - -- HALT - Halt <= '1'; - when "11110011" => - -- DI - SetDI <= '1'; - when "11111011" => - -- EI - SetEI <= '1'; - --- 16 BIT ARITHMETIC GROUP - when "00001001"|"00011001"|"00101001"|"00111001" => - -- ADD HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - Arith16 <= '1'; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - Arith16 <= '1'; - when others => - end case; - when "00000011"|"00010011"|"00100011"|"00110011" => - -- INC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; - when "00001011"|"00011011"|"00101011"|"00111011" => - -- DEC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; - --- ROTATE AND SHIFT GROUP - when "00000111" - -- RLCA - |"00010111" - -- RLA - |"00001111" - -- RRCA - |"00011111" => - -- RRA - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - --- JUMP GROUP - when "11000011" => - -- JP nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - Jump <= '1'; - when others => null; - end case; - when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+C),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IORQ <= '1'; - when others => - end case; - when "01" => - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - when "10" => - -- LD A,($FF00+C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - Read_To_Acc <= '1'; - IORQ <= '1'; - when others => - end case; - when "11" => - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end case; - else - -- JP cc,nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Jump <= '1'; - end if; - when others => null; - end case; - end if; - when "00011000" => - if Mode /= 2 then - -- JR e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00111000" => - if Mode /= 2 then - -- JR C,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '0' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00110000" => - if Mode /= 2 then - -- JR NC,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '1' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00101000" => - if Mode /= 2 then - -- JR Z,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '0' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00100000" => - if Mode /= 2 then - -- JR NZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '1' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "11101001" => - -- JP (HL) - JumpXY <= '1'; - when "00010000" => - if Mode = 3 then - I_DJNZ <= '1'; - elsif Mode < 2 then - -- DJNZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - I_DJNZ <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= "000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - I_DJNZ <= '1'; - Inc_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - --- CALL AND RETURN GROUP - when "11001101" => - -- CALL nn - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - IncDec_16 <= "1111"; - Inc_PC <= '1'; - TStates <= "100"; - Set_Addr_To <= aSP; - LDW <= '1'; - Set_BusB_To <= "1101"; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => - if IR(5) = '0' or Mode /= 3 then - -- CALL cc,nn - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - LDW <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - TStates <= "100"; - Set_BusB_To <= "1101"; - else - MCycles <= "011"; - end if; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - end if; - when "11001001" => - -- RET - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+nn),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - when others => null; - end case; - when "01" => - -- ADD SP,n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - ALU_Op <= "0000"; - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To <= "1000"; - Set_BusB_To <= "0110"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To <= "1001"; - Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! - when others => - end case; - when "10" => - -- LD A,($FF00+nn) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; - when others => null; - end case; - end case; - else - -- RET cc - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "001"; - end if; - TStates <= "101"; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - end if; - when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => - -- RST p - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; - --- INPUT AND OUTPUT GROUP - when "11011011" => - if Mode /= 3 then - -- IN A,(n) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - when "11010011" => - if Mode /= 3 then - -- OUT (n),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- --- MULTIBYTE INSTRUCTIONS ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- - - when "11001011" => - if Mode /= 2 then - Prefix <= "01"; - end if; - - when "11101101" => - if Mode < 2 then - Prefix <= "10"; - end if; - - when "11011101"|"11111101" => - if Mode < 2 then - Prefix <= "11"; - end if; - - end case; - - when "01" => - ------------------------------------------------------------------------------- --- --- CB prefixed instructions --- ------------------------------------------------------------------------------- - - Set_BusA_To(2 downto 0) <= IR(2 downto 0); - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => - -- RLC r - -- RL r - -- RRC r - -- RR r - -- SLA r - -- SRA r - -- SRL r - -- SLL r (Undocumented) / SWAP r - if MCycle = "001" then - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => - -- RLC (HL) - -- RL (HL) - -- RRC (HL) - -- RR (HL) - -- SRA (HL) - -- SRL (HL) - -- SLA (HL) - -- SLL (HL) (Undocumented) / SWAP (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- BIT b,r - if MCycle = "001" then - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - ALU_Op <= "1001"; - end if; - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => - -- BIT b,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1001"; - TStates <= "100"; - when others => - end case; - when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => - -- SET b,r - if MCycle = "001" then - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- SET b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- RES b,r - if MCycle = "001" then - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- RES b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - end case; - - when others => - ------------------------------------------------------------------------------- --- --- ED prefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" - - - |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" - | "10100100"|"10100101"|"10100110"|"10100111" - | "10101100"|"10101101"|"10101110"|"10101111" - | "10110100"|"10110101"|"10110110"|"10110111" - | "10111100"|"10111101"|"10111110"|"10111111" - |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => - null; -- NOP, undocumented - when "01111110"|"01111111" => - -- NOP, undocumented - null; --- 8 BIT LOAD GROUP - when "01010111" => - -- LD A,I - Special_LD <= "100"; - TStates <= "101"; - when "01011111" => - -- LD A,R - Special_LD <= "101"; - TStates <= "101"; - when "01000111" => - -- LD I,A - Special_LD <= "110"; - TStates <= "101"; - when "01001111" => - -- LD R,A - Special_LD <= "111"; - TStates <= "101"; --- 16 BIT LOAD GROUP - when "01001011"|"01011011"|"01101011"|"01111011" => - -- LD dd,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1000"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '1'; - end if; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1001"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "01000011"|"01010011"|"01100011"|"01110011" => - -- LD (nn),dd - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1000"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1001"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 5 => - Write <= '1'; - when others => null; - end case; - when "10100000" | "10101000" | "10110000" | "10111000" => - -- LDI, LDD, LDIR, LDDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0000"; - Set_Addr_To <= aDE; - if IR(3) = '0' then - IncDec_16 <= "0110"; -- IX - else - IncDec_16 <= "1110"; - end if; - when 3 => - I_BT <= '1'; - TStates <= "101"; - Write <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0101"; -- DE - else - IncDec_16 <= "1101"; - end if; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100001" | "10101001" | "10110001" | "10111001" => - -- CPI, CPD, CPIR, CPDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0111"; - Save_ALU <= '1'; - PreserveC <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0110"; - else - IncDec_16 <= "1110"; - end if; - when 3 => - NoRead <= '1'; - I_BC <= '1'; - TStates <= "101"; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => - -- NEG - Alu_OP <= "0010"; - Set_BusB_To <= "0111"; - Set_BusA_To <= "1010"; - Read_To_Acc <= '1'; - Save_ALU <= '1'; - when "01000110"|"01001110"|"01100110"|"01101110" => - -- IM 0 - IMode <= "00"; - when "01010110"|"01110110" => - -- IM 1 - IMode <= "01"; - when "01011110"|"01110111" => - -- IM 2 - IMode <= "10"; --- 16 bit arithmetic - when "01001010"|"01011010"|"01101010"|"01111010" => - -- ADC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0001"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01000010"|"01010010"|"01100010"|"01110010" => - -- SBC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - when 3 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01101111" => - -- RLD - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - Set_Addr_To <= aXY; - when 3 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1101"; - TStates <= "100"; - Set_Addr_To <= aXY; - Save_ALU <= '1'; - when 4 => - I_RLD <= '1'; - Write <= '1'; - when others => - end case; - when "01100111" => - -- RRD - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Set_Addr_To <= aXY; - when 3 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1110"; - TStates <= "100"; - Set_Addr_To <= aXY; - Save_ALU <= '1'; - when 4 => - I_RRD <= '1'; - Write <= '1'; - when others => - end case; - when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => - -- RETI, RETN - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - I_RETN <= '1'; - when others => null; - end case; - when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => - -- IN r,(C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - IORQ <= '1'; - if IR(5 downto 3) /= "110" then - Read_To_Reg <= '1'; - Set_BusA_To(2 downto 0) <= IR(5 downto 3); - end if; - I_INRC <= '1'; - when others => - end case; - when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => - -- OUT (C),r - -- OUT (C),0 - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To(2 downto 0) <= IR(5 downto 3); - if IR(5 downto 3) = "110" then - Set_BusB_To(3) <= '1'; - end if; - when 2 => - Write <= '1'; - IORQ <= '1'; - when others => - end case; - when "10100010" | "10101010" | "10110010" | "10111010" => - -- INI, IND, INIR, INDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - IORQ <= '1'; - Set_BusB_To <= "0110"; - Set_Addr_To <= aXY; - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0010"; - else - IncDec_16 <= "1010"; - end if; - TStates <= "100"; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100011" | "10101011" | "10110011" | "10111011" => - -- OUTI, OUTD, OTIR, OTDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_To <= aXY; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - Set_BusB_To <= "0110"; - Set_Addr_To <= aBC; - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0010"; - else - IncDec_16 <= "1010"; - end if; - IORQ <= '1'; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - end case; - - end case; - - if Mode = 1 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "011"; - end if; - end if; - - if Mode = 3 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "100"; - end if; - end if; - - if Mode < 2 then - if MCycle = "110" then - Inc_PC <= '1'; - if Mode = 1 then - Set_Addr_To <= aXY; - TStates <= "100"; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - end if; - if IRB = "00110110" or IRB = "11001011" then - Set_Addr_To <= aNone; - end if; - end if; - if MCycle = "111" then - if Mode = 0 then - TStates <= "101"; - end if; - if ISet /= "01" then - Set_Addr_To <= aXY; - end if; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - if IRB = "00110110" or ISet = "01" then - -- LD (HL),n - Inc_PC <= '1'; - else - NoRead <= '1'; - end if; - end if; - end if; - - end process; - -end; Index: trunk/rtl/vhdl/SSRAM.vhd =================================================================== --- trunk/rtl/vhdl/SSRAM.vhd (revision 46) +++ trunk/rtl/vhdl/SSRAM.vhd (nonexistent) @@ -1,92 +0,0 @@ --- --- Inferrable Synchronous SRAM for XST synthesis --- --- Version : 0220 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- 0208 : Initial release --- 0218 : Fixed data out at write --- 0220 : Added support for XST - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity SSRAM is - generic( - AddrWidth : integer := 11; - DataWidth : integer := 8 - ); - port( - Clk : in std_logic; - CE_n : in std_logic; - WE_n : in std_logic; - A : in std_logic_vector(AddrWidth - 1 downto 0); - DIn : in std_logic_vector(DataWidth - 1 downto 0); - DOut : out std_logic_vector(DataWidth - 1 downto 0) - ); -end SSRAM; - -architecture behaviour of SSRAM is - - type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); - signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); - signal A_r : std_logic_vector(AddrWidth - 1 downto 0); - -begin - - process (Clk) - begin - if Clk'event and Clk = '1' then - if (CE_n nor WE_n) = '1' then - RAM(to_integer(unsigned(A))) <= DIn; - end if; - A_r <= A; - end if; - end process; - - DOut <= RAM(to_integer(unsigned(A_r))) --- pragma translate_off - when not is_x(A_r) else (others => '-') --- pragma translate_on - ; -end; Index: trunk/rtl/vhdl/DebugSystem.vhd =================================================================== --- trunk/rtl/vhdl/DebugSystem.vhd (revision 46) +++ trunk/rtl/vhdl/DebugSystem.vhd (nonexistent) @@ -1,181 +0,0 @@ --- Z80, Monitor ROM, 4k RAM and two 16450 UARTs --- that can be synthesized and used with --- the NoICE debugger that can be found at --- http://www.noicedebugger.com/ - -library IEEE; -use IEEE.std_logic_1164.all; - -entity DebugSystem is - port( - Reset_n : in std_logic; - Clk : in std_logic; - NMI_n : in std_logic; - RXD0 : in std_logic; - CTS0 : in std_logic; - DSR0 : in std_logic; - RI0 : in std_logic; - DCD0 : in std_logic; - RXD1 : in std_logic; - CTS1 : in std_logic; - DSR1 : in std_logic; - RI1 : in std_logic; - DCD1 : in std_logic; - TXD0 : out std_logic; - RTS0 : out std_logic; - DTR0 : out std_logic; - TXD1 : out std_logic; - RTS1 : out std_logic; - DTR1 : out std_logic - ); -end DebugSystem; - -architecture struct of DebugSystem is - - signal M1_n : std_logic; - signal MREQ_n : std_logic; - signal IORQ_n : std_logic; - signal RD_n : std_logic; - signal WR_n : std_logic; - signal RFSH_n : std_logic; - signal HALT_n : std_logic; - signal WAIT_n : std_logic; - signal INT_n : std_logic; - signal RESET_s : std_logic; - signal BUSRQ_n : std_logic; - signal BUSAK_n : std_logic; - signal A : std_logic_vector(15 downto 0); - signal D : std_logic_vector(7 downto 0); - signal ROM_D : std_logic_vector(7 downto 0); - signal SRAM_D : std_logic_vector(7 downto 0); - signal UART0_D : std_logic_vector(7 downto 0); - signal UART1_D : std_logic_vector(7 downto 0); - signal CPU_D : std_logic_vector(7 downto 0); - - signal Mirror : std_logic; - - signal IOWR_n : std_logic; - signal RAMCS_n : std_logic; - signal UART0CS_n : std_logic; - signal UART1CS_n : std_logic; - - signal BaudOut0 : std_logic; - signal BaudOut1 : std_logic; - -begin - - Wait_n <= '1'; - BusRq_n <= '1'; - INT_n <= '1'; - - process (Reset_n, Clk) - begin - if Reset_n = '0' then - Reset_s <= '0'; - Mirror <= '0'; - elsif Clk'event and Clk = '1' then - Reset_s <= '1'; - if IORQ_n = '0' and A(7 downto 4) = "1111" then - Mirror <= D(0); - end if; - end if; - end process; - - IOWR_n <= WR_n or IORQ_n; - RAMCS_n <= (not Mirror and not A(15)) or MREQ_n; - UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1'; - UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1'; - - CPU_D <= - SRAM_D when RAMCS_n = '0' else - UART0_D when UART0CS_n = '0' else - UART1_D when UART1CS_n = '0' else - ROM_D; - - u0 : entity work.T80s - generic map(Mode => 1, T2Write => 1, IOWait => 0) - port map( - RESET_n => RESET_s, - CLK_n => Clk, - WAIT_n => WAIT_n, - INT_n => INT_n, - NMI_n => NMI_n, - BUSRQ_n => BUSRQ_n, - M1_n => M1_n, - MREQ_n => MREQ_n, - IORQ_n => IORQ_n, - RD_n => RD_n, - WR_n => WR_n, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - BUSAK_n => BUSAK_n, - A => A, - DI => CPU_D, - DO => D); - - u1 : entity work.MonZ80 - port map( - Clk => Clk, - A => A(10 downto 0), - D => ROM_D); - - u2 : entity work.SSRAM - generic map( - AddrWidth => 12) - port map( - Clk => Clk, - CE_n => RAMCS_n, - WE_n => WR_n, - A => A(11 downto 0), - DIn => D, - DOut => SRAM_D); - - u3 : entity work.T16450 - port map( - MR_n => Reset_s, - XIn => Clk, - RClk => BaudOut0, - CS_n => UART0CS_n, - Rd_n => RD_n, - Wr_n => IOWR_n, - A => A(2 downto 0), - D_In => D, - D_Out => UART0_D, - SIn => RXD0, - CTS_n => CTS0, - DSR_n => DSR0, - RI_n => RI0, - DCD_n => DCD0, - SOut => TXD0, - RTS_n => RTS0, - DTR_n => DTR0, - OUT1_n => open, - OUT2_n => open, - BaudOut => BaudOut0, - Intr => open); - - u4 : entity work.T16450 - port map( - MR_n => Reset_s, - XIn => Clk, - RClk => BaudOut1, - CS_n => UART1CS_n, - Rd_n => RD_n, - Wr_n => IOWR_n, - A => A(2 downto 0), - D_In => D, - D_Out => UART1_D, - SIn => RXD1, - CTS_n => CTS1, - DSR_n => DSR1, - RI_n => RI1, - DCD_n => DCD1, - SOut => TXD1, - RTS_n => RTS1, - DTR_n => DTR1, - OUT1_n => open, - OUT2_n => open, - BaudOut => BaudOut1, - Intr => open); - -end; Index: trunk/rtl/vhdl/T80s.vhd =================================================================== --- trunk/rtl/vhdl/T80s.vhd (revision 46) +++ trunk/rtl/vhdl/T80s.vhd (nonexistent) @@ -1,190 +0,0 @@ --- --- Z80 compatible microprocessor core, synchronous top level --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0210 : Fixed read with wait --- --- 0211 : Fixed interrupt cycle --- --- 0235 : Updated for T80 interface change --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80s is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80s; - -architecture rtl of T80s is - - signal CEN : std_logic; - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - CEN <= '1'; - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/T80_RegX.vhd =================================================================== --- trunk/rtl/vhdl/T80_RegX.vhd (revision 46) +++ trunk/rtl/vhdl/T80_RegX.vhd (nonexistent) @@ -1,167 +0,0 @@ --- --- T80 Registers for Xilinx Select RAM --- --- Version : 0244 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- --- 0242 : Initial release --- --- 0244 : Removed UNISIM library and added componet declaration --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_Reg is - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0) - ); -end T80_Reg; - -architecture rtl of T80_Reg is - - component RAM16X1D - port( - DPO : out std_ulogic; - SPO : out std_ulogic; - A0 : in std_ulogic; - A1 : in std_ulogic; - A2 : in std_ulogic; - A3 : in std_ulogic; - D : in std_ulogic; - DPRA0 : in std_ulogic; - DPRA1 : in std_ulogic; - DPRA2 : in std_ulogic; - DPRA3 : in std_ulogic; - WCLK : in std_ulogic; - WE : in std_ulogic); - end component; - - signal ENH : std_logic; - signal ENL : std_logic; - -begin - - ENH <= CEN and WEH; - ENL <= CEN and WEL; - - bG1: for I in 0 to 7 generate - begin - Reg1H : RAM16X1D - port map( - DPO => DOBH(i), - SPO => DOAH(i), - A0 => AddrA(0), - A1 => AddrA(1), - A2 => AddrA(2), - A3 => '0', - D => DIH(i), - DPRA0 => AddrB(0), - DPRA1 => AddrB(1), - DPRA2 => AddrB(2), - DPRA3 => '0', - WCLK => Clk, - WE => ENH); - Reg1L : RAM16X1D - port map( - DPO => DOBL(i), - SPO => DOAL(i), - A0 => AddrA(0), - A1 => AddrA(1), - A2 => AddrA(2), - A3 => '0', - D => DIL(i), - DPRA0 => AddrB(0), - DPRA1 => AddrB(1), - DPRA2 => AddrB(2), - DPRA3 => '0', - WCLK => Clk, - WE => ENL); - Reg2H : RAM16X1D - port map( - DPO => DOCH(i), - SPO => open, - A0 => AddrA(0), - A1 => AddrA(1), - A2 => AddrA(2), - A3 => '0', - D => DIH(i), - DPRA0 => AddrC(0), - DPRA1 => AddrC(1), - DPRA2 => AddrC(2), - DPRA3 => '0', - WCLK => Clk, - WE => ENH); - Reg2L : RAM16X1D - port map( - DPO => DOCL(i), - SPO => open, - A0 => AddrA(0), - A1 => AddrA(1), - A2 => AddrA(2), - A3 => '0', - D => DIL(i), - DPRA0 => AddrC(0), - DPRA1 => AddrC(1), - DPRA2 => AddrC(2), - DPRA3 => '0', - WCLK => Clk, - WE => ENL); - end generate; - -end; Index: trunk/rtl/vhdl/T80se.vhd =================================================================== --- trunk/rtl/vhdl/T80se.vhd (revision 46) +++ trunk/rtl/vhdl/T80se.vhd (nonexistent) @@ -1,184 +0,0 @@ --- --- Z80 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0235 : First release --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80se is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80se; - -architecture rtl of T80se is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - CEN => CLKEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - if CLKEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/T16450.vhd =================================================================== --- trunk/rtl/vhdl/T16450.vhd (revision 46) +++ trunk/rtl/vhdl/T16450.vhd (nonexistent) @@ -1,459 +0,0 @@ --- --- 16450 compatible UART with synchronous bus interface --- RClk/BaudOut is XIn enable instead of actual clock --- --- Version : 0249b --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First release --- --- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer --- Added modem status and break detection --- Added support for 1.5 and 2 stop bits --- --- 0249b : Fixed loopback break generation bugs found by Andy Dyer --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T16450 is - port( - MR_n : in std_logic; - XIn : in std_logic; - RClk : in std_logic; - CS_n : in std_logic; - Rd_n : in std_logic; - Wr_n : in std_logic; - A : in std_logic_vector(2 downto 0); - D_In : in std_logic_vector(7 downto 0); - D_Out : out std_logic_vector(7 downto 0); - SIn : in std_logic; - CTS_n : in std_logic; - DSR_n : in std_logic; - RI_n : in std_logic; - DCD_n : in std_logic; - SOut : out std_logic; - RTS_n : out std_logic; - DTR_n : out std_logic; - OUT1_n : out std_logic; - OUT2_n : out std_logic; - BaudOut : out std_logic; - Intr : out std_logic - ); -end T16450; - -architecture rtl of T16450 is - - signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register - signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register - signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register - signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register - signal LCR : std_logic_vector(7 downto 0); -- Line Control Register - signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register - signal LSR : std_logic_vector(7 downto 0); -- Line Status Register - signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register - signal SCR : std_logic_vector(7 downto 0); -- Scratch Register - signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS) - signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS) - - signal DM0 : std_logic_vector(7 downto 0); - signal DM1 : std_logic_vector(7 downto 0); - - signal MSR_In : std_logic_vector(3 downto 0); - - signal Bit_Phase : unsigned(3 downto 0); - signal Brk_Cnt : unsigned(3 downto 0); - signal RX_Filtered : std_logic; - signal RX_ShiftReg : std_logic_vector(7 downto 0); - signal RX_Bit_Cnt : integer range 0 to 11; - signal RX_Parity : std_logic; - signal RXD : std_logic; - - signal TX_Tick : std_logic; - signal TX_ShiftReg : std_logic_vector(7 downto 0); - signal TX_Bit_Cnt : integer range 0 to 11; - signal TX_Parity : std_logic; - signal TX_Next_Is_Stop : std_logic; - signal TX_Stop_Bit : std_logic; - signal TXD : std_logic; - -begin - - DTR_n <= MCR(4) or not MCR(0); - RTS_n <= MCR(4) or not MCR(1); - OUT1_n <= MCR(4) or not MCR(2); - OUT2_n <= MCR(4) or not MCR(3); - SOut <= MCR(4) or (TXD and not LCR(6)); - RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6)); - - Intr <= not IIR(0); - - -- Registers - DM0 <= DLL when LCR(7) = '1' else RBR; - DM1 <= DLM when LCR(7) = '1' else IER; - with A select - D_Out <= - DM0 when "000", - DM1 when "001", - IIR when "010", - LCR when "011", - MCR when "100", - LSR when "101", - MSR when "110", - SCR when others; - process (MR_n, XIn) - begin - if MR_n = '0' then - THR <= "00000000"; - IER <= "00000000"; - LCR <= "00000000"; - MCR <= "00000000"; - MSR(3 downto 0) <= "0000"; - SCR <= "00000000"; -- ?? - DLL <= "00000000"; -- ?? - DLM <= "00000000"; -- ?? - elsif XIn'event and XIn = '1' then - if Wr_n = '0' and CS_n = '0' then - case A is - when "000" => - if LCR(7) = '1' then - DLL <= D_In; - else - THR <= D_In; - end if; - when "001" => - if LCR(7) = '1' then - DLM <= D_In; - else - IER(3 downto 0) <= D_In(3 downto 0); - end if; - when "011" => - LCR <= D_In; - when "100" => - MCR <= D_In; - when "111" => - SCR <= D_In; - when others => - end case; - end if; - if Rd_n = '0' and CS_n = '0' and A = "110" then - MSR(3 downto 0) <= "0000"; - end if; - if MSR(4) /= MSR_In(0) then - MSR(0) <= '1'; - end if; - if MSR(5) /= MSR_In(1) then - MSR(1) <= '1'; - end if; - if MSR(6) = '0' and MSR_In(2) = '1' then - MSR(2) <= '1'; - end if; - if MSR(7) /= MSR_In(3) then - MSR(3) <= '1'; - end if; - end if; - end process; - process (XIn) - begin - if XIn'event and XIn = '1' then - if MCR(4) = '0' then - MSR(4) <= MSR_In(0); - MSR(5) <= MSR_In(1); - MSR(6) <= MSR_In(2); - MSR(7) <= MSR_In(3); - else - MSR(4) <= MCR(1); - MSR(5) <= MCR(0); - MSR(6) <= MCR(2); - MSR(7) <= MCR(3); - end if; - MSR_In(0) <= CTS_n; - MSR_In(1) <= DSR_n; - MSR_In(2) <= RI_n; - MSR_In(3) <= DCD_n; - end if; - end process; - - IIR(7 downto 3) <= "00000"; - IIR(2 downto 0) <= - "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else - "100" when (IER(0) and LSR(0)) = '1' else - "010" when (IER(1) and LSR(5)) = '1' else - "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or - (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else - "001"; - - -- Baud x 16 clock generator - process (MR_n, XIn) - variable Baud_Cnt : unsigned(15 downto 0); - begin - if MR_n = '0' then - Baud_Cnt := "0000000000000000"; - BaudOut <= '0'; - elsif XIn'event and XIn = '1' then - if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then - Baud_Cnt(15 downto 8) := unsigned(DLM); - Baud_Cnt(7 downto 0) := unsigned(DLL); - BaudOut <= '1'; - else - Baud_Cnt := Baud_Cnt - 1; - BaudOut <= '0'; - end if; - end if; - end process; - - -- Input filter - process (MR_n, XIn) - variable Samples : std_logic_vector(1 downto 0); - begin - if MR_n = '0' then - Samples := "11"; - RX_Filtered <= '1'; - elsif XIn'event and XIn = '1' then - if RClk = '1' then - Samples(1) := Samples(0); - Samples(0) := RXD; - end if; - if Samples = "00" then - RX_Filtered <= '0'; - end if; - if Samples = "11" then - RX_Filtered <= '1'; - end if; - end if; - end process; - - -- Receive state machine - process (MR_n, XIn) - begin - if MR_n = '0' then - RBR <= "00000000"; - LSR(4 downto 0) <= "00000"; - Bit_Phase <= "0000"; - Brk_Cnt <= "0000"; - RX_ShiftReg(7 downto 0) <= "00000000"; - RX_Bit_Cnt <= 0; - RX_Parity <= '0'; - elsif XIn'event and XIn = '1' then - if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then - LSR(0) <= '0'; -- DR - end if; - if A = "101" and Rd_n = '0' and CS_n = '0' then - LSR(4) <= '0'; -- BI - LSR(3) <= '0'; -- FE - LSR(2) <= '0'; -- PE - LSR(1) <= '0'; -- OE - end if; - if RClk = '1' then - if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then - Bit_Phase <= "0000"; - else - Bit_Phase <= Bit_Phase + 1; - end if; - if Bit_Phase = "1111" then - if RX_Filtered = '1' then - Brk_Cnt <= "0000"; - else - Brk_Cnt <= Brk_Cnt + 1; - end if; - if Brk_Cnt = "1100" then - LSR(4) <= '1'; -- BI - end if; - end if; - if RX_Bit_Cnt = 0 then - if Bit_Phase = "0111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - RX_Parity <= not LCR(4); -- EPS - end if; - elsif Bit_Phase = "1111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - if RX_Bit_Cnt = 10 then -- Parity stop bit - RX_Bit_Cnt <= 0; - LSR(0) <= '1'; -- UART Receive complete - LSR(3) <= not RX_Filtered; -- Framing error - elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or - (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or - (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or - (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity - RX_Bit_Cnt <= 0; - if LCR(3) = '1' then -- PEN - RX_Bit_Cnt <= 10; - if LCR(5) = '1' then -- Stick parity - if RX_Filtered = LCR(4) then - LSR(2) <= '1'; - end if; - else - if RX_Filtered /= RX_Parity then - LSR(2) <= '1'; - end if; - end if; - else - LSR(0) <= '1'; -- UART Receive complete - LSR(3) <= not RX_Filtered; -- Framing error - end if; - RBR <= RX_ShiftReg(7 downto 0); - LSR(1) <= LSR(0); - if A = "101" and Rd_n = '0' and CS_n = '0' then - LSR(1) <= '0'; - end if; - else - RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1); - RX_ShiftReg(7) <= RX_Filtered; - if LCR(1 downto 0) = "10" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= RX_Filtered; - end if; - if LCR(1 downto 0) = "01" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= '0'; - RX_ShiftReg(5) <= RX_Filtered; - end if; - if LCR(1 downto 0) = "00" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= '0'; - RX_ShiftReg(5) <= '0'; - RX_ShiftReg(4) <= RX_Filtered; - end if; - RX_Parity <= RX_Filtered xor RX_Parity; - end if; - end if; - end if; - end if; - end process; - - -- Transmit bit tick - process (MR_n, XIn) - variable TX_Cnt : unsigned(4 downto 0); - begin - if MR_n = '0' then - TX_Cnt := "00000"; - TX_Tick <= '0'; - elsif XIn'event and XIn = '1' then - TX_Tick <= '0'; - if RClk = '1' then - TX_Cnt := TX_Cnt + 1; - if LCR(2) = '1' and TX_Stop_Bit = '1' then - if LCR(1 downto 0) = "00" then - if TX_Cnt = "10111" then - TX_Tick <= '1'; - TX_Cnt(3 downto 0) := "0000"; - end if; - else - if TX_Cnt = "11111" then - TX_Tick <= '1'; - TX_Cnt(3 downto 0) := "0000"; - end if; - end if; - else - TX_Cnt(4) := '1'; - if TX_Cnt(3 downto 0) = "1111" then - TX_Tick <= '1'; - end if; - end if; - end if; - end if; - end process; - - -- Transmit state machine - process (MR_n, XIn) - begin - if MR_n = '0' then - LSR(7 downto 5) <= "011"; - TX_Bit_Cnt <= 0; - TX_ShiftReg <= (others => '0'); - TXD <= '1'; - TX_Parity <= '0'; - TX_Next_Is_Stop <= '0'; - TX_Stop_Bit <= '0'; - elsif XIn'event and XIn = '1' then - if TX_Tick = '1' then - TX_Next_Is_Stop <= '0'; - TX_Stop_Bit <= TX_Next_Is_Stop; - case TX_Bit_Cnt is - when 0 => - if LSR(5) <= '0' then -- THRE - TX_Bit_Cnt <= 1; - end if; - TXD <= '1'; - when 1 => -- Start bit - TX_ShiftReg(7 downto 0) <= THR; - LSR(5) <= '1'; -- THRE - TXD <= '0'; - TX_Parity <= not LCR(4); -- EPS - TX_Bit_Cnt <= TX_Bit_Cnt + 1; - when 10 => -- Parity bit - TXD <= TX_Parity; - if LCR(5) = '1' then -- Stick parity - TXD <= not LCR(4); - end if; - TX_Bit_Cnt <= 0; - TX_Next_Is_Stop <= '1'; - when others => - TX_Bit_Cnt <= TX_Bit_Cnt + 1; - if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or - (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or - (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or - (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then - TX_Bit_Cnt <= 0; - if LCR(3) = '1' then -- PEN - TX_Bit_Cnt <= 10; - else - TX_Next_Is_Stop <= '1'; - end if; - LSR(6) <= '1'; -- TEMT - end if; - TXD <= TX_ShiftReg(0); - TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1); - TX_Parity <= TX_ShiftReg(0) xor TX_Parity; - end case; - end if; - if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then - LSR(5) <= '0'; -- THRE - LSR(6) <= '0'; -- TEMT - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/DebugSystemXR.vhd =================================================================== --- trunk/rtl/vhdl/DebugSystemXR.vhd (revision 46) +++ trunk/rtl/vhdl/DebugSystemXR.vhd (nonexistent) @@ -1,185 +0,0 @@ --- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs --- that can be synthesized and used with --- the NoICE debugger that can be found at --- http://www.noicedebugger.com/ - -library IEEE; -use IEEE.std_logic_1164.all; - -entity DebugSystemXR is - port( - Reset_n : in std_logic; - Clk : in std_logic; - NMI_n : in std_logic; - OE_n : out std_logic; - WE_n : out std_logic; - RAMCS_n : out std_logic; - ROMCS_n : out std_logic; - PGM_n : out std_logic; - A : out std_logic_vector(16 downto 0); - D : inout std_logic_vector(7 downto 0); - RXD0 : in std_logic; - CTS0 : in std_logic; - DSR0 : in std_logic; - RI0 : in std_logic; - DCD0 : in std_logic; - RXD1 : in std_logic; - CTS1 : in std_logic; - DSR1 : in std_logic; - RI1 : in std_logic; - DCD1 : in std_logic; - TXD0 : out std_logic; - RTS0 : out std_logic; - DTR0 : out std_logic; - TXD1 : out std_logic; - RTS1 : out std_logic; - DTR1 : out std_logic - ); -end entity DebugSystemXR; - -architecture struct of DebugSystemXR is - - signal M1_n : std_logic; - signal MREQ_n : std_logic; - signal IORQ_n : std_logic; - signal RD_n : std_logic; - signal WR_n : std_logic; - signal RFSH_n : std_logic; - signal HALT_n : std_logic; - signal WAIT_n : std_logic; - signal INT_n : std_logic; - signal RESET_s : std_logic; - signal BUSRQ_n : std_logic; - signal BUSAK_n : std_logic; - signal A_i : std_logic_vector(15 downto 0); - signal D_i : std_logic_vector(7 downto 0); - signal ROM_D : std_logic_vector(7 downto 0); - signal UART0_D : std_logic_vector(7 downto 0); - signal UART1_D : std_logic_vector(7 downto 0); - signal CPU_D : std_logic_vector(7 downto 0); - - signal Mirror : std_logic; - - signal IOWR_n : std_logic; - signal RAMCS_n_i : std_logic; - signal UART0CS_n : std_logic; - signal UART1CS_n : std_logic; - - signal BaudOut0 : std_logic; - signal BaudOut1 : std_logic; - -begin - - Wait_n <= '1'; - BusRq_n <= '1'; - INT_n <= '1'; - - OE_n <= RD_n; - WE_n <= WR_n; - RAMCS_n <= RAMCS_n_i; - ROMCS_n <= '1'; - PGM_n <= '1'; - A(14 downto 0) <= A_i(14 downto 0); - A(16 downto 15) <= "00"; - D <= D_i when WR_n = '0' else "ZZZZZZZZ"; - - process (Reset_n, Clk) - begin - if Reset_n = '0' then - Reset_s <= '0'; - Mirror <= '0'; - elsif Clk'event and Clk = '1' then - Reset_s <= '1'; - if IORQ_n = '0' and A_i(7 downto 4) = "1111" then - Mirror <= D_i(0); - end if; - end if; - end process; - - IOWR_n <= WR_n or IORQ_n; - RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n; - UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1'; - UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1'; - - CPU_D <= - D when RAMCS_n_i = '0' else - UART0_D when UART0CS_n = '0' else - UART1_D when UART1CS_n = '0' else - ROM_D; - - u0 : entity work.T80s - generic map(Mode => 1, T2Write => 1, IOWait => 0) - port map( - RESET_n => RESET_s, - CLK_n => Clk, - WAIT_n => WAIT_n, - INT_n => INT_n, - NMI_n => NMI_n, - BUSRQ_n => BUSRQ_n, - M1_n => M1_n, - MREQ_n => MREQ_n, - IORQ_n => IORQ_n, - RD_n => RD_n, - WR_n => WR_n, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - BUSAK_n => BUSAK_n, - A => A_i, - DI => CPU_D, - DO => D_i); - - u1 : entity work.MonZ80 - port map( - Clk => Clk, - A => A_i(10 downto 0), - D => ROM_D); - - u3 : entity work.T16450 - port map( - MR_n => Reset_s, - XIn => Clk, - RClk => BaudOut0, - CS_n => UART0CS_n, - Rd_n => RD_n, - Wr_n => IOWR_n, - A => A_i(2 downto 0), - D_In => D_i, - D_Out => UART0_D, - SIn => RXD0, - CTS_n => CTS0, - DSR_n => DSR0, - RI_n => RI0, - DCD_n => DCD0, - SOut => TXD0, - RTS_n => RTS0, - DTR_n => DTR0, - OUT1_n => open, - OUT2_n => open, - BaudOut => BaudOut0, - Intr => open); - - u4 : entity work.T16450 - port map( - MR_n => Reset_s, - XIn => Clk, - RClk => BaudOut1, - CS_n => UART1CS_n, - Rd_n => RD_n, - Wr_n => IOWR_n, - A => A_i(2 downto 0), - D_In => D_i, - D_Out => UART1_D, - SIn => RXD1, - CTS_n => CTS1, - DSR_n => DSR1, - RI_n => RI1, - DCD_n => DCD1, - SOut => TXD1, - RTS_n => RTS1, - DTR_n => DTR1, - OUT1_n => open, - OUT2_n => open, - BaudOut => BaudOut1, - Intr => open); - -end; Index: trunk/rtl/vhdl/SSRAM2.vhd =================================================================== --- trunk/rtl/vhdl/SSRAM2.vhd (revision 46) +++ trunk/rtl/vhdl/SSRAM2.vhd (nonexistent) @@ -1,92 +0,0 @@ --- --- Inferrable Synchronous SRAM for Leonardo synthesis, no write through! --- --- Version : 0236 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity SSRAM is - generic( - AddrWidth : integer := 16; - DataWidth : integer := 8 - ); - port( - Clk : in std_logic; - CE_n : in std_logic; - WE_n : in std_logic; - A : in std_logic_vector(AddrWidth - 1 downto 0); - DIn : in std_logic_vector(DataWidth - 1 downto 0); - DOut : out std_logic_vector(DataWidth - 1 downto 0) - ); -end SSRAM; - -architecture behaviour of SSRAM is - - type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); - signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); --- signal A_r : std_logic_vector(AddrWidth - 1 downto 0); - -begin - - process (Clk) - begin - if Clk'event and Clk = '1' then --- pragma translate_off - if not is_x(A) then --- pragma translate_on - DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0)))); --- pragma translate_off - end if; --- pragma translate_on - if CE_n = '0' and WE_n = '0' then - RAM(to_integer(unsigned(A))) <= DIn; - end if; --- A_r <= A; - end if; - end process; - -end; Index: trunk/rtl/vhdl/T80_Reg.vhd =================================================================== --- trunk/rtl/vhdl/T80_Reg.vhd (revision 46) +++ trunk/rtl/vhdl/T80_Reg.vhd (nonexistent) @@ -1,105 +0,0 @@ --- --- T80 Registers, technology independent --- --- Version : 0244 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- --- 0242 : Initial release --- --- 0244 : Changed to single register file --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_Reg is - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0) - ); -end T80_Reg; - -architecture rtl of T80_Reg is - - type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); - signal RegsH : Register_Image(0 to 7); - signal RegsL : Register_Image(0 to 7); - -begin - - process (Clk) - begin - if Clk'event and Clk = '1' then - if CEN = '1' then - if WEH = '1' then - RegsH(to_integer(unsigned(AddrA))) <= DIH; - end if; - if WEL = '1' then - RegsL(to_integer(unsigned(AddrA))) <= DIL; - end if; - end if; - end if; - end process; - - DOAH <= RegsH(to_integer(unsigned(AddrA))); - DOAL <= RegsL(to_integer(unsigned(AddrA))); - DOBH <= RegsH(to_integer(unsigned(AddrB))); - DOBL <= RegsL(to_integer(unsigned(AddrB))); - DOCH <= RegsH(to_integer(unsigned(AddrC))); - DOCL <= RegsL(to_integer(unsigned(AddrC))); - -end; Index: trunk/rtl/vhdl/T80_Pack.vhd =================================================================== --- trunk/rtl/vhdl/T80_Pack.vhd (revision 46) +++ trunk/rtl/vhdl/T80_Pack.vhd (nonexistent) @@ -1,208 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; - -package T80_Pack is - - component T80 - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic - ); - end component; - - component T80_Reg - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0) - ); - end component; - - component T80_MCode - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic - ); - end component; - - component T80_ALU - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - ALU_Op : in std_logic_vector(3 downto 0); - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); - end component; - -end; Index: trunk/rtl/vhdl/T8080se.vhd =================================================================== --- trunk/rtl/vhdl/T8080se.vhd (revision 46) +++ trunk/rtl/vhdl/T8080se.vhd (nonexistent) @@ -1,185 +0,0 @@ --- --- 8080 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original 8080 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- STACK status output not supported --- --- File history : --- --- 0237 : First version --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T8080se is - generic( - Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - ); - port( - RESET_n : in std_logic; - CLK : in std_logic; - CLKEN : in std_logic; - READY : in std_logic; - HOLD : in std_logic; - INT : in std_logic; - INTE : out std_logic; - DBIN : out std_logic; - SYNC : out std_logic; - VAIT : out std_logic; - HLDA : out std_logic; - WR_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T8080se; - -architecture rtl of T8080se is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal INT_n : std_logic; - signal HALT_n : std_logic; - signal BUSRQ_n : std_logic; - signal BUSAK_n : std_logic; - signal DO_i : std_logic_vector(7 downto 0); - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - signal One : std_logic; - -begin - - INT_n <= not INT; - BUSRQ_n <= HOLD; - HLDA <= not BUSAK_n; - SYNC <= '1' when TState = "001" else '0'; - VAIT <= '1' when TState = "010" else '0'; - One <= '1'; - - DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA - DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n - DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! - DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA - DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT - DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 - DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP - DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR - - u0 : T80 - generic map( - Mode => Mode, - IOWait => 0) - port map( - CEN => CLKEN, - M1_n => open, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => open, - HALT_n => HALT_n, - WAIT_n => READY, - INT_n => INT_n, - NMI_n => One, - RESET_n => RESET_n, - BUSRQ_n => One, - BUSAK_n => BUSAK_n, - CLK_n => CLK, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO_i, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n, - IntE => INTE); - - process (RESET_n, CLK) - begin - if RESET_n = '0' then - DBIN <= '0'; - WR_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK'event and CLK = '1' then - if CLKEN = '1' then - DBIN <= '0'; - WR_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and READY = '0') then - DBIN <= IntCycle_n; - end if; - else - if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then - DBIN <= '1'; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then - WR_n <= '0'; - end if; - end if; - end if; - if TState = "010" and READY = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/T80.vhd =================================================================== --- trunk/rtl/vhdl/T80.vhd (revision 46) +++ trunk/rtl/vhdl/T80.vhd (nonexistent) @@ -1,1073 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0210 : Fixed wait and halt --- --- 0211 : Fixed Refresh addition and IM 1 --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson --- --- 0235 : Added clock enable and IM 2 fix by Mike Johnson --- --- 0237 : Changed 8080 I/O address output, added IntE output --- --- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag --- --- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode --- --- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM --- --- 0247 : Fixed bus req/ack cycle --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80 is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic - ); -end T80; - -architecture rtl of T80 is - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; - - -- Registers - signal ACC, F : std_logic_vector(7 downto 0); - signal Ap, Fp : std_logic_vector(7 downto 0); - signal I : std_logic_vector(7 downto 0); - signal R : unsigned(7 downto 0); - signal SP, PC : unsigned(15 downto 0); - signal RegDIH : std_logic_vector(7 downto 0); - signal RegDIL : std_logic_vector(7 downto 0); - signal RegBusA : std_logic_vector(15 downto 0); - signal RegBusB : std_logic_vector(15 downto 0); - signal RegBusC : std_logic_vector(15 downto 0); - signal RegAddrA_r : std_logic_vector(2 downto 0); - signal RegAddrA : std_logic_vector(2 downto 0); - signal RegAddrB_r : std_logic_vector(2 downto 0); - signal RegAddrB : std_logic_vector(2 downto 0); - signal RegAddrC : std_logic_vector(2 downto 0); - signal RegWEH : std_logic; - signal RegWEL : std_logic; - signal Alternate : std_logic; - - -- Help Registers - signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register - signal IR : std_logic_vector(7 downto 0); -- Instruction register - signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector - signal RegBusA_r : std_logic_vector(15 downto 0); - - signal ID16 : signed(15 downto 0); - signal Save_Mux : std_logic_vector(7 downto 0); - - signal TState : unsigned(2 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal IntE_FF1 : std_logic; - signal IntE_FF2 : std_logic; - signal Halt_FF : std_logic; - signal BusReq_s : std_logic; - signal BusAck : std_logic; - signal ClkEn : std_logic; - signal NMI_s : std_logic; - signal INT_s : std_logic; - signal IStatus : std_logic_vector(1 downto 0); - - signal DI_Reg : std_logic_vector(7 downto 0); - signal T_Res : std_logic; - signal XY_State : std_logic_vector(1 downto 0); - signal Pre_XY_F_M : std_logic_vector(2 downto 0); - signal NextIs_XY_Fetch : std_logic; - signal XY_Ind : std_logic; - signal No_BTR : std_logic; - signal BTR_r : std_logic; - signal Auto_Wait : std_logic; - signal Auto_Wait_t1 : std_logic; - signal Auto_Wait_t2 : std_logic; - signal IncDecZ : std_logic; - - -- ALU signals - signal BusB : std_logic_vector(7 downto 0); - signal BusA : std_logic_vector(7 downto 0); - signal ALU_Q : std_logic_vector(7 downto 0); - signal F_Out : std_logic_vector(7 downto 0); - - -- Registered micro code outputs - signal Read_To_Reg_r : std_logic_vector(4 downto 0); - signal Arith16_r : std_logic; - signal Z16_r : std_logic; - signal ALU_Op_r : std_logic_vector(3 downto 0); - signal Save_ALU_r : std_logic; - signal PreserveC_r : std_logic; - signal MCycles : std_logic_vector(2 downto 0); - - -- Micro code outputs - signal MCycles_d : std_logic_vector(2 downto 0); - signal TStates : std_logic_vector(2 downto 0); - signal IntCycle : std_logic; - signal NMICycle : std_logic; - signal Inc_PC : std_logic; - signal Inc_WZ : std_logic; - signal IncDec_16 : std_logic_vector(3 downto 0); - signal Prefix : std_logic_vector(1 downto 0); - signal Read_To_Acc : std_logic; - signal Read_To_Reg : std_logic; - signal Set_BusB_To : std_logic_vector(3 downto 0); - signal Set_BusA_To : std_logic_vector(3 downto 0); - signal ALU_Op : std_logic_vector(3 downto 0); - signal Save_ALU : std_logic; - signal PreserveC : std_logic; - signal Arith16 : std_logic; - signal Set_Addr_To : std_logic_vector(2 downto 0); - signal Jump : std_logic; - signal JumpE : std_logic; - signal JumpXY : std_logic; - signal Call : std_logic; - signal RstP : std_logic; - signal LDZ : std_logic; - signal LDW : std_logic; - signal LDSPHL : std_logic; - signal IORQ_i : std_logic; - signal Special_LD : std_logic_vector(2 downto 0); - signal ExchangeDH : std_logic; - signal ExchangeRp : std_logic; - signal ExchangeAF : std_logic; - signal ExchangeRS : std_logic; - signal I_DJNZ : std_logic; - signal I_CPL : std_logic; - signal I_CCF : std_logic; - signal I_SCF : std_logic; - signal I_RETN : std_logic; - signal I_BT : std_logic; - signal I_BC : std_logic; - signal I_BTR : std_logic; - signal I_RLD : std_logic; - signal I_RRD : std_logic; - signal I_INRC : std_logic; - signal SetDI : std_logic; - signal SetEI : std_logic; - signal IMode : std_logic_vector(1 downto 0); - signal Halt : std_logic; - -begin - - mcode : T80_MCode - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - IR => IR, - ISet => ISet, - MCycle => MCycle, - F => F, - NMICycle => NMICycle, - IntCycle => IntCycle, - MCycles => MCycles_d, - TStates => TStates, - Prefix => Prefix, - Inc_PC => Inc_PC, - Inc_WZ => Inc_WZ, - IncDec_16 => IncDec_16, - Read_To_Acc => Read_To_Acc, - Read_To_Reg => Read_To_Reg, - Set_BusB_To => Set_BusB_To, - Set_BusA_To => Set_BusA_To, - ALU_Op => ALU_Op, - Save_ALU => Save_ALU, - PreserveC => PreserveC, - Arith16 => Arith16, - Set_Addr_To => Set_Addr_To, - IORQ => IORQ_i, - Jump => Jump, - JumpE => JumpE, - JumpXY => JumpXY, - Call => Call, - RstP => RstP, - LDZ => LDZ, - LDW => LDW, - LDSPHL => LDSPHL, - Special_LD => Special_LD, - ExchangeDH => ExchangeDH, - ExchangeRp => ExchangeRp, - ExchangeAF => ExchangeAF, - ExchangeRS => ExchangeRS, - I_DJNZ => I_DJNZ, - I_CPL => I_CPL, - I_CCF => I_CCF, - I_SCF => I_SCF, - I_RETN => I_RETN, - I_BT => I_BT, - I_BC => I_BC, - I_BTR => I_BTR, - I_RLD => I_RLD, - I_RRD => I_RRD, - I_INRC => I_INRC, - SetDI => SetDI, - SetEI => SetEI, - IMode => IMode, - Halt => Halt, - NoRead => NoRead, - Write => Write); - - alu : T80_ALU - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - Arith16 => Arith16_r, - Z16 => Z16_r, - ALU_Op => ALU_Op_r, - IR => IR(5 downto 0), - ISet => ISet, - BusA => BusA, - BusB => BusB, - F_In => F, - Q => ALU_Q, - F_Out => F_Out); - - ClkEn <= CEN and not BusAck; - - T_Res <= '1' when TState = unsigned(TStates) else '0'; - - NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and - ((Set_Addr_To = aXY) or - (MCycle = "001" and IR = "11001011") or - (MCycle = "001" and IR = "00110110")) else '0'; - - Save_Mux <= BusB when ExchangeRp = '1' else - DI_Reg when Save_ALU_r = '0' else - ALU_Q; - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - PC <= (others => '0'); -- Program Counter - A <= (others => '0'); - TmpAddr <= (others => '0'); - IR <= "00000000"; - ISet <= "00"; - XY_State <= "00"; - IStatus <= "00"; - MCycles <= "000"; - DO <= "00000000"; - - ACC <= (others => '1'); - F <= (others => '1'); - Ap <= (others => '1'); - Fp <= (others => '1'); - I <= (others => '0'); - R <= (others => '0'); - SP <= (others => '1'); - Alternate <= '0'; - - Read_To_Reg_r <= "00000"; - F <= (others => '1'); - Arith16_r <= '0'; - BTR_r <= '0'; - Z16_r <= '0'; - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - PreserveC_r <= '0'; - XY_Ind <= '0'; - - elsif CLK_n'event and CLK_n = '1' then - - if ClkEn = '1' then - - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - Read_To_Reg_r <= "00000"; - - MCycles <= MCycles_d; - - if IMode /= "11" then - IStatus <= IMode; - end if; - - Arith16_r <= Arith16; - PreserveC_r <= PreserveC; - if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then - Z16_r <= '1'; - else - Z16_r <= '0'; - end if; - - if MCycle = "001" and TState(2) = '0' then - -- MCycle = 1 and TState = 1, 2, or 3 - - if TState = 2 and Wait_n = '1' then - if Mode < 2 then - A(7 downto 0) <= std_logic_vector(R); - A(15 downto 8) <= I; - R(6 downto 0) <= R(6 downto 0) + 1; - end if; - - if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then - PC <= PC + 1; - end if; - - if IntCycle = '1' and IStatus = "01" then - IR <= "11111111"; - elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then - IR <= "00000000"; - else - IR <= DInst; - end if; - - ISet <= "00"; - if Prefix /= "00" then - if Prefix = "11" then - if IR(5) = '1' then - XY_State <= "10"; - else - XY_State <= "01"; - end if; - else - if Prefix = "10" then - XY_State <= "00"; - XY_Ind <= '0'; - end if; - ISet <= Prefix; - end if; - else - XY_State <= "00"; - XY_Ind <= '0'; - end if; - end if; - - else - -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) - - if MCycle = "110" then - XY_Ind <= '1'; - if Prefix = "01" then - ISet <= "01"; - end if; - end if; - - if T_Res = '1' then - BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; - if Jump = '1' then - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= TmpAddr(7 downto 0); - PC(15 downto 8) <= unsigned(DI_Reg); - PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); - elsif JumpXY = '1' then - A <= RegBusC; - PC <= unsigned(RegBusC); - elsif Call = '1' or RstP = '1' then - A <= TmpAddr; - PC <= unsigned(TmpAddr); - elsif MCycle = MCycles and NMICycle = '1' then - A <= "0000000001100110"; - PC <= "0000000001100110"; - elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then - A(15 downto 8) <= I; - A(7 downto 0) <= TmpAddr(7 downto 0); - PC(15 downto 8) <= unsigned(I); - PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); - else - case Set_Addr_To is - when aXY => - if XY_State = "00" then - A <= RegBusC; - else - if NextIs_XY_Fetch = '1' then - A <= std_logic_vector(PC); - else - A <= TmpAddr; - end if; - end if; - when aIOA => - if Mode = 3 then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - elsif Mode = 2 then - -- Duplicate I/O address on 8080 - A(15 downto 8) <= DI_Reg; - else - A(15 downto 8) <= ACC; - end if; - A(7 downto 0) <= DI_Reg; - when aSP => - A <= std_logic_vector(SP); - when aBC => - if Mode = 3 and IORQ_i = '1' then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - A(7 downto 0) <= RegBusC(7 downto 0); - else - A <= RegBusC; - end if; - when aDE => - A <= RegBusC; - when aZI => - if Inc_WZ = '1' then - A <= std_logic_vector(unsigned(TmpAddr) + 1); - else - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= TmpAddr(7 downto 0); - end if; - when others => - A <= std_logic_vector(PC); - end case; - end if; - - Save_ALU_r <= Save_ALU; - ALU_Op_r <= ALU_Op; - - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - end if; - - if TState = 2 and Wait_n = '1' then - if ISet = "01" and MCycle = "111" then - IR <= DInst; - end if; - if JumpE = '1' then - PC <= unsigned(signed(PC) + signed(DI_Reg)); - elsif Inc_PC = '1' then - PC <= PC + 1; - end if; - if BTR_r = '1' then - PC <= PC - 2; - end if; - if RstP = '1' then - TmpAddr <= (others =>'0'); - TmpAddr(5 downto 3) <= IR(5 downto 3); - end if; - end if; - if TState = 3 and MCycle = "110" then - TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); - end if; - - if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then - if IncDec_16(2 downto 0) = "111" then - if IncDec_16(3) = '1' then - SP <= SP - 1; - else - SP <= SP + 1; - end if; - end if; - end if; - - if LDSPHL = '1' then - SP <= unsigned(RegBusC); - end if; - if ExchangeAF = '1' then - Ap <= ACC; - ACC <= Ap; - Fp <= F; - F <= Fp; - end if; - if ExchangeRS = '1' then - Alternate <= not Alternate; - end if; - end if; - - if TState = 3 then - if LDZ = '1' then - TmpAddr(7 downto 0) <= DI_Reg; - end if; - if LDW = '1' then - TmpAddr(15 downto 8) <= DI_Reg; - end if; - - if Special_LD(2) = '1' then - case Special_LD(1 downto 0) is - when "00" => - ACC <= I; - F(Flag_P) <= IntE_FF2; - when "01" => - ACC <= std_logic_vector(R); - F(Flag_P) <= IntE_FF2; - when "10" => - I <= ACC; - when others => - R <= unsigned(ACC); - end case; - end if; - end if; - - if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then - if Mode = 3 then - F(6) <= F_Out(6); - F(5) <= F_Out(5); - F(7) <= F_Out(7); - if PreserveC_r = '0' then - F(4) <= F_Out(4); - end if; - else - F(7 downto 1) <= F_Out(7 downto 1); - if PreserveC_r = '0' then - F(Flag_C) <= F_Out(0); - end if; - end if; - end if; - if T_Res = '1' and I_INRC = '1' then - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - if DI_Reg(7 downto 0) = "00000000" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - F(Flag_S) <= DI_Reg(7); - F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor - DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); - end if; - - if TState = 1 and Auto_Wait_t1 = '0' then - DO <= BusB; - if I_RLD = '1' then - DO(3 downto 0) <= BusA(3 downto 0); - DO(7 downto 4) <= BusB(3 downto 0); - end if; - if I_RRD = '1' then - DO(3 downto 0) <= BusB(7 downto 4); - DO(7 downto 4) <= BusA(3 downto 0); - end if; - end if; - - if T_Res = '1' then - Read_To_Reg_r(3 downto 0) <= Set_BusA_To; - Read_To_Reg_r(4) <= Read_To_Reg; - if Read_To_Acc = '1' then - Read_To_Reg_r(3 downto 0) <= "0111"; - Read_To_Reg_r(4) <= '1'; - end if; - end if; - - if TState = 1 and I_BT = '1' then - F(Flag_X) <= ALU_Q(3); - F(Flag_Y) <= ALU_Q(1); - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - if I_BC = '1' or I_BT = '1' then - F(Flag_P) <= IncDecZ; - end if; - - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10111" => - ACC <= Save_Mux; - when "10110" => - DO <= Save_Mux; - when "11000" => - SP(7 downto 0) <= unsigned(Save_Mux); - when "11001" => - SP(15 downto 8) <= unsigned(Save_Mux); - when "11011" => - F <= Save_Mux; - when others => - end case; - end if; - - end if; - - end if; - - end process; - ---------------------------------------------------------------------------- --- --- BC('), DE('), HL('), IX and IY --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if CLK_n'event and CLK_n = '1' then - if ClkEn = '1' then - -- Bus A / Write - RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then - RegAddrA_r <= XY_State(1) & "11"; - end if; - - -- Bus B - RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then - RegAddrB_r <= XY_State(1) & "11"; - end if; - - -- Address from register - RegAddrC <= Alternate & Set_Addr_To(1 downto 0); - -- Jump (HL), LD SP,HL - if (JumpXY = '1' or LDSPHL = '1') then - RegAddrC <= Alternate & "10"; - end if; - if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then - RegAddrC <= XY_State(1) & "11"; - end if; - - if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then - IncDecZ <= F_Out(Flag_Z); - end if; - if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then - if ID16 = 0 then - IncDecZ <= '0'; - else - IncDecZ <= '1'; - end if; - end if; - - RegBusA_r <= RegBusA; - end if; - end if; - end process; - - RegAddrA <= - -- 16 bit increment/decrement - Alternate & IncDec_16(1 downto 0) when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else - XY_State(1) & "11" when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else - -- EX HL,DL - Alternate & "10" when ExchangeDH = '1' and TState = 3 else - Alternate & "01" when ExchangeDH = '1' and TState = 4 else - -- Bus A / Write - RegAddrA_r; - - RegAddrB <= - -- EX HL,DL - Alternate & "01" when ExchangeDH = '1' and TState = 3 else - -- Bus B - RegAddrB_r; - - ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else - signed(RegBusA) + 1; - - process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) - begin - RegWEH <= '0'; - RegWEL <= '0'; - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => - RegWEH <= not Read_To_Reg_r(0); - RegWEL <= Read_To_Reg_r(0); - when others => - end case; - end if; - - if ExchangeDH = '1' and (TState = 3 or TState = 4) then - RegWEH <= '1'; - RegWEL <= '1'; - end if; - - if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - case IncDec_16(1 downto 0) is - when "00" | "01" | "10" => - RegWEH <= '1'; - RegWEL <= '1'; - when others => - end case; - end if; - end process; - - process (Save_Mux, RegBusB, RegBusA_r, ID16, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) - begin - RegDIH <= Save_Mux; - RegDIL <= Save_Mux; - - if ExchangeDH = '1' and TState = 3 then - RegDIH <= RegBusB(15 downto 8); - RegDIL <= RegBusB(7 downto 0); - end if; - if ExchangeDH = '1' and TState = 4 then - RegDIH <= RegBusA_r(15 downto 8); - RegDIL <= RegBusA_r(7 downto 0); - end if; - - if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - RegDIH <= std_logic_vector(ID16(15 downto 8)); - RegDIL <= std_logic_vector(ID16(7 downto 0)); - end if; - end process; - - Regs : T80_Reg - port map( - Clk => CLK_n, - CEN => ClkEn, - WEH => RegWEH, - WEL => RegWEL, - AddrA => RegAddrA, - AddrB => RegAddrB, - AddrC => RegAddrC, - DIH => RegDIH, - DIL => RegDIL, - DOAH => RegBusA(15 downto 8), - DOAL => RegBusA(7 downto 0), - DOBH => RegBusB(15 downto 8), - DOBL => RegBusB(7 downto 0), - DOCH => RegBusC(15 downto 8), - DOCL => RegBusC(7 downto 0)); - ---------------------------------------------------------------------------- --- --- Buses --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if CLK_n'event and CLK_n = '1' then - if ClkEn = '1' then - case Set_BusB_To is - when "0111" => - BusB <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusB_To(0) = '1' then - BusB <= RegBusB(7 downto 0); - else - BusB <= RegBusB(15 downto 8); - end if; - when "0110" => - BusB <= DI_Reg; - when "1000" => - BusB <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusB <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusB <= "00000001"; - when "1011" => - BusB <= F; - when "1100" => - BusB <= std_logic_vector(PC(7 downto 0)); - when "1101" => - BusB <= std_logic_vector(PC(15 downto 8)); - when "1110" => - BusB <= "00000000"; - when others => - BusB <= "--------"; - end case; - - case Set_BusA_To is - when "0111" => - BusA <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusA_To(0) = '1' then - BusA <= RegBusA(7 downto 0); - else - BusA <= RegBusA(15 downto 8); - end if; - when "0110" => - BusA <= DI_Reg; - when "1000" => - BusA <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusA <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusA <= "00000000"; - when others => - BusB <= "--------"; - end case; - end if; - end if; - end process; - ---------------------------------------------------------------------------- --- --- Generate external control signals --- ---------------------------------------------------------------------------- - process (RESET_n,CLK_n) - begin - if RESET_n = '0' then - RFSH_n <= '1'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then - RFSH_n <= '0'; - else - RFSH_n <= '1'; - end if; - end if; - end if; - end process; - - MC <= std_logic_vector(MCycle); - TS <= std_logic_vector(TState); - DI_Reg <= DI; - HALT_n <= not Halt_FF; - BUSAK_n <= not BusAck; - IntCycle_n <= not IntCycle; - IntE <= IntE_FF1; - IORQ <= IORQ_i; - Stop <= I_DJNZ; - -------------------------------------------------------------------------- --- --- Syncronise inputs --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - variable OldNMI_n : std_logic; - begin - if RESET_n = '0' then - BusReq_s <= '0'; - INT_s <= '0'; - NMI_s <= '0'; - OldNMI_n := '0'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - BusReq_s <= not BUSRQ_n; - INT_s <= not INT_n; - if NMICycle = '1' then - NMI_s <= '0'; - elsif NMI_n = '0' and OldNMI_n = '1' then - NMI_s <= '1'; - end if; - OldNMI_n := NMI_n; - end if; - end if; - end process; - -------------------------------------------------------------------------- --- --- Main state machine --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - MCycle <= "001"; - TState <= "000"; - Pre_XY_F_M <= "000"; - Halt_FF <= '0'; - BusAck <= '0'; - NMICycle <= '0'; - IntCycle <= '0'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - No_BTR <= '0'; - Auto_Wait_t1 <= '0'; - Auto_Wait_t2 <= '0'; - M1_n <= '1'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - if T_Res = '1' then - Auto_Wait_t1 <= '0'; - else - Auto_Wait_t1 <= Auto_Wait or IORQ_i; - end if; - Auto_Wait_t2 <= Auto_Wait_t1; - No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or - (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or - (I_BTR and (not IR(4) or F(Flag_Z))); - if TState = 2 then - if SetEI = '1' then - IntE_FF1 <= '1'; - IntE_FF2 <= '1'; - end if; - if I_RETN = '1' then - IntE_FF1 <= IntE_FF2; - end if; - end if; - if TState = 3 then - if SetDI = '1' then - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; - end if; - if IntCycle = '1' or NMICycle = '1' then - Halt_FF <= '0'; - end if; - if MCycle = "001" and TState = 2 and Wait_n = '1' then - M1_n <= '1'; - end if; - if BusReq_s = '1' and BusAck = '1' then - else - BusAck <= '0'; - if TState = 2 and Wait_n = '0' then - elsif T_Res = '1' then - if Halt = '1' then - Halt_FF <= '1'; - end if; - if BusReq_s = '1' then - BusAck <= '1'; - else - TState <= "001"; - if NextIs_XY_Fetch = '1' then - MCycle <= "110"; - Pre_XY_F_M <= MCycle; - if IR = "00110110" and Mode = 0 then - Pre_XY_F_M <= "010"; - end if; - elsif (MCycle = "111") or - (MCycle = "110" and Mode = 1 and ISet /= "01") then - MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); - elsif (MCycle = MCycles) or - No_BTR = '1' or - (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then - M1_n <= '0'; - MCycle <= "001"; - IntCycle <= '0'; - NMICycle <= '0'; - if NMI_s = '1' and Prefix = "00" then - NMICycle <= '1'; - IntE_FF1 <= '0'; - elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then - IntCycle <= '1'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; - else - MCycle <= std_logic_vector(unsigned(MCycle) + 1); - end if; - end if; - else - if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor - (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then - TState <= TState + 1; - end if; - end if; - end if; - if TState = 0 then - M1_n <= '0'; - end if; - end if; - end if; - end process; - - process (IntCycle, NMICycle, MCycle) - begin - Auto_Wait <= '0'; - if IntCycle = '1' or NMICycle = '1' then - if MCycle = "001" then - Auto_Wait <= '1'; - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/T80_ALU.vhd =================================================================== --- trunk/rtl/vhdl/T80_ALU.vhd (revision 46) +++ trunk/rtl/vhdl/T80_ALU.vhd (nonexistent) @@ -1,351 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0238 : Fixed zero flag for 16 bit SBC and ADC --- --- 0240 : Added GB operations --- --- 0242 : Cleanup --- --- 0247 : Cleanup --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_ALU is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - ALU_Op : in std_logic_vector(3 downto 0); - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); -end T80_ALU; - -architecture rtl of T80_ALU is - - procedure AddSub(A : std_logic_vector; - B : std_logic_vector; - Sub : std_logic; - Carry_In : std_logic; - signal Res : out std_logic_vector; - signal Carry : out std_logic) is - variable B_i : unsigned(A'length - 1 downto 0); - variable Res_i : unsigned(A'length + 1 downto 0); - begin - if Sub = '1' then - B_i := not unsigned(B); - else - B_i := unsigned(B); - end if; - Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); - Carry <= Res_i(A'length + 1); - Res <= std_logic_vector(Res_i(A'length downto 1)); - end; - - -- AddSub variables (temporary signals) - signal UseCarry : std_logic; - signal Carry7_v : std_logic; - signal Overflow_v : std_logic; - signal HalfCarry_v : std_logic; - signal Carry_v : std_logic; - signal Q_v : std_logic_vector(7 downto 0); - - signal BitMask : std_logic_vector(7 downto 0); - -begin - - with IR(5 downto 3) select BitMask <= "00000001" when "000", - "00000010" when "001", - "00000100" when "010", - "00001000" when "011", - "00010000" when "100", - "00100000" when "101", - "01000000" when "110", - "10000000" when others; - - UseCarry <= not ALU_Op(2) and ALU_Op(0); - AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); - AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); - AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); - OverFlow_v <= Carry_v xor Carry7_v; - - process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) - variable Q_t : std_logic_vector(7 downto 0); - variable DAA_Q : unsigned(8 downto 0); - begin - Q_t := "--------"; - F_Out <= F_In; - DAA_Q := "---------"; - case ALU_Op is - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => - F_Out(Flag_N) <= '0'; - F_Out(Flag_C) <= '0'; - case ALU_OP(2 downto 0) is - when "000" | "001" => -- ADD, ADC - Q_t := Q_v; - F_Out(Flag_C) <= Carry_v; - F_Out(Flag_H) <= HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "010" | "011" | "111" => -- SUB, SBC, CP - Q_t := Q_v; - F_Out(Flag_N) <= '1'; - F_Out(Flag_C) <= not Carry_v; - F_Out(Flag_H) <= not HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "100" => -- AND - Q_t(7 downto 0) := BusA and BusB; - F_Out(Flag_H) <= '1'; - when "101" => -- XOR - Q_t(7 downto 0) := BusA xor BusB; - F_Out(Flag_H) <= '0'; - when others => -- OR "110" - Q_t(7 downto 0) := BusA or BusB; - F_Out(Flag_H) <= '0'; - end case; - if ALU_Op(2 downto 0) = "111" then -- CP - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - else - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - end if; - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - if Z16 = '1' then - F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC - end if; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - case ALU_Op(2 downto 0) is - when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP - when others => - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - end case; - if Arith16 = '1' then - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - F_Out(Flag_P) <= F_In(Flag_P); - end if; - when "1100" => - -- DAA - F_Out(Flag_H) <= F_In(Flag_H); - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if (DAA_Q(3 downto 0) > 9) then - F_Out(Flag_H) <= '1'; - else - F_Out(Flag_H) <= '0'; - end if; - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 - end if; - else - -- After subtraction - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if DAA_Q(3 downto 0) > 5 then - F_Out(Flag_H) <= '0'; - end if; - DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; - end if; - if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 352; -- 0x160 - end if; - end if; - F_Out(Flag_X) <= DAA_Q(3); - F_Out(Flag_Y) <= DAA_Q(5); - F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); - Q_t := std_logic_vector(DAA_Q(7 downto 0)); - if DAA_Q(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= DAA_Q(7); - F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor - DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); - when "1101" | "1110" => - -- RLD, RRD - Q_t(7 downto 4) := BusA(7 downto 4); - if ALU_Op(0) = '1' then - Q_t(3 downto 0) := BusB(7 downto 4); - else - Q_t(3 downto 0) := BusB(3 downto 0); - end if; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - when "1001" => - -- BIT - Q_t(7 downto 0) := BusB and BitMask; - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - F_Out(Flag_P) <= '1'; - else - F_Out(Flag_Z) <= '0'; - F_Out(Flag_P) <= '0'; - end if; - F_Out(Flag_H) <= '1'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= '0'; - F_Out(Flag_Y) <= '0'; - if IR(2 downto 0) /= "110" then - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - end if; - when "1010" => - -- SET - Q_t(7 downto 0) := BusB or BitMask; - when "1011" => - -- RES - Q_t(7 downto 0) := BusB and not BitMask; - when "1000" => - -- ROT - case IR(5 downto 3) is - when "000" => -- RLC - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := BusA(7); - F_Out(Flag_C) <= BusA(7); - when "010" => -- RL - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(7); - when "001" => -- RRC - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(0); - F_Out(Flag_C) <= BusA(0); - when "011" => -- RR - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(0); - when "100" => -- SLA - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '0'; - F_Out(Flag_C) <= BusA(7); - when "110" => -- SLL (Undocumented) / SWAP - if Mode = 3 then - Q_t(7 downto 4) := BusA(3 downto 0); - Q_t(3 downto 0) := BusA(7 downto 4); - F_Out(Flag_C) <= '0'; - else - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '1'; - F_Out(Flag_C) <= BusA(7); - end if; - when "101" => -- SRA - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(7); - F_Out(Flag_C) <= BusA(0); - when others => -- SRL - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := '0'; - F_Out(Flag_C) <= BusA(0); - end case; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - if ISet = "00" then - F_Out(Flag_P) <= F_In(Flag_P); - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - end if; - when others => - null; - end case; - Q <= Q_t; - end process; - -end; Index: trunk/rtl/vhdl/T80a.vhd =================================================================== --- trunk/rtl/vhdl/T80a.vhd (revision 46) +++ trunk/rtl/vhdl/T80a.vhd (nonexistent) @@ -1,253 +0,0 @@ --- --- Z80 compatible microprocessor core, asynchronous top level --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0211 : Fixed interrupt cycle --- --- 0235 : Updated for T80 interface change --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- --- 0247 : Fixed bus req/ack cycle --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80a is - generic( - Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - D : inout std_logic_vector(7 downto 0) - ); -end T80a; - -architecture rtl of T80a is - - signal CEN : std_logic; - signal Reset_s : std_logic; - signal IntCycle_n : std_logic; - signal IORQ : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal MREQ : std_logic; - signal MReq_Inhibit : std_logic; - signal Req_Inhibit : std_logic; - signal RD : std_logic; - signal MREQ_n_i : std_logic; - signal IORQ_n_i : std_logic; - signal RD_n_i : std_logic; - signal WR_n_i : std_logic; - signal RFSH_n_i : std_logic; - signal BUSAK_n_i : std_logic; - signal A_i : std_logic_vector(15 downto 0); - signal DO : std_logic_vector(7 downto 0); - signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser - signal Wait_s : std_logic; - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - CEN <= '1'; - - BUSAK_n <= BUSAK_n_i; - MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); - RD_n_i <= not RD or Req_Inhibit; - - MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; - IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; - RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; - WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; - RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; - A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); - D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - Reset_s <= '0'; - elsif CLK_n'event and CLK_n = '1' then - Reset_s <= '1'; - end if; - end process; - - u0 : T80 - generic map( - Mode => Mode, - IOWait => 1) - port map( - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n_i, - HALT_n => HALT_n, - WAIT_n => Wait_s, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => Reset_s, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n_i, - CLK_n => CLK_n, - A => A_i, - DInst => D, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (CLK_n) - begin - if CLK_n'event and CLK_n = '0' then - Wait_s <= WAIT_n; - if TState = "011" and BUSAK_n_i = '1' then - DI_Reg <= to_x01(D); - end if; - end if; - end process; - - process (Reset_s,CLK_n) - begin - if Reset_s = '0' then - WR_n_i <= '1'; - elsif CLK_n'event and CLK_n = '1' then - WR_n_i <= '1'; - if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! - WR_n_i <= not Write; - end if; - end if; - end process; - - process (Reset_s,CLK_n) - begin - if Reset_s = '0' then - Req_Inhibit <= '0'; - elsif CLK_n'event and CLK_n = '1' then - if MCycle = "001" and TState = "010" then - Req_Inhibit <= '1'; - else - Req_Inhibit <= '0'; - end if; - end if; - end process; - - process (Reset_s,CLK_n) - begin - if Reset_s = '0' then - MReq_Inhibit <= '0'; - elsif CLK_n'event and CLK_n = '0' then - if MCycle = "001" and TState = "010" then - MReq_Inhibit <= '1'; - else - MReq_Inhibit <= '0'; - end if; - end if; - end process; - - process(Reset_s,CLK_n) - begin - if Reset_s = '0' then - RD <= '0'; - IORQ_n_i <= '1'; - MREQ <= '0'; - elsif CLK_n'event and CLK_n = '0' then - - if MCycle = "001" then - if TState = "001" then - RD <= IntCycle_n; - MREQ <= IntCycle_n; - IORQ_n_i <= IntCycle_n; - end if; - if TState = "011" then - RD <= '0'; - IORQ_n_i <= '1'; - MREQ <= '1'; - end if; - if TState = "100" then - MREQ <= '0'; - end if; - else - if TState = "001" and NoRead = '0' then - RD <= not Write; - IORQ_n_i <= not IORQ; - MREQ <= not IORQ; - end if; - if TState = "011" then - RD <= '0'; - IORQ_n_i <= '1'; - MREQ <= '0'; - end if; - end if; - end if; - end process; - -end; Index: trunk/rtl/vhdl/SSRAMX.vhd =================================================================== --- trunk/rtl/vhdl/SSRAMX.vhd (revision 46) +++ trunk/rtl/vhdl/SSRAMX.vhd (nonexistent) @@ -1,132 +0,0 @@ --- --- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes) --- --- Version : 0247 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- --- 0240 : Initial release --- --- 0242 : Changed RAMB4_S8 to map by name --- --- 0247 : Added RAMB4_S8 component declaration --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity SSRAM is - generic( - AddrWidth : integer := 11; - DataWidth : integer := 8 - ); - port( - Clk : in std_logic; - CE_n : in std_logic; - WE_n : in std_logic; - A : in std_logic_vector(AddrWidth - 1 downto 0); - DIn : in std_logic_vector(DataWidth - 1 downto 0); - DOut : out std_logic_vector(DataWidth - 1 downto 0) - ); -end SSRAM; - -architecture rtl of SSRAM is - - component RAMB4_S8 - port( - DO : out std_logic_vector(7 downto 0); - ADDR : in std_logic_vector(8 downto 0); - CLK : in std_ulogic; - DI : in std_logic_vector(7 downto 0); - EN : in std_ulogic; - RST : in std_ulogic; - WE : in std_ulogic); - end component; - - constant RAMs : integer := (2 ** AddrWidth) / 512; - - type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0); - - signal bRAMOut : bRAMOut_a; - signal biA_r : integer; - signal A_r : unsigned(A'left downto 0); --- signal A_i : std_logic_vector(8 downto 0); - signal WEA : std_logic_vector(RAMs - 1 downto 0); - -begin - - process (Clk) - begin - if Clk'event and Clk = '1' then - A_r <= unsigned(A); - end if; - end process; - - biA_r <= to_integer(A_r(A'left downto 9)); --- A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0); - - bG1: for I in 0 to RAMs - 1 generate - begin - WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0'; - BSSRAM : RAMB4_S8 - port map( - DI => DIn, - EN => '1', - WE => WEA(I), - RST => '0', - CLK => Clk, - ADDR => A, - DO => bRAMOut(I)); - end generate; - - process (biA_r, bRAMOut) - begin - DOut <= bRAMOut(0); - for I in 1 to RAMs - 1 loop - if biA_r = I then - DOut <= bRAMOut(I); - end if; - end loop; - end process; - -end; Index: t80/trunk/rtl/vhdl/SSRAM2.vhd =================================================================== --- t80/trunk/rtl/vhdl/SSRAM2.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/SSRAM2.vhd (revision 47) @@ -0,0 +1,92 @@ +-- +-- Inferrable Synchronous SRAM for Leonardo synthesis, no write through! +-- +-- Version : 0236 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity SSRAM is + generic( + AddrWidth : integer := 16; + DataWidth : integer := 8 + ); + port( + Clk : in std_logic; + CE_n : in std_logic; + WE_n : in std_logic; + A : in std_logic_vector(AddrWidth - 1 downto 0); + DIn : in std_logic_vector(DataWidth - 1 downto 0); + DOut : out std_logic_vector(DataWidth - 1 downto 0) + ); +end SSRAM; + +architecture behaviour of SSRAM is + + type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); + signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); +-- signal A_r : std_logic_vector(AddrWidth - 1 downto 0); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then +-- pragma translate_off + if not is_x(A) then +-- pragma translate_on + DOut <= RAM(to_integer(unsigned(A(AddrWidth - 1 downto 0)))); +-- pragma translate_off + end if; +-- pragma translate_on + if CE_n = '0' and WE_n = '0' then + RAM(to_integer(unsigned(A))) <= DIn; + end if; +-- A_r <= A; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/SSRAMX.vhd =================================================================== --- t80/trunk/rtl/vhdl/SSRAMX.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/SSRAMX.vhd (revision 47) @@ -0,0 +1,132 @@ +-- +-- Xilinx Block RAM, 8 bit wide and variable size (Min. 512 bytes) +-- +-- Version : 0247 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0240 : Initial release +-- +-- 0242 : Changed RAMB4_S8 to map by name +-- +-- 0247 : Added RAMB4_S8 component declaration +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity SSRAM is + generic( + AddrWidth : integer := 11; + DataWidth : integer := 8 + ); + port( + Clk : in std_logic; + CE_n : in std_logic; + WE_n : in std_logic; + A : in std_logic_vector(AddrWidth - 1 downto 0); + DIn : in std_logic_vector(DataWidth - 1 downto 0); + DOut : out std_logic_vector(DataWidth - 1 downto 0) + ); +end SSRAM; + +architecture rtl of SSRAM is + + component RAMB4_S8 + port( + DO : out std_logic_vector(7 downto 0); + ADDR : in std_logic_vector(8 downto 0); + CLK : in std_ulogic; + DI : in std_logic_vector(7 downto 0); + EN : in std_ulogic; + RST : in std_ulogic; + WE : in std_ulogic); + end component; + + constant RAMs : integer := (2 ** AddrWidth) / 512; + + type bRAMOut_a is array(0 to RAMs - 1) of std_logic_vector(7 downto 0); + + signal bRAMOut : bRAMOut_a; + signal biA_r : integer; + signal A_r : unsigned(A'left downto 0); +-- signal A_i : std_logic_vector(8 downto 0); + signal WEA : std_logic_vector(RAMs - 1 downto 0); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + A_r <= unsigned(A); + end if; + end process; + + biA_r <= to_integer(A_r(A'left downto 9)); +-- A_i <= std_logic_vector(A_r(8 downto 0)) when (CE_n nor WE_n) = '1' else A(8 downto 0); + + bG1: for I in 0 to RAMs - 1 generate + begin + WEA(I) <= '1' when (CE_n nor WE_n) = '1' and biA_r = I else '0'; + BSSRAM : RAMB4_S8 + port map( + DI => DIn, + EN => '1', + WE => WEA(I), + RST => '0', + CLK => Clk, + ADDR => A, + DO => bRAMOut(I)); + end generate; + + process (biA_r, bRAMOut) + begin + DOut <= bRAMOut(0); + for I in 1 to RAMs - 1 loop + if biA_r = I then + DOut <= bRAMOut(I); + end if; + end loop; + end process; + +end; Index: t80/trunk/rtl/vhdl/SSRAM.vhd =================================================================== --- t80/trunk/rtl/vhdl/SSRAM.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/SSRAM.vhd (revision 47) @@ -0,0 +1,92 @@ +-- +-- Inferrable Synchronous SRAM for XST synthesis +-- +-- Version : 0220 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- 0208 : Initial release +-- 0218 : Fixed data out at write +-- 0220 : Added support for XST + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity SSRAM is + generic( + AddrWidth : integer := 11; + DataWidth : integer := 8 + ); + port( + Clk : in std_logic; + CE_n : in std_logic; + WE_n : in std_logic; + A : in std_logic_vector(AddrWidth - 1 downto 0); + DIn : in std_logic_vector(DataWidth - 1 downto 0); + DOut : out std_logic_vector(DataWidth - 1 downto 0) + ); +end SSRAM; + +architecture behaviour of SSRAM is + + type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); + signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); + signal A_r : std_logic_vector(AddrWidth - 1 downto 0); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + if (CE_n nor WE_n) = '1' then + RAM(to_integer(unsigned(A))) <= DIn; + end if; + A_r <= A; + end if; + end process; + + DOut <= RAM(to_integer(unsigned(A_r))) +-- pragma translate_off + when not is_x(A_r) else (others => '-') +-- pragma translate_on + ; +end; Index: t80/trunk/rtl/vhdl/T16450.vhd =================================================================== --- t80/trunk/rtl/vhdl/T16450.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T16450.vhd (revision 47) @@ -0,0 +1,459 @@ +-- +-- 16450 compatible UART with synchronous bus interface +-- RClk/BaudOut is XIn enable instead of actual clock +-- +-- Version : 0249b +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First release +-- +-- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer +-- Added modem status and break detection +-- Added support for 1.5 and 2 stop bits +-- +-- 0249b : Fixed loopback break generation bugs found by Andy Dyer +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T16450 is + port( + MR_n : in std_logic; + XIn : in std_logic; + RClk : in std_logic; + CS_n : in std_logic; + Rd_n : in std_logic; + Wr_n : in std_logic; + A : in std_logic_vector(2 downto 0); + D_In : in std_logic_vector(7 downto 0); + D_Out : out std_logic_vector(7 downto 0); + SIn : in std_logic; + CTS_n : in std_logic; + DSR_n : in std_logic; + RI_n : in std_logic; + DCD_n : in std_logic; + SOut : out std_logic; + RTS_n : out std_logic; + DTR_n : out std_logic; + OUT1_n : out std_logic; + OUT2_n : out std_logic; + BaudOut : out std_logic; + Intr : out std_logic + ); +end T16450; + +architecture rtl of T16450 is + + signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register + signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register + signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register + signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register + signal LCR : std_logic_vector(7 downto 0); -- Line Control Register + signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register + signal LSR : std_logic_vector(7 downto 0); -- Line Status Register + signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register + signal SCR : std_logic_vector(7 downto 0); -- Scratch Register + signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS) + signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS) + + signal DM0 : std_logic_vector(7 downto 0); + signal DM1 : std_logic_vector(7 downto 0); + + signal MSR_In : std_logic_vector(3 downto 0); + + signal Bit_Phase : unsigned(3 downto 0); + signal Brk_Cnt : unsigned(3 downto 0); + signal RX_Filtered : std_logic; + signal RX_ShiftReg : std_logic_vector(7 downto 0); + signal RX_Bit_Cnt : integer range 0 to 11; + signal RX_Parity : std_logic; + signal RXD : std_logic; + + signal TX_Tick : std_logic; + signal TX_ShiftReg : std_logic_vector(7 downto 0); + signal TX_Bit_Cnt : integer range 0 to 11; + signal TX_Parity : std_logic; + signal TX_Next_Is_Stop : std_logic; + signal TX_Stop_Bit : std_logic; + signal TXD : std_logic; + +begin + + DTR_n <= MCR(4) or not MCR(0); + RTS_n <= MCR(4) or not MCR(1); + OUT1_n <= MCR(4) or not MCR(2); + OUT2_n <= MCR(4) or not MCR(3); + SOut <= MCR(4) or (TXD and not LCR(6)); + RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6)); + + Intr <= not IIR(0); + + -- Registers + DM0 <= DLL when LCR(7) = '1' else RBR; + DM1 <= DLM when LCR(7) = '1' else IER; + with A select + D_Out <= + DM0 when "000", + DM1 when "001", + IIR when "010", + LCR when "011", + MCR when "100", + LSR when "101", + MSR when "110", + SCR when others; + process (MR_n, XIn) + begin + if MR_n = '0' then + THR <= "00000000"; + IER <= "00000000"; + LCR <= "00000000"; + MCR <= "00000000"; + MSR(3 downto 0) <= "0000"; + SCR <= "00000000"; -- ?? + DLL <= "00000000"; -- ?? + DLM <= "00000000"; -- ?? + elsif XIn'event and XIn = '1' then + if Wr_n = '0' and CS_n = '0' then + case A is + when "000" => + if LCR(7) = '1' then + DLL <= D_In; + else + THR <= D_In; + end if; + when "001" => + if LCR(7) = '1' then + DLM <= D_In; + else + IER(3 downto 0) <= D_In(3 downto 0); + end if; + when "011" => + LCR <= D_In; + when "100" => + MCR <= D_In; + when "111" => + SCR <= D_In; + when others => + end case; + end if; + if Rd_n = '0' and CS_n = '0' and A = "110" then + MSR(3 downto 0) <= "0000"; + end if; + if MSR(4) /= MSR_In(0) then + MSR(0) <= '1'; + end if; + if MSR(5) /= MSR_In(1) then + MSR(1) <= '1'; + end if; + if MSR(6) = '0' and MSR_In(2) = '1' then + MSR(2) <= '1'; + end if; + if MSR(7) /= MSR_In(3) then + MSR(3) <= '1'; + end if; + end if; + end process; + process (XIn) + begin + if XIn'event and XIn = '1' then + if MCR(4) = '0' then + MSR(4) <= MSR_In(0); + MSR(5) <= MSR_In(1); + MSR(6) <= MSR_In(2); + MSR(7) <= MSR_In(3); + else + MSR(4) <= MCR(1); + MSR(5) <= MCR(0); + MSR(6) <= MCR(2); + MSR(7) <= MCR(3); + end if; + MSR_In(0) <= CTS_n; + MSR_In(1) <= DSR_n; + MSR_In(2) <= RI_n; + MSR_In(3) <= DCD_n; + end if; + end process; + + IIR(7 downto 3) <= "00000"; + IIR(2 downto 0) <= + "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else + "100" when (IER(0) and LSR(0)) = '1' else + "010" when (IER(1) and LSR(5)) = '1' else + "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or + (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else + "001"; + + -- Baud x 16 clock generator + process (MR_n, XIn) + variable Baud_Cnt : unsigned(15 downto 0); + begin + if MR_n = '0' then + Baud_Cnt := "0000000000000000"; + BaudOut <= '0'; + elsif XIn'event and XIn = '1' then + if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then + Baud_Cnt(15 downto 8) := unsigned(DLM); + Baud_Cnt(7 downto 0) := unsigned(DLL); + BaudOut <= '1'; + else + Baud_Cnt := Baud_Cnt - 1; + BaudOut <= '0'; + end if; + end if; + end process; + + -- Input filter + process (MR_n, XIn) + variable Samples : std_logic_vector(1 downto 0); + begin + if MR_n = '0' then + Samples := "11"; + RX_Filtered <= '1'; + elsif XIn'event and XIn = '1' then + if RClk = '1' then + Samples(1) := Samples(0); + Samples(0) := RXD; + end if; + if Samples = "00" then + RX_Filtered <= '0'; + end if; + if Samples = "11" then + RX_Filtered <= '1'; + end if; + end if; + end process; + + -- Receive state machine + process (MR_n, XIn) + begin + if MR_n = '0' then + RBR <= "00000000"; + LSR(4 downto 0) <= "00000"; + Bit_Phase <= "0000"; + Brk_Cnt <= "0000"; + RX_ShiftReg(7 downto 0) <= "00000000"; + RX_Bit_Cnt <= 0; + RX_Parity <= '0'; + elsif XIn'event and XIn = '1' then + if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then + LSR(0) <= '0'; -- DR + end if; + if A = "101" and Rd_n = '0' and CS_n = '0' then + LSR(4) <= '0'; -- BI + LSR(3) <= '0'; -- FE + LSR(2) <= '0'; -- PE + LSR(1) <= '0'; -- OE + end if; + if RClk = '1' then + if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then + Bit_Phase <= "0000"; + else + Bit_Phase <= Bit_Phase + 1; + end if; + if Bit_Phase = "1111" then + if RX_Filtered = '1' then + Brk_Cnt <= "0000"; + else + Brk_Cnt <= Brk_Cnt + 1; + end if; + if Brk_Cnt = "1100" then + LSR(4) <= '1'; -- BI + end if; + end if; + if RX_Bit_Cnt = 0 then + if Bit_Phase = "0111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + RX_Parity <= not LCR(4); -- EPS + end if; + elsif Bit_Phase = "1111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + if RX_Bit_Cnt = 10 then -- Parity stop bit + RX_Bit_Cnt <= 0; + LSR(0) <= '1'; -- UART Receive complete + LSR(3) <= not RX_Filtered; -- Framing error + elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or + (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or + (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or + (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity + RX_Bit_Cnt <= 0; + if LCR(3) = '1' then -- PEN + RX_Bit_Cnt <= 10; + if LCR(5) = '1' then -- Stick parity + if RX_Filtered = LCR(4) then + LSR(2) <= '1'; + end if; + else + if RX_Filtered /= RX_Parity then + LSR(2) <= '1'; + end if; + end if; + else + LSR(0) <= '1'; -- UART Receive complete + LSR(3) <= not RX_Filtered; -- Framing error + end if; + RBR <= RX_ShiftReg(7 downto 0); + LSR(1) <= LSR(0); + if A = "101" and Rd_n = '0' and CS_n = '0' then + LSR(1) <= '0'; + end if; + else + RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1); + RX_ShiftReg(7) <= RX_Filtered; + if LCR(1 downto 0) = "10" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= RX_Filtered; + end if; + if LCR(1 downto 0) = "01" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= '0'; + RX_ShiftReg(5) <= RX_Filtered; + end if; + if LCR(1 downto 0) = "00" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= '0'; + RX_ShiftReg(5) <= '0'; + RX_ShiftReg(4) <= RX_Filtered; + end if; + RX_Parity <= RX_Filtered xor RX_Parity; + end if; + end if; + end if; + end if; + end process; + + -- Transmit bit tick + process (MR_n, XIn) + variable TX_Cnt : unsigned(4 downto 0); + begin + if MR_n = '0' then + TX_Cnt := "00000"; + TX_Tick <= '0'; + elsif XIn'event and XIn = '1' then + TX_Tick <= '0'; + if RClk = '1' then + TX_Cnt := TX_Cnt + 1; + if LCR(2) = '1' and TX_Stop_Bit = '1' then + if LCR(1 downto 0) = "00" then + if TX_Cnt = "10111" then + TX_Tick <= '1'; + TX_Cnt(3 downto 0) := "0000"; + end if; + else + if TX_Cnt = "11111" then + TX_Tick <= '1'; + TX_Cnt(3 downto 0) := "0000"; + end if; + end if; + else + TX_Cnt(4) := '1'; + if TX_Cnt(3 downto 0) = "1111" then + TX_Tick <= '1'; + end if; + end if; + end if; + end if; + end process; + + -- Transmit state machine + process (MR_n, XIn) + begin + if MR_n = '0' then + LSR(7 downto 5) <= "011"; + TX_Bit_Cnt <= 0; + TX_ShiftReg <= (others => '0'); + TXD <= '1'; + TX_Parity <= '0'; + TX_Next_Is_Stop <= '0'; + TX_Stop_Bit <= '0'; + elsif XIn'event and XIn = '1' then + if TX_Tick = '1' then + TX_Next_Is_Stop <= '0'; + TX_Stop_Bit <= TX_Next_Is_Stop; + case TX_Bit_Cnt is + when 0 => + if LSR(5) <= '0' then -- THRE + TX_Bit_Cnt <= 1; + end if; + TXD <= '1'; + when 1 => -- Start bit + TX_ShiftReg(7 downto 0) <= THR; + LSR(5) <= '1'; -- THRE + TXD <= '0'; + TX_Parity <= not LCR(4); -- EPS + TX_Bit_Cnt <= TX_Bit_Cnt + 1; + when 10 => -- Parity bit + TXD <= TX_Parity; + if LCR(5) = '1' then -- Stick parity + TXD <= not LCR(4); + end if; + TX_Bit_Cnt <= 0; + TX_Next_Is_Stop <= '1'; + when others => + TX_Bit_Cnt <= TX_Bit_Cnt + 1; + if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or + (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or + (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or + (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then + TX_Bit_Cnt <= 0; + if LCR(3) = '1' then -- PEN + TX_Bit_Cnt <= 10; + else + TX_Next_Is_Stop <= '1'; + end if; + LSR(6) <= '1'; -- TEMT + end if; + TXD <= TX_ShiftReg(0); + TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1); + TX_Parity <= TX_ShiftReg(0) xor TX_Parity; + end case; + end if; + if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then + LSR(5) <= '0'; -- THRE + LSR(6) <= '0'; -- TEMT + end if; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/T80.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80.vhd (revision 47) @@ -0,0 +1,1073 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed wait and halt +-- +-- 0211 : Fixed Refresh addition and IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson +-- +-- 0235 : Added clock enable and IM 2 fix by Mike Johnson +-- +-- 0237 : Changed 8080 I/O address output, added IntE output +-- +-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag +-- +-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode +-- +-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80 is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic + ); +end T80; + +architecture rtl of T80 is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; + + -- Registers + signal ACC, F : std_logic_vector(7 downto 0); + signal Ap, Fp : std_logic_vector(7 downto 0); + signal I : std_logic_vector(7 downto 0); + signal R : unsigned(7 downto 0); + signal SP, PC : unsigned(15 downto 0); + signal RegDIH : std_logic_vector(7 downto 0); + signal RegDIL : std_logic_vector(7 downto 0); + signal RegBusA : std_logic_vector(15 downto 0); + signal RegBusB : std_logic_vector(15 downto 0); + signal RegBusC : std_logic_vector(15 downto 0); + signal RegAddrA_r : std_logic_vector(2 downto 0); + signal RegAddrA : std_logic_vector(2 downto 0); + signal RegAddrB_r : std_logic_vector(2 downto 0); + signal RegAddrB : std_logic_vector(2 downto 0); + signal RegAddrC : std_logic_vector(2 downto 0); + signal RegWEH : std_logic; + signal RegWEL : std_logic; + signal Alternate : std_logic; + + -- Help Registers + signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register + signal IR : std_logic_vector(7 downto 0); -- Instruction register + signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector + signal RegBusA_r : std_logic_vector(15 downto 0); + + signal ID16 : signed(15 downto 0); + signal Save_Mux : std_logic_vector(7 downto 0); + + signal TState : unsigned(2 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal IntE_FF1 : std_logic; + signal IntE_FF2 : std_logic; + signal Halt_FF : std_logic; + signal BusReq_s : std_logic; + signal BusAck : std_logic; + signal ClkEn : std_logic; + signal NMI_s : std_logic; + signal INT_s : std_logic; + signal IStatus : std_logic_vector(1 downto 0); + + signal DI_Reg : std_logic_vector(7 downto 0); + signal T_Res : std_logic; + signal XY_State : std_logic_vector(1 downto 0); + signal Pre_XY_F_M : std_logic_vector(2 downto 0); + signal NextIs_XY_Fetch : std_logic; + signal XY_Ind : std_logic; + signal No_BTR : std_logic; + signal BTR_r : std_logic; + signal Auto_Wait : std_logic; + signal Auto_Wait_t1 : std_logic; + signal Auto_Wait_t2 : std_logic; + signal IncDecZ : std_logic; + + -- ALU signals + signal BusB : std_logic_vector(7 downto 0); + signal BusA : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal F_Out : std_logic_vector(7 downto 0); + + -- Registered micro code outputs + signal Read_To_Reg_r : std_logic_vector(4 downto 0); + signal Arith16_r : std_logic; + signal Z16_r : std_logic; + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Save_ALU_r : std_logic; + signal PreserveC_r : std_logic; + signal MCycles : std_logic_vector(2 downto 0); + + -- Micro code outputs + signal MCycles_d : std_logic_vector(2 downto 0); + signal TStates : std_logic_vector(2 downto 0); + signal IntCycle : std_logic; + signal NMICycle : std_logic; + signal Inc_PC : std_logic; + signal Inc_WZ : std_logic; + signal IncDec_16 : std_logic_vector(3 downto 0); + signal Prefix : std_logic_vector(1 downto 0); + signal Read_To_Acc : std_logic; + signal Read_To_Reg : std_logic; + signal Set_BusB_To : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(3 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Save_ALU : std_logic; + signal PreserveC : std_logic; + signal Arith16 : std_logic; + signal Set_Addr_To : std_logic_vector(2 downto 0); + signal Jump : std_logic; + signal JumpE : std_logic; + signal JumpXY : std_logic; + signal Call : std_logic; + signal RstP : std_logic; + signal LDZ : std_logic; + signal LDW : std_logic; + signal LDSPHL : std_logic; + signal IORQ_i : std_logic; + signal Special_LD : std_logic_vector(2 downto 0); + signal ExchangeDH : std_logic; + signal ExchangeRp : std_logic; + signal ExchangeAF : std_logic; + signal ExchangeRS : std_logic; + signal I_DJNZ : std_logic; + signal I_CPL : std_logic; + signal I_CCF : std_logic; + signal I_SCF : std_logic; + signal I_RETN : std_logic; + signal I_BT : std_logic; + signal I_BC : std_logic; + signal I_BTR : std_logic; + signal I_RLD : std_logic; + signal I_RRD : std_logic; + signal I_INRC : std_logic; + signal SetDI : std_logic; + signal SetEI : std_logic; + signal IMode : std_logic_vector(1 downto 0); + signal Halt : std_logic; + +begin + + mcode : T80_MCode + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + IR => IR, + ISet => ISet, + MCycle => MCycle, + F => F, + NMICycle => NMICycle, + IntCycle => IntCycle, + MCycles => MCycles_d, + TStates => TStates, + Prefix => Prefix, + Inc_PC => Inc_PC, + Inc_WZ => Inc_WZ, + IncDec_16 => IncDec_16, + Read_To_Acc => Read_To_Acc, + Read_To_Reg => Read_To_Reg, + Set_BusB_To => Set_BusB_To, + Set_BusA_To => Set_BusA_To, + ALU_Op => ALU_Op, + Save_ALU => Save_ALU, + PreserveC => PreserveC, + Arith16 => Arith16, + Set_Addr_To => Set_Addr_To, + IORQ => IORQ_i, + Jump => Jump, + JumpE => JumpE, + JumpXY => JumpXY, + Call => Call, + RstP => RstP, + LDZ => LDZ, + LDW => LDW, + LDSPHL => LDSPHL, + Special_LD => Special_LD, + ExchangeDH => ExchangeDH, + ExchangeRp => ExchangeRp, + ExchangeAF => ExchangeAF, + ExchangeRS => ExchangeRS, + I_DJNZ => I_DJNZ, + I_CPL => I_CPL, + I_CCF => I_CCF, + I_SCF => I_SCF, + I_RETN => I_RETN, + I_BT => I_BT, + I_BC => I_BC, + I_BTR => I_BTR, + I_RLD => I_RLD, + I_RRD => I_RRD, + I_INRC => I_INRC, + SetDI => SetDI, + SetEI => SetEI, + IMode => IMode, + Halt => Halt, + NoRead => NoRead, + Write => Write); + + alu : T80_ALU + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + Arith16 => Arith16_r, + Z16 => Z16_r, + ALU_Op => ALU_Op_r, + IR => IR(5 downto 0), + ISet => ISet, + BusA => BusA, + BusB => BusB, + F_In => F, + Q => ALU_Q, + F_Out => F_Out); + + ClkEn <= CEN and not BusAck; + + T_Res <= '1' when TState = unsigned(TStates) else '0'; + + NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and + ((Set_Addr_To = aXY) or + (MCycle = "001" and IR = "11001011") or + (MCycle = "001" and IR = "00110110")) else '0'; + + Save_Mux <= BusB when ExchangeRp = '1' else + DI_Reg when Save_ALU_r = '0' else + ALU_Q; + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + PC <= (others => '0'); -- Program Counter + A <= (others => '0'); + TmpAddr <= (others => '0'); + IR <= "00000000"; + ISet <= "00"; + XY_State <= "00"; + IStatus <= "00"; + MCycles <= "000"; + DO <= "00000000"; + + ACC <= (others => '1'); + F <= (others => '1'); + Ap <= (others => '1'); + Fp <= (others => '1'); + I <= (others => '0'); + R <= (others => '0'); + SP <= (others => '1'); + Alternate <= '0'; + + Read_To_Reg_r <= "00000"; + F <= (others => '1'); + Arith16_r <= '0'; + BTR_r <= '0'; + Z16_r <= '0'; + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + PreserveC_r <= '0'; + XY_Ind <= '0'; + + elsif CLK_n'event and CLK_n = '1' then + + if ClkEn = '1' then + + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if IMode /= "11" then + IStatus <= IMode; + end if; + + Arith16_r <= Arith16; + PreserveC_r <= PreserveC; + if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then + Z16_r <= '1'; + else + Z16_r <= '0'; + end if; + + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 + + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; + + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; + + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; + + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; + else + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; + end if; + else + XY_State <= "00"; + XY_Ind <= '0'; + end if; + end if; + + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; + end if; + + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= TmpAddr; + PC <= unsigned(TmpAddr); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; + else + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= TmpAddr; + end if; + end if; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; + end if; + A(7 downto 0) <= DI_Reg; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + end if; + when aDE => + A <= RegBusC; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(TmpAddr) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + end if; + when others => + A <= std_logic_vector(PC); + end case; + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + end if; + + if TState = 2 and Wait_n = '1' then + if ISet = "01" and MCycle = "111" then + IR <= DInst; + end if; + if JumpE = '1' then + PC <= unsigned(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + TmpAddr <= (others =>'0'); + TmpAddr(5 downto 3) <= IR(5 downto 3); + end if; + end if; + if TState = 3 and MCycle = "110" then + TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); + end if; + + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + if IncDec_16(2 downto 0) = "111" then + if IncDec_16(3) = '1' then + SP <= SP - 1; + else + SP <= SP + 1; + end if; + end if; + end if; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); + end if; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; + end if; + if ExchangeRS = '1' then + Alternate <= not Alternate; + end if; + end if; + + if TState = 3 then + if LDZ = '1' then + TmpAddr(7 downto 0) <= DI_Reg; + end if; + if LDW = '1' then + TmpAddr(15 downto 8) <= DI_Reg; + end if; + + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; + end if; + + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 then + F(6) <= F_Out(6); + F(5) <= F_Out(5); + F(7) <= F_Out(7); + if PreserveC_r = '0' then + F(4) <= F_Out(4); + end if; + else + F(7 downto 1) <= F_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; + end if; + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); + end if; + + if TState = 1 and Auto_Wait_t1 = '0' then + DO <= BusB; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; + end if; + + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; + end if; + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; + end if; + + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10111" => + ACC <= Save_Mux; + when "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + F <= Save_Mux; + when others => + end case; + end if; + + end if; + + end if; + + end process; + +--------------------------------------------------------------------------- +-- +-- BC('), DE('), HL('), IX and IY +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + -- Bus A / Write + RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then + RegAddrA_r <= XY_State(1) & "11"; + end if; + + -- Bus B + RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then + RegAddrB_r <= XY_State(1) & "11"; + end if; + + -- Address from register + RegAddrC <= Alternate & Set_Addr_To(1 downto 0); + -- Jump (HL), LD SP,HL + if (JumpXY = '1' or LDSPHL = '1') then + RegAddrC <= Alternate & "10"; + end if; + if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then + RegAddrC <= XY_State(1) & "11"; + end if; + + if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then + IncDecZ <= F_Out(Flag_Z); + end if; + if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ID16 = 0 then + IncDecZ <= '0'; + else + IncDecZ <= '1'; + end if; + end if; + + RegBusA_r <= RegBusA; + end if; + end if; + end process; + + RegAddrA <= + -- 16 bit increment/decrement + Alternate & IncDec_16(1 downto 0) when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else + XY_State(1) & "11" when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else + -- EX HL,DL + Alternate & "10" when ExchangeDH = '1' and TState = 3 else + Alternate & "01" when ExchangeDH = '1' and TState = 4 else + -- Bus A / Write + RegAddrA_r; + + RegAddrB <= + -- EX HL,DL + Alternate & "01" when ExchangeDH = '1' and TState = 3 else + -- Bus B + RegAddrB_r; + + ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else + signed(RegBusA) + 1; + + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegWEH <= '0'; + RegWEL <= '0'; + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => + RegWEH <= not Read_To_Reg_r(0); + RegWEL <= Read_To_Reg_r(0); + when others => + end case; + end if; + + if ExchangeDH = '1' and (TState = 3 or TState = 4) then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + case IncDec_16(1 downto 0) is + when "00" | "01" | "10" => + RegWEH <= '1'; + RegWEL <= '1'; + when others => + end case; + end if; + end process; + + process (Save_Mux, RegBusB, RegBusA_r, ID16, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegDIH <= Save_Mux; + RegDIL <= Save_Mux; + + if ExchangeDH = '1' and TState = 3 then + RegDIH <= RegBusB(15 downto 8); + RegDIL <= RegBusB(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 4 then + RegDIH <= RegBusA_r(15 downto 8); + RegDIL <= RegBusA_r(7 downto 0); + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + RegDIH <= std_logic_vector(ID16(15 downto 8)); + RegDIL <= std_logic_vector(ID16(7 downto 0)); + end if; + end process; + + Regs : T80_Reg + port map( + Clk => CLK_n, + CEN => ClkEn, + WEH => RegWEH, + WEL => RegWEL, + AddrA => RegAddrA, + AddrB => RegAddrB, + AddrC => RegAddrC, + DIH => RegDIH, + DIL => RegDIL, + DOAH => RegBusA(15 downto 8), + DOAL => RegBusA(7 downto 0), + DOBH => RegBusB(15 downto 8), + DOBL => RegBusB(7 downto 0), + DOCH => RegBusC(15 downto 8), + DOCL => RegBusC(7 downto 0)); + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + BusB <= "00000000"; + when others => + BusB <= "--------"; + end case; + + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusB <= "--------"; + end case; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Generate external control signals +-- +--------------------------------------------------------------------------- + process (RESET_n,CLK_n) + begin + if RESET_n = '0' then + RFSH_n <= '1'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; + end if; + end if; + end process; + + MC <= std_logic_vector(MCycle); + TS <= std_logic_vector(TState); + DI_Reg <= DI; + HALT_n <= not Halt_FF; + BUSAK_n <= not BusAck; + IntCycle_n <= not IntCycle; + IntE <= IntE_FF1; + IORQ <= IORQ_i; + Stop <= I_DJNZ; + +------------------------------------------------------------------------- +-- +-- Syncronise inputs +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; + begin + if RESET_n = '0' then + BusReq_s <= '0'; + INT_s <= '0'; + NMI_s <= '0'; + OldNMI_n := '0'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + BusReq_s <= not BUSRQ_n; + INT_s <= not INT_n; + if NMICycle = '1' then + NMI_s <= '0'; + elsif NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; + end if; + OldNMI_n := NMI_n; + end if; + end if; + end process; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + MCycle <= "001"; + TState <= "000"; + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + M1_n <= '1'; + elsif CLK_n'event and CLK_n = '1' then + if CEN = '1' then + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; + end if; + Auto_Wait_t2 <= Auto_Wait_t1; + No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or + (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or + (I_BTR and (not IR(4) or F(Flag_Z))); + if TState = 2 then + if SetEI = '1' then + IntE_FF1 <= '1'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; + end if; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + end if; + if IntCycle = '1' or NMICycle = '1' then + Halt_FF <= '0'; + end if; + if MCycle = "001" and TState = 2 and Wait_n = '1' then + M1_n <= '1'; + end if; + if BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' then + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; + else + TState <= "001"; + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + elsif (MCycle = "111") or + (MCycle = "110" and Mode = 1 and ISet /= "01") then + MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); + elsif (MCycle = MCycles) or + No_BTR = '1' or + (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + else + if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor + (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then + TState <= TState + 1; + end if; + end if; + end if; + if TState = 0 then + M1_n <= '0'; + end if; + end if; + end if; + end process; + + process (IntCycle, NMICycle, MCycle) + begin + Auto_Wait <= '0'; + if IntCycle = '1' or NMICycle = '1' then + if MCycle = "001" then + Auto_Wait <= '1'; + end if; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/T80a.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80a.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80a.vhd (revision 47) @@ -0,0 +1,253 @@ +-- +-- Z80 compatible microprocessor core, asynchronous top level +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80a is + generic( + Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + D : inout std_logic_vector(7 downto 0) + ); +end T80a; + +architecture rtl of T80a is + + signal CEN : std_logic; + signal Reset_s : std_logic; + signal IntCycle_n : std_logic; + signal IORQ : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal MREQ : std_logic; + signal MReq_Inhibit : std_logic; + signal Req_Inhibit : std_logic; + signal RD : std_logic; + signal MREQ_n_i : std_logic; + signal IORQ_n_i : std_logic; + signal RD_n_i : std_logic; + signal WR_n_i : std_logic; + signal RFSH_n_i : std_logic; + signal BUSAK_n_i : std_logic; + signal A_i : std_logic_vector(15 downto 0); + signal DO : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser + signal Wait_s : std_logic; + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + BUSAK_n <= BUSAK_n_i; + MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); + RD_n_i <= not RD or Req_Inhibit; + + MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; + IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; + RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; + WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; + RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; + A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); + D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + Reset_s <= '0'; + elsif CLK_n'event and CLK_n = '1' then + Reset_s <= '1'; + end if; + end process; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 1) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n_i, + HALT_n => HALT_n, + WAIT_n => Wait_s, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => Reset_s, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n_i, + CLK_n => CLK_n, + A => A_i, + DInst => D, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '0' then + Wait_s <= WAIT_n; + if TState = "011" and BUSAK_n_i = '1' then + DI_Reg <= to_x01(D); + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + WR_n_i <= '1'; + elsif CLK_n'event and CLK_n = '1' then + WR_n_i <= '1'; + if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! + WR_n_i <= not Write; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + Req_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" and TState = "010" then + Req_Inhibit <= '1'; + else + Req_Inhibit <= '0'; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + MReq_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '0' then + if MCycle = "001" and TState = "010" then + MReq_Inhibit <= '1'; + else + MReq_Inhibit <= '0'; + end if; + end if; + end process; + + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '0'; + elsif CLK_n'event and CLK_n = '0' then + + if MCycle = "001" then + if TState = "001" then + RD <= IntCycle_n; + MREQ <= IntCycle_n; + IORQ_n_i <= IntCycle_n; + end if; + if TState = "011" then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '1'; + end if; + if TState = "100" then + MREQ <= '0'; + end if; + else + if TState = "001" and NoRead = '0' then + RD <= not Write; + IORQ_n_i <= not IORQ; + MREQ <= not IORQ; + end if; + if TState = "011" then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '0'; + end if; + end if; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/T80_ALU.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80_ALU.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80_ALU.vhd (revision 47) @@ -0,0 +1,351 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0238 : Fixed zero flag for 16 bit SBC and ADC +-- +-- 0240 : Added GB operations +-- +-- 0242 : Cleanup +-- +-- 0247 : Cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_ALU is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); +end T80_ALU; + +architecture rtl of T80_ALU is + + procedure AddSub(A : std_logic_vector; + B : std_logic_vector; + Sub : std_logic; + Carry_In : std_logic; + signal Res : out std_logic_vector; + signal Carry : out std_logic) is + variable B_i : unsigned(A'length - 1 downto 0); + variable Res_i : unsigned(A'length + 1 downto 0); + begin + if Sub = '1' then + B_i := not unsigned(B); + else + B_i := unsigned(B); + end if; + Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); + Carry <= Res_i(A'length + 1); + Res <= std_logic_vector(Res_i(A'length downto 1)); + end; + + -- AddSub variables (temporary signals) + signal UseCarry : std_logic; + signal Carry7_v : std_logic; + signal Overflow_v : std_logic; + signal HalfCarry_v : std_logic; + signal Carry_v : std_logic; + signal Q_v : std_logic_vector(7 downto 0); + + signal BitMask : std_logic_vector(7 downto 0); + +begin + + with IR(5 downto 3) select BitMask <= "00000001" when "000", + "00000010" when "001", + "00000100" when "010", + "00001000" when "011", + "00010000" when "100", + "00100000" when "101", + "01000000" when "110", + "10000000" when others; + + UseCarry <= not ALU_Op(2) and ALU_Op(0); + AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); + AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); + AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); + OverFlow_v <= Carry_v xor Carry7_v; + + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) + variable Q_t : std_logic_vector(7 downto 0); + variable DAA_Q : unsigned(8 downto 0); + begin + Q_t := "--------"; + F_Out <= F_In; + DAA_Q := "---------"; + case ALU_Op is + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => + F_Out(Flag_N) <= '0'; + F_Out(Flag_C) <= '0'; + case ALU_OP(2 downto 0) is + when "000" | "001" => -- ADD, ADC + Q_t := Q_v; + F_Out(Flag_C) <= Carry_v; + F_Out(Flag_H) <= HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "010" | "011" | "111" => -- SUB, SBC, CP + Q_t := Q_v; + F_Out(Flag_N) <= '1'; + F_Out(Flag_C) <= not Carry_v; + F_Out(Flag_H) <= not HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "100" => -- AND + Q_t(7 downto 0) := BusA and BusB; + F_Out(Flag_H) <= '1'; + when "101" => -- XOR + Q_t(7 downto 0) := BusA xor BusB; + F_Out(Flag_H) <= '0'; + when others => -- OR "110" + Q_t(7 downto 0) := BusA or BusB; + F_Out(Flag_H) <= '0'; + end case; + if ALU_Op(2 downto 0) = "111" then -- CP + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + else + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + end if; + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + if Z16 = '1' then + F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC + end if; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + case ALU_Op(2 downto 0) is + when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP + when others => + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + end case; + if Arith16 = '1' then + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + F_Out(Flag_P) <= F_In(Flag_P); + end if; + when "1100" => + -- DAA + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 + end if; + end if; + F_Out(Flag_X) <= DAA_Q(3); + F_Out(Flag_Y) <= DAA_Q(5); + F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); + Q_t := std_logic_vector(DAA_Q(7 downto 0)); + if DAA_Q(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= DAA_Q(7); + F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor + DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); + when "1101" | "1110" => + -- RLD, RRD + Q_t(7 downto 4) := BusA(7 downto 4); + if ALU_Op(0) = '1' then + Q_t(3 downto 0) := BusB(7 downto 4); + else + Q_t(3 downto 0) := BusB(3 downto 0); + end if; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + when "1001" => + -- BIT + Q_t(7 downto 0) := BusB and BitMask; + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + F_Out(Flag_P) <= '1'; + else + F_Out(Flag_Z) <= '0'; + F_Out(Flag_P) <= '0'; + end if; + F_Out(Flag_H) <= '1'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= '0'; + F_Out(Flag_Y) <= '0'; + if IR(2 downto 0) /= "110" then + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + end if; + when "1010" => + -- SET + Q_t(7 downto 0) := BusB or BitMask; + when "1011" => + -- RES + Q_t(7 downto 0) := BusB and not BitMask; + when "1000" => + -- ROT + case IR(5 downto 3) is + when "000" => -- RLC + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := BusA(7); + F_Out(Flag_C) <= BusA(7); + when "010" => -- RL + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(7); + when "001" => -- RRC + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(0); + F_Out(Flag_C) <= BusA(0); + when "011" => -- RR + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(0); + when "100" => -- SLA + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '0'; + F_Out(Flag_C) <= BusA(7); + when "110" => -- SLL (Undocumented) / SWAP + if Mode = 3 then + Q_t(7 downto 4) := BusA(3 downto 0); + Q_t(3 downto 0) := BusA(7 downto 4); + F_Out(Flag_C) <= '0'; + else + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '1'; + F_Out(Flag_C) <= BusA(7); + end if; + when "101" => -- SRA + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(7); + F_Out(Flag_C) <= BusA(0); + when others => -- SRL + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := '0'; + F_Out(Flag_C) <= BusA(0); + end case; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + if ISet = "00" then + F_Out(Flag_P) <= F_In(Flag_P); + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + end if; + when others => + null; + end case; + Q <= Q_t; + end process; + +end; Index: t80/trunk/rtl/vhdl/T80_Reg.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80_Reg.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80_Reg.vhd (revision 47) @@ -0,0 +1,105 @@ +-- +-- T80 Registers, technology independent +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Changed to single register file +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); + signal RegsH : Register_Image(0 to 7); + signal RegsL : Register_Image(0 to 7); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + if CEN = '1' then + if WEH = '1' then + RegsH(to_integer(unsigned(AddrA))) <= DIH; + end if; + if WEL = '1' then + RegsL(to_integer(unsigned(AddrA))) <= DIL; + end if; + end if; + end if; + end process; + + DOAH <= RegsH(to_integer(unsigned(AddrA))); + DOAL <= RegsL(to_integer(unsigned(AddrA))); + DOBH <= RegsH(to_integer(unsigned(AddrB))); + DOBL <= RegsL(to_integer(unsigned(AddrB))); + DOCH <= RegsH(to_integer(unsigned(AddrC))); + DOCL <= RegsL(to_integer(unsigned(AddrC))); + +end; Index: t80/trunk/rtl/vhdl/T80_RegX.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80_RegX.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80_RegX.vhd (revision 47) @@ -0,0 +1,167 @@ +-- +-- T80 Registers for Xilinx Select RAM +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Removed UNISIM library and added componet declaration +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + component RAM16X1D + port( + DPO : out std_ulogic; + SPO : out std_ulogic; + A0 : in std_ulogic; + A1 : in std_ulogic; + A2 : in std_ulogic; + A3 : in std_ulogic; + D : in std_ulogic; + DPRA0 : in std_ulogic; + DPRA1 : in std_ulogic; + DPRA2 : in std_ulogic; + DPRA3 : in std_ulogic; + WCLK : in std_ulogic; + WE : in std_ulogic); + end component; + + signal ENH : std_logic; + signal ENL : std_logic; + +begin + + ENH <= CEN and WEH; + ENL <= CEN and WEL; + + bG1: for I in 0 to 7 generate + begin + Reg1H : RAM16X1D + port map( + DPO => DOBH(i), + SPO => DOAH(i), + A0 => AddrA(0), + A1 => AddrA(1), + A2 => AddrA(2), + A3 => '0', + D => DIH(i), + DPRA0 => AddrB(0), + DPRA1 => AddrB(1), + DPRA2 => AddrB(2), + DPRA3 => '0', + WCLK => Clk, + WE => ENH); + Reg1L : RAM16X1D + port map( + DPO => DOBL(i), + SPO => DOAL(i), + A0 => AddrA(0), + A1 => AddrA(1), + A2 => AddrA(2), + A3 => '0', + D => DIL(i), + DPRA0 => AddrB(0), + DPRA1 => AddrB(1), + DPRA2 => AddrB(2), + DPRA3 => '0', + WCLK => Clk, + WE => ENL); + Reg2H : RAM16X1D + port map( + DPO => DOCH(i), + SPO => open, + A0 => AddrA(0), + A1 => AddrA(1), + A2 => AddrA(2), + A3 => '0', + D => DIH(i), + DPRA0 => AddrC(0), + DPRA1 => AddrC(1), + DPRA2 => AddrC(2), + DPRA3 => '0', + WCLK => Clk, + WE => ENH); + Reg2L : RAM16X1D + port map( + DPO => DOCL(i), + SPO => open, + A0 => AddrA(0), + A1 => AddrA(1), + A2 => AddrA(2), + A3 => '0', + D => DIL(i), + DPRA0 => AddrC(0), + DPRA1 => AddrC(1), + DPRA2 => AddrC(2), + DPRA3 => '0', + WCLK => Clk, + WE => ENL); + end generate; + +end; Index: t80/trunk/rtl/vhdl/T80se.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80se.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80se.vhd (revision 47) @@ -0,0 +1,184 @@ +-- +-- Z80 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80se is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T80se; + +architecture rtl of T80se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + if CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/DebugSystemXR.vhd =================================================================== --- t80/trunk/rtl/vhdl/DebugSystemXR.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/DebugSystemXR.vhd (revision 47) @@ -0,0 +1,185 @@ +-- Z80, Monitor ROM, external SRAM interface and two 16450 UARTs +-- that can be synthesized and used with +-- the NoICE debugger that can be found at +-- http://www.noicedebugger.com/ + +library IEEE; +use IEEE.std_logic_1164.all; + +entity DebugSystemXR is + port( + Reset_n : in std_logic; + Clk : in std_logic; + NMI_n : in std_logic; + OE_n : out std_logic; + WE_n : out std_logic; + RAMCS_n : out std_logic; + ROMCS_n : out std_logic; + PGM_n : out std_logic; + A : out std_logic_vector(16 downto 0); + D : inout std_logic_vector(7 downto 0); + RXD0 : in std_logic; + CTS0 : in std_logic; + DSR0 : in std_logic; + RI0 : in std_logic; + DCD0 : in std_logic; + RXD1 : in std_logic; + CTS1 : in std_logic; + DSR1 : in std_logic; + RI1 : in std_logic; + DCD1 : in std_logic; + TXD0 : out std_logic; + RTS0 : out std_logic; + DTR0 : out std_logic; + TXD1 : out std_logic; + RTS1 : out std_logic; + DTR1 : out std_logic + ); +end entity DebugSystemXR; + +architecture struct of DebugSystemXR is + + signal M1_n : std_logic; + signal MREQ_n : std_logic; + signal IORQ_n : std_logic; + signal RD_n : std_logic; + signal WR_n : std_logic; + signal RFSH_n : std_logic; + signal HALT_n : std_logic; + signal WAIT_n : std_logic; + signal INT_n : std_logic; + signal RESET_s : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal A_i : std_logic_vector(15 downto 0); + signal D_i : std_logic_vector(7 downto 0); + signal ROM_D : std_logic_vector(7 downto 0); + signal UART0_D : std_logic_vector(7 downto 0); + signal UART1_D : std_logic_vector(7 downto 0); + signal CPU_D : std_logic_vector(7 downto 0); + + signal Mirror : std_logic; + + signal IOWR_n : std_logic; + signal RAMCS_n_i : std_logic; + signal UART0CS_n : std_logic; + signal UART1CS_n : std_logic; + + signal BaudOut0 : std_logic; + signal BaudOut1 : std_logic; + +begin + + Wait_n <= '1'; + BusRq_n <= '1'; + INT_n <= '1'; + + OE_n <= RD_n; + WE_n <= WR_n; + RAMCS_n <= RAMCS_n_i; + ROMCS_n <= '1'; + PGM_n <= '1'; + A(14 downto 0) <= A_i(14 downto 0); + A(16 downto 15) <= "00"; + D <= D_i when WR_n = '0' else "ZZZZZZZZ"; + + process (Reset_n, Clk) + begin + if Reset_n = '0' then + Reset_s <= '0'; + Mirror <= '0'; + elsif Clk'event and Clk = '1' then + Reset_s <= '1'; + if IORQ_n = '0' and A_i(7 downto 4) = "1111" then + Mirror <= D_i(0); + end if; + end if; + end process; + + IOWR_n <= WR_n or IORQ_n; + RAMCS_n_i <= (not Mirror and not A_i(15)) or MREQ_n; + UART0CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "00000" else '1'; + UART1CS_n <= '0' when IORQ_n = '0' and A_i(7 downto 3) = "10000" else '1'; + + CPU_D <= + D when RAMCS_n_i = '0' else + UART0_D when UART0CS_n = '0' else + UART1_D when UART1CS_n = '0' else + ROM_D; + + u0 : entity work.T80s + generic map(Mode => 1, T2Write => 1, IOWait => 0) + port map( + RESET_n => RESET_s, + CLK_n => Clk, + WAIT_n => WAIT_n, + INT_n => INT_n, + NMI_n => NMI_n, + BUSRQ_n => BUSRQ_n, + M1_n => M1_n, + MREQ_n => MREQ_n, + IORQ_n => IORQ_n, + RD_n => RD_n, + WR_n => WR_n, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + BUSAK_n => BUSAK_n, + A => A_i, + DI => CPU_D, + DO => D_i); + + u1 : entity work.MonZ80 + port map( + Clk => Clk, + A => A_i(10 downto 0), + D => ROM_D); + + u3 : entity work.T16450 + port map( + MR_n => Reset_s, + XIn => Clk, + RClk => BaudOut0, + CS_n => UART0CS_n, + Rd_n => RD_n, + Wr_n => IOWR_n, + A => A_i(2 downto 0), + D_In => D_i, + D_Out => UART0_D, + SIn => RXD0, + CTS_n => CTS0, + DSR_n => DSR0, + RI_n => RI0, + DCD_n => DCD0, + SOut => TXD0, + RTS_n => RTS0, + DTR_n => DTR0, + OUT1_n => open, + OUT2_n => open, + BaudOut => BaudOut0, + Intr => open); + + u4 : entity work.T16450 + port map( + MR_n => Reset_s, + XIn => Clk, + RClk => BaudOut1, + CS_n => UART1CS_n, + Rd_n => RD_n, + Wr_n => IOWR_n, + A => A_i(2 downto 0), + D_In => D_i, + D_Out => UART1_D, + SIn => RXD1, + CTS_n => CTS1, + DSR_n => DSR1, + RI_n => RI1, + DCD_n => DCD1, + SOut => TXD1, + RTS_n => RTS1, + DTR_n => DTR1, + OUT1_n => open, + OUT2_n => open, + BaudOut => BaudOut1, + Intr => open); + +end; Index: t80/trunk/rtl/vhdl/T80_Pack.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80_Pack.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80_Pack.vhd (revision 47) @@ -0,0 +1,208 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T80_Pack is + + component T80 + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic + ); + end component; + + component T80_Reg + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); + end component; + + component T80_MCode + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); + end component; + + component T80_ALU + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); + end component; + +end; Index: t80/trunk/rtl/vhdl/T8080se.vhd =================================================================== --- t80/trunk/rtl/vhdl/T8080se.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T8080se.vhd (revision 47) @@ -0,0 +1,185 @@ +-- +-- 8080 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original 8080 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- STACK status output not supported +-- +-- File history : +-- +-- 0237 : First version +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T8080se is + generic( + Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CLKEN : in std_logic; + READY : in std_logic; + HOLD : in std_logic; + INT : in std_logic; + INTE : out std_logic; + DBIN : out std_logic; + SYNC : out std_logic; + VAIT : out std_logic; + HLDA : out std_logic; + WR_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T8080se; + +architecture rtl of T8080se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal INT_n : std_logic; + signal HALT_n : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal DO_i : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + signal One : std_logic; + +begin + + INT_n <= not INT; + BUSRQ_n <= HOLD; + HLDA <= not BUSAK_n; + SYNC <= '1' when TState = "001" else '0'; + VAIT <= '1' when TState = "010" else '0'; + One <= '1'; + + DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA + DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n + DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! + DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA + DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT + DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 + DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP + DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 0) + port map( + CEN => CLKEN, + M1_n => open, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => open, + HALT_n => HALT_n, + WAIT_n => READY, + INT_n => INT_n, + NMI_n => One, + RESET_n => RESET_n, + BUSRQ_n => One, + BUSAK_n => BUSAK_n, + CLK_n => CLK, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO_i, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + IntE => INTE); + + process (RESET_n, CLK) + begin + if RESET_n = '0' then + DBIN <= '0'; + WR_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK'event and CLK = '1' then + if CLKEN = '1' then + DBIN <= '0'; + WR_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and READY = '0') then + DBIN <= IntCycle_n; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then + DBIN <= '1'; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then + WR_n <= '0'; + end if; + end if; + end if; + if TState = "010" and READY = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; Index: t80/trunk/rtl/vhdl/T80_MCode.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80_MCode.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80_MCode.vhd (revision 47) @@ -0,0 +1,1934 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0235 : Added IM 2 fix by Mike Johnson +-- +-- 0238 : Added NoRead signal +-- +-- 0238b: Fixed instruction timing for POP and DJNZ +-- +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes +-- +-- 0242 : Fixed I/O instruction timing, cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_MCode is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic + ); +end T80_MCode; + +architecture rtl of T80_MCode is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; +-- constant aNone : std_logic_vector(2 downto 0) := "000"; +-- constant aXY : std_logic_vector(2 downto 0) := "001"; +-- constant aIOA : std_logic_vector(2 downto 0) := "010"; +-- constant aSP : std_logic_vector(2 downto 0) := "011"; +-- constant aBC : std_logic_vector(2 downto 0) := "100"; +-- constant aDE : std_logic_vector(2 downto 0) := "101"; +-- constant aZI : std_logic_vector(2 downto 0) := "110"; + + function is_cc_true( + F : std_logic_vector(7 downto 0); + cc : bit_vector(2 downto 0) + ) return boolean is + begin + if Mode = 3 then + case cc is + when "000" => return F(7) = '0'; -- NZ + when "001" => return F(7) = '1'; -- Z + when "010" => return F(4) = '0'; -- NC + when "011" => return F(4) = '1'; -- C + when "100" => return false; + when "101" => return false; + when "110" => return false; + when "111" => return false; + end case; + else + case cc is + when "000" => return F(6) = '0'; -- NZ + when "001" => return F(6) = '1'; -- Z + when "010" => return F(0) = '0'; -- NC + when "011" => return F(0) = '1'; -- C + when "100" => return F(2) = '0'; -- PO + when "101" => return F(2) = '1'; -- PE + when "110" => return F(7) = '0'; -- P + when "111" => return F(7) = '1'; -- M + end case; + end if; + end; + +begin + + process (IR, ISet, MCycle, F, NMICycle, IntCycle) + variable DDD : std_logic_vector(2 downto 0); + variable SSS : std_logic_vector(2 downto 0); + variable DPair : std_logic_vector(1 downto 0); + variable IRB : bit_vector(7 downto 0); + begin + DDD := IR(5 downto 3); + SSS := IR(2 downto 0); + DPair := IR(5 downto 4); + IRB := to_bitvector(IR); + + MCycles <= "001"; + if MCycle = "001" then + TStates <= "100"; + else + TStates <= "011"; + end if; + Prefix <= "00"; + Inc_PC <= '0'; + Inc_WZ <= '0'; + IncDec_16 <= "0000"; + Read_To_Acc <= '0'; + Read_To_Reg <= '0'; + Set_BusB_To <= "0000"; + Set_BusA_To <= "0000"; + ALU_Op <= "0" & IR(5 downto 3); + Save_ALU <= '0'; + PreserveC <= '0'; + Arith16 <= '0'; + IORQ <= '0'; + Set_Addr_To <= aNone; + Jump <= '0'; + JumpE <= '0'; + JumpXY <= '0'; + Call <= '0'; + RstP <= '0'; + LDZ <= '0'; + LDW <= '0'; + LDSPHL <= '0'; + Special_LD <= "000"; + ExchangeDH <= '0'; + ExchangeRp <= '0'; + ExchangeAF <= '0'; + ExchangeRS <= '0'; + I_DJNZ <= '0'; + I_CPL <= '0'; + I_CCF <= '0'; + I_SCF <= '0'; + I_RETN <= '0'; + I_BT <= '0'; + I_BC <= '0'; + I_BTR <= '0'; + I_RLD <= '0'; + I_RRD <= '0'; + I_INRC <= '0'; + SetDI <= '0'; + SetEI <= '0'; + IMode <= "11"; + Halt <= '0'; + NoRead <= '0'; + Write <= '0'; + + case ISet is + when "00" => + +------------------------------------------------------------------------------ +-- +-- Unprefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is +-- 8 BIT LOAD GROUP + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- LD r,r' + Set_BusB_To(2 downto 0) <= SSS; + ExchangeRp <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => + -- LD r,n + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => + -- LD r,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => + -- LD (HL),r + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110110" => + -- LD (HL),n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00001010" => + -- LD A,(BC) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00011010" => + -- LD A,(DE) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00111010" => + if Mode = 3 then + -- LDD A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end if; + when "00000010" => + -- LD (BC),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00010010" => + -- LD (DE),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110010" => + if Mode = 3 then + -- LDD (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + +-- 16 BIT LOAD GROUP + when "00000001"|"00010001"|"00100001"|"00110001" => + -- LD dd,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1000"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1001"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "00101010" => + if Mode = 3 then + -- LDI A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD HL,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end if; + when "00100010" => + if Mode = 3 then + -- LDI (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD (nn),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "0101"; -- L + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "0100"; -- H + when 5 => + Write <= '1'; + when others => null; + end case; + end if; + when "11111001" => + -- LD SP,HL + TStates <= "110"; + LDSPHL <= '1'; + when "11000101"|"11010101"|"11100101"|"11110101" => + -- PUSH qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "11000001"|"11010001"|"11100001"|"11110001" => + -- POP qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1011"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + IncDec_16 <= "0111"; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "0111"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + +-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + when "11101011" => + if Mode /= 3 then + -- EX DE,HL + ExchangeDH <= '1'; + end if; + when "00001000" => + if Mode = 3 then + -- LD (nn),SP + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "1000"; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "1001"; + when 5 => + Write <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EX AF,AF' + ExchangeAF <= '1'; + end if; + when "11011001" => + if Mode = 3 then + -- RETI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + SetEI <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EXX + ExchangeRS <= '1'; + end if; + when "11100011" => + if Mode /= 3 then + -- EX (SP),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0101"; + Set_BusB_To <= "0101"; + Set_Addr_To <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + TStates <= "100"; + Write <= '1'; + when 4 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0100"; + Set_BusB_To <= "0100"; + Set_Addr_To <= aSP; + when 5 => + IncDec_16 <= "1111"; + TStates <= "101"; + Write <= '1'; + when others => null; + end case; + end if; + +-- 8 BIT ARITHMETIC AND LOGICAL GROUP + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- ADD A,r + -- ADC A,r + -- SUB A,r + -- SBC A,r + -- AND A,r + -- OR A,r + -- XOR A,r + -- CP A,r + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- ADD A,(HL) + -- ADC A,(HL) + -- SUB A,(HL) + -- SBC A,(HL) + -- AND A,(HL) + -- OR A,(HL) + -- XOR A,(HL) + -- CP A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + when others => null; + end case; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- ADD A,n + -- ADC A,n + -- SUB A,n + -- SBC A,n + -- AND A,n + -- OR A,n + -- XOR A,n + -- CP A,n + MCycles <= "010"; + if MCycle = "010" then + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + end if; + when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => + -- INC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + when "00110100" => + -- INC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => + -- DEC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0010"; + when "00110101" => + -- DEC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + ALU_Op <= "0010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + +-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + when "00100111" => + -- DAA + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + ALU_Op <= "1100"; + Save_ALU <= '1'; + when "00101111" => + -- CPL + I_CPL <= '1'; + when "00111111" => + -- CCF + I_CCF <= '1'; + when "00110111" => + -- SCF + I_SCF <= '1'; + when "00000000" => + if NMICycle = '1' then + -- NMI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when others => null; + end case; + elsif IntCycle = '1' then + -- INT (IM 2) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + else + -- NOP + end if; + when "01110110" => + -- HALT + Halt <= '1'; + when "11110011" => + -- DI + SetDI <= '1'; + when "11111011" => + -- EI + SetEI <= '1'; + +-- 16 BIT ARITHMETIC GROUP + when "00001001"|"00011001"|"00101001"|"00111001" => + -- ADD HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + when "00000011"|"00010011"|"00100011"|"00110011" => + -- INC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when "00001011"|"00011011"|"00101011"|"00111011" => + -- DEC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + +-- ROTATE AND SHIFT GROUP + when "00000111" + -- RLCA + |"00010111" + -- RLA + |"00001111" + -- RRCA + |"00011111" => + -- RRA + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + +-- JUMP GROUP + when "11000011" => + -- JP nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + Jump <= '1'; + when others => null; + end case; + when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+C),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "01" => + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + when "10" => + -- LD A,($FF00+C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => + end case; + when "11" => + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end case; + else + -- JP cc,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Jump <= '1'; + end if; + when others => null; + end case; + end if; + when "00011000" => + if Mode /= 2 then + -- JR e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00111000" => + if Mode /= 2 then + -- JR C,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00110000" => + if Mode /= 2 then + -- JR NC,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00101000" => + if Mode /= 2 then + -- JR Z,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00100000" => + if Mode /= 2 then + -- JR NZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "11101001" => + -- JP (HL) + JumpXY <= '1'; + when "00010000" => + if Mode = 3 then + I_DJNZ <= '1'; + elsif Mode < 2 then + -- DJNZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + I_DJNZ <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= "000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + I_DJNZ <= '1'; + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + +-- CALL AND RETURN GROUP + when "11001101" => + -- CALL nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + IncDec_16 <= "1111"; + Inc_PC <= '1'; + TStates <= "100"; + Set_Addr_To <= aSP; + LDW <= '1'; + Set_BusB_To <= "1101"; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => + if IR(5) = '0' or Mode /= 3 then + -- CALL cc,nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + LDW <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + TStates <= "100"; + Set_BusB_To <= "1101"; + else + MCycles <= "011"; + end if; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + end if; + when "11001001" => + -- RET + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+nn),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "01" => + -- ADD SP,n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + ALU_Op <= "0000"; + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To <= "1000"; + Set_BusB_To <= "0110"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To <= "1001"; + Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + when others => + end case; + when "10" => + -- LD A,($FF00+nn) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "11" => + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end case; + else + -- RET cc + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => + -- RST p + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + +-- INPUT AND OUTPUT GROUP + when "11011011" => + if Mode /= 3 then + -- IN A,(n) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + when "11010011" => + if Mode /= 3 then + -- OUT (n),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- MULTIBYTE INSTRUCTIONS +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + + when "11001011" => + if Mode /= 2 then + Prefix <= "01"; + end if; + + when "11101101" => + if Mode < 2 then + Prefix <= "10"; + end if; + + when "11011101"|"11111101" => + if Mode < 2 then + Prefix <= "11"; + end if; + + end case; + + when "01" => + +------------------------------------------------------------------------------ +-- +-- CB prefixed instructions +-- +------------------------------------------------------------------------------ + + Set_BusA_To(2 downto 0) <= IR(2 downto 0); + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => + -- RLC r + -- RL r + -- RRC r + -- RR r + -- SLA r + -- SRA r + -- SRL r + -- SLL r (Undocumented) / SWAP r + if MCycle = "001" then + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => + -- RLC (HL) + -- RL (HL) + -- RRC (HL) + -- RR (HL) + -- SRA (HL) + -- SRL (HL) + -- SLA (HL) + -- SLL (HL) (Undocumented) / SWAP (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- BIT b,r + if MCycle = "001" then + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; + end if; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => + -- BIT b,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => + end case; + when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => + -- SET b,r + if MCycle = "001" then + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- SET b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- RES b,r + if MCycle = "001" then + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- RES b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + end case; + + when others => + +------------------------------------------------------------------------------ +-- +-- ED prefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" + + + |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" + | "10100100"|"10100101"|"10100110"|"10100111" + | "10101100"|"10101101"|"10101110"|"10101111" + | "10110100"|"10110101"|"10110110"|"10110111" + | "10111100"|"10111101"|"10111110"|"10111111" + |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => + null; -- NOP, undocumented + when "01111110"|"01111111" => + -- NOP, undocumented + null; +-- 8 BIT LOAD GROUP + when "01010111" => + -- LD A,I + Special_LD <= "100"; + TStates <= "101"; + when "01011111" => + -- LD A,R + Special_LD <= "101"; + TStates <= "101"; + when "01000111" => + -- LD I,A + Special_LD <= "110"; + TStates <= "101"; + when "01001111" => + -- LD R,A + Special_LD <= "111"; + TStates <= "101"; +-- 16 BIT LOAD GROUP + when "01001011"|"01011011"|"01101011"|"01111011" => + -- LD dd,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1000"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '1'; + end if; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1001"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "01000011"|"01010011"|"01100011"|"01110011" => + -- LD (nn),dd + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1000"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1001"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 5 => + Write <= '1'; + when others => null; + end case; + when "10100000" | "10101000" | "10110000" | "10111000" => + -- LDI, LDD, LDIR, LDDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0000"; + Set_Addr_To <= aDE; + if IR(3) = '0' then + IncDec_16 <= "0110"; -- IX + else + IncDec_16 <= "1110"; + end if; + when 3 => + I_BT <= '1'; + TStates <= "101"; + Write <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0101"; -- DE + else + IncDec_16 <= "1101"; + end if; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100001" | "10101001" | "10110001" | "10111001" => + -- CPI, CPD, CPIR, CPDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0111"; + Save_ALU <= '1'; + PreserveC <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + when 3 => + NoRead <= '1'; + I_BC <= '1'; + TStates <= "101"; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => + -- NEG + Alu_OP <= "0010"; + Set_BusB_To <= "0111"; + Set_BusA_To <= "1010"; + Read_To_Acc <= '1'; + Save_ALU <= '1'; + when "01000110"|"01001110"|"01100110"|"01101110" => + -- IM 0 + IMode <= "00"; + when "01010110"|"01110110" => + -- IM 1 + IMode <= "01"; + when "01011110"|"01110111" => + -- IM 2 + IMode <= "10"; +-- 16 bit arithmetic + when "01001010"|"01011010"|"01101010"|"01111010" => + -- ADC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0001"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01000010"|"01010010"|"01100010"|"01110010" => + -- SBC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01101111" => + -- RLD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1101"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RLD <= '1'; + Write <= '1'; + when others => + end case; + when "01100111" => + -- RRD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1110"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RRD <= '1'; + Write <= '1'; + when others => + end case; + when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => + -- RETI, RETN + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + when others => null; + end case; + when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => + -- IN r,(C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + IORQ <= '1'; + if IR(5 downto 3) /= "110" then + Read_To_Reg <= '1'; + Set_BusA_To(2 downto 0) <= IR(5 downto 3); + end if; + I_INRC <= '1'; + when others => + end case; + when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => + -- OUT (C),r + -- OUT (C),0 + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + if IR(5 downto 3) = "110" then + Set_BusB_To(3) <= '1'; + end if; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "10100010" | "10101010" | "10110010" | "10111010" => + -- INI, IND, INIR, INDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + IORQ <= '1'; + Set_BusB_To <= "0110"; + Set_Addr_To <= aXY; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0010"; + else + IncDec_16 <= "1010"; + end if; + TStates <= "100"; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100011" | "10101011" | "10110011" | "10111011" => + -- OUTI, OUTD, OTIR, OTDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aXY; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + Set_BusB_To <= "0110"; + Set_Addr_To <= aBC; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0010"; + else + IncDec_16 <= "1010"; + end if; + IORQ <= '1'; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + end case; + + end case; + + if Mode = 1 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "011"; + end if; + end if; + + if Mode = 3 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "100"; + end if; + end if; + + if Mode < 2 then + if MCycle = "110" then + Inc_PC <= '1'; + if Mode = 1 then + Set_Addr_To <= aXY; + TStates <= "100"; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + end if; + if IRB = "00110110" or IRB = "11001011" then + Set_Addr_To <= aNone; + end if; + end if; + if MCycle = "111" then + if Mode = 0 then + TStates <= "101"; + end if; + if ISet /= "01" then + Set_Addr_To <= aXY; + end if; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + if IRB = "00110110" or ISet = "01" then + -- LD (HL),n + Inc_PC <= '1'; + else + NoRead <= '1'; + end if; + end if; + end if; + + end process; + +end; Index: t80/trunk/rtl/vhdl/DebugSystem.vhd =================================================================== --- t80/trunk/rtl/vhdl/DebugSystem.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/DebugSystem.vhd (revision 47) @@ -0,0 +1,181 @@ +-- Z80, Monitor ROM, 4k RAM and two 16450 UARTs +-- that can be synthesized and used with +-- the NoICE debugger that can be found at +-- http://www.noicedebugger.com/ + +library IEEE; +use IEEE.std_logic_1164.all; + +entity DebugSystem is + port( + Reset_n : in std_logic; + Clk : in std_logic; + NMI_n : in std_logic; + RXD0 : in std_logic; + CTS0 : in std_logic; + DSR0 : in std_logic; + RI0 : in std_logic; + DCD0 : in std_logic; + RXD1 : in std_logic; + CTS1 : in std_logic; + DSR1 : in std_logic; + RI1 : in std_logic; + DCD1 : in std_logic; + TXD0 : out std_logic; + RTS0 : out std_logic; + DTR0 : out std_logic; + TXD1 : out std_logic; + RTS1 : out std_logic; + DTR1 : out std_logic + ); +end DebugSystem; + +architecture struct of DebugSystem is + + signal M1_n : std_logic; + signal MREQ_n : std_logic; + signal IORQ_n : std_logic; + signal RD_n : std_logic; + signal WR_n : std_logic; + signal RFSH_n : std_logic; + signal HALT_n : std_logic; + signal WAIT_n : std_logic; + signal INT_n : std_logic; + signal RESET_s : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal A : std_logic_vector(15 downto 0); + signal D : std_logic_vector(7 downto 0); + signal ROM_D : std_logic_vector(7 downto 0); + signal SRAM_D : std_logic_vector(7 downto 0); + signal UART0_D : std_logic_vector(7 downto 0); + signal UART1_D : std_logic_vector(7 downto 0); + signal CPU_D : std_logic_vector(7 downto 0); + + signal Mirror : std_logic; + + signal IOWR_n : std_logic; + signal RAMCS_n : std_logic; + signal UART0CS_n : std_logic; + signal UART1CS_n : std_logic; + + signal BaudOut0 : std_logic; + signal BaudOut1 : std_logic; + +begin + + Wait_n <= '1'; + BusRq_n <= '1'; + INT_n <= '1'; + + process (Reset_n, Clk) + begin + if Reset_n = '0' then + Reset_s <= '0'; + Mirror <= '0'; + elsif Clk'event and Clk = '1' then + Reset_s <= '1'; + if IORQ_n = '0' and A(7 downto 4) = "1111" then + Mirror <= D(0); + end if; + end if; + end process; + + IOWR_n <= WR_n or IORQ_n; + RAMCS_n <= (not Mirror and not A(15)) or MREQ_n; + UART0CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1'; + UART1CS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "10000" else '1'; + + CPU_D <= + SRAM_D when RAMCS_n = '0' else + UART0_D when UART0CS_n = '0' else + UART1_D when UART1CS_n = '0' else + ROM_D; + + u0 : entity work.T80s + generic map(Mode => 1, T2Write => 1, IOWait => 0) + port map( + RESET_n => RESET_s, + CLK_n => Clk, + WAIT_n => WAIT_n, + INT_n => INT_n, + NMI_n => NMI_n, + BUSRQ_n => BUSRQ_n, + M1_n => M1_n, + MREQ_n => MREQ_n, + IORQ_n => IORQ_n, + RD_n => RD_n, + WR_n => WR_n, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + BUSAK_n => BUSAK_n, + A => A, + DI => CPU_D, + DO => D); + + u1 : entity work.MonZ80 + port map( + Clk => Clk, + A => A(10 downto 0), + D => ROM_D); + + u2 : entity work.SSRAM + generic map( + AddrWidth => 12) + port map( + Clk => Clk, + CE_n => RAMCS_n, + WE_n => WR_n, + A => A(11 downto 0), + DIn => D, + DOut => SRAM_D); + + u3 : entity work.T16450 + port map( + MR_n => Reset_s, + XIn => Clk, + RClk => BaudOut0, + CS_n => UART0CS_n, + Rd_n => RD_n, + Wr_n => IOWR_n, + A => A(2 downto 0), + D_In => D, + D_Out => UART0_D, + SIn => RXD0, + CTS_n => CTS0, + DSR_n => DSR0, + RI_n => RI0, + DCD_n => DCD0, + SOut => TXD0, + RTS_n => RTS0, + DTR_n => DTR0, + OUT1_n => open, + OUT2_n => open, + BaudOut => BaudOut0, + Intr => open); + + u4 : entity work.T16450 + port map( + MR_n => Reset_s, + XIn => Clk, + RClk => BaudOut1, + CS_n => UART1CS_n, + Rd_n => RD_n, + Wr_n => IOWR_n, + A => A(2 downto 0), + D_In => D, + D_Out => UART1_D, + SIn => RXD1, + CTS_n => CTS1, + DSR_n => DSR1, + RI_n => RI1, + DCD_n => DCD1, + SOut => TXD1, + RTS_n => RTS1, + DTR_n => DTR1, + OUT1_n => open, + OUT2_n => open, + BaudOut => BaudOut1, + Intr => open); + +end; Index: t80/trunk/rtl/vhdl/T80s.vhd =================================================================== --- t80/trunk/rtl/vhdl/T80s.vhd (nonexistent) +++ t80/trunk/rtl/vhdl/T80s.vhd (revision 47) @@ -0,0 +1,190 @@ +-- +-- Z80 compatible microprocessor core, synchronous top level +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed read with wait +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80s is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T80s; + +architecture rtl of T80s is + + signal CEN : std_logic; + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end process; + +end; Index: t80/trunk/bench/vhdl/SRAM.vhd =================================================================== --- t80/trunk/bench/vhdl/SRAM.vhd (nonexistent) +++ t80/trunk/bench/vhdl/SRAM.vhd (revision 47) @@ -0,0 +1,92 @@ +-- +-- Simple SRAM model without timing +-- +-- Version : 0247 +-- +-- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity SRAM is + generic( + AddrWidth : integer := 16; + DataWidth : integer := 8 + ); + port( + CE_n : in std_logic; + OE_n : in std_logic; + WE_n : in std_logic; + A : in std_logic_vector(AddrWidth - 1 downto 0); + D : inout std_logic_vector(DataWidth - 1 downto 0) + ); +end SRAM; + +architecture behaviour of SRAM is + + type Memory_Image is array (natural range <>) of std_logic_vector(DataWidth - 1 downto 0); + signal RAM : Memory_Image(0 to 2 ** AddrWidth - 1); + + signal Write : std_logic; + signal D_del : std_logic_vector(7 downto 0); + +begin + + Write <= '1' when CE_n = '0' and WE_n = '0' else '0'; + D_del <= D after 1 ns; + + process (Write) + begin + if Write'event and Write = '0' then + RAM(to_integer(unsigned(A))) <= D_del; + end if; + end process; + + D <= RAM(to_integer(unsigned(A))) +-- pragma translate_off + when OE_n = '0' and CE_n = '0' and WE_n = '1' and not is_x(A) else (others => 'Z') +-- pragma translate_on + ; + +end; Index: t80/trunk/bench/vhdl/TestBench.vhd =================================================================== --- t80/trunk/bench/vhdl/TestBench.vhd (nonexistent) +++ t80/trunk/bench/vhdl/TestBench.vhd (revision 47) @@ -0,0 +1,125 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use work.StimLog.all; + +entity TestBench is +end entity TestBench; + +architecture behaviour of TestBench is + + signal M1_n : std_logic; + signal MREQ_n : std_logic; + signal IORQ_n : std_logic; + signal RD_n : std_logic; + signal WR_n : std_logic; + signal RFSH_n : std_logic; + signal HALT_n : std_logic; + signal WAIT_n : std_logic := '1'; + signal INT_n : std_logic := '1'; + signal NMI_n : std_logic := '1'; + signal RESET_n : std_logic; + signal BUSRQ_n : std_logic := '1'; + signal BUSAK_n : std_logic; + signal CLK_n : std_logic := '0'; + signal A : std_logic_vector(15 downto 0); + signal D : std_logic_vector(7 downto 0); + + signal UART_D : std_logic_vector(7 downto 0); + signal BaudOut : std_logic; + signal TXD : std_logic; + signal RXD : std_logic; + signal CTS : std_logic := '0'; + signal DSR : std_logic := '0'; + signal RI : std_logic := '1'; + signal DCD : std_logic := '0'; + + signal IOWR_n : std_logic; + signal ROMCS_n : std_logic; + signal RAMCS_n : std_logic; + signal UARTCS_n : std_logic; + +begin + + Reset_n <= '0', '1' after 1 us; + + -- 16 MHz clock + CLK_n <= not CLK_n after 31.25 ns; + + IOWR_n <= WR_n or IORQ_n; + ROMCS_n <= A(15) or MREQ_n; + RAMCS_n <= not A(15) or MREQ_n; + UARTCS_n <= '0' when IORQ_n = '0' and A(7 downto 3) = "00000" else '1'; + + -- NMI + NMI_n <= not D(0) when IOWR_n'event and IOWR_n = '1' and A(7 downto 0) = "00001000"; + -- INT + INT_n <= not D(1) when IOWR_n'event and IOWR_n = '1' and A(7 downto 0) = "00001000"; + + as : AsyncStim generic map(FileName => "../../../bench/vhdl/ROM80.vhd", InterCharDelay => 100 us, Baud => 1000000, Bits => 8) + port map(RXD); + + al : AsyncLog generic map(FileName => "RX_Log.txt", Baud => 1000000, Bits => 8) + port map(TXD); + + u0 : entity work.T80a + port map( + RESET_n, + CLK_n, + WAIT_n, + INT_n, + NMI_n, + BUSRQ_n, + M1_n, + MREQ_n, + IORQ_n, + RD_n, + WR_n, + RFSH_n, + HALT_n, + BUSAK_n, + A, + D); + + u1 : entity work.ROM80 + port map( + CE_n => ROMCS_n, + OE_n => RD_n, + A => A(14 downto 0), + D => D); + + u2 : entity work.SRAM + generic map( + AddrWidth => 15) + port map( + CE_n => RAMCS_n, + OE_n => RD_n, + WE_n => WR_n, + A => A(14 downto 0), + D => D); + + D <= UART_D when UARTCS_n = '0' and RD_n = '0' else "ZZZZZZZZ"; + u3 : entity work.T16450 + port map( + MR_n => Reset_n, + XIn => CLK_n, + RClk => BaudOut, + CS_n => UARTCS_n, + Rd_n => RD_n, + Wr_n => IOWR_n, + A => A(2 downto 0), + D_In => D, + D_Out => UART_D, + SIn => RXD, + CTS_n => CTS, + DSR_n => DSR, + RI_n => RI, + DCD_n => DCD, + SOut => TXD, + RTS_n => open, + DTR_n => open, + OUT1_n => open, + OUT2_n => open, + BaudOut => BaudOut, + Intr => open); + +end; Index: t80/trunk/bench/vhdl/DebugSystem_TB.vhd =================================================================== --- t80/trunk/bench/vhdl/DebugSystem_TB.vhd (nonexistent) +++ t80/trunk/bench/vhdl/DebugSystem_TB.vhd (revision 47) @@ -0,0 +1,73 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use work.StimLog.all; + +entity DebugSystem_TB is +end entity DebugSystem_TB; + +architecture behaviour of DebugSystem_TB is + + signal Reset_n : std_logic; + signal Clk : std_logic := '0'; + signal NMI_n : std_logic := '1'; + + signal TXD0 : std_logic; + signal RTS0 : std_logic; + signal DTR0 : std_logic; + signal RXD0 : std_logic; + signal CTS0 : std_logic := '0'; + signal DSR0 : std_logic := '0'; + signal RI0 : std_logic := '1'; + signal DCD0 : std_logic := '0'; + + signal TXD1 : std_logic; + signal RTS1 : std_logic; + signal DTR1 : std_logic; + signal RXD1 : std_logic; + signal CTS1 : std_logic := '0'; + signal DSR1 : std_logic := '0'; + signal RI1 : std_logic := '1'; + signal DCD1 : std_logic := '0'; + +begin + + ni : entity work.DebugSystem + port map( + Reset_n => Reset_n, + Clk => Clk, + NMI_n => NMI_n, + RXD0 => RXD0, + CTS0 => CTS0, + DSR0 => DSR0, + RI0 => RI0, + DCD0 => DCD0, + RXD1 => RXD1, + CTS1 => CTS1, + DSR1 => DSR1, + RI1 => RI1, + DCD1 => DCD1, + TXD0 => TXD0, + RTS0 => RTS0, + DTR0 => DTR0, + TXD1 => TXD1, + RTS1 => RTS1, + DTR1 => DTR1); + + as0 : AsyncStim generic map(FileName => "../../../bench/vhdl/ROM80.vhd", InterCharDelay => 0 us, Baud => 115200, Bits => 8) + port map(RXD0); + + al0 : AsyncLog generic map(FileName => "RX_Log0.txt", Baud => 115200, Bits => 8) + port map(TXD0); + + as1 : AsyncStim generic map(FileName => "RX_Cmd1.txt", InterCharDelay => 0 us, Baud => 115200, Bits => 8) + port map(RXD1); + + al1 : AsyncLog generic map(FileName => "RX_Log1.txt", Baud => 115200, Bits => 8) + port map(TXD1); + + Reset_n <= '0', '1' after 1 us; + + -- 18 MHz clock + Clk <= not Clk after 27 ns; + +end; Index: t80/trunk/bench/vhdl/AsyncLog.vhd =================================================================== --- t80/trunk/bench/vhdl/AsyncLog.vhd (nonexistent) +++ t80/trunk/bench/vhdl/AsyncLog.vhd (revision 47) @@ -0,0 +1,124 @@ +-- +-- Asynchronous serial input with binary file log +-- +-- Version : 0146 +-- +-- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity AsyncLog is + generic( + FileName : string; + Baud : integer; + Bits : integer := 8; -- Data bits + Parity : boolean := false; -- Enable Parity + P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity + ); + port( + RXD : in std_logic + ); +end AsyncLog; + +architecture behaviour of AsyncLog is + + function to_char( + constant Byte : std_logic_vector(7 downto 0) + ) return character is + begin + return character'val(to_integer(unsigned(Byte))); + end function; + + signal Baud16 : std_logic := '0'; + + -- Receive signals + signal Bit_Phase : unsigned(3 downto 0) := "0000"; + signal RX_ShiftReg : std_logic_vector(Bits - 1 downto 0) := (others => '0'); + signal RX_Bit_Cnt : integer := 0; + signal ParTmp : boolean; + +begin + + Baud16 <= not Baud16 after 1000000000 ns / 32 / Baud; + + process (Baud16) + type ChFile is file of character; + file OutFile : ChFile open write_mode is FileName; + begin + if Baud16'event and Baud16 = '1' then + if RX_Bit_Cnt = 0 and (RXD = '1' or Bit_Phase = "0111") then + Bit_Phase <= "0000"; + else + Bit_Phase <= Bit_Phase + 1; + end if; + if RX_Bit_Cnt = 0 then + if Bit_Phase = "0111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + end if; + ParTmp <= false; + elsif Bit_Phase = "1111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + if (RX_Bit_Cnt = Bits + 1 and not Parity) or + (RX_Bit_Cnt = Bits + 2 and Parity) then -- Stop bit + RX_Bit_Cnt <= 0; + assert RXD = '1' + report "Framing error" + severity error; + write(OutFile, to_char(RX_ShiftReg(7 downto 0))); + elsif RX_Bit_Cnt = Bits + 1 and Parity then -- Parity bit + assert ParTmp xor (RXD = '1') = P_Odd_Even_n + report "Parity error" + severity error; + else + ParTmp <= ParTmp xor (RXD = '1'); + RX_ShiftReg(Bits - 2 downto 0) <= RX_ShiftReg(Bits - 1 downto 1); + RX_ShiftReg(Bits - 1) <= RXD; + end if; + end if; + end if; + end process; + +end; + Index: t80/trunk/bench/vhdl/AsyncStim.vhd =================================================================== --- t80/trunk/bench/vhdl/AsyncStim.vhd (nonexistent) +++ t80/trunk/bench/vhdl/AsyncStim.vhd (revision 47) @@ -0,0 +1,115 @@ +-- +-- Asynchronous serial generator with input from binary file +-- +-- Version : 0146 +-- +-- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity AsyncStim is + generic( + FileName : string; + Baud : integer; + InterCharDelay : time := 0 ns; + Bits : integer := 8; -- Data bits + Parity : boolean := false; -- Enable Parity + P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity + ); + port( + TXD : out std_logic + ); +end AsyncStim; + +architecture behaviour of AsyncStim is + + signal TX_ShiftReg : std_logic_vector(Bits - 1 downto 0); + signal TX_Bit_Cnt : integer range 0 to 15 := 0; + signal ParTmp : boolean; + +begin + + process + type ChFile is file of character; + file InFile : ChFile open read_mode is FileName; + variable Inited : boolean := false; + variable CharTmp : character; + variable IntTmp : integer; + begin + if not Inited then + Inited := true; + TXD <= '1'; + end if; + wait for 1000000000 ns / Baud; + TX_Bit_Cnt <= TX_Bit_Cnt + 1; + case TX_Bit_Cnt is + when 0 => + TXD <= '1'; + wait for InterCharDelay; + when 1 => -- Start bit + read(InFile, CharTmp); + IntTmp := character'pos(CharTmp); + TX_ShiftReg(Bits - 1 downto 0) <= std_logic_vector(to_unsigned(IntTmp, Bits)); + TXD <= '0'; + ParTmp <= P_Odd_Even_n; + when others => + TXD <= TX_ShiftReg(0); + ParTmp <= ParTmp xor (TX_ShiftReg(0) = '1'); + TX_ShiftReg(Bits - 2 downto 0) <= TX_ShiftReg(Bits - 1 downto 1); + if (TX_Bit_Cnt = Bits + 1 and not Parity) or + (TX_Bit_Cnt = Bits + 2 and Parity) then -- Stop bit + TX_Bit_Cnt <= 0; + end if; + if Parity and TX_Bit_Cnt = Bits + 2 then + if ParTmp then + TXD <= '1'; + else + TXD <= '0'; + end if; + end if; + end case; + end process; + +end; Index: t80/trunk/bench/vhdl/StimLog.vhd =================================================================== --- t80/trunk/bench/vhdl/StimLog.vhd (nonexistent) +++ t80/trunk/bench/vhdl/StimLog.vhd (revision 47) @@ -0,0 +1,142 @@ +-- +-- File I/O test-bench utilities +-- +-- Version : 0146 +-- +-- Copyright (c) 2001 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package StimLog is + + component AsyncStim + generic( + FileName : string; + Baud : integer; + InterCharDelay : time := 0 ns; + Bits : integer := 8; -- Data bits + Parity : boolean := false; -- Enable Parity + P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity + ); + port( + TXD : out std_logic + ); + end component; + + component AsyncLog + generic( + FileName : string; + Baud : integer; + Bits : integer := 8; -- Data bits + Parity : boolean := false; -- Enable Parity + P_Odd_Even_n : boolean := false -- false => Even Parity, true => Odd Parity + ); + port( + RXD : in std_logic + ); + end component; + + component BinaryStim + generic( + FileName : string; + Bytes : integer := 1; -- Number of bytes per word + LittleEndian : boolean := true -- Byte order + ); + port( + Rd : in std_logic; + Data : out std_logic_vector(Bytes * 8 - 1 downto 0) + ); + end component; + + component BinaryLog + generic( + FileName : string; + Bytes : integer := 1; -- Number of bytes per word + LittleEndian : boolean := true -- Byte order + ); + port( + Clk : in std_logic; + En : in std_logic; + Data : in std_logic_vector(Bytes * 8 - 1 downto 0) + ); + end component; + + component I2SStim is + generic( + FileName : string; + Bytes : integer := 2; -- Number of bytes per word (1 to 4) + LittleEndian : boolean := true -- Byte order + ); + port( + BClk : in std_logic; + FSync : in std_logic; + SData : out std_logic + ); + end component; + + component I2SLog is + generic( + FileName : string; + Bytes : integer := 2; -- Number of bytes per word + LittleEndian : boolean := true -- Byte order + ); + port( + BClk : in std_logic; + FSync : in std_logic; + SData : in std_logic + ); + end component; + + component IntegerLog is + generic( + FileName : string + ); + port( + Clk : in std_logic; + En : in std_logic; + Data : in integer + ); + end component; + +end; Index: t80/trunk/sim/rtl_sim/bin/compile.do =================================================================== --- t80/trunk/sim/rtl_sim/bin/compile.do (nonexistent) +++ t80/trunk/sim/rtl_sim/bin/compile.do (revision 47) @@ -0,0 +1,18 @@ +vcom ../../../rtl/vhdl/T80_Pack.vhd +vcom ../../../rtl/vhdl/T80_MCode.vhd +vcom ../../../rtl/vhdl/T80_ALU.vhd +vcom ../../../rtl/vhdl/T80_Reg.vhd +vcom ../../../rtl/vhdl/T80.vhd +vcom ../../../rtl/vhdl/T80a.vhd +vcom ../../../rtl/vhdl/T80s.vhd +vcom ../../../rtl/vhdl/T16450.vhd +vcom ../../../rtl/vhdl/SSRAM2.vhd +vcom ../../../bench/vhdl/MonZ80.vhd +vcom ../../../rtl/vhdl/DebugSystem.vhd -93 +vcom ../../../bench/vhdl/ROM80.vhd +vcom ../../../bench/vhdl/StimLog.vhd -93 +vcom ../../../bench/vhdl/AsyncLog.vhd -93 +vcom ../../../bench/vhdl/AsyncStim.vhd -93 +vcom ../../../bench/vhdl/SRAM.vhd -93 +vcom ../../../bench/vhdl/TestBench.vhd -93 +vcom ../../../bench/vhdl/DebugSystem_TB.vhd -93 Index: t80/trunk/sim/rtl_sim/bin/RX_Cmd1.txt =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: t80/trunk/sim/rtl_sim/bin/RX_Cmd1.txt =================================================================== --- t80/trunk/sim/rtl_sim/bin/RX_Cmd1.txt (nonexistent) +++ t80/trunk/sim/rtl_sim/bin/RX_Cmd1.txt (revision 47)
t80/trunk/sim/rtl_sim/bin/RX_Cmd1.txt Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: t80/trunk/syn/xilinx/bin/t80debug.tcl =================================================================== --- t80/trunk/syn/xilinx/bin/t80debug.tcl (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debug.tcl (revision 47) @@ -0,0 +1,44 @@ +set process "5" +set part "2s200pq208" +set tristate_map "TRUE" +set opt_auto_mode "TRUE" +set opt_best_result "29223.458000" +set dont_lock_lcells "auto" +set input2output "30.000000" +set input2register "20.000000" +set register2output "20.000000" +set register2register "40.000000" +set wire_table "xis215-5_avg" +set encoding "auto" +set edifin_ground_port_names "GND" +set edifin_power_port_names "VCC" +set edif_array_range_extraction_style "%s\[%d:%d\]" + +set_xilinx_eqn + +load_library xis2 + +read -technology xis2 { +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd +../../../rtl/vhdl/T16450.vhd +../src/MonZ80_leo.vhd +../../../rtl/vhdl/SSRAMX.vhd +../../../rtl/vhdl/DebugSystem.vhd +} + +pre_optimize + +optimize -hierarchy=auto + +optimize_timing + +report_area + +report_delay + +write t80debug_leo.edf Index: t80/trunk/syn/xilinx/bin/t80.tcl =================================================================== --- t80/trunk/syn/xilinx/bin/t80.tcl (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80.tcl (revision 47) @@ -0,0 +1,40 @@ +set process "5" +set part "2s200pq208" +set tristate_map "TRUE" +set opt_auto_mode "TRUE" +set opt_best_result "29223.458000" +set dont_lock_lcells "auto" +set input2output "30.000000" +set input2register "20.000000" +set register2output "20.000000" +set register2register "40.000000" +set wire_table "xis215-5_avg" +set encoding "auto" +set edifin_ground_port_names "GND" +set edifin_power_port_names "VCC" +set edif_array_range_extraction_style "%s\[%d:%d\]" + +set_xilinx_eqn + +load_library xis2 + +read -technology xis2 { +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd +} + +pre_optimize + +optimize -area -hierarchy=auto -pass 1 -pass 2 -pass 3 -pass 4 + +optimize_timing + +report_area + +report_delay + +write t80_leo.edf Index: t80/trunk/syn/xilinx/bin/t80debugxr.tcl =================================================================== --- t80/trunk/syn/xilinx/bin/t80debugxr.tcl (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debugxr.tcl (revision 47) @@ -0,0 +1,43 @@ +set process "5" +set part "2s200pq208" +set tristate_map "TRUE" +set opt_auto_mode "TRUE" +set opt_best_result "29223.458000" +set dont_lock_lcells "auto" +set input2output "30.000000" +set input2register "20.000000" +set register2output "20.000000" +set register2register "40.000000" +set wire_table "xis215-5_avg" +set encoding "auto" +set edifin_ground_port_names "GND" +set edifin_power_port_names "VCC" +set edif_array_range_extraction_style "%s\[%d:%d\]" + +set_xilinx_eqn + +load_library xis2 + +read -technology xis2 { +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd +../../../rtl/vhdl/T16450.vhd +../src/MonZ80_leo.vhd +../../../rtl/vhdl/DebugSystemXR.vhd +} + +pre_optimize + +optimize -hierarchy=auto + +optimize_timing + +report_area + +report_delay + +write t80debugxr_leo.edf Index: t80/trunk/syn/xilinx/bin/t80.prj =================================================================== --- t80/trunk/syn/xilinx/bin/t80.prj (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80.prj (revision 47) @@ -0,0 +1,6 @@ +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd Index: t80/trunk/syn/xilinx/bin/t80debugxr.prj =================================================================== --- t80/trunk/syn/xilinx/bin/t80debugxr.prj (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debugxr.prj (revision 47) @@ -0,0 +1,9 @@ +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd +../../../rtl/vhdl/T16450.vhd +../src/MonZ80.vhd +../../../rtl/vhdl/DebugSystemXR.vhd Index: t80/trunk/syn/xilinx/bin/t80debug.prj =================================================================== --- t80/trunk/syn/xilinx/bin/t80debug.prj (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debug.prj (revision 47) @@ -0,0 +1,10 @@ +../../../rtl/vhdl/T80_Pack.vhd +../../../rtl/vhdl/T80_MCode.vhd +../../../rtl/vhdl/T80_ALU.vhd +../../../rtl/vhdl/T80_RegX.vhd +../../../rtl/vhdl/T80.vhd +../../../rtl/vhdl/T80s.vhd +../../../rtl/vhdl/T16450.vhd +../src/MonZ80.vhd +../../../rtl/vhdl/SSRAMX.vhd +../../../rtl/vhdl/DebugSystem.vhd Index: t80/trunk/syn/xilinx/bin/t80.pin =================================================================== --- t80/trunk/syn/xilinx/bin/t80.pin (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80.pin (revision 47) @@ -0,0 +1,14 @@ +#NET "clk" TNM_NET = "clk"; +#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; + +# Leonardo +#NET "Clk" LOC = "P77"; +#NET "Reset_n" LOC = "P134"; +#NET "Port_D(0)" LOC = "P98"; +#NET "Port_D(1)" LOC = "P96"; + +# XST +#NET "clk" LOC = "P77"; +#NET "reset_n" LOC = "P134"; +#NET "port_d<0>" LOC = "P98"; +#NET "port_d<1>" LOC = "P96"; Index: t80/trunk/syn/xilinx/bin/t80debugxr_leo.pin =================================================================== --- t80/trunk/syn/xilinx/bin/t80debugxr_leo.pin (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debugxr_leo.pin (revision 47) @@ -0,0 +1,41 @@ +#NET "clk" TNM_NET = "clk"; +#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; + +NET "Clk" LOC = "P77"; +NET "Reset_n" LOC = "P152"; +NET "NMI_n" LOC = "P135"; +NET "RXD0" LOC = "P89"; +NET "TXD0" LOC = "P94"; +NET "RXD1" LOC = "P98"; +NET "TXD1" LOC = "P96"; +NET "DTR1" LOC = "P82"; +NET "OE_n" LOC = "P31"; +NET "WE_n" LOC = "P17"; +NET "RAMCS_n" LOC = "P36"; +NET "ROMCS_n" LOC = "P14"; +NET "PGM_n" LOC = "P9"; +NET "A(0)" LOC = "P42"; +NET "A(1)" LOC = "P37"; +NET "A(2)" LOC = "P35"; +NET "A(3)" LOC = "P33"; +NET "A(4)" LOC = "P30"; +NET "A(5)" LOC = "P27"; +NET "A(6)" LOC = "P23"; +NET "A(7)" LOC = "P21"; +NET "A(8)" LOC = "P22"; +NET "A(9)" LOC = "P24"; +NET "A(10)" LOC = "P34"; +NET "A(11)" LOC = "P29"; +NET "A(12)" LOC = "P18"; +NET "A(13)" LOC = "P20"; +NET "A(14)" LOC = "P15"; +NET "A(15)" LOC = "P16"; +NET "A(16)" LOC = "P10"; +NET "D(0)" LOC = "P44"; +NET "D(1)" LOC = "P46"; +NET "D(2)" LOC = "P48"; +NET "D(3)" LOC = "P49"; +NET "D(4)" LOC = "P47"; +NET "D(5)" LOC = "P45"; +NET "D(6)" LOC = "P43"; +NET "D(7)" LOC = "P41"; Index: t80/trunk/syn/xilinx/bin/t80debugxr.pin =================================================================== --- t80/trunk/syn/xilinx/bin/t80debugxr.pin (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debugxr.pin (revision 47) @@ -0,0 +1,41 @@ +#NET "clk" TNM_NET = "clk"; +#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; + +NET "clk" LOC = "P77"; +NET "reset_n" LOC = "P152"; +NET "nmi_n" LOC = "P135"; +NET "rxd0" LOC = "P89"; +NET "txd0" LOC = "P94"; +NET "rxd1" LOC = "P98"; +NET "txd1" LOC = "P96"; +NET "dtr1" LOC = "P82"; +NET "oe_n" LOC = "P31"; +NET "we_n" LOC = "P17"; +NET "ramcs_n" LOC = "P36"; +NET "romcs_n" LOC = "P14"; +NET "pgm_n" LOC = "P9"; +NET "a<0>" LOC = "P42"; +NET "a<1>" LOC = "P37"; +NET "a<2>" LOC = "P35"; +NET "a<3>" LOC = "P33"; +NET "a<4>" LOC = "P30"; +NET "a<5>" LOC = "P27"; +NET "a<6>" LOC = "P23"; +NET "a<7>" LOC = "P21"; +NET "a<8>" LOC = "P22"; +NET "a<9>" LOC = "P24"; +NET "a<10>" LOC = "P34"; +NET "a<11>" LOC = "P29"; +NET "a<12>" LOC = "P18"; +NET "a<13>" LOC = "P20"; +NET "a<14>" LOC = "P15"; +NET "a<15>" LOC = "P16"; +NET "a<16>" LOC = "P10"; +NET "d<0>" LOC = "P44"; +NET "d<1>" LOC = "P46"; +NET "d<2>" LOC = "P48"; +NET "d<3>" LOC = "P49"; +NET "d<4>" LOC = "P47"; +NET "d<5>" LOC = "P45"; +NET "d<6>" LOC = "P43"; +NET "d<7>" LOC = "P41"; Index: t80/trunk/syn/xilinx/bin/t80debugxr.scr =================================================================== --- t80/trunk/syn/xilinx/bin/t80debugxr.scr (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debugxr.scr (revision 47) @@ -0,0 +1,7 @@ +run +-ifn ../bin/t80debugxr.prj +-ifmt VHDL +-ofn ../out/t80debugxr.ngc +-ofmt NGC -p xc2s200-pq208-5 +-opt_mode Speed +-opt_level 2 Index: t80/trunk/syn/xilinx/bin/t80debug.pin =================================================================== --- t80/trunk/syn/xilinx/bin/t80debug.pin (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debug.pin (revision 47) @@ -0,0 +1,11 @@ +#NET "clk" TNM_NET = "clk"; +#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; + +NET "clk" LOC = "P77"; +NET "reset_n" LOC = "P152"; +NET "nmi_n" LOC = "P135"; +NET "rxd0" LOC = "P89"; +NET "txd0" LOC = "P94"; +NET "rxd1" LOC = "P98"; +NET "txd1" LOC = "P96"; +NET "dtr1" LOC = "P82"; Index: t80/trunk/syn/xilinx/bin/t80_leo.pin =================================================================== --- t80/trunk/syn/xilinx/bin/t80_leo.pin (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80_leo.pin (revision 47) @@ -0,0 +1,14 @@ +#NET "clk" TNM_NET = "clk"; +#TIMESPEC "TS_clk" = PERIOD "clk" 20 ns HIGH 50%; + +# Leonardo +#NET "Clk" LOC = "P77"; +#NET "Reset_n" LOC = "P133"; +#NET "Port_D(0)" LOC = "P98"; +#NET "Port_D(1)" LOC = "P96"; + +# XST +#NET "clk" LOC = "P77"; +#NET "reset_n" LOC = "P133"; +#NET "port_d<0>" LOC = "P98"; +#NET "port_d<1>" LOC = "P96"; Index: t80/trunk/syn/xilinx/bin/t80.scr =================================================================== --- t80/trunk/syn/xilinx/bin/t80.scr (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80.scr (revision 47) @@ -0,0 +1,7 @@ +run +-ifn ../bin/t80.prj +-ifmt VHDL +-ofn ../out/t80.ngc +-ofmt NGC -p xc2s200-pq208-5 +-opt_mode Speed +-opt_level 2 Index: t80/trunk/syn/xilinx/bin/t80debug.scr =================================================================== --- t80/trunk/syn/xilinx/bin/t80debug.scr (nonexistent) +++ t80/trunk/syn/xilinx/bin/t80debug.scr (revision 47) @@ -0,0 +1,7 @@ +run +-ifn ../bin/t80debug.prj +-ifmt VHDL +-ofn ../out/t80debug.ngc +-ofmt NGC -p xc2s200-pq208-5 +-opt_mode Speed +-opt_level 2 Index: t80/trunk/syn/xilinx/run/t80.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80.bat (revision 47) @@ -0,0 +1,44 @@ +set name=t80 +rem set target=xc2v250-cs144-6 +rem set target=xcv300e-pq240-8 +set target=xc2s200-pq208-5 + +if "%2" == "" goto default +set target=%2 +:default + +cd ..\out + +if "%1" == "" goto xst + +set name=t80_leo + +copy ..\bin\t80_leo.pin %name%.ucf + +ngdbuild -p %target% %1 %name%.ngd + +goto builddone + +:xst + +copy ..\bin\%name%.pin %name%.ucf + +xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp +ngdbuild -p %target% %name%.ngc + +:builddone + +move %name%.bld ..\log + +map -p %target% -cm speed -c 100 -tx on -o %name%_map %name% +move %name%_map.mrp ..\log\%name%.mrp + +par -ol 3 -t 1 %name%_map -w %name% +move %name%.par ..\log + +trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf + +bitgen -w %name% +move %name%.bgn ..\log + +cd ..\run
t80/trunk/syn/xilinx/run/t80.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/run/t80debugxr.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80debugxr.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80debugxr.bat (revision 47) @@ -0,0 +1,46 @@ +set name=t80debugxr +rem set target=xc2v250-cs144-6 +rem set target=xcv300e-pq240-8 +set target=xc2s200-pq208-5 + +if "%2" == "" goto default +set target=%2 +:default + +cd ..\out + +if "%1" == "" goto xst + +set name=t80debugxr_leo + +copy ..\bin\t80debugxr_leo.pin %name%.ucf + +ngdbuild -p %target% %1 %name%.ngd + +goto builddone + +:xst + +xrom MonZ80 11 8 > ..\src\MonZ80.vhd +hex2rom ..\..\..\sw\monitorxr.hex MonZ80 11b8u > MonZ80.ini +copy ..\out\MonZ80.ini + ..\bin\%name%.pin %name%.ucf + +xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp +ngdbuild -p %target% %name%.ngc + +:builddone + +move %name%.bld ..\log + +map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% +move %name%_map.mrp ..\log\%name%.mrp + +par -ol 3 -t 1 %name%_map -w %name% +move %name%.par ..\log + +trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf + +bitgen -w %name% +move %name%.bgn ..\log + +cd ..\run
t80/trunk/syn/xilinx/run/t80debugxr.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/run/t80debug.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80debug.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80debug.bat (revision 47) @@ -0,0 +1,46 @@ +set name=t80debug +rem set target=xc2v250-cs144-6 +rem set target=xcv300e-pq240-8 +set target=xc2s200-pq208-5 + +if "%2" == "" goto default +set target=%2 +:default + +cd ..\out + +if "%1" == "" goto xst + +set name=t80debug_leo + +copy ..\bin\t80debug.pin %name%.ucf + +ngdbuild -p %target% %1 %name%.ngd + +goto builddone + +:xst + +xrom MonZ80 11 8 > ..\src\MonZ80.vhd +hex2rom ..\..\..\sw\monitor.hex MonZ80 11b8u > MonZ80.ini +copy ..\out\MonZ80.ini + ..\bin\%name%.pin %name%.ucf + +xst -ifn ../bin/%name%.scr -ofn ../log/%name%.srp +ngdbuild -p %target% %name%.ngc + +:builddone + +move %name%.bld ..\log + +map -p %target% -cm speed -c 100 -pr b -timing -tx on -o %name%_map %name% +move %name%_map.mrp ..\log\%name%.mrp + +par -ol 3 -t 1 %name%_map -w %name% +move %name%.par ..\log + +trce %name%.ncd -o ../log/%name%.twr %name%_map.pcf + +bitgen -w %name% +move %name%.bgn ..\log + +cd ..\run
t80/trunk/syn/xilinx/run/t80debug.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/run/t80debugxr_leo.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80debugxr_leo.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80debugxr_leo.bat (revision 47) @@ -0,0 +1,10 @@ +cd ..\out + +hex2rom ..\..\..\sw\monitorxr.hex MonZ80 11b8s > ..\src\MonZ80_leo.vhd + +spectrum -file ..\bin\t80debugxr.tcl +move exemplar.log ..\log\t80debugxr_leo.srp + +cd ..\run + +t80debugxr t80debugxr_leo.edf xc2s200-pq208-5
t80/trunk/syn/xilinx/run/t80debugxr_leo.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/run/t80debug_leo.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80debug_leo.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80debug_leo.bat (revision 47) @@ -0,0 +1,10 @@ +cd ..\out + +hex2rom ..\..\..\sw\monitor.hex MonZ80 11b8s > ..\src\MonZ80_leo.vhd + +spectrum -file ..\bin\t80debug.tcl +move exemplar.log ..\log\t80debug_leo.srp + +cd ..\run + +t80debug t80debug_leo.edf xc2s200-pq208-5
t80/trunk/syn/xilinx/run/t80debug_leo.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/run/t80_leo.bat =================================================================== --- t80/trunk/syn/xilinx/run/t80_leo.bat (nonexistent) +++ t80/trunk/syn/xilinx/run/t80_leo.bat (revision 47) @@ -0,0 +1,8 @@ +cd ..\out + +spectrum -file ..\bin\t80.tcl +move exemplar.log ..\log\t80_leo.srp + +cd ..\run + +t80 t80_leo.edf xc2s200-pq208-5
t80/trunk/syn/xilinx/run/t80_leo.bat Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: t80/trunk/syn/xilinx/log/.keepme =================================================================== Index: t80/trunk/syn/xilinx/out/.keepme =================================================================== Index: t80/trunk/syn/xilinx/src/.keepme =================================================================== Index: t80/trunk/sw/xrom.cpp =================================================================== --- t80/trunk/sw/xrom.cpp (nonexistent) +++ t80/trunk/sw/xrom.cpp (revision 47) @@ -0,0 +1,414 @@ +// +// Xilinx VHDL ROM generator +// +// Version : 0244 +// +// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +// +// All rights reserved +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// Redistributions in 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. +// +// Neither the name of the author nor the names of other contributors may +// be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Please report bugs to the author, but before you do so, please +// make sure that this is not a derivative work and that +// you have the latest version of this file. +// +// The latest version of this file can be found at: +// http://www.opencores.org/cvsweb.shtml/t51/ +// +// Limitations : +// Not all address/data widths produce working code +// Requires stl to compile +// +// File history : +// +// 0220 : Initial release +// +// 0221 : Fixed block ROMs with partial bytes +// +// 0241 : Updated for WebPack 5.1 +// +// 0244 : Added -n option and component declaration +// + +#include +#include +#include +#include + +using namespace std; + +#if !(defined(max)) && _MSC_VER + // VC fix + #define max __max +#endif + +int main (int argc, char *argv[]) +{ + cerr << "Xilinx VHDL ROM generator by Daniel Wallner. Version 0244\n"; + + try + { + unsigned long aWidth; + unsigned long dWidth; + unsigned long select = 0; + unsigned long length = 0; + char z = 0; + + if (argc < 4) + { + cerr << "\nUsage: xrom
\n"; + cerr << "\nThe options can be:\n"; + cerr << " -[decimal number] = SelectRAM usage in 1/16 parts\n"; + cerr << " -z = use tri-state buses\n"; + cerr << " -n [decimal size] = limit rom size\n"; + cerr << "\nExample:\n"; + cerr << " xrom Test_ROM 13 8 -6\n\n"; + return -1; + } + + int result; + + result = sscanf(argv[2], "%lu", &aWidth); + if (result < 1) + { + throw "Error in address bits argument!\n"; + } + + result = sscanf(argv[3], "%lu", &dWidth); + if (result < 1) + { + throw "Error in data bits argument!\n"; + } + + int argument = 4; + + while (argument < argc) + { + char tmpC = 0; + unsigned long tmpL = 0; + + result = sscanf(argv[argument], "%c%lu", &tmpC, &tmpL); + if (result < 1 || tmpC != '-' ) + { + throw "Error in options!\n"; + } + + if (result < 2) + { + sscanf(argv[argument], "%c%c", &tmpC, &tmpC); + if (tmpC != 'z' && tmpC != 'n') + { + throw "Unkown option!\n"; + } + if (tmpC == 'z') + { + z = tmpC; + } + else + { + argument++; + + if (argument == argc) + { + throw "No memory size argument!\n"; + } + + result = sscanf(argv[argument], "%lu", &tmpL); + if (!result) + { + throw "Memory size not a number!\n"; + } + length = tmpL; + } + } + else + { + select = tmpL; + } + argument++; + } + + unsigned long selectIter = 0; + unsigned long blockIter = 0; + unsigned long bytes = (dWidth + 7) / 8; + + if (!select) + { + blockIter = ((1UL << aWidth) + 511) / 512; + if (length && length < blockIter * 512) + { + blockIter = (length + 511) / 512; + } + } + else if (select == 16) + { + selectIter = ((1UL << aWidth) + 15) / 16; + if (length && length < selectIter * 16) + { + selectIter = (length + 15) / 16; + } + } + else + { + blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512; + selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16; + } + + unsigned long blockTotal = ((1UL << aWidth) + 511) / 512; + if (length && length < blockTotal * 512) + { + blockTotal = (length + 511) / 512; + } + + if (length) + { + if (length > selectIter * 16) + { + blockIter -= ((1UL << aWidth) + 511) / 512 - blockTotal; + } + else + { + blockIter = 0; + } + } + if (length && !blockIter && length < selectIter * 16) + { + selectIter = (length + 15) / 16; + } + + cerr << "Creating ROM with " << selectIter * bytes; + cerr << " RAM16X1S and " << blockIter * bytes << " RAMB4_S8\n"; + + printf("-- This file was generated with xrom written by Daniel Wallner\n"); + printf("\nlibrary IEEE;"); + printf("\nuse IEEE.std_logic_1164.all;"); + printf("\nuse IEEE.numeric_std.all;"); + printf("\n\nentity %s is", argv[1]); + printf("\n\tport("); + printf("\n\t\tClk\t: in std_logic;"); + printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1); + printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1); + printf("\n\t);"); + printf("\nend %s;", argv[1]); + printf("\n\narchitecture rtl of %s is", argv[1]); + + if (selectIter) + { + printf("\n\tcomponent RAM16X1S"); + printf("\n\t\tport("); + printf("\n\t\t\tO : out std_ulogic;"); + printf("\n\t\t\tA0 : in std_ulogic;"); + printf("\n\t\t\tA1 : in std_ulogic;"); + printf("\n\t\t\tA2 : in std_ulogic;"); + printf("\n\t\t\tA3 : in std_ulogic;"); + printf("\n\t\t\tD : in std_ulogic;"); + printf("\n\t\t\tWCLK : in std_ulogic;"); + printf("\n\t\t\tWE : in std_ulogic);"); + printf("\n\tend component;\n"); + } + if (blockIter) + { + printf("\n\tcomponent RAMB4_S8"); + printf("\n\t\tport("); + printf("\n\t\t\tDO : out std_logic_vector(7 downto 0);"); + printf("\n\t\t\tADDR : in std_logic_vector(8 downto 0);"); + printf("\n\t\t\tCLK : in std_ulogic;"); + printf("\n\t\t\tDI : in std_logic_vector(7 downto 0);"); + printf("\n\t\t\tEN : in std_ulogic;"); + printf("\n\t\t\tRST : in std_ulogic;"); + printf("\n\t\t\tWE : in std_ulogic);"); + printf("\n\tend component;\n"); + } + + if (selectIter > 0) + { + printf("\n\tsignal A_r: unsigned(A'range);"); + } + if (selectIter > 1) + { + printf("\n\ttype sRAMOut_a is array(0 to %d) of std_logic_vector(D'range);", selectIter - 1); + printf("\n\tsignal sRAMOut : sRAMOut_a;"); + printf("\n\tsignal siA_r : integer;"); + } + if (selectIter && blockIter) + { + printf("\n\tsignal sD : std_logic_vector(D'range);"); + } + if (blockIter == 1) + { + printf("\n\tsignal bRAMOut : std_logic_vector(%d downto 0);", bytes * 8 - 1); + } + if (blockIter > 1) + { + printf("\n\ttype bRAMOut_a is array(%d to %d) of std_logic_vector(%d downto 0);", blockTotal - blockIter, blockTotal - 1, bytes * 8 - 1); + printf("\n\tsignal bRAMOut : bRAMOut_a;"); + printf("\n\tsignal biA_r : integer;"); + if (!selectIter) + { + printf("\n\tsignal A_r : unsigned(A'left downto 9);"); + } + } + if (selectIter && blockIter) + { + printf("\n\tsignal bD : std_logic_vector(D'range);"); + } + + printf("\nbegin"); + + if (selectIter > 0 || blockIter > 1) + { + printf("\n\tprocess (Clk)"); + printf("\n\tbegin"); + printf("\n\t\tif Clk'event and Clk = '1' then"); + if (!selectIter) + { + printf("\n\t\t\tA_r <= unsigned(A(A'left downto 9));"); + } + else + { + printf("\n\t\t\tA_r <= unsigned(A);"); + } + printf("\n\t\tend if;"); + printf("\n\tend process;"); + } + + if (selectIter == 1) + { + printf("\n\n\tsG1: for I in 0 to %d generate", dWidth - 1); + printf("\n\t\tS%s : RAM16X1S\n\t\t\tport map (", argv[1]); + if (blockIter) + { + printf("s"); + } + printf("WE => '0', WCLK => '0', D => '0', O => D(I), A0 => A_r(0), A1 => A_r(1), A2 => A_r(2), A3 => A_r(3));"); + printf("\n\tend generate;"); + } + if (selectIter > 1) + { + printf("\n\n\tsiA_r <= to_integer(A_r(A'left downto 4));"); + printf("\n\n\tsG1: for I in 0 to %d generate", selectIter - 1); + printf("\n\t\tsG2: for J in 0 to %d generate", dWidth - 1); + printf("\n\t\t\tS%s : RAM16X1S\n\t\t\t\tport map (WE => '0', WCLK => '0', D => '0', O => sRAMOut(I)(J), A0 => A_r(0), A1 => A_r(1), A2 => A_r(2), A3 => A_r(3));", argv[1]); + printf("\n\t\tend generate;"); + if (z == 'z') + { + printf("\n\t\t"); + if (blockIter) + { + printf("s"); + } + printf("D <= sRAMOut(I) when siA_r = I else (others => 'Z');"); + } + printf("\n\tend generate;"); + if (z != 'z') + { + printf("\n\n\tprocess (siA_r, sRAMOut)\n\tbegin\n\t\t"); + if (blockIter) + { + printf("s"); + } + printf("D <= sRAMOut(0);"); + printf("\n\t\tfor I in 1 to %d loop", selectIter - 1); + printf("\n\t\t\tif siA_r = I then\n\t\t\t\t"); + if (blockIter) + { + printf("s"); + } + printf("D <= sRAMOut(I);\n\t\t\tend if;"); + printf("\n\t\tend loop;\n\tend process;"); + } + } + + if (blockIter == 1) + { + printf("\n\n\tbG1: for J in 0 to %d generate", bytes - 1); + printf("\n\t\tB%s : RAMB4_S8", argv[1]); + printf("\n\t\t\tport map (DI => \"00000000\", EN => '1', RST => '0', WE => '0', CLK => Clk, ADDR => A(8 downto 0), DO => bRAMOut(7 + 8 * J downto 8 * J));", argv[1]); + printf("\n\tend generate;"); + printf("\n\n\t"); + if (selectIter) + { + printf("b"); + } + printf("D <= bRAMOut(D'range);"); + } + if (blockIter > 1) + { + printf("\n\n\tbiA_r <= to_integer(A_r(A'left downto 9));"); + printf("\n\n\tbG1: for I in %d to %d generate", blockTotal - blockIter, blockTotal - 1); + printf("\n\t\tbG2: for J in 0 to %d generate", bytes - 1); + printf("\n\t\t\tB%s : RAMB4_S8\n\t\t\t\tport map (DI => \"00000000\", EN => '1', RST => '0', WE => '0', CLK => Clk, ADDR => A(8 downto 0), DO => bRAMOut(I)(7 + 8 * J downto 8 * J));", argv[1]); + printf("\n\t\tend generate;"); + if (z == 'z') + { + printf("\n\t\t"); + if (selectIter) + { + printf("b"); + } + printf("D <= bRAMOut(I) when biA_r = I else (others => 'Z');"); + } + printf("\n\tend generate;"); + if (z != 'z') + { + printf("\n\n\tprocess (biA_r, bRAMOut)\n\tbegin\n\t\t"); + if (selectIter) + { + printf("b"); + } + printf("D <= bRAMOut(%d)(D'range);", blockTotal - blockIter); + printf("\n\t\tfor I in %d to %d loop", blockTotal - blockIter + 1, blockTotal - 1); + printf("\n\t\t\tif biA_r = I then\n\t\t\t\t"); + if (selectIter) + { + printf("b"); + } + printf("D <= bRAMOut(I)(D'range);\n\t\t\tend if;"); + printf("\n\t\tend loop;\n\tend process;"); + } + } + + if (selectIter && blockIter) + { + printf("\n\n\tD <= bD when A_r(A'left downto 9) >= %d else sD;", blockTotal - blockIter); + } + + printf("\nend;\n"); + + return 0; + } + catch (string error) + { + cerr << "Fatal: " << error; + } + catch (const char *error) + { + cerr << "Fatal: " << error; + } + return -1; +} Index: t80/trunk/sw/hex2rom.cpp =================================================================== --- t80/trunk/sw/hex2rom.cpp (nonexistent) +++ t80/trunk/sw/hex2rom.cpp (revision 47) @@ -0,0 +1,962 @@ +// +// Binary and intel/motorola hex to VHDL ROM converter +// +// Version : 0244 +// +// Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +// +// All rights reserved +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// Redistributions in 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. +// +// Neither the name of the author nor the names of other contributors may +// be used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Please report bugs to the author, but before you do so, please +// make sure that this is not a derivative work and that +// you have the latest version of this file. +// +// The latest version of this file can be found at: +// http://www.opencores.org/cvsweb.shtml/t51/ +// +// Limitations : +// No support for wrapped intel segments +// Requires stl to compile +// +// File history : +// +// 0146 : Initial release +// +// 0150 : Added binary read +// +// 0208 : Changed some errors to warnings +// +// 0215 : Added support for synchronous ROM +// +// 0220 : Changed array ROM format, added support for Xilinx .UCF generation +// +// 0221 : Fixed small .UCF generation for small ROMs +// +// 0244 : Added Leonardo .UCF option +// + +#include +#include +#include +#include + +using namespace std; + +#if !(defined(max)) && _MSC_VER + // VC fix + #define max __max +#endif + +class MemBlock +{ +public: + unsigned long m_startAddress; + vector m_bytes; +}; + +class File +{ +public: + explicit File(const char *fileName, const char *mode) + { + m_file = fopen(fileName, mode); + if (m_file != NULL) + { + return; + } + string errorStr = "Error opening "; + errorStr += fileName; + errorStr += "\n"; + throw errorStr; + } + + ~File() + { + fclose(m_file); + } + + // Read binary file + void ReadBin(unsigned long limit) + { + m_top = 0; + + m_chunks.push_back(MemBlock()); + m_chunks.back().m_startAddress = 0; + + cerr << "Reading binary file\n"; + + int tmp = fgetc(m_file); + + while (!feof(m_file)) + { + m_chunks.back().m_bytes.push_back(tmp); + + if (m_chunks.back().m_bytes.size() > limit + 1) + { + m_chunks.back().m_bytes.pop_back(); + m_top = m_chunks.back().m_bytes.size() - 1; + cerr << "Ignoring data above address space!\n"; + cerr << " Limit: " << limit << "\n"; + return; + } + + tmp = fgetc(m_file); + } + + m_top = m_chunks.back().m_bytes.size() - 1; + + if (!m_chunks.back().m_bytes.size()) + { + cerr << "No data!\n"; + + m_chunks.pop_back(); + } + } + + // Read hex file + void ReadHex(unsigned long limit) + { + char szLine[1024]; + bool formatDetected = false; + bool intel; + bool endSeen = false; + bool linear = true; // Only used for intel hex + unsigned long addressBase = 0; // Only used for intel hex + unsigned long dataRecords = 0; // Only used for s-record + while (!feof(m_file)) + { + if (fgets(szLine, 1024, m_file) == 0) + { + if (ferror(m_file)) + { + throw "Error reading input!\n"; + } + continue; + } + + if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) + { + szLine[strlen(szLine) - 1] = 0; + } + + if (szLine[strlen(szLine) - 1] == 0xA || szLine[strlen(szLine) - 1] == 0xD) + { + szLine[strlen(szLine) - 1] = 0; + } + + if (strlen(szLine) == 1023) + { + throw "Hex file lines to long!\n"; + } + // Ignore blank lines + if (szLine[0] == '\n') + { + continue; + } + // Detect format and warn if garbage lines are found + if (!formatDetected) + { + if (szLine[0] != ':' && szLine[0] != 'S') + { + cerr << "Ignoring garbage line!\n"; + continue; + } + if (szLine[0] == 'S') + { + intel = false; + cerr << "Detected S-Record\n"; + } + else + { + intel = true; + cerr << "Detected intel hex file\n"; + } + formatDetected = true; + } + else if ((intel && szLine[0] != ':') || + (!intel && szLine[0] != 'S')) + { + cerr << "Ignoring garbage line!\n"; + continue; + } + + if (endSeen) + { + throw "Hex line after end of file record!\n"; + } + + if (intel) + { + unsigned long dataBytes; + unsigned long startAddress; + unsigned long type; + if (sscanf(&szLine[1], "%2lx%4lx%2lx", &dataBytes, &startAddress, &type) != 3) + { + throw "Hex line beginning corrupt!\n"; + } + // Check line length + if (szLine[11 + dataBytes * 2] != '\n' && szLine[11 + dataBytes * 2] != 0) + { + throw "Hex line length incorrect!\n"; + } + // Check line checksum + unsigned char checkSum = 0; + unsigned long tmp; + for (unsigned int i = 0; i <= dataBytes + 4; ++i) + { + if (sscanf(&szLine[1 + i * 2], "%2lx", &tmp) != 1) + { + throw "Hex line data corrupt!\n"; + } + checkSum += tmp; + } + if (checkSum != 0) + { + throw "Hex line checksum error!\n"; + } + + switch (type) + { + case 0: + // Data record + if (!linear) + { + // Segmented + unsigned long test = startAddress; + test += dataBytes; + if (test > 0xffff) + { + throw "Can't handle wrapped segments!\n"; + } + } + if (!m_chunks.size() || + m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != + addressBase + startAddress) + { + m_chunks.push_back(MemBlock()); + m_chunks.back().m_startAddress = addressBase + startAddress; + } + { + unsigned char i = 0; + for (i = 0; i < dataBytes; ++i) + { + sscanf(&szLine[9 + i * 2], "%2lx", &tmp); + if (addressBase + startAddress + i > limit) + { + cerr << "Ignoring data above address space!\n"; + cerr << "Data address: " << addressBase + startAddress + i; + cerr << " Limit: " << limit << "\n"; + if (!m_chunks.back().m_bytes.size()) + { + m_chunks.pop_back(); + } + continue; + } + m_chunks.back().m_bytes.push_back(tmp); + } + } + break; + + case 1: + // End-of-file record + if (dataBytes != 0) + { + cerr << "Warning: End of file record not zero length!\n"; + } + if (startAddress != 0) + { + cerr << "Warning: End of file record address not zero!\n"; + } + endSeen = true; + break; + + case 2: + // Extended segment address record + if (dataBytes != 2) + { + throw "Length field must be 2 in extended segment address record!\n"; + } + if (startAddress != 0) + { + throw "Address field must be zero in extended segment address record!\n"; + } + sscanf(&szLine[9], "%4lx", &startAddress); + addressBase = startAddress << 4; + linear = false; + break; + + case 3: + // Start segment address record + if (dataBytes != 4) + { + cerr << "Warning: Length field must be 4 in start segment address record!\n"; + } + if (startAddress != 0) + { + cerr << "Warning: Address field must be zero in start segment address record!\n"; + } + if (dataBytes == 4) + { + unsigned long ssa; + char ssaStr[16]; + sscanf(&szLine[9], "%8lx", &ssa); + sprintf(ssaStr, "%08X\n", ssa); + cerr << "Segment start address (CS/IP): "; + cerr << ssaStr; + } + break; + + case 4: + // Extended linear address record + if (dataBytes != 2) + { + throw "Length field must be 2 in extended linear address record!\n"; + } + if (startAddress != 0) + { + throw "Address field must be zero in extended linear address record!\n"; + } + sscanf(&szLine[9], "%4lx", &startAddress); + addressBase = ((unsigned long)startAddress) << 16; + linear = true; + break; + + case 5: + // Start linear address record + if (dataBytes != 4) + { + cerr << "Warning: Length field must be 4 in start linear address record!\n"; + } + if (startAddress != 0) + { + cerr << "Warning: Address field must be zero in start linear address record!\n"; + } + if (dataBytes == 4) + { + unsigned long lsa; + char lsaStr[16]; + sscanf(&szLine[9], "%8lx", &lsa); + sprintf(lsaStr, "%08X\n", lsa); + cerr << "Linear start address: "; + cerr << lsaStr; + } + break; + + default: + cerr << "Waring: Unknown record found!\n"; + } + } + else + { + // S-record + unsigned long count; + char type; + if (sscanf(&szLine[1], "%c%2lx", &type, &count) != 2) + { + throw "Hex line beginning corrupt!\n"; + } + // Check line length + if (szLine[4 + count * 2] != '\n' && szLine[4 + count * 2] != 0) + { + throw "Hex line length incorrect!\n"; + } + // Check line checksum + unsigned char checkSum = 0; + unsigned long tmp; + for (unsigned int i = 0; i < count + 1; ++i) + { + if (sscanf(&szLine[2 + i * 2], "%2lx", &tmp) != 1) + { + throw "Hex line data corrupt!\n"; + } + checkSum += tmp; + } + if (checkSum != 255) + { + throw "Hex line checksum error!\n"; + } + + switch (type) + { + case '0': + // Header record + { + char header[256]; + unsigned char i = 0; + for (i = 0; i + 3 < count; ++i) + { + sscanf(&szLine[8 + i * 2], "%2lx", &tmp); + header[i] = tmp; + } + header[i] = 0; + if (i > 0) + { + cerr << "Module name: " << header << "\n"; + } + } + break; + + case '1': + case '2': + case '3': + // Data record + { + dataRecords++; + unsigned long startAddress; + if (type == '1') + { + sscanf(&szLine[4], "%4lx", &startAddress); + } + else if (type == '2') + { + sscanf(&szLine[4], "%6lx", &startAddress); + } + else + { + sscanf(&szLine[4], "%8lx", &startAddress); + } + + if (!m_chunks.size() || + m_chunks.back().m_startAddress + m_chunks.back().m_bytes.size() != + startAddress) + { + m_chunks.push_back(MemBlock()); + m_chunks.back().m_startAddress = startAddress; + } + unsigned char i = 0; + for (i = (type - '1'); i + 3 < count; ++i) + { + sscanf(&szLine[8 + i * 2], "%2lx", &tmp); + if (startAddress + i > limit) + { + cerr << "Ignoring data above address space!\n"; + cerr << "Data address: " << startAddress + i; + cerr << " Limit: " << limit << "\n"; + if (!m_chunks.back().m_bytes.size()) + { + m_chunks.pop_back(); + } + continue; + } + m_chunks.back().m_bytes.push_back(tmp); + } + } + break; + + case '5': + // Count record + { + unsigned long address; + sscanf(&szLine[4], "%4lx", &address); + if (address != dataRecords) + { + throw "Wrong number of data records!\n"; + } + } + break; + + case '7': + case '8': + case '9': + // Start address record + cerr << "Ignoring start address record!\n"; + break; + + default: + cerr << "Unknown record found!\n"; + } + } + } + if (intel && !endSeen) + { + cerr << "No end of file record!\n"; + } + if (!m_chunks.size()) + { + throw "No data in file!\n"; + } + vector::iterator vi; + m_top = 0; + for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) + { + m_top = max(m_top, vi->m_startAddress + vi->m_bytes.size() - 1); + } + } + + // Rather inefficient this one, fix sometime + bool GetByte(const unsigned long address, unsigned char &chr) + { + vector::iterator vi; + + for (vi = m_chunks.begin(); vi < m_chunks.end(); vi++) + { + if (vi->m_startAddress + vi->m_bytes.size() > address && vi->m_startAddress <= address) + { + break; + } + } + if (vi == m_chunks.end()) + { + return false; + } + chr = vi->m_bytes[address - vi->m_startAddress]; + return true; + } + + bool BitString(const unsigned long address, const unsigned char bits, const bool lEndian, string &str) + { + bool ok = false; + long i; + unsigned char chr; + unsigned long data = 0; + unsigned long tmp; + + if (lEndian) + { + for (i = 0; i < (bits + 7) / 8; ++i) + { + ok |= GetByte(address + i, chr); + tmp = chr; + data |= tmp << (8 * i); + } + } + else + { + for (i = 0; i < (bits + 7) / 8; ++i) + { + ok |= GetByte(address + i, chr); + tmp = chr; + data |= tmp << (8 * ((bits + 7) / 8 - i - 1)); + } + } + + if (!ok) + { + return false; + } + + unsigned long mask = 1; + + str = ""; + for (i = 0; i < bits; i++) + { + if (data & mask) + { + str.insert(0,"1"); + } + else + { + str.insert(0,"0"); + } + mask <<= 1; + } + return true; + } + + FILE *Handle() { return m_file; }; + vector m_chunks; + unsigned long m_top; +private: + FILE *m_file; +}; + + +int main (int argc, char *argv[]) +{ + cerr << "Hex to VHDL ROM converter by Daniel Wallner. Version 0244\n"; + + try + { + unsigned long aWidth; + unsigned long dWidth; + char endian; + char O = 0; + + if (!(argc == 4 || argc == 5)) + { + cerr << "\nUsage: hex2rom [-b] \n"; + cerr << "\nIf the -b option is specified the file is read as a binary file\n"; + cerr << "Hex input files must be intel hex or motorola s-record\n"; + cerr << "\nThe format string has the format AEDOS where:\n"; + cerr << " A = Address bits\n"; + cerr << " E = Endianness, l or b\n"; + cerr << " D = Data bits\n"; + cerr << " O = ROM type: (one optional character)\n"; + cerr << " z for tri-state output\n"; + cerr << " a for array ROM\n"; + cerr << " s for synchronous ROM\n"; + cerr << " u for XST ucf\n"; + cerr << " l for Leonardo ucf\n"; + cerr << " S = SelectRAM usage in 1/16 parts (only used when O = u)\n"; + cerr << "\nExample:\n"; + cerr << " hex2rom test.hex Test_ROM 18b16z\n\n"; + return -1; + } + + string inFileName; + string outFileName; + + unsigned long bytes; + unsigned long select = 0; + + if (argc == 5) + { + if (strcmp(argv[1], "-b")) + { + throw "Error in arguments!\n"; + } + } + + int result; + + result = sscanf(argv[argc - 1], "%lu%c%lu%c%lu", &aWidth, &endian, &dWidth, &O, &select); + if (result < 3) + { + throw "Error in output format argument!\n"; + } + + if (aWidth > 32 || (endian != 'l' && endian != 'b') || dWidth > 32 || (result > 3 && O != 'z' && O != 'a' && O != 's' && O != 'u' && O != 'l')) + { + throw "Error in output format argument!\n"; + } + inFileName = argv[argc - 3]; + outFileName = argv[argc - 2]; + + bytes = (dWidth + 7) / 8; + + File inFile(inFileName.c_str(), "rb"); + + if (argc == 4) + { + inFile.ReadHex((1UL << aWidth) * bytes - 1); + } + else + { + inFile.ReadBin((1UL << aWidth) * bytes - 1); + } + + string line; + + unsigned long words = 1; + unsigned long i = inFile.m_top; + i /= bytes; + + while (i != 0) + { + i >>= 1; + words <<= 1; + } + + if (O != 'u' && O != 'l') + { + printf("-- This file was generated with hex2rom written by Daniel Wallner\n"); + printf("\nlibrary IEEE;"); + printf("\nuse IEEE.std_logic_1164.all;"); + printf("\nuse IEEE.numeric_std.all;"); + printf("\n\nentity %s is", outFileName.c_str()); + printf("\n\tport("); + if (O == 'z') + { + printf("\n\t\tCE_n\t: in std_logic;", dWidth - 1); + printf("\n\t\tOE_n\t: in std_logic;", dWidth - 1); + } + if (O == 's') + { + printf("\n\t\tClk\t: in std_logic;", dWidth - 1); + } + printf("\n\t\tA\t: in std_logic_vector(%d downto 0);", aWidth - 1); + printf("\n\t\tD\t: out std_logic_vector(%d downto 0)", dWidth - 1); + printf("\n\t);"); + printf("\nend %s;", outFileName.c_str()); + printf("\n\narchitecture rtl of %s is", outFileName.c_str()); + if (!O) + { + printf("\nbegin"); + printf("\n\tprocess (A)"); + printf("\n\tbegin"); + printf("\n\t\tcase to_integer(unsigned(A)) is"); + } + else if (O == 's') + { + printf("\n\tsignal A_r : std_logic_vector(%d downto 0);", aWidth - 1); + printf("\nbegin"); + printf("\n\tprocess (Clk)"); + printf("\n\tbegin"); + printf("\n\t\tif Clk'event and Clk = '1' then"); + printf("\n\t\t\tA_r <= A;"); + printf("\n\t\tend if;"); + printf("\n\tend process;"); + printf("\n\tprocess (A_r)"); + printf("\n\tbegin"); + printf("\n\t\tcase to_integer(unsigned(A_r)) is"); + } + else + { + printf("\n\tsubtype ROM_WORD is std_logic_vector(%d downto 0);", dWidth - 1); + printf("\n\ttype ROM_TABLE is array(0 to %d) of ROM_WORD;", words - 1); + printf("\n\tconstant ROM: ROM_TABLE := ROM_TABLE'("); + } + + string str; + string strDC; + for (i = 0; i < dWidth; i++) + { + strDC.insert(0, "-"); + } + for (i = 0; i < words; i++) + { + if (!inFile.BitString(i * bytes, dWidth, endian == 'l', str)) + { + str = strDC; + } + if (!O || O == 's') + { + if (inFile.m_top / bytes >= i) + { + printf("\n\t\twhen %06d => D <= \"%s\";",i, str.c_str()); + printf("\t-- 0x%04X", i * bytes); + } + } + else + { + printf("\n\t\t\"%s", str.c_str()); + if (i != words - 1) + { + printf("\","); + } + else + { + printf("\");"); + } + printf("\t-- 0x%04X", i * bytes); + } + } + + if (!O || O == 's') + { + printf("\n\t\twhen others => D <= \"%s\";", strDC.c_str()); + printf("\n\t\tend case;"); + printf("\n\tend process;"); + } + else + { + printf("\nbegin"); + if (O == 'z') + { + printf("\n\tD <= ROM(to_integer(unsigned(A))) when CE_n = '0' and OE_n = '0' else (others => 'Z');"); + } + else + { + printf("\n\tD <= ROM(to_integer(unsigned(A)));"); + } + } + printf("\nend;\n"); + } + else + { + unsigned long selectIter = 0; + unsigned long blockIter = 0; + + if (!select) + { + blockIter = ((1UL << aWidth) + 511) / 512; + } + else if (select == 16) + { + selectIter = ((1UL << aWidth) + 15) / 16; + } + else + { + blockIter = ((1UL << aWidth) * (16 - select) / 16 + 511) / 512; + selectIter = ((1UL << aWidth) - blockIter * 512 + 15) / 16; + } + + cerr << "Creating .ucf file with " << selectIter * bytes; + cerr << " LUTs and " << blockIter * bytes << " block RAMs\n"; + + unsigned long blockTotal = ((1UL << aWidth) + 511) / 512; + + printf("# This file was generated with hex2rom written by Daniel Wallner\n"); + + for (i = 0; i < selectIter; i++) + { + unsigned long base = i * 16 * bytes; + unsigned long j; + unsigned char c; + unsigned long pos; + + // Check that there is any actual data in segment + bool init = false; + for (pos = 0; pos < bytes * 16; pos++) + { + init = inFile.GetByte(base + pos, c); + if (init) + { + break; + } + } + + if (init) + { + for (j = 0; j < dWidth; j++) + { + unsigned long bitMask = 1; + unsigned long bits = 0; + + for (pos = 0; pos < 16; pos++) + { + unsigned long addr; + + if (endian = 'l') + { + addr = base + bytes * pos + j / 8; + } + else + { + addr = base + bytes * pos + bytes - j / 8 - 1; + } + + c = 0; + inFile.GetByte(addr, c); + if (c & (1 << (j % 8))) + { + bits |= bitMask; + } + bitMask <<= 1; + } + + if (O == 'u') + { + if (selectIter == 1) + { + printf("\nINST *s%s%d INIT = %04X;", outFileName.c_str(), j, bits); + } + else + { + printf("\nINST *s%s%d%d INIT = %04X;", outFileName.c_str(), i, j, bits); + } + } + else + { + if (selectIter == 1) + { + printf("\nINST *sG1_%d_S%s INIT = %04X;", j, outFileName.c_str(), bits); + } + else + { + printf("\nINST *sG1_%d_sG2_%d_S%s INIT = %04X;", i, j, outFileName.c_str(), bits); + } + } + } + } + } + + for (i = blockTotal - blockIter; i < blockTotal; i++) + { + unsigned long j; + for (j = 0; j < bytes; j++) + { + unsigned long k; + for (k = 0; k < 16; k++) + { + unsigned long base = i * 512 * bytes + k * 32 * bytes; + unsigned char c; + unsigned long pos; + + // Check that there is any actual data in segment + bool init = false; + for (pos = 0; pos < 32; pos++) + { + init = inFile.GetByte(base + bytes * pos + j, c); + if (init) + { + break; + } + } + + if (init) + { + if (O == 'u') + { + if (blockIter == 1) + { + printf("\nINST *b%s%d INIT_%02X = ", outFileName.c_str(), j, k); + } + else + { + printf("\nINST *b%s%d%d INIT_%02X = ", outFileName.c_str(), i, j, k); + } + } + else + { + if (blockIter == 1) + { + printf("\nINST *bG1_%d_B%s INIT_%02X = ", j, outFileName.c_str(), k); + } + else + { + printf("\nINST *bG1_%d_bG2_%d_B%s INIT_%02X = ", i, j, outFileName.c_str(), k); + } + } + for (pos = 0; pos < 32; pos++) + { + unsigned long addr; + + if (endian = 'l') + { + addr = base + bytes * (31 - pos) + j; + } + else + { + addr = base + bytes * (31 - pos) + bytes - j - 1; + } + + c = 0; + inFile.GetByte(addr, c); + printf("%02X", c); + } + printf(";"); + } + } + } + } + printf("\n"); + } + return 0; + } + catch (string error) + { + cerr << "Fatal: " << error; + } + catch (const char *error) + { + cerr << "Fatal: " << error; + } + return -1; +} Index: t80/trunk/sw/sine.bin =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: t80/trunk/sw/sine.bin =================================================================== --- t80/trunk/sw/sine.bin (nonexistent) +++ t80/trunk/sw/sine.bin (revision 47)
t80/trunk/sw/sine.bin Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: t80/trunk =================================================================== --- t80/trunk (nonexistent) +++ t80/trunk (revision 47)
t80/trunk Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: t80/web_uploads =================================================================== --- t80/web_uploads (nonexistent) +++ t80/web_uploads (revision 47)
t80/web_uploads Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: t80/branches =================================================================== --- t80/branches (nonexistent) +++ t80/branches (revision 47)
t80/branches Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ## Index: t80/tags =================================================================== --- t80/tags (nonexistent) +++ t80/tags (revision 47)
t80/tags Property changes : Added: svn:mergeinfo ## -0,0 +0,0 ##

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.