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

Subversion Repositories tv80

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /tv80/trunk
    from Rev 109 to Rev 110
    Reverse comparison

Rev 109 → Rev 110

/doc/rgen_doc.html
0,0 → 1,451
<!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" dir="ltr" lang="en"><head>
 
 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>rgen.py [TV80 Design]</title>
 
<meta name="generator" content="DokuWiki Release rc2006-10-08">
<meta name="robots" content="index,follow">
<meta name="date" content="2011-02-24T16:12:15-0800">
<meta name="keywords" content="rgen.py">
<link rel="start" href="http://192.168.1.1/dokuwiki/">
<link rel="contents" href="http://192.168.1.1/dokuwiki/doku.php?id=rgen.py&amp;do=index" title="Index">
<link rel="alternate" type="application/rss+xml" title="Recent Changes" href="http://192.168.1.1/dokuwiki/feed.php">
<link rel="alternate" type="application/rss+xml" title="Current Namespace" href="http://192.168.1.1/dokuwiki/feed.php?mode=list&amp;ns=">
<link rel="alternate" type="text/html" title="Plain HTML" href="http://192.168.1.1/dokuwiki/doku.php?do=export_xhtml&amp;id=rgen.py">
<link rel="alternate" type="text/plain" title="Wiki Markup" href="http://192.168.1.1/dokuwiki/doku.php?do=export_raw&amp;id=rgen.py">
<link rel="stylesheet" media="screen" type="text/css" href="rgen_doc_files/css.php">
<link rel="stylesheet" media="print" type="text/css" href="rgen_doc_files/css_002.php">
<script type="text/javascript" charset="utf-8" src="rgen_doc_files/js.php"></script>
 
<link rel="shortcut icon" href="http://192.168.1.1/dokuwiki/lib/tpl/default/images/favicon.ico"></head><body>
<div class="dokuwiki">
<div class="stylehead">
 
<div class="header">
<div class="pagename">
[[<a href="http://192.168.1.1/dokuwiki/doku.php?id=rgen.py&amp;do=backlink">rgen.py</a>]]
</div>
<div class="logo">
<a href="http://192.168.1.1/dokuwiki/doku.php?id=" name="dokuwiki__top" id="dokuwiki__top" accesskey="h" title="[ALT+H]">TV80 Design</a> </div>
 
<div class="clearer"></div>
</div>
 
<div class="bar" id="bar__top">
<div class="bar-left" id="bar__topleft">
<form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="rev" value="" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit this page" class="button" accesskey="e" title="Edit this page [ALT+E]" type="submit"></div></form> <form class="button" method="get" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="revisions" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Old revisions" class="button" accesskey="o" title="Old revisions [ALT+O]" type="submit"></div></form> </div>
 
<div class="bar-right" id="bar__topright">
<form class="button" method="get" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="recent" type="hidden"><input name="id" value="" type="hidden"><input value="Recent changes" class="button" accesskey="r" title="Recent changes [ALT+R]" type="submit"></div></form> <form action="/dokuwiki/doku.php?id=" accept-charset="utf-8" class="search" id="dw__search"><div class="no"><input name="do" value="search" type="hidden"><input id="qsearch__in" accesskey="f" name="id" class="edit" title="[ALT+F]" type="text"><input value="Search" class="button" title="Search" type="submit"><div id="qsearch__out" class="ajax_qsearch JSpopup"></div></div></form>&nbsp;
</div>
 
<div class="clearer"></div>
</div>
 
<div class="breadcrumbs">
Trace: <span class="bcsep">»</span> <a href="http://192.168.1.1/dokuwiki/doku.php?id=start" class="breadcrumbs" title="start">start</a> <span class="bcsep">»</span> <span class="curid"><a href="http://192.168.1.1/dokuwiki/doku.php?id=rgen.py" class="breadcrumbs" title="rgen.py">rgen.py</a></span> </div>
</div>
<div class="page">
<!-- wikipage start -->
<div class="toc">
<div class="tocheader toctoggle" id="toc__header"><img alt="-" src="rgen_doc_files/arrow_up.gif" id="toc__hide"><img style="display: none;" alt="+" src="rgen_doc_files/arrow_down.gif" id="toc__show">Table of Contents</div>
<div id="toc__inside">
 
<ul class="toc">
<li class="level1"><div class="li"><span class="li"><a href="#rgen_register_file_and_decoder_generator" class="toc">rgen Register File and Decoder Generator</a></span></div></li>
<li class="level1"><div class="li"><span class="li"><a href="#register_file_generator" class="toc">Register File Generator</a></span></div>
<ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#tag_definitions" class="toc">Tag Definitions</a></span></div>
<ul class="toc">
<li class="level3"><div class="li"><span class="li"><a href="#config" class="toc">config</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#status" class="toc">status</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#count" class="toc">count</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#int_msk" class="toc">int_msk</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#soft_set" class="toc">soft_set</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#write_stb" class="toc">write_stb</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#read_stb" class="toc">read_stb</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#ext_load" class="toc">ext_load</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#user" class="toc">user</a></span></div></li>
</ul>
</li>
</ul>
</li>
<li class="level1"><div class="li"><span class="li"><a href="#decoder_generator" class="toc">Decoder Generator</a></span></div></li></ul>
</div>
</div>
 
 
 
<h1><a name="rgen_register_file_and_decoder_generator" id="rgen_register_file_and_decoder_generator">rgen Register File and Decoder Generator</a></h1>
<div class="level1">
 
<p> rgen is a Python script for generating a hierarchical set of
register files and address decoders. It supports a variety of register
types and multiple levels of address decoding hieararchy.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="1-248" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="rgen Register File and Decoder Generator" type="submit"></div></form></div>
<h1><a name="register_file_generator" id="register_file_generator">Register File Generator</a></h1>
<div class="level1">
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="249-286" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="Register File Generator" type="submit"></div></form></div>
<h2><a name="tag_definitions" id="tag_definitions">Tag Definitions</a></h2>
<div class="level2">
<table class="inline">
<tbody><tr>
<th>tag name</th><th>attributes</th><th>description</th>
</tr>
<tr>
<td>tv_registers</td><td>name,addr_sz,data_sz,base_addr,registered_read</td><td>top-level tag for a register file</td>
</tr>
<tr>
<td>register</td><td>name,type,width,default</td><td>tag for a single logical register</td>
</tr>
<tr>
<td>field</td><td>name,width,default</td><td>tag for a bit field within a single register</td>
</tr>
</tbody></table>
<table class="inline">
<tbody><tr>
<th>register type</th><th>Access</th><th>description</th>
</tr>
<tr>
<td><a href="#config" title="rgen.py ↵" class="wikilink1">config</a></td><td>RW</td><td>General read-write configuration register</td>
</tr>
<tr>
<td><a href="#status" title="rgen.py ↵" class="wikilink1">status</a></td><td>RO</td><td>Read-only status register</td>
</tr>
<tr>
<td><a href="#count" title="rgen.py ↵" class="wikilink1">count</a></td><td>RW</td><td>Incrementing statistics register</td>
</tr>
<tr>
<td><a href="#int_msk" title="rgen.py ↵" class="wikilink1">int_msk</a></td><td>Special</td><td>Interrupt status &amp; mask registers</td>
</tr>
<tr>
<td><a href="#soft_set" title="rgen.py ↵" class="wikilink1">soft_set</a></td><td>RW</td><td>Software set, hardware clear register</td>
</tr>
<tr>
<td><a href="#write_stb" title="rgen.py ↵" class="wikilink1">write_stb</a></td><td>RW</td><td>Configuration register with additional strobe output</td>
</tr>
<tr>
<td><a href="#read_stb" title="rgen.py ↵" class="wikilink1">read_stb</a></td><td>RW</td><td>Configuration register with additional strobe outout</td>
</tr>
<tr>
<td><a href="#ext_load" title="rgen.py ↵" class="wikilink1">ext_load</a></td><td>RW</td><td>External-load register</td>
</tr>
<tr>
<td><a href="#user" title="rgen.py ↵" class="wikilink1">user</a></td><td>Special</td><td>User-defined pass-through register</td>
</tr>
</tbody></table>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="287-1131" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="Tag Definitions" type="submit"></div></form></div>
<h3><a name="config" id="config">config</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>output</td><td>WIDTH</td><td>Read-only value of config bits</td>
</tr>
</tbody></table>
 
