URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [rtl/] [cpudefs.v] - Rev 56
Go to most recent revision | Compare with Previous | Blame | View Log
/////////////////////////////////////////////////////////////////////////////// // // Filename: cpudefs.v // // Project: Zip CPU -- a small, lightweight, RISC CPU soft core // // Purpose: Some architectures have some needs, others have other needs. // Some of my projects need a Zip CPU with pipelining, others // can't handle the timing required to get the answer from the ALU // back into the input for the ALU. As each different projects has // different needs, I can either 1) reconfigure my entire baseline prior // to building each project, or 2) host a configuration file which contains // the information regarding each baseline. This file is that // configuration file. It controls how the CPU (not the system, // peripherals, or other) is defined and implemented. Several options // are available within here, making the Zip CPU pipelined or not, // able to handle a faster clock with more stalls or a slower clock with // no stalls, etc. // // This file encapsulates those control options. // // The number of LUTs the Zip CPU uses varies dramatically with the // options defined in this file. // // // Creator: Dan Gisselquist, Ph.D. // Gisselquist Tecnology, LLC // /////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015, Gisselquist Technology, LLC // // This program is free software (firmware): you can redistribute it and/or // modify it under the terms of the GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or (at // your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // License: GPL, v3, as defined and found on www.gnu.org, // http://www.gnu.org/licenses/gpl.html // // /////////////////////////////////////////////////////////////////////////////// `ifndef CPUDEFS_H `define CPUDEFS_H // // // The first couple options control the Zip CPU instruction set, and how // it handles various instructions within the set: // // // OPT_CONDITIONAL_FLAGS controls whether or not a conditional instruction // is allowed to set flags. If conditional instructions can set flags, then // strings of conditional instructions will die whenever a flag setting // instruction is executed. If they cannot, then you can execute a string // of functions with no further conditions in them. Set this flag to enable // strings of instructions, as these can be a lot cheaper than the pipeline // stalls associated with a conditional branch. // // This option will likely be changed in the future so that "CMP" and "TST" // instructions set the flags even if they are conditional, to allow multiple // conditions to be tested at once. // // I recommend setting this flag // `define OPT_CONDITIONAL_FLAGS // // // // OPT_ILLEGAL_INSTRUCTION is part of a new section of code that is supposed // to recognize illegal instructions and interrupt the CPU whenever one such // instruction is encountered. The goal is to create a soft floating point // unit via this approach, that can then be replaced with a true floating point // unit. As I'm not there yet, it just catches illegal instructions and // interrupts the CPU on any such instruction--when defined. Otherwise, // illegal instructions are quietly ignored and their behaviour is ... // undefined. (Many get treated like NOOPs ...) // // I recommend setting this flag, although it can be taken out if area is // critical ... // `define OPT_ILLEGAL_INSTRUCTION // // // // OPT_MULTIPLY controls whether or not the multiply is built and included // in the ALU by default. Set this option and a parameter will be set that // includes the multiply. (This parameter may still be overridden, as with // any parameter ...) If the multiply is not included and // OPT_ILLEGAL_INSTRUCTION is set, then the multiply will create an illegal // instruction that will then trip the illegal instruction trap. // // `define OPT_MULTIPLY // // // // OPT_SINGLE_FETCH controls whether or not the prefetch has a cache, and // whether or not it can issue one instruction per clock. When set, the // prefetch has no cache, and only one instruction is fetched at a time. // This effectively sets the CPU so that only one instruction is ever // in the pipeline at once, and hence you may think of this as a "kill // pipeline" option. However, since the pipelined fetch component uses so // much area on the FPGA, this is an important option to use in trimming down // used area if necessary. Hence, it needs to be maintained for that purpose. // Be aware, though, it will drop your performance by a factor between 2x and // 3x. // // I recommend only defining this if you "need" to, if area is tight and // speed isn't as important. Otherwise, just leave this undefined. // // `define OPT_SINGLE_FETCH // // // // The next several options are pipeline optimization options. They make no // sense in a single instruction fetch mode, hence we #ifndef them so they // are only defined if we are in a full pipelined mode (i.e. OPT_SINGLE_FETCH // is not defined). // `ifndef OPT_SINGLE_FETCH // // // // OPT_PRECLEAR_BUS allows an upcoming, unconditional, LOD/STO instruction // to kick the prefetch off the memory bus so that the LOD/STO instruction may // use the bus without waiting for the prefetch cycle to complete. While it // sounds like this should speed things up, it isn't clear that it speeds up // programs that much--often the bus gets precleared for the LOD/STO, only // to have the next instruction stall because it wasn't loaded in time. // // While I recommend setting this flag, that recommendation may change in the // future. // `define OPT_PRECLEAR_BUS // // // // OPT_EARLY_BRANCHING is an attempt to execute a BRA statement as early // as possible, to avoid as many pipeline stalls on a branch as possible. // It's not tremendously successful yet--BRA's suffer 3 stalls instead of 5, // but I intend to keep working on this approach until the number of stalls // gets down to one or (ideally) zero. That way a "BRA" can be used as the // compiler's branch prediction optimizer: BRA's don't stall, while branches on // conditions will always suffer about 5 stalls or so. // // I recommend setting this flag, so as to turn early branching on. // `define OPT_EARLY_BRANCHING // // // // OPT_PIPELINED_BUS_ACCESS controls whether or not LOD/STO instructions // can take advantaged of pipelined bus instructions. To be eligible, the // operations must be identical (cannot pipeline loads and stores, just loads // only or stores only), and the addresses must either be identical or one up // from the previous address. Further, the load/store string must all have // the same conditional. This approach gains the must use, in my humble // opinion, when saving registers to or restoring registers from the stack // at the beginning/end of a procedure, or when doing a context swap. // // I recommend setting this flag, for performance reasons, especially if your // wishbone bus can handle pipelined bus accesses. // `define OPT_PIPELINED_BUS_ACCESS // // // // OPT_SINGLE_CYCLE controls how the Zip CPU handles operations where the // second of two instructions uses a register output from the first of the // two. If set, there will be no stalling between such a pair of instructions. // If not set, the CPU will insert a stall between such a pair to give the // result time to propagate to the second instruction. Other than the existence // of a stall, the CPU will still yield the same results for the same // instructions. // // The purpose of this is really timing: With this option defined, a logical // or combinatorial mux is placed prior to the input of the ALU. This mux, // together with whatever ALU operation is to take place, must both fit within // one clock cycle. If they cannot be made to fit within the one clock cycle, // then either the clock must be slowed down so that they can fit, or this // flag needs to be turned off (not set) to get rid of the mux--hence speeding // up the clock while slowing down some instructions. // `define OPT_SINGLE_CYCLE // // `endif // OPT_SINGLE_FETCH // // `endif // CPUDEFS_H
Go to most recent revision | Compare with Previous | Blame | View Log