<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>%%CATEGORY%%:rss</title>
		<link>http://ccckmit.wikidot.com</link>
		<description>陳鍾誠的首頁 -- 金門大學 資訊工程系</description>
				<copyright></copyright>
		<lastBuildDate>Wed, 15 Apr 2026 07:28:13 +0000</lastBuildDate>
		
					<item>
				<guid>http://ccckmit.wikidot.com/ve:gtkwave</guid>
				<title>Gtkwave</title>
				<link>http://ccckmit.wikidot.com/ve:gtkwave</link>
				<description>

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://iverilog.wikia.com/wiki/GTKWAVE&quot;&gt;http://iverilog.wikia.com/wiki/GTKWAVE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://codeitdown.com/icarus-verilog-on-windows/&quot;&gt;http://codeitdown.com/icarus-verilog-on-windows/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 08 Oct 2013 13:15:56 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ul> <li><a href="http://iverilog.wikia.com/wiki/GTKWAVE">http://iverilog.wikia.com/wiki/GTKWAVE</a></li> <li><a href="http://codeitdown.com/icarus-verilog-on-windows/">http://codeitdown.com/icarus-verilog-on-windows/</a></li> </ul> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:icarus</guid>
				<title>Icarus Verilog 編譯工具鏈</title>
				<link>http://ccckmit.wikidot.com/ve:icarus</link>
				<description>

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:icarushello&quot;&gt;Icarus Verilog 的安裝與執行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:iverilog-vpi&quot;&gt;用 Iverilog-vpi 連結 C 語言與 Verilog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:iverilog-vpi2&quot;&gt;用 Iverilog-vpi 連結 C 語言與 Verilog (2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:gtkwave&quot;&gt;輸出波型給 GTKWave 讀取&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 22 May 2012 00:43:52 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ol> <li><a href="http://ccckmit.wikidot.com/ve:icarushello">Icarus Verilog 的安裝與執行</a></li> <li><a href="http://ccckmit.wikidot.com/ve:iverilog-vpi">用 Iverilog-vpi 連結 C 語言與 Verilog</a></li> <li><a href="http://ccckmit.wikidot.com/ve:iverilog-vpi2">用 Iverilog-vpi 連結 C 語言與 Verilog (2)</a></li> <li><a href="http://ccckmit.wikidot.com/ve:gtkwave">輸出波型給 GTKWave 讀取</a></li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:ref</guid>
				<title>Verilog -- 參考文獻</title>
				<link>http://ccckmit.wikidot.com/ve:ref</link>
				<description>

&lt;h1&gt;&lt;span&gt;最新參考&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;Verilog Coding forLogic Synthesis (讚、有加減乘除法器) &amp;#8212; &lt;a href=&quot;http://zh.scribd.com/doc/55729932/55/Example-4-31Verilog-Code-Using-a-Multiplication-Operator&quot;&gt;http://zh.scribd.com/doc/55729932/55/Example-4-31Verilog-Code-Using-a-Multiplication-Operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Understanding Verilog Blocking and Nonblocking Assignments (讚！推薦！超經典)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf&quot;&gt;http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Verilog Coding Styles – Synthesis Related - 南港IC設計育成中心：針對 RTL 與 Gate 轉換可能不一致的錯誤進行觀念說明與範例解析 (讚！)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nspark.org.tw/webfiles/verilog_coding_style-fina_20080818l.pdf&quot;&gt;http://www.nspark.org.tw/webfiles/verilog_coding_style-fina_20080818l.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Verilog 中的 &amp;lt;= 與 = 最好不要在同一個 block 中並用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.asic-world.com/verilog/vqref1.html&quot;&gt;http://www.asic-world.com/verilog/vqref1.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;真 OO无双:電路設計相關
&lt;ul&gt;
&lt;li&gt;Verilog &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/84456.html&quot;&gt;http://www.cnblogs.com/oomusou/category/84456.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Quartus II &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/106930.html&quot;&gt;http://www.cnblogs.com/oomusou/category/106930.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;NIOS II &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/106931.html&quot;&gt;http://www.cnblogs.com/oomusou/category/106931.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DE2-70 &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/149442.html&quot;&gt;http://www.cnblogs.com/oomusou/category/149442.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DE2 &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/110932.html&quot;&gt;http://www.cnblogs.com/oomusou/category/110932.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;uCOS II &amp;#8212; &lt;a href=&quot;http://www.cnblogs.com/oomusou/category/107216.html&quot;&gt;http://www.cnblogs.com/oomusou/category/107216.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;紙本書：&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2008/02/08/1066013.html&quot;&gt;(原創) Verilog入門書籍推薦：Verilog數位電路設計範例寶典(基礎篇) (IC Design) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tips to Optimize your Verilog HDL code &amp;#8212; &lt;a href=&quot;http://www.inno-logic.com/resourcesTips.html&quot;&gt;http://www.inno-logic.com/resourcesTips.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Bucknell Handbook on Verilog HDL &amp;#8212; &lt;a href=&quot;http://hdlplanet.tripod.com/verilog/verilog-manual.html&quot;&gt;http://hdlplanet.tripod.com/verilog/verilog-manual.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Altera 11. Recommended HDL Coding Styles &amp;#8212; &lt;a href=&quot;http://www.altera.com/literature/hb/qts/qts_qii51007.pdf&quot;&gt;http://www.altera.com/literature/hb/qts/qts_qii51007.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://csserver.evansville.edu/~blandfor/UEVerilogTutorial.pdf&quot;&gt;EE 254:Verilog Tutorial (PDF)&lt;/a&gt; , Dr. D. K. Blandford&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stenlyho.blogspot.com/search/label/verilog&quot;&gt;史丹利部落格:Verilog&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;電子書&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/Electronics/Verilog-Books-Download.html&quot;&gt;http://www.freebookcentre.net/Electronics/Verilog-Books-Download.html&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/electronics-ebooks-download/Introduction-to-Verilog-(PDF-31p).html&quot;&gt;Introduction to Verilog (PDF 31p)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/electronics-ebooks-download/Verilog-Tutorial-(PDF-227p).html&quot;&gt;Verilog Tutorial (PDF 227p)&lt;/a&gt; (讚！推薦！)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/electronics-ebooks-download/Handbook-on-Verilog-HDL-(PDF-32p).html&quot;&gt;Handbook on Verilog HDL (PDF 32p)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/electronics-ebooks-download/The-Verilog-Golden-Reference-Guide-(PDF-151p).html&quot;&gt;The Verilog Golden Reference Guide (PDF 151p)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freebookcentre.net/electronics-ebooks-download/The-Verilog-Language-(PDF-Slides-80p).html&quot;&gt;The Verilog Language (PDF Slides 80p)&lt;/a&gt; (讚！推薦！)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Wikipedia:Programmable Logic/Verilog
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikibooks.org/wiki/Programmable_Logic/Verilog&quot;&gt;http://en.wikibooks.org/wiki/Programmable_Logic/Verilog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A Verilog HDL Test Bench Primer (Application Note)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://people.ece.cornell.edu/land/courses/ece5760/Verilog/LatticeTestbenchPrimer.pdf&quot;&gt;http://people.ece.cornell.edu/land/courses/ece5760/Verilog/LatticeTestbenchPrimer.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Verilog&quot;&gt;http://en.wikipedia.org/wiki/Verilog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Verilog 2001 教學(第一章)，部分引用於Wiki &amp;#8212; &lt;a href=&quot;http://tw.myblog.yahoo.com/likeyoufacejang/article?mid=2451&quot;&gt;http://tw.myblog.yahoo.com/likeyoufacejang/article?mid=2451&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.altera.com/support/examples/verilog/verilog.html&quot;&gt;http://www.altera.com/support/examples/verilog/verilog.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Whats New in Verilog 2001 Part-II
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.asic-world.com/verilog/verilog2k2.html&quot;&gt;http://www.asic-world.com/verilog/verilog2k2.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;array initialization [1a] (system-verilog)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cadence.com/community/forums/T/9236.aspx&quot;&gt;http://www.cadence.com/community/forums/T/9236.aspx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;導引文章&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/07/30/blocking_vs_nonblocking.html&quot;&gt;(原創) 深入探討blocking與nonblocking (SOC) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2008/07/05/verilog_blocking_nonblocking.html&quot;&gt;(筆記) 如何使用blocking與nonblocking assignment? (SOC) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2008/06/17/c_verilog_mental_thinking.html&quot;&gt;(原創) 由C語言學習Verilog的思維轉換 (C/C++) (C) (IC Design) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2008/01/14/1038768.html&quot;&gt;(原創) 給對電機領域有興趣的學弟學妹建議 (IC Design) (C/C++) (C) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2007/10/10/919339.html&quot;&gt;(原創) wire與reg的差異? (初級) (IC Design) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2006/12/08/586527.html&quot;&gt;(原創) 硬體是如何加速軟體呢? (IC Design) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2011/02/28/de2_70_dual_pin.html&quot;&gt;(原創) 深入探討DE2-70的『Error：Can&#039;t place pins assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)』錯誤訊息的原因與解決方式 (SOC) (Quartus II) (DE2-70) (Tcl)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2011/02/28/de2_70_dual_pin.html&quot;&gt;(筆記) 如何對一變數指定某一個bit的值? (SOC) (C/C++) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2011/02/12/ise_ngc.html&quot;&gt;(原創) 如何將RTL產生netlist後讓其他人作synthesis? (SOC) (ISE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/09/05/verilog_mux2.html&quot;&gt;(原創) 多工器MUX coding style整理 (SOC) (Verilog) (Quartus II)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/08/14/de2_70_photo_frame.html&quot;&gt;(原創) 如何設計一個數位相框? (SOC) (Quartus II) (SOPC Builder) (Nios II) (TRDB-LTM) (DE2-70)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/08/13/de2_70_sd_player.html&quot;&gt;(原創) 如何設計一個SD卡Wav Player? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/08/10/de2_70_start_up.html&quot;&gt;(原創) 如何自己用SOPC Builder建立一個能在DE2-70上跑μC/OS-II的Nios II系統? (SOC) (Nios II) (μC/OS-II) (DE2-70)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/08/04/timing_slack.html&quot;&gt;(原創) timing中的slack是什麼意思? (SOC) (Quartus II)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2010/08/04/fmax.html&quot;&gt;(筆記) fmax的計算公式 (SOC) (Quartus II)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2009/10/31/verilog_signed_overflow.html&quot;&gt;(原創) 如何處理signed integer的加法運算與overflow? (SOC) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2009/10/25/de1_dos.html&quot;&gt;(轉貼) 使用DE1執行DOS 6.22與Windows 3.0 (News) (SOC) (DE2) (DE2-70)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2009/03/30/verilog_pli_show_value.html&quot;&gt;(筆記) 如何將參數從Verilog傳到C? (SOC) (Verilog) (Verilog PLI)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2009/03/25/verilog_hello_world.html&quot;&gt;(原創) 如何使用C開發Verilog System Task/Function? (SOC) (Verilog) (Verilog PLI)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.cnblogs.com/oomusou/archive/2008/02/11/1066839.html&quot;&gt;(原創) 如何讀取/寫入文字檔? (IC Design) (Verilog)&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;VHDL&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.freetechbooks.com/the-vhdl-cookbook-first-edition-t431.html&quot;&gt;The VHDL Cookbook&lt;/a&gt;, First Edition , Author : Peter J. Ashenden, School of Computer Science, University of Adelaide , Publication Date : July 1990&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 21 Nov 2011 06:30:43 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>最新參考</span></h1> <ol> <li>Verilog Coding forLogic Synthesis (讚、有加減乘除法器) &#8212; <a href="http://zh.scribd.com/doc/55729932/55/Example-4-31Verilog-Code-Using-a-Multiplication-Operator">http://zh.scribd.com/doc/55729932/55/Example-4-31Verilog-Code-Using-a-Multiplication-Operator</a></li> <li>Understanding Verilog Blocking and Nonblocking Assignments (讚！推薦！超經典) <ul> <li><a href="http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf">http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf</a></li> </ul> </li> <li>Verilog Coding Styles – Synthesis Related - 南港IC設計育成中心：針對 RTL 與 Gate 轉換可能不一致的錯誤進行觀念說明與範例解析 (讚！) <ul> <li><a href="http://www.nspark.org.tw/webfiles/verilog_coding_style-fina_20080818l.pdf">http://www.nspark.org.tw/webfiles/verilog_coding_style-fina_20080818l.pdf</a></li> </ul> </li> </ol> <blockquote> <p>Verilog 中的 &lt;= 與 = 最好不要在同一個 block 中並用</p> </blockquote> <ol> <li><a href="http://www.asic-world.com/verilog/vqref1.html">http://www.asic-world.com/verilog/vqref1.html</a></li> <li>真 OO无双:電路設計相關 <ul> <li>Verilog &#8212; <a href="http://www.cnblogs.com/oomusou/category/84456.html">http://www.cnblogs.com/oomusou/category/84456.html</a></li> <li>Quartus II &#8212; <a href="http://www.cnblogs.com/oomusou/category/106930.html">http://www.cnblogs.com/oomusou/category/106930.html</a></li> <li>NIOS II &#8212; <a href="http://www.cnblogs.com/oomusou/category/106931.html">http://www.cnblogs.com/oomusou/category/106931.html</a></li> <li>DE2-70 &#8212; <a href="http://www.cnblogs.com/oomusou/category/149442.html">http://www.cnblogs.com/oomusou/category/149442.html</a></li> <li>DE2 &#8212; <a href="http://www.cnblogs.com/oomusou/category/110932.html">http://www.cnblogs.com/oomusou/category/110932.html</a></li> <li>uCOS II &#8212; <a href="http://www.cnblogs.com/oomusou/category/107216.html">http://www.cnblogs.com/oomusou/category/107216.html</a></li> </ul> </li> <li>紙本書：<a href="http://www.cnblogs.com/oomusou/archive/2008/02/08/1066013.html">(原創) Verilog入門書籍推薦：Verilog數位電路設計範例寶典(基礎篇) (IC Design) (Verilog)</a></li> <li>Tips to Optimize your Verilog HDL code &#8212; <a href="http://www.inno-logic.com/resourcesTips.html">http://www.inno-logic.com/resourcesTips.html</a></li> <li>Bucknell Handbook on Verilog HDL &#8212; <a href="http://hdlplanet.tripod.com/verilog/verilog-manual.html">http://hdlplanet.tripod.com/verilog/verilog-manual.html</a></li> <li>Altera 11. Recommended HDL Coding Styles &#8212; <a href="http://www.altera.com/literature/hb/qts/qts_qii51007.pdf">http://www.altera.com/literature/hb/qts/qts_qii51007.pdf</a></li> <li><a href="http://csserver.evansville.edu/~blandfor/UEVerilogTutorial.pdf">EE 254:Verilog Tutorial (PDF)</a> , Dr. D. K. Blandford</li> <li><a href="http://stenlyho.blogspot.com/search/label/verilog">史丹利部落格:Verilog</a></li> </ol> <h1><span>電子書</span></h1> <ol> <li><a href="http://www.freebookcentre.net/Electronics/Verilog-Books-Download.html">http://www.freebookcentre.net/Electronics/Verilog-Books-Download.html</a> <ul> <li><a href="http://www.freebookcentre.net/electronics-ebooks-download/Introduction-to-Verilog-(PDF-31p).html">Introduction to Verilog (PDF 31p)</a></li> <li><a href="http://www.freebookcentre.net/electronics-ebooks-download/Verilog-Tutorial-(PDF-227p).html">Verilog Tutorial (PDF 227p)</a> (讚！推薦！)</li> <li><a href="http://www.freebookcentre.net/electronics-ebooks-download/Handbook-on-Verilog-HDL-(PDF-32p).html">Handbook on Verilog HDL (PDF 32p)</a></li> <li><a href="http://www.freebookcentre.net/electronics-ebooks-download/The-Verilog-Golden-Reference-Guide-(PDF-151p).html">The Verilog Golden Reference Guide (PDF 151p)</a></li> <li><a href="http://www.freebookcentre.net/electronics-ebooks-download/The-Verilog-Language-(PDF-Slides-80p).html">The Verilog Language (PDF Slides 80p)</a> (讚！推薦！)</li> </ul> </li> <li>Wikipedia:Programmable Logic/Verilog <ul> <li><a href="http://en.wikibooks.org/wiki/Programmable_Logic/Verilog">http://en.wikibooks.org/wiki/Programmable_Logic/Verilog</a></li> </ul> </li> <li>A Verilog HDL Test Bench Primer (Application Note) <ul> <li><a href="http://people.ece.cornell.edu/land/courses/ece5760/Verilog/LatticeTestbenchPrimer.pdf">http://people.ece.cornell.edu/land/courses/ece5760/Verilog/LatticeTestbenchPrimer.pdf</a></li> </ul> </li> <li><a href="http://en.wikipedia.org/wiki/Verilog">http://en.wikipedia.org/wiki/Verilog</a></li> <li>Verilog 2001 教學(第一章)，部分引用於Wiki &#8212; <a href="http://tw.myblog.yahoo.com/likeyoufacejang/article?mid=2451">http://tw.myblog.yahoo.com/likeyoufacejang/article?mid=2451</a></li> <li><a href="http://www.altera.com/support/examples/verilog/verilog.html">http://www.altera.com/support/examples/verilog/verilog.html</a></li> <li>Whats New in Verilog 2001 Part-II <ul> <li><a href="http://www.asic-world.com/verilog/verilog2k2.html">http://www.asic-world.com/verilog/verilog2k2.html</a></li> </ul> </li> <li>array initialization [1a] (system-verilog) <ul> <li><a href="http://www.cadence.com/community/forums/T/9236.aspx">http://www.cadence.com/community/forums/T/9236.aspx</a></li> </ul> </li> </ol> <h1><span>導引文章</span></h1> <ol> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/07/30/blocking_vs_nonblocking.html">(原創) 深入探討blocking與nonblocking (SOC) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2008/07/05/verilog_blocking_nonblocking.html">(筆記) 如何使用blocking與nonblocking assignment? (SOC) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2008/06/17/c_verilog_mental_thinking.html">(原創) 由C語言學習Verilog的思維轉換 (C/C++) (C) (IC Design) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2008/01/14/1038768.html">(原創) 給對電機領域有興趣的學弟學妹建議 (IC Design) (C/C++) (C) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2007/10/10/919339.html">(原創) wire與reg的差異? (初級) (IC Design) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2006/12/08/586527.html">(原創) 硬體是如何加速軟體呢? (IC Design) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2011/02/28/de2_70_dual_pin.html">(原創) 深入探討DE2-70的『Error：Can't place pins assigned to pin location Pin_AD25 (IOC_X95_Y2_N1)』錯誤訊息的原因與解決方式 (SOC) (Quartus II) (DE2-70) (Tcl)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2011/02/28/de2_70_dual_pin.html">(筆記) 如何對一變數指定某一個bit的值? (SOC) (C/C++) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2011/02/12/ise_ngc.html">(原創) 如何將RTL產生netlist後讓其他人作synthesis? (SOC) (ISE)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/09/05/verilog_mux2.html">(原創) 多工器MUX coding style整理 (SOC) (Verilog) (Quartus II)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/08/14/de2_70_photo_frame.html">(原創) 如何設計一個數位相框? (SOC) (Quartus II) (SOPC Builder) (Nios II) (TRDB-LTM) (DE2-70)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/08/13/de2_70_sd_player.html">(原創) 如何設計一個SD卡Wav Player? (SOC) (Quartus II) (SOPC Builder) (Nios II) (DE2-70)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/08/10/de2_70_start_up.html">(原創) 如何自己用SOPC Builder建立一個能在DE2-70上跑μC/OS-II的Nios II系統? (SOC) (Nios II) (μC/OS-II) (DE2-70)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/08/04/timing_slack.html">(原創) timing中的slack是什麼意思? (SOC) (Quartus II)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2010/08/04/fmax.html">(筆記) fmax的計算公式 (SOC) (Quartus II)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2009/10/31/verilog_signed_overflow.html">(原創) 如何處理signed integer的加法運算與overflow? (SOC) (Verilog)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2009/10/25/de1_dos.html">(轉貼) 使用DE1執行DOS 6.22與Windows 3.0 (News) (SOC) (DE2) (DE2-70)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2009/03/30/verilog_pli_show_value.html">(筆記) 如何將參數從Verilog傳到C? (SOC) (Verilog) (Verilog PLI)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2009/03/25/verilog_hello_world.html">(原創) 如何使用C開發Verilog System Task/Function? (SOC) (Verilog) (Verilog PLI)</a></li> <li><a href="http://www.cnblogs.com/oomusou/archive/2008/02/11/1066839.html">(原創) 如何讀取/寫入文字檔? (IC Design) (Verilog)</a></li> </ol> <h1><span>VHDL</span></h1> <ol> <li><a href="http://www.freetechbooks.com/the-vhdl-cookbook-first-edition-t431.html">The VHDL Cookbook</a>, First Edition , Author : Peter J. Ashenden, School of Computer Science, University of Adelaide , Publication Date : July 1990</li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:veritek</guid>
				<title>Veritek</title>
				<link>http://ccckmit.wikidot.com/ve:veritek</link>
				<description>

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.sugawara-systems.com/&quot;&gt;http://www.sugawara-systems.com/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Veritak is a Verilog HDL Compiler/Simulator that supports the major Verilog 2001 HDL features. It provides an integrated environment, which includes a VHDL to Verilog translator, a syntax highlighting editor (called Veripad), a class hierarchy viewer, a multiple-waveform viewer capable of handling a gigabyte vcd files, source analyzer, and more &amp;#8212; it is available for Windows XP/2000/2003/Vista32/Vista64/Windows7&amp;#160;32bit/64bit..&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sat, 20 Jul 2013 23:44:40 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ol> <li><a href="http://www.sugawara-systems.com/">http://www.sugawara-systems.com/</a> <ul> <li>Veritak is a Verilog HDL Compiler/Simulator that supports the major Verilog 2001 HDL features. It provides an integrated environment, which includes a VHDL to Verilog translator, a syntax highlighting editor (called Veripad), a class hierarchy viewer, a multiple-waveform viewer capable of handling a gigabyte vcd files, source analyzer, and more &#8212; it is available for Windows XP/2000/2003/Vista32/Vista64/Windows7&#160;32bit/64bit..</li> </ul> </li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:cpu0s</guid>
				<title>使用 Verilog 設計 CPU0 處理器</title>
				<link>http://ccckmit.wikidot.com/ve:cpu0s</link>
				<description>

&lt;p&gt;專案下載：&lt;a href=&quot;http://ccckmit.wdfiles.com/local--files/ve:cpu0s/cpu0s.zip&quot;&gt;cpu0s.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 23 May 2012 02:25:27 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>專案下載：<a href="http://ccckmit.wdfiles.com/local--files/ve:cpu0s/cpu0s.zip">cpu0s.zip</a></p> <h1><span>教學影片</span></h1> <p><iframe width="640" height="480" src="http://www.youtube.com/embed/KcbUO_VRQ0U" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p> <h1><span>輸入指令檔：cpu0s.hex</span></h1> <div class="code"> <pre><code>00 DF 00 B6 // 0 LD R13, StackEnd 08 40 00 04 // 4 LDI R4, 4 08 50 00 08 // 8 LDI R5, 8 05 4D 50 00 // c STR R4, [R13+R5] 04 6D 50 00 // 10 LDR R6, [R13+R5] 07 5D 40 00 // 14 SBR R5, [R13+R4] 06 6D 40 00 // 18 LBR R6, [R13+R4] 30 E0 00 00 // 1C PUSH R14 12 85 00 00 // 20 MOV R8, R5 13 85 40 00 // 24 ADD R8, R5, R4 14 85 40 00 // 28 SUB R8, R5, R4 15 85 40 00 // 2c MUL R8, R5, R4 16 85 40 00 // 30 DIV R8, R5, R4 18 85 40 00 // 34 AND R8, R5, R4 19 85 40 00 // 38 OR R8, R5, R4 1A 85 40 00 // 3c XOR R8, R5, R4 1E 85 00 03 // 40 SHL R8, R5, 3 1F 85 00 02 // 44 SHR R8, R5, 2 10 45 00 00 // 48 CMP R4, R5 20 00 00 18 // 4c JEQ L1 23 00 00 14 // 50 JGT L1 25 00 00 10 // 54 JGE L1 22 00 00 0C // 58 JLT L1 24 00 00 08 // 5c JLE L1 21 00 00 04 // 60 JNE L1 26 00 00 00 // 64 JMP L1 08 10 00 0A // 68 L1: LDI R1, 10 2B 00 00 08 // 6c CALL SUM 31 E0 00 00 // 70 POP R14 2C 00 00 00 // 74 RET 30 E0 00 00 // 78 SUM: PUSH R14 12 30 00 00 // 7c MOV R3, R0 // R3 = i = 0 02 4F 00 24 // 80 LDB R4, k1 // R4 = 1 08 20 00 00 // 84 LDI R2, 0 // SUM = R2 = 0 13 22 30 00 // 88 LOOP: ADD R2, R2, R3 // SUM = SUM + i 13 33 40 00 // 8c ADD R3, R3, R4 // i = i + 1 10 31 00 00 // 90 CMP R3, R1 // if (i &lt; R1) 24 FF FF F0 // 94 JLE LOOP // goto LOOP 01 2F 00 0D // 98 ST R2, s 03 3F 00 0D // 9c STB R3, i 31 E0 00 00 // a0 POP R14 2C 00 00 00 // a4 RET // return 01 // a8 k1: BYTE 1 // char K1=1 00 00 00 00 // a9 s: WORD 0 // int s 00 // ad i: BYTE 0 // char i=1 00 01 02 03 // ae Stack: BYTE 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11 04 05 06 07 // b2 08 09 0A 0B // b6 00 00 00 BA // ba StackEnd: WORD StackEnd 01 02 03 04 // be Data: BYTE 0, 1, 2, 3, 4, 5, 6, 7, 8 05 06 07 08 // c2</code></pre></div> <h1><span>Verilog 程式：cpu0s.v</span></h1> <div class="code"> <pre><code>// 寬度形態常數 `define INT32 2'b11 // 寬度 32 位元 `define INT24 2'b10 // 寬度 24 位元 `define INT16 2'b01 // 寬度 16 位元 `define BYTE 2'b00 // 寬度 8 位元 // 參考文獻：http://ccckmit.wikidot.com/ocs:cpu0 module cpu0(input clock, reset, output reg [2:0] tick, output reg [31:0] ir, pc, mar, mdr, inout [31:0] dbus, output reg m_en, m_rw, output reg [1:0] m_size); reg signed [31:0] R [0:15]; reg [7:0] op; reg [3:0] a, b, c; reg [4:0] c5; reg signed [31:0] c12, c16, c24, Ra, Rb, Rc, pc0; // pc0 : instruction pc // 暫存器簡稱 `define PC R[15] // 程式計數器 `define LR R[14] // 連結暫存器 `define SP R[13] // 堆疊暫存器 `define SW R[12] // 狀態暫存器 // 狀態暫存器旗標位元 `define N `SW[31] // 負號旗標 `define Z `SW[30] // 零旗標 `define C `SW[29] // 進位旗標 `define V `SW[28] // 溢位旗標 `define I `SW[7] // 硬體中斷許可 `define T `SW[6] // 軟體中斷許可 `define M `SW[0] // 模式位元 // 指令編碼表 parameter [7:0] LD=8'h00,ST=8'h01,LDB=8'h02,STB=8'h03,LDR=8'h04,STR=8'h05, LBR=8'h06,SBR=8'h07,LDI=8'h08,CMP=8'h10,MOV=8'h12,ADD=8'h13,SUB=8'h14, MUL=8'h15,DIV=8'h16,AND=8'h18,OR=8'h19,XOR=8'h1A,ROL=8'h1C,ROR=8'h1D, SHL=8'h1E,SHR=8'h1F,JEQ=8'h20,JNE=8'h21,JLT=8'h22,JGT=8'h23,JLE=8'h24, JGE=8'h25,JMP=8'h26,SWI=8'h2A,CALL=8'h2B,RET=8'h2C,IRET=8'h2D, PUSH=8'h30,POP=8'h31,PUSHB=8'h32,POPB=8'h33; task memReadStart(input [31:0] addr, input [1:0] size); begin // 讀取記憶體 Word mar = addr; // read(m[addr]) m_rw = 1; // 讀取模式：read m_en = 1; // 啟動讀取 m_size = size; end endtask task memReadEnd(output [31:0] data); begin // 讀取記憶體完成，取得資料 mdr = dbus; // 取得記憶體傳回的 dbus = m[addr] data = mdr; // 傳回資料 m_en = 0; // 讀取完畢 end endtask // 寫入記憶體 -- addr:寫入位址, data:寫入資料 task memWriteStart(input [31:0] addr, input [31:0] data, input [1:0] size); begin mar = addr; // write(m[addr], data) mdr = data; m_rw = 0; // 寫入模式：write m_en = 1; // 啟動寫入 m_size = size; end endtask task memWriteEnd; begin // 寫入記憶體完成 m_en = 0; // 寫入完畢 end endtask task regSet(input [3:0] i, input [31:0] data); begin if (i!=0) R[i] = data; end endtask always @(posedge clock or posedge reset) begin if (reset) begin `PC = 0; tick = 0; R[0] = 0; `SW = 0; `LR = -1; end else begin tick = tick+1; m_en = 0; case (tick) 1: begin // Tick 1 : 指令擷取，將 PC 丟到位址匯流排上，memory.read(m[PC]) memReadStart(`PC, `INT32); pc0 = `PC; `PC = `PC+4; end 2: begin // Tick 2 : 指令解碼，ir = m[PC] memReadEnd(ir); // IR = dbus = m[PC] {op,a,b,c} = ir[31:12]; c24 = $signed(ir[23:0]); c16 = $signed(ir[15:0]); c12 = $signed(ir[11:0]); c5 = ir[4:0]; Ra = R[a]; Rb = R[b]; Rc = R[c]; end 3: begin // Tick 3 : 指令執行 case (op) // 載入儲存指令 LD: memReadStart(Rb+c16, `INT32); // 載入word; LD Ra, [Rb+Cx]; Ra&lt;=[Rb+ Cx] ST: memWriteStart(Rb+c16, Ra, `INT32); // 儲存word; ST Ra, [Rb+ Cx]; Ra=&gt;[Rb+ Cx] LDB: memReadStart(Rb+c16, `BYTE); // 載入byte; LDB Ra, [Rb+ Cx]; Ra&lt;=(byte)[Rb+ Cx] STB: memWriteStart(Rb+c16, Ra, `BYTE); // 儲存byte; STB Ra, [Rb+ Cx]; Ra=&gt;(byte)[Rb+ Cx] LDR: memReadStart(Rb+Rc, `INT32); // LD的Rc版; LDR Ra, [Rb+Rc]; Ra&lt;=[Rb+ Rc] STR: memWriteStart(Rb+Rc, Ra, `INT32); // ST的Rc版; STR Ra, [Rb+Rc]; Ra=&gt;[Rb+ Rc] LBR: memReadStart(Rb+Rc, `BYTE); // LDB的Rc版; LBR Ra, [Rb+Rc]; Ra&lt;=(byte)[Rb+ Rc] SBR: memWriteStart(Rb+Rc, Ra, `BYTE); // STB的Rc版; SBR Ra, [Rb+Rc]; Ra=&gt;(byte)[Rb+ Rc] LDI: R[a] = Rb+c16; // 立即載入; LDI Ra, Rb+Cx; Ra&lt;=Rb + Cx // 運算指令 CMP: begin `N=(Ra-Rb&lt;0);`Z=(Ra-Rb==0); end // 比較; CMP Ra, Rb; SW=(Ra &gt;=&lt; Rb) MOV: regSet(a, Rb); // 移動; MOV Ra, Rb; Ra&lt;=Rb ADD: regSet(a, Rb+Rc); // 加法; ADD Ra, Rb, Rc; Ra&lt;=Rb+Rc SUB: regSet(a, Rb-Rc); // 減法; SUB Ra, Rb, Rc; Ra&lt;=Rb-Rc MUL: regSet(a, Rb*Rc); // 乘法; MUL Ra, Rb, Rc; Ra&lt;=Rb*Rc DIV: regSet(a, Rb/Rc); // 除法; DIV Ra, Rb, Rc; Ra&lt;=Rb/Rc AND: regSet(a, Rb&amp;Rc); // 位元 AND; AND Ra, Rb, Rc; Ra&lt;=Rb and Rc OR: regSet(a, Rb|Rc); // 位元 OR; OR Ra, Rb, Rc; Ra&lt;=Rb or Rc XOR: regSet(a, Rb^Rc); // 位元 XOR; XOR Ra, Rb, Rc; Ra&lt;=Rb xor Rc SHL: regSet(a, Rb&lt;&lt;c5); // 向左移位; SHL Ra, Rb, Cx; Ra&lt;=Rb &lt;&lt; Cx SHR: regSet(a, Rb&gt;&gt;c5); // 向右移位; SHR Ra, Rb, Cx; Ra&lt;=Rb &gt;&gt; Cx // 跳躍指令 JEQ: if (`Z) `PC=`PC+c24; // 跳躍 (相等); JEQ Cx; if SW(=) PC PC+Cx JNE: if (!`Z) `PC=`PC+c24; // 跳躍 (不相等); JNE Cx; if SW(!=) PC PC+Cx JLT: if (`N)`PC=`PC+c24; // 跳躍 ( &lt; ); JLT Cx; if SW(&lt;) PC PC+Cx JGT: if (!`N&amp;&amp;!`Z) `PC=`PC+c24; // 跳躍 ( &gt; ); JGT Cx; if SW(&gt;) PC PC+Cx JLE: if (`N || `Z) `PC=`PC+c24; // 跳躍 ( &lt;= ); JLE Cx; if SW(&lt;=) PC PC+Cx JGE: if (!`N || `Z) `PC=`PC+c24; // 跳躍 ( &gt;= ); JGE Cx; if SW(&gt;=) PC PC+Cx JMP: `PC = `PC+c24; // 跳躍 (無條件); JMP Cx; PC &lt;= PC+Cx SWI: begin `LR=`PC;`PC= c24; `I = 1'b1; end // 軟中斷; SWI Cx; LR &lt;= PC; PC &lt;= Cx; INT&lt;=1 CALL:begin `LR=`PC;`PC=`PC + c24; end // 跳到副程式; CALL Cx; LR&lt;=PC; PC&lt;=PC+Cx RET: begin `PC=`LR; end // 返回; RET; PC &lt;= LR IRET:begin `PC=`LR;`I = 1'b0; end // 中斷返回; IRET; PC &lt;= LR; INT&lt;=0 // 堆疊指令 PUSH:begin `SP = `SP-4; memWriteStart(`SP, Ra, `INT32); end // 推入 word; PUSH Ra; SP-=4;[SP]&lt;=Ra; POP: begin memReadStart(`SP, `INT32); `SP = `SP + 4; end // 彈出 word; POP Ra; Ra=[SP];SP+=4; PUSHB:begin `SP = `SP-1; memWriteStart(`SP, Ra, `BYTE); end // 推入 byte; PUSHB Ra; SP--;[SP]&lt;=Ra;(byte) POPB:begin memReadStart(`SP, `BYTE); `SP = `SP+1; end // 彈出 byte; POPB Ra; Ra&lt;=[SP];SP++;(byte) endcase end 4: begin // 讀取寫入指令完成，關閉記憶體 case (op) LD, LDB, LDR, LBR, POP, POPB : memReadEnd(R[a]); // 讀取記憶體完成 ST, STB, STR, SBR, PUSH, PUSHB: memWriteEnd(); // 寫入記憶體完成 endcase $display(&quot;%4dns %8x : %8x R[%02d]=%-8x=%-d SW=%8x&quot;, $stime, pc0, ir, a, R[a], R[a], `SW); if (op==RET &amp;&amp; `PC &lt; 0) begin $display(&quot;RET to PC &lt; 0, finished!&quot;); $finish; end tick = 0; end endcase end pc = `PC; end endmodule module memory0(input clock, reset, en, rw, input [1:0] m_size, input [31:0] abus, dbus_in, output [31:0] dbus_out); reg [7:0] m [0:258]; reg [31:0] data; integer i; initial begin $readmemh(&quot;cpu0s.hex&quot;, m); for (i=0; i &lt; 255; i=i+4) begin $display(&quot;%8x: %8x&quot;, i, {m[i], m[i+1], m[i+2], m[i+3]}); end end always @(clock or abus or en or rw or dbus_in) begin if (abus &gt;=0 &amp;&amp; abus &lt;= 255) begin if (en == 1 &amp;&amp; rw == 0) begin // r_w==0:write data = dbus_in; case (m_size) `BYTE: {m[abus]} = dbus_in[7:0]; `INT16: {m[abus], m[abus+1] } = dbus_in[15:0]; `INT24: {m[abus], m[abus+1], m[abus+2]} = dbus_in[24:0]; `INT32: {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus_in; endcase end else if (en == 1 &amp;&amp; rw == 1) begin// r_w==1:read case (m_size) `BYTE: data = {8'h00 , 8'h00, 8'h00, m[abus] }; `INT16: data = {8'h00 , 8'h00, m[abus], m[abus+1] }; `INT24: data = {8'h00 , m[abus], m[abus+1], m[abus+2] }; `INT32: data = {m[abus], m[abus+1], m[abus+2], m[abus+3]}; endcase end else data = 32'hZZZZZZZZ; end else data = 32'hZZZZZZZZ; end assign dbus_out = data; endmodule module main; reg clock, reset; wire [2:0] tick; wire [31:0] pc, ir, mar, mdr, dbus; wire m_en, m_rw; wire [1:0] m_size; cpu0 cpu(.clock(clock), .reset(reset), .pc(pc), .tick(tick), .ir(ir), .mar(mar), .mdr(mdr), .dbus(dbus), .m_en(m_en), .m_rw(m_rw), .m_size(m_size)); memory0 mem(.clock(clock), .reset(reset), .en(m_en), .rw(m_rw), .m_size(m_size), .abus(mar), .dbus_in(mdr), .dbus_out(dbus)); initial begin clock = 0; reset = 1; #20 reset = 0; #10000 $finish; end always #10 clock=clock+1; endmodule</code></pre></div> <h1><span>執行結果</span></h1> <div class="code"> <pre><code>D:\oc\cpu0&gt;iverilog cpu0s.v -o cpu0s D:\oc\cpu0&gt;vvp cpu0s WARNING: cpu0s.v:169: $readmemh(cpu0s.hex): Not enough words in the file for the requested range [0:258]. 00000000: 00df00b6 00000004: 08400004 00000008: 08500008 0000000c: 054d5000 00000010: 046d5000 00000014: 075d4000 00000018: 066d4000 0000001c: 30e00000 00000020: 12850000 00000024: 13854000 00000028: 14854000 0000002c: 15854000 00000030: 16854000 00000034: 18854000 00000038: 19854000 0000003c: 1a854000 00000040: 1e850003 00000044: 1f850002 00000048: 10450000 0000004c: 20000018 00000050: 23000014 00000054: 25000010 00000058: 2200000c 0000005c: 24000008 00000060: 21000004 00000064: 26000000 00000068: 0810000a 0000006c: 2b000008 00000070: 31e00000 00000074: 2c000000 00000078: 30e00000 0000007c: 12300000 00000080: 024f0024 00000084: 08200000 00000088: 13223000 0000008c: 13334000 00000090: 10310000 00000094: 24fffff0 00000098: 012f000d 0000009c: 033f000d 000000a0: 31e00000 000000a4: 2c000000 000000a8: 01000000 000000ac: 00000001 000000b0: 02030405 000000b4: 06070809 000000b8: 0a0b0000 000000bc: 00ba0102 000000c0: 03040506 000000c4: 0708xxxx 000000c8: xxxxxxxx 000000cc: xxxxxxxx 000000d0: xxxxxxxx 000000d4: xxxxxxxx 000000d8: xxxxxxxx 000000dc: xxxxxxxx 000000e0: xxxxxxxx 000000e4: xxxxxxxx 000000e8: xxxxxxxx 000000ec: xxxxxxxx 000000f0: xxxxxxxx 000000f4: xxxxxxxx 000000f8: xxxxxxxx 000000fc: xxxxxxxx 90ns 00000000 : 00df00b6 R[13]=000000ba=186 SW=00000000 170ns 00000004 : 08400004 R[04]=00000004=4 SW=00000000 250ns 00000008 : 08500008 R[05]=00000008=8 SW=00000000 330ns 0000000c : 054d5000 R[04]=00000004=4 SW=00000000 410ns 00000010 : 046d5000 R[06]=00000004=4 SW=00000000 490ns 00000014 : 075d4000 R[05]=00000008=8 SW=00000000 570ns 00000018 : 066d4000 R[06]=00000008=8 SW=00000000 650ns 0000001c : 30e00000 R[14]=ffffffff=-1 SW=00000000 730ns 00000020 : 12850000 R[08]=00000008=8 SW=00000000 810ns 00000024 : 13854000 R[08]=0000000c=12 SW=00000000 890ns 00000028 : 14854000 R[08]=00000004=4 SW=00000000 970ns 0000002c : 15854000 R[08]=00000020=32 SW=00000000 1050ns 00000030 : 16854000 R[08]=00000002=2 SW=00000000 1130ns 00000034 : 18854000 R[08]=00000000=0 SW=00000000 1210ns 00000038 : 19854000 R[08]=0000000c=12 SW=00000000 1290ns 0000003c : 1a854000 R[08]=0000000c=12 SW=00000000 1370ns 00000040 : 1e850003 R[08]=00000040=64 SW=00000000 1450ns 00000044 : 1f850002 R[08]=00000002=2 SW=00000000 1530ns 00000048 : 10450000 R[04]=00000004=4 SW=80000000 1610ns 0000004c : 20000018 R[00]=00000000=0 SW=80000000 1690ns 00000050 : 23000014 R[00]=00000000=0 SW=80000000 1770ns 00000054 : 25000010 R[00]=00000000=0 SW=80000000 1850ns 00000058 : 2200000c R[00]=00000000=0 SW=80000000 1930ns 00000068 : 0810000a R[01]=0000000a=10 SW=80000000 2010ns 0000006c : 2b000008 R[00]=00000000=0 SW=80000000 2090ns 00000078 : 30e00000 R[14]=00000070=112 SW=80000000 2170ns 0000007c : 12300000 R[03]=00000000=0 SW=80000000 2250ns 00000080 : 024f0024 R[04]=00000001=1 SW=80000000 2330ns 00000084 : 08200000 R[02]=00000000=0 SW=80000000 2410ns 00000088 : 13223000 R[02]=00000000=0 SW=80000000 2490ns 0000008c : 13334000 R[03]=00000001=1 SW=80000000 2570ns 00000090 : 10310000 R[03]=00000001=1 SW=80000000 2650ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 2730ns 00000088 : 13223000 R[02]=00000001=1 SW=80000000 2810ns 0000008c : 13334000 R[03]=00000002=2 SW=80000000 2890ns 00000090 : 10310000 R[03]=00000002=2 SW=80000000 2970ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 3050ns 00000088 : 13223000 R[02]=00000003=3 SW=80000000 3130ns 0000008c : 13334000 R[03]=00000003=3 SW=80000000 3210ns 00000090 : 10310000 R[03]=00000003=3 SW=80000000 3290ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 3370ns 00000088 : 13223000 R[02]=00000006=6 SW=80000000 3450ns 0000008c : 13334000 R[03]=00000004=4 SW=80000000 3530ns 00000090 : 10310000 R[03]=00000004=4 SW=80000000 3610ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 3690ns 00000088 : 13223000 R[02]=0000000a=10 SW=80000000 3770ns 0000008c : 13334000 R[03]=00000005=5 SW=80000000 3850ns 00000090 : 10310000 R[03]=00000005=5 SW=80000000 3930ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 4010ns 00000088 : 13223000 R[02]=0000000f=15 SW=80000000 4090ns 0000008c : 13334000 R[03]=00000006=6 SW=80000000 4170ns 00000090 : 10310000 R[03]=00000006=6 SW=80000000 4250ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 4330ns 00000088 : 13223000 R[02]=00000015=21 SW=80000000 4410ns 0000008c : 13334000 R[03]=00000007=7 SW=80000000 4490ns 00000090 : 10310000 R[03]=00000007=7 SW=80000000 4570ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 4650ns 00000088 : 13223000 R[02]=0000001c=28 SW=80000000 4730ns 0000008c : 13334000 R[03]=00000008=8 SW=80000000 4810ns 00000090 : 10310000 R[03]=00000008=8 SW=80000000 4890ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 4970ns 00000088 : 13223000 R[02]=00000024=36 SW=80000000 5050ns 0000008c : 13334000 R[03]=00000009=9 SW=80000000 5130ns 00000090 : 10310000 R[03]=00000009=9 SW=80000000 5210ns 00000094 : 24fffff0 R[15]=00000088=136 SW=80000000 5290ns 00000088 : 13223000 R[02]=0000002d=45 SW=80000000 5370ns 0000008c : 13334000 R[03]=0000000a=10 SW=80000000 5450ns 00000090 : 10310000 R[03]=0000000a=10 SW=40000000 5530ns 00000094 : 24fffff0 R[15]=00000088=136 SW=40000000 5610ns 00000088 : 13223000 R[02]=00000037=55 SW=40000000 5690ns 0000008c : 13334000 R[03]=0000000b=11 SW=40000000 5770ns 00000090 : 10310000 R[03]=0000000b=11 SW=00000000 5850ns 00000094 : 24fffff0 R[15]=00000098=152 SW=00000000 5930ns 00000098 : 012f000d R[02]=00000037=55 SW=00000000 6010ns 0000009c : 033f000d R[03]=0000000b=11 SW=00000000 6090ns 000000a0 : 31e00000 R[14]=00000070=112 SW=00000000 6170ns 000000a4 : 2c000000 R[00]=00000000=0 SW=00000000 6250ns 00000070 : 31e00000 R[14]=ffffffff=-1 SW=00000000 6330ns 00000074 : 2c000000 R[00]=00000000=0 SW=00000000 RET to PC &lt; 0, finished!</code></pre></div> <h1><span>歷史版本</span></h1> <ol> <li><a href="http://ccckmit.wikidot.com/ve:cpu0s">使用 Verilog 設計 CPU0 處理器 (簡單設計版1)</a> (中間版，程式完整，但測試不完整，程式較繁瑣)</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0s2">使用 Verilog 設計 CPU0 處理器 (簡單設計版2)</a> (中間版，程式完整，但測試不完整，程式較簡單)</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0s3">使用 Verilog 設計 CPU0 處理器 (簡單設計版3)</a> (程式完整，測試完整)</li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:cpu0p</guid>
				<title>Cpu0p</title>
				<link>http://ccckmit.wikidot.com/ve:cpu0p</link>
				<description>

&lt;h1&gt;&lt;span&gt;撰寫中：版本&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p0.9.zip&quot;&gt;cpu0p0.9.zip&lt;/a&gt; &amp;#8212; 混雜 = 與 &amp;lt;= 的程式，但可以正確運作。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p1.0.zip&quot;&gt;cpu0p1.0.zip&lt;/a&gt; &amp;#8212; 只使用 = 的程式，可以正確運作。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p1.1.zip&quot;&gt;cpu0p1.1.zip&lt;/a&gt; &amp;#8212; 只使用 &amp;lt;= 的程式，無法正確運作，修改中。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;規劃原則&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;指令與資料的存取必須使用兩組線路，因此有很多種可能的方法。
&lt;ul&gt;
&lt;li&gt;方案一：使用兩塊記憶體： iMem 與 dMem (哈佛架構)&lt;/li&gt;
&lt;li&gt;方案二：使用一塊記憶體加兩個 cache：iCache 與 dCache&lt;/li&gt;
&lt;li&gt;方案三：使用一塊記憶體，但是該記憶體有兩組位址線與資料線，也就是有 abus1, dbus1, abus2, dbus2 等兩組線。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;本程式採用方案三單一記憶體兩組線的方式。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;Verilog 程式：cpu0p.v&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;// 管線狀態：IDLE 或 WAIT
`define IDLE     2&#039;b00       // 閒置中
`define WAIT_M   2&#039;b01   // 等待回應
`define WAIT_ACK 2&#039;b10   // 等待回應

// 寬度形態常數
`define INT32 2&#039;b11     // 寬度 32 位元
`define INT24 2&#039;b10     // 寬度 24 位元
`define INT16 2&#039;b01     // 寬度 16 位元
`define BYTE  2&#039;b00     // 寬度  8 位元
// 暫存器簡稱
`define PC   cpu.R[15]   // 程式計數器
`define LR   cpu.R[14]   // 連結暫存器
`define SP   cpu.R[13]   // 堆疊暫存器
`define SW   cpu.R[12]   // 狀態暫存器
`define IR   cpu.ir         // 指令暫存器
// 狀態暫存器旗標位元
`define N    `SW[31] // 負號旗標
`define Z    `SW[30] // 零旗標
`define C    `SW[29] // 進位旗標
`define V    `SW[28] // 溢位旗標
`define I    `SW[7]  // 硬體中斷許可
`define T    `SW[6]  // 軟體中斷許可
`define M    `SW[0]  // 模式位元

module iFetch(input clock, reset, iReady, output reg iGet, oReady, input oGet);
reg [1:0] state;
reg [31:0] pc, pc0;

    always @(posedge clock) begin
        if (reset) begin oReady=0; iGet=0; state=`IDLE; end 
        else case (state) 
            `IDLE: begin // 閒置中
                #1;
                if (iReady) begin // 輸入資料已準備好
                    #1;
                    memReadStart1(`PC, `INT32);
                    pc0 = `PC;
                    `PC = `PC+4;
                    pc = `PC;
                    iGet = 1; // 處理輸入資料
                    #1;
                    state = `WAIT_ACK; // 進入等待狀態
                    oReady = 1;
                end
            end
            `WAIT_ACK:begin // 等待回應 (資料被取走)
                #1;                
                if (oGet) begin // 資料被取走了
                    oReady = 0; // 下一筆輸出資料尚未準備好。
                    state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料
                end
                #1;                
                iGet = 0;  // 下一筆輸入資料尚未準備好。
            end
        endcase
    end
endmodule

module iDecode(input clock, reset, iReady, output reg iGet, oReady, input oGet);
    parameter name=&amp;quot;iDecode&amp;quot;;
    reg [1:0] state;
    reg [31:0] ir, pc, pc0;
    reg [7:0] op;
    reg [3:0] a, b, c;
    reg [4:0] c5;
    reg signed [11:0] cx12;
    reg signed [15:0] cx16;
    reg signed [23:0] cx24;
    reg signed [31:0] c12, c16, c24, Ra, Rb, Rc; // ipc:instruction PC

    always @(posedge clock) begin
        if (reset) begin oReady=0; iGet=0; state=`IDLE; end 
        else case (state) 
            `IDLE: begin // 閒置中
                #1;                
                if (iReady &amp;amp;&amp;amp; (!cpu.m_en1 || cpu.m_ack1)) begin // 輸入資料已準備好
                    memReadEnd1(ir); // IR = dbus = m[PC]
                    pc0 = cpu.if1.pc0;
                    pc = cpu.if1.pc;
                    $display(&amp;quot;%-4d:fetch , pc0=%x pc=%x ir=%x&amp;quot;, $stime, pc0, pc, ir);
                    iGet = 1;
                    // 處理輸入資料
                    {op, a, b, c, cx12} = ir;
                    cx24 = ir[23:0];
                    cx16 = ir[15:0];
                    c5  = ir[4:0];
                    c12 = cx12; // 取出 cx12 並轉為 32 位元有號數 c12
                    c16 = cx16; // 取出 cx16 並轉為 32 位元有號數 c16
                    c24 = cx24; // 取出 cx24 並轉為 32 位元有號數 c24
                    Ra = cpu.R[a];
                    Rb = cpu.R[b];
                    Rc = cpu.R[c]; 
                    case (op)
                        // 載入儲存指令
                        cpu.LD:  memReadStart2(Rb+c16, `INT32);         // 載入word;    LD Ra, [Rb+Cx];     Ra&amp;lt;=[Rb+ Cx]
                        cpu.ST:  memWriteStart2(Rb+c16, Ra, `INT32); // 儲存word;    ST Ra, [Rb+ Cx];     Ra=&amp;gt;[Rb+ Cx]
                        cpu.LDB: memReadStart2(Rb+c16, `BYTE);        // 載入byte;    LDB Ra, [Rb+ Cx];     Ra&amp;lt;=(byte)[Rb+ Cx]
                        cpu.STB: memWriteStart2(Rb+c16, Ra, `BYTE);     // 儲存byte;    STB Ra, [Rb+ Cx];    Ra=&amp;gt;(byte)[Rb+ Cx]
                        cpu.LDR: memReadStart2(Rb+Rc, `INT32);        // LD的Rc版;     LDR Ra, [Rb+Rc];    Ra&amp;lt;=[Rb+ Rc]
                        cpu.STR: memWriteStart2(Rb+Rc, Ra, `INT32);    // ST的Rc版;    STR Ra, [Rb+Rc];    Ra=&amp;gt;[Rb+ Rc]
                        cpu.LBR: memReadStart2(Rb+Rc, `BYTE);        // LDB的Rc版;    LBR Ra, [Rb+Rc];    Ra&amp;lt;=(byte)[Rb+ Rc]
                        cpu.SBR: memWriteStart2(Rb+Rc, Ra, `BYTE);    // STB的Rc版;    SBR Ra, [Rb+Rc];    Ra=&amp;gt;(byte)[Rb+ Rc]
                        // 堆疊指令    
                        cpu.PUSH:begin `SP = `SP-4; memWriteStart2(`SP, Ra, `INT32); end // 推入 word;    PUSH Ra;    SP-=4;[SP]&amp;lt;=Ra;
                        cpu.POP: begin memReadStart2(`SP, `INT32); `SP = `SP + 4; end    // 彈出 word;    POP Ra;     Ra=[SP];SP+=4;
                        cpu.PUSHB:begin `SP = `SP-1; memWriteStart2(`SP, Ra, `BYTE); end    // 推入 byte;    PUSHB Ra;     SP--;[SP]&amp;lt;=Ra;(byte)
                        cpu.POPB:begin memReadStart2(`SP, `BYTE); `SP = `SP+1; end        // 彈出 byte;    POPB Ra;     Ra&amp;lt;=[SP];SP++;(byte)
                    endcase
                    #1;
                    oReady = 1; // 輸出資料已準備好
                    state = `WAIT_ACK; // 進入等待狀態
                    $display(&amp;quot;%-4d:decode, pc0=%x pc=%x ir=%x op=%x a=%x b=%x c=%x cx12=%x&amp;quot;, $stime, pc0, pc, ir, op, a, b, c, cx12);
                end
                #1;                
            end
            `WAIT_ACK:begin // 等待回應 (資料被取走)
                #1;                
                if (oGet) begin // 資料被取走了
                    oReady = 0; // 下一筆輸出資料尚未準備好。
                    state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料
                end
                #1;                
                iGet = 0;  // 下一筆輸入資料尚未準備好。
            end
        endcase
    end
endmodule

module iExec(input clock, reset, iReady, output reg iGet, oReady, input oGet);
    parameter name=&amp;quot;iExec&amp;quot;;
    reg [31:0] ir, pc, pc0;
    reg [7:0] op;
    reg [3:0] a, b, c;
    reg [4:0] c5;
    reg signed [31:0] c12, c16, c24, Ra, Rb, Rc; // ipc:instruction PC
    reg [1:0] state;
    reg [1:0] skip;

    always @(posedge clock) begin
        if (reset) begin oReady=0; iGet=0; state=`IDLE; skip = 0; end 
        else case (state) 
            `IDLE: begin // 閒置中
                #1;                
                if (iReady &amp;amp;&amp;amp; (!cpu.m_en2 || cpu.m_ack2)) begin // 輸入資料已準備好
                    if (skip &amp;gt; 0) skip = skip-1; else begin
                    // 處理輸入資料
                    pc0 = cpu.id1.pc0;
                    pc = cpu.id1.pc;
                    ir = cpu.id1.ir;
                    op = cpu.id1.op;
                    a = cpu.id1.a;
                    b = cpu.id1.b;
                    c = cpu.id1.c;
                    c5 = cpu.id1.c5;
                    c12 = cpu.id1.c12;
                    c16 = cpu.id1.c16;
                    c24 = cpu.id1.c24;
                    Ra = cpu.id1.Ra;
                    Rb = cpu.id1.Rb;
                    Rc = cpu.id1.Rc;
                    iGet = 1;
                    // 準備輸出資料
                    case (op)
                        cpu.LD, cpu.LDB, cpu.LDR, cpu.LBR, cpu.POP, cpu.POPB  : memReadEnd2(cpu.R[a]); // 讀取記憶體完成
                        cpu.ST, cpu.STB, cpu.STR, cpu.SBR, cpu.PUSH, cpu.PUSHB: memWriteEnd2(); // 寫入記憶體完成
                        cpu.LDI: cpu.R[a] = Rb+c16;                     // 立即載入;    LDI Ra, Rb+Cx;        Ra&amp;lt;=Rb + Cx
                        // 運算指令
                        cpu.CMP: begin `N=(Ra-Rb&amp;lt;0);`Z=(Ra-Rb==0); end // 比較;        CMP Ra, Rb;         SW=(Ra &amp;gt;=&amp;lt; Rb)
                        cpu.MOV: regSet(a, Rb);                 // 移動;            MOV Ra, Rb;         Ra&amp;lt;=Rb
                        cpu.ADD: regSet(a, Rb+Rc);                // 加法;            ADD Ra, Rb, Rc;     Ra&amp;lt;=Rb+Rc
                        cpu.SUB: regSet(a, Rb-Rc);                // 減法;            SUB Ra, Rb, Rc;     Ra&amp;lt;=Rb-Rc
                        cpu.MUL: regSet(a, Rb*Rc);                // 乘法;             MUL Ra, Rb, Rc;     Ra&amp;lt;=Rb*Rc
                        cpu.DIV: regSet(a, Rb/Rc);                // 除法;             DIV Ra, Rb, Rc;     Ra&amp;lt;=Rb/Rc
                        cpu.AND: regSet(a, Rb&amp;amp;Rc);                // 位元 AND;        AND Ra, Rb, Rc;     Ra&amp;lt;=Rb and Rc
                        cpu.OR:  regSet(a, Rb|Rc);                // 位元 OR;            OR Ra, Rb, Rc;         Ra&amp;lt;=Rb or Rc
                        cpu.XOR: regSet(a, Rb^Rc);                // 位元 XOR;        XOR Ra, Rb, Rc;     Ra&amp;lt;=Rb xor Rc
                        cpu.SHL: regSet(a, Rb&amp;lt;&amp;lt;c5);                // 向左移位;        SHL Ra, Rb, Cx;     Ra&amp;lt;=Rb &amp;lt;&amp;lt; Cx
                        cpu.SHR: regSet(a, Rb&amp;gt;&amp;gt;c5);                // 向右移位;        SHR Ra, Rb, Cx;     Ra&amp;lt;=Rb &amp;gt;&amp;gt; Cx
                        // 跳躍指令
                        cpu.JEQ: if (`Z) begin `PC=pc+c24; skip=2; end // 跳躍 (相等);        JEQ Cx;        if SW(=) PC  PC+Cx
                        cpu.JNE: if (!`Z) begin `PC=pc+c24; skip=2; end  // 跳躍 (不相等);    JNE Cx;     if SW(!=) PC  PC+Cx
                        cpu.JLT: if (`N) begin `PC=pc+c24; skip=2; end        // 跳躍 ( &amp;lt; );        JLT Cx;     if SW(&amp;lt;) PC  PC+Cx
                        cpu.JGT: if (!`N&amp;amp;&amp;amp;!`Z) begin `PC=pc+c24; skip=2; end        // 跳躍 ( &amp;gt; );        JGT Cx;     if SW(&amp;gt;) PC  PC+Cx
                        cpu.JLE: if (`N || `Z) begin `PC=pc+c24; skip=2; end        // 跳躍 ( &amp;lt;= );        JLE Cx;     if SW(&amp;lt;=) PC  PC+Cx    
                        cpu.JGE: if (!`N || `Z) begin `PC=pc+c24; skip=2; end    // 跳躍 ( &amp;gt;= );        JGE Cx;     if SW(&amp;gt;=) PC  PC+Cx
                        cpu.JMP: begin `PC = pc+c24; skip=2; end                     // 跳躍 (無條件);    JMP Cx;     PC &amp;lt;= PC+Cx
                        cpu.SWI: begin `LR=pc;`PC= c24; `I = 1&#039;b1; skip=2; end // 軟中斷;    SWI Cx;         LR &amp;lt;= PC; PC &amp;lt;= Cx; INT&amp;lt;=1
                        cpu.CALL:begin `LR=pc;`PC=pc + c24; skip=2; end // 跳到副程式;    CALL Cx;     LR&amp;lt;=PC; PC&amp;lt;=PC+Cx
                        cpu.RET: begin `PC=`LR; skip=2;                 // 返回;            RET;         PC &amp;lt;= LR
                            if (`PC &amp;lt; 0) begin
                                $display(&amp;quot;RET to PC &amp;lt; 0, finished!&amp;quot;);
                                $finish;
                            end                        
                        end
                        cpu.IRET:begin `PC=`LR;`I = 1&#039;b0; skip=2; end    // 中斷返回;        IRET;         PC &amp;lt;= LR; INT&amp;lt;=0
                    endcase
                    Ra = cpu.R[a];
                    $display(&amp;quot;%-4d:exec  , pc0=%x ir=%x Ra=%x=%-4d Rb=%x Rc=%x&amp;quot;, $stime, pc0, ir, Ra, Ra, Rb, Rc);
                    end
                    #1;                
                    oReady = 1; // 輸出資料已準備好
                    state = `WAIT_ACK; // 進入等待狀態
                end
            end
            `WAIT_ACK:begin // 等待回應 (資料被取走)
                #1;                
                if (oGet) begin // 資料被取走了
                    #1;                
                    oReady = 0; // 下一筆輸出資料尚未準備好。
                    state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料
                end
                #1;                
                iGet = 0;  // 下一筆輸入資料尚未準備好。
            end
        endcase
    end
endmodule

module cpu(input clock, reset, output [31:0] ir, pc,
           output [31:0] mar1, mdr1, inout [31:0] dbus1, output reg m_en1, m_rw1, input m_ack1, output reg [1:0] m_size1,
           output [31:0] mar2, mdr2, inout [31:0] dbus2, output reg m_en2, m_rw2, input m_ack2, output reg [1:0] m_size2
           ); // cpu0 是由 if1, id1, ie1, iw1 四根管子 (pipe) 連接後形成的管線           
   // 管線相關參數
    wire ifiGet, idiGet, ieiGet, iwiGet; // pipe 輸入是否準備好了
    wire ifoReady, idoReady, ieoReady, iwoReady; // pipe 輸出是否準備好了
    parameter iReady = 1&#039;b1, oGet=1&#039;b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。
    // 暫存器與欄位
    reg [31:0] mar1, mdr1, mar2, mdr2;
    reg signed [31:0] R [0:15];

    // 指令編碼表
    parameter [7:0] LD=8&#039;h00,ST=8&#039;h01,LDB=8&#039;h02,STB=8&#039;h03,LDR=8&#039;h04,STR=8&#039;h05,
    LBR=8&#039;h06,SBR=8&#039;h07,LDI=8&#039;h08,CMP=8&#039;h10,MOV=8&#039;h12,ADD=8&#039;h13,SUB=8&#039;h14,
    MUL=8&#039;h15,DIV=8&#039;h16,AND=8&#039;h18,OR=8&#039;h19,XOR=8&#039;h1A,ROL=8&#039;h1C,ROR=8&#039;h1D,
    SHL=8&#039;h1E,SHR=8&#039;h1F,JEQ=8&#039;h20,JNE=8&#039;h21,JLT=8&#039;h22,JGT=8&#039;h23,JLE=8&#039;h24,
    JGE=8&#039;h25,JMP=8&#039;h26,SWI=8&#039;h2A,CALL=8&#039;h2B,RET=8&#039;h2C,IRET=8&#039;h2D,
    PUSH=8&#039;h30,POP=8&#039;h31,PUSHB=8&#039;h32,POPB=8&#039;h33;

    task memReadStart1(input [31:0] addr, input [1:0] size); begin // 讀取記憶體 Word
       mar1 = addr;     // read(m[addr])
       m_rw1 = 1;     // 讀取模式：read 
       m_en1 = 1;     // 啟動讀取
       m_size1 = size;
    end    endtask

    task memReadEnd1(output [31:0] data); begin // 讀取記憶體完成，取得資料
       mdr1 = dbus1; // 取得記憶體傳回的 dbus = m[addr]
       data = dbus1; // 傳回資料
       m_en1 = 0; // 讀取完畢
    end    endtask

    // 寫入記憶體 -- addr:寫入位址, data:寫入資料
    task memWriteStart1(input [31:0] addr, input [31:0] data, input [1:0] size); begin 
       mar1 = addr;    // write(m[addr], data)
       mdr1 = data;
       m_rw1 = 0;    // 寫入模式：write
       m_en1 = 1;     // 啟動寫入
       m_size1  = size;
    end    endtask

    task memWriteEnd1; begin // 寫入記憶體完成
       m_en1 = 0; // 寫入完畢
    end endtask

    task memReadStart2(input [31:0] addr, input [1:0] size); begin // 讀取記憶體 Word
       mar2 = addr;     // read(m[addr])
       m_rw2 = 1;     // 讀取模式：read 
       m_en2 = 1;     // 啟動讀取
       m_size2 = size;
    end    endtask

    task memReadEnd2(output [31:0] data); begin // 讀取記憶體完成，取得資料
       mdr2 = dbus2; // 取得記憶體傳回的 dbus = m[addr]
       data = dbus2; // 傳回資料
       m_en2 = 0; // 讀取完畢
    end    endtask

    // 寫入記憶體 -- addr:寫入位址, data:寫入資料
    task memWriteStart2(input [31:0] addr, input [31:0] data, input [1:0] size); begin 
       mar2 = addr;    // write(m[addr], data)
       mdr2 = data;
       m_rw2 = 0;    // 寫入模式：write
       m_en2 = 1;     // 啟動寫入
       m_size2  = size;
    end    endtask

    task memWriteEnd2; begin // 寫入記憶體完成
       m_en2 = 0; // 寫入完畢
    end endtask

    task regSet(input [3:0] i, input [31:0] data); begin
        if (i!=0) R[i] = data;
    end endtask

    iFetch      if1(clock, reset, iReady,   ifiGet, ifoReady, idiGet); // 管子：
    iDecode     id1(clock, reset, ifoReady, idiGet, idoReady, ieiGet); // 管子：
    iExec       ie1(clock, reset, idoReady, ieiGet, ieoReady, oGet);   // 管子：

    always @(posedge clock) begin
        if (reset) begin `PC = 0; R[0] = 0; `SW = 0; `LR = -1;  end
    end
endmodule

module memory(input clock, reset, en1, en2, rw1, rw2, output reg ack1, ack2, input [1:0] size1, size2, 
              input [31:0] abus1, abus2, dbus_in1, dbus_in2, output [31:0] dbus_out1, dbus_out2);
reg [7:0] m [0:258];
reg [31:0] data1, data2;

integer i;
initial begin
    $readmemh(&amp;quot;cpu0p.hex&amp;quot;, m);
    for (i=0; i &amp;lt; 255; i=i+4) begin
       $display(&amp;quot;%8x: %8x&amp;quot;, i, {m[i], m[i+1], m[i+2], m[i+3]});
    end
end

    always @(*) 
    begin
        if (en1) begin
            ack1 = 0;
            #30;
            if (abus1 &amp;gt;=0 &amp;amp;&amp;amp; abus1 &amp;lt;= 255) begin
                if (rw1 == 0) begin // r_w==0:write
                    data1 = dbus_in1;
                    case (size1)
                        `BYTE:  {m[abus1]} = dbus_in1[7:0];
                        `INT16: {m[abus1], m[abus1+1] } = dbus_in1[15:0];
                        `INT24: {m[abus1], m[abus1+1], m[abus1+2]} = dbus_in1[24:0];
                        `INT32: {m[abus1], m[abus1+1], m[abus1+2], m[abus1+3]} = dbus_in1;
                    endcase
                end else begin// rw == 1:read
                    case (size1)
                        `BYTE:  data1 = {8&#039;h00  , 8&#039;h00,   8&#039;h00,   m[abus1]      };
                        `INT16: data1 = {8&#039;h00  , 8&#039;h00,   m[abus1], m[abus1+1]    };
                        `INT24: data1 = {8&#039;h00  , m[abus1], m[abus1+1], m[abus1+2]  };
                        `INT32: data1 = {m[abus1], m[abus1+1], m[abus1+2], m[abus1+3]};
                    endcase
                end
            end
            ack1 = 1;
        end else begin
            data1 = 32&#039;hZZZZZZZZ;
            ack1 = 0;
        end
    end
    assign dbus_out1 = data1;

    always @(*) 
    begin
        if (en2) begin
            ack2 = 0;
            #30;
            if (abus2 &amp;gt;=0 &amp;amp;&amp;amp; abus2 &amp;lt;= 255) begin
                if (rw2 == 0) begin // r_w==0:write
                    data2 = dbus_in2;
                    case (size2)
                        `BYTE:  {m[abus2]} = dbus_in2[7:0];
                        `INT16: {m[abus2], m[abus2+1] } = dbus_in2[15:0];
                        `INT24: {m[abus2], m[abus2+1], m[abus2+2]} = dbus_in2[24:0];
                        `INT32: {m[abus2], m[abus2+1], m[abus2+2], m[abus2+3]} = dbus_in2;
                    endcase
                end else begin// rw == 1:read
                    case (size2)
                        `BYTE:  data2 = {8&#039;h00  , 8&#039;h00,   8&#039;h00,   m[abus2]      };
                        `INT16: data2 = {8&#039;h00  , 8&#039;h00,   m[abus2], m[abus2+1]    };
                        `INT24: data2 = {8&#039;h00  , m[abus2], m[abus2+1], m[abus2+2]  };
                        `INT32: data2 = {m[abus2], m[abus2+1], m[abus2+2], m[abus2+3]};
                    endcase
                end
            end
            ack2 = 1;
        end else begin
            data2 = 32&#039;hZZZZZZZZ;
            ack2 = 0;
        end
    end
    assign dbus_out2 = data2;
endmodule

module main;
    reg clock, reset;
    wire [31:0] pc, ir;
    wire [31:0] mar1, mar2, mdr1, mdr2, dbus1, dbus2;
    wire m_en1, m_en2, m_rw1, m_rw2, m_ack1, m_ack2;
    wire [1:0] m_size1, m_size2;

    cpu cpu0(.clock(clock), .reset(reset), .pc(pc), .ir(ir),
        .mar1(mar1), .mdr1(mdr1), .dbus1(dbus1), .m_en1(m_en1), .m_rw1(m_rw1), .m_size1(m_size1), .m_ack1(m_ack1),
        .mar2(mar2), .mdr2(mdr2), .dbus2(dbus2), .m_en2(m_en2), .m_rw2(m_rw2), .m_size2(m_size2), .m_ack2(m_ack2));

    memory memory0(.clock(clock), .reset(reset), 
      .en1(m_en1), .rw1(m_rw1), .ack1(m_ack1), .size1(m_size1), .abus1(mar1), .dbus_in1(mdr1), .dbus_out1(dbus1),
      .en2(m_en2), .rw2(m_rw2), .ack2(m_ack2), .size2(m_size2), .abus2(mar2), .dbus_in2(mdr2), .dbus_out2(dbus2));

    initial
    begin
        clock = 0;
        reset = 1;
        #50 reset = 0;
        #10000 $finish;
    end

    always #10 clock=clock+1;

endmodule&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;Icarus 模擬結果&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;D:\oc\cpu0p&amp;gt;vvp cpu0p
WARNING: cpu0p.v:312: $readmemh(cpu0p.hex): Not enough words in the file for the
 requested range [0:258].
00000000: 00df00b6
00000004: 08400004
00000008: 08500008
0000000c: 054d5000
00000010: 046d5000
00000014: 075d4000
00000018: 066d4000
0000001c: 30e00000
00000020: 12850000
00000024: 13854000
00000028: 14854000
0000002c: 15854000
00000030: 16854000
00000034: 18854000
00000038: 19854000
0000003c: 1a854000
00000040: 1e850003
00000044: 1f850002
00000048: 10450000
0000004c: 20000018
00000050: 23000014
00000054: 25000010
00000058: 2200000c
0000005c: 24000008
00000060: 21000004
00000064: 26000000
00000068: 0810000a
0000006c: 2b000008
00000070: 31e00000
00000074: 2c000000
00000078: 30e00000
0000007c: 12300000
00000080: 024f0024
00000084: 08200000
00000088: 13223000
0000008c: 13334000
00000090: 10310000
00000094: 24fffff0
00000098: 012f000d
0000009c: 033f000d
000000a0: 31e00000
000000a4: 2c000000
000000a8: 01000000
000000ac: 00000001
000000b0: 02030405
000000b4: 06070809
000000b8: 0a0b0000
000000bc: 00ba0102
000000c0: 03040506
000000c4: 0708xxxx
000000c8: xxxxxxxx
000000cc: xxxxxxxx
000000d0: xxxxxxxx
000000d4: xxxxxxxx
000000d8: xxxxxxxx
000000dc: xxxxxxxx
000000e0: xxxxxxxx
000000e4: xxxxxxxx
000000e8: xxxxxxxx
000000ec: xxxxxxxx
000000f0: xxxxxxxx
000000f4: xxxxxxxx
000000f8: xxxxxxxx
000000fc: xxxxxxxx
91  :fetch , pc0=00000000 pc=00000004 ir=00df00b6
92  :decode, pc0=00000000 pc=00000004 ir=00df00b6 op=00 a=d b=f c=0 cx12=0b6
131 :exec  , pc0=00000000 ir=00df00b6 Ra=000000ba=186  Rb=00000004 Rc=00000000
171 :fetch , pc0=00000004 pc=00000008 ir=08400004
172 :decode, pc0=00000004 pc=00000008 ir=08400004 op=08 a=4 b=0 c=0 cx12=004
191 :exec  , pc0=00000004 ir=08400004 Ra=00000004=4    Rb=00000000 Rc=00000000
251 :fetch , pc0=00000008 pc=0000000c ir=08500008
252 :decode, pc0=00000008 pc=0000000c ir=08500008 op=08 a=5 b=0 c=0 cx12=008
271 :exec  , pc0=00000008 ir=08500008 Ra=00000008=8    Rb=00000000 Rc=00000000
311 :fetch , pc0=0000000c pc=00000010 ir=054d5000
312 :decode, pc0=0000000c pc=00000010 ir=054d5000 op=05 a=4 b=d c=5 cx12=000
351 :exec  , pc0=0000000c ir=054d5000 Ra=00000004=4    Rb=000000ba Rc=00000008
391 :fetch , pc0=00000010 pc=00000014 ir=046d5000
392 :decode, pc0=00000010 pc=00000014 ir=046d5000 op=04 a=6 b=d c=5 cx12=000
431 :exec  , pc0=00000010 ir=046d5000 Ra=00000004=4    Rb=000000ba Rc=00000008
471 :fetch , pc0=00000014 pc=00000018 ir=075d4000
472 :decode, pc0=00000014 pc=00000018 ir=075d4000 op=07 a=5 b=d c=4 cx12=000
511 :exec  , pc0=00000014 ir=075d4000 Ra=00000008=8    Rb=000000ba Rc=00000004
551 :fetch , pc0=00000018 pc=0000001c ir=066d4000
552 :decode, pc0=00000018 pc=0000001c ir=066d4000 op=06 a=6 b=d c=4 cx12=000
591 :exec  , pc0=00000018 ir=066d4000 Ra=00000008=8    Rb=000000ba Rc=00000004
631 :fetch , pc0=0000001c pc=00000020 ir=30e00000
632 :decode, pc0=0000001c pc=00000020 ir=30e00000 op=30 a=e b=0 c=0 cx12=000
671 :exec  , pc0=0000001c ir=30e00000 Ra=ffffffff=-1   Rb=00000000 Rc=00000000
711 :fetch , pc0=00000020 pc=00000024 ir=12850000
712 :decode, pc0=00000020 pc=00000024 ir=12850000 op=12 a=8 b=5 c=0 cx12=000
731 :exec  , pc0=00000020 ir=12850000 Ra=00000008=8    Rb=00000008 Rc=00000000
791 :fetch , pc0=00000024 pc=00000028 ir=13854000
792 :decode, pc0=00000024 pc=00000028 ir=13854000 op=13 a=8 b=5 c=4 cx12=000
811 :exec  , pc0=00000024 ir=13854000 Ra=0000000c=12   Rb=00000008 Rc=00000004
851 :fetch , pc0=00000028 pc=0000002c ir=14854000
852 :decode, pc0=00000028 pc=0000002c ir=14854000 op=14 a=8 b=5 c=4 cx12=000
871 :exec  , pc0=00000028 ir=14854000 Ra=00000004=4    Rb=00000008 Rc=00000004
911 :fetch , pc0=0000002c pc=00000030 ir=15854000
912 :decode, pc0=0000002c pc=00000030 ir=15854000 op=15 a=8 b=5 c=4 cx12=000
931 :exec  , pc0=0000002c ir=15854000 Ra=00000020=32   Rb=00000008 Rc=00000004
971 :fetch , pc0=00000030 pc=00000034 ir=16854000
972 :decode, pc0=00000030 pc=00000034 ir=16854000 op=16 a=8 b=5 c=4 cx12=000
991 :exec  , pc0=00000030 ir=16854000 Ra=00000002=2    Rb=00000008 Rc=00000004
1031:fetch , pc0=00000034 pc=00000038 ir=18854000
1032:decode, pc0=00000034 pc=00000038 ir=18854000 op=18 a=8 b=5 c=4 cx12=000
1051:exec  , pc0=00000034 ir=18854000 Ra=00000000=0    Rb=00000008 Rc=00000004
1091:fetch , pc0=00000038 pc=0000003c ir=19854000
1092:decode, pc0=00000038 pc=0000003c ir=19854000 op=19 a=8 b=5 c=4 cx12=000
1111:exec  , pc0=00000038 ir=19854000 Ra=0000000c=12   Rb=00000008 Rc=00000004
1151:fetch , pc0=0000003c pc=00000040 ir=1a854000
1152:decode, pc0=0000003c pc=00000040 ir=1a854000 op=1a a=8 b=5 c=4 cx12=000
1171:exec  , pc0=0000003c ir=1a854000 Ra=0000000c=12   Rb=00000008 Rc=00000004
1211:fetch , pc0=00000040 pc=00000044 ir=1e850003
1212:decode, pc0=00000040 pc=00000044 ir=1e850003 op=1e a=8 b=5 c=0 cx12=003
1231:exec  , pc0=00000040 ir=1e850003 Ra=00000040=64   Rb=00000008 Rc=00000000
1271:fetch , pc0=00000044 pc=00000048 ir=1f850002
1272:decode, pc0=00000044 pc=00000048 ir=1f850002 op=1f a=8 b=5 c=0 cx12=002
1291:exec  , pc0=00000044 ir=1f850002 Ra=00000002=2    Rb=00000008 Rc=00000000
1331:fetch , pc0=00000048 pc=0000004c ir=10450000
1332:decode, pc0=00000048 pc=0000004c ir=10450000 op=10 a=4 b=5 c=0 cx12=000
1351:exec  , pc0=00000048 ir=10450000 Ra=00000004=4    Rb=00000008 Rc=00000000
1391:fetch , pc0=0000004c pc=00000050 ir=20000018
1392:decode, pc0=0000004c pc=00000050 ir=20000018 op=20 a=0 b=0 c=0 cx12=018
1411:exec  , pc0=0000004c ir=20000018 Ra=00000000=0    Rb=00000000 Rc=00000000
1451:fetch , pc0=00000050 pc=00000054 ir=23000014
1452:decode, pc0=00000050 pc=00000054 ir=23000014 op=23 a=0 b=0 c=0 cx12=014
1471:exec  , pc0=00000050 ir=23000014 Ra=00000000=0    Rb=00000000 Rc=00000000
1511:fetch , pc0=00000054 pc=00000058 ir=25000010
1512:decode, pc0=00000054 pc=00000058 ir=25000010 op=25 a=0 b=0 c=0 cx12=010
1531:exec  , pc0=00000054 ir=25000010 Ra=00000000=0    Rb=00000000 Rc=00000000
1571:fetch , pc0=00000058 pc=0000005c ir=2200000c
1572:decode, pc0=00000058 pc=0000005c ir=2200000c op=22 a=0 b=0 c=0 cx12=00c
1591:exec  , pc0=00000058 ir=2200000c Ra=00000000=0    Rb=00000000 Rc=00000000
1631:fetch , pc0=00000068 pc=0000006c ir=0810000a
1632:decode, pc0=00000068 pc=0000006c ir=0810000a op=08 a=1 b=0 c=0 cx12=00a
1731:exec  , pc0=00000068 ir=0810000a Ra=0000000a=10   Rb=00000000 Rc=00000000
1751:fetch , pc0=0000006c pc=00000070 ir=2b000008
1752:decode, pc0=0000006c pc=00000070 ir=2b000008 op=2b a=0 b=0 c=0 cx12=008
1771:exec  , pc0=0000006c ir=2b000008 Ra=00000000=0    Rb=00000000 Rc=00000000
1831:fetch , pc0=00000078 pc=0000007c ir=30e00000
1832:decode, pc0=00000078 pc=0000007c ir=30e00000 op=30 a=e b=0 c=0 cx12=000
1951:exec  , pc0=00000078 ir=30e00000 Ra=00000070=112  Rb=00000000 Rc=00000000
1971:fetch , pc0=0000007c pc=00000080 ir=12300000
1972:decode, pc0=0000007c pc=00000080 ir=12300000 op=12 a=3 b=0 c=0 cx12=000
1991:exec  , pc0=0000007c ir=12300000 Ra=00000000=0    Rb=00000000 Rc=00000000
2031:fetch , pc0=00000080 pc=00000084 ir=024f0024
2032:decode, pc0=00000080 pc=00000084 ir=024f0024 op=02 a=4 b=f c=0 cx12=024
2071:exec  , pc0=00000080 ir=024f0024 Ra=00000001=1    Rb=00000084 Rc=00000000
2111:fetch , pc0=00000084 pc=00000088 ir=08200000
2112:decode, pc0=00000084 pc=00000088 ir=08200000 op=08 a=2 b=0 c=0 cx12=000
2131:exec  , pc0=00000084 ir=08200000 Ra=00000000=0    Rb=00000000 Rc=00000000
2191:fetch , pc0=00000088 pc=0000008c ir=13223000
2192:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
2211:exec  , pc0=00000088 ir=13223000 Ra=00000000=0    Rb=00000000 Rc=00000000
2251:fetch , pc0=0000008c pc=00000090 ir=13334000
2252:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
2271:exec  , pc0=0000008c ir=13334000 Ra=00000001=1    Rb=00000000 Rc=00000001
2311:fetch , pc0=00000090 pc=00000094 ir=10310000
2312:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
2331:exec  , pc0=00000090 ir=10310000 Ra=00000001=1    Rb=0000000a Rc=00000000
2371:fetch , pc0=00000094 pc=00000098 ir=24fffff0
2372:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
2391:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
2431:fetch , pc0=00000088 pc=0000008c ir=13223000
2432:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
2531:exec  , pc0=00000088 ir=13223000 Ra=00000001=1    Rb=00000000 Rc=00000001
2551:fetch , pc0=0000008c pc=00000090 ir=13334000
2552:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
2571:exec  , pc0=0000008c ir=13334000 Ra=00000002=2    Rb=00000001 Rc=00000001
2631:fetch , pc0=00000090 pc=00000094 ir=10310000
2632:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
2651:exec  , pc0=00000090 ir=10310000 Ra=00000002=2    Rb=0000000a Rc=00000000
2691:fetch , pc0=00000094 pc=00000098 ir=24fffff0
2692:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
2711:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
2751:fetch , pc0=00000088 pc=0000008c ir=13223000
2752:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
2851:exec  , pc0=00000088 ir=13223000 Ra=00000003=3    Rb=00000001 Rc=00000002
2871:fetch , pc0=0000008c pc=00000090 ir=13334000
2872:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
2891:exec  , pc0=0000008c ir=13334000 Ra=00000003=3    Rb=00000002 Rc=00000001
2951:fetch , pc0=00000090 pc=00000094 ir=10310000
2952:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
2971:exec  , pc0=00000090 ir=10310000 Ra=00000003=3    Rb=0000000a Rc=00000000
3011:fetch , pc0=00000094 pc=00000098 ir=24fffff0
3012:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
3031:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
3071:fetch , pc0=00000088 pc=0000008c ir=13223000
3072:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
3171:exec  , pc0=00000088 ir=13223000 Ra=00000006=6    Rb=00000003 Rc=00000003
3191:fetch , pc0=0000008c pc=00000090 ir=13334000
3192:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
3211:exec  , pc0=0000008c ir=13334000 Ra=00000004=4    Rb=00000003 Rc=00000001
3271:fetch , pc0=00000090 pc=00000094 ir=10310000
3272:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
3291:exec  , pc0=00000090 ir=10310000 Ra=00000004=4    Rb=0000000a Rc=00000000
3331:fetch , pc0=00000094 pc=00000098 ir=24fffff0
3332:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
3351:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
3391:fetch , pc0=00000088 pc=0000008c ir=13223000
3392:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
3491:exec  , pc0=00000088 ir=13223000 Ra=0000000a=10   Rb=00000006 Rc=00000004
3511:fetch , pc0=0000008c pc=00000090 ir=13334000
3512:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
3531:exec  , pc0=0000008c ir=13334000 Ra=00000005=5    Rb=00000004 Rc=00000001
3591:fetch , pc0=00000090 pc=00000094 ir=10310000
3592:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
3611:exec  , pc0=00000090 ir=10310000 Ra=00000005=5    Rb=0000000a Rc=00000000
3651:fetch , pc0=00000094 pc=00000098 ir=24fffff0
3652:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
3671:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
3711:fetch , pc0=00000088 pc=0000008c ir=13223000
3712:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
3811:exec  , pc0=00000088 ir=13223000 Ra=0000000f=15   Rb=0000000a Rc=00000005
3831:fetch , pc0=0000008c pc=00000090 ir=13334000
3832:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
3851:exec  , pc0=0000008c ir=13334000 Ra=00000006=6    Rb=00000005 Rc=00000001
3911:fetch , pc0=00000090 pc=00000094 ir=10310000
3912:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
3931:exec  , pc0=00000090 ir=10310000 Ra=00000006=6    Rb=0000000a Rc=00000000
3971:fetch , pc0=00000094 pc=00000098 ir=24fffff0
3972:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
3991:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
4031:fetch , pc0=00000088 pc=0000008c ir=13223000
4032:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
4131:exec  , pc0=00000088 ir=13223000 Ra=00000015=21   Rb=0000000f Rc=00000006
4151:fetch , pc0=0000008c pc=00000090 ir=13334000
4152:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
4171:exec  , pc0=0000008c ir=13334000 Ra=00000007=7    Rb=00000006 Rc=00000001
4231:fetch , pc0=00000090 pc=00000094 ir=10310000
4232:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
4251:exec  , pc0=00000090 ir=10310000 Ra=00000007=7    Rb=0000000a Rc=00000000
4291:fetch , pc0=00000094 pc=00000098 ir=24fffff0
4292:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
4311:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
4351:fetch , pc0=00000088 pc=0000008c ir=13223000
4352:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
4451:exec  , pc0=00000088 ir=13223000 Ra=0000001c=28   Rb=00000015 Rc=00000007
4471:fetch , pc0=0000008c pc=00000090 ir=13334000
4472:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
4491:exec  , pc0=0000008c ir=13334000 Ra=00000008=8    Rb=00000007 Rc=00000001
4551:fetch , pc0=00000090 pc=00000094 ir=10310000
4552:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
4571:exec  , pc0=00000090 ir=10310000 Ra=00000008=8    Rb=0000000a Rc=00000000
4611:fetch , pc0=00000094 pc=00000098 ir=24fffff0
4612:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
4631:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
4671:fetch , pc0=00000088 pc=0000008c ir=13223000
4672:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
4771:exec  , pc0=00000088 ir=13223000 Ra=00000024=36   Rb=0000001c Rc=00000008
4791:fetch , pc0=0000008c pc=00000090 ir=13334000
4792:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
4811:exec  , pc0=0000008c ir=13334000 Ra=00000009=9    Rb=00000008 Rc=00000001
4871:fetch , pc0=00000090 pc=00000094 ir=10310000
4872:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
4891:exec  , pc0=00000090 ir=10310000 Ra=00000009=9    Rb=0000000a Rc=00000000
4931:fetch , pc0=00000094 pc=00000098 ir=24fffff0
4932:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
4951:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
4991:fetch , pc0=00000088 pc=0000008c ir=13223000
4992:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
5091:exec  , pc0=00000088 ir=13223000 Ra=0000002d=45   Rb=00000024 Rc=00000009
5111:fetch , pc0=0000008c pc=00000090 ir=13334000
5112:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
5131:exec  , pc0=0000008c ir=13334000 Ra=0000000a=10   Rb=00000009 Rc=00000001
5191:fetch , pc0=00000090 pc=00000094 ir=10310000
5192:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
5211:exec  , pc0=00000090 ir=10310000 Ra=0000000a=10   Rb=0000000a Rc=00000000
5251:fetch , pc0=00000094 pc=00000098 ir=24fffff0
5252:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
5271:exec  , pc0=00000094 ir=24fffff0 Ra=00000088=136  Rb=00000098 Rc=00000098
5311:fetch , pc0=00000088 pc=0000008c ir=13223000
5312:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000
5411:exec  , pc0=00000088 ir=13223000 Ra=00000037=55   Rb=0000002d Rc=0000000a
5431:fetch , pc0=0000008c pc=00000090 ir=13334000
5432:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000
5451:exec  , pc0=0000008c ir=13334000 Ra=0000000b=11   Rb=0000000a Rc=00000001
5511:fetch , pc0=00000090 pc=00000094 ir=10310000
5512:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000
5531:exec  , pc0=00000090 ir=10310000 Ra=0000000b=11   Rb=0000000a Rc=00000000
5571:fetch , pc0=00000094 pc=00000098 ir=24fffff0
5572:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0
5591:exec  , pc0=00000094 ir=24fffff0 Ra=00000098=152  Rb=00000098 Rc=00000098
5631:fetch , pc0=00000098 pc=0000009c ir=012f000d
5632:decode, pc0=00000098 pc=0000009c ir=012f000d op=01 a=2 b=f c=0 cx12=00d
5671:exec  , pc0=00000098 ir=012f000d Ra=00000037=55   Rb=0000009c Rc=00000000
5711:fetch , pc0=0000009c pc=000000a0 ir=033f000d
5712:decode, pc0=0000009c pc=000000a0 ir=033f000d op=03 a=3 b=f c=0 cx12=00d
5751:exec  , pc0=0000009c ir=033f000d Ra=0000000b=11   Rb=000000a0 Rc=00000000
5791:fetch , pc0=000000a0 pc=000000a4 ir=31e00000
5792:decode, pc0=000000a0 pc=000000a4 ir=31e00000 op=31 a=e b=0 c=0 cx12=000
5831:exec  , pc0=000000a0 ir=31e00000 Ra=00000070=112  Rb=00000000 Rc=00000000
5871:fetch , pc0=000000a4 pc=000000a8 ir=2c000000
5872:decode, pc0=000000a4 pc=000000a8 ir=2c000000 op=2c a=0 b=0 c=0 cx12=000
5891:exec  , pc0=000000a4 ir=2c000000 Ra=00000000=0    Rb=00000000 Rc=00000000
5951:fetch , pc0=00000070 pc=00000074 ir=31e00000
5952:decode, pc0=00000070 pc=00000074 ir=31e00000 op=31 a=e b=0 c=0 cx12=000
6071:exec  , pc0=00000070 ir=31e00000 Ra=ffffffff=-1   Rb=00000000 Rc=00000000
6091:fetch , pc0=00000074 pc=00000078 ir=2c000000
6092:decode, pc0=00000074 pc=00000078 ir=2c000000 op=2c a=0 b=0 c=0 cx12=000
RET to PC &amp;lt; 0, finished!&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 13 Jun 2012 03:34:31 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>撰寫中：版本</span></h1> <ol> <li><a href="http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p0.9.zip">cpu0p0.9.zip</a> &#8212; 混雜 = 與 &lt;= 的程式，但可以正確運作。</li> <li><a href="http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p1.0.zip">cpu0p1.0.zip</a> &#8212; 只使用 = 的程式，可以正確運作。</li> <li><a href="http://ccckmit.wdfiles.com/local--files/ve:cpu0p/cpu0p1.1.zip">cpu0p1.1.zip</a> &#8212; 只使用 &lt;= 的程式，無法正確運作，修改中。</li> </ol> <h1><span>規劃原則</span></h1> <ol> <li>指令與資料的存取必須使用兩組線路，因此有很多種可能的方法。 <ul> <li>方案一：使用兩塊記憶體： iMem 與 dMem (哈佛架構)</li> <li>方案二：使用一塊記憶體加兩個 cache：iCache 與 dCache</li> <li>方案三：使用一塊記憶體，但是該記憶體有兩組位址線與資料線，也就是有 abus1, dbus1, abus2, dbus2 等兩組線。</li> </ul> </li> <li>本程式採用方案三單一記憶體兩組線的方式。</li> </ol> <h1><span>Verilog 程式：cpu0p.v</span></h1> <div class="code"> <pre><code>// 管線狀態：IDLE 或 WAIT `define IDLE 2'b00 // 閒置中 `define WAIT_M 2'b01 // 等待回應 `define WAIT_ACK 2'b10 // 等待回應 // 寬度形態常數 `define INT32 2'b11 // 寬度 32 位元 `define INT24 2'b10 // 寬度 24 位元 `define INT16 2'b01 // 寬度 16 位元 `define BYTE 2'b00 // 寬度 8 位元 // 暫存器簡稱 `define PC cpu.R[15] // 程式計數器 `define LR cpu.R[14] // 連結暫存器 `define SP cpu.R[13] // 堆疊暫存器 `define SW cpu.R[12] // 狀態暫存器 `define IR cpu.ir // 指令暫存器 // 狀態暫存器旗標位元 `define N `SW[31] // 負號旗標 `define Z `SW[30] // 零旗標 `define C `SW[29] // 進位旗標 `define V `SW[28] // 溢位旗標 `define I `SW[7] // 硬體中斷許可 `define T `SW[6] // 軟體中斷許可 `define M `SW[0] // 模式位元 module iFetch(input clock, reset, iReady, output reg iGet, oReady, input oGet); reg [1:0] state; reg [31:0] pc, pc0; always @(posedge clock) begin if (reset) begin oReady=0; iGet=0; state=`IDLE; end else case (state) `IDLE: begin // 閒置中 #1; if (iReady) begin // 輸入資料已準備好 #1; memReadStart1(`PC, `INT32); pc0 = `PC; `PC = `PC+4; pc = `PC; iGet = 1; // 處理輸入資料 #1; state = `WAIT_ACK; // 進入等待狀態 oReady = 1; end end `WAIT_ACK:begin // 等待回應 (資料被取走) #1; if (oGet) begin // 資料被取走了 oReady = 0; // 下一筆輸出資料尚未準備好。 state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 end #1; iGet = 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module iDecode(input clock, reset, iReady, output reg iGet, oReady, input oGet); parameter name=&quot;iDecode&quot;; reg [1:0] state; reg [31:0] ir, pc, pc0; reg [7:0] op; reg [3:0] a, b, c; reg [4:0] c5; reg signed [11:0] cx12; reg signed [15:0] cx16; reg signed [23:0] cx24; reg signed [31:0] c12, c16, c24, Ra, Rb, Rc; // ipc:instruction PC always @(posedge clock) begin if (reset) begin oReady=0; iGet=0; state=`IDLE; end else case (state) `IDLE: begin // 閒置中 #1; if (iReady &amp;&amp; (!cpu.m_en1 || cpu.m_ack1)) begin // 輸入資料已準備好 memReadEnd1(ir); // IR = dbus = m[PC] pc0 = cpu.if1.pc0; pc = cpu.if1.pc; $display(&quot;%-4d:fetch , pc0=%x pc=%x ir=%x&quot;, $stime, pc0, pc, ir); iGet = 1; // 處理輸入資料 {op, a, b, c, cx12} = ir; cx24 = ir[23:0]; cx16 = ir[15:0]; c5 = ir[4:0]; c12 = cx12; // 取出 cx12 並轉為 32 位元有號數 c12 c16 = cx16; // 取出 cx16 並轉為 32 位元有號數 c16 c24 = cx24; // 取出 cx24 並轉為 32 位元有號數 c24 Ra = cpu.R[a]; Rb = cpu.R[b]; Rc = cpu.R[c]; case (op) // 載入儲存指令 cpu.LD: memReadStart2(Rb+c16, `INT32); // 載入word; LD Ra, [Rb+Cx]; Ra&lt;=[Rb+ Cx] cpu.ST: memWriteStart2(Rb+c16, Ra, `INT32); // 儲存word; ST Ra, [Rb+ Cx]; Ra=&gt;[Rb+ Cx] cpu.LDB: memReadStart2(Rb+c16, `BYTE); // 載入byte; LDB Ra, [Rb+ Cx]; Ra&lt;=(byte)[Rb+ Cx] cpu.STB: memWriteStart2(Rb+c16, Ra, `BYTE); // 儲存byte; STB Ra, [Rb+ Cx]; Ra=&gt;(byte)[Rb+ Cx] cpu.LDR: memReadStart2(Rb+Rc, `INT32); // LD的Rc版; LDR Ra, [Rb+Rc]; Ra&lt;=[Rb+ Rc] cpu.STR: memWriteStart2(Rb+Rc, Ra, `INT32); // ST的Rc版; STR Ra, [Rb+Rc]; Ra=&gt;[Rb+ Rc] cpu.LBR: memReadStart2(Rb+Rc, `BYTE); // LDB的Rc版; LBR Ra, [Rb+Rc]; Ra&lt;=(byte)[Rb+ Rc] cpu.SBR: memWriteStart2(Rb+Rc, Ra, `BYTE); // STB的Rc版; SBR Ra, [Rb+Rc]; Ra=&gt;(byte)[Rb+ Rc] // 堆疊指令 cpu.PUSH:begin `SP = `SP-4; memWriteStart2(`SP, Ra, `INT32); end // 推入 word; PUSH Ra; SP-=4;[SP]&lt;=Ra; cpu.POP: begin memReadStart2(`SP, `INT32); `SP = `SP + 4; end // 彈出 word; POP Ra; Ra=[SP];SP+=4; cpu.PUSHB:begin `SP = `SP-1; memWriteStart2(`SP, Ra, `BYTE); end // 推入 byte; PUSHB Ra; SP--;[SP]&lt;=Ra;(byte) cpu.POPB:begin memReadStart2(`SP, `BYTE); `SP = `SP+1; end // 彈出 byte; POPB Ra; Ra&lt;=[SP];SP++;(byte) endcase #1; oReady = 1; // 輸出資料已準備好 state = `WAIT_ACK; // 進入等待狀態 $display(&quot;%-4d:decode, pc0=%x pc=%x ir=%x op=%x a=%x b=%x c=%x cx12=%x&quot;, $stime, pc0, pc, ir, op, a, b, c, cx12); end #1; end `WAIT_ACK:begin // 等待回應 (資料被取走) #1; if (oGet) begin // 資料被取走了 oReady = 0; // 下一筆輸出資料尚未準備好。 state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 end #1; iGet = 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module iExec(input clock, reset, iReady, output reg iGet, oReady, input oGet); parameter name=&quot;iExec&quot;; reg [31:0] ir, pc, pc0; reg [7:0] op; reg [3:0] a, b, c; reg [4:0] c5; reg signed [31:0] c12, c16, c24, Ra, Rb, Rc; // ipc:instruction PC reg [1:0] state; reg [1:0] skip; always @(posedge clock) begin if (reset) begin oReady=0; iGet=0; state=`IDLE; skip = 0; end else case (state) `IDLE: begin // 閒置中 #1; if (iReady &amp;&amp; (!cpu.m_en2 || cpu.m_ack2)) begin // 輸入資料已準備好 if (skip &gt; 0) skip = skip-1; else begin // 處理輸入資料 pc0 = cpu.id1.pc0; pc = cpu.id1.pc; ir = cpu.id1.ir; op = cpu.id1.op; a = cpu.id1.a; b = cpu.id1.b; c = cpu.id1.c; c5 = cpu.id1.c5; c12 = cpu.id1.c12; c16 = cpu.id1.c16; c24 = cpu.id1.c24; Ra = cpu.id1.Ra; Rb = cpu.id1.Rb; Rc = cpu.id1.Rc; iGet = 1; // 準備輸出資料 case (op) cpu.LD, cpu.LDB, cpu.LDR, cpu.LBR, cpu.POP, cpu.POPB : memReadEnd2(cpu.R[a]); // 讀取記憶體完成 cpu.ST, cpu.STB, cpu.STR, cpu.SBR, cpu.PUSH, cpu.PUSHB: memWriteEnd2(); // 寫入記憶體完成 cpu.LDI: cpu.R[a] = Rb+c16; // 立即載入; LDI Ra, Rb+Cx; Ra&lt;=Rb + Cx // 運算指令 cpu.CMP: begin `N=(Ra-Rb&lt;0);`Z=(Ra-Rb==0); end // 比較; CMP Ra, Rb; SW=(Ra &gt;=&lt; Rb) cpu.MOV: regSet(a, Rb); // 移動; MOV Ra, Rb; Ra&lt;=Rb cpu.ADD: regSet(a, Rb+Rc); // 加法; ADD Ra, Rb, Rc; Ra&lt;=Rb+Rc cpu.SUB: regSet(a, Rb-Rc); // 減法; SUB Ra, Rb, Rc; Ra&lt;=Rb-Rc cpu.MUL: regSet(a, Rb*Rc); // 乘法; MUL Ra, Rb, Rc; Ra&lt;=Rb*Rc cpu.DIV: regSet(a, Rb/Rc); // 除法; DIV Ra, Rb, Rc; Ra&lt;=Rb/Rc cpu.AND: regSet(a, Rb&amp;Rc); // 位元 AND; AND Ra, Rb, Rc; Ra&lt;=Rb and Rc cpu.OR: regSet(a, Rb|Rc); // 位元 OR; OR Ra, Rb, Rc; Ra&lt;=Rb or Rc cpu.XOR: regSet(a, Rb^Rc); // 位元 XOR; XOR Ra, Rb, Rc; Ra&lt;=Rb xor Rc cpu.SHL: regSet(a, Rb&lt;&lt;c5); // 向左移位; SHL Ra, Rb, Cx; Ra&lt;=Rb &lt;&lt; Cx cpu.SHR: regSet(a, Rb&gt;&gt;c5); // 向右移位; SHR Ra, Rb, Cx; Ra&lt;=Rb &gt;&gt; Cx // 跳躍指令 cpu.JEQ: if (`Z) begin `PC=pc+c24; skip=2; end // 跳躍 (相等); JEQ Cx; if SW(=) PC PC+Cx cpu.JNE: if (!`Z) begin `PC=pc+c24; skip=2; end // 跳躍 (不相等); JNE Cx; if SW(!=) PC PC+Cx cpu.JLT: if (`N) begin `PC=pc+c24; skip=2; end // 跳躍 ( &lt; ); JLT Cx; if SW(&lt;) PC PC+Cx cpu.JGT: if (!`N&amp;&amp;!`Z) begin `PC=pc+c24; skip=2; end // 跳躍 ( &gt; ); JGT Cx; if SW(&gt;) PC PC+Cx cpu.JLE: if (`N || `Z) begin `PC=pc+c24; skip=2; end // 跳躍 ( &lt;= ); JLE Cx; if SW(&lt;=) PC PC+Cx cpu.JGE: if (!`N || `Z) begin `PC=pc+c24; skip=2; end // 跳躍 ( &gt;= ); JGE Cx; if SW(&gt;=) PC PC+Cx cpu.JMP: begin `PC = pc+c24; skip=2; end // 跳躍 (無條件); JMP Cx; PC &lt;= PC+Cx cpu.SWI: begin `LR=pc;`PC= c24; `I = 1'b1; skip=2; end // 軟中斷; SWI Cx; LR &lt;= PC; PC &lt;= Cx; INT&lt;=1 cpu.CALL:begin `LR=pc;`PC=pc + c24; skip=2; end // 跳到副程式; CALL Cx; LR&lt;=PC; PC&lt;=PC+Cx cpu.RET: begin `PC=`LR; skip=2; // 返回; RET; PC &lt;= LR if (`PC &lt; 0) begin $display(&quot;RET to PC &lt; 0, finished!&quot;); $finish; end end cpu.IRET:begin `PC=`LR;`I = 1'b0; skip=2; end // 中斷返回; IRET; PC &lt;= LR; INT&lt;=0 endcase Ra = cpu.R[a]; $display(&quot;%-4d:exec , pc0=%x ir=%x Ra=%x=%-4d Rb=%x Rc=%x&quot;, $stime, pc0, ir, Ra, Ra, Rb, Rc); end #1; oReady = 1; // 輸出資料已準備好 state = `WAIT_ACK; // 進入等待狀態 end end `WAIT_ACK:begin // 等待回應 (資料被取走) #1; if (oGet) begin // 資料被取走了 #1; oReady = 0; // 下一筆輸出資料尚未準備好。 state = `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 end #1; iGet = 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module cpu(input clock, reset, output [31:0] ir, pc, output [31:0] mar1, mdr1, inout [31:0] dbus1, output reg m_en1, m_rw1, input m_ack1, output reg [1:0] m_size1, output [31:0] mar2, mdr2, inout [31:0] dbus2, output reg m_en2, m_rw2, input m_ack2, output reg [1:0] m_size2 ); // cpu0 是由 if1, id1, ie1, iw1 四根管子 (pipe) 連接後形成的管線 // 管線相關參數 wire ifiGet, idiGet, ieiGet, iwiGet; // pipe 輸入是否準備好了 wire ifoReady, idoReady, ieoReady, iwoReady; // pipe 輸出是否準備好了 parameter iReady = 1'b1, oGet=1'b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。 // 暫存器與欄位 reg [31:0] mar1, mdr1, mar2, mdr2; reg signed [31:0] R [0:15]; // 指令編碼表 parameter [7:0] LD=8'h00,ST=8'h01,LDB=8'h02,STB=8'h03,LDR=8'h04,STR=8'h05, LBR=8'h06,SBR=8'h07,LDI=8'h08,CMP=8'h10,MOV=8'h12,ADD=8'h13,SUB=8'h14, MUL=8'h15,DIV=8'h16,AND=8'h18,OR=8'h19,XOR=8'h1A,ROL=8'h1C,ROR=8'h1D, SHL=8'h1E,SHR=8'h1F,JEQ=8'h20,JNE=8'h21,JLT=8'h22,JGT=8'h23,JLE=8'h24, JGE=8'h25,JMP=8'h26,SWI=8'h2A,CALL=8'h2B,RET=8'h2C,IRET=8'h2D, PUSH=8'h30,POP=8'h31,PUSHB=8'h32,POPB=8'h33; task memReadStart1(input [31:0] addr, input [1:0] size); begin // 讀取記憶體 Word mar1 = addr; // read(m[addr]) m_rw1 = 1; // 讀取模式：read m_en1 = 1; // 啟動讀取 m_size1 = size; end endtask task memReadEnd1(output [31:0] data); begin // 讀取記憶體完成，取得資料 mdr1 = dbus1; // 取得記憶體傳回的 dbus = m[addr] data = dbus1; // 傳回資料 m_en1 = 0; // 讀取完畢 end endtask // 寫入記憶體 -- addr:寫入位址, data:寫入資料 task memWriteStart1(input [31:0] addr, input [31:0] data, input [1:0] size); begin mar1 = addr; // write(m[addr], data) mdr1 = data; m_rw1 = 0; // 寫入模式：write m_en1 = 1; // 啟動寫入 m_size1 = size; end endtask task memWriteEnd1; begin // 寫入記憶體完成 m_en1 = 0; // 寫入完畢 end endtask task memReadStart2(input [31:0] addr, input [1:0] size); begin // 讀取記憶體 Word mar2 = addr; // read(m[addr]) m_rw2 = 1; // 讀取模式：read m_en2 = 1; // 啟動讀取 m_size2 = size; end endtask task memReadEnd2(output [31:0] data); begin // 讀取記憶體完成，取得資料 mdr2 = dbus2; // 取得記憶體傳回的 dbus = m[addr] data = dbus2; // 傳回資料 m_en2 = 0; // 讀取完畢 end endtask // 寫入記憶體 -- addr:寫入位址, data:寫入資料 task memWriteStart2(input [31:0] addr, input [31:0] data, input [1:0] size); begin mar2 = addr; // write(m[addr], data) mdr2 = data; m_rw2 = 0; // 寫入模式：write m_en2 = 1; // 啟動寫入 m_size2 = size; end endtask task memWriteEnd2; begin // 寫入記憶體完成 m_en2 = 0; // 寫入完畢 end endtask task regSet(input [3:0] i, input [31:0] data); begin if (i!=0) R[i] = data; end endtask iFetch if1(clock, reset, iReady, ifiGet, ifoReady, idiGet); // 管子： iDecode id1(clock, reset, ifoReady, idiGet, idoReady, ieiGet); // 管子： iExec ie1(clock, reset, idoReady, ieiGet, ieoReady, oGet); // 管子： always @(posedge clock) begin if (reset) begin `PC = 0; R[0] = 0; `SW = 0; `LR = -1; end end endmodule module memory(input clock, reset, en1, en2, rw1, rw2, output reg ack1, ack2, input [1:0] size1, size2, input [31:0] abus1, abus2, dbus_in1, dbus_in2, output [31:0] dbus_out1, dbus_out2); reg [7:0] m [0:258]; reg [31:0] data1, data2; integer i; initial begin $readmemh(&quot;cpu0p.hex&quot;, m); for (i=0; i &lt; 255; i=i+4) begin $display(&quot;%8x: %8x&quot;, i, {m[i], m[i+1], m[i+2], m[i+3]}); end end always @(*) begin if (en1) begin ack1 = 0; #30; if (abus1 &gt;=0 &amp;&amp; abus1 &lt;= 255) begin if (rw1 == 0) begin // r_w==0:write data1 = dbus_in1; case (size1) `BYTE: {m[abus1]} = dbus_in1[7:0]; `INT16: {m[abus1], m[abus1+1] } = dbus_in1[15:0]; `INT24: {m[abus1], m[abus1+1], m[abus1+2]} = dbus_in1[24:0]; `INT32: {m[abus1], m[abus1+1], m[abus1+2], m[abus1+3]} = dbus_in1; endcase end else begin// rw == 1:read case (size1) `BYTE: data1 = {8'h00 , 8'h00, 8'h00, m[abus1] }; `INT16: data1 = {8'h00 , 8'h00, m[abus1], m[abus1+1] }; `INT24: data1 = {8'h00 , m[abus1], m[abus1+1], m[abus1+2] }; `INT32: data1 = {m[abus1], m[abus1+1], m[abus1+2], m[abus1+3]}; endcase end end ack1 = 1; end else begin data1 = 32'hZZZZZZZZ; ack1 = 0; end end assign dbus_out1 = data1; always @(*) begin if (en2) begin ack2 = 0; #30; if (abus2 &gt;=0 &amp;&amp; abus2 &lt;= 255) begin if (rw2 == 0) begin // r_w==0:write data2 = dbus_in2; case (size2) `BYTE: {m[abus2]} = dbus_in2[7:0]; `INT16: {m[abus2], m[abus2+1] } = dbus_in2[15:0]; `INT24: {m[abus2], m[abus2+1], m[abus2+2]} = dbus_in2[24:0]; `INT32: {m[abus2], m[abus2+1], m[abus2+2], m[abus2+3]} = dbus_in2; endcase end else begin// rw == 1:read case (size2) `BYTE: data2 = {8'h00 , 8'h00, 8'h00, m[abus2] }; `INT16: data2 = {8'h00 , 8'h00, m[abus2], m[abus2+1] }; `INT24: data2 = {8'h00 , m[abus2], m[abus2+1], m[abus2+2] }; `INT32: data2 = {m[abus2], m[abus2+1], m[abus2+2], m[abus2+3]}; endcase end end ack2 = 1; end else begin data2 = 32'hZZZZZZZZ; ack2 = 0; end end assign dbus_out2 = data2; endmodule module main; reg clock, reset; wire [31:0] pc, ir; wire [31:0] mar1, mar2, mdr1, mdr2, dbus1, dbus2; wire m_en1, m_en2, m_rw1, m_rw2, m_ack1, m_ack2; wire [1:0] m_size1, m_size2; cpu cpu0(.clock(clock), .reset(reset), .pc(pc), .ir(ir), .mar1(mar1), .mdr1(mdr1), .dbus1(dbus1), .m_en1(m_en1), .m_rw1(m_rw1), .m_size1(m_size1), .m_ack1(m_ack1), .mar2(mar2), .mdr2(mdr2), .dbus2(dbus2), .m_en2(m_en2), .m_rw2(m_rw2), .m_size2(m_size2), .m_ack2(m_ack2)); memory memory0(.clock(clock), .reset(reset), .en1(m_en1), .rw1(m_rw1), .ack1(m_ack1), .size1(m_size1), .abus1(mar1), .dbus_in1(mdr1), .dbus_out1(dbus1), .en2(m_en2), .rw2(m_rw2), .ack2(m_ack2), .size2(m_size2), .abus2(mar2), .dbus_in2(mdr2), .dbus_out2(dbus2)); initial begin clock = 0; reset = 1; #50 reset = 0; #10000 $finish; end always #10 clock=clock+1; endmodule</code></pre></div> <h1><span>Icarus 模擬結果</span></h1> <div class="code"> <pre><code>D:\oc\cpu0p&gt;vvp cpu0p WARNING: cpu0p.v:312: $readmemh(cpu0p.hex): Not enough words in the file for the requested range [0:258]. 00000000: 00df00b6 00000004: 08400004 00000008: 08500008 0000000c: 054d5000 00000010: 046d5000 00000014: 075d4000 00000018: 066d4000 0000001c: 30e00000 00000020: 12850000 00000024: 13854000 00000028: 14854000 0000002c: 15854000 00000030: 16854000 00000034: 18854000 00000038: 19854000 0000003c: 1a854000 00000040: 1e850003 00000044: 1f850002 00000048: 10450000 0000004c: 20000018 00000050: 23000014 00000054: 25000010 00000058: 2200000c 0000005c: 24000008 00000060: 21000004 00000064: 26000000 00000068: 0810000a 0000006c: 2b000008 00000070: 31e00000 00000074: 2c000000 00000078: 30e00000 0000007c: 12300000 00000080: 024f0024 00000084: 08200000 00000088: 13223000 0000008c: 13334000 00000090: 10310000 00000094: 24fffff0 00000098: 012f000d 0000009c: 033f000d 000000a0: 31e00000 000000a4: 2c000000 000000a8: 01000000 000000ac: 00000001 000000b0: 02030405 000000b4: 06070809 000000b8: 0a0b0000 000000bc: 00ba0102 000000c0: 03040506 000000c4: 0708xxxx 000000c8: xxxxxxxx 000000cc: xxxxxxxx 000000d0: xxxxxxxx 000000d4: xxxxxxxx 000000d8: xxxxxxxx 000000dc: xxxxxxxx 000000e0: xxxxxxxx 000000e4: xxxxxxxx 000000e8: xxxxxxxx 000000ec: xxxxxxxx 000000f0: xxxxxxxx 000000f4: xxxxxxxx 000000f8: xxxxxxxx 000000fc: xxxxxxxx 91 :fetch , pc0=00000000 pc=00000004 ir=00df00b6 92 :decode, pc0=00000000 pc=00000004 ir=00df00b6 op=00 a=d b=f c=0 cx12=0b6 131 :exec , pc0=00000000 ir=00df00b6 Ra=000000ba=186 Rb=00000004 Rc=00000000 171 :fetch , pc0=00000004 pc=00000008 ir=08400004 172 :decode, pc0=00000004 pc=00000008 ir=08400004 op=08 a=4 b=0 c=0 cx12=004 191 :exec , pc0=00000004 ir=08400004 Ra=00000004=4 Rb=00000000 Rc=00000000 251 :fetch , pc0=00000008 pc=0000000c ir=08500008 252 :decode, pc0=00000008 pc=0000000c ir=08500008 op=08 a=5 b=0 c=0 cx12=008 271 :exec , pc0=00000008 ir=08500008 Ra=00000008=8 Rb=00000000 Rc=00000000 311 :fetch , pc0=0000000c pc=00000010 ir=054d5000 312 :decode, pc0=0000000c pc=00000010 ir=054d5000 op=05 a=4 b=d c=5 cx12=000 351 :exec , pc0=0000000c ir=054d5000 Ra=00000004=4 Rb=000000ba Rc=00000008 391 :fetch , pc0=00000010 pc=00000014 ir=046d5000 392 :decode, pc0=00000010 pc=00000014 ir=046d5000 op=04 a=6 b=d c=5 cx12=000 431 :exec , pc0=00000010 ir=046d5000 Ra=00000004=4 Rb=000000ba Rc=00000008 471 :fetch , pc0=00000014 pc=00000018 ir=075d4000 472 :decode, pc0=00000014 pc=00000018 ir=075d4000 op=07 a=5 b=d c=4 cx12=000 511 :exec , pc0=00000014 ir=075d4000 Ra=00000008=8 Rb=000000ba Rc=00000004 551 :fetch , pc0=00000018 pc=0000001c ir=066d4000 552 :decode, pc0=00000018 pc=0000001c ir=066d4000 op=06 a=6 b=d c=4 cx12=000 591 :exec , pc0=00000018 ir=066d4000 Ra=00000008=8 Rb=000000ba Rc=00000004 631 :fetch , pc0=0000001c pc=00000020 ir=30e00000 632 :decode, pc0=0000001c pc=00000020 ir=30e00000 op=30 a=e b=0 c=0 cx12=000 671 :exec , pc0=0000001c ir=30e00000 Ra=ffffffff=-1 Rb=00000000 Rc=00000000 711 :fetch , pc0=00000020 pc=00000024 ir=12850000 712 :decode, pc0=00000020 pc=00000024 ir=12850000 op=12 a=8 b=5 c=0 cx12=000 731 :exec , pc0=00000020 ir=12850000 Ra=00000008=8 Rb=00000008 Rc=00000000 791 :fetch , pc0=00000024 pc=00000028 ir=13854000 792 :decode, pc0=00000024 pc=00000028 ir=13854000 op=13 a=8 b=5 c=4 cx12=000 811 :exec , pc0=00000024 ir=13854000 Ra=0000000c=12 Rb=00000008 Rc=00000004 851 :fetch , pc0=00000028 pc=0000002c ir=14854000 852 :decode, pc0=00000028 pc=0000002c ir=14854000 op=14 a=8 b=5 c=4 cx12=000 871 :exec , pc0=00000028 ir=14854000 Ra=00000004=4 Rb=00000008 Rc=00000004 911 :fetch , pc0=0000002c pc=00000030 ir=15854000 912 :decode, pc0=0000002c pc=00000030 ir=15854000 op=15 a=8 b=5 c=4 cx12=000 931 :exec , pc0=0000002c ir=15854000 Ra=00000020=32 Rb=00000008 Rc=00000004 971 :fetch , pc0=00000030 pc=00000034 ir=16854000 972 :decode, pc0=00000030 pc=00000034 ir=16854000 op=16 a=8 b=5 c=4 cx12=000 991 :exec , pc0=00000030 ir=16854000 Ra=00000002=2 Rb=00000008 Rc=00000004 1031:fetch , pc0=00000034 pc=00000038 ir=18854000 1032:decode, pc0=00000034 pc=00000038 ir=18854000 op=18 a=8 b=5 c=4 cx12=000 1051:exec , pc0=00000034 ir=18854000 Ra=00000000=0 Rb=00000008 Rc=00000004 1091:fetch , pc0=00000038 pc=0000003c ir=19854000 1092:decode, pc0=00000038 pc=0000003c ir=19854000 op=19 a=8 b=5 c=4 cx12=000 1111:exec , pc0=00000038 ir=19854000 Ra=0000000c=12 Rb=00000008 Rc=00000004 1151:fetch , pc0=0000003c pc=00000040 ir=1a854000 1152:decode, pc0=0000003c pc=00000040 ir=1a854000 op=1a a=8 b=5 c=4 cx12=000 1171:exec , pc0=0000003c ir=1a854000 Ra=0000000c=12 Rb=00000008 Rc=00000004 1211:fetch , pc0=00000040 pc=00000044 ir=1e850003 1212:decode, pc0=00000040 pc=00000044 ir=1e850003 op=1e a=8 b=5 c=0 cx12=003 1231:exec , pc0=00000040 ir=1e850003 Ra=00000040=64 Rb=00000008 Rc=00000000 1271:fetch , pc0=00000044 pc=00000048 ir=1f850002 1272:decode, pc0=00000044 pc=00000048 ir=1f850002 op=1f a=8 b=5 c=0 cx12=002 1291:exec , pc0=00000044 ir=1f850002 Ra=00000002=2 Rb=00000008 Rc=00000000 1331:fetch , pc0=00000048 pc=0000004c ir=10450000 1332:decode, pc0=00000048 pc=0000004c ir=10450000 op=10 a=4 b=5 c=0 cx12=000 1351:exec , pc0=00000048 ir=10450000 Ra=00000004=4 Rb=00000008 Rc=00000000 1391:fetch , pc0=0000004c pc=00000050 ir=20000018 1392:decode, pc0=0000004c pc=00000050 ir=20000018 op=20 a=0 b=0 c=0 cx12=018 1411:exec , pc0=0000004c ir=20000018 Ra=00000000=0 Rb=00000000 Rc=00000000 1451:fetch , pc0=00000050 pc=00000054 ir=23000014 1452:decode, pc0=00000050 pc=00000054 ir=23000014 op=23 a=0 b=0 c=0 cx12=014 1471:exec , pc0=00000050 ir=23000014 Ra=00000000=0 Rb=00000000 Rc=00000000 1511:fetch , pc0=00000054 pc=00000058 ir=25000010 1512:decode, pc0=00000054 pc=00000058 ir=25000010 op=25 a=0 b=0 c=0 cx12=010 1531:exec , pc0=00000054 ir=25000010 Ra=00000000=0 Rb=00000000 Rc=00000000 1571:fetch , pc0=00000058 pc=0000005c ir=2200000c 1572:decode, pc0=00000058 pc=0000005c ir=2200000c op=22 a=0 b=0 c=0 cx12=00c 1591:exec , pc0=00000058 ir=2200000c Ra=00000000=0 Rb=00000000 Rc=00000000 1631:fetch , pc0=00000068 pc=0000006c ir=0810000a 1632:decode, pc0=00000068 pc=0000006c ir=0810000a op=08 a=1 b=0 c=0 cx12=00a 1731:exec , pc0=00000068 ir=0810000a Ra=0000000a=10 Rb=00000000 Rc=00000000 1751:fetch , pc0=0000006c pc=00000070 ir=2b000008 1752:decode, pc0=0000006c pc=00000070 ir=2b000008 op=2b a=0 b=0 c=0 cx12=008 1771:exec , pc0=0000006c ir=2b000008 Ra=00000000=0 Rb=00000000 Rc=00000000 1831:fetch , pc0=00000078 pc=0000007c ir=30e00000 1832:decode, pc0=00000078 pc=0000007c ir=30e00000 op=30 a=e b=0 c=0 cx12=000 1951:exec , pc0=00000078 ir=30e00000 Ra=00000070=112 Rb=00000000 Rc=00000000 1971:fetch , pc0=0000007c pc=00000080 ir=12300000 1972:decode, pc0=0000007c pc=00000080 ir=12300000 op=12 a=3 b=0 c=0 cx12=000 1991:exec , pc0=0000007c ir=12300000 Ra=00000000=0 Rb=00000000 Rc=00000000 2031:fetch , pc0=00000080 pc=00000084 ir=024f0024 2032:decode, pc0=00000080 pc=00000084 ir=024f0024 op=02 a=4 b=f c=0 cx12=024 2071:exec , pc0=00000080 ir=024f0024 Ra=00000001=1 Rb=00000084 Rc=00000000 2111:fetch , pc0=00000084 pc=00000088 ir=08200000 2112:decode, pc0=00000084 pc=00000088 ir=08200000 op=08 a=2 b=0 c=0 cx12=000 2131:exec , pc0=00000084 ir=08200000 Ra=00000000=0 Rb=00000000 Rc=00000000 2191:fetch , pc0=00000088 pc=0000008c ir=13223000 2192:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 2211:exec , pc0=00000088 ir=13223000 Ra=00000000=0 Rb=00000000 Rc=00000000 2251:fetch , pc0=0000008c pc=00000090 ir=13334000 2252:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 2271:exec , pc0=0000008c ir=13334000 Ra=00000001=1 Rb=00000000 Rc=00000001 2311:fetch , pc0=00000090 pc=00000094 ir=10310000 2312:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 2331:exec , pc0=00000090 ir=10310000 Ra=00000001=1 Rb=0000000a Rc=00000000 2371:fetch , pc0=00000094 pc=00000098 ir=24fffff0 2372:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 2391:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 2431:fetch , pc0=00000088 pc=0000008c ir=13223000 2432:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 2531:exec , pc0=00000088 ir=13223000 Ra=00000001=1 Rb=00000000 Rc=00000001 2551:fetch , pc0=0000008c pc=00000090 ir=13334000 2552:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 2571:exec , pc0=0000008c ir=13334000 Ra=00000002=2 Rb=00000001 Rc=00000001 2631:fetch , pc0=00000090 pc=00000094 ir=10310000 2632:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 2651:exec , pc0=00000090 ir=10310000 Ra=00000002=2 Rb=0000000a Rc=00000000 2691:fetch , pc0=00000094 pc=00000098 ir=24fffff0 2692:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 2711:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 2751:fetch , pc0=00000088 pc=0000008c ir=13223000 2752:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 2851:exec , pc0=00000088 ir=13223000 Ra=00000003=3 Rb=00000001 Rc=00000002 2871:fetch , pc0=0000008c pc=00000090 ir=13334000 2872:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 2891:exec , pc0=0000008c ir=13334000 Ra=00000003=3 Rb=00000002 Rc=00000001 2951:fetch , pc0=00000090 pc=00000094 ir=10310000 2952:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 2971:exec , pc0=00000090 ir=10310000 Ra=00000003=3 Rb=0000000a Rc=00000000 3011:fetch , pc0=00000094 pc=00000098 ir=24fffff0 3012:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 3031:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 3071:fetch , pc0=00000088 pc=0000008c ir=13223000 3072:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 3171:exec , pc0=00000088 ir=13223000 Ra=00000006=6 Rb=00000003 Rc=00000003 3191:fetch , pc0=0000008c pc=00000090 ir=13334000 3192:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 3211:exec , pc0=0000008c ir=13334000 Ra=00000004=4 Rb=00000003 Rc=00000001 3271:fetch , pc0=00000090 pc=00000094 ir=10310000 3272:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 3291:exec , pc0=00000090 ir=10310000 Ra=00000004=4 Rb=0000000a Rc=00000000 3331:fetch , pc0=00000094 pc=00000098 ir=24fffff0 3332:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 3351:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 3391:fetch , pc0=00000088 pc=0000008c ir=13223000 3392:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 3491:exec , pc0=00000088 ir=13223000 Ra=0000000a=10 Rb=00000006 Rc=00000004 3511:fetch , pc0=0000008c pc=00000090 ir=13334000 3512:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 3531:exec , pc0=0000008c ir=13334000 Ra=00000005=5 Rb=00000004 Rc=00000001 3591:fetch , pc0=00000090 pc=00000094 ir=10310000 3592:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 3611:exec , pc0=00000090 ir=10310000 Ra=00000005=5 Rb=0000000a Rc=00000000 3651:fetch , pc0=00000094 pc=00000098 ir=24fffff0 3652:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 3671:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 3711:fetch , pc0=00000088 pc=0000008c ir=13223000 3712:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 3811:exec , pc0=00000088 ir=13223000 Ra=0000000f=15 Rb=0000000a Rc=00000005 3831:fetch , pc0=0000008c pc=00000090 ir=13334000 3832:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 3851:exec , pc0=0000008c ir=13334000 Ra=00000006=6 Rb=00000005 Rc=00000001 3911:fetch , pc0=00000090 pc=00000094 ir=10310000 3912:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 3931:exec , pc0=00000090 ir=10310000 Ra=00000006=6 Rb=0000000a Rc=00000000 3971:fetch , pc0=00000094 pc=00000098 ir=24fffff0 3972:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 3991:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 4031:fetch , pc0=00000088 pc=0000008c ir=13223000 4032:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 4131:exec , pc0=00000088 ir=13223000 Ra=00000015=21 Rb=0000000f Rc=00000006 4151:fetch , pc0=0000008c pc=00000090 ir=13334000 4152:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 4171:exec , pc0=0000008c ir=13334000 Ra=00000007=7 Rb=00000006 Rc=00000001 4231:fetch , pc0=00000090 pc=00000094 ir=10310000 4232:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 4251:exec , pc0=00000090 ir=10310000 Ra=00000007=7 Rb=0000000a Rc=00000000 4291:fetch , pc0=00000094 pc=00000098 ir=24fffff0 4292:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 4311:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 4351:fetch , pc0=00000088 pc=0000008c ir=13223000 4352:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 4451:exec , pc0=00000088 ir=13223000 Ra=0000001c=28 Rb=00000015 Rc=00000007 4471:fetch , pc0=0000008c pc=00000090 ir=13334000 4472:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 4491:exec , pc0=0000008c ir=13334000 Ra=00000008=8 Rb=00000007 Rc=00000001 4551:fetch , pc0=00000090 pc=00000094 ir=10310000 4552:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 4571:exec , pc0=00000090 ir=10310000 Ra=00000008=8 Rb=0000000a Rc=00000000 4611:fetch , pc0=00000094 pc=00000098 ir=24fffff0 4612:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 4631:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 4671:fetch , pc0=00000088 pc=0000008c ir=13223000 4672:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 4771:exec , pc0=00000088 ir=13223000 Ra=00000024=36 Rb=0000001c Rc=00000008 4791:fetch , pc0=0000008c pc=00000090 ir=13334000 4792:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 4811:exec , pc0=0000008c ir=13334000 Ra=00000009=9 Rb=00000008 Rc=00000001 4871:fetch , pc0=00000090 pc=00000094 ir=10310000 4872:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 4891:exec , pc0=00000090 ir=10310000 Ra=00000009=9 Rb=0000000a Rc=00000000 4931:fetch , pc0=00000094 pc=00000098 ir=24fffff0 4932:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 4951:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 4991:fetch , pc0=00000088 pc=0000008c ir=13223000 4992:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 5091:exec , pc0=00000088 ir=13223000 Ra=0000002d=45 Rb=00000024 Rc=00000009 5111:fetch , pc0=0000008c pc=00000090 ir=13334000 5112:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 5131:exec , pc0=0000008c ir=13334000 Ra=0000000a=10 Rb=00000009 Rc=00000001 5191:fetch , pc0=00000090 pc=00000094 ir=10310000 5192:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 5211:exec , pc0=00000090 ir=10310000 Ra=0000000a=10 Rb=0000000a Rc=00000000 5251:fetch , pc0=00000094 pc=00000098 ir=24fffff0 5252:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 5271:exec , pc0=00000094 ir=24fffff0 Ra=00000088=136 Rb=00000098 Rc=00000098 5311:fetch , pc0=00000088 pc=0000008c ir=13223000 5312:decode, pc0=00000088 pc=0000008c ir=13223000 op=13 a=2 b=2 c=3 cx12=000 5411:exec , pc0=00000088 ir=13223000 Ra=00000037=55 Rb=0000002d Rc=0000000a 5431:fetch , pc0=0000008c pc=00000090 ir=13334000 5432:decode, pc0=0000008c pc=00000090 ir=13334000 op=13 a=3 b=3 c=4 cx12=000 5451:exec , pc0=0000008c ir=13334000 Ra=0000000b=11 Rb=0000000a Rc=00000001 5511:fetch , pc0=00000090 pc=00000094 ir=10310000 5512:decode, pc0=00000090 pc=00000094 ir=10310000 op=10 a=3 b=1 c=0 cx12=000 5531:exec , pc0=00000090 ir=10310000 Ra=0000000b=11 Rb=0000000a Rc=00000000 5571:fetch , pc0=00000094 pc=00000098 ir=24fffff0 5572:decode, pc0=00000094 pc=00000098 ir=24fffff0 op=24 a=f b=f c=f cx12=ff0 5591:exec , pc0=00000094 ir=24fffff0 Ra=00000098=152 Rb=00000098 Rc=00000098 5631:fetch , pc0=00000098 pc=0000009c ir=012f000d 5632:decode, pc0=00000098 pc=0000009c ir=012f000d op=01 a=2 b=f c=0 cx12=00d 5671:exec , pc0=00000098 ir=012f000d Ra=00000037=55 Rb=0000009c Rc=00000000 5711:fetch , pc0=0000009c pc=000000a0 ir=033f000d 5712:decode, pc0=0000009c pc=000000a0 ir=033f000d op=03 a=3 b=f c=0 cx12=00d 5751:exec , pc0=0000009c ir=033f000d Ra=0000000b=11 Rb=000000a0 Rc=00000000 5791:fetch , pc0=000000a0 pc=000000a4 ir=31e00000 5792:decode, pc0=000000a0 pc=000000a4 ir=31e00000 op=31 a=e b=0 c=0 cx12=000 5831:exec , pc0=000000a0 ir=31e00000 Ra=00000070=112 Rb=00000000 Rc=00000000 5871:fetch , pc0=000000a4 pc=000000a8 ir=2c000000 5872:decode, pc0=000000a4 pc=000000a8 ir=2c000000 op=2c a=0 b=0 c=0 cx12=000 5891:exec , pc0=000000a4 ir=2c000000 Ra=00000000=0 Rb=00000000 Rc=00000000 5951:fetch , pc0=00000070 pc=00000074 ir=31e00000 5952:decode, pc0=00000070 pc=00000074 ir=31e00000 op=31 a=e b=0 c=0 cx12=000 6071:exec , pc0=00000070 ir=31e00000 Ra=ffffffff=-1 Rb=00000000 Rc=00000000 6091:fetch , pc0=00000074 pc=00000078 ir=2c000000 6092:decode, pc0=00000074 pc=00000078 ir=2c000000 op=2c a=0 b=0 c=0 cx12=000 RET to PC &lt; 0, finished!</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:assignment</guid>
				<title>指定 -- 平行與循序</title>
				<link>http://ccckmit.wikidot.com/ve:assignment</link>
				<description>

&lt;h1&gt;&lt;span&gt;結論&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 18 Jun 2012 09:08:07 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>結論</span></h1> <ul> <li>Combinational Logic : <ul> <li>No delays : Use blocking assignment (a=b; )</li> <li>Inertial delay : Use delay evaluation blocking assignments (#5 a=b;)</li> <li>Transport delays : Use delayed assignment non-blocking assignments (a &lt;= #5&#160;b; )</li> </ul> </li> </ul> <ol> <li>Sequential Logic : <ul> <li>No delays : Use non-blockig assignments (q&lt;=d)</li> <li>With delays : Use delayed assignment non-blocking assignments (q&lt;= #5 d;)</li> </ul> </li> </ol> <h1><span>範例：DelayedEval.v</span></h1> <div class="code"> <pre><code>module main; reg [7:0] A, B; initial begin #5 A=1; #5 A=A+1; B=A+1; $display(&quot;A=%d B=%d&quot;, A, B); end endmodule</code></pre></div> <p>執行結果</p> <div class="code"> <pre><code>D:\oc\assignment&gt;iverilog delayedEval.v -o delayedEval D:\oc\assignment&gt;vvp delayedEval A= 2 B= 3</code></pre></div> <h1><span>參考文獻</span></h1> <ol> <li>Understanding Verilog Blocking and Nonblocking Assignment (超經典，一定要看！) <ul> <li><a href="http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf">http://www.sutherland-hdl.com/papers/1996-CUG-presentation_nonblocking_assigns.pdf</a></li> </ul> </li> </ol> <p>摘錄：</p> <div class="code"> <pre><code>Time 0: ➤ Q1 — (in any order) : ➤ Evaluate RHS of all non-blocking assignments ➤ Evaluate RHS and change LHS of all blocking assignments ➤ Evaluate RHS and change LHS of all continuous assignments ➤ Evaluate inputs and change outputs of all primitives ➤ Evaluate and print output from $display and $write ➤ Q2 — (in any order) : ➤ Change LHS of all non-blocking assignments ➤ Q3 — (in any order) : ➤ Evaluate and print output from $monitor and $strobe ➤ Call PLI with reason_synchronize ➤ Q4 : ➤ Call PLI with reason_rosynchronize ... Rules of Thumb for Procedural Assignments</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline5</guid>
				<title>Pipeline5</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline5</link>
				<description>

&lt;h1&gt;&lt;span&gt;Verilog 程式：pipeline.v&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 17 Jun 2012 03:25:16 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Verilog 程式：pipeline.v</span></h1> <div class="code"> <pre><code>`define IDLE 1'b0 // 閒置中 `define WAIT 2'b1 // 等待回應 // pipe : 單一根管子 (iReady, iMsg, iGet) 為輸入部分，(oReady, oMsg, oGet) 為輸出部分, id 為管線代號 module pipe(input clock, reset, iReady, input [7:0] iMsg, output iGet, output oReady, output [7:0] oMsg, input oGet, input [3:0] id); reg oReady, iGet, state; reg [7:0] iMsgReg, oMsg; task taskPipe(input reset, inout state, input iReady, input [7:0] iMsg, inout [7:0] iMsgReg, output iGet, oReady, output [7:0] oMsg, input oGet); if (reset) begin oReady=0; iGet=0; state=`IDLE; end else case (state) `IDLE: begin // 閒置中 if (iReady) begin // 輸入資料已準備好 iMsgReg &lt;= iMsg; // 儲存輸入資料 iGet &lt;= 1; state &lt;= `WAIT; // 進入等帶狀態 $display(&quot;%-8d:p%x iMsg=%d, iGet&quot;, $stime, id, iMsg); #1 oMsg &lt;= iMsg + 1; // 設定輸出資料 #2; $display(&quot;%-8d:p%x oMsg=%d, oReady&quot;, $stime, id, oMsg); oReady &lt;= 1; // 這裏有修改 ***** end else $display(&quot;%-8d:p%x IDLE, not iReady&quot;, $stime, id); end `WAIT:begin // 等待回應 (資料被取走) if (oGet) begin // 資料被取走了 oReady &lt;= 0; // 下一筆輸出資料尚未準備好。 state &lt;= `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 #2; $display(&quot;%-8d:p%x oGet&quot;, $stime, id); // 顯示資料已經取走 end else begin oReady &lt;= 1; // 這裏有修改 ***** $display(&quot;%-8d:p%x WAIT, oReady, not oGet&quot;, $stime, id); end iGet &lt;= 0; // 下一筆輸入資料尚未準備好。 end endcase endtask always @(posedge clock) begin taskPipe(reset, state, iReady, iMsg, iMsgReg, iGet, oReady, oMsg, oGet); end endmodule module pipeline; // pipeline : 多根管子連接後形成的管線 reg clock, reset; // 時脈 wire [7:0] p1Msg, p2Msg, p3Msg; // pipe 傳遞的訊息 wire p1iGet, p2iGet, p3iGet; // pipe 輸入是否準備好了 wire p1oReady, p2oReady, p3oReady; // pipe 輸出是否準備好了 reg [7:0] iMsg=0; // pipeline 的整體輸入訊息 parameter iReady = 1'b1, oGet=1'b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。 pipe p1(clock, reset, iReady, iMsg, p1iGet, p1oReady, p1Msg, p2iGet,1); // 第一根管子 pipe p2(clock, reset, p1oReady, p1Msg, p2iGet, p2oReady, p2Msg, p3iGet,2); // 第二根管子 pipe p3(clock, reset, p2oReady, p2Msg, p3iGet, p3oReady, p3Msg, oGet, 3); // 第三根管子 initial begin reset = 1; clock = 0; #100 reset = 0; #100 iMsg = 10; // pipelie 的輸入資料改為 10 #100 iMsg = 20; // pipelie 的輸入資料改為 20 #200 $finish; end always #10 begin clock=clock+1; end endmodule</code></pre></div> <h1><span>Icarus 模擬結果</span></h1> <div class="code"> <pre><code>D:\oc\pipe&gt;iverilog pipeline.v -o pipeline D:\oc\pipe&gt;vvp pipeline 110 :p1 iMsg= 0, iGet 110 :p2 IDLE, not iReady 110 :p3 IDLE, not iReady 113 :p1 oMsg= 1, oReady 130 :p2 IDLE, not iReady 130 :p3 IDLE, not iReady 130 :p1 WAIT, oReady, not oGet 150 :p2 iMsg= 1, iGet 150 :p3 IDLE, not iReady 150 :p1 WAIT, oReady, not oGet 153 :p2 oMsg= 2, oReady 170 :p3 IDLE, not iReady 170 :p2 WAIT, oReady, not oGet 172 :p1 oGet 190 :p3 iMsg= 2, iGet 190 :p2 WAIT, oReady, not oGet 190 :p1 iMsg= 0, iGet 193 :p3 oMsg= 3, oReady 193 :p1 oMsg= 1, oReady 210 :p1 WAIT, oReady, not oGet 212 :p2 oGet 212 :p3 oGet 230 :p1 WAIT, oReady, not oGet 230 :p2 iMsg= 1, iGet 230 :p3 IDLE, not iReady 233 :p2 oMsg= 2, oReady 250 :p3 IDLE, not iReady 250 :p2 WAIT, oReady, not oGet 252 :p1 oGet 270 :p3 iMsg= 2, iGet 270 :p2 WAIT, oReady, not oGet 270 :p1 iMsg= 10, iGet 273 :p3 oMsg= 3, oReady 273 :p1 oMsg= 11, oReady 290 :p1 WAIT, oReady, not oGet 292 :p2 oGet 292 :p3 oGet 310 :p1 WAIT, oReady, not oGet 310 :p2 iMsg= 11, iGet 310 :p3 IDLE, not iReady 313 :p2 oMsg= 12, oReady 330 :p3 IDLE, not iReady 330 :p2 WAIT, oReady, not oGet 332 :p1 oGet 350 :p3 iMsg= 12, iGet 350 :p2 WAIT, oReady, not oGet 350 :p1 iMsg= 20, iGet 353 :p3 oMsg= 13, oReady 353 :p1 oMsg= 21, oReady 370 :p1 WAIT, oReady, not oGet 372 :p2 oGet 372 :p3 oGet 390 :p1 WAIT, oReady, not oGet 390 :p2 iMsg= 21, iGet 390 :p3 IDLE, not iReady 393 :p2 oMsg= 22, oReady 410 :p3 IDLE, not iReady 410 :p2 WAIT, oReady, not oGet 412 :p1 oGet 430 :p3 iMsg= 22, iGet 430 :p2 WAIT, oReady, not oGet 430 :p1 iMsg= 20, iGet 433 :p3 oMsg= 23, oReady 433 :p1 oMsg= 21, oReady 450 :p1 WAIT, oReady, not oGet 452 :p2 oGet 452 :p3 oGet 470 :p1 WAIT, oReady, not oGet 470 :p2 iMsg= 21, iGet 470 :p3 IDLE, not iReady 473 :p2 oMsg= 22, oReady 490 :p3 IDLE, not iReady 490 :p2 WAIT, oReady, not oGet 492 :p1 oGet</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline</guid>
				<title>Pipeline 管線</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline</link>
				<description>

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:pipeline4&quot;&gt;pipeline4&lt;/a&gt; &amp;#8212; 展示如何設計 pipeline 的原理。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:harvard&quot;&gt;harvard&lt;/a&gt; &amp;#8212; Pipeline 與哈佛架構。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:cpu0p&quot;&gt;cpu0p&lt;/a&gt; &amp;#8212; CPU0 的 Pipeline 版本，構思中，此頁顯示了蒐集的相關資料。&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;&lt;span&gt;參考文獻&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Instruction_pipeline&quot;&gt;http://en.wikipedia.org/wiki/Instruction_pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;(原創) 如何用管線(Pipeline)實作無號數乘加運算? (IC Design) (Verilog) (讚！)&lt;/li&gt;
&lt;li&gt;加法器的流水线设计Verilog源码(pipeline)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://hi.baidu.com/ibmnothing/blog/item/154734371845c4daa2cc2b26.html&quot;&gt;http://hi.baidu.com/ibmnothing/blog/item/154734371845c4daa2cc2b26.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Google 工程師寫的一個微小管線型 CPU &amp;#8212; &lt;a href=&quot;https://github.com/fallen/tinycpu&quot;&gt;https://github.com/fallen/tinycpu&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example&quot;&gt;http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;questions on verilog pipeline. is the example below acts as a pipeline adder ?
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.edaboard.com/thread138486.html&quot;&gt;http://www.edaboard.com/thread138486.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 11 Jun 2012 07:17:03 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ol> <li><a href="http://ccckmit.wikidot.com/ve:pipeline4">pipeline4</a> &#8212; 展示如何設計 pipeline 的原理。</li> <li><a href="http://ccckmit.wikidot.com/ve:harvard">harvard</a> &#8212; Pipeline 與哈佛架構。</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0p">cpu0p</a> &#8212; CPU0 的 Pipeline 版本，構思中，此頁顯示了蒐集的相關資料。</li> </ol> <h1><span>參考文獻</span></h1> <ol> <li><a href="http://en.wikipedia.org/wiki/Instruction_pipeline">http://en.wikipedia.org/wiki/Instruction_pipeline</a></li> <li>(原創) 如何用管線(Pipeline)實作無號數乘加運算? (IC Design) (Verilog) (讚！)</li> <li>加法器的流水线设计Verilog源码(pipeline) <ul> <li><a href="http://hi.baidu.com/ibmnothing/blog/item/154734371845c4daa2cc2b26.html">http://hi.baidu.com/ibmnothing/blog/item/154734371845c4daa2cc2b26.html</a></li> </ul> </li> <li>Google 工程師寫的一個微小管線型 CPU &#8212; <a href="https://github.com/fallen/tinycpu">https://github.com/fallen/tinycpu</a> <ul> <li><a href="http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example">http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example</a></li> </ul> </li> <li>questions on verilog pipeline. is the example below acts as a pipeline adder ? <ul> <li><a href="http://www.edaboard.com/thread138486.html">http://www.edaboard.com/thread138486.html</a></li> </ul> </li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline4</guid>
				<title>Pipeline 管線的運作原理</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline4</link>
				<description>

&lt;h1&gt;&lt;span&gt;Verilog 程式：pipeline.v&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 17 Jun 2012 02:54:42 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Verilog 程式：pipeline.v</span></h1> <div class="code"> <pre><code>`define IDLE 1'b0 // 閒置中 `define WAIT 2'b1 // 等待回應 // pipe : 單一根管子 (iReady, iMsg, iGet) 為輸入部分，(oReady, oMsg, oGet) 為輸出部分, id 為管線代號 module pipe(input clock, reset, iReady, input [7:0] iMsg, output iGet, output oReady, output [7:0] oMsg, input oGet, input [3:0] id); reg oReady, iGet, state; reg [7:0] iMsgReg, oMsg; always @(posedge clock) begin if (reset) begin oReady=0; iGet=0; state=`IDLE; end else case (state) `IDLE: begin // 閒置中 if (iReady) begin // 輸入資料已準備好 iMsgReg &lt;= iMsg; // 儲存輸入資料 iGet &lt;= 1; state &lt;= `WAIT; // 進入等帶狀態 $display(&quot;%-8d:p%x iMsg=%d, iGet&quot;, $stime, id, iMsg); #1 oMsg &lt;= iMsg + 1; // 設定輸出資料 #2; $display(&quot;%-8d:p%x oMsg=%d, oReady&quot;, $stime, id, oMsg); end else $display(&quot;%-8d:p%x IDLE, not iReady&quot;, $stime, id); end `WAIT:begin // 等待回應 (資料被取走) if (oGet) begin // 資料被取走了 oReady &lt;= 0; // 下一筆輸出資料尚未準備好。 state &lt;= `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 #2; $display(&quot;%-8d:p%x oGet&quot;, $stime, id); // 顯示資料已經取走 end else begin oReady &lt;= 1; // 這裏有修改 ***** $display(&quot;%-8d:p%x WAIT, oReady, not oGet&quot;, $stime, id); end iGet &lt;= 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module pipeline; // pipeline : 多根管子連接後形成的管線 reg clock, reset; // 時脈 wire [7:0] p1Msg, p2Msg, p3Msg; // pipe 傳遞的訊息 wire p1iGet, p2iGet, p3iGet; // pipe 輸入是否準備好了 wire p1oReady, p2oReady, p3oReady; // pipe 輸出是否準備好了 reg [7:0] iMsg=0; // pipeline 的整體輸入訊息 parameter iReady = 1'b1, oGet=1'b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。 pipe p1(clock, reset, iReady, iMsg, p1iGet, p1oReady, p1Msg, p2iGet,1); // 第一根管子 pipe p2(clock, reset, p1oReady, p1Msg, p2iGet, p2oReady, p2Msg, p3iGet,2); // 第二根管子 pipe p3(clock, reset, p2oReady, p2Msg, p3iGet, p3oReady, p3Msg, oGet, 3); // 第三根管子 initial begin reset = 1; clock = 0; #100 reset = 0; #100 iMsg = 10; // pipelie 的輸入資料改為 10 #100 iMsg = 20; // pipelie 的輸入資料改為 20 #200 $finish; end always #10 begin clock=clock+1; end endmodule</code></pre></div> <h1><span>Icarus 模擬結果</span></h1> <div class="code"> <pre><code>D:\oc\pipe&gt;iverilog pipeline.v -o pipeline D:\oc\pipe&gt;vvp pipeline 110 :p1 iMsg= 0, iGet 110 :p2 IDLE, not iReady 110 :p3 IDLE, not iReady 113 :p1 oMsg= 1, oReady 130 :p1 WAIT, oReady, not oGet 130 :p3 IDLE, not iReady 130 :p2 IDLE, not iReady 150 :p2 iMsg= 1, iGet 150 :p3 IDLE, not iReady 150 :p1 WAIT, oReady, not oGet 153 :p2 oMsg= 2, oReady 170 :p2 WAIT, oReady, not oGet 170 :p3 IDLE, not iReady 172 :p1 oGet 190 :p1 iMsg= 0, iGet 190 :p3 iMsg= 2, iGet 190 :p2 WAIT, oReady, not oGet 193 :p1 oMsg= 1, oReady 193 :p3 oMsg= 3, oReady 210 :p1 WAIT, oReady, not oGet 212 :p3 oGet 212 :p2 oGet 230 :p2 iMsg= 1, iGet 230 :p3 IDLE, not iReady 230 :p1 WAIT, oReady, not oGet 233 :p2 oMsg= 2, oReady 250 :p2 WAIT, oReady, not oGet 250 :p3 IDLE, not iReady 252 :p1 oGet 270 :p1 iMsg= 10, iGet 270 :p3 iMsg= 2, iGet 270 :p2 WAIT, oReady, not oGet 273 :p1 oMsg= 11, oReady 273 :p3 oMsg= 3, oReady 290 :p1 WAIT, oReady, not oGet 292 :p3 oGet 292 :p2 oGet 310 :p2 iMsg= 11, iGet 310 :p3 IDLE, not iReady 310 :p1 WAIT, oReady, not oGet 313 :p2 oMsg= 12, oReady 330 :p2 WAIT, oReady, not oGet 330 :p3 IDLE, not iReady 332 :p1 oGet 350 :p1 iMsg= 20, iGet 350 :p3 iMsg= 12, iGet 350 :p2 WAIT, oReady, not oGet 353 :p1 oMsg= 21, oReady 353 :p3 oMsg= 13, oReady 370 :p1 WAIT, oReady, not oGet 372 :p3 oGet 372 :p2 oGet 390 :p2 iMsg= 21, iGet 390 :p3 IDLE, not iReady 390 :p1 WAIT, oReady, not oGet 393 :p2 oMsg= 22, oReady 410 :p2 WAIT, oReady, not oGet 410 :p3 IDLE, not iReady 412 :p1 oGet 430 :p1 iMsg= 20, iGet 430 :p3 iMsg= 22, iGet 430 :p2 WAIT, oReady, not oGet 433 :p1 oMsg= 21, oReady 433 :p3 oMsg= 23, oReady 450 :p1 WAIT, oReady, not oGet 452 :p3 oGet 452 :p2 oGet 470 :p2 iMsg= 21, iGet 470 :p3 IDLE, not iReady 470 :p1 WAIT, oReady, not oGet 473 :p2 oMsg= 22, oReady 490 :p2 WAIT, oReady, not oGet 490 :p3 IDLE, not iReady 492 :p1 oGet</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline3</guid>
				<title>Pipeline3 管線設計範例</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline3</link>
				<description>

&lt;h1&gt;&lt;span&gt;Verilog 程式：pipeline3.v&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;`define IDLE 1&#039;b0     // 閒置中
`define WAIT 2&#039;b1     // 等待回應

// pipe : 單一根管子 (iReady, iMsg, iGet) 為輸入部分，(oReady, oMsg, oGet) 為輸出部分, id 為管線代號
module pipe(input clock, reset, iReady, input [7:0] iMsg, output iGet, 
            output oReady, output [7:0] oMsg, input oGet, input [3:0] id);
reg oReady, iGet, state;
reg [7:0] iMsgReg, oMsg;
    always @(posedge clock) begin
        if (reset) begin oReady=0; iGet=0; state=`IDLE; end 
        else case (state) 
            `IDLE: begin // 閒置中
                if (iReady) begin // 輸入資料已準備好
                    iMsgReg &amp;lt;= iMsg; // 儲存輸入資料
                    #2;
                    $display(&amp;quot;%-8d:p%x iMsg=%d, iGet&amp;quot;, $stime, id, iMsg);
                    iGet &amp;lt;= 1;
                    #3;
                    oMsg = iMsg + 1; // 設定輸出資料
                    #3;
                    oReady &amp;lt;= 1; // 輸出資料已準備好
                    $display(&amp;quot;%-8d:p%x oMsg=%d, oReady&amp;quot;, $stime, id, oMsg);
                    #3;
                    state &amp;lt;= `WAIT; // 進入等帶狀態
                    #2;
                end
            end
            `WAIT:begin // 等待回應 (資料被取走)
                if (oGet) begin // 資料被取走了
                    #2;
                    $display(&amp;quot;%-8d:p%x oGet&amp;quot;, $stime, id); // 顯示資料已經取走
                    oReady &amp;lt;= 0; // 下一筆輸出資料尚未準備好。
                    #3;
                    state &amp;lt;= `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料
                    #2;
                end
                iGet &amp;lt;= 0;  // 下一筆輸入資料尚未準備好。
            end
        endcase
    end
endmodule

module pipeline; // pipeline : 多根管子連接後形成的管線
reg clock, reset; // 時脈
wire [7:0] p1Msg, p2Msg, p3Msg; // pipe 傳遞的訊息
wire p1iGet, p2iGet, p3iGet; // pipe 輸入是否準備好了
wire p1oReady, p2oReady, p3oReady; // pipe 輸出是否準備好了
reg [7:0] iMsg=0; // pipeline 的整體輸入訊息
parameter iReady = 1&#039;b1, oGet=1&#039;b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。

pipe p1(clock, reset, iReady,     iMsg, p1iGet,  p1oReady, p1Msg, p2iGet,1); // 第一根管子
pipe p2(clock, reset, p1oReady, p1Msg, p2iGet, p2oReady, p2Msg, p3iGet,2); // 第二根管子
pipe p3(clock, reset, p2oReady, p2Msg, p3iGet, p3oReady, p3Msg, oGet,     3); // 第三根管子

initial begin
  reset = 1;
  clock = 0;
  #100 reset = 0;
  #100 iMsg = 10; // pipelie 的輸入資料改為 10
  #100 iMsg = 20; // pipelie 的輸入資料改為 20
  #100 $finish;
end

always #10 begin
  clock=clock+1;
end

endmodule&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;Icarus 模擬結果&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;D:\oc\cpu0p&amp;gt;iverilog pipeline3.v -o pipeline3

D:\oc\cpu0p&amp;gt;vvp pipeline3
112     :p1 iMsg=  0, iGet
118     :p1 oMsg=  1, oReady
132     :p2 iMsg=  1, iGet
138     :p2 oMsg=  2, oReady
152     :p3 iMsg=  2, iGet
152     :p1 oGet
158     :p3 oMsg=  3, oReady
172     :p3 oGet
172     :p1 iMsg=  0, iGet
172     :p2 oGet
178     :p1 oMsg=  1, oReady
192     :p2 iMsg=  1, iGet
198     :p2 oMsg=  2, oReady
212     :p3 iMsg=  2, iGet
212     :p1 oGet
218     :p3 oMsg=  3, oReady
232     :p3 oGet
232     :p1 iMsg= 10, iGet
232     :p2 oGet
238     :p1 oMsg= 11, oReady
252     :p2 iMsg= 11, iGet
258     :p2 oMsg= 12, oReady
272     :p3 iMsg= 12, iGet
272     :p1 oGet
278     :p3 oMsg= 13, oReady
292     :p3 oGet
292     :p1 iMsg= 10, iGet
292     :p2 oGet
298     :p1 oMsg= 11, oReady
312     :p2 iMsg= 11, iGet
318     :p2 oMsg= 12, oReady
332     :p3 iMsg= 12, iGet
332     :p1 oGet
338     :p3 oMsg= 13, oReady
352     :p3 oGet
352     :p1 iMsg= 20, iGet
352     :p2 oGet
358     :p1 oMsg= 21, oReady
372     :p2 iMsg= 21, iGet
378     :p2 oMsg= 22, oReady
392     :p3 iMsg= 22, iGet
392     :p1 oGet
398     :p3 oMsg= 23, oReady&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;歷史版本&lt;/span&gt;&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:pipe&quot;&gt;pipe&lt;/a&gt; &amp;#8212; 不太像 pipeline 的 pipeline。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:pipeline1&quot;&gt;pipeline1&lt;/a&gt; &amp;#8212; 展示如何設計 pipeline 的原理, Ready, Ack 版。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:pipeline2&quot;&gt;pipeline2&lt;/a&gt; &amp;#8212; 展示如何設計 pipeline 的原理, 直接初始化版。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 14 Jun 2012 02:34:04 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Verilog 程式：pipeline3.v</span></h1> <div class="code"> <pre><code>`define IDLE 1'b0 // 閒置中 `define WAIT 2'b1 // 等待回應 // pipe : 單一根管子 (iReady, iMsg, iGet) 為輸入部分，(oReady, oMsg, oGet) 為輸出部分, id 為管線代號 module pipe(input clock, reset, iReady, input [7:0] iMsg, output iGet, output oReady, output [7:0] oMsg, input oGet, input [3:0] id); reg oReady, iGet, state; reg [7:0] iMsgReg, oMsg; always @(posedge clock) begin if (reset) begin oReady=0; iGet=0; state=`IDLE; end else case (state) `IDLE: begin // 閒置中 if (iReady) begin // 輸入資料已準備好 iMsgReg &lt;= iMsg; // 儲存輸入資料 #2; $display(&quot;%-8d:p%x iMsg=%d, iGet&quot;, $stime, id, iMsg); iGet &lt;= 1; #3; oMsg = iMsg + 1; // 設定輸出資料 #3; oReady &lt;= 1; // 輸出資料已準備好 $display(&quot;%-8d:p%x oMsg=%d, oReady&quot;, $stime, id, oMsg); #3; state &lt;= `WAIT; // 進入等帶狀態 #2; end end `WAIT:begin // 等待回應 (資料被取走) if (oGet) begin // 資料被取走了 #2; $display(&quot;%-8d:p%x oGet&quot;, $stime, id); // 顯示資料已經取走 oReady &lt;= 0; // 下一筆輸出資料尚未準備好。 #3; state &lt;= `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 #2; end iGet &lt;= 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module pipeline; // pipeline : 多根管子連接後形成的管線 reg clock, reset; // 時脈 wire [7:0] p1Msg, p2Msg, p3Msg; // pipe 傳遞的訊息 wire p1iGet, p2iGet, p3iGet; // pipe 輸入是否準備好了 wire p1oReady, p2oReady, p3oReady; // pipe 輸出是否準備好了 reg [7:0] iMsg=0; // pipeline 的整體輸入訊息 parameter iReady = 1'b1, oGet=1'b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。 pipe p1(clock, reset, iReady, iMsg, p1iGet, p1oReady, p1Msg, p2iGet,1); // 第一根管子 pipe p2(clock, reset, p1oReady, p1Msg, p2iGet, p2oReady, p2Msg, p3iGet,2); // 第二根管子 pipe p3(clock, reset, p2oReady, p2Msg, p3iGet, p3oReady, p3Msg, oGet, 3); // 第三根管子 initial begin reset = 1; clock = 0; #100 reset = 0; #100 iMsg = 10; // pipelie 的輸入資料改為 10 #100 iMsg = 20; // pipelie 的輸入資料改為 20 #100 $finish; end always #10 begin clock=clock+1; end endmodule</code></pre></div> <h1><span>Icarus 模擬結果</span></h1> <div class="code"> <pre><code>D:\oc\cpu0p&gt;iverilog pipeline3.v -o pipeline3 D:\oc\cpu0p&gt;vvp pipeline3 112 :p1 iMsg= 0, iGet 118 :p1 oMsg= 1, oReady 132 :p2 iMsg= 1, iGet 138 :p2 oMsg= 2, oReady 152 :p3 iMsg= 2, iGet 152 :p1 oGet 158 :p3 oMsg= 3, oReady 172 :p3 oGet 172 :p1 iMsg= 0, iGet 172 :p2 oGet 178 :p1 oMsg= 1, oReady 192 :p2 iMsg= 1, iGet 198 :p2 oMsg= 2, oReady 212 :p3 iMsg= 2, iGet 212 :p1 oGet 218 :p3 oMsg= 3, oReady 232 :p3 oGet 232 :p1 iMsg= 10, iGet 232 :p2 oGet 238 :p1 oMsg= 11, oReady 252 :p2 iMsg= 11, iGet 258 :p2 oMsg= 12, oReady 272 :p3 iMsg= 12, iGet 272 :p1 oGet 278 :p3 oMsg= 13, oReady 292 :p3 oGet 292 :p1 iMsg= 10, iGet 292 :p2 oGet 298 :p1 oMsg= 11, oReady 312 :p2 iMsg= 11, iGet 318 :p2 oMsg= 12, oReady 332 :p3 iMsg= 12, iGet 332 :p1 oGet 338 :p3 oMsg= 13, oReady 352 :p3 oGet 352 :p1 iMsg= 20, iGet 352 :p2 oGet 358 :p1 oMsg= 21, oReady 372 :p2 iMsg= 21, iGet 378 :p2 oMsg= 22, oReady 392 :p3 iMsg= 22, iGet 392 :p1 oGet 398 :p3 oMsg= 23, oReady</code></pre></div> <h1><span>歷史版本</span></h1> <ol> <li><a href="http://ccckmit.wikidot.com/ve:pipe">pipe</a> &#8212; 不太像 pipeline 的 pipeline。</li> <li><a href="http://ccckmit.wikidot.com/ve:pipeline1">pipeline1</a> &#8212; 展示如何設計 pipeline 的原理, Ready, Ack 版。</li> <li><a href="http://ccckmit.wikidot.com/ve:pipeline2">pipeline2</a> &#8212; 展示如何設計 pipeline 的原理, 直接初始化版。</li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline2</guid>
				<title>Pipeline2</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline2</link>
				<description>

&lt;h1&gt;&lt;span&gt;Verilog 程式：pipeline.v&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 13 Jun 2012 12:54:35 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Verilog 程式：pipeline.v</span></h1> <div class="code"> <pre><code>`define IDLE 1'b0 // 閒置中 `define WAIT 2'b1 // 等待回應 // pipe : 單一根管子 (iReady, iMsg, iGet) 為輸入部分，(oReady, oMsg, oGet) 為輸出部分, id 為管線代號 module pipe(input clock, iReady, input [7:0] iMsg, output iGet, output oReady, output [7:0] oMsg, input oGet, input [3:0] id); reg oReady=0, iGet=0, state=`IDLE; reg [7:0] iMsgReg, oMsg; always @(posedge clock) begin case (state) `IDLE: begin // 閒置中 if (iReady) begin // 輸入資料已準備好 iMsgReg &lt;= iMsg; // 儲存輸入資料 #2; $display(&quot;%-8d:p%x iMsg=%d, iGet&quot;, $stime, id, iMsg); iGet &lt;= 1; #3; oMsg = iMsg + 1; // 設定輸出資料 #3; oReady &lt;= 1; // 輸出資料已準備好 $display(&quot;%-8d:p%x oMsg=%d, oReady&quot;, $stime, id, oMsg); #3; state &lt;= `WAIT; // 進入等帶狀態 #2; end end `WAIT:begin // 等待回應 (資料被取走) if (oGet) begin // 資料被取走了 #2; $display(&quot;%-8d:p%x oGet&quot;, $stime, id); // 顯示資料已經取走 oReady &lt;= 0; // 下一筆輸出資料尚未準備好。 #3; state &lt;= `IDLE; // 回到閒置狀態，準備取得下一筆輸入資料 #2; end iGet &lt;= 0; // 下一筆輸入資料尚未準備好。 end endcase end endmodule module pipeline; // pipeline : 多根管子連接後形成的管線 reg clock; // 時脈 wire [7:0] p1Msg, p2Msg, p3Msg; // pipe 傳遞的訊息 wire p1iGet, p2iGet, p3iGet; // pipe 輸入是否準備好了 wire p1oReady, p2oReady, p3oReady; // pipe 輸出是否準備好了 reg [7:0] iMsg=0; // pipeline 的整體輸入訊息 parameter iReady = 1'b1, oGet=1'b1; // pipeline 的整體輸入輸出是否準備好了 (隨時都準備好，這樣才會不斷驅動)。 pipe p1(clock, iReady, iMsg, p1iGet, p1oReady, p1Msg, p2iGet,1); // 第一根管子 pipe p2(clock, p1oReady, p1Msg, p2iGet, p2oReady, p2Msg, p3iGet,2); // 第二根管子 pipe p3(clock, p2oReady, p2Msg, p3iGet, p3oReady, p3Msg, oGet, 3); // 第三根管子 initial begin clock = 0; #100 iMsg = 10; // pipelie 的輸入資料改為 10 #100 iMsg = 20; // pipelie 的輸入資料改為 20 #100 $finish; end always #10 begin clock=clock+1; end endmodule</code></pre></div> <h1><span>Icarus 執行結果</span></h1> <div class="code"> <pre><code>D:\oc\cpu0p&gt;iverilog pipeline.v -o pipeline D:\oc\cpu0p&gt;vvp pipeline 12 :p1 iMsg= 0, iGet 18 :p1 oMsg= 1, oReady 32 :p2 iMsg= 1, iGet 38 :p2 oMsg= 2, oReady 52 :p3 iMsg= 2, iGet 52 :p1 oGet 58 :p3 oMsg= 3, oReady 72 :p3 oGet 72 :p1 iMsg= 0, iGet 72 :p2 oGet 78 :p1 oMsg= 1, oReady 92 :p2 iMsg= 1, iGet 98 :p2 oMsg= 2, oReady 112 :p3 iMsg= 2, iGet 112 :p1 oGet 118 :p3 oMsg= 3, oReady 132 :p3 oGet 132 :p1 iMsg= 10, iGet 132 :p2 oGet 138 :p1 oMsg= 11, oReady 152 :p2 iMsg= 11, iGet 158 :p2 oMsg= 12, oReady 172 :p3 iMsg= 12, iGet 172 :p1 oGet 178 :p3 oMsg= 13, oReady 192 :p3 oGet 192 :p1 iMsg= 10, iGet 192 :p2 oGet 198 :p1 oMsg= 11, oReady 212 :p2 iMsg= 11, iGet 218 :p2 oMsg= 12, oReady 232 :p3 iMsg= 12, iGet 232 :p1 oGet 238 :p3 oMsg= 13, oReady 252 :p3 oGet 252 :p1 iMsg= 20, iGet 252 :p2 oGet 258 :p1 oMsg= 21, oReady 272 :p2 iMsg= 21, iGet 278 :p2 oMsg= 22, oReady 292 :p3 iMsg= 22, iGet 292 :p1 oGet 298 :p3 oMsg= 23, oReady</code></pre></div> <h1><span>歷史版本</span></h1> <ol> <li><a href="http://ccckmit.wikidot.com/ve:pipe">pipe</a> &#8212; 不太像 pipeline 的 pipeline。</li> <li><a href="http://ccckmit.wikidot.com/ve:pipeline1">pipeline1</a> &#8212; 展示如何設計 pipeline 的原理, Ready, Ack 版。</li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:cpu0p0-1</guid>
				<title>Cpu0p (撰寫中，未完成)</title>
				<link>http://ccckmit.wikidot.com/ve:cpu0p0-1</link>
				<description>

&lt;p&gt;&lt;a href=&quot;http://ccckmit.wdfiles.com/local--files/ve:cpu0p0-1/cpu0p0.3.zip&quot;&gt;cpu0p0.3.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 11 Jun 2012 06:02:33 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p><a href="http://ccckmit.wdfiles.com/local--files/ve:cpu0p0-1/cpu0p0.3.zip">cpu0p0.3.zip</a></p> <h1><span>輸入程式：cpu0p.hex</span></h1> <div class="code"> <pre><code>00 1F 00 24 // 0000 LD R1, K1 00 2F 00 1C // 0004 LD R2, K0 00 3F 00 20 // 0008 LD R3, SUM 08 40 00 0A // 000C LDI R4, 10 13 22 10 00 // 0010 LOOP: ADD R2, R2, R1 13 33 20 00 // 0014 ADD R3, R3, R2 10 24 00 00 // 0018 CMP R2, R4 21 FF FF F0 // 001C JNE LOOP 2C 00 00 00 // 0020 RET 00 00 00 00 // 0024 K0: WORD 0 00 00 00 01 // 0028 K1: WORD 1 00 00 00 00 // 002C SUM: WORD 0</code></pre></div> <h1><span>Verilog 程式</span></h1> <div class="code"> <pre><code>// 定義：寬度形態常數 `define INT32 2'b11 // 寬度 32 位元 `define INT24 2'b10 // 寬度 24 位元 `define INT16 2'b01 // 寬度 16 位元 `define BYTE 2'b00 // 寬度 8 位元 // 記憶體狀態 `define WAITING 2'b00 // 閒置中 `define READING 2'b01 // 讀取中 `define WRITING 2'b10 // 寫入中 // 記憶體讀寫 `define READ 1'b1 // 讀取 `define WRITE 1'b0 // 寫入 module ifetch(input clock, reset); always @(posedge clock) begin // $display(&quot;m_state=%d pc1=%x&quot;, m_state, pc1); if (cpu0.m_state == `WAITING &amp;&amp; cpu0.m_en == 0) begin cpu0.m_rw = `READ; // 讀取模式：read cpu0.m_en = 1; // 啟動讀取 cpu0.m_w1 = `INT32; cpu0.pc = cpu0.pc + 4; cpu0.mar = cpu0.pc; $display(&quot;%-4d:ifetch(abus=pc=%x)&quot;, $stime, cpu0.pc); end end endmodule module idecode(input clock, reset); reg signed [11:0] cx12; reg signed [15:0] cx16; reg signed [23:0] cx24; always @(posedge clock) begin // if (cpu0.m_state == `WAITING &amp;&amp; cpu0.m_en == 1) begin cpu0.ir = cpu0.mdr; // 取得指令 cpu0.m_en = 0; // 讀取完畢 {cpu0.op,cpu0.a,cpu0.b,cpu0.c,cx12} = cpu0.ir; cx24 = cpu0.ir[23:0]; cx16 = cpu0.ir[15:0]; cpu0.c5 = cpu0.ir[4:0]; cpu0.c12 = cx12; // 取出 cx12 並轉為 32 位元有號數 c12 cpu0.c16 = cx16; // 取出 cx16 並轉為 32 位元有號數 c16 cpu0.c24 = cx24; // 取出 cx24 並轉為 32 位元有號數 c24 $display(&quot;%-8d:idecode(mdr=%x ir=%x op=%x a=%x b=%x c=%x cx12=%x)&quot;, $stime, cpu0.mdr, cpu0.ir, cpu0.op, cpu0.a, cpu0.b, cpu0.c, cpu0.c12); // end end endmodule module cpu0(input clock, reset, input [1:0] m_state, output [31:0] pc, abus, dbus, output reg m_en, m_rw, output reg [1:0] m_w1); reg signed [31:0] R [0:15]; reg [7:0] op; reg [3:0] a, b, c; reg [4:0] c5; reg signed [31:0] c12, c16, c24, Ra, Rb, Rc, ipc; // ipc:instruction PC reg [31:0] pc, ir, mar, mdr; initial begin pc = 0; m_en = 0; end assign abus = mar; always @(m_en, dbus) begin if (m_en &amp;&amp; m_rw==`READ &amp;&amp; dbus !== 32'hZ) mdr = dbus; end ifetch if1(clock, reset); idecode id1(clock, reset); // tick2 t2(.clock(clock), .reset(reset), .dbus(dbus), .ir(ir), .m_en(m_en)); // controller ctrl(.clock(clock), .reset(reset), .pc(pc), .abus(abus), .dbus(dbus), .ir(ir), .m_en(m_en), .m_rw(m_rw)); endmodule module memory0(input clock, reset, m_en, m_rw, input [1:0] m_w1, input [31:0] abus, inout [31:0] dbus, output [1:0] m_state); reg [7:0] m [0:258]; reg [31:0] data; reg m_state = `WAITING; integer i; initial begin $readmemh(&quot;cpu0p.hex&quot;, m); for (i=0; i &lt; 255; i=i+4) begin $display(&quot;%8x: %8x&quot;, i, {m[i], m[i+1], m[i+2], m[i+3]}); end end always @(abus or m_en or m_rw or m_state or dbus) begin // $display(&quot;%d:1 memory trigger(m_en=%b, m_rw=%b, m_state=%b, abus=%x)&quot;, $stime, m_en, m_rw, m_state, abus); if (abus &gt;=0 &amp;&amp; abus &lt;= 255) begin // $display(&quot;%d:2 memory trigger(m_en=%b, m_rw=%b, m_state=%b)&quot;, $stime, m_en, m_rw, m_state); if (m_en == 1) begin if (m_rw == 0) begin // r_w==0:write m_state = `WRITING; #10; data = dbus; case (m_w1) `BYTE: {m[abus]} = dbus[7:0]; `INT16: {m[abus], m[abus+1] } = dbus[15:0]; `INT24: {m[abus], m[abus+1], m[abus+2]} = dbus[24:0]; `INT32: {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus; endcase $display(&quot;%-8d:write(abus=%x data=%x)&quot;, $stime, abus, data); m_state = `WAITING; end else begin// r_w==1:read m_state = `READING; #10; case (m_w1) `BYTE: data = {8'h00 , 8'h00, 8'h00, m[abus] }; `INT16: data = {8'h00 , 8'h00, m[abus], m[abus+1] }; `INT24: data = {8'h00 , m[abus], m[abus+1], m[abus+2] }; `INT32: data = {m[abus], m[abus+1], m[abus+2], m[abus+3]}; endcase $display(&quot;%-8d:read(abus=%x data=%x)&quot;, $stime, abus, data); m_state = `WAITING; end end else // m_en==0 data = 32'hZZZZZZZZ; end else // a &gt; 255 data = 32'hZZZZZZZZ; end assign dbus = data; endmodule module main; reg clock, reset; wire [31:0] abus, dbus, pc; wire m_en, m_rw; wire [1:0] m_w1, m_state; cpu0 cpu(.clock(clock), .reset(reset), .m_state(m_state), .pc(pc), .abus(abus), .dbus(dbus), .m_en(m_en), .m_rw(m_rw), .m_w1(m_w1)); memory0 mem(.clock(clock), .reset(reset), .m_en(m_en), .m_rw(m_rw), .m_state(m_state), .m_w1(m_w1), .abus(abus), .dbus(dbus)); initial begin clock = 0; reset = 1; #10 reset=0; #1000 $finish; end always #50 begin clock=clock+1; // $monitor(&quot;%4dns pc=%x&quot;, $stime, pc); end endmodule</code></pre></div> <h1><span>執行結果</span></h1> <div class="code"> <pre><code>D:\oc\pipepc&gt;iverilog cpu0p.v -o cpu0p D:\oc\pipepc&gt;vvp cpu0p WARNING: cpu0p.v:81: $readmemh(cpu0p.hex): Not enough words in the file for the requested range [0:258]. 00000000: 001f0024 00000004: 002f001c 00000008: 003f0020 0000000c: 0840000a 00000010: 13221000 00000014: 13332000 00000018: 10240000 0000001c: 21fffff0 00000020: 2c000000 00000024: 00000000 00000028: 00000001 0000002c: 00000000 00000030: xxxxxxxx 00000034: xxxxxxxx 00000038: xxxxxxxx 0000003c: xxxxxxxx 00000040: xxxxxxxx 00000044: xxxxxxxx 00000048: xxxxxxxx 0000004c: xxxxxxxx 00000050: xxxxxxxx 00000054: xxxxxxxx 00000058: xxxxxxxx 0000005c: xxxxxxxx 00000060: xxxxxxxx 00000064: xxxxxxxx 00000068: xxxxxxxx 0000006c: xxxxxxxx 00000070: xxxxxxxx 00000074: xxxxxxxx 00000078: xxxxxxxx 0000007c: xxxxxxxx 00000080: xxxxxxxx 00000084: xxxxxxxx 00000088: xxxxxxxx 0000008c: xxxxxxxx 00000090: xxxxxxxx 00000094: xxxxxxxx 00000098: xxxxxxxx 0000009c: xxxxxxxx 000000a0: xxxxxxxx 000000a4: xxxxxxxx 000000a8: xxxxxxxx 000000ac: xxxxxxxx 000000b0: xxxxxxxx 000000b4: xxxxxxxx 000000b8: xxxxxxxx 000000bc: xxxxxxxx 000000c0: xxxxxxxx 000000c4: xxxxxxxx 000000c8: xxxxxxxx 000000cc: xxxxxxxx 000000d0: xxxxxxxx 000000d4: xxxxxxxx 000000d8: xxxxxxxx 000000dc: xxxxxxxx 000000e0: xxxxxxxx 000000e4: xxxxxxxx 000000e8: xxxxxxxx 000000ec: xxxxxxxx 000000f0: xxxxxxxx 000000f4: xxxxxxxx 000000f8: xxxxxxxx 000000fc: xxxxxxxx 50 :idecode(mdr=xxxxxxxx ir=xxxxxxxx op=xx a=x b=x c=x cx12=xxxxxxxx) 50 :ifetch(abus=pc=00000004) 60 :read(abus=00000004 data=002f001c) 150 :idecode(mdr=002f001c ir=002f001c op=00 a=2 b=f c=0 cx12=0000001c) 250 :idecode(mdr=002f001c ir=002f001c op=00 a=2 b=f c=0 cx12=0000001c) 250 :ifetch(abus=pc=00000008) 260 :read(abus=00000008 data=003f0020) 350 :idecode(mdr=003f0020 ir=003f0020 op=00 a=3 b=f c=0 cx12=00000020) 450 :idecode(mdr=003f0020 ir=003f0020 op=00 a=3 b=f c=0 cx12=00000020) 450 :ifetch(abus=pc=0000000c) 460 :read(abus=0000000c data=0840000a) 550 :idecode(mdr=0840000a ir=0840000a op=08 a=4 b=0 c=0 cx12=0000000a) 650 :idecode(mdr=0840000a ir=0840000a op=08 a=4 b=0 c=0 cx12=0000000a) 650 :ifetch(abus=pc=00000010) 660 :read(abus=00000010 data=13221000) 750 :idecode(mdr=13221000 ir=13221000 op=13 a=2 b=2 c=1 cx12=00000000) 850 :idecode(mdr=13221000 ir=13221000 op=13 a=2 b=2 c=1 cx12=00000000) 850 :ifetch(abus=pc=00000014) 860 :read(abus=00000014 data=13332000) 950 :idecode(mdr=13332000 ir=13332000 op=13 a=3 b=3 c=2 cx12=00000000) D:\oc\pipepc&gt;</code></pre></div> <h1><span>參考文獻</span></h1> <ol> <li>Hardware pipelining example, Written by Yann Sionneau, Tuesday, 01 November 2011&#160;11:24 <ul> <li><a href="http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example">http://sionneau.net/en/projects/3-divers/17-hardware-pipelining-example</a></li> </ul> </li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipeline1</guid>
				<title>Pipeline 架構的範例 1</title>
				<link>http://ccckmit.wikidot.com/ve:pipeline1</link>
				<description>

&lt;h1&gt;&lt;span&gt;程式：pipeline.v&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;`define IDLE     1&#039;b0     // 閒置中
`define WAIT_ACK 2&#039;b1     // 等待回應

module timer(input clock);
reg [7:0] count=0;
    always @(posedge clock) begin
        count = count + 1;
        $display(&amp;quot;%d:count=%d&amp;quot;, $stime, count);
    end
endmodule

module pipe(input clock, iReady, output myAck, output oReady, input nextAck, input [3:0] id);
reg oReady=0, myAck=0, state=`IDLE;
    always @(posedge clock) begin
        case (state) 
            `IDLE: begin
                if (iReady) begin
                    $display(&amp;quot;%-8d:p%x iReady&amp;quot;, $stime, id);
                    #20;
                    state &amp;lt;= `WAIT_ACK;
                    myAck &amp;lt;= 1;
                    oReady &amp;lt;= 1;
                    $display(&amp;quot;%-8d:p%x ack, oReady&amp;quot;, $stime, id);
                    #10;
                end
            end
            `WAIT_ACK:begin
                if (nextAck) begin
                    $display(&amp;quot;%-8d:p%x nextAck&amp;quot;, $stime, id);
                    #20;
                    oReady &amp;lt;= 0;
                    state &amp;lt;= `IDLE;
                    #10;
                end
                myAck &amp;lt;= 0;
            end
        endcase
    end
endmodule

module pipeline;
reg clock;
wire p1Ack, p2Ack, p3Ack, p1oReady, p2oReady, p3oReady;

pipe p1(clock, 1,          p1Ack, p1oReady, p2Ack,    1);
pipe p2(clock, p1oReady, p2Ack, p2oReady, p3Ack,     2);
pipe p3(clock, p2oReady, p3Ack, p3oReady, 1,         3);

initial begin
  clock = 0;
  #1000 $finish;
end

always #10 begin
  clock=clock+1;
end

endmodule&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;執行結果&lt;/span&gt;&lt;/h1&gt;
&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;D:\oc\cpu0p&amp;gt;iverilog pipeline.v -o pipeline

D:\oc\cpu0p&amp;gt;vvp pipeline
10      :p1 iReady
30      :p1 ack, oReady
50      :p2 iReady
70      :p2 ack, oReady
90      :p1 nextAck
90      :p3 iReady
110     :p3 ack, oReady
130     :p3 nextAck
130     :p1 iReady
130     :p2 nextAck
150     :p1 ack, oReady
170     :p2 iReady
190     :p2 ack, oReady
210     :p1 nextAck
210     :p3 iReady
230     :p3 ack, oReady
250     :p3 nextAck
250     :p1 iReady
250     :p2 nextAck
270     :p1 ack, oReady
290     :p2 iReady
310     :p2 ack, oReady
330     :p1 nextAck
330     :p3 iReady
350     :p3 ack, oReady
370     :p3 nextAck
370     :p1 iReady
370     :p2 nextAck
390     :p1 ack, oReady
410     :p2 iReady
430     :p2 ack, oReady
450     :p1 nextAck
450     :p3 iReady
470     :p3 ack, oReady
490     :p3 nextAck
490     :p1 iReady
490     :p2 nextAck
510     :p1 ack, oReady
530     :p2 iReady
550     :p2 ack, oReady
570     :p1 nextAck
570     :p3 iReady
590     :p3 ack, oReady
610     :p3 nextAck
610     :p1 iReady
610     :p2 nextAck
630     :p1 ack, oReady
650     :p2 iReady
670     :p2 ack, oReady
690     :p1 nextAck
690     :p3 iReady
710     :p3 ack, oReady
730     :p3 nextAck
730     :p1 iReady
730     :p2 nextAck
750     :p1 ack, oReady
770     :p2 iReady
790     :p2 ack, oReady
810     :p1 nextAck
810     :p3 iReady
830     :p3 ack, oReady
850     :p3 nextAck
850     :p1 iReady
850     :p2 nextAck
870     :p1 ack, oReady
890     :p2 iReady
910     :p2 ack, oReady
930     :p1 nextAck
930     :p3 iReady
950     :p3 ack, oReady
970     :p3 nextAck
970     :p1 iReady
970     :p2 nextAck
990     :p1 ack, oReady&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 13 Jun 2012 01:40:42 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>程式：pipeline.v</span></h1> <div class="code"> <pre><code>`define IDLE 1'b0 // 閒置中 `define WAIT_ACK 2'b1 // 等待回應 module timer(input clock); reg [7:0] count=0; always @(posedge clock) begin count = count + 1; $display(&quot;%d:count=%d&quot;, $stime, count); end endmodule module pipe(input clock, iReady, output myAck, output oReady, input nextAck, input [3:0] id); reg oReady=0, myAck=0, state=`IDLE; always @(posedge clock) begin case (state) `IDLE: begin if (iReady) begin $display(&quot;%-8d:p%x iReady&quot;, $stime, id); #20; state &lt;= `WAIT_ACK; myAck &lt;= 1; oReady &lt;= 1; $display(&quot;%-8d:p%x ack, oReady&quot;, $stime, id); #10; end end `WAIT_ACK:begin if (nextAck) begin $display(&quot;%-8d:p%x nextAck&quot;, $stime, id); #20; oReady &lt;= 0; state &lt;= `IDLE; #10; end myAck &lt;= 0; end endcase end endmodule module pipeline; reg clock; wire p1Ack, p2Ack, p3Ack, p1oReady, p2oReady, p3oReady; pipe p1(clock, 1, p1Ack, p1oReady, p2Ack, 1); pipe p2(clock, p1oReady, p2Ack, p2oReady, p3Ack, 2); pipe p3(clock, p2oReady, p3Ack, p3oReady, 1, 3); initial begin clock = 0; #1000 $finish; end always #10 begin clock=clock+1; end endmodule</code></pre></div> <h1><span>執行結果</span></h1> <div class="code"> <pre><code>D:\oc\cpu0p&gt;iverilog pipeline.v -o pipeline D:\oc\cpu0p&gt;vvp pipeline 10 :p1 iReady 30 :p1 ack, oReady 50 :p2 iReady 70 :p2 ack, oReady 90 :p1 nextAck 90 :p3 iReady 110 :p3 ack, oReady 130 :p3 nextAck 130 :p1 iReady 130 :p2 nextAck 150 :p1 ack, oReady 170 :p2 iReady 190 :p2 ack, oReady 210 :p1 nextAck 210 :p3 iReady 230 :p3 ack, oReady 250 :p3 nextAck 250 :p1 iReady 250 :p2 nextAck 270 :p1 ack, oReady 290 :p2 iReady 310 :p2 ack, oReady 330 :p1 nextAck 330 :p3 iReady 350 :p3 ack, oReady 370 :p3 nextAck 370 :p1 iReady 370 :p2 nextAck 390 :p1 ack, oReady 410 :p2 iReady 430 :p2 ack, oReady 450 :p1 nextAck 450 :p3 iReady 470 :p3 ack, oReady 490 :p3 nextAck 490 :p1 iReady 490 :p2 nextAck 510 :p1 ack, oReady 530 :p2 iReady 550 :p2 ack, oReady 570 :p1 nextAck 570 :p3 iReady 590 :p3 ack, oReady 610 :p3 nextAck 610 :p1 iReady 610 :p2 nextAck 630 :p1 ack, oReady 650 :p2 iReady 670 :p2 ack, oReady 690 :p1 nextAck 690 :p3 iReady 710 :p3 ack, oReady 730 :p3 nextAck 730 :p1 iReady 730 :p2 nextAck 750 :p1 ack, oReady 770 :p2 iReady 790 :p2 ack, oReady 810 :p1 nextAck 810 :p3 iReady 830 :p3 ack, oReady 850 :p3 nextAck 850 :p1 iReady 850 :p2 nextAck 870 :p1 ack, oReady 890 :p2 iReady 910 :p2 ack, oReady 930 :p1 nextAck 930 :p3 iReady 950 :p3 ack, oReady 970 :p3 nextAck 970 :p1 iReady 970 :p2 nextAck 990 :p1 ack, oReady</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:cpu0p2</guid>
				<title>Cpu0p2</title>
				<link>http://ccckmit.wikidot.com/ve:cpu0p2</link>
				<description>

&lt;div class=&quot;code&quot;&gt;
&lt;pre&gt;&lt;code&gt;// 定義：寬度形態常數
`define INT32 2&#039;b11     // 寬度 32 位元
`define INT24 2&#039;b10     // 寬度 24 位元
`define INT16 2&#039;b01     // 寬度 16 位元
`define BYTE  2&#039;b00     // 寬度  8 位元
// 記憶體狀態
`define IDLE     1&#039;b0 // 閒置中
`define BUSY     2&#039;b1 // 忙碌中
`define WAIT_ACK 2&#039;b1 // 忙碌中
// 記憶體讀寫
`define READ     1&#039;b1     // 讀取
`define WRITE     1&#039;b0     // 寫入

module ifetch(input clock, reset, i_ready, output o_ready, input next_ack, output ack_prev);
    always @(posedge clock) begin
//        $display(&amp;quot;m_state=%d pc1=%x&amp;quot;, m_state, pc1);
        case (state) 
            `IDLE: begin
                if (cpu.m_en == 0) begin
                    cpu.m_rw = `READ; // 讀取模式：read 
                    cpu.m_en = 1;     // 啟動讀取
                    cpu.m_w1 = `INT32;
                    cpu.pc = cpu.pc + 4;
                    cpu.mar = cpu.pc;
                    $display(&amp;quot;%-4d:ifetch(abus=pc=%x)&amp;quot;, $stime, cpu.pc);
                end
            end
            `WAIT_ACK: begin
                if (next_ack) begin
                    state &amp;lt;= IDLE;
                end
            end
        endcase
    end
endmodule

module idecode(input clock, reset, i_ready, output o_ready, input next_ack, output ack_prev);
    reg state
    reg signed [11:0] cx12;
    reg signed [15:0] cx16;
    reg signed [23:0] cx24;
    always @(posedge clock) begin
        case (state) 
            `IDLE: begin
                cpu.ir = cpu.mdr; // 取得指令
                cpu.m_en = 0; // 讀取完畢
                {cpu.op,cpu.a,cpu.b,cpu.c,cx12} = cpu.ir;
                cx24 = cpu.ir[23:0];
                cx16 = cpu.ir[15:0];
                cpu.c5  = cpu.ir[4:0];
                cpu.c12 = cx12; // 取出 cx12 並轉為 32 位元有號數 c12
                cpu.c16 = cx16; // 取出 cx16 並轉為 32 位元有號數 c16
                cpu.c24 = cx24; // 取出 cx24 並轉為 32 位元有號數 c24
                $display(&amp;quot;%-8d:idecode(mdr=%x ir=%x op=%x a=%x b=%x c=%x cx12=%x)&amp;quot;, $stime, cpu.mdr, cpu.ir, cpu.op, cpu.a, cpu.b, cpu.c, cpu.c12);
            end
            `WAIT_ACK:begin
                if (next_ack) begin
                    state &amp;lt;= IDLE;
                end
            end
        endcase
    end
endmodule

module cpu0(input clock, reset, input [1:0] m_state, output [31:0] pc, abus, dbus, output reg m_en, m_rw, output reg [1:0] m_w1);
    reg signed [31:0] R [0:15];
    reg [7:0] op;
    reg [3:0] a, b, c;
    reg [4:0] c5;
    reg signed [31:0] c12, c16, c24, Ra, Rb, Rc, ipc; // ipc:instruction PC
    reg [31:0] pc, ir, mar, mdr;

initial begin
  pc = 0;
  m_en = 0;
end

assign abus = mar;
always @(m_en, dbus) begin
    if (m_en &amp;amp;&amp;amp; m_rw==`READ &amp;amp;&amp;amp; dbus !== 32&#039;hZ)
        mdr = dbus;
end

  ifetch if1(clock, reset, m_state, );
  idecode id1(clock, reset);
//  tick2 t2(.clock(clock), .reset(reset), .dbus(dbus), .ir(ir), .m_en(m_en));
//  controller ctrl(.clock(clock), .reset(reset), .pc(pc), .abus(abus), .dbus(dbus), .ir(ir), .m_en(m_en), .m_rw(m_rw));
endmodule

module memory0(input clock, reset, m_en, m_rw, input [1:0] m_w1, 
                input [31:0] abus, inout [31:0] dbus, output [1:0] m_state);
reg [7:0] m [0:258];
reg [31:0] data;
reg m_state = `WAITING;

integer i;
initial begin
    $readmemh(&amp;quot;cpu0p.hex&amp;quot;, m);
    for (i=0; i &amp;lt; 255; i=i+4) begin
       $display(&amp;quot;%8x: %8x&amp;quot;, i, {m[i], m[i+1], m[i+2], m[i+3]});
    end
end

    always @(abus or m_en or m_rw or m_state or dbus) 
    begin
//        $display(&amp;quot;%d:1 memory trigger(m_en=%b, m_rw=%b, m_state=%b, abus=%x)&amp;quot;, $stime, m_en, m_rw, m_state, abus);
        if (abus &amp;gt;=0 &amp;amp;&amp;amp; abus &amp;lt;= 255) begin
//            $display(&amp;quot;%d:2 memory trigger(m_en=%b, m_rw=%b, m_state=%b)&amp;quot;, $stime, m_en, m_rw, m_state);
            if (m_en == 1) begin
                if (m_rw == 0) begin // r_w==0:write
                    m_state = `BUSY;
                    #10;
                    data = dbus;
                    case (m_w1)
                        `BYTE:  {m[abus]} = dbus[7:0];
                        `INT16: {m[abus], m[abus+1] } = dbus[15:0];
                        `INT24: {m[abus], m[abus+1], m[abus+2]} = dbus[24:0];
                        `INT32: {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus;
                    endcase
                    $display(&amp;quot;%-8d:write(abus=%x data=%x)&amp;quot;, $stime, abus, data);
                    m_state = `IDLE;
                end else begin// r_w==1:read
                    m_state = `BUSY;
                    #10;
                    case (m_w1)
                        `BYTE:  data = {8&#039;h00  , 8&#039;h00,   8&#039;h00,   m[abus]      };
                        `INT16: data = {8&#039;h00  , 8&#039;h00,   m[abus], m[abus+1]    };
                        `INT24: data = {8&#039;h00  , m[abus], m[abus+1], m[abus+2]  };
                        `INT32: data = {m[abus], m[abus+1], m[abus+2], m[abus+3]};
                    endcase
                    $display(&amp;quot;%-8d:read(abus=%x data=%x)&amp;quot;, $stime, abus, data);
                    m_state = `IDLE;
                end
            end else // m_en==0
                data = 32&#039;hZZZZZZZZ;
        end else // a &amp;gt; 255
            data = 32&#039;hZZZZZZZZ;
    end
    assign dbus = data;
endmodule

module main;
reg clock, reset;
wire [31:0] abus, dbus, pc;
wire m_en, m_rw;
wire [1:0] m_w1, m_state;

cpu0 cpu(.clock(clock), .reset(reset), .m_state(m_state), .pc(pc), .abus(abus), .dbus(dbus), .m_en(m_en), .m_rw(m_rw), .m_w1(m_w1));
memory0 mem(.clock(clock), .reset(reset), .m_en(m_en), .m_rw(m_rw), .m_state(m_state), .m_w1(m_w1), .abus(abus), .dbus(dbus));

initial
begin
  clock = 0;
  reset = 1;
  #10 reset=0;  
  #1000 $finish;
end

always #50 begin
  clock=clock+1;
//  $monitor(&amp;quot;%4dns pc=%x&amp;quot;, $stime, pc);  
end
endmodule&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 12 Jun 2012 12:59:10 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <div class="code"> <pre><code>// 定義：寬度形態常數 `define INT32 2'b11 // 寬度 32 位元 `define INT24 2'b10 // 寬度 24 位元 `define INT16 2'b01 // 寬度 16 位元 `define BYTE 2'b00 // 寬度 8 位元 // 記憶體狀態 `define IDLE 1'b0 // 閒置中 `define BUSY 2'b1 // 忙碌中 `define WAIT_ACK 2'b1 // 忙碌中 // 記憶體讀寫 `define READ 1'b1 // 讀取 `define WRITE 1'b0 // 寫入 module ifetch(input clock, reset, i_ready, output o_ready, input next_ack, output ack_prev); always @(posedge clock) begin // $display(&quot;m_state=%d pc1=%x&quot;, m_state, pc1); case (state) `IDLE: begin if (cpu.m_en == 0) begin cpu.m_rw = `READ; // 讀取模式：read cpu.m_en = 1; // 啟動讀取 cpu.m_w1 = `INT32; cpu.pc = cpu.pc + 4; cpu.mar = cpu.pc; $display(&quot;%-4d:ifetch(abus=pc=%x)&quot;, $stime, cpu.pc); end end `WAIT_ACK: begin if (next_ack) begin state &lt;= IDLE; end end endcase end endmodule module idecode(input clock, reset, i_ready, output o_ready, input next_ack, output ack_prev); reg state reg signed [11:0] cx12; reg signed [15:0] cx16; reg signed [23:0] cx24; always @(posedge clock) begin case (state) `IDLE: begin cpu.ir = cpu.mdr; // 取得指令 cpu.m_en = 0; // 讀取完畢 {cpu.op,cpu.a,cpu.b,cpu.c,cx12} = cpu.ir; cx24 = cpu.ir[23:0]; cx16 = cpu.ir[15:0]; cpu.c5 = cpu.ir[4:0]; cpu.c12 = cx12; // 取出 cx12 並轉為 32 位元有號數 c12 cpu.c16 = cx16; // 取出 cx16 並轉為 32 位元有號數 c16 cpu.c24 = cx24; // 取出 cx24 並轉為 32 位元有號數 c24 $display(&quot;%-8d:idecode(mdr=%x ir=%x op=%x a=%x b=%x c=%x cx12=%x)&quot;, $stime, cpu.mdr, cpu.ir, cpu.op, cpu.a, cpu.b, cpu.c, cpu.c12); end `WAIT_ACK:begin if (next_ack) begin state &lt;= IDLE; end end endcase end endmodule module cpu0(input clock, reset, input [1:0] m_state, output [31:0] pc, abus, dbus, output reg m_en, m_rw, output reg [1:0] m_w1); reg signed [31:0] R [0:15]; reg [7:0] op; reg [3:0] a, b, c; reg [4:0] c5; reg signed [31:0] c12, c16, c24, Ra, Rb, Rc, ipc; // ipc:instruction PC reg [31:0] pc, ir, mar, mdr; initial begin pc = 0; m_en = 0; end assign abus = mar; always @(m_en, dbus) begin if (m_en &amp;&amp; m_rw==`READ &amp;&amp; dbus !== 32'hZ) mdr = dbus; end ifetch if1(clock, reset, m_state, ); idecode id1(clock, reset); // tick2 t2(.clock(clock), .reset(reset), .dbus(dbus), .ir(ir), .m_en(m_en)); // controller ctrl(.clock(clock), .reset(reset), .pc(pc), .abus(abus), .dbus(dbus), .ir(ir), .m_en(m_en), .m_rw(m_rw)); endmodule module memory0(input clock, reset, m_en, m_rw, input [1:0] m_w1, input [31:0] abus, inout [31:0] dbus, output [1:0] m_state); reg [7:0] m [0:258]; reg [31:0] data; reg m_state = `WAITING; integer i; initial begin $readmemh(&quot;cpu0p.hex&quot;, m); for (i=0; i &lt; 255; i=i+4) begin $display(&quot;%8x: %8x&quot;, i, {m[i], m[i+1], m[i+2], m[i+3]}); end end always @(abus or m_en or m_rw or m_state or dbus) begin // $display(&quot;%d:1 memory trigger(m_en=%b, m_rw=%b, m_state=%b, abus=%x)&quot;, $stime, m_en, m_rw, m_state, abus); if (abus &gt;=0 &amp;&amp; abus &lt;= 255) begin // $display(&quot;%d:2 memory trigger(m_en=%b, m_rw=%b, m_state=%b)&quot;, $stime, m_en, m_rw, m_state); if (m_en == 1) begin if (m_rw == 0) begin // r_w==0:write m_state = `BUSY; #10; data = dbus; case (m_w1) `BYTE: {m[abus]} = dbus[7:0]; `INT16: {m[abus], m[abus+1] } = dbus[15:0]; `INT24: {m[abus], m[abus+1], m[abus+2]} = dbus[24:0]; `INT32: {m[abus], m[abus+1], m[abus+2], m[abus+3]} = dbus; endcase $display(&quot;%-8d:write(abus=%x data=%x)&quot;, $stime, abus, data); m_state = `IDLE; end else begin// r_w==1:read m_state = `BUSY; #10; case (m_w1) `BYTE: data = {8'h00 , 8'h00, 8'h00, m[abus] }; `INT16: data = {8'h00 , 8'h00, m[abus], m[abus+1] }; `INT24: data = {8'h00 , m[abus], m[abus+1], m[abus+2] }; `INT32: data = {m[abus], m[abus+1], m[abus+2], m[abus+3]}; endcase $display(&quot;%-8d:read(abus=%x data=%x)&quot;, $stime, abus, data); m_state = `IDLE; end end else // m_en==0 data = 32'hZZZZZZZZ; end else // a &gt; 255 data = 32'hZZZZZZZZ; end assign dbus = data; endmodule module main; reg clock, reset; wire [31:0] abus, dbus, pc; wire m_en, m_rw; wire [1:0] m_w1, m_state; cpu0 cpu(.clock(clock), .reset(reset), .m_state(m_state), .pc(pc), .abus(abus), .dbus(dbus), .m_en(m_en), .m_rw(m_rw), .m_w1(m_w1)); memory0 mem(.clock(clock), .reset(reset), .m_en(m_en), .m_rw(m_rw), .m_state(m_state), .m_w1(m_w1), .abus(abus), .dbus(dbus)); initial begin clock = 0; reset = 1; #10 reset=0; #1000 $finish; end always #50 begin clock=clock+1; // $monitor(&quot;%4dns pc=%x&quot;, $stime, pc); end endmodule</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:cpu0</guid>
				<title>Cpu0</title>
				<link>http://ccckmit.wikidot.com/ve:cpu0</link>
				<description>

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:cpu0s&quot;&gt;cpu0s&lt;/a&gt; &amp;#8212; 簡易 CPU，包含 CPU0 所有指令的實作，但沒有中斷。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:cpu0i&quot;&gt;cpu0i&lt;/a&gt; &amp;#8212; CPU0 所有指令的實作，有中斷。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:cpu0f&quot;&gt;cpu0f&lt;/a&gt; &amp;#8212; CPU0 所有指令的實作，有中斷，且有浮點數運算 FADD, FSUB, FMUL, FDIV。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ccckmit.wikidot.com/ve:cpu0p&quot;&gt;cpu0p&lt;/a&gt; &amp;#8212; 使用管線 (Pipeline) 平行化後的 CPU0 處理器。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 08 Jun 2012 03:40:15 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ol> <li><a href="http://ccckmit.wikidot.com/ve:cpu0s">cpu0s</a> &#8212; 簡易 CPU，包含 CPU0 所有指令的實作，但沒有中斷。</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0i">cpu0i</a> &#8212; CPU0 所有指令的實作，有中斷。</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0f">cpu0f</a> &#8212; CPU0 所有指令的實作，有中斷，且有浮點數運算 FADD, FSUB, FMUL, FDIV。</li> <li><a href="http://ccckmit.wikidot.com/ve:cpu0p">cpu0p</a> &#8212; 使用管線 (Pipeline) 平行化後的 CPU0 處理器。</li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:global</guid>
				<title>全域變數</title>
				<link>http://ccckmit.wikidot.com/ve:global</link>
				<description>

&lt;p&gt;Verilog 中所有的變數都是全域變數，只要加上模組名稱就可直接存取，範例如下。&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 12 Jun 2012 07:45:02 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Verilog 中所有的變數都是全域變數，只要加上模組名稱就可直接存取，範例如下。</p> <div class="code"> <pre><code>module top; integer myglobalvar; endmodule module any; initial $display(top.myglobalvar); endmodule</code></pre></div> <h1><span>參考文獻</span></h1> <ol> <li><a href="http://stackoverflow.com/questions/6008017/global-variables-in-verilog">http://stackoverflow.com/questions/6008017/global-variables-in-verilog</a></li> </ol> <p>#Thread: Global Variable in Verilog &#8212; <a href="http://www.edaboard.com/thread174172.html">http://www.edaboard.com/thread174172.html</a></p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:module</guid>
				<title>模組</title>
				<link>http://ccckmit.wikidot.com/ve:module</link>
				<description>

&lt;h1&gt;&lt;span&gt;模組的語法&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 08 Dec 2011 07:37:42 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>模組的語法</span></h1> <div class="code"> <pre><code>module &lt;module name&gt; (&lt;port list&gt;); &lt;declares&gt; &lt;module items&gt; endmodule</code></pre></div> <p>其中的 &lt;module items&gt; 可能是以下的語句：<br /> 1. initial<br /> 2. always<br /> 3. assign<br /> 4. module 的實例</p> <h1><span>模組的範例：</span></h1> <div class="code"> <pre><code>module A(out1, out2, in1, in2); output out1; output [3:0] out2; input in1; input [2:0] in2; endmodule</code></pre></div> <p>更簡單的語法：</p> <div class="code"> <pre><code>module A(output out1, output [3:0] out2, input in1, input [2:0] in2); endmodule</code></pre></div> <h1><span>模組實例化</span></h1> <div class="code"> <pre><code>A x(x1, y1, a1, b1); // 按照位置一對一連接 A (x1, y1, a1, b1); // 省略名稱 A y(.out1(x1), .out2(y1), .in1(a1), .in2(b1)); // 按照名稱進行連接</code></pre></div> <h1><span>SystemVerilog 中的 module</span></h1> <ol> <li><a href="http://www.asic-world.com/systemverilog/hierarchy3.html">http://www.asic-world.com/systemverilog/hierarchy3.html</a></li> </ol> <blockquote> <p>In Verilog 2001 and 1995, module declaration inside another module is not allowed, only modules can be instanciated. But in SystemVerilog, module declaration can be nested.</p> </blockquote> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:harvard</guid>
				<title>Pipeline 與哈佛架構</title>
				<link>http://ccckmit.wikidot.com/ve:harvard</link>
				<description>

&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.scribd.com/doc/16506954/MIPS-Pipeline-And-Harvard-Architecture&quot;&gt;http://www.scribd.com/doc/16506954/MIPS-Pipeline-And-Harvard-Architecture&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Harvard Architecture:Separate memory units for instructions and data (Harvard Architecture) are required because in agiven pipeline cycle two instructions may need to use memory (one for instruction fetch andanother for data read/write) as shown below&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 12 Jun 2012 07:16:01 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <ol> <li><a href="http://www.scribd.com/doc/16506954/MIPS-Pipeline-And-Harvard-Architecture">http://www.scribd.com/doc/16506954/MIPS-Pipeline-And-Harvard-Architecture</a> <ul> <li>Harvard Architecture:Separate memory units for instructions and data (Harvard Architecture) are required because in agiven pipeline cycle two instructions may need to use memory (one for instruction fetch andanother for data read/write) as shown below</li> </ul> </li> </ol> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://ccckmit.wikidot.com/ve:pipe</guid>
				<title>Pipe</title>
				<link>http://ccckmit.wikidot.com/ve:pipe</link>
				<description>

&lt;h1&gt;&lt;span&gt;Verilog 程式：pipe.v&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=296763&amp;amp;amp;size=small&amp;amp;amp;timestamp=1776238093&quot; alt=&quot;ccckmit&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=296763)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/ccckmit&quot;  &gt;ccckmit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 11 Jun 2012 23:48:10 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <h1><span>Verilog 程式：pipe.v</span></h1> <div class="code"> <pre><code>module pipe(input clock, reset, input [7:0] i, output reg [7:0] a, b); always @(posedge clock) begin a &lt;= i; b &lt;= a; end endmodule module main; reg clock, reset; reg [7:0] i; wire [7:0] a1, b1, a2, b2, a3, b3; pipe p1(clock, reset, i, a1, b1); pipe p2(clock, reset, a1, a2, b2); pipe p3(clock, reset, a2, a3, b3); initial begin clock = 0; reset = 1; i=0; #200 $finish; end always #10 begin clock=clock+1; $monitor(&quot;%-d:clock=%d i=%d a1=%d b1=%d a2=%d b2=%d a3=%d b3=%d&quot;, $stime, clock, i, a1, b1, a2, b2, a3, b3); end always #20 begin i = i + 1; end endmodule</code></pre></div> <h1><span>執行結果</span></h1> <div class="code"> <pre><code>D:\oc\pipe&gt;vvp pipe 10 :clock=1 i= 0 a1= 0 b1= x a2= x b2= x a3= x b3= x 20 :clock=0 i= 1 a1= 0 b1= x a2= x b2= x a3= x b3= x 30 :clock=1 i= 1 a1= 1 b1= 0 a2= 0 b2= x a3= x b3= x 40 :clock=0 i= 2 a1= 1 b1= 0 a2= 0 b2= x a3= x b3= x 50 :clock=1 i= 2 a1= 2 b1= 1 a2= 1 b2= 0 a3= 0 b3= x 60 :clock=0 i= 3 a1= 2 b1= 1 a2= 1 b2= 0 a3= 0 b3= x 70 :clock=1 i= 3 a1= 3 b1= 2 a2= 2 b2= 1 a3= 1 b3= 0 80 :clock=0 i= 4 a1= 3 b1= 2 a2= 2 b2= 1 a3= 1 b3= 0 90 :clock=1 i= 4 a1= 4 b1= 3 a2= 3 b2= 2 a3= 2 b3= 1 100 :clock=0 i= 5 a1= 4 b1= 3 a2= 3 b2= 2 a3= 2 b3= 1 110 :clock=1 i= 5 a1= 5 b1= 4 a2= 4 b2= 3 a3= 3 b3= 2 120 :clock=0 i= 6 a1= 5 b1= 4 a2= 4 b2= 3 a3= 3 b3= 2 130 :clock=1 i= 6 a1= 6 b1= 5 a2= 5 b2= 4 a3= 4 b3= 3 140 :clock=0 i= 7 a1= 6 b1= 5 a2= 5 b2= 4 a3= 4 b3= 3 150 :clock=1 i= 7 a1= 7 b1= 6 a2= 6 b2= 5 a3= 5 b3= 4 160 :clock=0 i= 8 a1= 7 b1= 6 a2= 6 b2= 5 a3= 5 b3= 4 170 :clock=1 i= 8 a1= 8 b1= 7 a2= 7 b2= 6 a3= 6 b3= 5 180 :clock=0 i= 9 a1= 8 b1= 7 a2= 7 b2= 6 a3= 6 b3= 5 190 :clock=1 i= 9 a1= 9 b1= 8 a2= 8 b2= 7 a3= 7 b3= 6 200 :clock=0 i= 10 a1= 9 b1= 8 a2= 8 b2= 7 a3= 7 b3= 6</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/ccckmit" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=296763&amp;amp;size=small&amp;amp;timestamp=1776238093" alt="ccckmit" style="background-image:url(http://www.wikidot.com/userkarma.php?u=296763)" /></a><a href="http://www.wikidot.com/user:info/ccckmit" >ccckmit</a></span></p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>