<p>
Basic configuration register, read/write by the configuration side, register bits available read-only from the hardware side.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="1132-1367" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="config" type="submit"></div></form></div>
<h3><a name="status" id="status">status</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>input</td><td>WIDTH</td><td>status input bits</td>
</tr>
</tbody></table>
 
<p>
Status register, read-only by the config side, status bits are combinatorial input from the hardware side.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="1368-1570" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="status" type="submit"></div></form></div>
<h3><a name="count" id="count">count</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>output</td><td>WIDTH</td><td>current count value</td>
</tr>
<tr>
<td>NAME_inc</td><td>input</td><td>1</td><td>When high, increment count by 1</td>
</tr>
</tbody></table>
 
<p> Basic statistics register. Read/write by config side, count value
available read-only from hardware side. Increment value provided for
hardware side.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="1571-1871" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="count" type="submit"></div></form></div>
<h3><a name="int_msk" id="int_msk">int_msk</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME_set</td><td>input</td><td>WIDTH</td><td>set interrupt</td>
</tr>
</tbody></table>
 
<p> The int_msk register type provides a pair of interrupt registers.
The first register is the interrupt status register, and the second is
the interrupt mask register. The interrupt status register can be set
by hardware and cleared by software by writing a ‘1’ to the bit which
should be cleared. Software cannot set any bits in the interrupt
register, and writing ‘0’ to a bit has no effect (leave unchanged).
</p>
 
<p>The paired mask register has the same number of bits as the status
register, but each bit set in the mask register disables interrupt
generation for the corresponding status bit. Note that even if
interrupt generation is disabled, the status bit will still be set. The
mask register is Read/Write by software.
</p>
 
<p>The default attribute for this register type sets the default value
of the mask register; the default value of the status register is
always zero.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="1872-2842" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="int_msk" type="submit"></div></form></div>
<h3><a name="soft_set" id="soft_set">soft_set</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>output</td><td>WIDTH</td><td>Read-only value of config bits</td>
</tr>
<tr>
<td>NAME_clr</td><td>input</td><td>WIDTH</td><td>Read-only value of config bits</td>
</tr>
</tbody></table>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="2843-3007" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="soft_set" type="submit"></div></form></div>
<h3><a name="write_stb" id="write_stb">write_stb</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>output</td><td>WIDTH</td><td>Read-only value of config bits</td>
</tr>
<tr>
<td>NAME_wr_stb</td><td>output</td><td>1</td><td>Pulses on write to this register</td>
</tr>
</tbody></table>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="3008-3175" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="write_stb" type="submit"></div></form></div>
<h3><a name="read_stb" id="read_stb">read_stb</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME</td><td>output</td><td>WIDTH</td><td>Read-only value of config bits</td>
</tr>
<tr>
<td>NAME_wr_stb</td><td>output</td><td>1</td><td>Pulses on read to this register</td>
</tr>
</tbody></table>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="3176-3341" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="read_stb" type="submit"></div></form></div>
<h3><a name="ext_load" id="ext_load">ext_load</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME_out</td><td>output</td><td>WIDTH</td><td>Data from config interface</td>
</tr>
<tr>
<td>NAME_in</td><td>input</td><td>WIDTH</td><td>Sample data in to config interface</td>
</tr>
<tr>
<td>NAME_wr_stb</td><td>output</td><td>1</td><td>Pulsed on final write operation</td>
</tr>
<tr>
<td>NAME_rd_stb</td><td>output</td><td>1</td><td>Pulsed on initial read operation</td>
</tr>
</tbody></table>
 
<p> An external-load register is used to sample and cache values which
may be changing over time. It is intended to be used for values which
are wider than the configuration interface (otherwise, a <a href="#status" title="rgen.py ↵" class="wikilink1">status</a> or <a href="#write_stb" title="rgen.py ↵" class="wikilink1">write_stb</a>
register would be more appropriate). The width of an ext_load register
can be wider than the data_sz width of the module, and rgen will split
the logical register into multiple physical registers.
</p>
 
<p>
Current limitations: ext_load registers must be an even multiple of data_size otherwise syntax errors will result.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="3342-4161" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="ext_load" type="submit"></div></form></div>
<h3><a name="user" id="user">user</a></h3>
<div class="level3">
<table class="inline">
<tbody><tr>
<th>port name</th><th>direction</th><th>size</th><th>description</th>
</tr>
<tr>
<td>NAME_wr_data</td><td>output</td><td>WIDTH</td><td>Data from config on write</td>
</tr>
<tr>
<td>NAME_wr_stb</td><td>output</td><td>1</td><td>Asserted during write operation</td>
</tr>
<tr>
<td>NAME_wr_ack</td><td>input</td><td>1</td><td>Assert by HW side to acknowledge write</td>
</tr>
<tr>
<td>NAME_rd_data</td><td>input</td><td>WIDTH</td><td>Data to config on read</td>
</tr>
<tr>
<td>NAME_rd_stb</td><td>output</td><td>1</td><td>Asserted during read operation</td>
</tr>
<tr>
<td>NAME_rd_ack</td><td>input</td><td>1</td><td>Assert by HW side to acknowledge read</td>
</tr>
</tbody></table>
 
<p> Register with user-defined behavior. Used to implement registers
with read-side effects, or where config interface must arbitrate with
the HW datapath for access to a resource. Provides full handshake for
each of read and write operations.
</p>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="4162-4794" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="user" type="submit"></div></form></div>
<h1><a name="decoder_generator" id="decoder_generator">Decoder Generator</a></h1>
<div class="level1">
 
<p>
Decoders are created using a different set of tags from the register file generator.
</p>
<table class="inline">
<tbody><tr>
<th>tag name</th><th>attributes</th><th>description</th>
</tr>
<tr>
<td>it_decoder</td><td>name,addr_sz,data_sz</td><td>top-level tag for an address decoder</td>
</tr>
<tr>
<td>range</td><td>prefix,base,bits</td><td>tag for an address decode range</td>
</tr>
</tbody></table>
 
</div>
<div class="secedit"><form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="lines" value="4795-" type="hidden"><input name="rev" value="1298592735" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit" class="button" title="Decoder Generator" type="submit"></div></form></div>
<!-- wikipage stop -->
</div>
 
