1
0
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:
Marcel
2020-09-06 18:16:38 +02:00
parent 676a48a545
commit 7e1b772d56
30 changed files with 19582 additions and 0 deletions

Binary file not shown.

Binary file not shown.

View 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>
&nbsp;
<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 (&quot;CERN OHL&quot;) 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 &quot;as is&quot; 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>

Binary file not shown.

Binary file not shown.

View 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}

View 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;

File diff suppressed because it is too large Load Diff

View 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;

File diff suppressed because it is too large Load Diff

View 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;

View 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;

File diff suppressed because it is too large Load Diff

View 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;

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View 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>
&nbsp;
<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 (&quot;CERN OHL&quot;) 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 &quot;as is&quot; 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>

Binary file not shown.

Binary file not shown.

View 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}

View 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;

File diff suppressed because it is too large Load Diff

View 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;

File diff suppressed because it is too large Load Diff

View 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;

View 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;

File diff suppressed because it is too large Load Diff

View 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;

File diff suppressed because it is too large Load Diff