mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-03-04 18:33:50 +00:00
add 68k10 and 68k30 to common
This commit is contained in:
BIN
common/CPU/68K10/license/cern_ohl_v_1_2.odt
Normal file
BIN
common/CPU/68K10/license/cern_ohl_v_1_2.odt
Normal file
Binary file not shown.
BIN
common/CPU/68K10/license/cern_ohl_v_1_2.pdf
Normal file
BIN
common/CPU/68K10/license/cern_ohl_v_1_2.pdf
Normal file
Binary file not shown.
897
common/CPU/68K10/license/cern_ohl_v_1_2.txt
Normal file
897
common/CPU/68K10/license/cern_ohl_v_1_2.txt
Normal file
@@ -0,0 +1,897 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head><script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>CERN Open Hardware Licence - cern_ohl_v_1_2.txt - Open Hardware Repository</title>
|
||||
<meta name="description" content="ChiliProject" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<meta name="csrf-param" content="authenticity_token"/>
|
||||
<meta name="csrf-token" content="vZISqDiAMljbLq5tYqMywduU9VQksdL/1JYUZ1Pky8c="/>
|
||||
<link rel='shortcut icon' href='/favicon.ico?1405312613' />
|
||||
<link href="/themes/ohwr-theme/stylesheets/application.css?1404713280" media="all" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="/javascripts/prototype.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/effects.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/dragdrop.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/controls.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/application.js?1405312613" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('The current page contains unsaved text that will be lost if you leave this page.'); });
|
||||
//]]>
|
||||
</script>
|
||||
<script src="/themes/ohwr-theme/javascripts/theme.js?1404713280" type="text/javascript"></script>
|
||||
<!--[if IE 6]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1405312613);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
<!-- page specific tags -->
|
||||
<link href="/stylesheets/scm.css?1405312613" media="screen" rel="stylesheet" type="text/css" /></head>
|
||||
<body class="theme-Ohwr-theme controller-attachments action-show environment-production">
|
||||
<div id="wrapper">
|
||||
<div id="wrapper2">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Sign in</a></li>
|
||||
<li><a href="/account/register" class="register">Register</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Home</a></li>
|
||||
<li><a href="/projects" class="projects">Projects</a></li>
|
||||
<li><a href="/licenses" class="licenses">Licenses</a></li>
|
||||
<li><a href="/companies" class="companies">Companies</a></li>
|
||||
<li><a href="http://www.ohwr.org/projects/ohr-support/wiki" class="help">Help</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/cernohl" method="get">
|
||||
|
||||
<label for='q'>
|
||||
<a href="/search/index/cernohl" accesskey="4">Search</a>:
|
||||
</label>
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h1>CERN Open Hardware Licence</h1>
|
||||
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/cernohl" class="overview">Overview</a></li>
|
||||
<li><a href="/projects/cernohl/wiki" class="wiki">Wiki</a></li>
|
||||
<li><a href="/projects/cernohl/activity" class="activity">Activity</a></li>
|
||||
<li><a href="/mailing_list/show?project_id=cernohl" class="mailing-list">Mailing List</a></li>
|
||||
<li><a href="/projects/cernohl/news" class="news">News</a></li>
|
||||
<li><a href="/projects/cernohl/documents" class="documents">Documents</a></li></ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="nosidebar" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>cern_ohl_v_1_2.txt</h2>
|
||||
|
||||
<div class="attachments">
|
||||
<p>Licence text in text format. -
|
||||
<span class="author"><a href="/users/7">Javier Serrano</a>, 2013-09-06 10:05</span></p>
|
||||
<p><a href="/attachments/download/2388/cern_ohl_v_1_2.txt">Download</a> <span class="size">(8.9 kB)</span></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="filecontent syntaxhl">
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L1"><a href="#L1">1</a></th><td class="line-code"><pre>CERN Open Hardware Licence v1.2
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L2"><a href="#L2">2</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L3"><a href="#L3">3</a></th><td class="line-code"><pre>Preamble
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L4"><a href="#L4">4</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L5"><a href="#L5">5</a></th><td class="line-code"><pre>Through this CERN Open Hardware Licence ("CERN OHL") version 1.2, CERN
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L6"><a href="#L6">6</a></th><td class="line-code"><pre>wishes to provide a tool to foster collaboration and sharing among
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L7"><a href="#L7">7</a></th><td class="line-code"><pre>hardware designers. The CERN OHL is copyright CERN. Anyone is welcome
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L8"><a href="#L8">8</a></th><td class="line-code"><pre>to use the CERN OHL, in unmodified form only, for the distribution of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L9"><a href="#L9">9</a></th><td class="line-code"><pre>their own Open Hardware designs. Any other right is reserved. Release
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L10"><a href="#L10">10</a></th><td class="line-code"><pre>of hardware designs under the CERN OHL does not constitute an
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L11"><a href="#L11">11</a></th><td class="line-code"><pre>endorsement of the licensor or its designs nor does it imply any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L12"><a href="#L12">12</a></th><td class="line-code"><pre>involvement by CERN in the development of such designs.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L13"><a href="#L13">13</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L14"><a href="#L14">14</a></th><td class="line-code"><pre>1. Definitions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L15"><a href="#L15">15</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L16"><a href="#L16">16</a></th><td class="line-code"><pre>In this Licence, the following terms have the following meanings:
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L17"><a href="#L17">17</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L18"><a href="#L18">18</a></th><td class="line-code"><pre>“Licence” means this CERN OHL.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L19"><a href="#L19">19</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L20"><a href="#L20">20</a></th><td class="line-code"><pre>“Documentation” means schematic diagrams, designs, circuit or circuit
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L21"><a href="#L21">21</a></th><td class="line-code"><pre>board layouts, mechanical drawings, flow charts and descriptive text,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L22"><a href="#L22">22</a></th><td class="line-code"><pre>and other explanatory material that is explicitly stated as being made
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L23"><a href="#L23">23</a></th><td class="line-code"><pre>available under the conditions of this Licence. The Documentation may
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L24"><a href="#L24">24</a></th><td class="line-code"><pre>be in any medium, including but not limited to computer files and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L25"><a href="#L25">25</a></th><td class="line-code"><pre>representations on paper, film, or any other media.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L26"><a href="#L26">26</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L27"><a href="#L27">27</a></th><td class="line-code"><pre>“Documentation Location” means a location where the Licensor has
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L28"><a href="#L28">28</a></th><td class="line-code"><pre>placed Documentation, and which he believes will be publicly
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L29"><a href="#L29">29</a></th><td class="line-code"><pre>accessible for at least three years from the first communication to
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L30"><a href="#L30">30</a></th><td class="line-code"><pre>the public or distribution of Documentation.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L31"><a href="#L31">31</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L32"><a href="#L32">32</a></th><td class="line-code"><pre>“Product” means either an entire, or any part of a, device built using
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L33"><a href="#L33">33</a></th><td class="line-code"><pre>the Documentation or the modified Documentation.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L34"><a href="#L34">34</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L35"><a href="#L35">35</a></th><td class="line-code"><pre>“Licensee” means any natural or legal person exercising rights under
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L36"><a href="#L36">36</a></th><td class="line-code"><pre>this Licence.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L37"><a href="#L37">37</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L38"><a href="#L38">38</a></th><td class="line-code"><pre>“Licensor” means any natural or legal person that creates or modifies
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L39"><a href="#L39">39</a></th><td class="line-code"><pre>Documentation and subsequently communicates to the public and/ or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L40"><a href="#L40">40</a></th><td class="line-code"><pre>distributes the resulting Documentation under the terms and conditions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L41"><a href="#L41">41</a></th><td class="line-code"><pre>of this Licence.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L42"><a href="#L42">42</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L43"><a href="#L43">43</a></th><td class="line-code"><pre>A Licensee may at the same time be a Licensor, and vice versa.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L44"><a href="#L44">44</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L45"><a href="#L45">45</a></th><td class="line-code"><pre>Use of the masculine gender includes the feminine and neuter genders
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L46"><a href="#L46">46</a></th><td class="line-code"><pre>and is employed solely to facilitate reading.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L47"><a href="#L47">47</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L48"><a href="#L48">48</a></th><td class="line-code"><pre>2. Applicability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L49"><a href="#L49">49</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L50"><a href="#L50">50</a></th><td class="line-code"><pre>2.1. This Licence governs the use, copying, modification,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L51"><a href="#L51">51</a></th><td class="line-code"><pre>communication to the public and distribution of the Documentation, and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L52"><a href="#L52">52</a></th><td class="line-code"><pre>the manufacture and distribution of Products. By exercising any right
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L53"><a href="#L53">53</a></th><td class="line-code"><pre>granted under this Licence, the Licensee irrevocably accepts these
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L54"><a href="#L54">54</a></th><td class="line-code"><pre>terms and conditions.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L55"><a href="#L55">55</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L56"><a href="#L56">56</a></th><td class="line-code"><pre>2.2. This Licence is granted by the Licensor directly to the Licensee,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L57"><a href="#L57">57</a></th><td class="line-code"><pre>and shall apply worldwide and without limitation in time. The Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L58"><a href="#L58">58</a></th><td class="line-code"><pre>may assign his licence rights or grant sub-licences.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L59"><a href="#L59">59</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L60"><a href="#L60">60</a></th><td class="line-code"><pre>2.3. This Licence does not extend to software, firmware, or code
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L61"><a href="#L61">61</a></th><td class="line-code"><pre>loaded into programmable devices which may be used in conjunction with
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L62"><a href="#L62">62</a></th><td class="line-code"><pre>the Documentation, the modified Documentation or with Products, unless
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L63"><a href="#L63">63</a></th><td class="line-code"><pre>such software, firmware, or code is explicitly expressed to be subject
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L64"><a href="#L64">64</a></th><td class="line-code"><pre>to this Licence. The use of such software, firmware, or code is
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L65"><a href="#L65">65</a></th><td class="line-code"><pre>otherwise subject to the applicable licence terms and conditions.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L66"><a href="#L66">66</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L67"><a href="#L67">67</a></th><td class="line-code"><pre>3. Copying, modification, communication to the public and distribution
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L68"><a href="#L68">68</a></th><td class="line-code"><pre>of the Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L69"><a href="#L69">69</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L70"><a href="#L70">70</a></th><td class="line-code"><pre>3.1. The Licensee shall keep intact all copyright and trademarks
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L71"><a href="#L71">71</a></th><td class="line-code"><pre>notices, all notices referring to Documentation Location, and all
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L72"><a href="#L72">72</a></th><td class="line-code"><pre>notices that refer to this Licence and to the disclaimer of warranties
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L73"><a href="#L73">73</a></th><td class="line-code"><pre>that are included in the Documentation. He shall include a copy
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L74"><a href="#L74">74</a></th><td class="line-code"><pre>thereof in every copy of the Documentation or, as the case may be,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L75"><a href="#L75">75</a></th><td class="line-code"><pre>modified Documentation, that he communicates to the public or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L76"><a href="#L76">76</a></th><td class="line-code"><pre>distributes.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L77"><a href="#L77">77</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L78"><a href="#L78">78</a></th><td class="line-code"><pre>3.2. The Licensee may copy, communicate to the public and distribute
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L79"><a href="#L79">79</a></th><td class="line-code"><pre>verbatim copies of the Documentation, in any medium, subject to the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L80"><a href="#L80">80</a></th><td class="line-code"><pre>requirements specified in section 3.1.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L81"><a href="#L81">81</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L82"><a href="#L82">82</a></th><td class="line-code"><pre>3.3. The Licensee may modify the Documentation or any portion thereof
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L83"><a href="#L83">83</a></th><td class="line-code"><pre>provided that upon modification of the Documentation, the Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L84"><a href="#L84">84</a></th><td class="line-code"><pre>shall make the modified Documentation available from a Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L85"><a href="#L85">85</a></th><td class="line-code"><pre>Location such that it can be easily located by an original Licensor
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L86"><a href="#L86">86</a></th><td class="line-code"><pre>once the Licensee communicates to the public or distributes the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L87"><a href="#L87">87</a></th><td class="line-code"><pre>modified Documentation under section 3.4, and, where required by
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L88"><a href="#L88">88</a></th><td class="line-code"><pre>section 4.1, by a recipient of a Product. However, the Licensor shall
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L89"><a href="#L89">89</a></th><td class="line-code"><pre>not assert his rights under the foregoing proviso unless or until a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L90"><a href="#L90">90</a></th><td class="line-code"><pre>Product is distributed.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L91"><a href="#L91">91</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L92"><a href="#L92">92</a></th><td class="line-code"><pre>3.4. The Licensee may communicate to the public and distribute the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L93"><a href="#L93">93</a></th><td class="line-code"><pre>modified Documentation (thereby in addition to being a Licensee also
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L94"><a href="#L94">94</a></th><td class="line-code"><pre>becoming a Licensor), always provided that he shall:
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L95"><a href="#L95">95</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L96"><a href="#L96">96</a></th><td class="line-code"><pre>a) comply with section 3.1;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L97"><a href="#L97">97</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L98"><a href="#L98">98</a></th><td class="line-code"><pre>b) cause the modified Documentation to carry prominent notices stating
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L99"><a href="#L99">99</a></th><td class="line-code"><pre>that the Licensee has modified the Documentation, with the date and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L100"><a href="#L100">100</a></th><td class="line-code"><pre>description of the modifications;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L101"><a href="#L101">101</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L102"><a href="#L102">102</a></th><td class="line-code"><pre>c) cause the modified Documentation to carry a new Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L103"><a href="#L103">103</a></th><td class="line-code"><pre>Location notice if the original Documentation provided for one;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L104"><a href="#L104">104</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L105"><a href="#L105">105</a></th><td class="line-code"><pre>d) make available the modified Documentation at the same level of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L106"><a href="#L106">106</a></th><td class="line-code"><pre>abstraction as that of the Documentation, in the preferred format for
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L107"><a href="#L107">107</a></th><td class="line-code"><pre>making modifications to it (e.g. the native format of the CAD tool as
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L108"><a href="#L108">108</a></th><td class="line-code"><pre>applicable), and in the event that format is proprietary, in a format
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L109"><a href="#L109">109</a></th><td class="line-code"><pre>viewable with a tool licensed under an OSI-approved license if the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L110"><a href="#L110">110</a></th><td class="line-code"><pre>proprietary tool can create it; and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L111"><a href="#L111">111</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L112"><a href="#L112">112</a></th><td class="line-code"><pre>e) license the modified Documentation under the terms and conditions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L113"><a href="#L113">113</a></th><td class="line-code"><pre>of this Licence or, where applicable, a later version of this Licence
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L114"><a href="#L114">114</a></th><td class="line-code"><pre>as may be issued by CERN.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L115"><a href="#L115">115</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L116"><a href="#L116">116</a></th><td class="line-code"><pre>3.5. The Licence includes a non-exclusive licence to those patents or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L117"><a href="#L117">117</a></th><td class="line-code"><pre>registered designs that are held by, under the control of, or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L118"><a href="#L118">118</a></th><td class="line-code"><pre>sub-licensable by the Licensor, to the extent necessary to make use of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L119"><a href="#L119">119</a></th><td class="line-code"><pre>the rights granted under this Licence. The scope of this section 3.5
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L120"><a href="#L120">120</a></th><td class="line-code"><pre>shall be strictly limited to the parts of the Documentation or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L121"><a href="#L121">121</a></th><td class="line-code"><pre>modified Documentation created by the Licensor.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L122"><a href="#L122">122</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L123"><a href="#L123">123</a></th><td class="line-code"><pre>4. Manufacture and distribution of Products
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L124"><a href="#L124">124</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L125"><a href="#L125">125</a></th><td class="line-code"><pre>4.1. The Licensee may manufacture or distribute Products always
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L126"><a href="#L126">126</a></th><td class="line-code"><pre>provided that, where such manufacture or distribution requires a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L127"><a href="#L127">127</a></th><td class="line-code"><pre>licence under this Licence the Licensee provides to each recipient of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L128"><a href="#L128">128</a></th><td class="line-code"><pre>such Products an easy means of accessing a copy of the Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L129"><a href="#L129">129</a></th><td class="line-code"><pre>or modified Documentation, as applicable, as set out in section 3.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L130"><a href="#L130">130</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L131"><a href="#L131">131</a></th><td class="line-code"><pre>4.2. The Licensee is invited to inform any Licensor who has indicated
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L132"><a href="#L132">132</a></th><td class="line-code"><pre>his wish to receive this information about the type, quantity and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L133"><a href="#L133">133</a></th><td class="line-code"><pre>dates of production of Products the Licensee has (had) manufactured
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L134"><a href="#L134">134</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L135"><a href="#L135">135</a></th><td class="line-code"><pre>5. Warranty and liability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L136"><a href="#L136">136</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L137"><a href="#L137">137</a></th><td class="line-code"><pre>5.1. DISCLAIMER – The Documentation and any modified Documentation are
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L138"><a href="#L138">138</a></th><td class="line-code"><pre>provided "as is" and any express or implied warranties, including, but
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L139"><a href="#L139">139</a></th><td class="line-code"><pre>not limited to, implied warranties of merchantability, of satisfactory
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L140"><a href="#L140">140</a></th><td class="line-code"><pre>quality, non-infringement of third party rights, and fitness for a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L141"><a href="#L141">141</a></th><td class="line-code"><pre>particular purpose or use are disclaimed in respect of the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L142"><a href="#L142">142</a></th><td class="line-code"><pre>Documentation, the modified Documentation or any Product. The Licensor
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L143"><a href="#L143">143</a></th><td class="line-code"><pre>makes no representation that the Documentation, modified
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L144"><a href="#L144">144</a></th><td class="line-code"><pre>Documentation, or any Product, does or will not infringe any patent,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L145"><a href="#L145">145</a></th><td class="line-code"><pre>copyright, trade secret or other proprietary right. The entire risk as
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L146"><a href="#L146">146</a></th><td class="line-code"><pre>to the use, quality, and performance of a Product shall be with the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L147"><a href="#L147">147</a></th><td class="line-code"><pre>Licensee and not the Licensor. This disclaimer of warranty is an
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L148"><a href="#L148">148</a></th><td class="line-code"><pre>essential part of this Licence and a condition for the grant of any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L149"><a href="#L149">149</a></th><td class="line-code"><pre>rights granted under this Licence. The Licensee warrants that it does
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L150"><a href="#L150">150</a></th><td class="line-code"><pre>not act in a consumer capacity.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L151"><a href="#L151">151</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L152"><a href="#L152">152</a></th><td class="line-code"><pre>5.2. LIMITATION OF LIABILITY – The Licensor shall have no liability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L153"><a href="#L153">153</a></th><td class="line-code"><pre>for direct, indirect, special, incidental, consequential, exemplary,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L154"><a href="#L154">154</a></th><td class="line-code"><pre>punitive or other damages of any character including, without
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L155"><a href="#L155">155</a></th><td class="line-code"><pre>limitation, procurement of substitute goods or services, loss of use,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L156"><a href="#L156">156</a></th><td class="line-code"><pre>data or profits, or business interruption, however caused and on any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L157"><a href="#L157">157</a></th><td class="line-code"><pre>theory of contract, warranty, tort (including negligence), product
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L158"><a href="#L158">158</a></th><td class="line-code"><pre>liability or otherwise, arising in any way in relation to the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L159"><a href="#L159">159</a></th><td class="line-code"><pre>Documentation, modified Documentation and/or the use, manufacture or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L160"><a href="#L160">160</a></th><td class="line-code"><pre>distribution of a Product, even if advised of the possibility of such
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L161"><a href="#L161">161</a></th><td class="line-code"><pre>damages, and the Licensee shall hold the Licensor(s) free and harmless
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L162"><a href="#L162">162</a></th><td class="line-code"><pre>from any liability, costs, damages, fees and expenses, including
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L163"><a href="#L163">163</a></th><td class="line-code"><pre>claims by third parties, in relation to such use.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L164"><a href="#L164">164</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L165"><a href="#L165">165</a></th><td class="line-code"><pre>6. General
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L166"><a href="#L166">166</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L167"><a href="#L167">167</a></th><td class="line-code"><pre>6.1. Except for the rights explicitly granted hereunder, this Licence
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L168"><a href="#L168">168</a></th><td class="line-code"><pre>does not imply or represent any transfer or assignment of intellectual
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L169"><a href="#L169">169</a></th><td class="line-code"><pre>property rights to the Licensee.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L170"><a href="#L170">170</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L171"><a href="#L171">171</a></th><td class="line-code"><pre>6.2. The Licensee shall not use or make reference to any of the names
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L172"><a href="#L172">172</a></th><td class="line-code"><pre>(including acronyms and abbreviations), images, or logos under which
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L173"><a href="#L173">173</a></th><td class="line-code"><pre>the Licensor is known, save in so far as required to comply with
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L174"><a href="#L174">174</a></th><td class="line-code"><pre>section 3. Any such permitted use or reference shall be factual and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L175"><a href="#L175">175</a></th><td class="line-code"><pre>shall in no event suggest any kind of endorsement by the Licensor or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L176"><a href="#L176">176</a></th><td class="line-code"><pre>its personnel of the modified Documentation or any Product, or any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L177"><a href="#L177">177</a></th><td class="line-code"><pre>kind of implication by the Licensor or its personnel in the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L178"><a href="#L178">178</a></th><td class="line-code"><pre>preparation of the modified Documentation or Product.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L179"><a href="#L179">179</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L180"><a href="#L180">180</a></th><td class="line-code"><pre>6.3. CERN may publish updated versions of this Licence which retain
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L181"><a href="#L181">181</a></th><td class="line-code"><pre>the same general provisions as this version, but differ in detail so
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L182"><a href="#L182">182</a></th><td class="line-code"><pre>far this is required and reasonable. New versions will be published
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L183"><a href="#L183">183</a></th><td class="line-code"><pre>with a unique version number.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L184"><a href="#L184">184</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L185"><a href="#L185">185</a></th><td class="line-code"><pre>6.4. This Licence shall terminate with immediate effect, upon written
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L186"><a href="#L186">186</a></th><td class="line-code"><pre>notice and without involvement of a court if the Licensee fails to
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L187"><a href="#L187">187</a></th><td class="line-code"><pre>comply with any of its terms and conditions, or if the Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L188"><a href="#L188">188</a></th><td class="line-code"><pre>initiates legal action against Licensor in relation to this
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L189"><a href="#L189">189</a></th><td class="line-code"><pre>Licence. Section 5 shall continue to apply.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Loading...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="bgl"><div class="bgr">
|
||||
Powered by <a href="https://www.chiliproject.org/">ChiliProject</a>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript" src="http://piwik.ohwr.org/piwik.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var piwikTracker = Piwik.getTracker("http://piwik.ohwr.org/piwik.php", 1);
|
||||
piwikTracker.trackPageView();
|
||||
piwikTracker.enableLinkTracking();
|
||||
} catch( err ) {}
|
||||
</script><noscript><p><img src="http://piwik.ohwr.org/piwik.php?idsite=1" style="border:0" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {
|
||||
NREUMQ.push(["load",new Date().getTime()]);
|
||||
var e=document.createElement("script");
|
||||
e.type="text/javascript";
|
||||
e.src=(("http:"===document.location.protocol)?"http:":"https:") + "//" +
|
||||
"js-agent.newrelic.com/nr-100.js";
|
||||
document.body.appendChild(e);
|
||||
if(NREUMQ.a)NREUMQ.a();
|
||||
};
|
||||
NREUMQ.a=window.onload;window.onload=NREUMQ.f;
|
||||
};
|
||||
NREUMQ.push(["nrfj","beacon-1.newrelic.com","a682afbce1","790800","cl4LRBQNCloGF0lWREVQBlgLBwhCEEoVX19G",0,570,new Date().getTime(),"","","","",""]);</script></body>
|
||||
</html>
|
||||
BIN
common/CPU/68K10/license/cern_ohl_v_1_2_howto.odt
Normal file
BIN
common/CPU/68K10/license/cern_ohl_v_1_2_howto.odt
Normal file
Binary file not shown.
BIN
common/CPU/68K10/license/cern_ohl_v_1_2_howto.pdf
Normal file
BIN
common/CPU/68K10/license/cern_ohl_v_1_2_howto.pdf
Normal file
Binary file not shown.
40
common/CPU/68K10/wf68K10.sdc
Normal file
40
common/CPU/68K10/wf68K10.sdc
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright © 2014 Wolfgang Foerster Inventronik GmbH.
|
||||
#
|
||||
# This documentation describes Open Hardware and is licensed
|
||||
# under the CERN OHL v. 1.2. You may redistribute and modify
|
||||
# this documentation under the terms of the CERN OHL v.1.2.
|
||||
# (http://ohwr.org/cernohl). This documentation is distributed
|
||||
# WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF
|
||||
# MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for
|
||||
# applicable conditions
|
||||
|
||||
# Revision History
|
||||
|
||||
# Revision 2K14B 20140922 WF
|
||||
# Initial Release.
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Time Information
|
||||
#**************************************************************
|
||||
|
||||
# set_time_format -unit ns -decimal_places 3
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Create Clock
|
||||
#**************************************************************
|
||||
|
||||
# create_clock -name CLK -period 100.000 -waveform {0.000 50.000} [get_ports {CLK}]
|
||||
create_clock -period 20.000 -name CLK [get_ports {CLK}]
|
||||
|
||||
#derive_pll_clocks
|
||||
#derive_pll_clocks -use_net_name
|
||||
derive_clock_uncertainty
|
||||
|
||||
#set_clock_groups -exclusive -group {CLK_PLL1}
|
||||
#set_clock_groups -exclusive -group {CLK_PLL2}
|
||||
#set_clock_groups -exclusive -group {CODEC_SCLK}
|
||||
512
common/CPU/68K10/wf68k10_address_registers.vhd
Normal file
512
common/CPU/68K10/wf68k10_address_registers.vhd
Normal file
@@ -0,0 +1,512 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K10 IP Core: Address register logic. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This module provides the address registers, stack pointers, ----
|
||||
---- the address arithmetics, the program counter logic and the SFC ----
|
||||
---- and DFC registers. The address registers are accessible by two ----
|
||||
---- read and two write ports simultaneously. For more information ----
|
||||
---- refer to the MC68030 User' Manual. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K16A 20160620 WF
|
||||
-- Minor optimizations.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- Changed ADR_ATN logic to be valid one clock cycle earlier.
|
||||
-- Fixed PC restoring during exception processing.
|
||||
-- Fixed the writing ISP_REG during EXG instruction with two address registers.
|
||||
-- Fixed writing the stack pointer registers (SBIT_WB is used instead of SBIT).
|
||||
-- The address registers are always written long.
|
||||
-- Bugfix: exception handler do not increment and decrement the USP any more.
|
||||
-- MOVEM-Fix: the effective address in memory to register is stored (STORE_AEFF) not to be overwritten in case the addressing register is also loaded.
|
||||
-- Revision 2K19A 2019## WF
|
||||
-- Removed ADR_ATN. We do not need this any more.
|
||||
-- Fixed the condition if UNMARK and AR_MARK_USED are asserted simultaneously (see process P_IN_USE).
|
||||
--
|
||||
|
||||
use work.WF68K10_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K10_ADDRESS_REGISTERS is
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
|
||||
-- Address and data:
|
||||
AR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
AR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
AR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
AR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
INDEX_IN : in std_logic_vector(31 downto 0);
|
||||
PC : out std_logic_vector(31 downto 0); -- Program counter (or sPC) always word aligned.
|
||||
PC_EW_OFFSET : in std_logic_vector(3 downto 0); -- Offset to the first address extension word.
|
||||
STORE_ADR_FORMAT : in bit;
|
||||
STORE_ABS_HI : in bit;
|
||||
STORE_ABS_LO : in bit;
|
||||
STORE_D16 : in bit;
|
||||
STORE_DISPL : in bit;
|
||||
STORE_AEFF : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
|
||||
ADR_OFFSET : in std_logic_vector(31 downto 0);
|
||||
ADR_MARK_USED : in bit;
|
||||
USE_APAIR : in boolean;
|
||||
ADR_IN_USE : out bit;
|
||||
|
||||
ADR_MODE : in std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : in std_logic_vector(2 downto 0);
|
||||
ADR_EFF : out std_logic_vector(31 downto 0); -- This is the effective address.
|
||||
ADR_EFF_WB : out std_logic_vector(31 downto 0); -- This is the effective address.
|
||||
|
||||
DFC : out std_logic_vector(2 downto 0);
|
||||
DFC_WR : in bit;
|
||||
SFC : out std_logic_vector(2 downto 0);
|
||||
SFC_WR : in bit;
|
||||
|
||||
ISP_DEC : in bit;
|
||||
ISP_WR : in bit;
|
||||
USP_RD : in bit;
|
||||
USP_WR : in bit;
|
||||
|
||||
-- Registers controls:
|
||||
AR_MARK_USED : in bit;
|
||||
AR_IN_USE : out bit;
|
||||
AR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
AR_DEC : in bit; -- Address register decrement.
|
||||
AR_INC : in bit; -- Address register increment.
|
||||
AR_WR_1 : in bit; -- Address register write.
|
||||
AR_WR_2 : in bit; -- Address register write.
|
||||
UNMARK : in bit;
|
||||
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
|
||||
SBIT : in std_logic;
|
||||
|
||||
SP_ADD_DISPL : in bit;
|
||||
RESTORE_ISP_PC : in bit;
|
||||
|
||||
-- Other controls:
|
||||
DISPLACEMENT : in std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : in bit;
|
||||
PC_INC : in bit; -- Program counter increment.
|
||||
PC_LOAD : in bit; -- Program counter write.
|
||||
PC_RESTORE : in bit;
|
||||
PC_OFFSET : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity WF68K10_ADDRESS_REGISTERS;
|
||||
|
||||
architecture BEHAVIOR of WF68K10_ADDRESS_REGISTERS is
|
||||
type AR_TYPE is array(0 to 6) of std_logic_vector(31 downto 0);
|
||||
signal ADR_EFF_I : std_logic_vector(31 downto 0);
|
||||
signal AR : AR_TYPE; -- Address registers A0 to A6.
|
||||
signal AR_OUT_1_I : std_logic_vector(31 downto 0);
|
||||
signal AR_OUT_2_I : std_logic_vector(31 downto 0);
|
||||
signal ADR_WB : std_logic_vector(32 downto 0);
|
||||
signal AR_PNTR_1 : integer range 0 to 7;
|
||||
signal AR_PNTR_2 : integer range 0 to 7;
|
||||
signal AR_PNTR_WB_1 : integer range 0 to 7;
|
||||
signal AR_PNTR_WB_2 : integer range 0 to 7;
|
||||
signal AR_USED_1 : std_logic_vector(3 downto 0);
|
||||
signal AR_USED_2 : std_logic_vector(3 downto 0);
|
||||
signal DFC_REG : std_logic_vector(2 downto 0); -- Special function code registers.
|
||||
signal ISP_REG : std_logic_vector(31 downto 0); -- Interrupt stack pointer (refers to A7'' in the supervisor mode).
|
||||
signal SBIT_WB : std_logic;
|
||||
signal PC_I : std_logic_vector(31 downto 0); -- Active program counter.
|
||||
signal SCALE : std_logic_vector(1 downto 0); -- Scale information for the index.
|
||||
signal SFC_REG : std_logic_vector(2 downto 0); -- Special function code registers.
|
||||
signal USP_REG : std_logic_vector(31 downto 0); -- User stack pointer (refers to A7 in the user mode.).
|
||||
begin
|
||||
INBUFFER: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if AR_MARK_USED = '1' then
|
||||
AR_PNTR_WB_1 <= conv_integer(AR_SEL_WR_1);
|
||||
AR_PNTR_WB_2 <= conv_integer(AR_SEL_WR_2);
|
||||
end if;
|
||||
end process INBUFFER;
|
||||
|
||||
AR_PNTR_1 <= conv_integer(AR_SEL_RD_1);
|
||||
AR_PNTR_2 <= conv_integer(AR_SEL_RD_2);
|
||||
|
||||
P_IN_USE: process
|
||||
variable DELAY : boolean;
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' or (UNMARK = '1' and AR_MARK_USED = '0') then
|
||||
AR_USED_1(3) <= '0';
|
||||
AR_USED_2(3) <= '0';
|
||||
elsif AR_MARK_USED = '1' then
|
||||
AR_USED_1 <= '1' & AR_SEL_WR_1;
|
||||
if USE_APAIR = true then
|
||||
AR_USED_2 <= '1' & AR_SEL_WR_2;
|
||||
end if;
|
||||
SBIT_WB <= SBIT;
|
||||
end if;
|
||||
--
|
||||
if RESET = '1' or (UNMARK = '1' and AR_MARK_USED = '0') then
|
||||
ADR_WB(32) <= '0';
|
||||
DELAY := false;
|
||||
elsif ADR_MARK_USED = '1' then
|
||||
DELAY := true; -- One clock cycle address calculation delay.
|
||||
elsif DELAY = true then
|
||||
ADR_WB <= '1' & ADR_EFF_I;
|
||||
DELAY := false;
|
||||
end if;
|
||||
end process P_IN_USE;
|
||||
|
||||
AR_IN_USE <= '1' when AR_USED_1(3) = '1' and AR_USED_1(2 downto 0) = AR_SEL_RD_1 else
|
||||
'1' when AR_USED_1(3) = '1' and AR_USED_1(2 downto 0) = AR_SEL_RD_2 else
|
||||
'1' when AR_USED_2(3) = '1' and AR_USED_2(2 downto 0) = AR_SEL_RD_1 else
|
||||
'1' when AR_USED_2(3) = '1' and AR_USED_2(2 downto 0) = AR_SEL_RD_2 else '0';
|
||||
|
||||
AR_OUT_1 <= AR_OUT_1_I;
|
||||
AR_OUT_2 <= AR_OUT_2_I;
|
||||
|
||||
ADR_IN_USE <= '1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) = ADR_EFF_I(31 downto 2) else -- Actual long word address.
|
||||
'1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) - '1' = ADR_EFF_I(31 downto 2) else -- Lock a misaligned access.
|
||||
'1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) + '1' = ADR_EFF_I(31 downto 2) else '0'; -- Lock a misaligned access.
|
||||
|
||||
ADR_FORMAT: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if STORE_ADR_FORMAT = '1' then
|
||||
SCALE <= EXT_WORD(10 downto 9);
|
||||
end if;
|
||||
end process ADR_FORMAT;
|
||||
|
||||
ADDRESS_MODES: process(ADR_MODE, AMODE_SEL, AR, AR_PNTR_1, CLK,
|
||||
ISP_REG, PC_EW_OFFSET, PC_I, RESTORE_ISP_PC, SBIT, USP_REG)
|
||||
-- The effective address calculation takes place in this process depending on the
|
||||
-- selected addressing mode.
|
||||
-- The PC address (PC_I) used for the address calculation points to the first
|
||||
-- extension word used.
|
||||
variable ABS_ADDRESS : std_logic_vector(31 downto 0);
|
||||
variable ADR_EFF_VAR : std_logic_vector(31 downto 0);
|
||||
variable ADR_EFF_TMP : std_logic_vector(31 downto 0);
|
||||
variable ADR_MUX : std_logic_vector(31 downto 0);
|
||||
variable BASE_DISPL : std_logic_vector(31 downto 0);
|
||||
variable INDEX : std_logic_vector(31 downto 0) := x"00000000";
|
||||
variable INDEX_SCALED : std_logic_vector(31 downto 0);
|
||||
variable PCVAR : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
PCVAR := PC_I + PC_EW_OFFSET; -- This is the address of the extension word.
|
||||
|
||||
if CLK = '1' and CLK' event then
|
||||
-- This logic selects the INDEX from one of the data registers or from one of
|
||||
-- the address registers. Furthermore the index needs to be sign extended from
|
||||
-- 8 bit to 32 bit or from 16 bit to 32 bit dependent on the address mode.
|
||||
-- In case of a long word operation, no extension is required. The index is
|
||||
-- multiplied by 1, 2, 4 or 8.
|
||||
if STORE_ADR_FORMAT = '1' and EXT_WORD(15) = '0' and EXT_WORD(11) = '1' then
|
||||
INDEX := INDEX_IN; -- Long data register.
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(15) = '0' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := INDEX_IN(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := INDEX_IN(15 downto 0); -- Sign extended data register;
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(11) = '1' then -- Long address register.
|
||||
if EXT_WORD(14 downto 12) = "111" and SBIT = '1' then
|
||||
INDEX := ISP_REG;
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '0' then
|
||||
INDEX := USP_REG;
|
||||
else
|
||||
INDEX := AR(conv_integer(EXT_WORD(14 downto 12)));
|
||||
end if;
|
||||
elsif STORE_ADR_FORMAT = '1' then -- Sign extended address register;
|
||||
if EXT_WORD(14 downto 12) = "111" and SBIT = '1' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := ISP_REG(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := ISP_REG(15 downto 0);
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '0' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := USP_REG(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := USP_REG(15 downto 0);
|
||||
else
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := AR(conv_integer(EXT_WORD(14 downto 12)))(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := AR(conv_integer(EXT_WORD(14 downto 12)))(15 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
case SCALE is
|
||||
when "00" => INDEX_SCALED := INDEX; -- Multiple by 1.
|
||||
when "01" => INDEX_SCALED := INDEX(30 downto 0) & '0'; -- Multiple by 2.
|
||||
when "10" => INDEX_SCALED := INDEX(29 downto 0) & "00"; -- Multiple by 4.
|
||||
when others => INDEX_SCALED := INDEX(28 downto 0) & "000"; -- Multiple by 8.
|
||||
end case;
|
||||
--
|
||||
-- The displacement needs to be sign extended from 8 bit to 32, from 16 bit to 32 bit or
|
||||
-- not extended dependent on the address mode.
|
||||
if RESET = '1' then
|
||||
BASE_DISPL := (others => '0'); -- Null base displacement.
|
||||
elsif STORE_ADR_FORMAT = '1' then
|
||||
for i in 31 downto 8 loop
|
||||
BASE_DISPL(i) := EXT_WORD(7);
|
||||
end loop;
|
||||
BASE_DISPL(7 downto 0) := EXT_WORD(7 downto 0);
|
||||
elsif STORE_D16 = '1' then
|
||||
for i in 31 downto 16 loop
|
||||
BASE_DISPL(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
BASE_DISPL(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_DISPL = '1' then
|
||||
BASE_DISPL := DISPLACEMENT;
|
||||
end if;
|
||||
--
|
||||
if STORE_ABS_LO = '1' then
|
||||
if AMODE_SEL = "000" then
|
||||
for i in 31 downto 16 loop
|
||||
ABS_ADDRESS(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
end if;
|
||||
ABS_ADDRESS(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_ABS_HI = '1' then
|
||||
ABS_ADDRESS(31 downto 16) := EXT_WORD;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
case AR_PNTR_1 is
|
||||
when 7 =>
|
||||
if SBIT = '1' then
|
||||
ADR_MUX := ISP_REG;
|
||||
else
|
||||
ADR_MUX := USP_REG;
|
||||
end if;
|
||||
when others => ADR_MUX := AR(AR_PNTR_1);
|
||||
end case;
|
||||
|
||||
case ADR_MODE is
|
||||
-- when "000" | "001" => Direct address modes: no effective address required.
|
||||
when "010" | "011" | "100" =>
|
||||
ADR_EFF_VAR := ADR_MUX; -- (An), (An)+, -(An).
|
||||
when "101" => -- Address register indirect with offset. Assembler syntax: (d16,An).
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL; -- (d16,An).
|
||||
when "110" =>
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL + INDEX_SCALED; -- (d8, An, Xn, SIZE*SCALE).
|
||||
when "111" =>
|
||||
case AMODE_SEL is
|
||||
when "000" | "001" =>
|
||||
ADR_EFF_VAR := ABS_ADDRESS;
|
||||
when "010" => -- (d16, PC).
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL;
|
||||
when "011" =>
|
||||
-- Assembler syntax: (d8,PC,Xn.SIZE*SCALE).
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL + INDEX_SCALED; -- (d8, PC, Xn, SIZE*SCALE).
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Don't care, while not used.
|
||||
end case;
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Result not required.
|
||||
end case;
|
||||
--
|
||||
if CLK = '1' and CLK' event then
|
||||
if RESTORE_ISP_PC = '1' then
|
||||
ADR_EFF_I <= ADR_OFFSET; -- During exception processing.
|
||||
elsif STORE_AEFF = '1' then -- Used for MOVEM.
|
||||
ADR_EFF_I <= ADR_EFF_TMP + ADR_OFFSET; -- Keep the effective address. See also CONTROL section.
|
||||
else -- Normal operation:
|
||||
ADR_EFF_I <= ADR_EFF_VAR + ADR_OFFSET;
|
||||
ADR_EFF_TMP := ADR_EFF_VAR;
|
||||
end if;
|
||||
end if;
|
||||
end process ADDRESS_MODES;
|
||||
|
||||
ADR_EFF <= ADR_EFF_I;
|
||||
ADR_EFF_WB <= ADR_WB(31 downto 0);
|
||||
|
||||
-- Data outputs:
|
||||
AR_OUT_1_I <= USP_REG when USP_RD = '1' else
|
||||
AR(AR_PNTR_1) when AR_PNTR_1 < 7 else
|
||||
ISP_REG when SBIT = '1' else USP_REG;
|
||||
|
||||
AR_OUT_2_I <= AR(AR_PNTR_2) when AR_PNTR_2 < 7 else
|
||||
ISP_REG when SBIT = '1' else USP_REG;
|
||||
|
||||
PC <= PC_I;
|
||||
|
||||
PROGRAM_COUNTER: process
|
||||
-- Note: PC_LOAD and PC_ADD_DISPL must be highest
|
||||
-- prioritized. The reason is that in case of jumps
|
||||
-- or branches the Ipipe is flushed in connection
|
||||
-- with PC_INC. In such cases PC_LOAD or PC_ADD_DISPL
|
||||
-- are asserted simultaneously with PC_INC.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
PC_I <= (others => '0');
|
||||
elsif PC_LOAD = '1' then
|
||||
PC_I <= AR_IN_1;
|
||||
elsif PC_ADD_DISPL = '1' then
|
||||
PC_I <= PC_I + DISPLACEMENT;
|
||||
elsif PC_RESTORE = '1' then
|
||||
PC_I <= AR_IN_1; -- Keep prioritization!
|
||||
elsif PC_INC = '1' then
|
||||
PC_I <= PC_I + PC_OFFSET;
|
||||
end if;
|
||||
end process PROGRAM_COUNTER;
|
||||
|
||||
STACK_POINTERS: process
|
||||
-- The registers are modeled in a way
|
||||
-- that write and simultaneously increment
|
||||
-- decrement and others are possible for
|
||||
-- different registers.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
---------------------------------------- ISP section ----------------------------------------
|
||||
if RESET = '1' then
|
||||
ISP_REG <= (others => '0');
|
||||
elsif AR_WR_1 = '1' and AR_PNTR_WB_1 = 7 and SBIT_WB = '1' then
|
||||
ISP_REG <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 = 7 and SBIT = '1' then
|
||||
case OP_SIZE is
|
||||
when BYTE => ISP_REG <= ISP_REG + "10"; -- Increment by two!
|
||||
when WORD => ISP_REG <= ISP_REG + "10"; -- Increment by two.
|
||||
when others => ISP_REG <= ISP_REG + "100"; -- Increment by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if ISP_DEC = '1' or (AR_DEC = '1' and AR_PNTR_1 = 7 and SBIT = '1') then
|
||||
case OP_SIZE is
|
||||
when BYTE => ISP_REG <= ISP_REG - "10"; -- Decrement by two!
|
||||
when WORD => ISP_REG <= ISP_REG - "10"; -- Decrement by two.
|
||||
when others => ISP_REG <= ISP_REG - "100"; -- Decrement by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if ISP_WR = '1' then
|
||||
ISP_REG <= AR_IN_1;
|
||||
elsif SP_ADD_DISPL = '1' and AR_INC = '1' and SBIT = '1' then
|
||||
ISP_REG <= ISP_REG + DISPLACEMENT + "100"; -- Used for RTD.
|
||||
elsif SP_ADD_DISPL = '1' and SBIT = '1' then
|
||||
ISP_REG <= ISP_REG + DISPLACEMENT;
|
||||
end if;
|
||||
|
||||
---------------------------------------- USP section ----------------------------------------
|
||||
if RESET = '1' then
|
||||
USP_REG <= (others => '0');
|
||||
elsif AR_WR_1 = '1' and AR_PNTR_WB_1 = 7 and SBIT_WB = '0' then
|
||||
USP_REG <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 = 7 and SBIT = '0' then
|
||||
case OP_SIZE is
|
||||
when BYTE => USP_REG <= USP_REG + "10"; -- Increment by two!
|
||||
when WORD => USP_REG <= USP_REG + "10"; -- Increment by two.
|
||||
when others => USP_REG <= USP_REG + "100"; -- Increment by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_DEC = '1' and AR_PNTR_1 = 7 and SBIT = '0' then
|
||||
case OP_SIZE is
|
||||
when BYTE => USP_REG <= USP_REG - "10"; -- Decrement by two!
|
||||
when WORD => USP_REG <= USP_REG - "10"; -- Decrement by two.
|
||||
when others => USP_REG <= USP_REG - "100"; -- Decrement by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if USP_WR = '1' then
|
||||
USP_REG <= AR_IN_1;
|
||||
elsif SP_ADD_DISPL = '1' and AR_INC = '1' and SBIT = '0' then
|
||||
USP_REG <= USP_REG + DISPLACEMENT + "100"; -- Used for RTD.
|
||||
elsif SP_ADD_DISPL = '1' and SBIT = '0' then
|
||||
USP_REG <= USP_REG + DISPLACEMENT;
|
||||
end if;
|
||||
|
||||
---------------------------------- ISP / USP section ----------------------------------------
|
||||
if AR_WR_2 = '1' and AR_PNTR_WB_2 = 7 and SBIT_WB = '1' then
|
||||
ISP_REG <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
elsif AR_WR_2 = '1' and AR_PNTR_WB_2 = 7 then
|
||||
USP_REG <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
end if;
|
||||
end process STACK_POINTERS;
|
||||
|
||||
ADDRESS_REGISTERS: process
|
||||
-- The registers are modeled in a way
|
||||
-- that write and simultaneously increment
|
||||
-- decrement and others are possible for
|
||||
-- different registers.
|
||||
begin
|
||||
--
|
||||
wait until CLK = '1' and CLK' event;
|
||||
|
||||
if RESET = '1' then
|
||||
AR <= (others => (Others => '0'));
|
||||
end if;
|
||||
|
||||
if AR_WR_1 = '1' and AR_PNTR_WB_1 < 7 then
|
||||
AR(AR_PNTR_WB_1) <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 < 7 then
|
||||
case OP_SIZE is
|
||||
when BYTE => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + '1';
|
||||
when WORD => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + "10";
|
||||
when others => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + "100";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_DEC = '1' and AR_PNTR_1 < 7 then
|
||||
case OP_SIZE is
|
||||
when BYTE => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - '1';
|
||||
when WORD => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - "10";
|
||||
when others => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - "100";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_WR_2 = '1' and AR_PNTR_WB_2 < 7 then
|
||||
AR(AR_PNTR_WB_2) <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
end if;
|
||||
end process ADDRESS_REGISTERS;
|
||||
|
||||
FCODES: process
|
||||
-- These flip flops provide the alternate function
|
||||
-- code registers.
|
||||
variable SFC_REG : std_logic_vector(2 downto 0);
|
||||
variable DFC_REG : std_logic_vector(2 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if DFC_WR = '1' then
|
||||
DFC_REG := AR_IN_1(2 downto 0);
|
||||
end if;
|
||||
--
|
||||
if SFC_WR = '1' then
|
||||
SFC_REG := AR_IN_1(2 downto 0);
|
||||
end if;
|
||||
--
|
||||
DFC <= DFC_REG;
|
||||
SFC <= SFC_REG;
|
||||
end process FCODES;
|
||||
end BEHAVIOR;
|
||||
1071
common/CPU/68K10/wf68k10_alu.vhd
Normal file
1071
common/CPU/68K10/wf68k10_alu.vhd
Normal file
File diff suppressed because it is too large
Load Diff
767
common/CPU/68K10/wf68k10_bus_interface.vhd
Normal file
767
common/CPU/68K10/wf68k10_bus_interface.vhd
Normal file
@@ -0,0 +1,767 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K10 IP Core: this is the bus interface. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This module is a 68010 compatible bus controller featuring ----
|
||||
---- all of the 68010 bus interface functionality. ----
|
||||
---- ----
|
||||
---- Bus cycle operation: ----
|
||||
---- A bus cycle is invoked by either asserting RD_REQ, WR_REQ or ----
|
||||
---- OPCODE_REQ. Data is provided after the respective bus cycle ----
|
||||
---- has finished. The RD_REQ, WR_REQ or OPCODE_REQ signals should ----
|
||||
---- stay asserted until the respective _RDY signal from the bus ----
|
||||
---- controller indicates, that the data is available. These _RDY ----
|
||||
---- signals are strobes. If more than one read or write request ----
|
||||
---- are asserted the same time, RD_REQ is prioritized over WR_REQ ----
|
||||
---- and OPCODE_REQ has lowest priority. For more information of ----
|
||||
---- the signal functionality of the bus controller entity see also ----
|
||||
---- the comments below. ----
|
||||
---- ----
|
||||
---- Remarks: ----
|
||||
---- ----
|
||||
---- Bus arbitration topics: ----
|
||||
---- Additionally to the single wire and the three wire bus arbi- ----
|
||||
---- tration as described in the 68030 hardware manual, the bus ----
|
||||
---- controller also features the two wire arbitration as des- ----
|
||||
---- cribed in the documentation of the 68020 processor. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- Fixed a bug in the DATA_PORT_OUT multiplexer. Thanks to Gary Bingham for the support.
|
||||
-- Fixed a bug in the DATA_INMUX multiplexer. Thanks to Gary Bingham for the support.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- RESET is now 124 instead of 512 clock cycles.
|
||||
-- Adjusted the SSW to 68K10.
|
||||
-- Removed RERUN_RMC.
|
||||
-- Suppress bus faults during RESET instruction.
|
||||
-- Optimized ASn and DSn timing for synchronous RAM.
|
||||
-- DATA_PORT_EN timing optimization.
|
||||
-- BUS_EN is now active except during arbitration.
|
||||
-- Rearanged the DATA_RDY vs. BUS_FLT logic.
|
||||
-- Opted out START_READ and CHK_RD.
|
||||
-- UDSn and LDSn are now always enabled for opcode cycles (bugfix).
|
||||
-- Fixed the faulty bus arbitration logic.
|
||||
-- Rearranged address error handling.
|
||||
-- Revision 2K20A 20200620 WF
|
||||
-- ASn and DSn are not asserted in S0 any more.
|
||||
-- Some modifications to optimize the RETRY logic.
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K10_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity WF68K10_BUS_INTERFACE is
|
||||
port (
|
||||
-- System control:
|
||||
CLK : in std_logic; -- System clock.
|
||||
|
||||
-- Adress bus:
|
||||
ADR_IN_P : in std_logic_vector(31 downto 0); -- Logical address line inputs.
|
||||
ADR_OUT_P : out std_logic_vector(31 downto 0); -- Address line outputs.
|
||||
|
||||
-- Function code relevant stuff:
|
||||
FC_IN : in std_logic_vector(2 downto 0); -- Function codes.
|
||||
FC_OUT : out std_logic_vector(2 downto 0); -- Physical function codes (top level entity).
|
||||
|
||||
-- Data bus:
|
||||
DATA_PORT_IN : in std_logic_vector(15 downto 0); -- Data bus input lines (top level entity).
|
||||
DATA_PORT_OUT : out std_logic_vector(15 downto 0); -- Data bus output lines (top level entity).
|
||||
DATA_FROM_CORE : in std_logic_vector(31 downto 0); -- Internal bus input lines.
|
||||
DATA_TO_CORE : out std_logic_vector(31 downto 0); -- Internal data bus output lines.
|
||||
OPCODE_TO_CORE : out std_logic_vector(15 downto 0); -- Internal instruction bus output lines.
|
||||
|
||||
-- Tri state controls:
|
||||
DATA_PORT_EN : out std_logic; -- For the data bus.
|
||||
BUS_EN : out std_logic; -- For all other bus control signals.
|
||||
|
||||
|
||||
-- Operation size:
|
||||
OP_SIZE : in OP_SIZETYPE; -- Used for bus access control.
|
||||
|
||||
-- Control signals:
|
||||
RD_REQ : in bit; -- Read data.
|
||||
WR_REQ : in bit; -- Write data.
|
||||
DATA_RDY : out bit; -- Indicates 'new data available' (this is a strobe).
|
||||
DATA_VALID : out std_logic; -- The data buffer contains valid data when '1'.
|
||||
OPCODE_REQ : in bit; -- Read opcode.
|
||||
OPCODE_RDY : out bit; -- Indicates 'new opcode available' (this is a strobe).
|
||||
OPCODE_VALID : out std_logic; -- The opcode buffer contains valid data when '1'.
|
||||
RMC : in bit; -- Indicates a read modify write operation.
|
||||
BUSY_EXH : in bit;
|
||||
INBUFFER : out std_logic_vector(31 downto 0); -- Used by the exception handler for stack frame type B.
|
||||
OUTBUFFER : out std_logic_vector(31 downto 0); -- Used by the exception handler for stack frame types A and B.
|
||||
SSW : out std_logic_vector(15 downto 0);
|
||||
|
||||
-- Asynchronous bus control signals:
|
||||
DTACKn : in std_logic; -- Asynchronous bus cycle termination (top level entity).
|
||||
ASn : out std_logic; -- Adress select (top level entity).
|
||||
UDSn : out std_logic; -- Data select (top level entity).
|
||||
LDSn : out std_logic; -- Data select (top level entity).
|
||||
RWn : out std_logic; -- Hi is read, low = write (top level entity).
|
||||
RMCn : out std_logic; -- Read modify write indicator (top level entity).
|
||||
DBENn : out std_logic; -- Data buffer enable (top level entity).
|
||||
|
||||
-- Synchronous peripheral control:
|
||||
E : out std_logic;
|
||||
VMAn : out std_logic;
|
||||
VMA_EN : out std_logic;
|
||||
VPAn : in std_logic;
|
||||
|
||||
-- Bus arbitration:
|
||||
BRn : in std_logic; -- Bus request (top level entity).
|
||||
BGACKn : in std_logic; -- Bus grant acknowledge (top level entity).
|
||||
BGn : out std_logic; -- Bus grant (top level entity).
|
||||
|
||||
-- Exception signals:
|
||||
RESET_IN : in std_logic; -- System's reset input (top level entity).
|
||||
RESET_STRB : in bit; -- From Core: force external reset.
|
||||
RESET_OUT : out std_logic; -- System's reset output open drain enable.
|
||||
RESET_CPU : out bit; -- Internal reset used for CPU initialization.
|
||||
AVECn : in std_logic; -- Auto interrupt vector input (top level entity).
|
||||
HALTn : in std_logic; -- Halt (top level entity).
|
||||
BERRn : in std_logic; -- Bus error (top level entity).
|
||||
AERR : out bit; -- Core internal address error.
|
||||
|
||||
BUS_BSY : out bit -- Bus is busy when '1'.
|
||||
);
|
||||
end entity WF68K10_BUS_INTERFACE;
|
||||
|
||||
architecture BEHAVIOR of WF68K10_BUS_INTERFACE is
|
||||
type BUS_CTRL_STATES is (IDLE, START_CYCLE, DATA_C1C4);
|
||||
type ARB_STATES is(IDLE, GRANT, WAIT_RELEASE_3WIRE);
|
||||
type TIME_SLICES is (IDLE, S0, S1, S2, S3, S4, S5);
|
||||
signal ADR_OFFSET : std_logic_vector(5 downto 0);
|
||||
signal ADR_OUT_I : std_logic_vector(31 downto 0);
|
||||
signal AERR_I : bit;
|
||||
signal ARB_STATE : ARB_STATES := IDLE;
|
||||
signal AVEC_In : std_logic;
|
||||
signal BGACK_In : std_logic;
|
||||
signal BR_In : std_logic;
|
||||
signal BUS_CTRL_STATE : BUS_CTRL_STATES;
|
||||
signal BUS_CYC_RDY : bit;
|
||||
signal BUS_FLT : std_logic;
|
||||
signal DATA_INMUX : std_logic_vector(31 downto 0);
|
||||
signal DATA_RDY_I : bit;
|
||||
signal DBUFFER : std_logic_vector(31 downto 0);
|
||||
signal DSn : std_logic;
|
||||
signal DTACK_In : std_logic;
|
||||
signal HALT_In : std_logic;
|
||||
signal HALTED : bit;
|
||||
signal NEXT_ARB_STATE : ARB_STATES;
|
||||
signal NEXT_BUS_CTRL_STATE : BUS_CTRL_STATES;
|
||||
signal OBUFFER : std_logic_vector(15 downto 0);
|
||||
signal OPCODE_ACCESS : bit;
|
||||
signal OPCODE_RDY_I : bit;
|
||||
signal READ_ACCESS : bit;
|
||||
signal RESET_CPU_I : bit;
|
||||
signal RESET_OUT_I : std_logic;
|
||||
signal RETRY : bit;
|
||||
signal RW_In : std_logic;
|
||||
signal SIZE_D : std_logic_vector(1 downto 0);
|
||||
signal SIZE_I : std_logic_vector(1 downto 0);
|
||||
signal SIZE_N : std_logic_vector(2 downto 0) := "000";
|
||||
signal SLICE_CNT_N : std_logic_vector(2 downto 0);
|
||||
signal SLICE_CNT_P : std_logic_vector(2 downto 0);
|
||||
signal SYNCn : bit;
|
||||
signal T_SLICE : TIME_SLICES;
|
||||
signal VMA_In : std_logic;
|
||||
signal WAITSTATES : bit;
|
||||
signal WP_BUFFER : std_logic_vector(31 downto 0);
|
||||
signal WRITE_ACCESS : bit;
|
||||
begin
|
||||
P_SYNC: process(CLK)
|
||||
-- These flip flops synchronize external signals on the negative clock edge. This
|
||||
-- meets the requirement of sampling these signals in the end of S2 for asynchronous
|
||||
-- bus access. Be aware, that we have to buffer the RETRY signal to prevent the bus
|
||||
-- controller of spurious or timing critical BERRn and/or HALTn signals. The logic
|
||||
-- for BUS_FLT and RETRY is coded in a way that we have a bus error or a retry
|
||||
-- condition but not both at the same time.
|
||||
-- Note: there is no need to synchronize the already synchronous bus control signals
|
||||
variable BERR_VARn : std_logic;
|
||||
variable HALT_VARn : std_logic;
|
||||
begin
|
||||
if CLK = '0' and CLK' event then
|
||||
DTACK_In <= DTACKn;
|
||||
BR_In <= BRn;
|
||||
BGACK_In <= BGACKn;
|
||||
AVEC_In <= AVECn;
|
||||
HALT_VARn := HALTn;
|
||||
BERR_VARn := BERRn;
|
||||
end if;
|
||||
--
|
||||
if CLK = '1' and CLK' event then
|
||||
if BUS_CTRL_STATE = START_CYCLE then
|
||||
AERR <= AERR_I; -- AERR_I is valid in this state.
|
||||
else
|
||||
AERR <= '0';
|
||||
end if;
|
||||
--
|
||||
HALT_In <= HALTn or HALT_VARn;
|
||||
--
|
||||
if BUS_CTRL_STATE = DATA_C1C4 then
|
||||
if (BERRn nand BERR_VARn) = '1' and (HALTn or HALT_VARn) = '0' and SIZE_N /= "000" then
|
||||
RETRY <= '1';
|
||||
elsif T_SLICE = IDLE and (BERRn = '1' and HALTn = '1' and BERR_VARn = '1' and HALT_VARn = '1') then
|
||||
RETRY <= '0';
|
||||
elsif RETRY = '0' then
|
||||
BUS_FLT <= (BERRn nor BERR_VARn) and HALT_VARn and HALTn;
|
||||
end if;
|
||||
else
|
||||
BUS_FLT <= '0';
|
||||
RETRY <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process P_SYNC;
|
||||
|
||||
ACCESSTYPE: process
|
||||
-- This logic stores the execution unit control
|
||||
-- signals during the current bus access. This is
|
||||
-- important for the bus control signals to be
|
||||
-- stable during the complete bus access.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUS_CTRL_STATE = START_CYCLE then
|
||||
if READ_ACCESS = '1' or WRITE_ACCESS = '1' or OPCODE_ACCESS = '1' then
|
||||
null; -- Do not start either new cycle.
|
||||
elsif RD_REQ = '1' then
|
||||
READ_ACCESS <= '1';
|
||||
elsif WR_REQ = '1' then
|
||||
WRITE_ACCESS <= '1';
|
||||
elsif OPCODE_REQ = '1' then
|
||||
OPCODE_ACCESS <= '1';
|
||||
end if;
|
||||
elsif AERR_I = '1' or (BUS_CTRL_STATE = DATA_C1C4 and NEXT_BUS_CTRL_STATE = IDLE) then
|
||||
READ_ACCESS <= '0';
|
||||
WRITE_ACCESS <= '0';
|
||||
OPCODE_ACCESS <= '0';
|
||||
end if;
|
||||
end process ACCESSTYPE;
|
||||
|
||||
P_DF: process
|
||||
-- This is the logic which provides the fault flags for data cycles and
|
||||
-- input and output buffer information.
|
||||
variable SIZEVAR : std_logic_vector(1 downto 0) := "00";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUSY_EXH = '0' then -- Do not alter during exception processing.
|
||||
case OP_SIZE is
|
||||
when LONG => SIZEVAR := "10";
|
||||
when WORD => SIZEVAR := "01";
|
||||
when BYTE => SIZEVAR := "00";
|
||||
end case;
|
||||
--
|
||||
if BUS_CTRL_STATE = START_CYCLE and NEXT_BUS_CTRL_STATE = DATA_C1C4 then
|
||||
SSW <= To_StdLogicVector (RMC & '0' & OPCODE_REQ & RD_REQ & RMC) & SIZEVAR & RW_In & "00000" & FC_IN;
|
||||
end if;
|
||||
|
||||
OUTBUFFER <= WP_BUFFER; -- Used for exception stack frame type A and B.
|
||||
INBUFFER <= DATA_INMUX; -- Used for exception stack frame type B.
|
||||
end if;
|
||||
end process P_DF;
|
||||
|
||||
WRITEBACK_INFO: process
|
||||
-- This registers stor writeback relevant information.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUS_CTRL_STATE = IDLE and NEXT_BUS_CTRL_STATE = START_CYCLE then -- Freeze during a bus cycle.
|
||||
WP_BUFFER <= DATA_FROM_CORE;
|
||||
end if;
|
||||
end process WRITEBACK_INFO;
|
||||
|
||||
BUS_BSY <= '1' when BUS_CTRL_STATE /= IDLE else '0';
|
||||
|
||||
PARTITIONING: process
|
||||
-- This logic gives information about the remaining bus cycles The initial
|
||||
-- size is sampled right before the bus acces. This requires the RD_REQ
|
||||
-- and WR_REQ signals to work on the positive clock edge.
|
||||
variable RESTORE_VAR : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
|
||||
if BUS_CTRL_STATE = DATA_C1C4 and T_SLICE = S1 then -- On positive clock edge.
|
||||
RESTORE_VAR := SIZE_N; -- We need this initial value for early RETRY.
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
SIZE_N <= "000";
|
||||
elsif BUS_CTRL_STATE /= DATA_C1C4 and NEXT_BUS_CTRL_STATE = DATA_C1C4 then
|
||||
if RD_REQ = '1' or WR_REQ = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => SIZE_N <= "100";
|
||||
when WORD => SIZE_N <= "010";
|
||||
when BYTE => SIZE_N <= "001";
|
||||
end case;
|
||||
else -- OPCODE_ACCESS.
|
||||
SIZE_N <= "010"; -- WORD.
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Decrementing the size information:
|
||||
-- In this logic all permutations are considered. This allows a dynamically changing bus size.
|
||||
if RETRY = '1' then
|
||||
SIZE_N <= RESTORE_VAR;
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and T_SLICE = S3 and WAITSTATES = '0' then -- On positive clock edge.
|
||||
if ADR_OUT_I(1 downto 0) = "11" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif ADR_OUT_I(1 downto 0) = "01" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif SIZE_N = "001" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
else
|
||||
SIZE_N <= SIZE_N - "10";
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
if (BUS_FLT = '1' and HALT_In = '1') then -- Abort bus cycle.
|
||||
SIZE_N <= "000";
|
||||
end if;
|
||||
end process PARTITIONING;
|
||||
|
||||
SIZE_I <= SIZE_N(1 downto 0) when T_SLICE = S0 or T_SLICE = S1 else SIZE_D;
|
||||
|
||||
P_DELAY: process
|
||||
-- This delay is responsible for a correct SIZE_I information. Use this, if the
|
||||
-- process PARTITIONING works on the positive clock edge. The SIZE_I information
|
||||
-- is delayed by half a clock cycle to be valid just in time of sampling the INMUX.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
SIZE_D <= SIZE_N(1 downto 0);
|
||||
end process P_DELAY;
|
||||
|
||||
BUS_STATE_REG: process
|
||||
-- This is the bus controller's state register.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
BUS_CTRL_STATE <= NEXT_BUS_CTRL_STATE;
|
||||
end process BUS_STATE_REG;
|
||||
|
||||
BUS_CTRL_DEC: process(ADR_IN_P, ADR_OUT_I, AERR_I, ARB_STATE, BGACK_In, BR_In, BUS_CTRL_STATE, BUS_CYC_RDY,
|
||||
BUS_FLT, HALT_In, OPCODE_REQ, RD_REQ, RESET_CPU_I, RMC, SIZE_N, WR_REQ)
|
||||
-- This is the bus controller's state machine decoder. A SIZE_N count of "000" means that all bytes
|
||||
-- to be transfered. After a bus transfer a value of x"0" indicates that no further bytes are required
|
||||
-- for a bus transfer.
|
||||
begin
|
||||
case BUS_CTRL_STATE is
|
||||
when IDLE =>
|
||||
if RESET_CPU_I = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Reset condition (bus cycle terminated).
|
||||
elsif HALT_In = '0' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- This is the 'HALT' condition.
|
||||
elsif (BR_In = '0' and RMC = '0') or ARB_STATE /= IDLE or BGACK_In = '0' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Arbitration, wait!
|
||||
elsif RD_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- Read cycle.
|
||||
elsif WR_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- Write cycle.
|
||||
elsif OPCODE_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- Opcode cycle.
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
end if;
|
||||
when START_CYCLE =>
|
||||
if (RD_REQ = '1' or WR_REQ = '1') and AERR_I = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
elsif RD_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
elsif WR_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
elsif OPCODE_REQ = '1' and ADR_IN_P(0) = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Abort due to address error.
|
||||
elsif OPCODE_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
end if;
|
||||
when DATA_C1C4 =>
|
||||
if BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
end if;
|
||||
end case;
|
||||
end process BUS_CTRL_DEC;
|
||||
|
||||
P_ADR_OFFS: process
|
||||
-- This process provides a temporary address offset.
|
||||
variable OFFSET_VAR : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET_CPU_I = '1' then
|
||||
OFFSET_VAR := "000";
|
||||
elsif T_SLICE = S3 then
|
||||
case ADR_OUT_I(1 downto 0) is
|
||||
when "01" | "11" => OFFSET_VAR := "001";
|
||||
when others => OFFSET_VAR := "010";
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
ADR_OFFSET <= (others => '0');
|
||||
elsif RETRY = '1' then
|
||||
null; -- Do not update if there is a retry cycle.
|
||||
elsif BUS_CTRL_STATE /= IDLE and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
ADR_OFFSET <= (others => '0');
|
||||
elsif BUS_CYC_RDY = '1' then
|
||||
ADR_OFFSET <= ADR_OFFSET + OFFSET_VAR;
|
||||
end if;
|
||||
end process P_ADR_OFFS;
|
||||
|
||||
ADR_OUT_I <= ADR_IN_P + ADR_OFFSET;
|
||||
ADR_OUT_P <= ADR_OUT_I;
|
||||
|
||||
FC_OUT <= FC_IN;
|
||||
|
||||
-- Address and bus errors:
|
||||
AERR_I <= '1' when BUS_CTRL_STATE = START_CYCLE and OPCODE_REQ = '1' and RD_REQ = '0' and WR_REQ = '0' and ADR_IN_P(0) = '1' else
|
||||
'1' when BUS_CTRL_STATE = START_CYCLE and OP_SIZE = LONG and ADR_IN_P(0) = '1' else
|
||||
'1' when BUS_CTRL_STATE = START_CYCLE and OP_SIZE = WORD and ADR_IN_P(0) = '1' else '0';
|
||||
|
||||
|
||||
DATA_PORT_OUT <= WP_BUFFER(31 downto 16) when SIZE_I = "00" else
|
||||
WP_BUFFER(15 downto 0) when SIZE_I = "10" else
|
||||
WP_BUFFER(7 downto 0) & WP_BUFFER(7 downto 0);
|
||||
|
||||
IN_MUX: process
|
||||
-- This is the input multiplexer which can handle up to four bytes.
|
||||
begin
|
||||
wait until CLK = '0' and CLK' event;
|
||||
--
|
||||
if T_SLICE = S4 then
|
||||
case SIZE_I is
|
||||
when "00" =>
|
||||
DATA_INMUX(31 downto 16) <= DATA_PORT_IN;
|
||||
when "10" => -- Word.
|
||||
DATA_INMUX(15 downto 0) <= DATA_PORT_IN;
|
||||
when others => -- Byte.
|
||||
case ADR_OUT_I(0) is
|
||||
when '0' => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(15 downto 8);
|
||||
when others => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(7 downto 0);
|
||||
end case;
|
||||
end case;
|
||||
end if;
|
||||
end process IN_MUX;
|
||||
|
||||
VALIDATION: process
|
||||
-- These flip flops detect a fault during the read operation over one or
|
||||
-- several bytes or during the write operation.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
OPCODE_VALID <= '1';
|
||||
elsif OPCODE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_FLT = '1' then
|
||||
OPCODE_VALID <= '0';
|
||||
elsif OPCODE_RDY_I = '1' then
|
||||
OPCODE_VALID <= '1'; -- Reset after use, TRAP_BERR is asserted during DATA_RDY.
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
DATA_VALID <= '1';
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and BUS_FLT = '1' then
|
||||
DATA_VALID <= '0';
|
||||
elsif DATA_RDY_I = '1' then
|
||||
DATA_VALID <= '1'; -- Reset after use, TRAP_BERR is asserted during DATA_RDY.
|
||||
end if;
|
||||
end process VALIDATION;
|
||||
|
||||
PREFETCH_BUFFERS: process
|
||||
-- These are the data and the operation code input registers. After a last read to the registered
|
||||
-- input multiplexer, the respective data is copied from the input multiplexer to these buffers.
|
||||
-- The opcode buffer is always written with 32 bit data. The data buffers may contain invalid bytes
|
||||
-- in case of word or byte data size.
|
||||
variable DBUFFER_MEM : std_logic_vector(31 downto 8) := x"000000";
|
||||
variable RDY_VAR : bit := '0';
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
OPCODE_RDY_I <= '0'; -- This is a strobe.
|
||||
DATA_RDY_I <= '0'; -- This is a strobe.
|
||||
--
|
||||
-- The following variable is responsible, that the _RDY signals are
|
||||
-- always strobes.
|
||||
if DATA_RDY_I = '1' or OPCODE_RDY_I = '1' then
|
||||
RDY_VAR := '0';
|
||||
elsif BUS_CTRL_STATE = START_CYCLE then
|
||||
RDY_VAR := '1';
|
||||
end if;
|
||||
-- Opcode cycle:
|
||||
if AERR_I = '1' then
|
||||
OPCODE_RDY_I <= '1';
|
||||
elsif OPCODE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
-- Instruction prefetches are always long and on word boundaries.
|
||||
-- The word is available after the first word read.
|
||||
OBUFFER <= DATA_INMUX(15 downto 0);
|
||||
OPCODE_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
-- Data cycle:
|
||||
if AERR_I = '1' then
|
||||
DATA_RDY_I <= '1';
|
||||
elsif WRITE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
elsif READ_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG =>
|
||||
if SIZE_N = "000" then
|
||||
DBUFFER <= DATA_INMUX;
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
when WORD =>
|
||||
if SIZE_N = "000" then
|
||||
DBUFFER <= x"0000" & DATA_INMUX(15 downto 0);
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
when BYTE => -- Byte always aligned.
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
DBUFFER <= x"000000" & DATA_INMUX(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
end process PREFETCH_BUFFERS;
|
||||
|
||||
DATA_RDY <= DATA_RDY_I;
|
||||
OPCODE_RDY <= OPCODE_RDY_I;
|
||||
|
||||
DATA_TO_CORE <= DBUFFER;
|
||||
OPCODE_TO_CORE <= OBUFFER;
|
||||
|
||||
WAITSTATES <= '0' when T_SLICE /= S3 else
|
||||
'1' when RESET_OUT_I = '1' else -- No bus fault during RESET instruction.
|
||||
'0' when SYNCn = '0' else -- For synchronous bus cycles.
|
||||
'0' when DTACK_In = '0' else -- For asynchronous bus cycles.
|
||||
'0' when ADR_IN_P(19 downto 16) = x"F" and AVEC_In = '0' else -- Interrupt acknowledge space cycle.
|
||||
'0' when BUS_FLT = '1' else -- In case of a bus error;
|
||||
'0' when RESET_CPU_I = '1' else '1'; -- A CPU reset terminates the current bus cycle.
|
||||
|
||||
SLICES: process(CLK)
|
||||
-- This process provides the central timing for the read, write and read modify write cycle as also
|
||||
-- for the bus arbitration procedure. Be aware, that the bus controller state machine changes it's
|
||||
-- state on the positive clock edge. The BUS_CYC_RDY signal is asserted during S3 or S5. So the
|
||||
-- slice counter working on the positive clock edge may change it's state.
|
||||
begin
|
||||
if CLK = '1' and CLK' event then
|
||||
if BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Init.
|
||||
elsif RETRY = '1' then
|
||||
SLICE_CNT_P <= "111"; -- Stay in IDLE, go to IDLE.
|
||||
elsif BUS_CTRL_STATE /= IDLE and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Init.
|
||||
elsif SLICE_CNT_P = "010" then
|
||||
if RETRY = '1' then
|
||||
SLICE_CNT_P <= "111"; -- Go IDLE.
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Ready.
|
||||
else
|
||||
SLICE_CNT_P <= "000"; -- Go on.
|
||||
end if;
|
||||
elsif WAITSTATES = '0' then
|
||||
SLICE_CNT_P <= SLICE_CNT_P + '1'; -- Cycle active.
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
if CLK = '0' and CLK' event then
|
||||
SLICE_CNT_N <= SLICE_CNT_P; -- Follow the P counter.
|
||||
end if;
|
||||
end process SLICES;
|
||||
|
||||
T_SLICE <= S0 when SLICE_CNT_P = "000" and SLICE_CNT_N = "111" else
|
||||
S1 when SLICE_CNT_P = "000" and SLICE_CNT_N = "000" else
|
||||
S2 when SLICE_CNT_P = "001" and SLICE_CNT_N = "000" else
|
||||
S3 when SLICE_CNT_P = "001" and SLICE_CNT_N = "001" else
|
||||
S4 when SLICE_CNT_P = "010" and SLICE_CNT_N = "001" else
|
||||
S5 when SLICE_CNT_P = "010" and SLICE_CNT_N = "010" else
|
||||
S0 when SLICE_CNT_P = "000" and SLICE_CNT_N = "010" else IDLE; -- Rollover from state S5 to S0.
|
||||
|
||||
-- Bus control signals:
|
||||
RWn <= RW_In;
|
||||
RW_In <= '0' when WRITE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 else '1';
|
||||
RMCn <= '0' when RMC = '1' else '1';
|
||||
ASn <= '0' when T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1';
|
||||
|
||||
UDSn <= '1' when OPCODE_ACCESS = '0' and OP_SIZE = BYTE and ADR_OUT_I(0) = '1' else DSn;
|
||||
LDSn <= '1' when OPCODE_ACCESS = '0' and OP_SIZE = BYTE and ADR_OUT_I(0) = '0' else DSn;
|
||||
DSn <= '0' when (T_SLICE = S3 or T_SLICE = S4 or T_SLICE = S5) and WRITE_ACCESS = '1' else -- Write.
|
||||
'0' when T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1'; -- Read.
|
||||
|
||||
DBENn <= '0' when (T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 or T_SLICE = S5) and WRITE_ACCESS = '1' else -- Write.
|
||||
'0' when T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1'; -- Read.
|
||||
|
||||
-- Bus tri state controls:
|
||||
BUS_EN <= '1' when ARB_STATE = IDLE and RESET_CPU_I = '0' else '0';
|
||||
DATA_PORT_EN <= '1' when WRITE_ACCESS = '1' and ARB_STATE = IDLE and RESET_CPU_I = '0' else '0';
|
||||
|
||||
-- Progress controls:
|
||||
BUS_CYC_RDY <= '0' when RETRY = '1' else
|
||||
'1' when T_SLICE = S5 else '0'; -- Asynchronous cycles.
|
||||
|
||||
-- Bus arbitration:
|
||||
ARB_REG: process
|
||||
-- This is the arbiters state register.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
ARB_STATE <= IDLE;
|
||||
else
|
||||
ARB_STATE <= NEXT_ARB_STATE;
|
||||
end if;
|
||||
end process ARB_REG;
|
||||
|
||||
ARB_DEC: process(ARB_STATE, BGACK_In, BR_In, BUS_CTRL_STATE, RETRY, RMC)
|
||||
-- This is the bus arbitration state machine's decoder. It can handle single-, two-
|
||||
-- or three wire arbitration. The two wire arbitration is done in the GRANT state
|
||||
-- by negating BRn.
|
||||
begin
|
||||
case ARB_STATE is
|
||||
when IDLE =>
|
||||
if RMC = '1' and RETRY = '0' then
|
||||
NEXT_ARB_STATE <= IDLE; -- Arbitration in RETRY operation is possible.
|
||||
elsif BGACK_In = '0' and BUS_CTRL_STATE = IDLE then -- This is the single wire arbitration.
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
elsif BR_In = '0' and BUS_CTRL_STATE = IDLE then -- Wait until the bus is free.
|
||||
NEXT_ARB_STATE <= GRANT;
|
||||
else
|
||||
NEXT_ARB_STATE <= IDLE;
|
||||
end if;
|
||||
when GRANT =>
|
||||
if BGACK_In = '0' then
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
elsif BR_In = '1' then
|
||||
NEXT_ARB_STATE <= IDLE; -- Resume normal operation.
|
||||
else
|
||||
NEXT_ARB_STATE <= GRANT;
|
||||
end if;
|
||||
when WAIT_RELEASE_3WIRE =>
|
||||
if BGACK_In = '1' and BR_In = '0' then
|
||||
NEXT_ARB_STATE <= GRANT; -- Re-enter new arbitration.
|
||||
elsif BGACK_In = '1' then
|
||||
NEXT_ARB_STATE <= IDLE;
|
||||
else
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
end if;
|
||||
end case;
|
||||
end process ARB_DEC;
|
||||
|
||||
BGn <= '0' when ARB_STATE = GRANT else '1';
|
||||
|
||||
-- RESET logic:
|
||||
RESET_FILTER: process
|
||||
-- This process filters the incoming reset pin.
|
||||
-- If RESET_IN and HALT_In are asserted together for longer
|
||||
-- than 10 clock cycles over the execution of a CPU reset
|
||||
-- command, the CPU reset is released.
|
||||
variable STARTUP : boolean := false;
|
||||
variable TMP : std_logic_vector(3 downto 0) := x"0";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_IN = '1' and HALT_In = '0' and RESET_OUT_I = '0' and TMP < x"F" then
|
||||
TMP := TMP + '1';
|
||||
elsif RESET_IN = '0' or HALT_In = '1' or RESET_OUT_I = '1' then
|
||||
TMP := x"0";
|
||||
end if;
|
||||
if TMP > x"A" then
|
||||
RESET_CPU_I <= '1'; -- Release internal reset.
|
||||
STARTUP := true;
|
||||
elsif STARTUP = false then
|
||||
RESET_CPU_I <= '1';
|
||||
else
|
||||
RESET_CPU_I <= '0';
|
||||
end if;
|
||||
end process RESET_FILTER;
|
||||
|
||||
RESET_TIMER: process
|
||||
-- This logic is responsible for the assertion of the
|
||||
-- reset output for 124 clock cycles, during the reset
|
||||
-- command. The LOCK variable avoids re-initialisation
|
||||
-- of the counter in the case that the RESET_EN is no
|
||||
-- strobe.
|
||||
variable TMP : std_logic_vector(6 downto 0) := "0000000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_STRB = '1' or TMP > "0000000" then
|
||||
RESET_OUT_I <= '1';
|
||||
else
|
||||
RESET_OUT_I <= '0';
|
||||
end if;
|
||||
--
|
||||
if RESET_STRB = '1' then
|
||||
TMP := "1111011"; -- 124 initial value.
|
||||
elsif TMP > "0000000" then
|
||||
TMP := TMP - '1';
|
||||
end if;
|
||||
end process RESET_TIMER;
|
||||
|
||||
RESET_CPU <= RESET_CPU_I;
|
||||
RESET_OUT <= RESET_OUT_I;
|
||||
|
||||
VMA_EN <= '0' when ARB_STATE /= IDLE or RESET_CPU_I = '1' else '1';
|
||||
VMAn <= VMA_In;
|
||||
|
||||
-- Synchronous bus timing:
|
||||
E_TIMER: process
|
||||
-- The E clock is a free running clock with a period of 10 times
|
||||
-- the CLK period. The pulse ratio is 4 CLK high and 6 CLK low.
|
||||
-- Use a synchronous reset due to FPGA constraints.
|
||||
variable TMP : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET_CPU_I = '1' then
|
||||
TMP := x"0";
|
||||
VMA_In <= '1';
|
||||
SYNCn <= '1';
|
||||
E <= '1';
|
||||
elsif TMP < x"9" then
|
||||
TMP := TMP + '1';
|
||||
else
|
||||
TMP := x"0";
|
||||
end if;
|
||||
|
||||
-- E logic:
|
||||
if TMP = x"0" then
|
||||
E <= '1';
|
||||
elsif TMP = x"4" then
|
||||
E <= '0';
|
||||
end if;
|
||||
|
||||
-- VMA logic:
|
||||
if VPAn = '0' and TMP >= x"4" then -- Switch, when E is low.
|
||||
VMA_In <= '0';
|
||||
elsif VPAn = '1' then
|
||||
VMA_In <= '1';
|
||||
end if;
|
||||
|
||||
-- SYNCn logic (wait states controlling):
|
||||
if VPAn = '0' and VMA_In = '0' and TMP = x"2" then -- Adjust E to S6..
|
||||
SYNCn <= '0';
|
||||
elsif VPAn = '1' then
|
||||
SYNCn <= '1';
|
||||
end if;
|
||||
end process E_TIMER;
|
||||
end BEHAVIOR;
|
||||
2044
common/CPU/68K10/wf68k10_control.vhd
Normal file
2044
common/CPU/68K10/wf68k10_control.vhd
Normal file
File diff suppressed because it is too large
Load Diff
137
common/CPU/68K10/wf68k10_data_registers.vhd
Normal file
137
common/CPU/68K10/wf68k10_data_registers.vhd
Normal file
@@ -0,0 +1,137 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K10 IP Core: Data register logic. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- These are the eight data registers. The logic provides two ----
|
||||
---- read and two write ports providing simultaneos access. For ----
|
||||
---- more information refer to the MC68010 User' Manual. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K10_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K10_DATA_REGISTERS is
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
|
||||
-- Data lines:
|
||||
DR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
DR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
DR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
DR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
|
||||
-- Registers controls:
|
||||
DR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : in bit;
|
||||
DR_WR_2 : in bit;
|
||||
DR_MARK_USED : in bit;
|
||||
USE_DPAIR : in boolean;
|
||||
DR_IN_USE : out bit;
|
||||
UNMARK : in bit;
|
||||
|
||||
OP_SIZE : in OP_SIZETYPE
|
||||
);
|
||||
end entity WF68K10_DATA_REGISTERS;
|
||||
|
||||
architecture BEHAVIOUR of WF68K10_DATA_REGISTERS is
|
||||
type DR_TYPE is array(0 to 7) of std_logic_vector(31 downto 0);
|
||||
signal DR : DR_TYPE; -- Data registers D0 to D7.
|
||||
signal DR_PNTR_WR_1 : integer range 0 to 7;
|
||||
signal DR_PNTR_WR_2 : integer range 0 to 7;
|
||||
signal DR_PNTR_RD_1 : integer range 0 to 7;
|
||||
signal DR_PNTR_RD_2 : integer range 0 to 7;
|
||||
signal DR_SEL_WR_I1 : std_logic_vector(2 downto 0);
|
||||
signal DR_SEL_WR_I2 : std_logic_vector(2 downto 0);
|
||||
signal DR_USED_1 : std_logic_vector(3 downto 0);
|
||||
signal DR_USED_2 : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
INBUFFER: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if DR_MARK_USED = '1' then
|
||||
DR_SEL_WR_I1 <= DR_SEL_WR_1;
|
||||
DR_SEL_WR_I2 <= DR_SEL_WR_2;
|
||||
end if;
|
||||
end process INBUFFER;
|
||||
|
||||
DR_PNTR_WR_1 <= conv_integer(DR_SEL_WR_I1);
|
||||
DR_PNTR_WR_2 <= conv_integer(DR_SEL_WR_I2);
|
||||
DR_PNTR_RD_1 <= conv_integer(DR_SEL_RD_1);
|
||||
DR_PNTR_RD_2 <= conv_integer(DR_SEL_RD_2);
|
||||
|
||||
P_IN_USE: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' or UNMARK = '1' then
|
||||
DR_USED_1(3) <= '0';
|
||||
DR_USED_2(3) <= '0';
|
||||
elsif DR_MARK_USED = '1' then
|
||||
DR_USED_1 <= '1' & DR_SEL_WR_1;
|
||||
if USE_DPAIR = true then
|
||||
DR_USED_2 <= '1' & DR_SEL_WR_2;
|
||||
end if;
|
||||
end if;
|
||||
end process P_IN_USE;
|
||||
|
||||
DR_IN_USE <= '1' when DR_USED_1(3) = '1' and DR_USED_1(2 downto 0) = DR_SEL_RD_1 else
|
||||
'1' when DR_USED_1(3) = '1' and DR_USED_1(2 downto 0) = DR_SEL_RD_2 else
|
||||
'1' when DR_USED_2(3) = '1' and DR_USED_2(2 downto 0) = DR_SEL_RD_1 else
|
||||
'1' when DR_USED_2(3) = '1' and DR_USED_2(2 downto 0) = DR_SEL_RD_2 else '0';
|
||||
|
||||
DR_OUT_1 <= DR(DR_PNTR_RD_1);
|
||||
DR_OUT_2 <= DR(DR_PNTR_RD_2);
|
||||
|
||||
REGISTERS: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
DR <= (others => (others => '0'));
|
||||
end if;
|
||||
if DR_WR_1 = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => DR(DR_PNTR_WR_1) <= DR_IN_1;
|
||||
when WORD => DR(DR_PNTR_WR_1)(15 downto 0) <= DR_IN_1(15 downto 0);
|
||||
when Byte => DR(DR_PNTR_WR_1)(7 downto 0) <= DR_IN_1(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
if DR_WR_2 = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => DR(DR_PNTR_WR_2) <= DR_IN_2;
|
||||
when WORD => DR(DR_PNTR_WR_2)(15 downto 0) <= DR_IN_2(15 downto 0);
|
||||
when Byte => DR(DR_PNTR_WR_2)(7 downto 0) <= DR_IN_2(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
end process REGISTERS;
|
||||
end BEHAVIOUR;
|
||||
818
common/CPU/68K10/wf68k10_exception_handler.vhd
Normal file
818
common/CPU/68K10/wf68k10_exception_handler.vhd
Normal file
@@ -0,0 +1,818 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K10 IP Core: this is the exception handler module. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This is the exception handler which is responsible for the ----
|
||||
---- interrupt management of the external interrupt and internal ----
|
||||
---- exception processing. It manages auto-vectored interrupt ----
|
||||
---- cycles, priority resolving and correct vector numbers. ----
|
||||
---- For further information concerning the functionality of this ----
|
||||
---- module refer to the MC68010 User's Manual and to the MC68K ----
|
||||
---- family Programmer's Reference Manual. ----
|
||||
---- ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K16A 20141201 WF
|
||||
-- Fixed a bug in PC_LOAD.
|
||||
-- Revision 2K18A (unreleased) WF
|
||||
-- Removed REST_BIW_0.
|
||||
-- Removed FC_OUT.
|
||||
-- Removed ADR_CPY.
|
||||
-- Removed PC_OFFSET.
|
||||
-- Fixed the vector calculation of INT vectors.
|
||||
-- Fixed faulty modeling in IRQ_FILTER.
|
||||
-- Implemented the AVEC_FILTER to better meet bus timings.
|
||||
-- STACK_POS_VAR is initialized earlier to be valid for early asserted ISP_DEC.
|
||||
-- Update the IRQ mask only for RESET and interrupts.
|
||||
-- External interrupts are postponed if any system controllers are in initialize operation status.
|
||||
-- RTE now loads the address offset correctly when entering the handler.
|
||||
-- Rearranged address error handling.
|
||||
-- Revision 2K19B 20191224 WF
|
||||
-- Introduced signal synchronization in the P_D process to avoid malfunction by hazards.
|
||||
-- The processor VERSION is now 32 bit wide.
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K10_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K10_EXCEPTION_HANDLER is
|
||||
generic(VERSION : std_logic_vector(31 downto 0) := x"20191224");
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
K6800n : in std_logic;
|
||||
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : in bit;
|
||||
|
||||
EXH_REQ : out bit;
|
||||
BUSY_EXH : out bit;
|
||||
|
||||
ADR_IN : in std_logic_vector(31 downto 0);
|
||||
ADR_OFFSET : out std_logic_vector(31 downto 0);
|
||||
CPU_SPACE : out bit;
|
||||
|
||||
DATA_0 : in std_logic;
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_IN : in std_logic_vector(31 downto 0);
|
||||
|
||||
OP_SIZE : out OP_SIZETYPE; -- Operand size.
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
|
||||
OPCODE_RDY : in bit; -- OPCODE is available.
|
||||
|
||||
STATUS_REG_IN : in std_logic_vector(15 downto 0);
|
||||
SR_CPY : out std_logic_vector(15 downto 0);
|
||||
SR_INIT : out bit;
|
||||
SR_WR : out bit;
|
||||
|
||||
ISP_DEC : out bit;
|
||||
ISP_LOAD : out bit;
|
||||
PC_INC : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_RESTORE : out bit;
|
||||
|
||||
STACK_FORMAT : out std_logic_vector(3 downto 0);
|
||||
STACK_POS : out integer range 0 to 31;
|
||||
|
||||
SP_ADD_DISPL : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(7 downto 0);
|
||||
|
||||
IPIPE_FILL : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
RESTORE_ISP_PC : out bit;
|
||||
|
||||
HALT_OUTn : out std_logic;
|
||||
|
||||
-- Interrupt controls:
|
||||
INT_TRIG : in bit;
|
||||
IRQ_IN : in std_logic_vector(2 downto 0);
|
||||
IRQ_PEND : out std_logic_vector(2 downto 0);
|
||||
AVECn : in std_logic;
|
||||
IPENDn : out bit;
|
||||
IVECT_OFFS : out std_logic_vector(9 downto 0); -- Interrupt vector offset.
|
||||
|
||||
-- Trap signals:
|
||||
TRAP_AERR : in bit;
|
||||
TRAP_BERR : in bit;
|
||||
TRAP_CHK : in bit;
|
||||
TRAP_DIVZERO : in bit;
|
||||
TRAP_ILLEGAL : in bit;
|
||||
TRAP_CODE_OPC : in TRAPTYPE_OPC; -- T_1010, T_1111, T_ILLEGAL, T_TRAP, T_PRIV.
|
||||
TRAP_VECTOR : in std_logic_vector(3 downto 0);
|
||||
TRAP_V : in bit;
|
||||
EX_TRACE_IN : in bit;
|
||||
VBR_WR : in bit;
|
||||
VBR : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity WF68K10_EXCEPTION_HANDLER;
|
||||
|
||||
architecture BEHAVIOR of WF68K10_EXCEPTION_HANDLER is
|
||||
type EX_STATES is (IDLE, BUILD_STACK, CALC_VECT_No, EXAMINE_VERSION, GET_VECTOR, HALTED, INIT, READ_BOTTOM,
|
||||
REFILL_PIPE, RESTORE_ISP, RESTORE_PC, RESTORE_STATUS, UPDATE_PC, VALIDATE_FRAME);
|
||||
|
||||
type EXCEPTIONS is (EX_NONE, EX_1010, EX_1111, EX_AERR, EX_BERR, EX_CHK, EX_DIVZERO, EX_FORMAT, EX_ILLEGAL,
|
||||
EX_INT, EX_PRIV, EX_RESET, EX_RTE, EX_TRACE, EX_TRAP, EX_TRAPV);
|
||||
|
||||
signal ACCESS_ERR : bit;
|
||||
signal AVEC : bit;
|
||||
signal DATA_RD_I : bit;
|
||||
signal DATA_WR_I : bit;
|
||||
signal DOUBLE_BUSFLT : bit;
|
||||
signal EXCEPTION : EXCEPTIONS; -- Currently executed exception.
|
||||
signal EX_STATE : EX_STATES := IDLE;
|
||||
signal NEXT_EX_STATE : EX_STATES;
|
||||
signal EX_P_1010 : bit; -- ..._P are the pending exceptions.
|
||||
signal EX_P_1111 : bit;
|
||||
signal EX_P_AERR : bit;
|
||||
signal EX_P_BERR : bit;
|
||||
signal EX_P_CHK : bit;
|
||||
signal EX_P_DIVZERO : bit;
|
||||
signal EX_P_FORMAT : bit;
|
||||
signal EX_P_ILLEGAL : bit;
|
||||
signal EX_P_INT : bit;
|
||||
signal EX_P_RESET : bit;
|
||||
signal EX_P_RTE : bit;
|
||||
signal EX_P_PRIV : bit;
|
||||
signal EX_P_TRACE : bit;
|
||||
signal EX_P_TRAP : bit;
|
||||
signal EX_P_TRAPV : bit;
|
||||
signal INT_VECT : std_logic_vector(31 downto 0); -- Interrupt vector.
|
||||
signal IRQ : std_logic_vector(2 downto 0);
|
||||
signal IRQ_PEND_I : std_logic_vector(2 downto 0);
|
||||
signal PIPE_CNT : std_logic_vector(1 downto 0);
|
||||
signal PIPE_FULL : boolean;
|
||||
signal STACK_CNT : integer range 0 to 46;
|
||||
signal STACK_FORMAT_I : std_logic_vector(3 downto 0);
|
||||
signal SYS_INIT : bit;
|
||||
begin
|
||||
|
||||
BUSY_EXH <= '1' when EX_STATE /= IDLE else '0';
|
||||
|
||||
IRQ_FILTER : process
|
||||
-- This logic is intended to avoid spurious IRQs due
|
||||
-- to setup / hold violations (IRQ_IN may operate in
|
||||
-- a different clock domain).
|
||||
variable IRQ_TMP_1 : std_logic_vector(2 downto 0) := "000";
|
||||
variable IRQ_TMP_2 : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '0' and CLK' event;
|
||||
if IRQ_TMP_1 = IRQ_TMP_2 then
|
||||
IRQ <= IRQ_TMP_2;
|
||||
end if;
|
||||
IRQ_TMP_2 := IRQ_TMP_1;
|
||||
IRQ_TMP_1 := IRQ_IN;
|
||||
end process IRQ_FILTER;
|
||||
|
||||
AVEC_FILTER : process
|
||||
-- We need a flip flop for the incoming AVECn to meet
|
||||
-- the timing requirements of the bus interface. AVECn
|
||||
-- is asserted (low active) before DATA_RDY of the
|
||||
-- bus interface. AVEC stays asserted until DATA_RDY.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if AVECn = '0' then
|
||||
AVEC <= '1';
|
||||
elsif DATA_RDY = '1' or RESET = '1' then
|
||||
AVEC <= '0';
|
||||
end if;
|
||||
end process AVEC_FILTER;
|
||||
|
||||
PENDING: process
|
||||
-- The exceptions which occurs are stored in this pending register until the
|
||||
-- interrupt handler handled the respective exception.
|
||||
-- The TRAP_PRIV, TRAP_1010, TRAP_1111, TRAP_ILLEGAL, TRAP_OP and TRAP_V may be a strobe
|
||||
-- of 1 clock period. All others must be strobes of 1 clock period..
|
||||
variable INT7_TRIG : boolean;
|
||||
variable INT_VAR : std_logic_vector(2 downto 0);
|
||||
variable SR_VAR : std_logic_vector(2 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
EX_P_RESET <= '1';
|
||||
elsif EX_STATE = RESTORE_PC and DATA_RDY = '1' and EXCEPTION = EX_RESET then
|
||||
EX_P_RESET <= '0';
|
||||
end if;
|
||||
--
|
||||
if TRAP_BERR = '1' then
|
||||
EX_P_BERR <= '1';
|
||||
elsif EX_STATE /= IDLE and DATA_RDY = '1' and DATA_VALID = '0' then
|
||||
EX_P_BERR <= '1';
|
||||
elsif EX_STATE = INIT and EXCEPTION = EX_BERR then
|
||||
EX_P_BERR <= '0'; -- Reset in the beginning to enable retriggering.
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_BERR <= '0';
|
||||
end if;
|
||||
--
|
||||
if TRAP_AERR = '1' then
|
||||
EX_P_AERR <= '1';
|
||||
elsif EX_STATE = BUILD_STACK and EXCEPTION = EX_AERR then
|
||||
EX_P_AERR <= '0';
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_AERR <= '0';
|
||||
end if;
|
||||
--
|
||||
if EX_TRACE_IN = '1' then
|
||||
EX_P_TRACE <= '1';
|
||||
elsif EX_STATE = BUILD_STACK and EXCEPTION = EX_TRACE then
|
||||
EX_P_TRACE <= '0';
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_TRACE <= '0';
|
||||
end if;
|
||||
--
|
||||
if IRQ = "111" and SR_VAR = "111" and STATUS_REG_IN(10 downto 8) /= "111" then
|
||||
INT7_TRIG := true; -- Trigger by lowering the mask from 7 to any value.
|
||||
elsif IRQ = "111" and INT_VAR < "111" then
|
||||
INT7_TRIG := true; -- Trigger when level 7 is entered.
|
||||
else
|
||||
INT7_TRIG := false;
|
||||
end if;
|
||||
--
|
||||
SR_VAR := STATUS_REG_IN(10 downto 8); -- Update after use!
|
||||
INT_VAR := IRQ; -- Update after use!
|
||||
--
|
||||
if SYS_INIT = '1' then -- Reset when disabling the interrupts.
|
||||
EX_P_INT <= '0';
|
||||
IRQ_PEND_I <= "111"; -- This is required for system startup.
|
||||
elsif EX_STATE = GET_VECTOR and DATA_RDY = '1' then
|
||||
EX_P_INT <= '0';
|
||||
elsif INT7_TRIG = true then -- Level 7 is nonmaskable ...
|
||||
EX_P_INT <= '1';
|
||||
IRQ_PEND_I <= IRQ;
|
||||
elsif INT_TRIG = '1' and STATUS_REG_IN(10 downto 8) < IRQ then
|
||||
EX_P_INT <= '1';
|
||||
IRQ_PEND_I <= IRQ;
|
||||
end if;
|
||||
--
|
||||
-- The following nine traps never appear at the same time:
|
||||
if TRAP_CHK = '1' then
|
||||
EX_P_CHK <= '1';
|
||||
elsif TRAP_DIVZERO = '1' then
|
||||
EX_P_DIVZERO <= '1';
|
||||
elsif TRAP_CODE_OPC = T_TRAP then
|
||||
EX_P_TRAP <= '1';
|
||||
elsif TRAP_V = '1' then
|
||||
EX_P_TRAPV <= '1';
|
||||
elsif TRAP_CODE_OPC = T_PRIV then
|
||||
EX_P_PRIV <= '1';
|
||||
elsif TRAP_CODE_OPC = T_1010 then
|
||||
EX_P_1010 <= '1';
|
||||
elsif TRAP_CODE_OPC = T_1111 then
|
||||
EX_P_1111 <= '1';
|
||||
elsif TRAP_CODE_OPC = T_ILLEGAL then
|
||||
EX_P_ILLEGAL <= '1';
|
||||
elsif TRAP_ILLEGAL = '1' then -- Used for BKPT.
|
||||
EX_P_ILLEGAL <= '1';
|
||||
elsif EX_STATE = VALIDATE_FRAME and DATA_RDY = '1' and DATA_VALID = '1' and NEXT_EX_STATE = IDLE then
|
||||
EX_P_FORMAT <= '1';
|
||||
elsif EX_STATE = EXAMINE_VERSION and DATA_RDY = '1' and DATA_VALID = '1' and NEXT_EX_STATE = IDLE then
|
||||
EX_P_FORMAT <= '1';
|
||||
elsif TRAP_CODE_OPC = T_RTE then
|
||||
EX_P_RTE <= '1';
|
||||
elsif EX_STATE = REFILL_PIPE and NEXT_EX_STATE /= REFILL_PIPE then -- Clear after IPIPE_FLUSH.
|
||||
case EXCEPTION is
|
||||
when EX_1010 | EX_1111 | EX_CHK | EX_DIVZERO | EX_ILLEGAL | EX_TRAP | EX_TRAPV | EX_FORMAT | EX_PRIV | EX_RTE =>
|
||||
EX_P_CHK <= '0';
|
||||
EX_P_DIVZERO <= '0';
|
||||
EX_P_PRIV <= '0';
|
||||
EX_P_1010 <= '0';
|
||||
EX_P_1111 <= '0';
|
||||
EX_P_ILLEGAL <= '0';
|
||||
EX_P_RTE <= '0';
|
||||
EX_P_TRAP <= '0';
|
||||
EX_P_TRAPV <= '0';
|
||||
EX_P_FORMAT <= '0';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
-- Clear all possible traps during reset exception because the
|
||||
-- signal EXCEPTION is not valid at this time:
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_CHK <= '0';
|
||||
EX_P_DIVZERO <= '0';
|
||||
EX_P_PRIV <= '0';
|
||||
EX_P_1010 <= '0';
|
||||
EX_P_1111 <= '0';
|
||||
EX_P_ILLEGAL <= '0';
|
||||
EX_P_RTE <= '0';
|
||||
EX_P_TRAP <= '0';
|
||||
EX_P_TRAPV <= '0';
|
||||
EX_P_FORMAT <= '0';
|
||||
end if;
|
||||
end process PENDING;
|
||||
|
||||
ACCESS_ERR <= '1' when EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_0 = '1' else -- Odd PC value.
|
||||
'1' when DATA_RDY = '1' and DATA_VALID = '0' else '0'; -- Bus error.
|
||||
|
||||
IRQ_PEND <= IRQ_PEND_I when EXCEPTION = EX_RESET or EXCEPTION = EX_INT else STATUS_REG_IN(10 downto 8);
|
||||
IPENDn <= '0' when EX_P_INT = '1' or EX_P_RESET = '1' or EX_P_TRACE = '1' else '1';
|
||||
|
||||
-- This signal is asserted eraly to indicate the respective controller to stay in its idle state.
|
||||
-- The exception is then inserted before a new operation has been loaded and processed.
|
||||
EXH_REQ <= '0' when EX_STATE /= IDLE else
|
||||
'1' when TRAP_CODE_OPC /= NONE else
|
||||
'1' when (EX_P_RESET or EX_P_BERR or EX_P_AERR or EX_P_DIVZERO) = '1' else
|
||||
'1' when (EX_P_CHK or EX_P_TRAPV or EX_P_TRACE or EX_P_FORMAT or EX_P_INT) = '1' else '0';
|
||||
|
||||
INT_VECTOR: process
|
||||
-- This process provides the vector base register handling and
|
||||
-- the interrupt vector number INT_VECT, which is determined
|
||||
-- during interrupt processing.
|
||||
variable VECT_No : std_logic_vector(9 downto 2) := "00000000";
|
||||
variable VB_REG : std_logic_vector(31 downto 0) := x"00000000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if VBR_WR = '1' then
|
||||
VB_REG := DATA_IN;
|
||||
elsif SYS_INIT = '1' then
|
||||
VB_REG := (others => '0');
|
||||
end if;
|
||||
--
|
||||
if EX_STATE = CALC_VECT_No or EX_STATE = GET_VECTOR then
|
||||
case EXCEPTION is
|
||||
when EX_RESET => VECT_No := x"00";
|
||||
when EX_BERR => VECT_No := x"02";
|
||||
when EX_AERR => VECT_No := x"03";
|
||||
when EX_ILLEGAL => VECT_No := x"04";
|
||||
when EX_DIVZERO => VECT_No := x"05";
|
||||
when EX_CHK => VECT_No := x"06";
|
||||
when EX_TRAPV => VECT_No := x"07";
|
||||
when EX_PRIV => VECT_No := x"08";
|
||||
when EX_TRACE => VECT_No := x"09";
|
||||
when EX_1010 => VECT_No := x"0A";
|
||||
when EX_1111 => VECT_No := x"0B";
|
||||
when EX_FORMAT => VECT_No := x"0E";
|
||||
-- The uninitialized interrupt vector number x"0F"
|
||||
-- is provided by the peripheral interrupt source
|
||||
-- during the auto vector bus cycle.
|
||||
when EX_INT =>
|
||||
if DATA_RDY = '1' and AVEC = '1' then
|
||||
VECT_No := x"18" + IRQ_PEND_I; -- Autovector.
|
||||
elsif DATA_RDY = '1' and DATA_VALID = '0' then
|
||||
VECT_No := x"18"; -- Spurious interrupt.
|
||||
elsif DATA_RDY = '1' then
|
||||
-- This is the vector number provided by the device.
|
||||
-- If the returned VECT_No is x"0F" then it is the
|
||||
-- uninitialized interrupt vector due to non initia-
|
||||
-- lized vector register of the peripheral device.
|
||||
VECT_No := DATA_IN(7 downto 0); -- Non autovector.
|
||||
end if;
|
||||
when EX_TRAP => VECT_No := x"2" & TRAP_VECTOR;
|
||||
when others => VECT_No := (others => '-'); -- Don't care.
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
INT_VECT <= VB_REG + (VECT_No & "00");
|
||||
VBR <= VB_REG;
|
||||
IVECT_OFFS <= VECT_No & "00";
|
||||
end process INT_VECTOR;
|
||||
|
||||
STORE_CURRENT_EXCEPTION: process
|
||||
-- The exceptions which occurs are stored in the following flags until the
|
||||
-- interrupt handler handled the respective exception.
|
||||
-- This process also stores the current processed exception for further use.
|
||||
-- The update takes place in the IDLE EX_STATE.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
-- Priority level 0:
|
||||
if EX_STATE = IDLE and EX_P_RESET = '1' then
|
||||
EXCEPTION <= EX_RESET;
|
||||
-- Priority level 1:
|
||||
elsif EX_STATE = IDLE and EX_P_AERR = '1' then
|
||||
EXCEPTION <= EX_AERR;
|
||||
elsif EX_STATE = IDLE and EX_P_BERR = '1' then
|
||||
EXCEPTION <= EX_BERR;
|
||||
-- Priority level 2:
|
||||
-- BREAKPOINT is part of the main controller.
|
||||
elsif EX_STATE = IDLE and EX_P_CHK = '1' then
|
||||
EXCEPTION <= EX_CHK;
|
||||
elsif EX_STATE = IDLE and EX_P_DIVZERO = '1' then
|
||||
EXCEPTION <= EX_DIVZERO;
|
||||
elsif EX_STATE = IDLE and EX_P_TRAP = '1' then
|
||||
EXCEPTION <= EX_TRAP;
|
||||
elsif EX_STATE = IDLE and EX_P_TRAPV = '1' then
|
||||
EXCEPTION <= EX_TRAPV;
|
||||
elsif EX_STATE = IDLE and EX_P_FORMAT = '1' then
|
||||
EXCEPTION <= EX_FORMAT;
|
||||
-- Priority level 3:
|
||||
elsif EX_STATE = IDLE and EX_P_ILLEGAL = '1' then
|
||||
EXCEPTION <= EX_ILLEGAL;
|
||||
elsif EX_STATE = IDLE and EX_P_RTE = '1' then
|
||||
EXCEPTION <= EX_RTE;
|
||||
elsif EX_STATE = IDLE and EX_P_1010 = '1' then
|
||||
EXCEPTION <= EX_1010;
|
||||
elsif EX_STATE = IDLE and EX_P_1111 = '1' then
|
||||
EXCEPTION <= EX_1111;
|
||||
elsif EX_STATE = IDLE and EX_P_PRIV = '1' then
|
||||
EXCEPTION <= EX_PRIV;
|
||||
elsif EX_STATE = IDLE and EX_P_TRACE = '1' then
|
||||
EXCEPTION <= EX_TRACE;
|
||||
elsif EX_STATE = IDLE and EX_P_INT = '1' then
|
||||
EXCEPTION <= EX_INT;
|
||||
elsif NEXT_EX_STATE = IDLE then
|
||||
EXCEPTION <= EX_NONE;
|
||||
end if;
|
||||
end process STORE_CURRENT_EXCEPTION;
|
||||
|
||||
CPU_SPACE <= '1' when NEXT_EX_STATE = GET_VECTOR else '0';
|
||||
|
||||
ADR_OFFSET <= x"000000" & "00000" & PIPE_CNT & '0' when EX_STATE = REFILL_PIPE else
|
||||
x"00000004" when NEXT_EX_STATE = RESTORE_PC and EXCEPTION = EX_RESET else
|
||||
x"00000002" when NEXT_EX_STATE = RESTORE_PC else
|
||||
x"00000006" when NEXT_EX_STATE = VALIDATE_FRAME else
|
||||
x"0000001A" when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
x"0000001E" when NEXT_EX_STATE = READ_BOTTOM else
|
||||
INT_VECT when NEXT_EX_STATE = UPDATE_PC else x"00000000"; -- Default is top of the stack (STATUS).
|
||||
|
||||
OP_SIZE <= LONG when K6800n = '1' and EX_STATE = INIT and EXCEPTION /= EX_AERR and EXCEPTION /= EX_BERR else -- First access of AERR or BERR is WORD.
|
||||
LONG when NEXT_EX_STATE = RESTORE_ISP or NEXT_EX_STATE = RESTORE_PC else
|
||||
LONG when NEXT_EX_STATE = UPDATE_PC else
|
||||
LONG when K6800n = '0' and NEXT_EX_STATE = BUILD_STACK and (STACK_CNT = 7 or STACK_CNT = 3) and DATA_RDY = '1' else -- Words 7 and 3 are word wide.
|
||||
LONG when K6800n = '0' and NEXT_EX_STATE = BUILD_STACK and STACK_CNT /= 7 and STACK_CNT /= 3 else
|
||||
LONG when K6800n = '1' and NEXT_EX_STATE = BUILD_STACK and STACK_CNT = 29 and DATA_RDY = '1' else -- Always long access, except word 29.
|
||||
LONG when K6800n = '1' and NEXT_EX_STATE = BUILD_STACK and STACK_CNT /= 29 else
|
||||
LONG when EX_STATE = UPDATE_PC or NEXT_EX_STATE = RESTORE_PC else
|
||||
LONG when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
BYTE when EX_STATE = GET_VECTOR and NEXT_EX_STATE = GET_VECTOR else WORD;
|
||||
|
||||
DISPLACEMENT <= x"08" when STACK_FORMAT_I = x"0" and K6800n = '1' else -- 68K10.
|
||||
x"3A" when STACK_FORMAT_I = x"8" and K6800n = '1' else -- 68K10.
|
||||
x"06" when STACK_FORMAT_I = x"0" else x"0E"; -- 68K00.
|
||||
|
||||
SP_ADD_DISPL <= '1' when EX_STATE = RESTORE_STATUS and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
|
||||
P_D: process(CLK, DATA_RDY)
|
||||
-- These flip flops are necessary to delay
|
||||
-- the read and writes during BUILD_STACK
|
||||
-- and restoring the system because the
|
||||
-- address calculation in the address
|
||||
-- section requires one clock.
|
||||
-- Important note: to avoid asynchronous reset by data hazards the
|
||||
-- resetting signal is synchronized on the negative clock edge.
|
||||
variable DATA_RDY_VAR : bit;
|
||||
begin
|
||||
if CLK = '0' and CLK' event then
|
||||
DATA_RDY_VAR := DATA_RDY;
|
||||
end if;
|
||||
--
|
||||
if DATA_RDY_VAR = '1' then
|
||||
DATA_RD <= '0';
|
||||
elsif CLK = '1' and CLK' event then
|
||||
DATA_RD <= DATA_RD_I;
|
||||
end if;
|
||||
|
||||
if DATA_RDY_VAR = '1' then
|
||||
DATA_WR <= '0';
|
||||
elsif CLK = '1' and CLK' event then
|
||||
DATA_WR <= DATA_WR_I;
|
||||
end if;
|
||||
end process P_D;
|
||||
|
||||
DATA_RD_I <= '0' when DATA_RDY = '1' else
|
||||
'1' when NEXT_EX_STATE = GET_VECTOR else
|
||||
'1' when NEXT_EX_STATE = VALIDATE_FRAME else
|
||||
'1' when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
'1' when NEXT_EX_STATE = READ_BOTTOM else
|
||||
'1' when NEXT_EX_STATE = RESTORE_ISP else
|
||||
'1' when NEXT_EX_STATE = RESTORE_STATUS else
|
||||
'1' when NEXT_EX_STATE = UPDATE_PC else
|
||||
'1' when NEXT_EX_STATE = RESTORE_PC else '0';
|
||||
|
||||
DATA_WR_I <= '0' when DATA_RDY = '1' else
|
||||
'1' when EX_STATE = BUILD_STACK else '0';
|
||||
|
||||
ISP_LOAD <= '1' when EX_STATE = RESTORE_ISP and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
PC_RESTORE <= '1' when EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
PC_LOAD <= '1' when EXCEPTION /= EX_RESET and EXCEPTION /= EX_RTE and EX_STATE /= REFILL_PIPE and NEXT_EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
IPIPE_FILL <= '1' when EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
-- This signal forces the PC logic in the address register section to calculate the address
|
||||
-- of the next instruction. This address is written on the stack. For the following
|
||||
-- instructions the old PC value is stacked: BERR, AERR, ILLEGAL, PRIV, TRACE, 1010, 1111, FORMAT.
|
||||
PC_INC <= '1' when EXCEPTION = EX_CHK and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_DIVZERO and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_INT and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_TRAP and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_TRAPV and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else '0';
|
||||
|
||||
ISP_DEC <= '1' when EX_STATE = INIT and EXCEPTION /= EX_RESET and EXCEPTION /= EX_RTE else -- Early due to one clock cycle address calculation.
|
||||
'1' when EX_STATE = BUILD_STACK and DATA_RDY = '1' and NEXT_EX_STATE = BUILD_STACK else '0';
|
||||
|
||||
SR_INIT <= '1' when EX_STATE = INIT else '0';
|
||||
SR_WR <= '1' when EX_STATE = RESTORE_STATUS and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
|
||||
SYS_INIT <= '1' when EX_STATE = IDLE and EX_P_RESET = '1' else '0';
|
||||
|
||||
-- The processor gets halted, if a bus error occurs in the stacking or updating states during
|
||||
-- the exception processing of a bus error, an address error or a reset.
|
||||
HALT_OUTn <= '0' when EX_STATE = HALTED else '1';
|
||||
|
||||
RESTORE_ISP_PC <= '1' when EXCEPTION = EX_RESET and (NEXT_EX_STATE = RESTORE_ISP or EX_STATE = RESTORE_ISP) else
|
||||
'1' when EXCEPTION = EX_RESET and (NEXT_EX_STATE = RESTORE_PC or EX_STATE = RESTORE_PC) else
|
||||
'1' when NEXT_EX_STATE = UPDATE_PC else '0';
|
||||
|
||||
IPIPE_FLUSH <= '1' when EXCEPTION = EX_RESET and EX_STATE /= REFILL_PIPE else
|
||||
'1' when EXCEPTION /= EX_NONE and EX_STATE /= REFILL_PIPE and NEXT_EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
DOUBLE_BUSFLT <= '1' when (EXCEPTION = EX_AERR or EXCEPTION = EX_RESET) and EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_0 = '1' else -- Odd PC value.
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_AERR and DATA_RDY = '1' and DATA_VALID = '0' else
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_BERR and DATA_RDY = '1' and DATA_VALID = '0' else
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_RESET and DATA_RDY = '1' and DATA_VALID = '0' else '0';
|
||||
|
||||
P_TMP_CPY: process
|
||||
-- These registers contain a copy of system relevant state information
|
||||
-- which is necessary for restoring the exception. Copies are provided
|
||||
-- for the status register, the program counter and the effective address.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE = IDLE and NEXT_EX_STATE /= IDLE then
|
||||
SR_CPY <= STATUS_REG_IN;
|
||||
end if;
|
||||
end process P_TMP_CPY;
|
||||
|
||||
STACK_CTRL: process
|
||||
-- This process controls the stacking of the data to the stack. Depending
|
||||
-- on the stack frame format, the number of words written to the stack is
|
||||
-- adjusted to long words. See the DATA_2_PORT multiplexer in the top level
|
||||
-- file for more information.
|
||||
variable STACK_POS_VAR : integer range 0 to 31 := 0;
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK then
|
||||
case EXCEPTION is
|
||||
when EX_AERR | EX_BERR =>
|
||||
if K6800n = '0' then
|
||||
STACK_POS_VAR := 7; -- 68K00 bus or address error stack format.
|
||||
else
|
||||
STACK_POS_VAR := 29; -- Format 8.
|
||||
end if;
|
||||
STACK_FORMAT_I <= x"8";
|
||||
when others =>
|
||||
if K6800n = '0' then
|
||||
STACK_POS_VAR := 3; -- 68K00 3 word stack format.
|
||||
else
|
||||
STACK_POS_VAR := 4; -- Format 0.
|
||||
end if;
|
||||
STACK_FORMAT_I <= x"0";
|
||||
end case;
|
||||
elsif EX_STATE = VALIDATE_FRAME and DATA_RDY = '1' and DATA_VALID = '1' then
|
||||
STACK_FORMAT_I <= DATA_IN(15 downto 12);
|
||||
elsif EX_STATE = BUILD_STACK and DATA_RDY = '1' then
|
||||
case STACK_POS_VAR is
|
||||
when 29 | 7 | 3 => STACK_POS_VAR := STACK_POS_VAR - 1; -- WORD access.
|
||||
when others => STACK_POS_VAR := STACK_POS_VAR - 2; -- LONG access.
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
STACK_CNT <= STACK_POS_VAR;
|
||||
STACK_POS <= STACK_POS_VAR;
|
||||
end process STACK_CTRL;
|
||||
|
||||
STACK_FORMAT <= STACK_FORMAT_I;
|
||||
|
||||
PIPE_STATUS: process
|
||||
-- This logic detects the status of the
|
||||
-- instruction pipe prefetch in the
|
||||
-- REFILL_PIPE state.
|
||||
variable CNT : std_logic_vector(1 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE /= REFILL_PIPE then
|
||||
PIPE_FULL <= false;
|
||||
CNT := "00";
|
||||
elsif EX_STATE = REFILL_PIPE and OPCODE_RDY = '1' and CNT < "10" then
|
||||
CNT := CNT + '1';
|
||||
elsif EX_STATE = REFILL_PIPE and OPCODE_RDY = '1' then
|
||||
PIPE_FULL <= true;
|
||||
end if;
|
||||
PIPE_CNT <= CNT;
|
||||
end process PIPE_STATUS;
|
||||
|
||||
EXCEPTION_HANDLER_REG: process
|
||||
-- This is the register portion of the
|
||||
-- exception control state machine.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
EX_STATE <= IDLE;
|
||||
else
|
||||
EX_STATE <= NEXT_EX_STATE;
|
||||
end if;
|
||||
end process EXCEPTION_HANDLER_REG;
|
||||
|
||||
EXCEPTION_HANDLER_DEC: process(ACCESS_ERR, BUSY_MAIN, BUSY_OPD, DATA_IN, DATA_VALID, DOUBLE_BUSFLT, EX_STATE, EX_P_RESET, EX_P_AERR, EX_P_BERR,
|
||||
EX_P_TRACE, EX_P_INT, EX_P_ILLEGAL, EX_P_1010, EX_P_RTE, EX_P_1111, EX_P_FORMAT, EX_P_PRIV, EX_P_TRAP, EX_P_TRAPV,
|
||||
EX_P_CHK, EX_P_DIVZERO, EXCEPTION, DATA_RDY, PIPE_FULL, STACK_CNT, K6800n)
|
||||
begin
|
||||
case EX_STATE is
|
||||
when IDLE =>
|
||||
-- The priority of the exception execution is given by the
|
||||
-- following construct. Although type 3 commands do not require
|
||||
-- a prioritization, there is no drawback using these conditions.
|
||||
-- The spurious interrupt and uninitialized interrupt never appear
|
||||
-- as basic interrupts and therefore are not an interrupt source.
|
||||
-- During IDLE, when an interrupt occurs, the status register copy
|
||||
-- control is asserted and the current interrupt controll is given
|
||||
-- to the STORE_EXCEPTION process. During bus or address errors,
|
||||
-- the status register must be copied immediately to recognize
|
||||
-- the current status for RWn etc. (before the faulty bus cycle is
|
||||
-- finished).
|
||||
if (BUSY_MAIN = '1' or BUSY_OPD = '1') and EX_P_RESET = '0' then
|
||||
NEXT_EX_STATE <= IDLE; -- Wait until the pipelined architecture is ready.
|
||||
elsif EX_P_RESET = '1' or EX_P_AERR = '1' or EX_P_BERR = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_TRAP = '1' or EX_P_TRAPV = '1' or EX_P_CHK = '1' or EX_P_DIVZERO = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_FORMAT = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_TRACE = '1' or EX_P_ILLEGAL = '1' or EX_P_1010 = '1' or EX_P_1111 = '1' or EX_P_PRIV = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_RTE = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_INT = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
else -- No exception.
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
end if;
|
||||
when INIT =>
|
||||
-- In this state, the supervisor mode is switched on (the S bit is set)
|
||||
-- and the trace mode is switched off (the T bit is cleared).
|
||||
-- Do not service, if halted. The current bus cycle is always finished
|
||||
-- in this state. The worst case is a bus error which the finishes the
|
||||
-- current bus cycle within the next clock cycle after BERR is asserted.
|
||||
case EXCEPTION is
|
||||
when EX_RTE =>
|
||||
-- This state is foreseen to handle the address offset
|
||||
-- correctly in the case the ADR_ATN is already set
|
||||
-- by the main controller. So we have to wait one
|
||||
-- clock cycle to ensure this data hazard.
|
||||
if K6800n = '1' then
|
||||
NEXT_EX_STATE <= VALIDATE_FRAME; -- 68K10.
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_PC; -- 68K00.
|
||||
end if;
|
||||
when EX_INT =>
|
||||
NEXT_EX_STATE <= GET_VECTOR;
|
||||
when others =>
|
||||
NEXT_EX_STATE <= CALC_VECT_No;
|
||||
end case;
|
||||
when GET_VECTOR =>
|
||||
-- This state is intended to determine the vector number for the current process.
|
||||
if DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
else
|
||||
NEXT_EX_STATE <= GET_VECTOR;
|
||||
end if;
|
||||
when CALC_VECT_No =>
|
||||
-- This state is introduced to control the generation of the vector number
|
||||
-- for all exceptions except the external interrupts.
|
||||
case EXCEPTION is
|
||||
when EX_RESET =>
|
||||
NEXT_EX_STATE <= RESTORE_ISP; -- Do not stack anything but update the SSP and PC.
|
||||
when others =>
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
end case;
|
||||
-- The following states provide writing to the stack pointer or reading
|
||||
-- the exception vector address from memory. If there is a bus error
|
||||
-- or an address error during the read or write cycles, the processor
|
||||
-- proceeds in two different ways:
|
||||
-- If the errors occur during a reset, bus error or address error
|
||||
-- exception processing, a double bus fault has occured. In
|
||||
-- consequence, the processor halts due to catastrophic system failure.
|
||||
-- If the errors occur during other exception processings, the current
|
||||
-- processing is aborted and this exception handler state machine will
|
||||
-- immediately begin with the bus error exception handling.
|
||||
when BUILD_STACK =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' and STACK_CNT = 2 then
|
||||
NEXT_EX_STATE <= UPDATE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
end if;
|
||||
when UPDATE_PC =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
else
|
||||
NEXT_EX_STATE <= UPDATE_PC;
|
||||
end if;
|
||||
when VALIDATE_FRAME =>
|
||||
if DATA_RDY = '1' and DATA_VALID = '0' then
|
||||
NEXT_EX_STATE <= IDLE; -- Bus error.
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
case DATA_IN(15 downto 12) is
|
||||
when x"0" =>
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
when x"8" =>
|
||||
NEXT_EX_STATE <= EXAMINE_VERSION;
|
||||
when others =>
|
||||
NEXT_EX_STATE <= IDLE; -- Format error.
|
||||
end case;
|
||||
else
|
||||
NEXT_EX_STATE <= VALIDATE_FRAME;
|
||||
end if;
|
||||
when EXAMINE_VERSION =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
if DATA_IN /= VERSION then
|
||||
NEXT_EX_STATE <= IDLE; -- Format error.
|
||||
else
|
||||
NEXT_EX_STATE <= READ_BOTTOM;
|
||||
end if;
|
||||
else
|
||||
NEXT_EX_STATE <= EXAMINE_VERSION;
|
||||
end if;
|
||||
when READ_BOTTOM =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= READ_BOTTOM;
|
||||
end if;
|
||||
when RESTORE_STATUS =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_STATUS;
|
||||
end if;
|
||||
when RESTORE_ISP =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_ISP;
|
||||
end if;
|
||||
when RESTORE_PC =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED; -- Double bus fault.
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif EXCEPTION = EX_RESET and DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_STATUS;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
end if;
|
||||
when REFILL_PIPE =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif PIPE_FULL = true then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
else
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
end if;
|
||||
when HALTED =>
|
||||
-- Processor halted, Double bus error!
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
end case;
|
||||
end process EXCEPTION_HANDLER_DEC;
|
||||
end BEHAVIOR;
|
||||
1228
common/CPU/68K10/wf68k10_opcode_decoder.vhd
Normal file
1228
common/CPU/68K10/wf68k10_opcode_decoder.vhd
Normal file
File diff suppressed because it is too large
Load Diff
413
common/CPU/68K10/wf68k10_pkg.vhd
Normal file
413
common/CPU/68K10/wf68k10_pkg.vhd
Normal file
@@ -0,0 +1,413 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K10 IP Core: this is the package file containing the data ----
|
||||
---- types and the component declarations. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Later revisions
|
||||
-- Modifications according to changes of the entity in other modules.
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package WF68K10_PKG is
|
||||
type OP_SIZETYPE is (LONG, WORD, BYTE);
|
||||
-- The OPCODES AND, NOT, OR, ROR and ROL are defined keywords in VHDL. Therefore the assignment is
|
||||
-- AND_B, NOT_B, OR_B, ROTR and ROTL.
|
||||
type OP_68K is (ABCD, ADD, ADDA, ADDI, ADDQ, ADDX, AND_B, ANDI, ANDI_TO_CCR, ANDI_TO_SR, ASL, ASR, Bcc, BCHG, BCLR,
|
||||
BKPT, BRA, BSET, BSR, BTST, CHK, CLR, CMP, CMPA, CMPI, CMPM, DBcc, DIVS, DIVU, EOR, EORI, EORI_TO_CCR,
|
||||
EORI_TO_SR, EXG, EXT, ILLEGAL, JMP, JSR, LEA, LINK, LSL, LSR, MOVE, MOVE_FROM_CCR, MOVE_TO_CCR,
|
||||
MOVE_FROM_SR, MOVE_TO_SR, MOVE_USP, MOVEA, MOVEC, MOVEM, MOVEP, MOVEQ, MOVES, MULS, MULU, NBCD, NEG,
|
||||
NEGX, NOP, NOT_B, OR_B, ORI, ORI_TO_CCR, ORI_TO_SR, PEA, RESET, ROTL, ROTR, ROXL, ROXR, RTD,
|
||||
RTE, RTR, RTS, SBCD, Scc, STOP, SUB, SUBA, SUBI, SUBQ, SUBX, SWAP, TAS, TRAP, TRAPV, TST,
|
||||
UNLK, UNIMPLEMENTED);
|
||||
|
||||
type TRAPTYPE_OPC is(NONE, T_1010, T_1111, T_ILLEGAL, T_TRAP, T_PRIV, T_RTE); -- None is the first entry and default.
|
||||
|
||||
component WF68K10_ADDRESS_REGISTERS
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
AR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
AR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
AR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
AR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
INDEX_IN : in std_logic_vector(31 downto 0);
|
||||
PC : out std_logic_vector(31 downto 0);
|
||||
PC_EW_OFFSET : in std_logic_vector(3 downto 0);
|
||||
STORE_ADR_FORMAT : in bit;
|
||||
STORE_ABS_HI : in bit;
|
||||
STORE_ABS_LO : in bit;
|
||||
STORE_D16 : in bit;
|
||||
STORE_DISPL : in bit;
|
||||
STORE_AEFF : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
ADR_OFFSET : in std_logic_vector(31 downto 0);
|
||||
ADR_MARK_USED : in bit;
|
||||
ADR_IN_USE : out bit;
|
||||
ADR_MODE : in std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : in std_logic_vector(2 downto 0);
|
||||
ADR_EFF : out std_logic_vector(31 downto 0);
|
||||
ADR_EFF_WB : out std_logic_vector(31 downto 0);
|
||||
DFC : out std_logic_vector(2 downto 0);
|
||||
DFC_WR : in bit;
|
||||
SFC : out std_logic_vector(2 downto 0);
|
||||
SFC_WR : in bit;
|
||||
ISP_DEC : in bit;
|
||||
ISP_WR : in bit;
|
||||
USP_RD : in bit;
|
||||
USP_WR : in bit;
|
||||
AR_MARK_USED : in bit;
|
||||
USE_APAIR : in boolean;
|
||||
AR_IN_USE : out bit;
|
||||
AR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
AR_DEC : in bit;
|
||||
AR_INC : in bit;
|
||||
AR_WR_1 : in bit;
|
||||
AR_WR_2 : in bit;
|
||||
UNMARK : in bit;
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
SBIT : in std_logic;
|
||||
SP_ADD_DISPL : in bit;
|
||||
RESTORE_ISP_PC : in bit;
|
||||
DISPLACEMENT : in std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : in bit;
|
||||
PC_INC : in bit;
|
||||
PC_LOAD : in bit;
|
||||
PC_RESTORE : in bit;
|
||||
PC_OFFSET : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_ALU
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
LOAD_OP1 : in bit;
|
||||
LOAD_OP2 : in bit;
|
||||
LOAD_OP3 : in bit;
|
||||
OP1_IN : in std_logic_vector(31 downto 0);
|
||||
OP2_IN : in std_logic_vector(31 downto 0);
|
||||
OP3_IN : in std_logic_vector(31 downto 0);
|
||||
BITPOS_IN : in Std_Logic_Vector(4 downto 0);
|
||||
RESULT : out std_logic_vector(63 downto 0);
|
||||
ADR_MODE_IN : in std_logic_vector(2 downto 0);
|
||||
OP_SIZE_IN : in OP_SIZETYPE;
|
||||
OP_IN : in OP_68K;
|
||||
OP_WB : in OP_68K;
|
||||
BIW_0_IN : in std_logic_vector(11 downto 0);
|
||||
BIW_1_IN : in std_logic_vector(15 downto 0);
|
||||
SR_WR : in bit;
|
||||
SR_INIT : in bit;
|
||||
CC_UPDT : in bit;
|
||||
STATUS_REG_OUT : out std_logic_vector(15 downto 0);
|
||||
ALU_COND : out boolean;
|
||||
ALU_INIT : in bit;
|
||||
ALU_BSY : out bit;
|
||||
ALU_REQ : out bit;
|
||||
ALU_ACK : in bit;
|
||||
IRQ_PEND : in std_logic_vector(2 downto 0);
|
||||
TRAP_CHK : out bit;
|
||||
TRAP_DIVZERO : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_BUS_INTERFACE
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
ADR_IN_P : in std_logic_vector(31 downto 0);
|
||||
ADR_OUT_P : out std_logic_vector(31 downto 0);
|
||||
FC_IN : in std_logic_vector(2 downto 0);
|
||||
FC_OUT : out std_logic_vector(2 downto 0);
|
||||
DATA_PORT_IN : in std_logic_vector(15 downto 0);
|
||||
DATA_PORT_OUT : out std_logic_vector(15 downto 0);
|
||||
DATA_FROM_CORE : in std_logic_vector(31 downto 0);
|
||||
DATA_TO_CORE : out std_logic_vector(31 downto 0);
|
||||
OPCODE_TO_CORE : out std_logic_vector(15 downto 0);
|
||||
DATA_PORT_EN : out std_logic;
|
||||
BUS_EN : out std_logic;
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
RD_REQ : in bit;
|
||||
WR_REQ : in bit;
|
||||
DATA_RDY : out bit;
|
||||
DATA_VALID : out std_logic;
|
||||
OPCODE_REQ : in bit;
|
||||
OPCODE_RDY : out bit;
|
||||
OPCODE_VALID : out std_logic;
|
||||
RMC : in bit;
|
||||
BUSY_EXH : in bit;
|
||||
INBUFFER : out std_logic_vector(31 downto 0);
|
||||
OUTBUFFER : out std_logic_vector(31 downto 0);
|
||||
SSW : out std_logic_vector(15 downto 0);
|
||||
DTACKn : in std_logic;
|
||||
ASn : out std_logic;
|
||||
UDSn : out std_logic;
|
||||
LDSn : out std_logic;
|
||||
RWn : out std_logic;
|
||||
RMCn : out std_logic;
|
||||
DBENn : out std_logic;
|
||||
E : out std_logic;
|
||||
VMAn : out std_logic;
|
||||
VMA_EN : out std_logic;
|
||||
VPAn : in std_logic;
|
||||
BRn : in std_logic;
|
||||
BGACKn : in std_logic;
|
||||
BGn : out std_logic;
|
||||
RESET_STRB : in bit;
|
||||
RESET_IN : in std_logic;
|
||||
RESET_OUT : out std_logic;
|
||||
RESET_CPU : out bit;
|
||||
AVECn : in std_logic;
|
||||
HALTn : in std_logic;
|
||||
BERRn : in std_logic;
|
||||
AERR : out bit;
|
||||
BUS_BSY : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_CONTROL
|
||||
generic(NO_PIPELINE : boolean := false); -- If true the controller work in scalar mode.
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
RESET_CPU : in bit;
|
||||
BUSY : out bit;
|
||||
BUSY_EXH : in bit;
|
||||
EXH_REQ : in bit;
|
||||
INT_TRIG : out bit;
|
||||
OW_REQ : out bit;
|
||||
OW_VALID : in std_logic;
|
||||
EW_REQ : out bit;
|
||||
EW_ACK : in bit;
|
||||
OPD_ACK : in bit;
|
||||
ADR_MARK_USED : out bit;
|
||||
ADR_IN_USE : in bit;
|
||||
ADR_OFFSET : out std_logic_vector(5 downto 0);
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
RMC : out bit;
|
||||
LOAD_OP2 : out bit;
|
||||
LOAD_OP3 : out bit;
|
||||
LOAD_OP1 : out bit;
|
||||
STORE_ADR_FORMAT : out bit;
|
||||
STORE_D16 : out bit;
|
||||
STORE_DISPL : out bit;
|
||||
STORE_ABS_HI : out bit;
|
||||
STORE_ABS_LO : out bit;
|
||||
STORE_AEFF : out bit;
|
||||
STORE_IDATA_B2 : out bit;
|
||||
STORE_IDATA_B1 : out bit;
|
||||
OP : in OP_68K;
|
||||
OP_SIZE : out OP_SIZETYPE;
|
||||
BIW_0 : in std_logic_vector(13 downto 0);
|
||||
BIW_1 : in std_logic_vector(15 downto 0);
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
ADR_MODE : out std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : out std_logic_vector(2 downto 0);
|
||||
OP_WB : out OP_68K;
|
||||
OP_SIZE_WB : out OP_SIZETYPE;
|
||||
BIW_0_WB_73 : out std_logic_vector(7 downto 3);
|
||||
AR_MARK_USED : out bit;
|
||||
USE_APAIR : out boolean;
|
||||
AR_IN_USE : in bit;
|
||||
AR_SEL_RD_1 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : out std_logic_vector(2 downto 0);
|
||||
AR_INC : out bit;
|
||||
AR_DEC : out bit;
|
||||
AR_WR_1 : out bit;
|
||||
AR_WR_2 : out bit;
|
||||
DR_MARK_USED : out bit;
|
||||
USE_DPAIR : out boolean;
|
||||
DR_IN_USE : in bit;
|
||||
DR_SEL_RD_1 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_1 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : out std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : out bit;
|
||||
DR_WR_2 : out bit;
|
||||
UNMARK : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_INC_EXH : in bit;
|
||||
SP_ADD_DISPL : out bit;
|
||||
DFC_WR : out bit;
|
||||
DFC_RD : out bit;
|
||||
SFC_WR : out bit;
|
||||
SFC_RD : out bit;
|
||||
VBR_WR : out bit;
|
||||
VBR_RD : out bit;
|
||||
USP_RD : out bit;
|
||||
USP_WR : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
ALU_INIT : out bit;
|
||||
ALU_BSY : in bit;
|
||||
ALU_REQ : in bit;
|
||||
ALU_ACK : out bit;
|
||||
BKPT_CYCLE : out bit;
|
||||
BKPT_INSERT : out bit;
|
||||
LOOP_BSY : in bit;
|
||||
LOOP_SPLIT : out boolean;
|
||||
LOOP_EXIT : out bit;
|
||||
SR_WR : out bit;
|
||||
MOVEM_ADn : out bit;
|
||||
MOVEP_PNTR : out integer range 0 to 3;
|
||||
CC_UPDT : out bit;
|
||||
TRACE_EN : in std_logic;
|
||||
ALU_COND : in boolean;
|
||||
DBcc_COND : in boolean;
|
||||
BRANCH_ATN : in bit;
|
||||
RESET_STRB : out bit;
|
||||
BERR : out bit;
|
||||
EX_TRACE : out bit;
|
||||
TRAP_ILLEGAL : out bit;
|
||||
TRAP_V : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_DATA_REGISTERS
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
DR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
DR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
DR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
DR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
DR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : in bit;
|
||||
DR_WR_2 : in bit;
|
||||
DR_MARK_USED : in bit;
|
||||
USE_DPAIR : in boolean;
|
||||
DR_IN_USE : out bit;
|
||||
UNMARK : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_EXCEPTION_HANDLER
|
||||
generic(VERSION : std_logic_vector(31 downto 0));
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
K6800n : in std_logic;
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : in bit;
|
||||
EXH_REQ : out bit;
|
||||
BUSY_EXH : out bit;
|
||||
ADR_IN : in std_logic_vector(31 downto 0);
|
||||
ADR_OFFSET : out std_logic_vector(31 downto 0);
|
||||
CPU_SPACE : out bit;
|
||||
DATA_0 : in std_logic;
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_IN : in std_logic_vector(31 downto 0);
|
||||
OP_SIZE : out OP_SIZETYPE;
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
OPCODE_RDY : in bit;
|
||||
STATUS_REG_IN : in std_logic_vector(15 downto 0);
|
||||
SR_CPY : out std_logic_vector(15 downto 0);
|
||||
SR_INIT : out bit;
|
||||
SR_WR : out bit;
|
||||
ISP_DEC : out bit;
|
||||
ISP_LOAD : out bit;
|
||||
PC_INC : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_RESTORE : out bit;
|
||||
STACK_FORMAT : out std_logic_vector(3 downto 0);
|
||||
STACK_POS : out integer range 0 to 31;
|
||||
SP_ADD_DISPL : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(7 downto 0);
|
||||
IPIPE_FILL : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
RESTORE_ISP_PC : out bit;
|
||||
HALT_OUTn : out std_logic;
|
||||
INT_TRIG : in bit;
|
||||
IRQ_IN : in std_logic_vector(2 downto 0);
|
||||
IRQ_PEND : out std_logic_vector(2 downto 0);
|
||||
AVECn : in std_logic;
|
||||
IVECT_OFFS : out std_logic_vector(9 downto 0);
|
||||
TRAP_AERR : in bit;
|
||||
TRAP_BERR : in bit;
|
||||
TRAP_CHK : in bit;
|
||||
TRAP_DIVZERO : in bit;
|
||||
TRAP_ILLEGAL : in bit;
|
||||
TRAP_CODE_OPC : in TRAPTYPE_OPC;
|
||||
TRAP_VECTOR : in std_logic_vector(3 downto 0);
|
||||
TRAP_V : in bit;
|
||||
EX_TRACE_IN : in bit;
|
||||
VBR_WR : in bit;
|
||||
VBR : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K10_OPCODE_DECODER
|
||||
generic(NO_LOOP : boolean := false); -- If true the DBcc loop mechanism is disabled.
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
K6800n : in std_logic;
|
||||
OW_REQ_MAIN : in bit;
|
||||
EW_REQ_MAIN : in bit;
|
||||
EXH_REQ : in bit;
|
||||
BUSY_EXH : in bit;
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : out bit;
|
||||
BKPT_INSERT : in bit;
|
||||
BKPT_DATA : in std_logic_vector(15 downto 0);
|
||||
LOOP_EXIT : in bit;
|
||||
LOOP_BSY : out bit;
|
||||
OPD_ACK_MAIN : out bit;
|
||||
EW_ACK : out bit;
|
||||
PC_EW_OFFSET : out std_logic_vector(3 downto 0);
|
||||
PC_INC : out bit;
|
||||
PC_INC_EXH : in bit;
|
||||
PC_ADR_OFFSET : out std_logic_vector(7 downto 0);
|
||||
PC_OFFSET : out std_logic_vector(7 downto 0);
|
||||
OPCODE_RD : out bit;
|
||||
OPCODE_RDY : in bit;
|
||||
OPCODE_VALID : in std_logic;
|
||||
OPCODE_DATA : in std_logic_vector(15 downto 0);
|
||||
IPIPE_FILL : in bit;
|
||||
IPIPE_FLUSH : in bit;
|
||||
OW_VALID : out std_logic;
|
||||
SBIT : in std_logic;
|
||||
TRAP_CODE : out TRAPTYPE_OPC;
|
||||
OP : out OP_68K;
|
||||
BIW_0 : out std_logic_vector(15 downto 0);
|
||||
BIW_1 : out std_logic_vector(15 downto 0);
|
||||
BIW_2 : out std_logic_vector(15 downto 0);
|
||||
EXT_WORD : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
end WF68K10_PKG;
|
||||
1257
common/CPU/68K10/wf68k10_top.vhd
Normal file
1257
common/CPU/68K10/wf68k10_top.vhd
Normal file
File diff suppressed because it is too large
Load Diff
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2.odt
Normal file
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2.odt
Normal file
Binary file not shown.
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2.pdf
Normal file
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2.pdf
Normal file
Binary file not shown.
897
common/CPU/68K30L/license/cern_ohl_v_1_2.txt
Normal file
897
common/CPU/68K30L/license/cern_ohl_v_1_2.txt
Normal file
@@ -0,0 +1,897 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head><script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<title>CERN Open Hardware Licence - cern_ohl_v_1_2.txt - Open Hardware Repository</title>
|
||||
<meta name="description" content="ChiliProject" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<meta name="csrf-param" content="authenticity_token"/>
|
||||
<meta name="csrf-token" content="vZISqDiAMljbLq5tYqMywduU9VQksdL/1JYUZ1Pky8c="/>
|
||||
<link rel='shortcut icon' href='/favicon.ico?1405312613' />
|
||||
<link href="/themes/ohwr-theme/stylesheets/application.css?1404713280" media="all" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script src="/javascripts/prototype.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/effects.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/dragdrop.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/controls.js?1405312613" type="text/javascript"></script>
|
||||
<script src="/javascripts/application.js?1405312613" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('The current page contains unsaved text that will be lost if you leave this page.'); });
|
||||
//]]>
|
||||
</script>
|
||||
<script src="/themes/ohwr-theme/javascripts/theme.js?1404713280" type="text/javascript"></script>
|
||||
<!--[if IE 6]>
|
||||
<style type="text/css">
|
||||
* html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
|
||||
body {behavior: url(/stylesheets/csshover.htc?1405312613);}
|
||||
</style>
|
||||
<![endif]-->
|
||||
|
||||
<!-- page specific tags -->
|
||||
<link href="/stylesheets/scm.css?1405312613" media="screen" rel="stylesheet" type="text/css" /></head>
|
||||
<body class="theme-Ohwr-theme controller-attachments action-show environment-production">
|
||||
<div id="wrapper">
|
||||
<div id="wrapper2">
|
||||
<div id="top-menu">
|
||||
<div id="account">
|
||||
<ul><li><a href="/login" class="login">Sign in</a></li>
|
||||
<li><a href="/account/register" class="register">Register</a></li></ul> </div>
|
||||
|
||||
<ul><li><a href="/" class="home">Home</a></li>
|
||||
<li><a href="/projects" class="projects">Projects</a></li>
|
||||
<li><a href="/licenses" class="licenses">Licenses</a></li>
|
||||
<li><a href="/companies" class="companies">Companies</a></li>
|
||||
<li><a href="http://www.ohwr.org/projects/ohr-support/wiki" class="help">Help</a></li></ul></div>
|
||||
|
||||
<div id="header">
|
||||
|
||||
<div id="quick-search">
|
||||
<form action="/search/index/cernohl" method="get">
|
||||
|
||||
<label for='q'>
|
||||
<a href="/search/index/cernohl" accesskey="4">Search</a>:
|
||||
</label>
|
||||
<input accesskey="f" class="small" id="q" name="q" size="20" type="text" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h1>CERN Open Hardware Licence</h1>
|
||||
|
||||
|
||||
<div id="main-menu">
|
||||
<ul><li><a href="/projects/cernohl" class="overview">Overview</a></li>
|
||||
<li><a href="/projects/cernohl/wiki" class="wiki">Wiki</a></li>
|
||||
<li><a href="/projects/cernohl/activity" class="activity">Activity</a></li>
|
||||
<li><a href="/mailing_list/show?project_id=cernohl" class="mailing-list">Mailing List</a></li>
|
||||
<li><a href="/projects/cernohl/news" class="news">News</a></li>
|
||||
<li><a href="/projects/cernohl/documents" class="documents">Documents</a></li></ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="nosidebar" id="main">
|
||||
<div id="sidebar">
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h2>cern_ohl_v_1_2.txt</h2>
|
||||
|
||||
<div class="attachments">
|
||||
<p>Licence text in text format. -
|
||||
<span class="author"><a href="/users/7">Javier Serrano</a>, 2013-09-06 10:05</span></p>
|
||||
<p><a href="/attachments/download/2388/cern_ohl_v_1_2.txt">Download</a> <span class="size">(8.9 kB)</span></p>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="filecontent syntaxhl">
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L1"><a href="#L1">1</a></th><td class="line-code"><pre>CERN Open Hardware Licence v1.2
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L2"><a href="#L2">2</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L3"><a href="#L3">3</a></th><td class="line-code"><pre>Preamble
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L4"><a href="#L4">4</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L5"><a href="#L5">5</a></th><td class="line-code"><pre>Through this CERN Open Hardware Licence ("CERN OHL") version 1.2, CERN
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L6"><a href="#L6">6</a></th><td class="line-code"><pre>wishes to provide a tool to foster collaboration and sharing among
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L7"><a href="#L7">7</a></th><td class="line-code"><pre>hardware designers. The CERN OHL is copyright CERN. Anyone is welcome
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L8"><a href="#L8">8</a></th><td class="line-code"><pre>to use the CERN OHL, in unmodified form only, for the distribution of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L9"><a href="#L9">9</a></th><td class="line-code"><pre>their own Open Hardware designs. Any other right is reserved. Release
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L10"><a href="#L10">10</a></th><td class="line-code"><pre>of hardware designs under the CERN OHL does not constitute an
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L11"><a href="#L11">11</a></th><td class="line-code"><pre>endorsement of the licensor or its designs nor does it imply any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L12"><a href="#L12">12</a></th><td class="line-code"><pre>involvement by CERN in the development of such designs.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L13"><a href="#L13">13</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L14"><a href="#L14">14</a></th><td class="line-code"><pre>1. Definitions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L15"><a href="#L15">15</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L16"><a href="#L16">16</a></th><td class="line-code"><pre>In this Licence, the following terms have the following meanings:
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L17"><a href="#L17">17</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L18"><a href="#L18">18</a></th><td class="line-code"><pre>“Licence” means this CERN OHL.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L19"><a href="#L19">19</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L20"><a href="#L20">20</a></th><td class="line-code"><pre>“Documentation” means schematic diagrams, designs, circuit or circuit
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L21"><a href="#L21">21</a></th><td class="line-code"><pre>board layouts, mechanical drawings, flow charts and descriptive text,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L22"><a href="#L22">22</a></th><td class="line-code"><pre>and other explanatory material that is explicitly stated as being made
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L23"><a href="#L23">23</a></th><td class="line-code"><pre>available under the conditions of this Licence. The Documentation may
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L24"><a href="#L24">24</a></th><td class="line-code"><pre>be in any medium, including but not limited to computer files and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L25"><a href="#L25">25</a></th><td class="line-code"><pre>representations on paper, film, or any other media.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L26"><a href="#L26">26</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L27"><a href="#L27">27</a></th><td class="line-code"><pre>“Documentation Location” means a location where the Licensor has
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L28"><a href="#L28">28</a></th><td class="line-code"><pre>placed Documentation, and which he believes will be publicly
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L29"><a href="#L29">29</a></th><td class="line-code"><pre>accessible for at least three years from the first communication to
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L30"><a href="#L30">30</a></th><td class="line-code"><pre>the public or distribution of Documentation.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L31"><a href="#L31">31</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L32"><a href="#L32">32</a></th><td class="line-code"><pre>“Product” means either an entire, or any part of a, device built using
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L33"><a href="#L33">33</a></th><td class="line-code"><pre>the Documentation or the modified Documentation.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L34"><a href="#L34">34</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L35"><a href="#L35">35</a></th><td class="line-code"><pre>“Licensee” means any natural or legal person exercising rights under
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L36"><a href="#L36">36</a></th><td class="line-code"><pre>this Licence.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L37"><a href="#L37">37</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L38"><a href="#L38">38</a></th><td class="line-code"><pre>“Licensor” means any natural or legal person that creates or modifies
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L39"><a href="#L39">39</a></th><td class="line-code"><pre>Documentation and subsequently communicates to the public and/ or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L40"><a href="#L40">40</a></th><td class="line-code"><pre>distributes the resulting Documentation under the terms and conditions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L41"><a href="#L41">41</a></th><td class="line-code"><pre>of this Licence.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L42"><a href="#L42">42</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L43"><a href="#L43">43</a></th><td class="line-code"><pre>A Licensee may at the same time be a Licensor, and vice versa.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L44"><a href="#L44">44</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L45"><a href="#L45">45</a></th><td class="line-code"><pre>Use of the masculine gender includes the feminine and neuter genders
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L46"><a href="#L46">46</a></th><td class="line-code"><pre>and is employed solely to facilitate reading.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L47"><a href="#L47">47</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L48"><a href="#L48">48</a></th><td class="line-code"><pre>2. Applicability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L49"><a href="#L49">49</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L50"><a href="#L50">50</a></th><td class="line-code"><pre>2.1. This Licence governs the use, copying, modification,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L51"><a href="#L51">51</a></th><td class="line-code"><pre>communication to the public and distribution of the Documentation, and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L52"><a href="#L52">52</a></th><td class="line-code"><pre>the manufacture and distribution of Products. By exercising any right
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L53"><a href="#L53">53</a></th><td class="line-code"><pre>granted under this Licence, the Licensee irrevocably accepts these
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L54"><a href="#L54">54</a></th><td class="line-code"><pre>terms and conditions.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L55"><a href="#L55">55</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L56"><a href="#L56">56</a></th><td class="line-code"><pre>2.2. This Licence is granted by the Licensor directly to the Licensee,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L57"><a href="#L57">57</a></th><td class="line-code"><pre>and shall apply worldwide and without limitation in time. The Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L58"><a href="#L58">58</a></th><td class="line-code"><pre>may assign his licence rights or grant sub-licences.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L59"><a href="#L59">59</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L60"><a href="#L60">60</a></th><td class="line-code"><pre>2.3. This Licence does not extend to software, firmware, or code
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L61"><a href="#L61">61</a></th><td class="line-code"><pre>loaded into programmable devices which may be used in conjunction with
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L62"><a href="#L62">62</a></th><td class="line-code"><pre>the Documentation, the modified Documentation or with Products, unless
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L63"><a href="#L63">63</a></th><td class="line-code"><pre>such software, firmware, or code is explicitly expressed to be subject
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L64"><a href="#L64">64</a></th><td class="line-code"><pre>to this Licence. The use of such software, firmware, or code is
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L65"><a href="#L65">65</a></th><td class="line-code"><pre>otherwise subject to the applicable licence terms and conditions.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L66"><a href="#L66">66</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L67"><a href="#L67">67</a></th><td class="line-code"><pre>3. Copying, modification, communication to the public and distribution
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L68"><a href="#L68">68</a></th><td class="line-code"><pre>of the Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L69"><a href="#L69">69</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L70"><a href="#L70">70</a></th><td class="line-code"><pre>3.1. The Licensee shall keep intact all copyright and trademarks
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L71"><a href="#L71">71</a></th><td class="line-code"><pre>notices, all notices referring to Documentation Location, and all
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L72"><a href="#L72">72</a></th><td class="line-code"><pre>notices that refer to this Licence and to the disclaimer of warranties
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L73"><a href="#L73">73</a></th><td class="line-code"><pre>that are included in the Documentation. He shall include a copy
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L74"><a href="#L74">74</a></th><td class="line-code"><pre>thereof in every copy of the Documentation or, as the case may be,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L75"><a href="#L75">75</a></th><td class="line-code"><pre>modified Documentation, that he communicates to the public or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L76"><a href="#L76">76</a></th><td class="line-code"><pre>distributes.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L77"><a href="#L77">77</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L78"><a href="#L78">78</a></th><td class="line-code"><pre>3.2. The Licensee may copy, communicate to the public and distribute
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L79"><a href="#L79">79</a></th><td class="line-code"><pre>verbatim copies of the Documentation, in any medium, subject to the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L80"><a href="#L80">80</a></th><td class="line-code"><pre>requirements specified in section 3.1.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L81"><a href="#L81">81</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L82"><a href="#L82">82</a></th><td class="line-code"><pre>3.3. The Licensee may modify the Documentation or any portion thereof
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L83"><a href="#L83">83</a></th><td class="line-code"><pre>provided that upon modification of the Documentation, the Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L84"><a href="#L84">84</a></th><td class="line-code"><pre>shall make the modified Documentation available from a Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L85"><a href="#L85">85</a></th><td class="line-code"><pre>Location such that it can be easily located by an original Licensor
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L86"><a href="#L86">86</a></th><td class="line-code"><pre>once the Licensee communicates to the public or distributes the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L87"><a href="#L87">87</a></th><td class="line-code"><pre>modified Documentation under section 3.4, and, where required by
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L88"><a href="#L88">88</a></th><td class="line-code"><pre>section 4.1, by a recipient of a Product. However, the Licensor shall
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L89"><a href="#L89">89</a></th><td class="line-code"><pre>not assert his rights under the foregoing proviso unless or until a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L90"><a href="#L90">90</a></th><td class="line-code"><pre>Product is distributed.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L91"><a href="#L91">91</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L92"><a href="#L92">92</a></th><td class="line-code"><pre>3.4. The Licensee may communicate to the public and distribute the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L93"><a href="#L93">93</a></th><td class="line-code"><pre>modified Documentation (thereby in addition to being a Licensee also
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L94"><a href="#L94">94</a></th><td class="line-code"><pre>becoming a Licensor), always provided that he shall:
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L95"><a href="#L95">95</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L96"><a href="#L96">96</a></th><td class="line-code"><pre>a) comply with section 3.1;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L97"><a href="#L97">97</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L98"><a href="#L98">98</a></th><td class="line-code"><pre>b) cause the modified Documentation to carry prominent notices stating
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L99"><a href="#L99">99</a></th><td class="line-code"><pre>that the Licensee has modified the Documentation, with the date and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L100"><a href="#L100">100</a></th><td class="line-code"><pre>description of the modifications;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L101"><a href="#L101">101</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L102"><a href="#L102">102</a></th><td class="line-code"><pre>c) cause the modified Documentation to carry a new Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L103"><a href="#L103">103</a></th><td class="line-code"><pre>Location notice if the original Documentation provided for one;
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L104"><a href="#L104">104</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L105"><a href="#L105">105</a></th><td class="line-code"><pre>d) make available the modified Documentation at the same level of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L106"><a href="#L106">106</a></th><td class="line-code"><pre>abstraction as that of the Documentation, in the preferred format for
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L107"><a href="#L107">107</a></th><td class="line-code"><pre>making modifications to it (e.g. the native format of the CAD tool as
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L108"><a href="#L108">108</a></th><td class="line-code"><pre>applicable), and in the event that format is proprietary, in a format
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L109"><a href="#L109">109</a></th><td class="line-code"><pre>viewable with a tool licensed under an OSI-approved license if the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L110"><a href="#L110">110</a></th><td class="line-code"><pre>proprietary tool can create it; and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L111"><a href="#L111">111</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L112"><a href="#L112">112</a></th><td class="line-code"><pre>e) license the modified Documentation under the terms and conditions
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L113"><a href="#L113">113</a></th><td class="line-code"><pre>of this Licence or, where applicable, a later version of this Licence
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L114"><a href="#L114">114</a></th><td class="line-code"><pre>as may be issued by CERN.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L115"><a href="#L115">115</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L116"><a href="#L116">116</a></th><td class="line-code"><pre>3.5. The Licence includes a non-exclusive licence to those patents or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L117"><a href="#L117">117</a></th><td class="line-code"><pre>registered designs that are held by, under the control of, or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L118"><a href="#L118">118</a></th><td class="line-code"><pre>sub-licensable by the Licensor, to the extent necessary to make use of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L119"><a href="#L119">119</a></th><td class="line-code"><pre>the rights granted under this Licence. The scope of this section 3.5
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L120"><a href="#L120">120</a></th><td class="line-code"><pre>shall be strictly limited to the parts of the Documentation or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L121"><a href="#L121">121</a></th><td class="line-code"><pre>modified Documentation created by the Licensor.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L122"><a href="#L122">122</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L123"><a href="#L123">123</a></th><td class="line-code"><pre>4. Manufacture and distribution of Products
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L124"><a href="#L124">124</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L125"><a href="#L125">125</a></th><td class="line-code"><pre>4.1. The Licensee may manufacture or distribute Products always
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L126"><a href="#L126">126</a></th><td class="line-code"><pre>provided that, where such manufacture or distribution requires a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L127"><a href="#L127">127</a></th><td class="line-code"><pre>licence under this Licence the Licensee provides to each recipient of
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L128"><a href="#L128">128</a></th><td class="line-code"><pre>such Products an easy means of accessing a copy of the Documentation
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L129"><a href="#L129">129</a></th><td class="line-code"><pre>or modified Documentation, as applicable, as set out in section 3.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L130"><a href="#L130">130</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L131"><a href="#L131">131</a></th><td class="line-code"><pre>4.2. The Licensee is invited to inform any Licensor who has indicated
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L132"><a href="#L132">132</a></th><td class="line-code"><pre>his wish to receive this information about the type, quantity and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L133"><a href="#L133">133</a></th><td class="line-code"><pre>dates of production of Products the Licensee has (had) manufactured
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L134"><a href="#L134">134</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L135"><a href="#L135">135</a></th><td class="line-code"><pre>5. Warranty and liability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L136"><a href="#L136">136</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L137"><a href="#L137">137</a></th><td class="line-code"><pre>5.1. DISCLAIMER – The Documentation and any modified Documentation are
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L138"><a href="#L138">138</a></th><td class="line-code"><pre>provided "as is" and any express or implied warranties, including, but
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L139"><a href="#L139">139</a></th><td class="line-code"><pre>not limited to, implied warranties of merchantability, of satisfactory
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L140"><a href="#L140">140</a></th><td class="line-code"><pre>quality, non-infringement of third party rights, and fitness for a
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L141"><a href="#L141">141</a></th><td class="line-code"><pre>particular purpose or use are disclaimed in respect of the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L142"><a href="#L142">142</a></th><td class="line-code"><pre>Documentation, the modified Documentation or any Product. The Licensor
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L143"><a href="#L143">143</a></th><td class="line-code"><pre>makes no representation that the Documentation, modified
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L144"><a href="#L144">144</a></th><td class="line-code"><pre>Documentation, or any Product, does or will not infringe any patent,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L145"><a href="#L145">145</a></th><td class="line-code"><pre>copyright, trade secret or other proprietary right. The entire risk as
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L146"><a href="#L146">146</a></th><td class="line-code"><pre>to the use, quality, and performance of a Product shall be with the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L147"><a href="#L147">147</a></th><td class="line-code"><pre>Licensee and not the Licensor. This disclaimer of warranty is an
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L148"><a href="#L148">148</a></th><td class="line-code"><pre>essential part of this Licence and a condition for the grant of any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L149"><a href="#L149">149</a></th><td class="line-code"><pre>rights granted under this Licence. The Licensee warrants that it does
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L150"><a href="#L150">150</a></th><td class="line-code"><pre>not act in a consumer capacity.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L151"><a href="#L151">151</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L152"><a href="#L152">152</a></th><td class="line-code"><pre>5.2. LIMITATION OF LIABILITY – The Licensor shall have no liability
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L153"><a href="#L153">153</a></th><td class="line-code"><pre>for direct, indirect, special, incidental, consequential, exemplary,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L154"><a href="#L154">154</a></th><td class="line-code"><pre>punitive or other damages of any character including, without
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L155"><a href="#L155">155</a></th><td class="line-code"><pre>limitation, procurement of substitute goods or services, loss of use,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L156"><a href="#L156">156</a></th><td class="line-code"><pre>data or profits, or business interruption, however caused and on any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L157"><a href="#L157">157</a></th><td class="line-code"><pre>theory of contract, warranty, tort (including negligence), product
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L158"><a href="#L158">158</a></th><td class="line-code"><pre>liability or otherwise, arising in any way in relation to the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L159"><a href="#L159">159</a></th><td class="line-code"><pre>Documentation, modified Documentation and/or the use, manufacture or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L160"><a href="#L160">160</a></th><td class="line-code"><pre>distribution of a Product, even if advised of the possibility of such
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L161"><a href="#L161">161</a></th><td class="line-code"><pre>damages, and the Licensee shall hold the Licensor(s) free and harmless
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L162"><a href="#L162">162</a></th><td class="line-code"><pre>from any liability, costs, damages, fees and expenses, including
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L163"><a href="#L163">163</a></th><td class="line-code"><pre>claims by third parties, in relation to such use.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L164"><a href="#L164">164</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L165"><a href="#L165">165</a></th><td class="line-code"><pre>6. General
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L166"><a href="#L166">166</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L167"><a href="#L167">167</a></th><td class="line-code"><pre>6.1. Except for the rights explicitly granted hereunder, this Licence
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L168"><a href="#L168">168</a></th><td class="line-code"><pre>does not imply or represent any transfer or assignment of intellectual
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L169"><a href="#L169">169</a></th><td class="line-code"><pre>property rights to the Licensee.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L170"><a href="#L170">170</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L171"><a href="#L171">171</a></th><td class="line-code"><pre>6.2. The Licensee shall not use or make reference to any of the names
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L172"><a href="#L172">172</a></th><td class="line-code"><pre>(including acronyms and abbreviations), images, or logos under which
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L173"><a href="#L173">173</a></th><td class="line-code"><pre>the Licensor is known, save in so far as required to comply with
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L174"><a href="#L174">174</a></th><td class="line-code"><pre>section 3. Any such permitted use or reference shall be factual and
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L175"><a href="#L175">175</a></th><td class="line-code"><pre>shall in no event suggest any kind of endorsement by the Licensor or
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L176"><a href="#L176">176</a></th><td class="line-code"><pre>its personnel of the modified Documentation or any Product, or any
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L177"><a href="#L177">177</a></th><td class="line-code"><pre>kind of implication by the Licensor or its personnel in the
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L178"><a href="#L178">178</a></th><td class="line-code"><pre>preparation of the modified Documentation or Product.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L179"><a href="#L179">179</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L180"><a href="#L180">180</a></th><td class="line-code"><pre>6.3. CERN may publish updated versions of this Licence which retain
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L181"><a href="#L181">181</a></th><td class="line-code"><pre>the same general provisions as this version, but differ in detail so
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L182"><a href="#L182">182</a></th><td class="line-code"><pre>far this is required and reasonable. New versions will be published
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L183"><a href="#L183">183</a></th><td class="line-code"><pre>with a unique version number.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L184"><a href="#L184">184</a></th><td class="line-code"><pre>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L185"><a href="#L185">185</a></th><td class="line-code"><pre>6.4. This Licence shall terminate with immediate effect, upon written
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L186"><a href="#L186">186</a></th><td class="line-code"><pre>notice and without involvement of a court if the Licensee fails to
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L187"><a href="#L187">187</a></th><td class="line-code"><pre>comply with any of its terms and conditions, or if the Licensee
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L188"><a href="#L188">188</a></th><td class="line-code"><pre>initiates legal action against Licensor in relation to this
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><th class="line-num" id="L189"><a href="#L189">189</a></th><td class="line-code"><pre>Licence. Section 5 shall continue to apply.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="ajax-indicator" style="display:none;"><span>Loading...</span></div>
|
||||
|
||||
<div id="footer">
|
||||
<div class="bgl"><div class="bgr">
|
||||
Powered by <a href="https://www.chiliproject.org/">ChiliProject</a>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Piwik -->
|
||||
<script type="text/javascript" src="http://piwik.ohwr.org/piwik.js"></script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
var piwikTracker = Piwik.getTracker("http://piwik.ohwr.org/piwik.php", 1);
|
||||
piwikTracker.trackPageView();
|
||||
piwikTracker.enableLinkTracking();
|
||||
} catch( err ) {}
|
||||
</script><noscript><p><img src="http://piwik.ohwr.org/piwik.php?idsite=1" style="border:0" alt=""/></p></noscript>
|
||||
<!-- End Piwik Tag -->
|
||||
<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {
|
||||
NREUMQ.push(["load",new Date().getTime()]);
|
||||
var e=document.createElement("script");
|
||||
e.type="text/javascript";
|
||||
e.src=(("http:"===document.location.protocol)?"http:":"https:") + "//" +
|
||||
"js-agent.newrelic.com/nr-100.js";
|
||||
document.body.appendChild(e);
|
||||
if(NREUMQ.a)NREUMQ.a();
|
||||
};
|
||||
NREUMQ.a=window.onload;window.onload=NREUMQ.f;
|
||||
};
|
||||
NREUMQ.push(["nrfj","beacon-1.newrelic.com","a682afbce1","790800","cl4LRBQNCloGF0lWREVQBlgLBwhCEEoVX19G",0,570,new Date().getTime(),"","","","",""]);</script></body>
|
||||
</html>
|
||||
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2_howto.odt
Normal file
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2_howto.odt
Normal file
Binary file not shown.
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2_howto.pdf
Normal file
BIN
common/CPU/68K30L/license/cern_ohl_v_1_2_howto.pdf
Normal file
Binary file not shown.
40
common/CPU/68K30L/wf68K30L.sdc
Normal file
40
common/CPU/68K30L/wf68K30L.sdc
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright © 2014 Wolfgang Foerster Inventronik GmbH.
|
||||
#
|
||||
# This documentation describes Open Hardware and is licensed
|
||||
# under the CERN OHL v. 1.2. You may redistribute and modify
|
||||
# this documentation under the terms of the CERN OHL v.1.2.
|
||||
# (http://ohwr.org/cernohl). This documentation is distributed
|
||||
# WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF
|
||||
# MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for
|
||||
# applicable conditions
|
||||
|
||||
# Revision History
|
||||
|
||||
# Revision 2K14B 20140922 WF
|
||||
# Initial Release.
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Time Information
|
||||
#**************************************************************
|
||||
|
||||
# set_time_format -unit ns -decimal_places 3
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Create Clock
|
||||
#**************************************************************
|
||||
|
||||
# create_clock -name CLK -period 100.000 -waveform {0.000 50.000} [get_ports {CLK}]
|
||||
create_clock -period 32.000 -name CLK [get_ports {CLK}]
|
||||
|
||||
#derive_pll_clocks
|
||||
#derive_pll_clocks -use_net_name
|
||||
derive_clock_uncertainty
|
||||
|
||||
#set_clock_groups -exclusive -group {CLK_PLL1}
|
||||
#set_clock_groups -exclusive -group {CLK_PLL2}
|
||||
#set_clock_groups -exclusive -group {CODEC_SCLK}
|
||||
680
common/CPU/68K30L/wf68k30L_address_registers.vhd
Normal file
680
common/CPU/68K30L/wf68k30L_address_registers.vhd
Normal file
@@ -0,0 +1,680 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K30L IP Core: Address register logic. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This module provides the address registers, stack pointers, ----
|
||||
---- the address arithmetics, the program counter logic and the SFC ----
|
||||
---- and DFC registers. The address registers are accessible by two ----
|
||||
---- read and two write ports simultaneously. For more information ----
|
||||
---- refer to the MC68030 User' Manual. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K16A 20160620 WF
|
||||
-- Minor optimizations.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- Changed ADR_ATN logic to be valid one clock cycle earlier.
|
||||
-- Fixed PC restoring during exception processing.
|
||||
-- Fixed the writing ISP_REG during EXG instruction with two address registers.
|
||||
-- Fixed writing the stack pointer registers (MSBIT is used now).
|
||||
-- The address registers are always written long.
|
||||
-- Bugfix: exception handler do not increment and decrement the USP any more.
|
||||
-- MOVEM-Fix: the effective address in memory to register is stored (STORE_AEFF) not to be overwritten in case the addressing register is also loaded.
|
||||
-- Revision 2K19A 2019## WF
|
||||
-- Removed ADR_ATN. We do not need this any more.
|
||||
-- Fixed the condition if UNMARK and AR_MARK_USED are asserted simultaneously (see process P_IN_USE).
|
||||
-- Fixed the '0' conditions for AR_IN_USE.
|
||||
--
|
||||
|
||||
use work.WF68K30L_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K30L_ADDRESS_REGISTERS is
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
|
||||
-- Address and data:
|
||||
AR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
AR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
AR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
AR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
INDEX_IN : in std_logic_vector(31 downto 0);
|
||||
PC : out std_logic_vector(31 downto 0); -- Program counter (or sPC) always word aligned.
|
||||
PC_EW_OFFSET : in std_logic_vector(3 downto 0); -- Offset to the first address extension word.
|
||||
FETCH_MEM_ADR : in bit;
|
||||
STORE_ADR_FORMAT : in bit;
|
||||
STORE_ABS_HI : in bit;
|
||||
STORE_ABS_LO : in bit;
|
||||
STORE_D16 : in bit;
|
||||
STORE_D32_LO : in bit;
|
||||
STORE_D32_HI : in bit;
|
||||
STORE_DISPL : in bit;
|
||||
STORE_MEM_ADR : in bit;
|
||||
STORE_OD_HI : in bit;
|
||||
STORE_OD_LO : in bit;
|
||||
STORE_AEFF : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
|
||||
ADR_OFFSET : in std_logic_vector(31 downto 0);
|
||||
ADR_MARK_USED : in bit;
|
||||
USE_APAIR : in boolean;
|
||||
ADR_IN_USE : out bit;
|
||||
|
||||
ADR_MODE : in std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : in std_logic_vector(2 downto 0);
|
||||
USE_DREG : in bit; -- Use data register as address pointer.
|
||||
ADR_EFF : out std_logic_vector(31 downto 0); -- This is the effective address.
|
||||
ADR_EFF_WB : out std_logic_vector(31 downto 0); -- This is the effective address.
|
||||
|
||||
DFC : out std_logic_vector(2 downto 0);
|
||||
DFC_WR : in bit;
|
||||
SFC : out std_logic_vector(2 downto 0);
|
||||
SFC_WR : in bit;
|
||||
|
||||
ISP_DEC : in bit;
|
||||
ISP_RD : in bit;
|
||||
ISP_WR : in bit;
|
||||
MSP_RD : in bit;
|
||||
MSP_WR : in bit;
|
||||
USP_RD : in bit;
|
||||
USP_WR : in bit;
|
||||
|
||||
-- Registers controls:
|
||||
AR_MARK_USED : in bit;
|
||||
AR_IN_USE : out bit;
|
||||
AR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
AR_DEC : in bit; -- Address register decrement.
|
||||
AR_INC : in bit; -- Address register increment.
|
||||
AR_WR_1 : in bit; -- Address register write.
|
||||
AR_WR_2 : in bit; -- Address register write.
|
||||
UNMARK : in bit;
|
||||
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
|
||||
MBIT : in std_logic;
|
||||
SBIT : in std_logic;
|
||||
|
||||
SP_ADD_DISPL : in bit;
|
||||
RESTORE_ISP_PC : in bit;
|
||||
|
||||
-- Other controls:
|
||||
DISPLACEMENT : in std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : in bit;
|
||||
PC_INC : in bit; -- Program counter increment.
|
||||
PC_LOAD : in bit; -- Program counter write.
|
||||
PC_RESTORE : in bit;
|
||||
PC_OFFSET : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
end entity WF68K30L_ADDRESS_REGISTERS;
|
||||
|
||||
architecture BEHAVIOR of WF68K30L_ADDRESS_REGISTERS is
|
||||
type AR_TYPE is array(0 to 6) of std_logic_vector(31 downto 0);
|
||||
signal ADR_EFF_I : std_logic_vector(31 downto 0);
|
||||
signal AR : AR_TYPE; -- Address registers A0 to A6.
|
||||
signal AR_OUT_1_I : std_logic_vector(31 downto 0);
|
||||
signal AR_OUT_2_I : std_logic_vector(31 downto 0);
|
||||
signal ADR_WB : std_logic_vector(32 downto 0);
|
||||
signal AR_PNTR_1 : integer range 0 to 7;
|
||||
signal AR_PNTR_2 : integer range 0 to 7;
|
||||
signal AR_PNTR_WB_1 : integer range 0 to 7;
|
||||
signal AR_PNTR_WB_2 : integer range 0 to 7;
|
||||
signal AR_USED_1 : std_logic_vector(3 downto 0);
|
||||
signal AR_USED_2 : std_logic_vector(3 downto 0);
|
||||
signal B_S : std_logic := '0'; -- Base register suppress.
|
||||
signal BD_SIZE : std_logic_vector(1 downto 0); -- Indexed / Indirect.
|
||||
signal DFC_REG : std_logic_vector(2 downto 0); -- Special function code registers.
|
||||
signal F_E : std_logic; -- Full extension word.
|
||||
signal I_IS : std_logic_vector(2 downto 0); -- Indexed / Indirect.
|
||||
signal I_S : std_logic; -- Index suppress.
|
||||
signal ISP_REG : std_logic_vector(31 downto 0); -- Interrupt stack pointer (refers to A7'' in the supervisor mode).
|
||||
signal MSBIT : std_logic_vector(1 downto 0);
|
||||
signal MSP_REG : std_logic_vector(31 downto 0); -- Master stack pointer (refers to A7' in the supervisor mode).
|
||||
signal PC_I : std_logic_vector(31 downto 0); -- Active program counter.
|
||||
signal SCALE : std_logic_vector(1 downto 0); -- Scale information for the index.
|
||||
signal SFC_REG : std_logic_vector(2 downto 0); -- Special function code registers.
|
||||
signal USP_REG : std_logic_vector(31 downto 0); -- User stack pointer (refers to A7 in the user mode.).
|
||||
begin
|
||||
INBUFFER: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if AR_MARK_USED = '1' then
|
||||
AR_PNTR_WB_1 <= conv_integer(AR_SEL_WR_1);
|
||||
AR_PNTR_WB_2 <= conv_integer(AR_SEL_WR_2);
|
||||
end if;
|
||||
end process INBUFFER;
|
||||
|
||||
AR_PNTR_1 <= conv_integer(AR_SEL_RD_1);
|
||||
AR_PNTR_2 <= conv_integer(AR_SEL_RD_2);
|
||||
|
||||
P_IN_USE: process
|
||||
variable DELAY : boolean;
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' or (UNMARK = '1' and AR_MARK_USED = '0') then
|
||||
AR_USED_1(3) <= '0';
|
||||
AR_USED_2(3) <= '0';
|
||||
elsif AR_MARK_USED = '1' then
|
||||
AR_USED_1 <= '1' & AR_SEL_WR_1;
|
||||
if USE_APAIR = true then
|
||||
AR_USED_2 <= '1' & AR_SEL_WR_2;
|
||||
end if;
|
||||
MSBIT <= MBIT & SBIT;
|
||||
end if;
|
||||
--
|
||||
if RESET = '1' or (UNMARK = '1' and AR_MARK_USED = '0') then
|
||||
ADR_WB(32) <= '0';
|
||||
DELAY := false;
|
||||
elsif ADR_MARK_USED = '1' then
|
||||
DELAY := true; -- One clock cycle address calculation delay.
|
||||
elsif DELAY = true then
|
||||
ADR_WB <= '1' & ADR_EFF_I;
|
||||
DELAY := false;
|
||||
end if;
|
||||
end process P_IN_USE;
|
||||
|
||||
AR_IN_USE <= '0' when AR_USED_1(3) = '1' and AR_USED_1(2 downto 0) = "111" and SBIT = '1' and MSBIT(1) /= MBIT else -- Wrong stack pointer.
|
||||
'0' when AR_USED_2(3) = '1' and AR_USED_2(2 downto 0) = "111" and SBIT = '1' and MSBIT(1) /= MBIT else -- Wrong stack pointer.
|
||||
'1' when AR_USED_1(3) = '1' and AR_USED_1(2 downto 0) = AR_SEL_RD_1 else
|
||||
'1' when AR_USED_1(3) = '1' and AR_USED_1(2 downto 0) = AR_SEL_RD_2 else
|
||||
'1' when AR_USED_2(3) = '1' and AR_USED_2(2 downto 0) = AR_SEL_RD_1 else
|
||||
'1' when AR_USED_2(3) = '1' and AR_USED_2(2 downto 0) = AR_SEL_RD_2 else '0';
|
||||
|
||||
AR_OUT_1 <= AR_OUT_1_I;
|
||||
AR_OUT_2 <= AR_OUT_2_I;
|
||||
|
||||
ADR_IN_USE <= '1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) = ADR_EFF_I(31 downto 2) else -- Actual long word address.
|
||||
'1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) - '1' = ADR_EFF_I(31 downto 2) else -- Lock a misaligned access.
|
||||
'1' when ADR_WB(32) = '1' and ADR_WB(31 downto 2) + '1' = ADR_EFF_I(31 downto 2) else '0'; -- Lock a misaligned access.
|
||||
|
||||
ADR_FORMAT: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if STORE_ADR_FORMAT = '1' then
|
||||
SCALE <= EXT_WORD(10 downto 9);
|
||||
F_E <= EXT_WORD(8);
|
||||
B_S <= EXT_WORD(7);
|
||||
I_S <= EXT_WORD(6);
|
||||
BD_SIZE <= EXT_WORD(5 downto 4);
|
||||
I_IS <= EXT_WORD(2 downto 0);
|
||||
end if;
|
||||
end process ADR_FORMAT;
|
||||
|
||||
ADDRESS_MODES: process(ADR_MODE, AMODE_SEL, AR, AR_IN_1, AR_PNTR_1, B_S,
|
||||
CLK, F_E, FETCH_MEM_ADR, I_S, I_IS, ISP_REG, MBIT, MSP_REG,
|
||||
PC_EW_OFFSET, PC_I, RESTORE_ISP_PC, SBIT, USE_DREG, USP_REG)
|
||||
-- The effective address calculation takes place in this process depending on the
|
||||
-- selected addressing mode.
|
||||
-- The PC address (PC_I) used for the address calculation points to the first
|
||||
-- extension word used.
|
||||
variable ABS_ADDRESS : std_logic_vector(31 downto 0);
|
||||
variable ADR_EFF_VAR : std_logic_vector(31 downto 0);
|
||||
variable ADR_EFF_TMP : std_logic_vector(31 downto 0);
|
||||
variable ADR_MUX : std_logic_vector(31 downto 0);
|
||||
variable BASE_DISPL : std_logic_vector(31 downto 0);
|
||||
variable I_S_IS : std_logic_vector(3 downto 0);
|
||||
variable INDEX : std_logic_vector(31 downto 0) := x"00000000";
|
||||
variable INDEX_SCALED : std_logic_vector(31 downto 0);
|
||||
variable MEM_ADR : std_logic_vector(31 downto 0);
|
||||
variable OUTER_DISPL : std_logic_vector(31 downto 0);
|
||||
variable PCVAR : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
I_S_IS := I_S & I_IS;
|
||||
PCVAR := PC_I + PC_EW_OFFSET; -- This is the address of the extension word.
|
||||
|
||||
if CLK = '1' and CLK' event then
|
||||
-- This logic selects the INDEX from one of the data registers or from one of
|
||||
-- the address registers. Furthermore the index needs to be sign extended from
|
||||
-- 8 bit to 32 bit or from 16 bit to 32 bit dependent on the address mode.
|
||||
-- In case of a long word operation, no extension is required. The index is
|
||||
-- multiplied by 1, 2, 4 or 8.
|
||||
if STORE_ADR_FORMAT = '1' and EXT_WORD(15) = '0' and EXT_WORD(11) = '1' then
|
||||
INDEX := INDEX_IN; -- Long data register.
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(15) = '0' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := INDEX_IN(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := INDEX_IN(15 downto 0); -- Sign extended data register;
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(11) = '1' then -- Long address register.
|
||||
if EXT_WORD(14 downto 12) = "111" and SBIT = '1' and MBIT = '1' then
|
||||
INDEX := MSP_REG;
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '1' and MBIT = '0' then
|
||||
INDEX := ISP_REG;
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '0' then
|
||||
INDEX := USP_REG;
|
||||
else
|
||||
INDEX := AR(conv_integer(EXT_WORD(14 downto 12)));
|
||||
end if;
|
||||
elsif STORE_ADR_FORMAT = '1' then -- Sign extended address register;
|
||||
if EXT_WORD(14 downto 12) = "111" and SBIT = '1' and MBIT = '1' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := MSP_REG(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := MSP_REG(15 downto 0);
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '1' and MBIT = '0' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := ISP_REG(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := ISP_REG(15 downto 0);
|
||||
elsif EXT_WORD(14 downto 12) = "111" and SBIT = '0' then
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := USP_REG(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := USP_REG(15 downto 0);
|
||||
else
|
||||
for i in 31 downto 16 loop
|
||||
INDEX(i) := AR(conv_integer(EXT_WORD(14 downto 12)))(15);
|
||||
end loop;
|
||||
INDEX(15 downto 0) := AR(conv_integer(EXT_WORD(14 downto 12)))(15 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
case SCALE is
|
||||
when "00" => INDEX_SCALED := INDEX; -- Multiple by 1.
|
||||
when "01" => INDEX_SCALED := INDEX(30 downto 0) & '0'; -- Multiple by 2.
|
||||
when "10" => INDEX_SCALED := INDEX(29 downto 0) & "00"; -- Multiple by 4.
|
||||
when others => INDEX_SCALED := INDEX(28 downto 0) & "000"; -- Multiple by 8.
|
||||
end case;
|
||||
--
|
||||
-- Register for memory indirect addressing modes.
|
||||
if STORE_MEM_ADR = '1' then
|
||||
MEM_ADR := AR_IN_1;
|
||||
end if;
|
||||
--
|
||||
-- The displacement needs to be sign extended from 8 bit to 32, from 16 bit to 32 bit or
|
||||
-- not extended dependent on the address mode.
|
||||
if RESET = '1' then
|
||||
BASE_DISPL := (others => '0'); -- Null base displacement.
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(8) = '1' and EXT_WORD(5 downto 4) = "01" then
|
||||
BASE_DISPL := (others => '0'); -- Null base displacement.
|
||||
elsif STORE_ADR_FORMAT = '1' and EXT_WORD(8) = '0' then
|
||||
for i in 31 downto 8 loop
|
||||
BASE_DISPL(i) := EXT_WORD(7);
|
||||
end loop;
|
||||
BASE_DISPL(7 downto 0) := EXT_WORD(7 downto 0);
|
||||
elsif STORE_D16 = '1' then
|
||||
for i in 31 downto 16 loop
|
||||
BASE_DISPL(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
BASE_DISPL(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_D32_LO = '1' then
|
||||
if BD_SIZE = "10" then -- Word displacement.
|
||||
for i in 31 downto 16 loop
|
||||
BASE_DISPL(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
end if;
|
||||
BASE_DISPL(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_D32_HI = '1' then
|
||||
BASE_DISPL(31 downto 16) := EXT_WORD;
|
||||
elsif STORE_DISPL = '1' then
|
||||
BASE_DISPL := DISPLACEMENT;
|
||||
end if;
|
||||
--
|
||||
-- The outer displacement may be NULL, WORD or LONG.
|
||||
if STORE_ADR_FORMAT = '1' and EXT_WORD(8) = '1' and EXT_WORD(1 downto 0) = "01" then
|
||||
OUTER_DISPL := (others => '0'); -- Null outer displacement.
|
||||
elsif STORE_OD_LO = '1' then
|
||||
if I_IS(1 downto 0) = "10" then
|
||||
for i in 31 downto 16 loop
|
||||
OUTER_DISPL(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
end if;
|
||||
OUTER_DISPL(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_OD_HI = '1' then
|
||||
OUTER_DISPL(31 downto 16) := EXT_WORD;
|
||||
end if;
|
||||
--
|
||||
if STORE_ABS_LO = '1' then
|
||||
if AMODE_SEL = "000" then
|
||||
for i in 31 downto 16 loop
|
||||
ABS_ADDRESS(i) := EXT_WORD(15);
|
||||
end loop;
|
||||
end if;
|
||||
ABS_ADDRESS(15 downto 0) := EXT_WORD;
|
||||
elsif STORE_ABS_HI = '1' then
|
||||
ABS_ADDRESS(31 downto 16) := EXT_WORD;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if ADR_MODE = "110" and FETCH_MEM_ADR = '1' and F_E = '1' and B_S = '1' then
|
||||
ADR_MUX := x"00000000"; -- Base register suppress.
|
||||
elsif ADR_MODE = "111" and FETCH_MEM_ADR = '1' and AMODE_SEL = "011" and F_E = '1' and B_S = '1' then
|
||||
ADR_MUX := x"00000000"; -- Base register suppress.
|
||||
elsif USE_DREG = '1' then
|
||||
ADR_MUX := AR_IN_1;
|
||||
else
|
||||
case AR_PNTR_1 is
|
||||
when 7 =>
|
||||
if SBIT = '1' and MBIT = '0' then
|
||||
ADR_MUX := ISP_REG;
|
||||
elsif SBIT = '1' then
|
||||
ADR_MUX := MSP_REG;
|
||||
else
|
||||
ADR_MUX := USP_REG;
|
||||
end if;
|
||||
when others => ADR_MUX := AR(AR_PNTR_1);
|
||||
end case;
|
||||
end if;
|
||||
|
||||
case ADR_MODE is
|
||||
-- when "000" | "001" => Direct address modes: no effective address required.
|
||||
when "010" | "011" | "100" =>
|
||||
ADR_EFF_VAR := ADR_MUX; -- (An), (An)+, -(An).
|
||||
when "101" => -- Address register indirect with offset. Assembler syntax: (d16,An).
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL; -- (d16,An).
|
||||
when "110" =>
|
||||
if F_E = '0' then -- Brief extension word.
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL + INDEX_SCALED; -- (d8, An, Xn, SIZE*SCALE).
|
||||
else -- Full extension word.
|
||||
case I_S_IS is
|
||||
when "0000" | "1000" => -- No memory indirect action.
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL + INDEX_SCALED; -- (bd, An, Xn, SIZE*SCALE).
|
||||
when "0001" | "0010" | "0011" => -- Memory indirect preindexed.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL + INDEX_SCALED;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + OUTER_DISPL;
|
||||
end if;
|
||||
when "0101" | "0110" | "0111" => -- Memory indirect postindexed.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + INDEX_SCALED + OUTER_DISPL;
|
||||
end if;
|
||||
when "1001" | "1010" | "1011" => -- Memory indirect.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := ADR_MUX + BASE_DISPL;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + OUTER_DISPL;
|
||||
end if;
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Reserved, don't care.
|
||||
end case;
|
||||
end if;
|
||||
when "111" =>
|
||||
case AMODE_SEL is
|
||||
when "000" | "001" =>
|
||||
ADR_EFF_VAR := ABS_ADDRESS;
|
||||
when "010" => -- (d16, PC).
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL;
|
||||
when "011" =>
|
||||
if F_E = '0' then -- Brief extension word.
|
||||
-- Assembler syntax: (d8,PC,Xn.SIZE*SCALE).
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL + INDEX_SCALED; -- (d8, PC, Xn, SIZE*SCALE).
|
||||
else -- Full extension word.
|
||||
case I_S_IS is
|
||||
when "0000" | "1000" => -- No memory indirect action.
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL + INDEX_SCALED; -- (bd, PC, Xn, SIZE*SCALE).
|
||||
when "0001" | "0010" | "0011" => -- Memory indirect preindexed.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL + INDEX_SCALED;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + OUTER_DISPL;
|
||||
end if;
|
||||
when "0101" | "0110" | "0111" => -- Memory indirect postindexed.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + INDEX_SCALED + OUTER_DISPL;
|
||||
end if;
|
||||
when "1001" | "1010" | "1011" => -- Memory indirect.
|
||||
if FETCH_MEM_ADR = '1' then
|
||||
ADR_EFF_VAR := PCVAR + BASE_DISPL;
|
||||
else
|
||||
ADR_EFF_VAR := MEM_ADR + OUTER_DISPL;
|
||||
end if;
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Reserved, don't care.
|
||||
end case;
|
||||
end if;
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Don't care, while not used.
|
||||
end case;
|
||||
when others =>
|
||||
ADR_EFF_VAR := (others => '-'); -- Result not required.
|
||||
end case;
|
||||
--
|
||||
if CLK = '1' and CLK' event then
|
||||
if RESTORE_ISP_PC = '1' then
|
||||
ADR_EFF_I <= ADR_OFFSET; -- During system initialization.
|
||||
elsif STORE_AEFF = '1' then -- Used for MOVEM.
|
||||
ADR_EFF_I <= ADR_EFF_TMP + ADR_OFFSET; -- Keep the effective address. See also CONTROL section.
|
||||
else -- Normal operation:
|
||||
ADR_EFF_I <= ADR_EFF_VAR + ADR_OFFSET;
|
||||
ADR_EFF_TMP := ADR_EFF_VAR;
|
||||
end if;
|
||||
end if;
|
||||
end process ADDRESS_MODES;
|
||||
|
||||
ADR_EFF <= ADR_EFF_I;
|
||||
ADR_EFF_WB <= ADR_WB(31 downto 0);
|
||||
|
||||
-- Data outputs:
|
||||
AR_OUT_1_I <= ISP_REG when ISP_RD = '1' else
|
||||
MSP_REG when MSP_RD = '1' else
|
||||
USP_REG when USP_RD = '1' else
|
||||
AR(AR_PNTR_1) when AR_PNTR_1 < 7 else
|
||||
MSP_REG when SBIT = '1' and MBIT = '1' else
|
||||
ISP_REG when SBIT = '1' and MBIT = '0' else USP_REG;
|
||||
|
||||
AR_OUT_2_I <= AR(AR_PNTR_2) when AR_PNTR_2 < 7 else
|
||||
MSP_REG when SBIT = '1' and MBIT = '1' else
|
||||
ISP_REG when SBIT = '1' and MBIT = '0' else USP_REG;
|
||||
|
||||
PC <= PC_I;
|
||||
|
||||
PROGRAM_COUNTER: process
|
||||
-- Note: PC_LOAD and PC_ADD_DISPL must be highest
|
||||
-- prioritized. The reason is that in case of jumps
|
||||
-- or branches the Ipipe is flushed in connection
|
||||
-- with PC_INC. In such cases PC_LOAD or PC_ADD_DISPL
|
||||
-- are asserted simultaneously with PC_INC.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
PC_I <= (others => '0');
|
||||
elsif PC_LOAD = '1' then
|
||||
PC_I <= AR_IN_1;
|
||||
elsif PC_ADD_DISPL = '1' then
|
||||
PC_I <= PC_I + DISPLACEMENT;
|
||||
elsif PC_RESTORE = '1' then
|
||||
PC_I <= AR_IN_1; -- Keep prioritization!
|
||||
elsif PC_INC = '1' then
|
||||
PC_I <= PC_I + PC_OFFSET;
|
||||
end if;
|
||||
end process PROGRAM_COUNTER;
|
||||
|
||||
STACK_POINTERS: process
|
||||
-- The registers are modeled in a way
|
||||
-- that write and simultaneously increment
|
||||
-- decrement and others are possible for
|
||||
-- different registers.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
|
||||
---------------------------------------- MSP section ----------------------------------------
|
||||
if RESET = '1' then
|
||||
MSP_REG <= (others => '0');
|
||||
elsif AR_WR_1 = '1' and AR_PNTR_WB_1 = 7 and MSBIT = "11" then
|
||||
MSP_REG <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 = 7 and SBIT = '1' and MBIT = '1' then
|
||||
case OP_SIZE is
|
||||
when BYTE => MSP_REG <= MSP_REG + "10"; -- Increment by two!
|
||||
when WORD => MSP_REG <= MSP_REG + "10"; -- Increment by two.
|
||||
when others => MSP_REG <= MSP_REG + "100"; -- Increment by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_DEC = '1' and AR_PNTR_1 = 7 and SBIT = '1' and MBIT = '1' then
|
||||
case OP_SIZE is
|
||||
when BYTE => MSP_REG <= MSP_REG - "10"; -- Decrement by two!
|
||||
when WORD => MSP_REG <= MSP_REG - "10"; -- Decrement by two.
|
||||
when others => MSP_REG <= MSP_REG - "100"; -- Decrement by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if MSP_WR = '1' then
|
||||
MSP_REG <= AR_IN_1;
|
||||
elsif SP_ADD_DISPL = '1' and AR_INC = '1' and SBIT = '1' and MBIT = '1' then
|
||||
MSP_REG <= MSP_REG + DISPLACEMENT + "100"; -- Used for RTD.
|
||||
elsif SP_ADD_DISPL = '1' and SBIT = '1' and MBIT = '1' then
|
||||
MSP_REG <= MSP_REG + DISPLACEMENT;
|
||||
end if;
|
||||
|
||||
---------------------------------------- ISP section ----------------------------------------
|
||||
if RESET = '1' then
|
||||
ISP_REG <= (others => '0');
|
||||
elsif AR_WR_1 = '1' and AR_PNTR_WB_1 = 7 and MSBIT = "01" then
|
||||
ISP_REG <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 = 7 and SBIT = '1' and MBIT = '0' then
|
||||
case OP_SIZE is
|
||||
when BYTE => ISP_REG <= ISP_REG + "10"; -- Increment by two!
|
||||
when WORD => ISP_REG <= ISP_REG + "10"; -- Increment by two.
|
||||
when others => ISP_REG <= ISP_REG + "100"; -- Increment by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if ISP_DEC = '1' or (AR_DEC = '1' and AR_PNTR_1 = 7 and SBIT = '1' and MBIT = '0') then
|
||||
case OP_SIZE is
|
||||
when BYTE => ISP_REG <= ISP_REG - "10"; -- Decrement by two!
|
||||
when WORD => ISP_REG <= ISP_REG - "10"; -- Decrement by two.
|
||||
when others => ISP_REG <= ISP_REG - "100"; -- Decrement by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if ISP_WR = '1' then
|
||||
ISP_REG <= AR_IN_1;
|
||||
elsif SP_ADD_DISPL = '1' and AR_INC = '1' and SBIT = '1' and MBIT = '0' then
|
||||
ISP_REG <= ISP_REG + DISPLACEMENT + "100"; -- Used for RTD.
|
||||
elsif SP_ADD_DISPL = '1' and SBIT = '1' and MBIT = '0' then
|
||||
ISP_REG <= ISP_REG + DISPLACEMENT;
|
||||
end if;
|
||||
|
||||
---------------------------------------- USP section ----------------------------------------
|
||||
if RESET = '1' then
|
||||
USP_REG <= (others => '0');
|
||||
elsif AR_WR_1 = '1' and AR_PNTR_WB_1 = 7 and MSBIT(0) = '0' then
|
||||
USP_REG <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 = 7 and SBIT = '0' then
|
||||
case OP_SIZE is
|
||||
when BYTE => USP_REG <= USP_REG + "10"; -- Increment by two!
|
||||
when WORD => USP_REG <= USP_REG + "10"; -- Increment by two.
|
||||
when others => USP_REG <= USP_REG + "100"; -- Increment by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_DEC = '1' and AR_PNTR_1 = 7 and SBIT = '0' then
|
||||
case OP_SIZE is
|
||||
when BYTE => USP_REG <= USP_REG - "10"; -- Decrement by two!
|
||||
when WORD => USP_REG <= USP_REG - "10"; -- Decrement by two.
|
||||
when others => USP_REG <= USP_REG - "100"; -- Decrement by four, (LONG).
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if USP_WR = '1' then
|
||||
USP_REG <= AR_IN_1;
|
||||
elsif SP_ADD_DISPL = '1' and AR_INC = '1' and SBIT = '0' then
|
||||
USP_REG <= USP_REG + DISPLACEMENT + "100"; -- Used for RTD.
|
||||
elsif SP_ADD_DISPL = '1' and SBIT = '0' then
|
||||
USP_REG <= USP_REG + DISPLACEMENT;
|
||||
end if;
|
||||
|
||||
if AR_WR_2 = '1' and AR_PNTR_WB_2 = 7 and MSBIT = "11" then
|
||||
MSP_REG <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
elsif AR_WR_2 = '1' and AR_PNTR_WB_2 = 7 and MSBIT = "01" then
|
||||
ISP_REG <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
elsif AR_WR_2 = '1' and AR_PNTR_WB_2 = 7 then
|
||||
USP_REG <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
end if;
|
||||
end process STACK_POINTERS;
|
||||
|
||||
ADDRESS_REGISTERS: process
|
||||
-- The registers are modeled in a way
|
||||
-- that write and simultaneously increment
|
||||
-- decrement and others are possible for
|
||||
-- different registers.
|
||||
begin
|
||||
--
|
||||
wait until CLK = '1' and CLK' event;
|
||||
|
||||
if RESET = '1' then
|
||||
AR <= (others => (Others => '0'));
|
||||
end if;
|
||||
|
||||
if AR_WR_1 = '1' and AR_PNTR_WB_1 < 7 then
|
||||
AR(AR_PNTR_WB_1) <= AR_IN_1; -- Always written long.
|
||||
end if;
|
||||
|
||||
if AR_INC = '1' and AR_PNTR_1 < 7 then
|
||||
case OP_SIZE is
|
||||
when BYTE => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + '1';
|
||||
when WORD => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + "10";
|
||||
when others => AR(AR_PNTR_1) <= AR(AR_PNTR_1) + "100";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_DEC = '1' and AR_PNTR_1 < 7 then
|
||||
case OP_SIZE is
|
||||
when BYTE => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - '1';
|
||||
when WORD => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - "10";
|
||||
when others => AR(AR_PNTR_1) <= AR(AR_PNTR_1) - "100";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if AR_WR_2 = '1' and AR_PNTR_WB_2 < 7 then
|
||||
AR(AR_PNTR_WB_2) <= AR_IN_2; -- Used for EXG and UNLK.
|
||||
end if;
|
||||
end process ADDRESS_REGISTERS;
|
||||
|
||||
FCODES: process
|
||||
-- These flip flops provide the alternate function
|
||||
-- code registers.
|
||||
variable SFC_REG : std_logic_vector(2 downto 0);
|
||||
variable DFC_REG : std_logic_vector(2 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if DFC_WR = '1' then
|
||||
DFC_REG := AR_IN_1(2 downto 0);
|
||||
end if;
|
||||
--
|
||||
if SFC_WR = '1' then
|
||||
SFC_REG := AR_IN_1(2 downto 0);
|
||||
end if;
|
||||
--
|
||||
DFC <= DFC_REG;
|
||||
SFC <= SFC_REG;
|
||||
end process FCODES;
|
||||
end BEHAVIOR;
|
||||
1264
common/CPU/68K30L/wf68k30L_alu.vhd
Normal file
1264
common/CPU/68K30L/wf68k30L_alu.vhd
Normal file
File diff suppressed because it is too large
Load Diff
879
common/CPU/68K30L/wf68k30L_bus_interface.vhd
Normal file
879
common/CPU/68K30L/wf68k30L_bus_interface.vhd
Normal file
@@ -0,0 +1,879 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K30L IP Core: this is the bus interface. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This module is a 68030 compatible bus controller featuring ----
|
||||
---- all of the 68030 bus interface functionality. ----
|
||||
---- ----
|
||||
---- Bus cycle operation: ----
|
||||
---- A bus cycle is invoked by either asserting RD_REQ, WR_REQ or ----
|
||||
---- OPCODE_REQ. Data is provided immediately or after the ----
|
||||
---- respective bus cycle has finished. The RD_REQ, WR_REQ or ----
|
||||
---- OPCODE_REQ signals should stay asserted until the respective ----
|
||||
---- _RDY signal from the bus controller indicates, that the data ----
|
||||
---- is available. These _RDY signals are strobes. If more than one ----
|
||||
---- read or write request are asserted the same time, RD_REQ is ----
|
||||
---- prioritized over WR_REQ and OPCODE_REQ has lowest priority. ----
|
||||
---- For more information of the signal functionality of the bus ----
|
||||
---- controller entity see also the comments below. ----
|
||||
---- ----
|
||||
---- Remarks: ----
|
||||
---- ----
|
||||
---- Bus arbitration topics: ----
|
||||
---- Additionally to the single wire and the three wire bus arbi- ----
|
||||
---- tration as described in the 68030 hardware manual, the bus ----
|
||||
---- controller also features the two wire arbitration as des- ----
|
||||
---- cribed in the documentation of the 68020 processor. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- Suppress bus faults during RESET instruction.
|
||||
-- Optimized ASn and DSn timing for synchronous RAM.
|
||||
-- DATA_PORT_EN timing optimization.
|
||||
-- BUS_EN is now active except during arbitration.
|
||||
-- Rearanged the DATA_RDY vs. BUS_FLT logic.
|
||||
-- Opted out START_READ and CHK_RD.
|
||||
-- Fixed the faulty bus arbitration logic.
|
||||
-- Rearranged address error handling.
|
||||
-- Revision 2K20A 20200620 WF
|
||||
-- ASn and DSn are not asserted in S0 any more.
|
||||
-- Some modifications to optimize the RETRY logic.
|
||||
-- Fixed a bug in the DSACK_MEM logic (now switches explicitely to "00").
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K30L_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity WF68K30L_BUS_INTERFACE is
|
||||
port (
|
||||
-- System control:
|
||||
CLK : in std_logic; -- System clock.
|
||||
|
||||
-- Adress bus:
|
||||
ADR_IN_P : in std_logic_vector(31 downto 0); -- Logical address line inputs.
|
||||
ADR_OUT_P : out std_logic_vector(31 downto 0); -- Address line outputs.
|
||||
|
||||
-- Function code relevant stuff:
|
||||
FC_IN : in std_logic_vector(2 downto 0); -- Function codes.
|
||||
FC_OUT : out std_logic_vector(2 downto 0); -- Physical function codes (top level entity).
|
||||
|
||||
-- Data bus:
|
||||
DATA_PORT_IN : in std_logic_vector(31 downto 0); -- Data bus input lines (top level entity).
|
||||
DATA_PORT_OUT : out std_logic_vector(31 downto 0); -- Data bus output lines (top level entity).
|
||||
DATA_FROM_CORE : in std_logic_vector(31 downto 0); -- Internal bus input lines.
|
||||
DATA_TO_CORE : out std_logic_vector(31 downto 0); -- Internal data bus output lines.
|
||||
OPCODE_TO_CORE : out std_logic_vector(15 downto 0); -- Internal instruction bus output lines.
|
||||
|
||||
-- Tri state controls:
|
||||
DATA_PORT_EN : out std_logic; -- For the data bus.
|
||||
BUS_EN : out std_logic; -- For all other bus control signals.
|
||||
|
||||
-- Transfer and operation size:
|
||||
SIZE : out std_logic_vector(1 downto 0); -- This is the size information (top level entity).
|
||||
OP_SIZE : in OP_SIZETYPE; -- Used for bus access control.
|
||||
|
||||
-- Control signals:
|
||||
RD_REQ : in bit; -- Read data.
|
||||
WR_REQ : in bit; -- Write data.
|
||||
DATA_RDY : out bit; -- Indicates 'new data available' (this is a strobe).
|
||||
DATA_VALID : out std_logic; -- The data buffer contains valid data when '1'.
|
||||
OPCODE_REQ : in bit; -- Read opcode.
|
||||
OPCODE_RDY : out bit; -- Indicates 'new opcode available' (this is a strobe).
|
||||
OPCODE_VALID : out std_logic; -- The opcode buffer contains valid data when '1'.
|
||||
RMC : in bit; -- Indicates a read modify write operation.
|
||||
BUSY_EXH : in bit;
|
||||
INBUFFER : out std_logic_vector(31 downto 0); -- Used by the exception handler for stack frame type B.
|
||||
OUTBUFFER : out std_logic_vector(31 downto 0); -- Used by the exception handler for stack frame types A and B.
|
||||
SSW_80 : out std_logic_vector(8 downto 0);
|
||||
|
||||
-- Asynchronous bus control signals:
|
||||
DSACKn : in std_logic_vector(1 downto 0); -- Asynchronous bus cycle termination (top level entity).
|
||||
ASn : out std_logic; -- Adress select (top level entity).
|
||||
DSn : out std_logic; -- Data select (top level entity).
|
||||
RWn : out std_logic; -- Hi is read, low = write (top level entity).
|
||||
RMCn : out std_logic; -- Read modify write indicator (top level entity).
|
||||
ECSn : out std_logic; -- External cycle start (top level entity).
|
||||
OCSn : out std_logic; -- Operand cycle start (top level entity).
|
||||
DBENn : out std_logic; -- Data buffer enable (top level entity).
|
||||
|
||||
-- Synchronous bus control:
|
||||
STERMn : in std_logic; -- Synchronous bus cycle termination (top level entity).
|
||||
|
||||
-- Bus arbitration:
|
||||
BRn : in std_logic; -- Bus request (top level entity).
|
||||
BGACKn : in std_logic; -- Bus grant acknowledge (top level entity).
|
||||
BGn : out std_logic; -- Bus grant (top level entity).
|
||||
|
||||
-- Exception signals:
|
||||
RESET_IN : in std_logic; -- System's reset input (top level entity).
|
||||
RESET_STRB : in bit; -- From Core: force external reset.
|
||||
RESET_OUT : out std_logic; -- System's reset output open drain enable.
|
||||
RESET_CPU : out bit; -- Internal reset used for CPU initialization.
|
||||
AVECn : in std_logic; -- Auto interrupt vector input (top level entity).
|
||||
HALTn : in std_logic; -- Halt (top level entity).
|
||||
BERRn : in std_logic; -- Bus error (top level entity).
|
||||
AERR : buffer bit; -- Core internal address error.
|
||||
|
||||
BUS_BSY : out bit -- Bus is busy when '1'.
|
||||
);
|
||||
end entity WF68K30L_BUS_INTERFACE;
|
||||
|
||||
architecture BEHAVIOR of WF68K30L_BUS_INTERFACE is
|
||||
type BUS_CTRL_STATES is (IDLE, START_CYCLE, DATA_C1C4);
|
||||
type ARB_STATES is(IDLE, GRANT, WAIT_RELEASE_3WIRE);
|
||||
type BUS_WIDTH_TYPE is(LONG_32, WORD, BYTE);
|
||||
type TIME_SLICES is (IDLE, S0, S1, S2, S3, S4, S5);
|
||||
signal ADR_10 : std_logic_vector(1 downto 0);
|
||||
signal ADR_OFFSET : std_logic_vector(5 downto 0);
|
||||
signal ADR_OUT_I : std_logic_vector(31 downto 0);
|
||||
signal AERR_I : bit;
|
||||
signal ARB_STATE : ARB_STATES := IDLE;
|
||||
signal AVEC_In : std_logic;
|
||||
signal BGACK_In : std_logic;
|
||||
signal BR_In : std_logic;
|
||||
signal BUS_CTRL_STATE : BUS_CTRL_STATES;
|
||||
signal BUS_CYC_RDY : bit;
|
||||
signal BUS_FLT : std_logic;
|
||||
signal BUS_WIDTH : BUS_WIDTH_TYPE;
|
||||
signal DATA_INMUX : std_logic_vector(31 downto 0);
|
||||
signal DATA_RDY_I : bit;
|
||||
signal DBUFFER : std_logic_vector(31 downto 0);
|
||||
signal DSACK_In : std_logic_vector(1 downto 0);
|
||||
signal DSACK_MEM : std_logic_vector(1 downto 0);
|
||||
signal OCS_INH : bit;
|
||||
signal HALT_In : std_logic;
|
||||
signal HALTED : bit;
|
||||
signal NEXT_ARB_STATE : ARB_STATES;
|
||||
signal NEXT_BUS_CTRL_STATE : BUS_CTRL_STATES;
|
||||
signal OBUFFER : std_logic_vector(15 downto 0);
|
||||
signal OPCODE_ACCESS : bit;
|
||||
signal OPCODE_RDY_I : bit;
|
||||
signal READ_ACCESS : bit;
|
||||
signal RESET_CPU_I : bit;
|
||||
signal RESET_OUT_I : std_logic;
|
||||
signal RETRY : bit;
|
||||
signal SIZE_D : std_logic_vector(1 downto 0);
|
||||
signal SIZE_I : std_logic_vector(1 downto 0);
|
||||
signal SIZE_N : std_logic_vector(2 downto 0) := "000";
|
||||
signal SLICE_CNT_N : std_logic_vector(2 downto 0);
|
||||
signal SLICE_CNT_P : std_logic_vector(2 downto 0);
|
||||
signal STERM_Dn : std_logic;
|
||||
signal T_SLICE : TIME_SLICES;
|
||||
signal WAITSTATES : bit;
|
||||
signal WP_BUFFER : std_logic_vector(31 downto 0);
|
||||
signal WRITE_ACCESS : bit;
|
||||
begin
|
||||
P_SYNC: process(CLK)
|
||||
-- These flip flops synchronize external signals on the negative clock edge. This
|
||||
-- meets the requirement of sampling these signals in the end of S2 for asynchronous
|
||||
-- bus access. Be aware, that we have to buffer the RETRY signal to prevent the bus
|
||||
-- controller of spurious or timing critical BERRn and/or HALTn signals. The logic
|
||||
-- for BUS_FLT and RETRY is coded in a way that we have a bus error or a retry
|
||||
-- condition but not both at the same time.
|
||||
-- Note: there is no need to synchronize the already synchronous bus control signals
|
||||
variable BERR_VARn : std_logic;
|
||||
variable HALT_VARn : std_logic;
|
||||
begin
|
||||
if CLK = '0' and CLK' event then
|
||||
DSACK_In <= DSACKn;
|
||||
BR_In <= BRn;
|
||||
BGACK_In <= BGACKn;
|
||||
AVEC_In <= AVECn;
|
||||
HALT_VARn := HALTn;
|
||||
BERR_VARn := BERRn;
|
||||
end if;
|
||||
--
|
||||
if CLK = '1' and CLK' event then
|
||||
if BUS_CTRL_STATE = START_CYCLE then
|
||||
AERR <= AERR_I; -- AERR_I is valid in this state.
|
||||
else
|
||||
AERR <= '0';
|
||||
end if;
|
||||
--
|
||||
HALT_In <= HALTn or HALT_VARn;
|
||||
--
|
||||
if BUS_CTRL_STATE = DATA_C1C4 then
|
||||
if (BERRn nand BERR_VARn) = '1' and (HALTn or HALT_VARn) = '0' and SIZE_N /= "000" then
|
||||
RETRY <= '1';
|
||||
elsif T_SLICE = IDLE and (BERRn = '1' and HALTn = '1' and BERR_VARn = '1' and HALT_VARn = '1') then
|
||||
RETRY <= '0';
|
||||
elsif RETRY = '0' then
|
||||
BUS_FLT <= (BERRn nor BERR_VARn) and HALT_VARn and HALTn;
|
||||
end if;
|
||||
else
|
||||
BUS_FLT <= '0';
|
||||
RETRY <= '0';
|
||||
end if;
|
||||
--
|
||||
STERM_Dn <= STERMn; -- Delay to update the SIZE_N and SIZE_M before BUS_CYC_RDY is asserted.
|
||||
end if;
|
||||
end process P_SYNC;
|
||||
|
||||
ACCESSTYPE: process
|
||||
-- This logic stores the execution unit control
|
||||
-- signals during the current bus access. This is
|
||||
-- important for the bus control signals to be
|
||||
-- stable during the complete bus access.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUS_CTRL_STATE = START_CYCLE then
|
||||
if READ_ACCESS = '1' or WRITE_ACCESS = '1' or OPCODE_ACCESS = '1' then
|
||||
null; -- Do not start either new cycle.
|
||||
elsif RD_REQ = '1' then
|
||||
READ_ACCESS <= '1';
|
||||
elsif WR_REQ = '1' then
|
||||
WRITE_ACCESS <= '1';
|
||||
elsif OPCODE_REQ = '1' then
|
||||
OPCODE_ACCESS <= '1';
|
||||
end if;
|
||||
elsif AERR = '1' then -- Reject due to address error.
|
||||
READ_ACCESS <= '0';
|
||||
WRITE_ACCESS <= '0';
|
||||
OPCODE_ACCESS <= '0';
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and NEXT_BUS_CTRL_STATE = IDLE and SIZE_N = "000" then
|
||||
READ_ACCESS <= '0';
|
||||
WRITE_ACCESS <= '0';
|
||||
OPCODE_ACCESS <= '0';
|
||||
end if;
|
||||
end process ACCESSTYPE;
|
||||
|
||||
P_DF: process
|
||||
-- This is the logic which provides the fault flags for data cycles and
|
||||
-- input and output buffer information.
|
||||
variable SIZEVAR : std_logic_vector(1 downto 0) := "00";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUSY_EXH = '0' then -- Do not alter during exception processing.
|
||||
case OP_SIZE is
|
||||
when LONG => SIZEVAR := "10";
|
||||
when WORD => SIZEVAR := "01";
|
||||
when BYTE => SIZEVAR := "00";
|
||||
end case;
|
||||
--
|
||||
if BUS_CTRL_STATE = START_CYCLE and NEXT_BUS_CTRL_STATE = DATA_C1C4 then
|
||||
SSW_80 <= To_StdLogicVector('0' & RMC & not WR_REQ) & SIZEVAR & '0' & FC_IN;
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and (READ_ACCESS = '1' or WRITE_ACCESS = '1') and BUS_FLT = '1' then
|
||||
SSW_80(8) <= '1';
|
||||
end if;
|
||||
|
||||
OUTBUFFER <= WP_BUFFER; -- Used for exception stack frame type A and B.
|
||||
INBUFFER <= DATA_INMUX; -- Used for exception stack frame type B.
|
||||
end if;
|
||||
end process P_DF;
|
||||
|
||||
WRITEBACK_INFO: process
|
||||
-- This registers stor writeback relevant information.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUS_CTRL_STATE = IDLE and NEXT_BUS_CTRL_STATE = START_CYCLE then -- Freeze during a bus cycle.
|
||||
WP_BUFFER <= DATA_FROM_CORE;
|
||||
end if;
|
||||
end process WRITEBACK_INFO;
|
||||
|
||||
P_BUSWIDTH: process
|
||||
-- These flip flops store the bus width information
|
||||
-- during the current bus access.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if BUS_CTRL_STATE = IDLE then
|
||||
DSACK_MEM <= "11";
|
||||
elsif DSACK_In /= "11" then
|
||||
DSACK_MEM <= DSACK_In;
|
||||
end if;
|
||||
end process P_BUSWIDTH;
|
||||
|
||||
BUS_WIDTH <= WORD when DSACKn = "01" or DSACK_MEM = "01" else
|
||||
BYTE when DSACKn = "10" or DSACK_MEM = "10" else
|
||||
LONG_32; -- Also used during synchronous cycles.
|
||||
|
||||
BUS_BSY <= '1' when BUS_CTRL_STATE /= IDLE else '0';
|
||||
|
||||
PARTITIONING: process
|
||||
-- This logic gives information about the remaining bus cycles The initial
|
||||
-- size is sampled right before the bus acces. This requires the RD_REQ
|
||||
-- and WR_REQ signals to work on the positive clock edge.
|
||||
variable RESTORE_VAR : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
|
||||
if BUS_CTRL_STATE = DATA_C1C4 and T_SLICE = S1 then -- On positive clock edge.
|
||||
RESTORE_VAR := SIZE_N; -- We need this initial value for early RETRY.
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
SIZE_N <= "000";
|
||||
elsif BUS_CTRL_STATE /= DATA_C1C4 and NEXT_BUS_CTRL_STATE = DATA_C1C4 then
|
||||
if RD_REQ = '1' or WR_REQ = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => SIZE_N <= "100";
|
||||
when WORD => SIZE_N <= "010";
|
||||
when BYTE => SIZE_N <= "001";
|
||||
end case;
|
||||
else -- OPCODE_ACCESS.
|
||||
SIZE_N <= "010"; -- WORD.
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Decrementing the size information:
|
||||
-- In this logic all permutations are considered. This allows a dynamically changing bus size.
|
||||
if RETRY = '1' then
|
||||
SIZE_N <= RESTORE_VAR;
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and ((T_SLICE = S1 and STERMn = '0') or (T_SLICE = S3 and WAITSTATES = '0')) then -- On positive clock edge.
|
||||
if BUS_WIDTH = LONG_32 and SIZE_N > x"3" and ADR_OUT_I(1 downto 0) = "01" then
|
||||
SIZE_N <= SIZE_N - "11";
|
||||
elsif BUS_WIDTH = LONG_32 and SIZE_N > x"2" and ADR_OUT_I(1 downto 0) = "10" then
|
||||
SIZE_N <= SIZE_N - "10";
|
||||
elsif BUS_WIDTH = LONG_32 and SIZE_N > x"1" and ADR_OUT_I(1 downto 0) = "11" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif BUS_WIDTH = LONG_32 then
|
||||
SIZE_N <= "000";
|
||||
--
|
||||
elsif BUS_WIDTH = WORD and ADR_OUT_I(1 downto 0) = "11" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif BUS_WIDTH = WORD and ADR_OUT_I(1 downto 0) = "01" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif BUS_WIDTH = WORD and SIZE_N = "001" then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
elsif BUS_WIDTH = WORD then
|
||||
SIZE_N <= SIZE_N - "10";
|
||||
--
|
||||
elsif BUS_WIDTH = BYTE then
|
||||
SIZE_N <= SIZE_N - '1';
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
if (BUS_FLT = '1' and HALT_In = '1') then -- Abort bus cycle.
|
||||
SIZE_N <= "000";
|
||||
end if;
|
||||
end process PARTITIONING;
|
||||
|
||||
SIZE_I <= SIZE_N(1 downto 0) when T_SLICE = S0 or T_SLICE = S1 else SIZE_D;
|
||||
SIZE <= SIZE_I;
|
||||
|
||||
P_DELAY: process
|
||||
-- This delay is responsible for a correct SIZE_I information. Use this, if the
|
||||
-- process PARTITIONING works on the positive clock edge. The SIZE_I information
|
||||
-- is delayed by half a clock cycle to be valid just in time of sampling the INMUX.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
SIZE_D <= SIZE_N(1 downto 0);
|
||||
end process P_DELAY;
|
||||
|
||||
BUS_STATE_REG: process
|
||||
-- This is the bus controller's state register.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
BUS_CTRL_STATE <= NEXT_BUS_CTRL_STATE;
|
||||
end process BUS_STATE_REG;
|
||||
|
||||
BUS_CTRL_DEC: process(ADR_IN_P, ADR_OUT_I, ARB_STATE, BGACK_In, BR_In, BUS_CTRL_STATE, BUS_CYC_RDY, BUS_FLT, HALT_In,
|
||||
OPCODE_ACCESS, OPCODE_REQ, RD_REQ, READ_ACCESS, RESET_CPU_I, RMC, SIZE_N, WR_REQ, WRITE_ACCESS)
|
||||
-- This is the bus controller's state machine decoder. A SIZE_N count of "000" means that all bytes
|
||||
-- to be transfered. After a bus transfer a value of x"0" indicates that no further bytes are required
|
||||
-- for a bus transfer.
|
||||
begin
|
||||
case BUS_CTRL_STATE is
|
||||
when IDLE =>
|
||||
if RESET_CPU_I = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Reset condition (bus cycle terminated).
|
||||
elsif HALT_In = '0' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- This is the 'HALT' condition.
|
||||
elsif (BR_In = '0' and RMC = '0') or ARB_STATE /= IDLE or BGACK_In = '0' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Arbitration, wait!
|
||||
elsif RD_REQ = '1' and SIZE_N = "000" then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- New read cycle.
|
||||
elsif WR_REQ = '1' and SIZE_N = "000" then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- New write cycle.
|
||||
elsif OPCODE_REQ = '1' and SIZE_N = "000" then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- New read cycle.
|
||||
elsif READ_ACCESS = '1' or WRITE_ACCESS = '1' or OPCODE_ACCESS = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= START_CYCLE; -- Pending (split) bus cycles.
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
end if;
|
||||
when START_CYCLE =>
|
||||
if RD_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
elsif WR_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
elsif OPCODE_REQ = '1' and ADR_IN_P(0) = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Abort due to address error.
|
||||
elsif OPCODE_REQ = '1' and ADR_IN_P(0) = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE; -- Abort due to address error.
|
||||
elsif OPCODE_REQ = '1' then
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
end if;
|
||||
when DATA_C1C4 =>
|
||||
if BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
NEXT_BUS_CTRL_STATE <= IDLE;
|
||||
else
|
||||
NEXT_BUS_CTRL_STATE <= DATA_C1C4;
|
||||
end if;
|
||||
end case;
|
||||
end process BUS_CTRL_DEC;
|
||||
|
||||
P_ADR_OFFS: process
|
||||
-- This process provides a temporary address offset during
|
||||
-- bus access.
|
||||
variable OFFSET_VAR : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET_CPU_I = '1' then
|
||||
OFFSET_VAR := "000";
|
||||
elsif (T_SLICE = S2 and STERMn = '0') or T_SLICE = S3 then
|
||||
case BUS_WIDTH is
|
||||
when LONG_32 =>
|
||||
case ADR_OUT_I(1 downto 0) is
|
||||
when "11" => OFFSET_VAR := "001";
|
||||
when "10" => OFFSET_VAR := "010";
|
||||
when "01" => OFFSET_VAR := "011";
|
||||
when others => OFFSET_VAR := "100";
|
||||
end case;
|
||||
when WORD =>
|
||||
case ADR_OUT_I(1 downto 0) is
|
||||
when "01" | "11" => OFFSET_VAR := "001";
|
||||
when others => OFFSET_VAR := "010";
|
||||
end case;
|
||||
when BYTE =>
|
||||
OFFSET_VAR := "001";
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
ADR_OFFSET <= (others => '0');
|
||||
elsif RETRY = '1' then
|
||||
null; -- Do not update if there is a retry cycle.
|
||||
elsif BUS_CTRL_STATE /= IDLE and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
ADR_OFFSET <= (others => '0');
|
||||
elsif BUS_CYC_RDY = '1' then
|
||||
ADR_OFFSET <= ADR_OFFSET + OFFSET_VAR;
|
||||
end if;
|
||||
end process P_ADR_OFFS;
|
||||
|
||||
ADR_OUT_I <= ADR_IN_P + ADR_OFFSET;
|
||||
ADR_OUT_P <= ADR_OUT_I;
|
||||
|
||||
P_ADR_10: process
|
||||
-- This logic is registered to enhance the system performance concerning fmax.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
ADR_10 <= ADR_OUT_I(1 downto 0);
|
||||
end process P_ADR_10;
|
||||
|
||||
-- Address and bus errors:
|
||||
AERR_I <= '1' when BUS_CTRL_STATE = START_CYCLE and OPCODE_REQ = '1' and RD_REQ = '0' and WR_REQ = '0' and ADR_IN_P(0) = '1' else '0';
|
||||
|
||||
FC_OUT <= FC_IN;
|
||||
|
||||
-- The output multiplexer is as follows:
|
||||
-- SIZE ADR Bytes (L = long word port, W = word port, B = Byte port, x = not used by either port)
|
||||
-- 00 00 3 (L, W, B) 2 (L, W ) 1 (L ) 0 (L )
|
||||
-- 00 01 3 ( B) 3 (L, W ) 2 (L ) 1 (L )
|
||||
-- 00 10 3 ( W, B) 2 ( W ) 3 (L ) 2 (L )
|
||||
-- 00 11 3 ( B) 2 ( W ) -----x----- 0 (L )
|
||||
-- 11 00 2 (L, W, B) 1 (L, W ) 0 (L ) -----x-----
|
||||
-- 11 01 2 ( B) 2 (L, W ) 1 (L ) 0 (L )
|
||||
-- 11 10 1 ( W, B) 0 ( W ) 1 (L ) 0 (L )
|
||||
-- 11 11 1 ( B) 1 ( W ) -----x----- 1 (L )
|
||||
-- 10 00 1 (L, W, B) 0 (L, W ) -----x----- -----x-----
|
||||
-- 10 01 1 ( B) 1 (L, W ) 0 (L ) -----x-----
|
||||
-- 10 10 1 ( W, B) 0 ( W ) 1 (L ) 0 (L )
|
||||
-- 10 11 1 ( B) 1 ( W ) -----x----- 1 (L )
|
||||
-- 01 00 0 (L, W, B) -----x----- -----x----- -----x-----
|
||||
-- 01 01 0 ( B) 0 (L, W ) -----x----- -----x-----
|
||||
-- 01 10 0 ( W, B) -----x----- 0 (L ) -----x-----
|
||||
-- 01 11 0 ( B) 0 ( W ) -----x----- 0 (L )
|
||||
|
||||
DATA_PORT_OUT <= -- Data output multiplexer.
|
||||
-- LONG:
|
||||
WP_BUFFER(31 downto 0) when SIZE_I = "00" and ADR_OUT_I(1 downto 0) = "00" else
|
||||
WP_BUFFER(31 downto 24) & WP_BUFFER(31 downto 8) when SIZE_I = "00" and ADR_OUT_I(1 downto 0) = "01" else
|
||||
WP_BUFFER(31 downto 16) & WP_BUFFER(31 downto 16) when SIZE_I = "00" and ADR_OUT_I(1 downto 0) = "10" else
|
||||
WP_BUFFER(31 downto 24) & WP_BUFFER(31 downto 16) & WP_BUFFER(31 downto 24) when SIZE_I = "00" and ADR_OUT_I(1 downto 0) = "11" else
|
||||
-- 3 bytes:
|
||||
WP_BUFFER(23 downto 0) & WP_BUFFER(31 downto 24) when SIZE_I = x"3" and ADR_OUT_I(1 downto 0) = "00" else
|
||||
WP_BUFFER(23 downto 16) & WP_BUFFER(23 downto 0) when SIZE_I = "11" and ADR_OUT_I(1 downto 0) = "01" else
|
||||
WP_BUFFER(23 downto 8) & WP_BUFFER(23 downto 8) when SIZE_I = "11" and ADR_OUT_I(1 downto 0) = "10" else
|
||||
WP_BUFFER(23 downto 16) & WP_BUFFER(23 downto 8) & WP_BUFFER(23 downto 16) when SIZE_I = "11" and ADR_OUT_I(1 downto 0) = "11" else
|
||||
-- Word:
|
||||
WP_BUFFER(15 downto 0) & WP_BUFFER(15 downto 0) when SIZE_I = "10" and ADR_OUT_I(1 downto 0) = "00" else
|
||||
WP_BUFFER(15 downto 8) & WP_BUFFER(15 downto 0) & WP_BUFFER(15 downto 8) when SIZE_I = "10" and ADR_OUT_I(1 downto 0) = "01" else
|
||||
WP_BUFFER(15 downto 0) & WP_BUFFER(15 downto 0) when SIZE_I = "10" and ADR_OUT_I(1 downto 0) = "10" else
|
||||
WP_BUFFER(15 downto 8) & WP_BUFFER(15 downto 0) & WP_BUFFER(15 downto 8) when SIZE_I = "10" and ADR_OUT_I(1 downto 0) = "11" else
|
||||
-- Byte:
|
||||
WP_BUFFER(7 downto 0) & WP_BUFFER(7 downto 0) & WP_BUFFER(7 downto 0) & WP_BUFFER(7 downto 0); -- SIZE = "01".
|
||||
|
||||
IN_MUX: process
|
||||
-- This is the input multiplexer which can handle up to four bytes.
|
||||
begin
|
||||
wait until CLK = '0' and CLK' event;
|
||||
--
|
||||
if ((T_SLICE = S2 or T_SLICE = S3) and STERMn = '0') or T_SLICE = S4 then
|
||||
case BUS_WIDTH is
|
||||
when BYTE =>
|
||||
case SIZE_I is
|
||||
when "00" => DATA_INMUX(31 downto 24) <= DATA_PORT_IN(31 downto 24); -- LONG.
|
||||
when "11" => DATA_INMUX(23 downto 16) <= DATA_PORT_IN(31 downto 24); -- Three bytes.
|
||||
when "10" => DATA_INMUX(15 downto 8) <= DATA_PORT_IN(31 downto 24); -- Word.
|
||||
when others => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(31 downto 24); -- Byte.
|
||||
end case;
|
||||
when WORD =>
|
||||
case SIZE_I is
|
||||
when "01" => -- Byte.
|
||||
case ADR_10 is
|
||||
when "00" | "10" => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(31 downto 24);
|
||||
when others => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(23 downto 16); -- "01", "11".
|
||||
end case;
|
||||
when "10" => -- Word.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(15 downto 0) <= DATA_PORT_IN(31 downto 16);
|
||||
when "01" => DATA_INMUX(15 downto 8) <= DATA_PORT_IN(23 downto 16);
|
||||
when "10" => DATA_INMUX(15 downto 0) <= DATA_PORT_IN(31 downto 16);
|
||||
when others => DATA_INMUX(15 downto 8) <= DATA_PORT_IN(23 downto 16); -- "11".
|
||||
end case;
|
||||
when "11" => -- Three bytes.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(23 downto 8) <= DATA_PORT_IN(31 downto 16);
|
||||
when "01" => DATA_INMUX(23 downto 16) <= DATA_PORT_IN(23 downto 16);
|
||||
when "10" => DATA_INMUX(23 downto 8) <= DATA_PORT_IN(31 downto 16);
|
||||
when others => DATA_INMUX(23 downto 16) <= DATA_PORT_IN(23 downto 16); -- "11".
|
||||
end case;
|
||||
when others => -- "00" = LONG.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(31 downto 16) <= DATA_PORT_IN(31 downto 16);
|
||||
when "01" => DATA_INMUX(31 downto 24) <= DATA_PORT_IN(23 downto 16);
|
||||
when "10" => DATA_INMUX(31 downto 16) <= DATA_PORT_IN(31 downto 16);
|
||||
when others => DATA_INMUX(31 downto 24) <= DATA_PORT_IN(23 downto 16); -- "11".
|
||||
end case;
|
||||
end case;
|
||||
when LONG_32 =>
|
||||
case SIZE_I is
|
||||
when "01" => -- Byte.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(31 downto 24);
|
||||
when "01" => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(23 downto 16);
|
||||
when "10" => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(15 downto 8);
|
||||
when others => DATA_INMUX(7 downto 0) <= DATA_PORT_IN(7 downto 0); -- "11".
|
||||
end case;
|
||||
when "10" => -- Word.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(15 downto 0) <= DATA_PORT_IN(31 downto 16);
|
||||
when "01" => DATA_INMUX(15 downto 0) <= DATA_PORT_IN(23 downto 8);
|
||||
when "10" => DATA_INMUX(15 downto 0) <= DATA_PORT_IN(15 downto 0);
|
||||
when others => DATA_INMUX(15 downto 8) <= DATA_PORT_IN(7 downto 0); -- "11".
|
||||
end case;
|
||||
when "11" => -- Three bytes.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(23 downto 0) <= DATA_PORT_IN(31 downto 8);
|
||||
when "01" => DATA_INMUX(23 downto 0) <= DATA_PORT_IN(23 downto 0);
|
||||
when "10" => DATA_INMUX(23 downto 8) <= DATA_PORT_IN(15 downto 0);
|
||||
when others => DATA_INMUX(23 downto 16) <= DATA_PORT_IN(7 downto 0); -- "11".
|
||||
end case;
|
||||
when others => -- "00" = LONG.
|
||||
case ADR_10 is
|
||||
when "00" => DATA_INMUX(31 downto 0) <= DATA_PORT_IN(31 downto 0);
|
||||
when "01" => DATA_INMUX(31 downto 8) <= DATA_PORT_IN(23 downto 0);
|
||||
when "10" => DATA_INMUX(31 downto 16) <= DATA_PORT_IN(15 downto 0);
|
||||
when others => DATA_INMUX(31 downto 24) <= DATA_PORT_IN(7 downto 0); -- "11".
|
||||
end case;
|
||||
end case;
|
||||
end case;
|
||||
end if;
|
||||
end process IN_MUX;
|
||||
|
||||
VALIDATION: process
|
||||
-- These flip flops detect a fault during the read operation over one or
|
||||
-- several bytes or during the write operation.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
OPCODE_VALID <= '1';
|
||||
elsif OPCODE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_FLT = '1' then
|
||||
OPCODE_VALID <= '0';
|
||||
elsif OPCODE_RDY_I = '1' then
|
||||
OPCODE_VALID <= '1'; -- Reset after use, TRAP_BERR is asserted during DATA_RDY.
|
||||
end if;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
DATA_VALID <= '1';
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and BUS_FLT = '1' then
|
||||
DATA_VALID <= '0';
|
||||
elsif DATA_RDY_I = '1' then
|
||||
DATA_VALID <= '1'; -- Reset after use, TRAP_BERR is asserted during DATA_RDY.
|
||||
end if;
|
||||
end process VALIDATION;
|
||||
|
||||
PREFETCH_BUFFERS: process
|
||||
-- These are the data and the operation code input registers. After a last read to the registered
|
||||
-- input multiplexer, the respective data is copied from the input multiplexer to these buffers.
|
||||
-- The opcode buffer is always written with 32 bit data. The data buffers may contain invalid bytes
|
||||
-- in case of word or byte data size.
|
||||
variable DBUFFER_MEM : std_logic_vector(31 downto 8) := x"000000";
|
||||
variable RDY_VAR : bit := '0';
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
OPCODE_RDY_I <= '0'; -- This is a strobe.
|
||||
DATA_RDY_I <= '0'; -- This is a strobe.
|
||||
--
|
||||
-- The following variable is responsible, that the _RDY signals are
|
||||
-- always strobes.
|
||||
if DATA_RDY_I = '1' or OPCODE_RDY_I = '1' then
|
||||
RDY_VAR := '0';
|
||||
elsif BUS_CTRL_STATE = START_CYCLE then
|
||||
RDY_VAR := '1';
|
||||
end if;
|
||||
-- Opcode cycle:
|
||||
if AERR_I = '1' then
|
||||
OPCODE_RDY_I <= '1';
|
||||
elsif OPCODE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
-- Instruction prefetches are always long and on word boundaries.
|
||||
-- The word is available after the first word read.
|
||||
OBUFFER <= DATA_INMUX(15 downto 0);
|
||||
OPCODE_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
-- Data cycle:
|
||||
if WRITE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' and SIZE_N = "000" then
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
elsif READ_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 and BUS_CYC_RDY = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG =>
|
||||
if SIZE_N = "000" then
|
||||
DBUFFER <= DATA_INMUX;
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
when WORD =>
|
||||
if SIZE_N = "000" then
|
||||
DBUFFER <= x"0000" & DATA_INMUX(15 downto 0);
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
end if;
|
||||
when BYTE => -- Byte always aligned.
|
||||
DATA_RDY_I <= RDY_VAR;
|
||||
DBUFFER <= x"000000" & DATA_INMUX(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
end process PREFETCH_BUFFERS;
|
||||
|
||||
DATA_RDY <= DATA_RDY_I;
|
||||
OPCODE_RDY <= OPCODE_RDY_I;
|
||||
|
||||
DATA_TO_CORE <= DBUFFER;
|
||||
OPCODE_TO_CORE <= OBUFFER;
|
||||
|
||||
WAITSTATES <= '0' when T_SLICE /= S3 else
|
||||
'1' when RESET_OUT_I = '1' else -- No bus fault during RESET instruction.
|
||||
'0' when DSACK_In /= "11" else -- For asynchronous bus cycles.
|
||||
'0' when STERMn = '0' else -- For synchronous bus cycles.
|
||||
'0' when ADR_IN_P(19 downto 16) = x"F" and AVEC_In = '0' else -- Interrupt acknowledge space cycle.
|
||||
'0' when BUS_FLT = '1' else -- In case of a bus error;
|
||||
'0' when RESET_CPU_I = '1' else '1'; -- A CPU reset terminates the current bus cycle.
|
||||
|
||||
SLICES: process(CLK)
|
||||
-- This process provides the central timing for the read, write and read modify write cycle as also
|
||||
-- for the bus arbitration procedure. Be aware, that the bus controller state machine changes it's
|
||||
-- state on the positive clock edge. The BUS_CYC_RDY signal is asserted during S3 or S5. So the
|
||||
-- slice counter working on the positive clock edge may change it's state.
|
||||
begin
|
||||
if CLK = '1' and CLK' event then
|
||||
if BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Init.
|
||||
elsif RETRY = '1' then
|
||||
SLICE_CNT_P <= "111"; -- Stay in IDLE, go to IDLE.
|
||||
elsif BUS_CTRL_STATE /= IDLE and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Init.
|
||||
elsif SLICE_CNT_P = "001" and STERMn = '0' then -- Synchronous cycle.
|
||||
SLICE_CNT_P <= "110"; -- Ready.
|
||||
elsif SLICE_CNT_P = "010" then
|
||||
if RETRY = '1' then
|
||||
SLICE_CNT_P <= "111"; -- Go IDLE.
|
||||
elsif BUS_CTRL_STATE = DATA_C1C4 and NEXT_BUS_CTRL_STATE = IDLE then
|
||||
SLICE_CNT_P <= "111"; -- Ready.
|
||||
else
|
||||
SLICE_CNT_P <= "000"; -- Go on.
|
||||
end if;
|
||||
elsif WAITSTATES = '0' then
|
||||
SLICE_CNT_P <= SLICE_CNT_P + '1'; -- Cycle active.
|
||||
end if;
|
||||
end if;
|
||||
--
|
||||
if CLK = '0' and CLK' event then
|
||||
SLICE_CNT_N <= SLICE_CNT_P; -- Follow the P counter.
|
||||
end if;
|
||||
end process SLICES;
|
||||
|
||||
T_SLICE <= S0 when SLICE_CNT_P = "000" and SLICE_CNT_N = "111" else
|
||||
S1 when SLICE_CNT_P = "000" and SLICE_CNT_N = "000" else
|
||||
S2 when SLICE_CNT_P = "001" and SLICE_CNT_N = "000" else
|
||||
S3 when SLICE_CNT_P = "001" and SLICE_CNT_N = "001" else
|
||||
S4 when SLICE_CNT_P = "010" and SLICE_CNT_N = "001" else
|
||||
S5 when SLICE_CNT_P = "010" and SLICE_CNT_N = "010" else
|
||||
S3 when SLICE_CNT_P = "110" else -- This is a waitstate cycle for synchronous bus cycles to update SIZE_N before latching data.
|
||||
S0 when SLICE_CNT_P = "000" and SLICE_CNT_N = "010" else IDLE; -- Rollover from state S5 to S0.
|
||||
|
||||
P_OCS: process
|
||||
-- This flip flop enables the output of the OCSn signal for
|
||||
-- the first bus cycle and locks OCSn for all other bus cycles.
|
||||
-- ECSn is locked only during cache burst access.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if BUS_CTRL_STATE = START_CYCLE and NEXT_BUS_CTRL_STATE /= IDLE then
|
||||
OCS_INH <= '0';
|
||||
elsif BUS_CYC_RDY = '1' and RETRY = '0' then -- No inhibit if first portion results in a retry cycle.
|
||||
OCS_INH <= '1';
|
||||
end if;
|
||||
end process P_OCS;
|
||||
|
||||
-- Bus control signals:
|
||||
RWn <= '0' when WRITE_ACCESS = '1' and BUS_CTRL_STATE = DATA_C1C4 else '1';
|
||||
RMCn <= '0' when RMC = '1' else '1';
|
||||
ECSn <= '0' when T_SLICE = S0 else '1';
|
||||
OCSn <= '0' when T_SLICE = S0 and OCS_INH = '0' else '1';
|
||||
ASn <= '0' when T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1';
|
||||
DSn <= '0' when (T_SLICE = S3 or T_SLICE = S4 or T_SLICE = S5) and WRITE_ACCESS = '1' else -- Write.
|
||||
'0' when T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1'; -- Read.
|
||||
|
||||
DBENn <= '0' when (T_SLICE = S1 or T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 or T_SLICE = S5) and WRITE_ACCESS = '1' else -- Write.
|
||||
'0' when T_SLICE = S2 or T_SLICE = S3 or T_SLICE = S4 else '1'; -- Read.
|
||||
|
||||
-- Bus tri state controls:
|
||||
BUS_EN <= '1' when ARB_STATE = IDLE and RESET_CPU_I = '0' else '0';
|
||||
DATA_PORT_EN <= '1' when WRITE_ACCESS = '1' and ARB_STATE = IDLE and RESET_CPU_I = '0' else '0';
|
||||
|
||||
-- Progress controls:
|
||||
BUS_CYC_RDY <= '0' when RETRY = '1' else
|
||||
'1' when STERM_Dn = '0' else -- Synchronous cycles. STERMn delayed to update the SIZE_N and SIZE_M before BUS_CYC_RDY is asserted.
|
||||
'1' when T_SLICE = S5 else '0'; -- Asynchronous cycles.
|
||||
|
||||
-- Bus arbitration:
|
||||
ARB_REG: process
|
||||
-- This is the arbiters state register.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_CPU_I = '1' then
|
||||
ARB_STATE <= IDLE;
|
||||
else
|
||||
ARB_STATE <= NEXT_ARB_STATE;
|
||||
end if;
|
||||
end process ARB_REG;
|
||||
|
||||
ARB_DEC: process(ARB_STATE, BGACK_In, BR_In, BUS_CTRL_STATE, RETRY, RMC)
|
||||
-- This is the bus arbitration state machine's decoder. It can handle single-, two-
|
||||
-- or three wire arbitration. The two wire arbitration is done in the GRANT state
|
||||
-- by negating BRn.
|
||||
begin
|
||||
case ARB_STATE is
|
||||
when IDLE =>
|
||||
if RMC = '1' and RETRY = '0' then
|
||||
NEXT_ARB_STATE <= IDLE; -- Arbitration in RETRY operation is possible.
|
||||
elsif BGACK_In = '0' and BUS_CTRL_STATE = IDLE then -- This is the single wire arbitration.
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
elsif BR_In = '0' and BUS_CTRL_STATE = IDLE then -- Wait until the bus is free.
|
||||
NEXT_ARB_STATE <= GRANT;
|
||||
else
|
||||
NEXT_ARB_STATE <= IDLE;
|
||||
end if;
|
||||
when GRANT =>
|
||||
if BGACK_In = '0' then
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
elsif BR_In = '1' then
|
||||
NEXT_ARB_STATE <= IDLE; -- Resume normal operation.
|
||||
else
|
||||
NEXT_ARB_STATE <= GRANT;
|
||||
end if;
|
||||
when WAIT_RELEASE_3WIRE =>
|
||||
if BGACK_In = '1' and BR_In = '0' then
|
||||
NEXT_ARB_STATE <= GRANT; -- Re-enter new arbitration.
|
||||
elsif BGACK_In = '1' then
|
||||
NEXT_ARB_STATE <= IDLE;
|
||||
else
|
||||
NEXT_ARB_STATE <= WAIT_RELEASE_3WIRE;
|
||||
end if;
|
||||
end case;
|
||||
end process ARB_DEC;
|
||||
|
||||
BGn <= '0' when ARB_STATE = GRANT else '1';
|
||||
|
||||
-- RESET logic:
|
||||
RESET_FILTER: process
|
||||
-- This process filters the incoming reset pin.
|
||||
-- If RESET_IN and HALT_In are asserted together for longer
|
||||
-- than 10 clock cycles over the execution of a CPU reset
|
||||
-- command, the CPU reset is released.
|
||||
variable STARTUP : boolean := false;
|
||||
variable TMP : std_logic_vector(3 downto 0) := x"0";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_IN = '1' and HALT_In = '0' and RESET_OUT_I = '0' and TMP < x"F" then
|
||||
TMP := TMP + '1';
|
||||
elsif RESET_IN = '0' or HALT_In = '1' or RESET_OUT_I = '1' then
|
||||
TMP := x"0";
|
||||
end if;
|
||||
if TMP > x"A" then
|
||||
RESET_CPU_I <= '1'; -- Release internal reset.
|
||||
STARTUP := true;
|
||||
elsif STARTUP = false then
|
||||
RESET_CPU_I <= '1';
|
||||
else
|
||||
RESET_CPU_I <= '0';
|
||||
end if;
|
||||
end process RESET_FILTER;
|
||||
|
||||
RESET_TIMER: process
|
||||
-- This logic is responsible for the assertion of the
|
||||
-- reset output for 512 clock cycles, during the reset
|
||||
-- command. The LOCK variable avoids re-initialisation
|
||||
-- of the counter in the case that the RESET_EN is no
|
||||
-- strobe.
|
||||
variable TMP : std_logic_vector(8 downto 0) := "000000000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
--
|
||||
if RESET_STRB = '1' or TMP > "000000000" then
|
||||
RESET_OUT_I <= '1';
|
||||
else
|
||||
RESET_OUT_I <= '0';
|
||||
end if;
|
||||
--
|
||||
if RESET_STRB = '1' then
|
||||
TMP := "111111111"; -- 512 initial value.
|
||||
elsif TMP > "000000000" then
|
||||
TMP := TMP - '1';
|
||||
end if;
|
||||
end process RESET_TIMER;
|
||||
|
||||
RESET_CPU <= RESET_CPU_I;
|
||||
RESET_OUT <= RESET_OUT_I;
|
||||
end BEHAVIOR;
|
||||
2553
common/CPU/68K30L/wf68k30L_control.vhd
Normal file
2553
common/CPU/68K30L/wf68k30L_control.vhd
Normal file
File diff suppressed because it is too large
Load Diff
137
common/CPU/68K30L/wf68k30L_data_registers.vhd
Normal file
137
common/CPU/68K30L/wf68k30L_data_registers.vhd
Normal file
@@ -0,0 +1,137 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K30L IP Core: Data register logic. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- These are the eight data registers. The logic provides two ----
|
||||
---- read and two write ports providing simultaneos access. For ----
|
||||
---- more information refer to the MC68030 User' Manual. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K30L_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K30L_DATA_REGISTERS is
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
|
||||
-- Data lines:
|
||||
DR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
DR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
DR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
DR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
|
||||
-- Registers controls:
|
||||
DR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : in bit;
|
||||
DR_WR_2 : in bit;
|
||||
DR_MARK_USED : in bit;
|
||||
USE_DPAIR : in boolean;
|
||||
DR_IN_USE : out bit;
|
||||
UNMARK : in bit;
|
||||
|
||||
OP_SIZE : in OP_SIZETYPE
|
||||
);
|
||||
end entity WF68K30L_DATA_REGISTERS;
|
||||
|
||||
architecture BEHAVIOUR of WF68K30L_DATA_REGISTERS is
|
||||
type DR_TYPE is array(0 to 7) of std_logic_vector(31 downto 0);
|
||||
signal DR : DR_TYPE; -- Data registers D0 to D7.
|
||||
signal DR_PNTR_WR_1 : integer range 0 to 7;
|
||||
signal DR_PNTR_WR_2 : integer range 0 to 7;
|
||||
signal DR_PNTR_RD_1 : integer range 0 to 7;
|
||||
signal DR_PNTR_RD_2 : integer range 0 to 7;
|
||||
signal DR_SEL_WR_I1 : std_logic_vector(2 downto 0);
|
||||
signal DR_SEL_WR_I2 : std_logic_vector(2 downto 0);
|
||||
signal DR_USED_1 : std_logic_vector(3 downto 0);
|
||||
signal DR_USED_2 : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
INBUFFER: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if DR_MARK_USED = '1' then
|
||||
DR_SEL_WR_I1 <= DR_SEL_WR_1;
|
||||
DR_SEL_WR_I2 <= DR_SEL_WR_2;
|
||||
end if;
|
||||
end process INBUFFER;
|
||||
|
||||
DR_PNTR_WR_1 <= conv_integer(DR_SEL_WR_I1);
|
||||
DR_PNTR_WR_2 <= conv_integer(DR_SEL_WR_I2);
|
||||
DR_PNTR_RD_1 <= conv_integer(DR_SEL_RD_1);
|
||||
DR_PNTR_RD_2 <= conv_integer(DR_SEL_RD_2);
|
||||
|
||||
P_IN_USE: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' or UNMARK = '1' then
|
||||
DR_USED_1(3) <= '0';
|
||||
DR_USED_2(3) <= '0';
|
||||
elsif DR_MARK_USED = '1' then
|
||||
DR_USED_1 <= '1' & DR_SEL_WR_1;
|
||||
if USE_DPAIR = true then
|
||||
DR_USED_2 <= '1' & DR_SEL_WR_2;
|
||||
end if;
|
||||
end if;
|
||||
end process P_IN_USE;
|
||||
|
||||
DR_IN_USE <= '1' when DR_USED_1(3) = '1' and DR_USED_1(2 downto 0) = DR_SEL_RD_1 else
|
||||
'1' when DR_USED_1(3) = '1' and DR_USED_1(2 downto 0) = DR_SEL_RD_2 else
|
||||
'1' when DR_USED_2(3) = '1' and DR_USED_2(2 downto 0) = DR_SEL_RD_1 else
|
||||
'1' when DR_USED_2(3) = '1' and DR_USED_2(2 downto 0) = DR_SEL_RD_2 else '0';
|
||||
|
||||
DR_OUT_1 <= DR(DR_PNTR_RD_1);
|
||||
DR_OUT_2 <= DR(DR_PNTR_RD_2);
|
||||
|
||||
REGISTERS: process
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
DR <= (others => (others => '0'));
|
||||
end if;
|
||||
if DR_WR_1 = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => DR(DR_PNTR_WR_1) <= DR_IN_1;
|
||||
when WORD => DR(DR_PNTR_WR_1)(15 downto 0) <= DR_IN_1(15 downto 0);
|
||||
when Byte => DR(DR_PNTR_WR_1)(7 downto 0) <= DR_IN_1(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
if DR_WR_2 = '1' then
|
||||
case OP_SIZE is
|
||||
when LONG => DR(DR_PNTR_WR_2) <= DR_IN_2;
|
||||
when WORD => DR(DR_PNTR_WR_2)(15 downto 0) <= DR_IN_2(15 downto 0);
|
||||
when Byte => DR(DR_PNTR_WR_2)(7 downto 0) <= DR_IN_2(7 downto 0);
|
||||
end case;
|
||||
end if;
|
||||
end process REGISTERS;
|
||||
end BEHAVIOUR;
|
||||
934
common/CPU/68K30L/wf68k30L_exception_handler.vhd
Normal file
934
common/CPU/68K30L/wf68k30L_exception_handler.vhd
Normal file
@@ -0,0 +1,934 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K30L IP Core: this is the exception handler module. ----
|
||||
---- ----
|
||||
---- Description: ----
|
||||
---- This is the exception handler which is responsible for the ----
|
||||
---- interrupt management of the external interrupt and internal ----
|
||||
---- exception processing. It manages auto-vectored interrupt ----
|
||||
---- cycles, priority resolving and correct vector numbers. ----
|
||||
---- For further information concerning the functionality of this ----
|
||||
---- module refer to the MC68030 User's Manual and to the MC68K ----
|
||||
---- family Programmer's Reference Manual. ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Remarks: ----
|
||||
---- The relationship between the STATUSn signal and the execution ----
|
||||
---- of the next pending exception is handled by the BUSY signals. ----
|
||||
---- If the pending interrupt is not signaled in time, when the ----
|
||||
---- main controller signal STATUSn, the next instruction is ----
|
||||
---- executed and afterwards the exception. When the pending ----
|
||||
---- exception is asserted before the STATUSn of one of the main ----
|
||||
---- controller, the exception is executed immediately. ----
|
||||
---- ----
|
||||
---- A bus error at an instruction boundary may occur, when the ----
|
||||
---- operation word fetched from the instruction pipe is invalid. ----
|
||||
---- Bus errors which occur at the time of the instruction boundary ----
|
||||
---- but where released early or at the same time due to the pipe- ----
|
||||
---- lined structure are treated as regular bus errors not related ----
|
||||
---- with the instruction boundary. The signal IBOUND is used to ----
|
||||
---- handle this situations correctly. ----
|
||||
---- ----
|
||||
---- This exception handler uses a simple logic for the handling ----
|
||||
---- the RTE instruction. In comparision to the full featured 68K30 ----
|
||||
---- it cannot complete from defective bus exception stack frames. ----
|
||||
---- It is assumed, that a software handler has modified the images ----
|
||||
---- in the exception stack frame for a bus handler so that the RTE ----
|
||||
---- instruction restores from a correct stack frame. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Revision 2K16A 20141201 WF
|
||||
-- Fixed a bug in PC_LOAD.
|
||||
-- Revision 2K18A 20180620 WF
|
||||
-- Removed REST_BIW_0.
|
||||
-- Removed PC_OFFSET.
|
||||
-- Fixed PC restoring during exception processing.
|
||||
-- Fixed the vector calculation of INT vectors.
|
||||
-- Fixed faulty modeling in IRQ_FILTER.
|
||||
-- Implemented the AVEC_FILTER to better meet bus timings.
|
||||
-- The RTE exception has now highest priority (avoids mismatch).
|
||||
-- TOP, CONTROL, Exception Handler Opcode Decoder: Rearranged PC_INC and ipipe flush logic.
|
||||
-- Update the IRQ mask only for RESET and interrupts.
|
||||
-- External interrupts are postponed if any system controllers are in initialize operation status.
|
||||
-- RTE now loads the address offset correctly when entering the handler.
|
||||
-- Rearranged address error handling.
|
||||
-- Revision 2K19B 20191224 WF
|
||||
-- Introduced signal synchronization in the P_D process to avoid malfunction by hazards.
|
||||
-- The processor VERSION is now 32 bit wide.
|
||||
--
|
||||
|
||||
library work;
|
||||
use work.WF68K30L_PKG.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity WF68K30L_EXCEPTION_HANDLER is
|
||||
generic(VERSION : std_logic_vector(31 downto 0) := x"20191224");
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : in bit;
|
||||
|
||||
EXH_REQ : out bit;
|
||||
BUSY_EXH : out bit;
|
||||
|
||||
ADR_IN : in std_logic_vector(31 downto 0);
|
||||
ADR_CPY : out std_logic_vector(31 downto 0);
|
||||
ADR_OFFSET : out std_logic_vector(31 downto 0);
|
||||
CPU_SPACE : out bit;
|
||||
|
||||
DATA_0 : in std_logic;
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_IN : in std_logic_vector(31 downto 0);
|
||||
|
||||
OP_SIZE : out OP_SIZETYPE; -- Operand size.
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
|
||||
OPCODE_RDY : in bit; -- OPCODE is available.
|
||||
OPD_ACK : in bit; -- Opword is available.
|
||||
OW_VALID : in std_logic; -- Status from the opcode decoder.
|
||||
|
||||
STATUS_REG_IN : in std_logic_vector(15 downto 0);
|
||||
SR_CPY : out std_logic_vector(15 downto 0);
|
||||
SR_INIT : out bit;
|
||||
SR_CLR_MBIT : out bit;
|
||||
SR_WR : out bit;
|
||||
|
||||
ISP_DEC : out bit;
|
||||
ISP_LOAD : out bit;
|
||||
PC_INC : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_RESTORE : out bit;
|
||||
|
||||
STACK_FORMAT : out std_logic_vector(3 downto 0);
|
||||
STACK_POS : out integer range 0 to 46;
|
||||
|
||||
SP_ADD_DISPL : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(7 downto 0);
|
||||
|
||||
IPIPE_FILL : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
REFILLn : out std_logic;
|
||||
RESTORE_ISP_PC : out bit;
|
||||
|
||||
HALT_OUTn : out std_logic;
|
||||
STATUSn : out bit;
|
||||
|
||||
-- Interrupt controls:
|
||||
INT_TRIG : in bit;
|
||||
IRQ_IN : in std_logic_vector(2 downto 0);
|
||||
IRQ_PEND : out std_logic_vector(2 downto 0);
|
||||
AVECn : in std_logic;
|
||||
IPENDn : out std_logic;
|
||||
IVECT_OFFS : out std_logic_vector(9 downto 0); -- Interrupt vector offset.
|
||||
|
||||
|
||||
-- Trap signals:
|
||||
TRAP_AERR : in bit;
|
||||
TRAP_BERR : in bit;
|
||||
TRAP_CHK : in bit;
|
||||
TRAP_DIVZERO : in bit;
|
||||
TRAP_ILLEGAL : in bit;
|
||||
TRAP_CODE_OPC : in TRAPTYPE_OPC; -- T_1010, T_1111, T_ILLEGAL, T_TRAP, T_PRIV.
|
||||
TRAP_VECTOR : in std_logic_vector(3 downto 0);
|
||||
TRAP_cc : in bit;
|
||||
TRAP_V : in bit;
|
||||
EX_TRACE_IN : in bit;
|
||||
VBR_WR : in bit;
|
||||
VBR : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity WF68K30L_EXCEPTION_HANDLER;
|
||||
|
||||
architecture BEHAVIOR of WF68K30L_EXCEPTION_HANDLER is
|
||||
type EX_STATES is (IDLE, BUILD_STACK, BUILD_TSTACK, CALC_VECT_No, EXAMINE_VERSION, GET_VECTOR, HALTED, INIT, READ_BOTTOM,
|
||||
READ_TOP, REFILL_PIPE, RESTORE_ISP, RESTORE_PC, RESTORE_STATUS, UPDATE_PC, SWITCH_STATE, VALIDATE_FRAME);
|
||||
|
||||
type EXCEPTIONS is (EX_NONE, EX_1010, EX_1111, EX_AERR, EX_BERR, EX_CHK, EX_DIVZERO, EX_FORMAT, EX_ILLEGAL,
|
||||
EX_INT, EX_PRIV, EX_RESET, EX_RTE, EX_TRACE, EX_TRAP, EX_TRAPcc, EX_TRAPV);
|
||||
|
||||
signal ACCESS_ERR : bit;
|
||||
signal AVEC : bit;
|
||||
signal DATA_RD_I : bit;
|
||||
signal DATA_WR_I : bit;
|
||||
signal DOUBLE_BUSFLT : bit;
|
||||
signal EXCEPTION : EXCEPTIONS; -- Currently executed exception.
|
||||
signal EX_STATE : EX_STATES := IDLE;
|
||||
signal NEXT_EX_STATE : EX_STATES;
|
||||
signal EX_P_1010 : bit; -- ..._P are the pending exceptions.
|
||||
signal EX_P_1111 : bit;
|
||||
signal EX_P_AERR : bit;
|
||||
signal EX_P_BERR : bit;
|
||||
signal EX_P_CHK : bit;
|
||||
signal EX_P_DIVZERO : bit;
|
||||
signal EX_P_FORMAT : bit;
|
||||
signal EX_P_ILLEGAL : bit;
|
||||
signal EX_P_INT : bit;
|
||||
signal EX_P_RESET : bit;
|
||||
signal EX_P_RTE : bit;
|
||||
signal EX_P_PRIV : bit;
|
||||
signal EX_P_TRACE : bit;
|
||||
signal EX_P_TRAP : bit;
|
||||
signal EX_P_TRAPcc : bit;
|
||||
signal EX_P_TRAPV : bit;
|
||||
signal INT_VECT : std_logic_vector(31 downto 0); -- Interrupt vector.
|
||||
signal IBOUND : boolean;
|
||||
signal IRQ : std_logic_vector(2 downto 0);
|
||||
signal IRQ_PEND_I : std_logic_vector(2 downto 0);
|
||||
signal MBIT : std_logic;
|
||||
signal PIPE_CNT : std_logic_vector(1 downto 0);
|
||||
signal PIPE_FULL : boolean;
|
||||
signal STACK_CNT : integer range 0 to 46;
|
||||
signal STACK_FORMAT_I : std_logic_vector(3 downto 0);
|
||||
signal SYS_INIT : bit;
|
||||
begin
|
||||
BUSY_EXH <= '1' when EX_STATE /= IDLE else '0';
|
||||
|
||||
IRQ_FILTER : process
|
||||
-- This logic is intended to avoid spurious IRQs due
|
||||
-- to setup / hold violations (IRQ_IN may operate in
|
||||
-- a different clock domain).
|
||||
variable IRQ_TMP_1 : std_logic_vector(2 downto 0) := "000";
|
||||
variable IRQ_TMP_2 : std_logic_vector(2 downto 0) := "000";
|
||||
begin
|
||||
wait until CLK = '0' and CLK' event;
|
||||
if IRQ_TMP_1 = IRQ_TMP_2 then
|
||||
IRQ <= IRQ_TMP_2;
|
||||
end if;
|
||||
IRQ_TMP_2 := IRQ_TMP_1;
|
||||
IRQ_TMP_1 := IRQ_IN;
|
||||
end process IRQ_FILTER;
|
||||
|
||||
AVEC_FILTER : process
|
||||
-- We need a flip flop for the incoming AVECn to meet
|
||||
-- the timing requirements of the bus interface. AVECn
|
||||
-- is asserted (low active) before DATA_RDY of the
|
||||
-- bus interface. AVEC stays asserted until DATA_RDY.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if AVECn = '0' then
|
||||
AVEC <= '1';
|
||||
elsif DATA_RDY = '1' or RESET = '1' then
|
||||
AVEC <= '0';
|
||||
end if;
|
||||
end process AVEC_FILTER;
|
||||
|
||||
INSTRUCTION_BOUNDARY: process
|
||||
-- This flip flop indicates a bus error exception,
|
||||
-- when the micro sequencer is at an instruction
|
||||
-- boundary.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
IBOUND <= false;
|
||||
elsif OPD_ACK = '1' and OW_VALID = '0' then
|
||||
IBOUND <= true;
|
||||
elsif EX_STATE = BUILD_STACK then
|
||||
IBOUND <= false;
|
||||
end if;
|
||||
end process INSTRUCTION_BOUNDARY;
|
||||
|
||||
PENDING: process
|
||||
-- The exceptions which occurs are stored in this pending register until the
|
||||
-- interrupt handler handled the respective exception.
|
||||
-- The TRAP_PRIV, TRAP_1010, TRAP_1111, TRAP_ILLEGAL, TRAP_OP and TRAP_V may be a strobe
|
||||
-- of 1 clock period. All others must be strobes of 1 clock period..
|
||||
variable INT7_TRIG : boolean;
|
||||
variable INT_VAR : std_logic_vector(2 downto 0);
|
||||
variable SR_VAR : std_logic_vector(2 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
EX_P_RESET <= '1';
|
||||
elsif EX_STATE = RESTORE_PC and DATA_RDY = '1' and EXCEPTION = EX_RESET then
|
||||
EX_P_RESET <= '0';
|
||||
end if;
|
||||
--
|
||||
if TRAP_BERR = '1' then
|
||||
EX_P_BERR <= '1';
|
||||
elsif EX_STATE /= IDLE and DATA_RDY = '1' and DATA_VALID = '0' then
|
||||
EX_P_BERR <= '1';
|
||||
elsif EX_STATE = INIT and EXCEPTION = EX_BERR then
|
||||
EX_P_BERR <= '0'; -- Reset in the beginning to enable retriggering.
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_BERR <= '0';
|
||||
end if;
|
||||
--
|
||||
if TRAP_AERR = '1' then
|
||||
EX_P_AERR <= '1';
|
||||
elsif EX_STATE = BUILD_STACK and EXCEPTION = EX_AERR then
|
||||
EX_P_AERR <= '0';
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_AERR <= '0';
|
||||
end if;
|
||||
--
|
||||
if EX_TRACE_IN = '1' then
|
||||
EX_P_TRACE <= '1';
|
||||
elsif EX_STATE = BUILD_STACK and EXCEPTION = EX_TRACE then
|
||||
EX_P_TRACE <= '0';
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_TRACE <= '0';
|
||||
end if;
|
||||
--
|
||||
if IRQ = "111" and SR_VAR = "111" and STATUS_REG_IN(10 downto 8) /= "111" then
|
||||
INT7_TRIG := true; -- Trigger by lowering the mask from 7 to any value.
|
||||
elsif IRQ = "111" and INT_VAR < "111" then
|
||||
INT7_TRIG := true; -- Trigger when level 7 is entered.
|
||||
else
|
||||
INT7_TRIG := false;
|
||||
end if;
|
||||
--
|
||||
SR_VAR := STATUS_REG_IN(10 downto 8); -- Update after use!
|
||||
INT_VAR := IRQ; -- Update after use!
|
||||
--
|
||||
if SYS_INIT = '1' then -- Reset when disabling the interrupts.
|
||||
EX_P_INT <= '0';
|
||||
IRQ_PEND_I <= "111"; -- This is required for system startup.
|
||||
elsif EX_STATE = GET_VECTOR and DATA_RDY = '1' then
|
||||
EX_P_INT <= '0';
|
||||
elsif INT7_TRIG = true then -- Level 7 is nonmaskable ...
|
||||
EX_P_INT <= '1';
|
||||
IRQ_PEND_I <= IRQ;
|
||||
elsif INT_TRIG = '1' and STATUS_REG_IN(10 downto 8) < IRQ then
|
||||
EX_P_INT <= '1';
|
||||
IRQ_PEND_I <= IRQ;
|
||||
end if;
|
||||
--
|
||||
-- The following nine traps never appear at the same time:
|
||||
if TRAP_CHK = '1' then
|
||||
EX_P_CHK <= '1';
|
||||
elsif TRAP_DIVZERO = '1' then
|
||||
EX_P_DIVZERO <= '1';
|
||||
elsif TRAP_CODE_OPC = T_TRAP then
|
||||
EX_P_TRAP <= '1';
|
||||
elsif TRAP_cc = '1' then
|
||||
EX_P_TRAPcc <= '1';
|
||||
elsif TRAP_V = '1' then
|
||||
EX_P_TRAPV <= '1';
|
||||
elsif TRAP_CODE_OPC = T_PRIV then
|
||||
EX_P_PRIV <= '1';
|
||||
elsif TRAP_CODE_OPC = T_1010 then
|
||||
EX_P_1010 <= '1';
|
||||
elsif TRAP_CODE_OPC = T_1111 then
|
||||
EX_P_1111 <= '1';
|
||||
elsif TRAP_CODE_OPC = T_ILLEGAL then
|
||||
EX_P_ILLEGAL <= '1';
|
||||
elsif TRAP_ILLEGAL = '1' then -- Used for BKPT.
|
||||
EX_P_ILLEGAL <= '1';
|
||||
elsif EX_STATE = VALIDATE_FRAME and DATA_RDY = '1' and DATA_VALID = '1' and NEXT_EX_STATE = IDLE then
|
||||
EX_P_FORMAT <= '1';
|
||||
elsif EX_STATE = EXAMINE_VERSION and DATA_RDY = '1' and DATA_VALID = '1' and NEXT_EX_STATE = IDLE then
|
||||
EX_P_FORMAT <= '1';
|
||||
elsif TRAP_CODE_OPC = T_RTE then
|
||||
EX_P_RTE <= '1';
|
||||
elsif EX_STATE = REFILL_PIPE and NEXT_EX_STATE /= REFILL_PIPE then -- Clear after IPIPE_FLUSH.
|
||||
case EXCEPTION is
|
||||
when EX_1010 | EX_1111 | EX_CHK | EX_DIVZERO | EX_ILLEGAL | EX_TRAP | EX_TRAPcc | EX_TRAPV | EX_FORMAT | EX_PRIV | EX_RTE =>
|
||||
EX_P_CHK <= '0';
|
||||
EX_P_DIVZERO <= '0';
|
||||
EX_P_PRIV <= '0';
|
||||
EX_P_1010 <= '0';
|
||||
EX_P_1111 <= '0';
|
||||
EX_P_ILLEGAL <= '0';
|
||||
EX_P_RTE <= '0';
|
||||
EX_P_TRAP <= '0';
|
||||
EX_P_TRAPcc <= '0';
|
||||
EX_P_TRAPV <= '0';
|
||||
EX_P_FORMAT <= '0';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
-- Clear all possible traps during reset exception because the
|
||||
-- signal EXCEPTION is not valid at this time:
|
||||
elsif SYS_INIT = '1' then
|
||||
EX_P_CHK <= '0';
|
||||
EX_P_DIVZERO <= '0';
|
||||
EX_P_PRIV <= '0';
|
||||
EX_P_1010 <= '0';
|
||||
EX_P_1111 <= '0';
|
||||
EX_P_ILLEGAL <= '0';
|
||||
EX_P_RTE <= '0';
|
||||
EX_P_TRAP <= '0';
|
||||
EX_P_TRAPV <= '0';
|
||||
EX_P_FORMAT <= '0';
|
||||
end if;
|
||||
end process PENDING;
|
||||
|
||||
ACCESS_ERR <= '1' when EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_0 = '1' else -- Odd PC value.
|
||||
'1' when DATA_RDY = '1' and DATA_VALID = '0' else '0'; -- Bus error.
|
||||
|
||||
IRQ_PEND <= IRQ_PEND_I when EXCEPTION = EX_RESET or EXCEPTION = EX_INT else STATUS_REG_IN(10 downto 8);
|
||||
IPENDn <= '0' when EX_P_INT = '1' or EX_P_RESET = '1' or EX_P_TRACE = '1' else '1';
|
||||
|
||||
-- This signal is asserted eraly to indicate the respective controller to stay in its idle state.
|
||||
-- The exception is then inserted before a new operation has been loaded and processed.
|
||||
EXH_REQ <= '0' when EX_STATE /= IDLE else
|
||||
'1' when TRAP_CODE_OPC /= NONE else
|
||||
'1' when (EX_P_RESET or EX_P_BERR or EX_P_AERR or EX_P_DIVZERO or EX_P_CHK) = '1' else
|
||||
'1' when (EX_P_TRAPcc or EX_P_TRAPV or EX_P_TRACE or EX_P_FORMAT or EX_P_INT) = '1' else '0';
|
||||
|
||||
INT_VECTOR: process
|
||||
-- This process provides the vector base register handling and
|
||||
-- the interrupt vector number INT_VECT, which is determined
|
||||
-- during interrupt processing.
|
||||
variable VECT_No : std_logic_vector(9 downto 2) := "00000000";
|
||||
variable VB_REG : std_logic_vector(31 downto 0) := x"00000000";
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if VBR_WR = '1' then
|
||||
VB_REG := DATA_IN;
|
||||
elsif SYS_INIT = '1' then
|
||||
VB_REG := (others => '0');
|
||||
end if;
|
||||
--
|
||||
if EX_STATE = CALC_VECT_No or EX_STATE = GET_VECTOR then
|
||||
case EXCEPTION is
|
||||
when EX_RESET => VECT_No := x"00";
|
||||
when EX_BERR => VECT_No := x"02";
|
||||
when EX_AERR => VECT_No := x"03";
|
||||
when EX_ILLEGAL => VECT_No := x"04";
|
||||
when EX_DIVZERO => VECT_No := x"05";
|
||||
when EX_CHK => VECT_No := x"06";
|
||||
when EX_TRAPcc => VECT_No := x"07";
|
||||
when EX_TRAPV => VECT_No := x"07";
|
||||
when EX_PRIV => VECT_No := x"08";
|
||||
when EX_TRACE => VECT_No := x"09";
|
||||
when EX_1010 => VECT_No := x"0A";
|
||||
when EX_1111 => VECT_No := x"0B";
|
||||
when EX_FORMAT => VECT_No := x"0E";
|
||||
-- The uninitialized interrupt vector number x"0F"
|
||||
-- is provided by the peripheral interrupt source
|
||||
-- during the auto vector bus cycle.
|
||||
when EX_INT =>
|
||||
if DATA_RDY = '1' and AVEC = '1' then
|
||||
VECT_No := x"18" + IRQ_PEND_I; -- Autovector.
|
||||
elsif DATA_RDY = '1' and DATA_VALID = '0' then
|
||||
VECT_No := x"18"; -- Spurious interrupt.
|
||||
elsif DATA_RDY = '1' then
|
||||
-- This is the vector number provided by the device.
|
||||
-- If the returned VECT_No is x"0F" then it is the
|
||||
-- uninitialized interrupt vector due to non initia-
|
||||
-- lized vector register of the peripheral device.
|
||||
VECT_No := DATA_IN(7 downto 0); -- Non autovector.
|
||||
end if;
|
||||
when EX_TRAP => VECT_No := x"2" & TRAP_VECTOR;
|
||||
when others => VECT_No := (others => '-'); -- Don't care.
|
||||
end case;
|
||||
end if;
|
||||
--
|
||||
INT_VECT <= VB_REG + (VECT_No & "00");
|
||||
VBR <= VB_REG;
|
||||
IVECT_OFFS <= VECT_No & "00";
|
||||
end process INT_VECTOR;
|
||||
|
||||
STORE_CURRENT_EXCEPTION: process
|
||||
-- The exceptions which occurs are stored in the following flags until the
|
||||
-- interrupt handler handled the respective exception.
|
||||
-- This process also stores the current processed exception for further use.
|
||||
-- The update takes place in the IDLE EX_STATE.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
-- Priority level 0:
|
||||
if EX_STATE = IDLE and EX_P_RESET = '1' then
|
||||
EXCEPTION <= EX_RESET;
|
||||
-- Priority level 1:
|
||||
elsif EX_STATE = IDLE and EX_P_AERR = '1' then
|
||||
EXCEPTION <= EX_AERR;
|
||||
elsif EX_STATE = IDLE and EX_P_BERR = '1' then
|
||||
EXCEPTION <= EX_BERR;
|
||||
-- Priority level 2:
|
||||
-- BREAKPOINT is part of the main controller.
|
||||
elsif EX_STATE = IDLE and EX_P_CHK = '1' then
|
||||
EXCEPTION <= EX_CHK;
|
||||
elsif EX_STATE = IDLE and EX_P_TRAPcc = '1' then
|
||||
EXCEPTION <= EX_TRAPcc;
|
||||
elsif EX_STATE = IDLE and EX_P_DIVZERO = '1' then
|
||||
EXCEPTION <= EX_DIVZERO;
|
||||
elsif EX_STATE = IDLE and EX_P_TRAP = '1' then
|
||||
EXCEPTION <= EX_TRAP;
|
||||
elsif EX_STATE = IDLE and EX_P_TRAPV = '1' then
|
||||
EXCEPTION <= EX_TRAPV;
|
||||
elsif EX_STATE = IDLE and EX_P_FORMAT = '1' then
|
||||
EXCEPTION <= EX_FORMAT;
|
||||
-- Priority level 3:
|
||||
elsif EX_STATE = IDLE and EX_P_ILLEGAL = '1' then
|
||||
EXCEPTION <= EX_ILLEGAL;
|
||||
elsif EX_STATE = IDLE and EX_P_RTE = '1' then
|
||||
EXCEPTION <= EX_RTE;
|
||||
elsif EX_STATE = IDLE and EX_P_1010 = '1' then
|
||||
EXCEPTION <= EX_1010;
|
||||
elsif EX_STATE = IDLE and EX_P_1111 = '1' then
|
||||
EXCEPTION <= EX_1111;
|
||||
elsif EX_STATE = IDLE and EX_P_PRIV = '1' then
|
||||
EXCEPTION <= EX_PRIV;
|
||||
elsif EX_STATE = IDLE and EX_P_TRACE = '1' then
|
||||
EXCEPTION <= EX_TRACE;
|
||||
elsif EX_STATE = IDLE and EX_P_INT = '1' then
|
||||
EXCEPTION <= EX_INT;
|
||||
elsif NEXT_EX_STATE = IDLE then
|
||||
EXCEPTION <= EX_NONE;
|
||||
end if;
|
||||
end process STORE_CURRENT_EXCEPTION;
|
||||
|
||||
CPU_SPACE <= '1' when NEXT_EX_STATE = GET_VECTOR else '0';
|
||||
|
||||
ADR_OFFSET <= x"000000" & "00000" & PIPE_CNT & '0' when EX_STATE = REFILL_PIPE else
|
||||
x"00000004" when NEXT_EX_STATE = RESTORE_PC and EXCEPTION = EX_RESET else
|
||||
x"00000002" when NEXT_EX_STATE = RESTORE_PC else
|
||||
x"00000006" when NEXT_EX_STATE = VALIDATE_FRAME else
|
||||
x"00000036" when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
x"0000005C" when NEXT_EX_STATE = READ_BOTTOM else
|
||||
INT_VECT when NEXT_EX_STATE = UPDATE_PC else x"00000000"; -- Default is top of the stack.
|
||||
|
||||
OP_SIZE <= LONG when EX_STATE = INIT else -- Decrement the stack by four (ISP_DEC).
|
||||
LONG when NEXT_EX_STATE = RESTORE_ISP or NEXT_EX_STATE = RESTORE_PC else
|
||||
LONG when NEXT_EX_STATE = BUILD_STACK or NEXT_EX_STATE = BUILD_TSTACK else -- Always long access.
|
||||
LONG when NEXT_EX_STATE = UPDATE_PC or EX_STATE = UPDATE_PC else
|
||||
LONG when EX_STATE = SWITCH_STATE else
|
||||
LONG when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
BYTE when NEXT_EX_STATE = GET_VECTOR else WORD;
|
||||
|
||||
with STACK_FORMAT_I select
|
||||
DISPLACEMENT <= x"08" when x"0" | x"1",
|
||||
x"0C" when x"2",
|
||||
x"12" when x"9",
|
||||
x"20" when x"A",
|
||||
x"5C" when others; -- x"B".
|
||||
|
||||
SP_ADD_DISPL <= '1' when EX_STATE = RESTORE_STATUS and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
|
||||
P_D: process(CLK, DATA_RDY)
|
||||
-- These flip flops are necessary to delay
|
||||
-- the read and writes during BUILD_STACK
|
||||
-- and restoring the system because the
|
||||
-- address calculation in the address
|
||||
-- section requires one clock.
|
||||
-- Important note: to avoid asynchronous reset by data hazards the
|
||||
-- resetting signal is synchronized on the negative clock edge.
|
||||
variable DATA_RDY_VAR : bit;
|
||||
begin
|
||||
if CLK = '0' and CLK' event then
|
||||
DATA_RDY_VAR := DATA_RDY;
|
||||
end if;
|
||||
--
|
||||
if DATA_RDY_VAR = '1' then
|
||||
DATA_RD <= '0';
|
||||
elsif CLK = '1' and CLK' event then
|
||||
DATA_RD <= DATA_RD_I;
|
||||
end if;
|
||||
|
||||
if DATA_RDY_VAR = '1' then
|
||||
DATA_WR <= '0';
|
||||
elsif CLK = '1' and CLK' event then
|
||||
DATA_WR <= DATA_WR_I;
|
||||
end if;
|
||||
end process P_D;
|
||||
|
||||
DATA_RD_I <= '0' when DATA_RDY = '1' else
|
||||
'1' when NEXT_EX_STATE = GET_VECTOR else
|
||||
'1' when NEXT_EX_STATE = VALIDATE_FRAME else
|
||||
'1' when NEXT_EX_STATE = EXAMINE_VERSION else
|
||||
'1' when NEXT_EX_STATE = READ_TOP else
|
||||
'1' when NEXT_EX_STATE = READ_BOTTOM else
|
||||
'1' when NEXT_EX_STATE = RESTORE_ISP else
|
||||
'1' when NEXT_EX_STATE = RESTORE_STATUS else
|
||||
'1' when NEXT_EX_STATE = UPDATE_PC else
|
||||
'1' when NEXT_EX_STATE = RESTORE_PC else '0';
|
||||
|
||||
DATA_WR_I <= '0' when DATA_RDY = '1' else
|
||||
'1' when EX_STATE = BUILD_STACK else
|
||||
'1' when EX_STATE = BUILD_TSTACK else '0';
|
||||
|
||||
ISP_LOAD <= '1' when EX_STATE = RESTORE_ISP and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
PC_RESTORE <= '1' when EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
PC_LOAD <= '1' when EXCEPTION /= EX_RESET and EXCEPTION /= EX_RTE and EX_STATE /= REFILL_PIPE and NEXT_EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
IPIPE_FILL <= '1' when EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
-- This signal forces the PC logic in the address register section to calculate the address
|
||||
-- of the next instruction. This address is written on the stack. For the following
|
||||
-- instructions the old PC value is stacked: BERR, AERR, ILLEGAL, PRIV, TRACE, 1010, 1111, FORMAT.
|
||||
PC_INC <= '1' when EXCEPTION = EX_CHK and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_DIVZERO and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_INT and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_TRAP and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_TRAPcc and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EXCEPTION = EX_TRAPV and EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK else '0';
|
||||
|
||||
ISP_DEC <= '1' when EX_STATE = INIT and EXCEPTION /= EX_RESET and EXCEPTION /= EX_RTE else -- Early due to one clock cycle address calculation.
|
||||
'1' when EX_STATE = BUILD_STACK and DATA_RDY = '1' and NEXT_EX_STATE = BUILD_STACK else
|
||||
'1' when EX_STATE = SWITCH_STATE else
|
||||
'1' when EX_STATE = BUILD_TSTACK and DATA_RDY = '1' and NEXT_EX_STATE = BUILD_TSTACK else '0';
|
||||
|
||||
SR_INIT <= '1' when EX_STATE = INIT else '0';
|
||||
SR_CLR_MBIT <= '1' when EX_STATE = BUILD_STACK and DATA_RDY = '1' and STACK_CNT = 2 and EXCEPTION = EX_INT and MBIT = '1' else '0';
|
||||
SR_WR <= '1' when EX_STATE = RESTORE_STATUS and DATA_RDY = '1' and DATA_VALID = '1' else '0';
|
||||
|
||||
SYS_INIT <= '1' when EX_STATE = IDLE and EX_P_RESET = '1' else '0';
|
||||
|
||||
-- The processor gets halted, if a bus error occurs in the stacking or updating states during
|
||||
-- the exception processing of a bus error, an address error or a reset.
|
||||
HALT_OUTn <= '0' when EX_STATE = HALTED else '1';
|
||||
|
||||
RESTORE_ISP_PC <= '1' when EXCEPTION = EX_RESET and (NEXT_EX_STATE = RESTORE_ISP or EX_STATE = RESTORE_ISP) else
|
||||
'1' when EXCEPTION = EX_RESET and (NEXT_EX_STATE = RESTORE_PC or EX_STATE = RESTORE_PC) else
|
||||
'1' when NEXT_EX_STATE = UPDATE_PC else '0';
|
||||
|
||||
REFILLn <= '0' when EX_STATE = REFILL_PIPE else '1';
|
||||
|
||||
STACK_FORMAT <= STACK_FORMAT_I;
|
||||
|
||||
IPIPE_FLUSH <= '1' when EXCEPTION = EX_RESET and EX_STATE /= REFILL_PIPE else
|
||||
'1' when EXCEPTION /= EX_NONE and EX_STATE /= REFILL_PIPE and NEXT_EX_STATE = REFILL_PIPE else '0';
|
||||
|
||||
DOUBLE_BUSFLT <= '1' when (EXCEPTION = EX_AERR or EXCEPTION = EX_RESET) and EX_STATE = RESTORE_PC and DATA_RDY = '1' and DATA_0 = '1' else -- Odd PC value.
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_AERR and DATA_RDY = '1' and DATA_VALID = '0' else
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_BERR and DATA_RDY = '1' and DATA_VALID = '0' else
|
||||
'1' when EX_STATE /= IDLE and EXCEPTION = EX_RESET and DATA_RDY = '1' and DATA_VALID = '0' else '0';
|
||||
|
||||
P_TMP_CPY: process
|
||||
-- These registers contain a copy of system relevant state information
|
||||
-- which is necessary for restoring the exception. Copies are provided
|
||||
-- for the status register, the program counter and the effective address.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE = IDLE and NEXT_EX_STATE /= IDLE then
|
||||
SR_CPY <= STATUS_REG_IN;
|
||||
ADR_CPY <= ADR_IN;
|
||||
MBIT <= STATUS_REG_IN(12);
|
||||
elsif EX_STATE = BUILD_STACK and NEXT_EX_STATE = SWITCH_STATE then
|
||||
SR_CPY(13) <= '1'; -- Set S bit.
|
||||
end if;
|
||||
end process P_TMP_CPY;
|
||||
|
||||
STACK_CTRL: process
|
||||
-- This process controls the stacking of the data to the stack. Depending
|
||||
-- on the stack frame format, the number of words written to the stack is
|
||||
-- adjusted to long words. See the DATA_2_PORT multiplexer in the top level
|
||||
-- file for more information.
|
||||
variable STACK_POS_VAR : integer range 0 to 46 := 0;
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE /= BUILD_TSTACK and NEXT_EX_STATE = BUILD_TSTACK then
|
||||
STACK_POS_VAR := 4;
|
||||
STACK_FORMAT_I <= x"1";
|
||||
elsif EX_STATE /= BUILD_STACK and NEXT_EX_STATE = BUILD_STACK then
|
||||
case EXCEPTION is
|
||||
when EX_INT | EX_ILLEGAL | EX_1010 | EX_1111 | EX_FORMAT | EX_PRIV | EX_TRAP =>
|
||||
STACK_POS_VAR := 4; -- Format 0.
|
||||
STACK_FORMAT_I <= x"0";
|
||||
when EX_CHK | EX_TRAPcc | EX_TRAPV | EX_TRACE | EX_DIVZERO =>
|
||||
STACK_POS_VAR := 6; -- Format 2.
|
||||
STACK_FORMAT_I <= x"2";
|
||||
when EX_AERR | EX_BERR =>
|
||||
if IBOUND = true then
|
||||
STACK_POS_VAR := 16; -- Format A.
|
||||
STACK_FORMAT_I <= x"A";
|
||||
else
|
||||
STACK_POS_VAR := 46; -- Format B.
|
||||
STACK_FORMAT_I <= x"B";
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
elsif EX_STATE = VALIDATE_FRAME and DATA_RDY = '1' and DATA_VALID = '1' then
|
||||
STACK_FORMAT_I <= DATA_IN(15 downto 12);
|
||||
elsif (EX_STATE = BUILD_STACK or EX_STATE = BUILD_TSTACK) and DATA_RDY = '1' then
|
||||
STACK_POS_VAR := STACK_POS_VAR - 2; -- Always long words are written.
|
||||
end if;
|
||||
--
|
||||
STACK_CNT <= STACK_POS_VAR;
|
||||
STACK_POS <= STACK_POS_VAR;
|
||||
end process STACK_CTRL;
|
||||
|
||||
P_STATUSn : process
|
||||
-- This logic asserts the STATUSn permanently when the CPU is halted.
|
||||
-- STATUSn is asserted for three clock cycles when the exception
|
||||
-- processing starts for RESET, BERR, AERR, 1111, spurious inter-
|
||||
-- rupt and autovectored interrupt. And for TRACE or external
|
||||
-- interrupt exception it is asserted for two clock cycles.
|
||||
variable CNT : std_logic_vector(1 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE = CALC_VECT_No then
|
||||
case EXCEPTION is
|
||||
when EX_RESET | EX_AERR | EX_BERR | EX_1111 =>
|
||||
CNT := "11";
|
||||
STATUSn <= '0';
|
||||
when EX_INT | EX_TRACE =>
|
||||
CNT := "10";
|
||||
when others =>
|
||||
CNT := "00";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if EX_STATE = HALTED then
|
||||
STATUSn <= '0';
|
||||
elsif CNT > "00" then
|
||||
CNT := CNT - '1';
|
||||
STATUSn <= '0';
|
||||
else
|
||||
STATUSn <= '1';
|
||||
end if;
|
||||
end process P_STATUSn;
|
||||
|
||||
PIPE_STATUS: process
|
||||
-- This logic detects the status of the
|
||||
-- instruction pipe prefetch in the
|
||||
-- REFILL_PIPE state.
|
||||
variable CNT : std_logic_vector(1 downto 0);
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if EX_STATE /= REFILL_PIPE then
|
||||
PIPE_FULL <= false;
|
||||
CNT := "00";
|
||||
elsif EX_STATE = REFILL_PIPE and OPCODE_RDY = '1' and CNT < "10" then
|
||||
CNT := CNT + '1';
|
||||
elsif EX_STATE = REFILL_PIPE and OPCODE_RDY = '1' then
|
||||
PIPE_FULL <= true;
|
||||
end if;
|
||||
PIPE_CNT <= CNT;
|
||||
end process PIPE_STATUS;
|
||||
|
||||
EXCEPTION_HANDLER_REG: process
|
||||
-- This is the register portion of the
|
||||
-- exception control state machine.
|
||||
begin
|
||||
wait until CLK = '1' and CLK' event;
|
||||
if RESET = '1' then
|
||||
EX_STATE <= IDLE;
|
||||
else
|
||||
EX_STATE <= NEXT_EX_STATE;
|
||||
end if;
|
||||
end process EXCEPTION_HANDLER_REG;
|
||||
|
||||
EXCEPTION_HANDLER_DEC: process(ACCESS_ERR, BUSY_MAIN, BUSY_OPD, DATA_IN, DATA_VALID, DOUBLE_BUSFLT, EX_STATE, EX_P_RESET, EX_P_AERR, EX_P_BERR, EX_P_TRACE,
|
||||
EX_P_INT, EX_P_ILLEGAL, EX_P_1010, EX_P_TRAPcc, EX_P_RTE, EX_P_1111, EX_P_FORMAT, EX_P_PRIV, EX_P_TRAP, EX_P_TRAPV,
|
||||
EX_P_CHK, EX_P_DIVZERO, EXCEPTION, DATA_RDY, PIPE_FULL, MBIT, STACK_CNT, STACK_FORMAT_I)
|
||||
begin
|
||||
case EX_STATE is
|
||||
when IDLE =>
|
||||
-- The priority of the exception execution is given by the
|
||||
-- following construct. Although type 3 commands do not require
|
||||
-- a prioritization, there is no drawback using these conditions.
|
||||
-- The spurious interrupt and uninitialized interrupt never appear
|
||||
-- as basic interrupts and therefore are not an interrupt source.
|
||||
-- During IDLE, when an interrupt occurs, the status register copy
|
||||
-- control is asserted and the current interrupt controll is given
|
||||
-- to the STORE_EXCEPTION process. During bus or address errors,
|
||||
-- the status register must be copied immediately to recognize
|
||||
-- the current status for RWn etc. (before the faulty bus cycle is
|
||||
-- finished).
|
||||
if (BUSY_MAIN = '1' or BUSY_OPD = '1') and EX_P_RESET = '0' then
|
||||
NEXT_EX_STATE <= IDLE; -- Wait until the pipelined architecture is ready.
|
||||
elsif EX_P_RESET = '1' or EX_P_AERR = '1' or EX_P_BERR = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_TRAP = '1' or EX_P_TRAPcc = '1' or EX_P_TRAPV = '1' or EX_P_CHK = '1' or EX_P_DIVZERO = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_FORMAT = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_TRACE = '1' or EX_P_ILLEGAL = '1' or EX_P_1010 = '1' or EX_P_1111 = '1' or EX_P_PRIV = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_RTE = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
elsif EX_P_INT = '1' then
|
||||
NEXT_EX_STATE <= INIT;
|
||||
else -- No exception.
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
end if;
|
||||
when INIT =>
|
||||
-- In this state, the supervisor mode is switched on (the S bit is set)
|
||||
-- and the trace mode is switched off (the T bit is cleared).
|
||||
-- Do not service, if halted. The current bus cycle is always finished
|
||||
-- in this state. The worst case is a bus error which the finishes the
|
||||
-- current bus cycle within the next clock cycle after BERR is asserted.
|
||||
case EXCEPTION is
|
||||
when EX_RTE =>
|
||||
-- This state is foreseen to handle the address offset
|
||||
-- correctly in the case the ADR_ATN is already set
|
||||
-- by the main controller. So we have to wait one
|
||||
-- clock cycle to ensure this data hazard.
|
||||
NEXT_EX_STATE <= VALIDATE_FRAME; -- 68K10.
|
||||
when EX_INT =>
|
||||
NEXT_EX_STATE <= GET_VECTOR;
|
||||
when others =>
|
||||
NEXT_EX_STATE <= CALC_VECT_No;
|
||||
end case;
|
||||
when GET_VECTOR =>
|
||||
-- This state is intended to determine the vector number for the current process.
|
||||
-- See also the process EXC_VECTOR for the handling of the vector determination.
|
||||
if DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
else
|
||||
NEXT_EX_STATE <= GET_VECTOR;
|
||||
end if;
|
||||
when CALC_VECT_No =>
|
||||
-- This state is introduced to control the generation of the vector number
|
||||
-- for all exceptions except the external interrupts.
|
||||
case EXCEPTION is
|
||||
when EX_RESET =>
|
||||
NEXT_EX_STATE <= RESTORE_ISP; -- Do not stack anything but update the SSP and PC.
|
||||
when others =>
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
end case;
|
||||
-- The following states provide writing to the stack pointer or reading
|
||||
-- the exception vector address from memory. If there is a bus error
|
||||
-- or an address error during the read or write cycles, the processor
|
||||
-- proceeds in two different ways:
|
||||
-- If the errors occur during a reset, bus error or address error
|
||||
-- exception processing, a double bus fault has occured. In
|
||||
-- consequence, the processor halts due to catastrophic system failure.
|
||||
-- If the errors occur during other exception processings, the current
|
||||
-- processing is aborted and this exception handler state machine will
|
||||
-- immediately begin with the bus error exception handling.
|
||||
when BUILD_STACK =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' and STACK_CNT = 2 and EXCEPTION = EX_INT and MBIT = '1' then
|
||||
NEXT_EX_STATE <= SWITCH_STATE; -- Build throwaway stack frame.
|
||||
elsif DATA_RDY = '1' and STACK_CNT = 2 then
|
||||
NEXT_EX_STATE <= UPDATE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= BUILD_STACK;
|
||||
end if;
|
||||
when SWITCH_STATE => -- Required to decrement the correct stack pointer.
|
||||
NEXT_EX_STATE <= BUILD_TSTACK;
|
||||
when BUILD_TSTACK => -- Build throwaway stack frame.
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' and STACK_CNT = 2 then
|
||||
NEXT_EX_STATE <= UPDATE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= BUILD_TSTACK;
|
||||
end if;
|
||||
when UPDATE_PC =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
else
|
||||
NEXT_EX_STATE <= UPDATE_PC;
|
||||
end if;
|
||||
when VALIDATE_FRAME =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
case DATA_IN(15 downto 12) is
|
||||
when x"0" | x"1" | x"2" | x"9" =>
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
when x"A" | x"B" =>
|
||||
NEXT_EX_STATE <= EXAMINE_VERSION;
|
||||
when others =>
|
||||
NEXT_EX_STATE <= IDLE; -- Format error.
|
||||
end case;
|
||||
else
|
||||
NEXT_EX_STATE <= VALIDATE_FRAME;
|
||||
end if;
|
||||
when EXAMINE_VERSION =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
if DATA_IN /= VERSION then
|
||||
NEXT_EX_STATE <= IDLE; -- Format error.
|
||||
else
|
||||
NEXT_EX_STATE <= READ_TOP;
|
||||
end if;
|
||||
else
|
||||
NEXT_EX_STATE <= EXAMINE_VERSION;
|
||||
end if;
|
||||
when READ_TOP =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= READ_BOTTOM;
|
||||
else
|
||||
NEXT_EX_STATE <= READ_TOP;
|
||||
end if;
|
||||
when READ_BOTTOM =>
|
||||
if ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= READ_BOTTOM;
|
||||
end if;
|
||||
when RESTORE_STATUS =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' and STACK_FORMAT_I = x"1" then
|
||||
NEXT_EX_STATE <= VALIDATE_FRAME; -- Throwaway stack frame.
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_STATUS;
|
||||
end if;
|
||||
when RESTORE_ISP =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_ISP;
|
||||
end if;
|
||||
when RESTORE_PC =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED; -- Double bus fault.
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif EXCEPTION = EX_RESET and DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
elsif DATA_RDY = '1' then
|
||||
NEXT_EX_STATE <= RESTORE_STATUS;
|
||||
else
|
||||
NEXT_EX_STATE <= RESTORE_PC;
|
||||
end if;
|
||||
when REFILL_PIPE =>
|
||||
if DOUBLE_BUSFLT = '1' then
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
elsif ACCESS_ERR = '1' then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
elsif PIPE_FULL = true then
|
||||
NEXT_EX_STATE <= IDLE;
|
||||
else
|
||||
NEXT_EX_STATE <= REFILL_PIPE;
|
||||
end if;
|
||||
when HALTED =>
|
||||
-- Processor halted, Double bus error!
|
||||
NEXT_EX_STATE <= HALTED;
|
||||
end case;
|
||||
end process EXCEPTION_HANDLER_DEC;
|
||||
end BEHAVIOR;
|
||||
|
||||
1345
common/CPU/68K30L/wf68k30L_opcode_decoder.vhd
Normal file
1345
common/CPU/68K30L/wf68k30L_opcode_decoder.vhd
Normal file
File diff suppressed because it is too large
Load Diff
457
common/CPU/68K30L/wf68k30L_pkg.vhd
Normal file
457
common/CPU/68K30L/wf68k30L_pkg.vhd
Normal file
@@ -0,0 +1,457 @@
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- WF68K30L IP Core: this is the package file containing the data ----
|
||||
---- types and the component declarations. ----
|
||||
---- ----
|
||||
---- Author(s): ----
|
||||
---- - Wolfgang Foerster, wf@experiment-s.de; wf@inventronik.de ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
---- ----
|
||||
---- Copyright © 2014-2019 Wolfgang Foerster Inventronik GmbH. ----
|
||||
---- ----
|
||||
---- This documentation describes Open Hardware and is licensed ----
|
||||
---- under the CERN OHL v. 1.2. You may redistribute and modify ----
|
||||
---- this documentation under the terms of the CERN OHL v.1.2. ----
|
||||
---- (http://ohwr.org/cernohl). This documentation is distributed ----
|
||||
---- WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF ----
|
||||
---- MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A ----
|
||||
---- PARTICULAR PURPOSE. Please see the CERN OHL v.1.2 for ----
|
||||
---- applicable conditions ----
|
||||
---- ----
|
||||
------------------------------------------------------------------------
|
||||
--
|
||||
-- Revision History
|
||||
--
|
||||
-- Revision 2K14B 20141201 WF
|
||||
-- Initial Release.
|
||||
-- Later revisions
|
||||
-- Modifications according to changes of the entity in other modules.
|
||||
--
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package WF68K30L_PKG is
|
||||
type OP_SIZETYPE is (LONG, WORD, BYTE);
|
||||
-- The OPCODES AND, NOT, OR, ROR and ROL are defined keywords in VHDL. Therefore the assignment is
|
||||
-- AND_B, NOT_B, OR_B, ROTR and ROTL.
|
||||
type OP_68K is (ABCD, ADD, ADDA, ADDI, ADDQ, ADDX, AND_B, ANDI, ANDI_TO_CCR, ANDI_TO_SR, ASL, ASR, Bcc, BCHG, BCLR,
|
||||
BFCHG, BFCLR, BFEXTS, BFEXTU, BFFFO, BFINS, BFSET, BFTST, BKPT, BRA, BSET, BSR, BTST, CAS, CAS2,
|
||||
CHK, CHK2, CLR, CMP, CMP2, CMPA, CMPI, CMPM, DBcc, DIVS, DIVU, EOR, EORI, EORI_TO_CCR,
|
||||
EORI_TO_SR, EXG, EXT, EXTB, ILLEGAL, JMP, JSR, LEA, LINK, LSL, LSR, MOVE, MOVE_FROM_CCR, MOVE_TO_CCR,
|
||||
MOVE_FROM_SR, MOVE_TO_SR, MOVE_USP, MOVEA, MOVEC, MOVEM, MOVEP, MOVEQ, MOVES, MULS, MULU, NBCD, NEG,
|
||||
NEGX, NOP, NOT_B, OR_B, ORI, ORI_TO_CCR, ORI_TO_SR, PACK, PEA, RESET, ROTL, ROTR, ROXL, ROXR, RTD,
|
||||
RTE, RTR, RTS, SBCD, Scc, STOP, SUB, SUBA, SUBI, SUBQ, SUBX, SWAP, TAS, TRAP, TRAPcc, TRAPV, TST,
|
||||
UNLK, UNPK, UNIMPLEMENTED);
|
||||
|
||||
type TRAPTYPE_OPC is(NONE, T_1010, T_1111, T_ILLEGAL, T_TRAP, T_PRIV, T_RTE); -- None is the first entry and default.
|
||||
|
||||
component WF68K30L_ADDRESS_REGISTERS
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
AR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
AR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
AR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
AR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
INDEX_IN : in std_logic_vector(31 downto 0);
|
||||
PC : out std_logic_vector(31 downto 0);
|
||||
PC_EW_OFFSET : in std_logic_vector(3 downto 0);
|
||||
FETCH_MEM_ADR : in bit;
|
||||
STORE_ADR_FORMAT : in bit;
|
||||
STORE_ABS_HI : in bit;
|
||||
STORE_ABS_LO : in bit;
|
||||
STORE_D16 : in bit;
|
||||
STORE_D32_LO : in bit;
|
||||
STORE_D32_HI : in bit;
|
||||
STORE_DISPL : in bit;
|
||||
STORE_MEM_ADR : in bit;
|
||||
STORE_OD_HI : in bit;
|
||||
STORE_OD_LO : in bit;
|
||||
STORE_AEFF : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
ADR_OFFSET : in std_logic_vector(31 downto 0);
|
||||
ADR_MARK_USED : in bit;
|
||||
ADR_IN_USE : out bit;
|
||||
ADR_MODE : in std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : in std_logic_vector(2 downto 0);
|
||||
USE_DREG : in bit;
|
||||
ADR_EFF : out std_logic_vector(31 downto 0);
|
||||
ADR_EFF_WB : out std_logic_vector(31 downto 0);
|
||||
DFC : out std_logic_vector(2 downto 0);
|
||||
DFC_WR : in bit;
|
||||
SFC : out std_logic_vector(2 downto 0);
|
||||
SFC_WR : in bit;
|
||||
ISP_DEC : in bit;
|
||||
ISP_RD : in bit;
|
||||
ISP_WR : in bit;
|
||||
MSP_RD : in bit;
|
||||
MSP_WR : in bit;
|
||||
USP_RD : in bit;
|
||||
USP_WR : in bit;
|
||||
AR_MARK_USED : in bit;
|
||||
USE_APAIR : in boolean;
|
||||
AR_IN_USE : out bit;
|
||||
AR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
AR_DEC : in bit;
|
||||
AR_INC : in bit;
|
||||
AR_WR_1 : in bit;
|
||||
AR_WR_2 : in bit;
|
||||
UNMARK : in bit;
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
MBIT : in std_logic;
|
||||
SBIT : in std_logic;
|
||||
SP_ADD_DISPL : in bit;
|
||||
RESTORE_ISP_PC : in bit;
|
||||
DISPLACEMENT : in std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : in bit;
|
||||
PC_INC : in bit;
|
||||
PC_LOAD : in bit;
|
||||
PC_RESTORE : in bit;
|
||||
PC_OFFSET : in std_logic_vector(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_ALU
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
LOAD_OP1 : in bit;
|
||||
LOAD_OP2 : in bit;
|
||||
LOAD_OP3 : in bit;
|
||||
OP1_IN : in std_logic_vector(31 downto 0);
|
||||
OP2_IN : in std_logic_vector(31 downto 0);
|
||||
OP3_IN : in std_logic_vector(31 downto 0);
|
||||
BF_OFFSET_IN : in Std_Logic_Vector(31 downto 0);
|
||||
BF_WIDTH_IN : in Std_Logic_Vector(5 downto 0);
|
||||
BITPOS_IN : in Std_Logic_Vector(4 downto 0);
|
||||
RESULT : out std_logic_vector(63 downto 0);
|
||||
ADR_MODE_IN : in std_logic_vector(2 downto 0);
|
||||
OP_SIZE_IN : in OP_SIZETYPE;
|
||||
OP_IN : in OP_68K;
|
||||
OP_WB : in OP_68K;
|
||||
BIW_0_IN : in std_logic_vector(11 downto 0);
|
||||
BIW_1_IN : in std_logic_vector(15 downto 0);
|
||||
SR_WR : in bit;
|
||||
SR_INIT : in bit;
|
||||
SR_CLR_MBIT : in bit;
|
||||
CC_UPDT : in bit;
|
||||
STATUS_REG_OUT : out std_logic_vector(15 downto 0);
|
||||
ALU_COND : out boolean;
|
||||
ALU_INIT : in bit;
|
||||
ALU_BSY : out bit;
|
||||
ALU_REQ : out bit;
|
||||
ALU_ACK : in bit;
|
||||
USE_DREG : in bit;
|
||||
HILOn : in bit;
|
||||
IRQ_PEND : in std_logic_vector(2 downto 0);
|
||||
TRAP_CHK : out bit;
|
||||
TRAP_DIVZERO : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_BUS_INTERFACE
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
ADR_IN_P : in std_logic_vector(31 downto 0);
|
||||
ADR_OUT_P : out std_logic_vector(31 downto 0);
|
||||
FC_IN : in std_logic_vector(2 downto 0);
|
||||
FC_OUT : out std_logic_vector(2 downto 0);
|
||||
DATA_PORT_IN : in std_logic_vector(31 downto 0);
|
||||
DATA_PORT_OUT : out std_logic_vector(31 downto 0);
|
||||
DATA_FROM_CORE : in std_logic_vector(31 downto 0);
|
||||
DATA_TO_CORE : out std_logic_vector(31 downto 0);
|
||||
OPCODE_TO_CORE : out std_logic_vector(15 downto 0);
|
||||
DATA_PORT_EN : out std_logic;
|
||||
BUS_EN : out std_logic;
|
||||
SIZE : out std_logic_vector(1 downto 0);
|
||||
OP_SIZE : in OP_SIZETYPE;
|
||||
RD_REQ : in bit;
|
||||
WR_REQ : in bit;
|
||||
DATA_RDY : out bit;
|
||||
DATA_VALID : out std_logic;
|
||||
OPCODE_REQ : in bit;
|
||||
OPCODE_RDY : out bit;
|
||||
OPCODE_VALID : out std_logic;
|
||||
RMC : in bit;
|
||||
BUSY_EXH : in bit;
|
||||
INBUFFER : out std_logic_vector(31 downto 0);
|
||||
OUTBUFFER : out std_logic_vector(31 downto 0);
|
||||
SSW_80 : out std_logic_vector(8 downto 0);
|
||||
DSACKn : in std_logic_vector(1 downto 0);
|
||||
ASn : out std_logic;
|
||||
DSn : out std_logic;
|
||||
RWn : out std_logic;
|
||||
RMCn : out std_logic;
|
||||
ECSn : out std_logic;
|
||||
OCSn : out std_logic;
|
||||
DBENn : out std_logic;
|
||||
STERMn : in std_logic;
|
||||
BRn : in std_logic;
|
||||
BGACKn : in std_logic;
|
||||
BGn : out std_logic;
|
||||
RESET_STRB : in bit;
|
||||
RESET_IN : in std_logic;
|
||||
RESET_OUT : out std_logic;
|
||||
RESET_CPU : out bit;
|
||||
AVECn : in std_logic;
|
||||
HALTn : in std_logic;
|
||||
BERRn : in std_logic;
|
||||
AERR : out bit;
|
||||
BUS_BSY : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_CONTROL
|
||||
generic(NO_PIPELINE : boolean := false); -- If true the controller work in scalar mode.
|
||||
port(
|
||||
CLK : in std_logic;
|
||||
RESET_CPU : in bit;
|
||||
BUSY : out bit;
|
||||
BUSY_EXH : in bit;
|
||||
EXH_REQ : in bit;
|
||||
INT_TRIG : out bit;
|
||||
OW_REQ : out bit;
|
||||
OW_VALID : in std_logic;
|
||||
EW_REQ : out bit;
|
||||
EW_ACK : in bit;
|
||||
OPD_ACK : in bit;
|
||||
ADR_MARK_USED : out bit;
|
||||
ADR_IN_USE : in bit;
|
||||
ADR_OFFSET : out std_logic_vector(5 downto 0);
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
RMC : out bit;
|
||||
FETCH_MEM_ADR : out bit;
|
||||
LOAD_OP2 : out bit;
|
||||
LOAD_OP3 : out bit;
|
||||
LOAD_OP1 : out bit;
|
||||
STORE_ADR_FORMAT : out bit;
|
||||
STORE_D16 : out bit;
|
||||
STORE_D32_LO : out bit;
|
||||
STORE_D32_HI : out bit;
|
||||
STORE_DISPL : out bit;
|
||||
STORE_OD_HI : out bit;
|
||||
STORE_OD_LO : out bit;
|
||||
STORE_ABS_HI : out bit;
|
||||
STORE_ABS_LO : out bit;
|
||||
STORE_IDATA_B2 : out bit;
|
||||
STORE_IDATA_B1 : out bit;
|
||||
STORE_MEM_ADR : out bit;
|
||||
STORE_AEFF : out bit;
|
||||
OP : in OP_68K;
|
||||
OP_SIZE : out OP_SIZETYPE;
|
||||
BIW_0 : in std_logic_vector(13 downto 0);
|
||||
BIW_1 : in std_logic_vector(15 downto 0);
|
||||
BIW_2 : in std_logic_vector(15 downto 0);
|
||||
EXT_WORD : in std_logic_vector(15 downto 0);
|
||||
ADR_MODE : out std_logic_vector(2 downto 0);
|
||||
AMODE_SEL : out std_logic_vector(2 downto 0);
|
||||
USE_DREG : out bit;
|
||||
HILOn : out bit;
|
||||
OP_WB : out OP_68K;
|
||||
OP_SIZE_WB : out OP_SIZETYPE;
|
||||
BIW_0_WB_73 : out std_logic_vector(7 downto 3);
|
||||
AR_MARK_USED : out bit;
|
||||
USE_APAIR : out boolean;
|
||||
AR_IN_USE : in bit;
|
||||
AR_SEL_RD_1 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_RD_2 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_1 : out std_logic_vector(2 downto 0);
|
||||
AR_SEL_WR_2 : out std_logic_vector(2 downto 0);
|
||||
AR_INC : out bit;
|
||||
AR_DEC : out bit;
|
||||
AR_WR_1 : out bit;
|
||||
AR_WR_2 : out bit;
|
||||
DR_MARK_USED : out bit;
|
||||
USE_DPAIR : out boolean;
|
||||
DR_IN_USE : in bit;
|
||||
DR_SEL_RD_1 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_1 : out std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : out std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : out bit;
|
||||
DR_WR_2 : out bit;
|
||||
UNMARK : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(31 downto 0);
|
||||
PC_ADD_DISPL : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_INC_EXH : in bit;
|
||||
SP_ADD_DISPL : out bit;
|
||||
DFC_WR : out bit;
|
||||
DFC_RD : out bit;
|
||||
SFC_WR : out bit;
|
||||
SFC_RD : out bit;
|
||||
VBR_WR : out bit;
|
||||
VBR_RD : out bit;
|
||||
ISP_RD : out bit;
|
||||
ISP_WR : out bit;
|
||||
MSP_RD : out bit;
|
||||
MSP_WR : out bit;
|
||||
USP_RD : out bit;
|
||||
USP_WR : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
ALU_INIT : out bit;
|
||||
ALU_BSY : in bit;
|
||||
ALU_REQ : in bit;
|
||||
ALU_ACK : out bit;
|
||||
BKPT_CYCLE : out bit;
|
||||
BKPT_INSERT : out bit;
|
||||
LOOP_BSY : in bit;
|
||||
LOOP_SPLIT : out boolean;
|
||||
LOOP_EXIT : out bit;
|
||||
BF_OFFSET : in Std_Logic_Vector(2 downto 0);
|
||||
BF_WIDTH : in Std_Logic_Vector(5 downto 0);
|
||||
SR_WR : out bit;
|
||||
MOVEM_ADn : out bit;
|
||||
MOVEP_PNTR : out integer range 0 to 3;
|
||||
CC_UPDT : out bit;
|
||||
TRACE_MODE : in std_logic_vector(1 downto 0);
|
||||
VBIT : in std_logic;
|
||||
ALU_COND : in boolean;
|
||||
DBcc_COND : in boolean;
|
||||
BRANCH_ATN : in bit;
|
||||
RESET_STRB : out bit;
|
||||
BERR : out bit;
|
||||
STATUSn : out bit;
|
||||
EX_TRACE : out bit;
|
||||
TRAP_cc : out bit;
|
||||
TRAP_ILLEGAL : out bit;
|
||||
TRAP_V : out bit
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_DATA_REGISTERS
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
DR_IN_1 : in std_logic_vector(31 downto 0);
|
||||
DR_IN_2 : in std_logic_vector(31 downto 0);
|
||||
DR_OUT_1 : out std_logic_vector(31 downto 0);
|
||||
DR_OUT_2 : out std_logic_vector(31 downto 0);
|
||||
DR_SEL_WR_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_WR_2 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_1 : in std_logic_vector(2 downto 0);
|
||||
DR_SEL_RD_2 : in std_logic_vector(2 downto 0);
|
||||
DR_WR_1 : in bit;
|
||||
DR_WR_2 : in bit;
|
||||
DR_MARK_USED : in bit;
|
||||
USE_DPAIR : in boolean;
|
||||
DR_IN_USE : out bit;
|
||||
UNMARK : in bit;
|
||||
OP_SIZE : in OP_SIZETYPE
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_EXCEPTION_HANDLER
|
||||
generic(VERSION : std_logic_vector(31 downto 0));
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
RESET : in bit;
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : in bit;
|
||||
EXH_REQ : out bit;
|
||||
BUSY_EXH : out bit;
|
||||
ADR_IN : in std_logic_vector(31 downto 0);
|
||||
ADR_CPY : out std_logic_vector(31 downto 0);
|
||||
ADR_OFFSET : out std_logic_vector(31 downto 0);
|
||||
CPU_SPACE : out bit;
|
||||
DATA_0 : in std_logic;
|
||||
DATA_RD : out bit;
|
||||
DATA_WR : out bit;
|
||||
DATA_IN : in std_logic_vector(31 downto 0);
|
||||
OP_SIZE : out OP_SIZETYPE;
|
||||
DATA_RDY : in bit;
|
||||
DATA_VALID : in std_logic;
|
||||
OPCODE_RDY : in bit;
|
||||
OPD_ACK : in bit; -- Opword is available.
|
||||
OW_VALID : in std_logic;
|
||||
STATUS_REG_IN : in std_logic_vector(15 downto 0);
|
||||
SR_CPY : out std_logic_vector(15 downto 0);
|
||||
SR_INIT : out bit;
|
||||
SR_CLR_MBIT : out bit;
|
||||
SR_WR : out bit;
|
||||
ISP_DEC : out bit;
|
||||
ISP_LOAD : out bit;
|
||||
PC_INC : out bit;
|
||||
PC_LOAD : out bit;
|
||||
PC_RESTORE : out bit;
|
||||
STACK_FORMAT : out std_logic_vector(3 downto 0);
|
||||
STACK_POS : out integer range 0 to 46;
|
||||
SP_ADD_DISPL : out bit;
|
||||
DISPLACEMENT : out std_logic_vector(7 downto 0);
|
||||
IPIPE_FILL : out bit;
|
||||
IPIPE_FLUSH : out bit;
|
||||
REFILLn : out std_logic;
|
||||
RESTORE_ISP_PC : out bit;
|
||||
HALT_OUTn : out std_logic;
|
||||
STATUSn : out bit;
|
||||
INT_TRIG : in bit;
|
||||
IRQ_IN : in std_logic_vector(2 downto 0);
|
||||
IRQ_PEND : out std_logic_vector(2 downto 0);
|
||||
AVECn : in std_logic;
|
||||
IPENDn : out std_logic;
|
||||
IVECT_OFFS : out std_logic_vector(9 downto 0);
|
||||
TRAP_AERR : in bit;
|
||||
TRAP_BERR : in bit;
|
||||
TRAP_CHK : in bit;
|
||||
TRAP_DIVZERO : in bit;
|
||||
TRAP_ILLEGAL : in bit;
|
||||
TRAP_CODE_OPC : in TRAPTYPE_OPC;
|
||||
TRAP_VECTOR : in std_logic_vector(3 downto 0);
|
||||
TRAP_cc : in bit;
|
||||
TRAP_V : in bit;
|
||||
EX_TRACE_IN : in bit;
|
||||
VBR_WR : in bit;
|
||||
VBR : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component WF68K30L_OPCODE_DECODER
|
||||
generic(NO_LOOP : boolean := false); -- If true the DBcc loop mechanism is disabled.
|
||||
port (
|
||||
CLK : in std_logic;
|
||||
OW_REQ_MAIN : in bit;
|
||||
EW_REQ_MAIN : in bit;
|
||||
EXH_REQ : in bit;
|
||||
BUSY_EXH : in bit;
|
||||
BUSY_MAIN : in bit;
|
||||
BUSY_OPD : out bit;
|
||||
BKPT_INSERT : in bit;
|
||||
BKPT_DATA : in std_logic_vector(15 downto 0);
|
||||
LOOP_EXIT : in bit;
|
||||
LOOP_BSY : out bit;
|
||||
OPD_ACK_MAIN : out bit;
|
||||
EW_ACK : out bit;
|
||||
PC_EW_OFFSET : out std_logic_vector(3 downto 0);
|
||||
PC_INC : out bit;
|
||||
PC_INC_EXH : in bit;
|
||||
PC_ADR_OFFSET : out std_logic_vector(7 downto 0);
|
||||
PC_OFFSET : out std_logic_vector(7 downto 0);
|
||||
OPCODE_RD : out bit;
|
||||
OPCODE_RDY : in bit;
|
||||
OPCODE_VALID : in std_logic;
|
||||
OPCODE_DATA : in std_logic_vector(15 downto 0);
|
||||
IPIPE_FILL : in bit;
|
||||
IPIPE_FLUSH : in bit;
|
||||
OW_VALID : out std_logic;
|
||||
RC : out std_logic;
|
||||
RB : out std_logic;
|
||||
FC : out std_logic;
|
||||
FB : out std_logic;
|
||||
SBIT : in std_logic;
|
||||
TRAP_CODE : out TRAPTYPE_OPC;
|
||||
OP : out OP_68K;
|
||||
BIW_0 : out std_logic_vector(15 downto 0);
|
||||
BIW_1 : out std_logic_vector(15 downto 0);
|
||||
BIW_2 : out std_logic_vector(15 downto 0);
|
||||
EXT_WORD : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
end WF68K30L_PKG;
|
||||
1212
common/CPU/68K30L/wf68k30L_top.vhd
Normal file
1212
common/CPU/68K30L/wf68k30L_top.vhd
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user