<div class="clearer">&nbsp;</div>
 
<div class="stylefoot">
 
<div class="meta">
<div class="user">
</div>
<div class="doc">
rgen.py.txt · Last modified: 2011/02/24 16:12 by 10.81.24.204 </div>
</div>
 
<div class="bar" id="bar__bottom">
<div class="bar-left" id="bar__bottomleft">
<form class="button" method="post" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="edit" type="hidden"><input name="rev" value="" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Edit this page" class="button" accesskey="e" title="Edit this page [ALT+E]" type="submit"></div></form> <form class="button" method="get" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="revisions" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Old revisions" class="button" accesskey="o" title="Old revisions [ALT+O]" type="submit"></div></form> </div>
<div class="bar-right" id="bar__bottomright">
<form class="button" method="get" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="login" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Login" class="button" title="Login" type="submit"></div></form> <form class="button" method="get" action="/dokuwiki/doku.php"><div class="no"><input name="do" value="index" type="hidden"><input name="id" value="rgen.py" type="hidden"><input value="Index" class="button" accesskey="x" title="Index [ALT+X]" type="submit"></div></form> <a class="nolink" href="#dokuwiki__top"><input class="button" value="Back to top" onclick="window.scrollTo(0, 0)" title="Back to top" type="button"></a>&nbsp;
</div>
<div class="clearer"></div>
</div>
 
</div>
 
</div>
 
<div class="footerinc">
<a href="http://192.168.1.1/dokuwiki/feed.php" title="Recent changes RSS feed"><img src="rgen_doc_files/button-rss.png" alt="Recent changes RSS feed" height="15" width="80"></a>
 
<a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" rel="license" title="Creative Commons License"><img src="rgen_doc_files/button-cc.gif" alt="Creative Commons License" height="15" width="80"></a>
 
<a href="https://www.paypal.com/xclick/business=andi%40splitbrain.org&amp;item_name=DokuWiki+Donation&amp;no_shipping=1&amp;no_note=1&amp;tax=0&amp;currency_code=EUR&amp;lc=US" title="Donate"><img src="rgen_doc_files/button-donate.gif" alt="Donate" height="15" width="80"></a>
 
<a href="http://www.php.net/" title="Powered by PHP"><img src="rgen_doc_files/button-php.gif" alt="Powered by PHP" height="15" width="80"></a>
 
<a href="http://validator.w3.org/check/referer" title="Valid XHTML 1.0"><img src="rgen_doc_files/button-xhtml.png" alt="Valid XHTML 1.0" height="15" width="80"></a>
 
<a href="http://jigsaw.w3.org/css-validator/check/referer" title="Valid CSS"><img src="rgen_doc_files/button-css.png" alt="Valid CSS" height="15" width="80"></a>
 
<a href="http://wiki.splitbrain.org/wiki:dokuwiki" title="Driven by DokuWiki"><img src="rgen_doc_files/button-dw.png" alt="Driven by DokuWiki" height="15" width="80"></a>
 
 
 
<!--
 
<rdf:RDF xmlns="http://web.resource.org/cc/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<Work rdf:about="">
<dc:type rdf:resource="http://purl.org/dc/dcmitype/Text" />
<license rdf:resource="http://creativecommons.org/licenses/by-nc-sa/2.0/" />
</Work>
 
<License rdf:about="http://creativecommons.org/licenses/by-nc-sa/2.0/">
<permits rdf:resource="http://web.resource.org/cc/Reproduction" />
<permits rdf:resource="http://web.resource.org/cc/Distribution" />
<requires rdf:resource="http://web.resource.org/cc/Notice" />
<requires rdf:resource="http://web.resource.org/cc/Attribution" />
<prohibits rdf:resource="http://web.resource.org/cc/CommercialUse" />
<permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
</License>
 
</rdf:RDF>
 
-->
 
 
</div>
 
<div class="no"><img src="rgen_doc_files/indexer.php" alt="" height="1" width="1"></div>
</body></html>
/scripts/rgen.py
1,4 → 1,4
#!/usr/bin/python
#!/usr/bin/env python
# Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
#
# Permission is hereby granted, free of charge, to any person obtaining a
21,15 → 21,54
 
# This script generates I/O mapped control and status registers based
# on an XML configuration file.
#
 
import reglib
import xml.dom.minidom
import sys, os, re
import sys, os, re, string
 
def node_info (node):
print "Methods:",dir(node)
print "Child Nodes:",node.childNodes
 
def create_addr_vh (filename, dg):
fh = open (filename, 'w')
for d in dg.ranges:
print repr(d)
ba = d.get_base_addr()
fh.write ("`define %s 'h%x\n" % (d.name.upper(), ba))
fh.close()
def create_addr_decoder (node):
rg = reglib.decoder_group()
 
rg.name = node.getAttribute ("name")
rg.addr_size = reglib.number(node.getAttribute ("addr_sz"))
 
data_sz = node.getAttribute ("data_sz")
if (data_sz != ''):
rg.data_size = reglib.number(data_sz)
 
return rg
 
def create_decoder_verilog (top_node):
dg = create_addr_decoder (top_node)
 
# get list of address ranges
range_nodes = top_node.getElementsByTagName ("range")
for rn in range_nodes:
prefix = rn.getAttribute ("prefix")
base = reglib.number(rn.getAttribute ("base"))
bits = int(rn.getAttribute ("bits"))
r = reglib.decoder_range (prefix, base, bits)
dg.add_range (r)
 
fname = dg.name + ".v"
fh = open (fname, 'w')
fh.write (dg.verilog())
fh.close()
create_addr_vh (dg.name + ".vh", dg)
def create_reg_group (node):
rg = reglib.register_group()
 
37,6 → 76,14
rg.addr_size = reglib.number(node.getAttribute ("addr_sz"))
rg.base_addr = reglib.number(node.getAttribute ("base_addr"))
 
data_sz = node.getAttribute ("data_sz")
if (data_sz != ''):
rg.data_size = reglib.number(data_sz)
 
rread = node.getAttribute ("registered_read")
if (data_sz != ''):
rg.registered_read = reglib.number(rread)
 
return rg
 
def create_register (rg, node):
43,7 → 90,9
params = {}
params['name'] = node.getAttribute ("name")
type = node.getAttribute ("type")
params['width'] = int(node.getAttribute ("width"))
width = node.getAttribute ("width")
if (width == ''): params['width'] = 1
else : params['width'] = int(width)
params['default'] = node.getAttribute ("default")
params['int_value'] = node.getAttribute ("int_value")
 
52,11 → 101,40
# if anode.nodeType = anode.ATTRIBUTE_NODE:
# params[anode.nodeName] = anode.nodeValue
 
print "Reg:",params['name'], " width:",params['width']
fld_nodes = node.getElementsByTagName ("field")
fld_list = []
cum_width = 0
cum_default = 0L
if (len(fld_nodes) != 0):
for fld in fld_nodes:
wstr = fld.getAttribute ("width")
if wstr == '':
width = 1
else:
width = int(wstr)
fld_list.append (reglib.net('wire',fld.getAttribute("name"),width))
 
default = fld.getAttribute ("default")
if default == '':
default = 0
else:
default = long(reglib.number (default))
cum_default = cum_default | (default << cum_width)
print "Fld: %20s CD: %x CW: %d D: %x" % (fld.getAttribute("name"),cum_default, cum_width, default)
cum_width += width
 
params['width'] = cum_width
params['default'] = cum_default
fld_list.reverse()
else:
if params['default'] == '': params['default'] = 0
else: params['default'] = reglib.number (params['default'])
if type == '': type = 'config'
if params['default'] == '': params['default'] = 0
else: params['default'] = reglib.number (params['default'])
 
rg.add_register (type, params)
rg.registers[-1].fields = fld_list
 
def create_verilog (top_node):
rg = create_reg_group (top_node)
72,6 → 150,27
fh.write (rg.verilog())
fh.close()
 
create_map (rg)
create_vh (rg)
 
def create_vh (rg):
fname = rg.name + ".vh"
fh = open (fname, 'w')
for r in rg.registers:
fh.write ("`define %s 16'h%04x\n" % (string.upper(r.name), rg.base_addr+r.offset))
fh.close()
 
def create_map (rg):
fname = rg.name + ".h"
fh = open (fname, 'w')
 
for r in rg.registers:
fh.write ("#define %s 0x%x\n" % (string.upper(r.name),r.offset))
#for r in rg.registers:
# fh.write ("sfr at 0x%02x %s;\n" % (r.offset, r.name))
fh.close()
 
def parse_file (filename):
rdoc = xml.dom.minidom.parse (filename)
blk_list = rdoc.getElementsByTagName ("tv_registers")
79,8 → 178,20
for blk in blk_list:
create_verilog (blk)
dec_list = rdoc.getElementsByTagName ("it_decoder")
 
for dec in dec_list:
create_decoder_verilog (dec)
rdoc.unlink()
 
def check_version():
version = float (sys.version[0:3])
if (version < 2.3):
print "rgen requires at least Python 2.3 to function correctly"
sys.exit (1)
 
check_version()
if (len (sys.argv) > 1):
parse_file (sys.argv[1])
else:
/scripts/reglib.py
41,6 → 41,15
print "ERROR: number conversion of %s failed" % str
return 0
 
def int2bin (n):
bStr = ''
if (n < 0): raise ValueError, "must be positive integer"
if (n == 0): return '0'
while (n > 0):
bStr = str (n%2) + bStr
n = n >> 1
return bStr
def comb_block (statements):
result = 'always @*\n'
result += ' begin\n'
50,7 → 59,7
return result
 
def seq_block (clock, statements):
result = 'always @(posedge ' + clock + ')\n'
result = 'always @(posedge ' + clock + ' or negedge reset_n)\n'
result += ' begin\n'
for s in statements:
result += ' ' + s + '\n'
80,7 → 89,137
return self.direction + ' ' + self.name + ';'
else:
return "%s [%d:0] %s;" % (self.direction, self.width-1, self.name)
 
class decoder_range:
def __init__ (self, name, base, bits):
self.name = name
self.base = base
self.bits = bits
 
def check_range(self):
mask = (1 << self.bits) - 1
if (self.base & mask):
return 1
else: return 0
 
def get_base_addr(self):
return self.base
class decoder_group:
def __init__ (self, mem_mapped=0):
self.addr_size = 16
self.data_size = 8
self.name = ''
self.ranges = []
self.ports = [port ('input', 'clk'), port('input','reset_n')]
self.nets = []
 
self.blocks = []
 
def build (self):
self.ports.append (port ('input', 'cfgi_irdy'))
self.ports.append (port ('output', 'cfgi_trdy'))
self.ports.append (port ('input', 'cfgi_write'))
self.ports.append (port ('input', 'cfgi_addr', self.addr_size))
self.ports.append (port ('input', 'cfgi_wr_data', self.data_size))
self.ports.append (port ('output', 'cfgo_wr_data', self.data_size))
self.ports.append (port ('output', 'cfgi_rd_data', self.data_size))
self.ports.append (port ('output', 'cfgo_addr', self.addr_size))
self.ports.append (port ('output', 'cfgo_write'))
self.nets.append (net('reg','cfgi_rd_data',self.data_size))
self.nets.append (net('reg','nxt_rd_data',self.data_size))
self.nets.append (net('reg', 'nxt_cfgi_trdy'))
self.nets.append (net('reg', 'irdy_out'))
self.nets.append (net('reg', 'trdy_out'))
self.nets.append (net('reg', 'cfgo_wr_data', self.data_size))
self.nets.append (net('reg', 'cfgo_addr', self.addr_size))
self.nets.append (net ('reg', 'cfgo_write'))
self.nets.append (net ('reg', 'cfgi_trdy'))
self.blocks.append ( """
always @(posedge clk or negedge reset_n)
begin
if (~reset_n)
begin
irdy_out <= #1 0;
cfgo_wr_data <= #1 0;
cfgo_addr <= #1 0;
cfgo_write <= #1 0;
cfgi_trdy <= #1 0;
end
else
begin
irdy_out <= #1 (irdy_out) ? !trdy_out : cfgi_irdy & ~cfgi_trdy;
cfgi_trdy <= #1 irdy_out & trdy_out;
 
if (cfgi_irdy & !irdy_out)
begin
cfgo_wr_data <= #1 cfgi_wr_data;
cfgo_addr <= #1 cfgi_addr;
cfgo_write <= #1 cfgi_write;
end
if (trdy_out & !cfgo_write)
cfgi_rd_data <= #1 nxt_rd_data;
end // else: !if(reset)
end // always @ (posedge clk)\n""")
 
addr_mux = ["casez (cfgo_addr)\n"]
for r in self.ranges:
self.ports.append (port ('output', r.name + "_irdy"))
self.ports.append (port ('input', r.name + "_trdy"))
self.ports.append (port ('input', r.name + "_rd_data", self.data_size))
self.nets.append (net('reg', r.name + "_irdy"))
addr_mux.insert(0, "%s_irdy = 0;" % r.name)
base_addr = int2bin (r.base)
#for b in range(-r.bits,0):
# base_addr[b] = 'z'
fill = self.addr_size - len(base_addr)
if (fill > 0):
base_addr = '0' * fill + base_addr
base_addr = base_addr[:-r.bits] + 'z'*r.bits
addr_mux.append ("%d'b%s :" % (self.addr_size, base_addr))
addr_mux.append ("begin")
addr_mux.append ("%s_irdy = irdy_out;" % r.name)
addr_mux.append ("trdy_out = %s_trdy;" % r.name)
addr_mux.append ("nxt_rd_data = %s_rd_data;" % r.name)
addr_mux.append ("end")
 
addr_mux.append("""
default :
begin
trdy_out = 1'b1;
nxt_rd_data = 0;
end
endcase\n""")
 
self.blocks.append (comb_block(addr_mux))
def verilog (self):
self.build()
result = 'module ' + self.name + ' (\n'
result += string.join (map (lambda x: x.name, self.ports), ',')
result += ');\n'
 
# print port list
for p in self.ports:
result += p.declaration() + '\n'
 
# print net list
for n in self.nets:
result += n.declaration() + '\n'
 
# create all blocks in block list
for b in self.blocks:
result += b
result += 'endmodule\n'
return result
 
 
def add_range (self, r):
self.ranges.append (r)
 
class register_group:
def __init__ (self, mem_mapped=0):
self.base_addr = 0
87,32 → 226,60
self.addr_size = 16
self.data_size = 8
self.name = ''
self.local_width = 1
self.local_width = 1 # number of address bits consumed
self.registers = []
self.ports = [port ('input', 'clk'), port('input','reset')]
self.ports = [port ('input', 'clk'), port('input','reset_n')]
self.nets = []
self.interrupts = 0
if (mem_mapped):
self.req_pin = 'mreq_n'
else:
self.req_pin = 'iorq_n'
self.tv80_intf()
self.interrupts = 0 # if interrupt registers present
self.user = 0 # if user-defined registers present
self.blocks = []
self.registered_read = 0
self.hold_regs = 0
self.hold_inputs = []
 
def tv80_intf (self):
self.ports.append (port ('input', 'addr', self.addr_size))
self.ports.append (port ('input', 'wr_data', self.data_size))
self.ports.append (port ('output', 'rd_data', self.data_size))
self.ports.append (port ('output', 'doe'))
self.ports.append (port ('input','rd_n'))
self.ports.append (port ('input', 'wr_n'))
self.ports.append (port ('input', self.req_pin))
self.nets.append (net('reg','rd_data',self.data_size))
self.nets.append (net('reg','block_select'))
self.nets.append (net('reg','doe'))
def top_intf (self):
self.ports.append (port ('input', 'rf_irdy'))
self.ports.append (port ('output', 'rf_trdy'))
self.ports.append (port ('input', 'rf_write'))
self.ports.append (port ('input', 'rf_addr', self.addr_size))
self.ports.append (port ('input', 'rf_wr_data', self.data_size))
self.ports.append (port ('output', 'rf_rd_data', self.data_size))
self.nets.append (net('reg','rf_rd_data',self.data_size))
self.nets.append (net('reg', 'nxt_rf_trdy'))
if (self.registered_read):
self.nets.append (net('reg','nxt_rf_rd_data',self.data_size))
for i in range(0,self.hold_regs):
self.nets.append (net('reg',"xxhold_%d" % i,self.data_size))
self.nets.append (net('reg',"nxt_xxhold_%d" % i,self.data_size))
self.nets.append (net('reg', 'rf_trdy'))
 
def build_load_mux (self):
for i in range(0,self.hold_regs):
nn = "nxt_xxhold_%d" % i
txt = []
for hi,nregs in self.hold_inputs:
high = (i+1) * self.data_size - 1
low = i* self.data_size
if (i < nregs):
txt.append ("if (%s_rd_stb) %s = %s_in[%d:%d];" % (hi, nn, hi, high, low))
txt.append ("else if (%s_%d_wr_sel) %s = rf_wr_data; else " % (hi, i, nn))
txt.append("%s = xxhold_%d;" % (nn, i))
self.blocks.append (comb_block(txt))
 
# create a hook for post-processing to be done after all data has been
# added to the object.
def post (self):
self.top_intf()
for reg in self.registers:
self.ports.extend (reg.io())
self.nets.extend (reg.nets())
#self.local_width = int(math.ceil (log2 (len (self.registers))))
self.local_width = self.addr_size;
rnum = 0
for r in self.registers:
r.offset = rnum
rnum += 1
self.build_load_mux()
if (self.interrupts):
self.int_ports()
122,29 → 289,54
def int_ports (self):
self.ports.append (port ('output','int_n'))
self.nets.append (net ('reg','int_n'))
self.nets.append (net ('reg','int_vec',self.data_size))
#self.nets.append (net ('reg','int_vec',self.data_size))
 
def int_logic (self):
statements = []
int_nets = []
for r in self.registers:
if r.interrupt: int_nets.append (r.name + "_int")
statements.append ("int_n = ~(" + string.join (int_nets, ' | ') + ");")
return comb_block (statements)
self.blocks.append (comb_block (["int_n = ~(" + string.join (int_nets, ' | ') + ");"]))
 
def wait_logic (self):
wait_nets = []
for r in self.registers:
if r.type() == 'user':
wait_nets.append (r.name + "_wait_n")
elif r.type() == 'ext_load':
if r.eindex == 0:
wait_nets.append (r.name + "_wait_n")
if (len(wait_nets) > 0):
self.blocks.append (comb_block (["if (rf_trdy) nxt_rf_trdy = 0;",
"else if (rf_irdy) nxt_rf_trdy = " + ' & '.join (wait_nets) + ";",
"else nxt_rf_trdy = 0;"]))
else:
self.blocks.append (comb_block (["if (rf_trdy) nxt_rf_trdy = 0;",
"else if (rf_irdy) nxt_rf_trdy = 1;",
"else nxt_rf_trdy = 0;"]))
self.blocks.append (seq_block ("clk", ["if (~reset_n) rf_trdy <= #1 0;",
"else rf_trdy <= #1 nxt_rf_trdy;"]))
#if (len(wait_nets) > 0):
# self.blocks.append (comb_block (["wait_n = " + string.join (wait_nets, ' & ') + ";"]))
 
if (self.registered_read):
self.blocks.append (seq_block ("clk", ["if (~reset_n) rf_rd_data <= #1 0;", "else if (nxt_rf_trdy) rf_rd_data <= #1 nxt_rf_rd_data;"]))
for i in range (0,self.hold_regs):
self.blocks.append (seq_block ("clk", ["if (~reset_n) xxhold_%d <= 0;"%i,"else xxhold_%d <= nxt_xxhold_%d;" % (i, i)]))
 
def global_logic (self):
# create select pin for this block
statements = ["block_select = (addr[%d:%d] == %d) & !%s;" % (self.addr_size-1,self.local_width,self.base_addr >> self.local_width, self.req_pin)]
statements = []
 
# create read and write selects for each register
for r in self.registers:
slogic = "block_select & (addr[%d:%d] == %d) & !rd_n" % (self.local_width-1,0,r.offset)
slogic = "(rf_addr[%d:%d] == %d) & rf_irdy & !rf_write" % (self.local_width-1,0,r.offset)
#if r.interrupt:
# slogic = "%s_int | (%s)" % (r.name, slogic)
s = "%s_rd_sel = %s;" % (r.name,slogic)
statements.append (s)
if r.write_cap():
s = "%s_wr_sel = block_select & (addr[%d:%d] == %d) & !wr_n;" % (r.name,self.local_width-1,0,r.offset)
s = "%s_wr_sel = (rf_addr[%d:%d] == %d) & rf_irdy & rf_write;\n" % (r.name,self.local_width-1,0,r.offset)
statements.append (s)
 
return comb_block (statements)
153,30 → 345,22
s = ''
sments = []
rd_sel_list = []
# Old code for simple tri-state interface
#for r in self.registers:
# s += "assign rd_data = (%s_rd_sel) ? %s : %d'bz;\n" % (r.name, r.name, self.data_size)
 
# create interrupt address mux
if (self.interrupts):
sments.append ("case (1'b1)")
for r in self.registers:
if r.interrupt:
sments.append (" %s_int : int_vec = %d;" % (r.name, r.int_value))
sments.append (" default : int_vec = %d'bx;" % self.data_size)
sments.append ("endcase")
 
# create data-output mux
sments.append ("case (1'b1)")
if (self.registered_read):
rd_target = "nxt_rf_rd_data"
else:
rd_target = "rf_rd_data"
for r in self.registers:
sments.append (" %s_rd_sel : rd_data = %s;" % (r.name, r.name))
sments.append (" %s_rd_sel : %s = %s;" % (r.name, rd_target, r.name))
rd_sel_list.append (r.name + "_rd_sel")
if (self.interrupts):
sments.append (" default : rd_data = int_vec;")
else: sments.append (" default : rd_data = %d'bx;" % self.data_size)
#if (self.interrupts):
# sments.append (" default : rd_data = int_vec;")
sments.append (" default : %s = %d'b0;" % (rd_target, self.data_size))
sments.append ("endcase")
 
sments.append ("doe = %s;" % string.join (rd_sel_list, ' | '))
#sments.append ("doe = %s;" % string.join (rd_sel_list, ' | '))
 
return comb_block (sments)
199,7 → 383,12
# create global logic
result += self.global_logic()
result += self.read_mux()
if (self.interrupts > 0): result += self.int_logic()
if (self.interrupts > 0): self.int_logic()
self.wait_logic()
 
# create all blocks in block list
for b in self.blocks:
result += b
# print function blocks
for r in self.registers:
208,6 → 397,16
result += 'endmodule\n'
return result
 
# calculate number of holding registers required and update
# hold_regs internal property
def calc_hold (self, width):
hregs = width / self.data_size
if (width % self.data_size) != 0:
hregs += 1
if (hregs > self.hold_regs):
self.hold_regs = hregs
return hregs
 
def add_register (self, type, params):
#def add_register (self, name, type, width):
if (type == 'status'):
214,9 → 413,9
self.add (status_reg (params['name'],params['width']))
elif (type == 'config'):
self.add (config_reg (params['name'],params['width'],params['default']))
elif (type == 'int_fixed'):
elif (type == 'int_msk'):
r2 = config_reg (params['name'] + "_msk",params['width'],params['default'])
r1 = int_fixed_reg (params['name'],r2,number(params['int_value']),params['width'])
r1 = int_msk_reg (params['name'],r2,params['width'])
self.add (r1)
self.add (r2)
self.interrupts += 1
226,20 → 425,31
self.add (read_stb_reg (params['name'],params['width']))
elif (type == 'write_stb'):
self.add (write_stb_reg (params['name'],params['width'],params['default']))
elif (type == 'hw_load'):
self.add (hw_load_reg (params['name'],params['width']))
elif (type == 'user'):
self.user = 1
self.add (user_reg (params['name'],params['width']))
elif (type == 'ext_load'):
width = params['width']
regs = self.calc_hold (width)
print "ext_load %s, splitting into %d regs" % (params['name'],regs)
for i in range(0,regs):
last = (i == (regs-1))
self.add (ext_load_reg(params['name'],self.data_size,i,params['width'],last))
self.hold_inputs.append ( (params['name'], regs) )
elif (type == 'count'):
self.add (count_reg (params['name'],params['width']))
else:
print "Unknown register type",type
 
def add (self, reg):
self.registers.append (reg)
self.ports.extend (reg.io())
self.nets.extend (reg.nets())
self.local_width = int(math.ceil (log2 (len (self.registers))))
rnum = 0
for r in self.registers:
r.offset = rnum
rnum += 1
#self.ports.extend (reg.io())
#self.nets.extend (reg.nets())
#self.local_width = int(math.ceil (log2 (len (self.registers))))
#rnum = 0
#for r in self.registers:
# r.offset = rnum
# rnum += 1
class basic_register:
def __init__ (self, name='', width=0):
251,6 → 461,9
def verilog_body (self):
pass
 
def type (self):
return 'basic'
def io (self):
return []
 
261,14 → 474,17
return 0
 
def id_comment (self):
return "// register: %s\n" % self.name
return "// %s: %s\n" % (self.type(), self.name)
 
class status_reg (basic_register):
def __init__ (self, name='', width=0):
basic_register.__init__(self, name, width)
 
def type (self):
return 'status'
def verilog_body (self):
return ''
return self.id_comment()
 
def io (self):
return [port('input', self.name, self.width)]
276,22 → 492,110
def nets (self):
return [ net('reg', self.name + '_rd_sel')]
 
class ext_load_reg (basic_register):
def __init__ (self, name='', width=0, eindex=0, twidth=0, last=0):
basic_register.__init__(self, name+"_%d" % eindex, width)
self.fullname = name
self.eindex = eindex
self.twidth = twidth
self.last = last
print "Adding %s eindex %d" % (name, eindex)
 
def type (self): return "ext_load"
 
def write_cap (self): return 1
 
def verilog_body (self):
print "Building %s eindex %d" % (self.name, self.eindex)
 
txt = ""
low = self.eindex * self.width
high = (self.eindex + 1) * self.width - 1
txt += "assign %s = xxhold_%d;\n" % (self.name, self.eindex)
txt += "assign %s_out[%d:%d] = xxhold_%d;\n" % (self.fullname, high, low, self.eindex)
if (self.eindex == 0):
#txt += "assign %s_rd_stb = %s_rd_sel & !rf_trdy;\n" % (self.fullname,self.name)
sm = state_machine ("sm_" + self.name)
sm.add_state ('idle')
sm.add_state ('rd_req')
sm.add_state ('done')
 
sm.add_trans ('idle','rd_req',self.name+"_rd_sel", self.name+"_wait_n = 0")
sm.add_trans ('rd_req','done',"1'b1")
sm.add_moore ('rd_req',self.name+"_wait_n = 1'b0")
sm.add_moore ('rd_req',self.fullname+"_rd_stb = 1'b1")
 
sm.add_trans ('done','idle',"~%s_rd_sel" % self.name)
 
sm.add_default (self.fullname+"_rd_stb", "1'b0")
sm.add_default (self.name+"_wait_n", "1'b1")
txt += sm.verilog()
 
if (self.last):
txt += seq_block ("clk", ["if (~reset_n) %s_wr_stb <= 1'b0;" % self.fullname,
"else %s_wr_stb <= %s_%d_wr_sel;" % (self.fullname,self.fullname,self.eindex)])
return txt
 
def nets (self):
nets = [net('reg', self.name + '_rd_sel'),
net('reg', self.name + '_wr_sel'),
net('wire', self.name, self.width)]
if (self.eindex == 0):
nets.append (net('reg', self.name + "_wait_n"))
nets.append (net('reg',"sm_%s_state" % self.name, 2))
nets.append (net('reg',"nxt_sm_%s_state" % self.name, 2))
if (self.last):
nets.append (net('reg', self.fullname + '_rd_stb'))
nets.append (net('reg', self.fullname + '_wr_stb'))
return nets
 
def io (self):
# ports are all tied to the 0 eindex register
plist = []
if (self.eindex == 0):
plist.append (port('input', self.fullname+"_in", self.twidth))
plist.append (port('output', self.fullname+"_out", self.twidth))
plist.append (port('output', self.fullname+"_rd_stb", 1))
plist.append (port('output', self.fullname+"_wr_stb", 1))
return plist
 
class config_reg (basic_register):
def __init__ (self, name='', width=0, default=0):
basic_register.__init__(self, name, width)
self.default = default
self.fields = []
def verilog_body (self):
statements = ["if (reset) %s <= %d;" % (self.name, self.default),
"else if (%s_wr_sel) %s <= %s;" % (self.name, self.name, 'wr_data')
]
return self.id_comment() + seq_block ('clk', statements)
vstr = self.id_comment()
statements = ["if (%s_wr_sel) nxt_%s = %s;" % (self.name, self.name, 'rf_wr_data'),
"else nxt_%s = %s;" % tuple([self.name] * 2)]
vstr += comb_block (statements)
statements = ["if (~reset_n) %s <= #1 %d'h%x;" % (self.name, self.width, self.default),
"else %s <= #1 nxt_%s;" % tuple([self.name] * 2)]
vstr += seq_block ('clk', statements)
if (len(self.fields) != 0):
vstr += "assign {"
vstr += ','.join (map(lambda(x):x.name,self.fields))
vstr += "} = %s;\n" % self.name
return vstr
 
def type (self):
return 'config'
def io (self):
return [ port('output',self.name, self.width) ]
if (len(self.fields) == 0):
return [ port('output',self.name, self.width) ]
else:
plist = []
for fld in self.fields:
plist.append (port ('output', fld.name, fld.width))
return plist
 
def nets (self):
return [ net('reg', self.name, self.width),
net('reg', "nxt_"+self.name, self.width),
net('reg', self.name + '_rd_sel'),
net('reg', self.name + '_wr_sel')]
 
298,48 → 602,52
def write_cap (self):
return 1
 
class hw_load_reg (config_reg):
class count_reg (config_reg):
def __init__ (self, name='', width=0, default=0):
basic_register.__init__(self, name, width)
config_reg.__init__(self, name, width)
self.default = default
def verilog_body (self):
statements = ["if (reset) %s <= %d;" % (self.name, self.default),
"else if (%s_wr_sel) %s <= %s;" % (self.name, self.name, 'wr_data'),
"else if (%s_load) %s <= %s_wrdata;" % (self.name,self.name,self.name)
txt = self.id_comment()
alist = (self.name, self.name, self.width, self.name, self.name)
statements = [
"if (%s_wr_sel) nxt_%s = %s;" % (self.name, self.name, 'rf_wr_data'),
"else if (%s_inc && (%s != {%d{1'b1}})) nxt_%s = %s + 1;" % alist,
"else nxt_%s = %s;" % (self.name,self.name)
]
return self.id_comment() + seq_block ('clk', statements)
 
txt += comb_block (statements)
statements = ["if (~reset_n) %s <= #1 %d;" % (self.name, self.default),
"else %s <= #1 nxt_%s;" % (self.name, self.name)
]
txt += seq_block ('clk', statements)
return txt
def io (self):
return [ port('input', self.name+'_wrdata', self.width),
port('input', self.name+'_load', 1),
port('output',self.name, self.width) ]
return [ port('input',self.name + "_inc", 1) ]
 
def nets (self):
return [ net('reg', self.name, self.width),
net('reg', self.name + '_rd_sel'),
net('reg', self.name + '_wr_sel')]
 
def write_cap (self):
return 1
 
 
class int_fixed_reg (basic_register):
def __init__ (self, name, mask_reg, int_value, width=0):
class int_msk_reg (basic_register):
def __init__ (self, name, mask_reg, width=0):
basic_register.__init__(self, name, width)
self.mask_reg = mask_reg
self.interrupt = 1
self.int_value = int_value
def verilog_body (self):
statements = ["if (reset) %s <= %d;" % (self.name, 0),
"else %s <= (%s_set | %s) & ~( {%d{%s}} & %s);" %
(self.name, self.name, self.name, self.width, self.name + '_wr_sel', 'wr_data'),
"if (reset) %s_int <= 0;" % self.name,
"else %s_int <= |(%s & ~%s);" % (self.name, self.name, self.mask_reg.name)
text = self.id_comment()
statements = ["nxt_%s = (%s_set | %s) & ~( {%d{%s}} & %s);" % (self.name, self.name, self.name, self.width, self.name + '_wr_sel', 'rf_wr_data')]
statements += ["nxt_%s_int = |(%s & ~%s);" % (self.name, self.name, self.mask_reg.name)]
text += comb_block (statements)
statements = ["if (~reset_n) %s <= #1 %d;" % (self.name, 0),
"else %s <= #1 nxt_%s;" % (self.name, self.name)]
text += seq_block ('clk', statements)
statements = ["if (~reset_n) %s_int <= #1 0;" % self.name,
"else %s_int <= nxt_%s_int;" % (self.name, self.name)
]
return self.id_comment() + seq_block ('clk', statements)
text += seq_block ('clk', statements)
return text
 
def type (self):
return 'int_msk'
def io (self):
return [ port('input',self.name+"_set", self.width) ]
 
346,36 → 654,51
def nets (self):
return [ net('reg', self.name + '_rd_sel'),
net('reg', self.name, self.width),
net('reg', "nxt_"+self.name, self.width),
net('reg', self.name + '_wr_sel'),
net('reg', 'nxt_'+self.name + '_int'),
net('reg', self.name + '_int')]
 
def write_cap (self):
return 1
 
class soft_set_reg (basic_register):
class soft_set_reg (config_reg):
def __init__ (self, name='', width=0, default=0):
basic_register.__init__(self, name, width)
self.default = default
def verilog_body (self):
statements = ["if (reset) %s <= %d;" % (self.name, self.default),
"else %s <= ( ({%d{%s}} & %s) | %s) & ~(%s);" %
(self.name, self.width, self.name+'_wr_sel', 'wr_data',
txt = self.id_comment()
statements = [
"nxt_%s = ( ({%d{%s}} & %s) | %s) & ~(%s);" %
(self.name, self.width, self.name+'_wr_sel', 'rf_wr_data',
self.name, self.name + '_clr')
]
return self.id_comment() + seq_block ('clk', statements)
txt += comb_block (statements)
statements = ["if (~reset_n) %s <= #1 %d;" % (self.name, self.default),
"else %s <= #1 nxt_%s;" % (self.name, self.name)
]
txt += seq_block ('clk', statements)
if (len(self.fields) != 0):
txt += "assign {"
txt += ','.join (map(lambda(x):x.name,self.fields))
txt += "} = %s;\n" % self.name
return txt
 
def type (self):
return 'soft_set'
def io (self):
return [ port('output',self.name, self.width),
port ('input',self.name+"_clr", self.width)]
return config_reg.io(self) + [port ('input',self.name+"_clr", self.width)]
 
def nets (self):
return [ net('reg', self.name, self.width),
net('reg', self.name + '_rd_sel'),
net('reg', self.name + '_wr_sel')]
#def nets (self):
# return [ net('reg', self.name, self.width),
# net('reg', "nxt_"+self.name, self.width),
# net('reg', self.name + '_rd_sel'),
# net('reg', self.name + '_wr_sel')]
 
def write_cap (self):
return 1
#def write_cap (self):
# return 1
 
class write_stb_reg (config_reg):
def __init__ (self, name='', width=0, default=0):
382,14 → 705,30
config_reg.__init__(self, name, width, default)
def verilog_body (self):
statements = ["if (reset) %s <= %d;" % (self.name, self.default),
"else if (%s_wr_sel) %s <= %s;" % (self.name, self.name, 'wr_data'),
"if (reset) %s_stb <= 0;" % (self.name),
"else if (%s_wr_sel) %s_stb <= 1;" % (self.name, self.name),
"else %s_stb <= 0;" % (self.name)
txt = self.id_comment()
statements = [
"if (%s_wr_sel) nxt_%s = %s;" % (self.name, self.name, 'rf_wr_data'),
"else nxt_%s = %s;" % (self.name, self.name)]
txt += comb_block (statements)
statements = ["if (~reset_n) %s <= #1 %d;" % (self.name, self.default),
"else %s <= #1 nxt_%s;" % (self.name, self.name)]
txt += seq_block('clk',statements)
statements = [
"if (~reset_n) %s_stb <= #1 0;" % (self.name),
"else %s_stb <= #1 %s_wr_sel & rf_trdy;" % (self.name, self.name),
]
return seq_block ('clk', statements)
txt += seq_block ('clk', statements)
 
if (len(self.fields) != 0):
txt += "assign {"
txt += ','.join (map(lambda(x):x.name,self.fields))
txt += "} = %s;\n" % self.name
 
return txt+seq_block ('clk', statements)
 
def type (self):
return 'write_stb'
def io (self):
io_list = config_reg.io (self)
io_list.append ( port('output',self.name+"_stb") )
406,12 → 745,14
def verilog_body (self):
statements = [
"if (reset) %s_stb <= 0;" % (self.name),
"else if (%s_rd_sel) %s_stb <= 1;" % (self.name, self.name),
"else %s_stb <= 0;" % (self.name)
"if (~reset_n) %s_stb <= #1 0;" % (self.name),
"else %s_stb <= #1 %s_rd_sel & rf_trdy;" % (self.name, self.name),
]
return self.id_comment() + seq_block ('clk', statements)
 
def type (self):
return 'read_stb'
def io (self):
io_list = status_reg.io (self)
io_list.append (port('output',self.name+"_stb"))
421,3 → 762,140
net_list = status_reg.nets(self)
net_list.append (net('reg',self.name + '_stb'))
return net_list
 
class state_machine:
def __init__ (self, name='', clk="clk", reset="reset_n"):
self.name = name
self.states = {}
self.trans = []
self.clk = clk
self.reset = reset
self.idle = ""
self.defaults = []
 
def add_state (self, name):
self.states[name] = []
if (self.idle == ""):
self.idle = name
 
def add_trans (self, st_from, st_to, cond, asrt=''):
self.states[st_from].append ( (st_to, cond, asrt) )
 
def add_moore (self, st_name, asrt):
self.states[st_name].append ( (st_name, '1', asrt) )
 
def add_default (self, signal, value):
self.defaults.append ( (signal, value) )
 
def verilog (self):
code = "// state machine %s\n" % self.name
 
# create state names
snum = 0
for st in self.states.keys():
code += "parameter st_%s_%s = %d;\n" % (self.name, st, snum)
snum += 1
# create combinatorial block
cblk = []
for d in self.defaults:
cblk.append ( "%s = %s;" % d)
cblk.append ("%s = %s;" % ("nxt_" + self.name + "_state", self.name + "_state"))
cblk.append ("case (%s)" % (self.name + "_state"))
for st in self.states.keys():
cblk.append ( "st_%s_%s : " % (self.name, st))
cblk.append ( " begin")
first = 1
moore = []
for c in self.states[st]:
if (c[0] == st) and (c[1] == "1"):
moore.append (c[2])
else:
if (not first): statement = " else if"
else:
statement = " if"
first = 0
cblk.append ( "%s (%s)" % (statement, c[1]))
cblk.append (" begin")
if (c[0] != st):
cblk.append ( " nxt_%s_state = st_%s_%s;" % (self.name, self.name, c[0]))
if (c[2] != ""):
cblk.append ( " " + c[2] + ";")
cblk.append ( " end")
for m in moore:
cblk.append (" %s;" % m)
cblk.append (" end")
cblk.append ( "endcase")
code += comb_block (cblk)
 
# create sequential block
cblk = []
cblk.append ("if(~%s)" % self.reset)
cblk.append ("%s_state <= #1 st_%s_%s;" % (self.name, self.name, self.idle))
cblk.append ("else")
cblk.append ("%s_state <= #1 nxt_%s_state;" % (self.name, self.name))
code += seq_block (self.clk, cblk)
return code
class user_reg (basic_register):
def __init__ (self, name='', width=0):
basic_register.__init__(self, name, width)
 
def io (self):
io_list = []
io_list.append (port('output',self.name+"_wr_stb"))
io_list.append (port('output',self.name+"_rd_stb"))
io_list.append (port('output',self.name+"_wr_data", self.width))
io_list.append (port('input',self.name+"_rd_data",self.width))
io_list.append (port('input',self.name+"_rd_ack"))
io_list.append (port('input',self.name+"_wr_ack"))
return io_list
 
def type (self):
return 'user'
def nets (self):
net_list = []
net_list.append (net('reg',self.name+"_rd_sel"))
net_list.append (net('reg',self.name+"_wr_sel"))
net_list.append (net('reg',self.name+"_rd_stb"))
net_list.append (net('reg',self.name+"_wr_stb"))
net_list.append (net('reg',self.name+"_wait_n"))
net_list.append (net('reg',self.name,self.width))
net_list.append (net('reg',self.name+"_wr_data",self.width))
net_list.append (net('reg',"sm_%s_state" % self.name, 2))
net_list.append (net('reg',"nxt_sm_%s_state" % self.name, 2))
return net_list
def write_cap (self):
return 1
 
def verilog_body (self):
sm = state_machine ("sm_" + self.name)
sm.add_state ('idle')
sm.add_state ('rd_req')
sm.add_state ('wr_req')
sm.add_state ('w_clear')
#sm.add_state ('rd_ack')
#sm.add_state ('wr_ack')
sm.add_trans ('idle','rd_req',self.name+"_rd_sel", self.name+"_wait_n = 0")
sm.add_trans ('idle','wr_req',self.name+"_wr_sel", self.name+"_wait_n = 0")
sm.add_trans ('rd_req', 'w_clear', self.name+"_rd_ack", "")
#sm.add_trans ('rd_req', 'rd_ack', '1','')
sm.add_trans ('rd_req', 'rd_req', "!"+self.name+"_rd_ack", self.name+"_wait_n = 0")
sm.add_moore ('rd_req', self.name+"_rd_stb = 1")
sm.add_moore ('wr_req', self.name+"_wr_stb = 1")
sm.add_trans ('wr_req', 'w_clear', self.name+"_wr_ack", "")
sm.add_trans ('wr_req', 'wr_req', "!"+self.name+"_wr_ack", self.name+"_wait_n = 0")
 
# added w_clear to avoid duplicate requests on interface
sm.add_trans ('w_clear', 'idle', "~(%s_rd_sel | %s_wr_sel)" % (self.name,self.name), "")
 
sm.add_default (self.name+"_rd_stb", "0")
sm.add_default (self.name+"_wr_stb", "0")
sm.add_default (self.name+"_wait_n", "1")
 
comb = comb_block (["%s_wr_data = rf_wr_data;" % self.name,
"%s = %s_rd_data;" % (self.name, self.name)])
 
return sm.verilog() + comb

powered by: WebSVN 2.1.0

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