-
Notifications
You must be signed in to change notification settings - Fork 0
/
457375898.html
123 lines (109 loc) · 24.8 KB
/
457375898.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<!DOCTYPE html>
<html>
<head>
<title>Di Luo : Di Luo's CS232 Project 7</title>
<link rel="stylesheet" href="styles/site.css" type="text/css" />
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body class="theme-default aui-theme-default">
<div id="page">
<div id="main" class="aui-page-panel">
<div id="main-header">
<div id="breadcrumb-section">
<ol id="breadcrumbs">
<li class="first">
<span><a href="index.html">Di Luo</a></span>
</li>
<li>
<span><a href="413631037.html">Di Luo’s Home</a></span>
</li>
<li>
<span><a href="474513832.html">Di Luo's CS232</a></span>
</li>
</ol>
</div>
<h1 id="title-heading" class="pagetitle">
<span id="title-text">
Di Luo : Di Luo's CS232 Project 7
</span>
</h1>
</div>
<div id="content" class="view">
<div class="page-metadata">
Created by <span class='author'> Di Luo</span>, last modified on Nov 11, 2019
</div>
<div id="main-content" class="wiki-content group">
<p><u><strong>Summary</strong></u></p><p><span style="color: rgb(34,51,68);">The purpose of this project is to build a simple CPU that integrates all the necessary aspects of a general-purpose computer. The CPU was implemented as a Moore state machine, which is in fetch-execute style. The state machine has fetch state and many stages of execution. In the cycle of state machine, the CPU reads instructions stored in Read-Only Memory (ROM) and executes them.</span></p><p> </p><p><u><strong>Main Task</strong></u></p><p>In the main task, the CPU was implemented, which has the design shown as follow. The top-level design was stored in cpu.vhd.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image confluence-external-resource" draggable="false" width="500" src="http://cs.colby.edu/courses/F19/cs232-labs/labs/lab07/cpudesign.png" data-image-src="http://cs.colby.edu/courses/F19/cs232-labs/labs/lab07/cpudesign.png"></span></p><p>The instructions were stored in ProgramROM the memory was stored in DataRAM. There are 5 registers RA, RB, RC, RD, and RE for general purposes. PC is the program counter that specifies which instruction to be executed. IR is the instruction register that reads the instruction from the address in ROM indicated by PC. ALU has two inputs ALUinputA (srcA) and ALUinputB (srcB) and it conducts operations such as adding, subtracting, or, xor, shift, and rotate on both or one of the inputs, then outputs from ALUoutput (DEST). CR is the flags of ALU. MAR, MBR, and stack pointer SP handles the memory. The input port (iport) is the input of the CPU and the output port (oport) is the output of the CPU.</p><p> </p><p>The state machine starts with start state, then it goes to fetch state and loads instruction from ROM. The CPU starts execution state with execute-setup, in which the 16-bit instruction is divided and the source and the destination are set up according to the opcode. MAR and MBR receives data and starts reading from RAM. Jumps are executed in this stage. In executeALU state, the operations are completed and the results are ready for the next state. In write state, the results are written to the indicated destination, register or memory, and then the state machine goes back to fetch state. Extra states are used for specific instructions that need to read from RAM, which takes a few more clock cycles to wait for the output from RAM.</p><p> </p><p>The project started with implementing ALU, which conducts the specific operation indicated by opcode on two/one source(s) and outputs the result. It also renews the flags according to the result value, when the value is 0, negative, overflows, or has a carry out. The test result is shown below, which is identical to the one in project instruction, proving the validity of ALU.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277544.png" data-image-src="attachments/457375898/457277544.png" data-unresolved-comment-count="0" data-linked-resource-id="457277544" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="alutest.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></p><p> </p><p>The next part was implemented the state machine of the CPU. To test the CPU, three tests were run through as follow.</p><p>The first test move immediate values to registers and conducts operations with ALU between them, then jumps back to the beginning. The initial contents of ROM and RAM are shown below, in which RAM was not touched in this test. The following tests use the same initial content of RAM, which would not influence the result since the following tests rewrite at each position for building the stack.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277545.png" data-image-src="attachments/457375898/457277545.png" data-unresolved-comment-count="0" data-linked-resource-id="457277545" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="programmif.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(program.mif)</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277553.png" data-image-src="attachments/457375898/457277553.png" data-unresolved-comment-count="0" data-linked-resource-id="457277553" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 8.04.04 AM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(data.mif)</p><p> </p><p>The testing result below shows the correctness. Before 60ns, RA=RB=RC=8, RD=1, RE=2. Then RA = RD + RE = 2+1 = 3, RB=RD-RE=1-2=-1, which corresponds to the testing result.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277543.png" data-image-src="attachments/457375898/457277543.png" data-unresolved-comment-count="0" data-linked-resource-id="457277543" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="cpubench.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(Test on program.mif)</p><p> </p><p>The second test is testpush.mif that tests push, in which 1, 2, 3 were pushed to stack in steps at the beginning. Then 0, 1 were assigned to RD and RE, RA was rewritten as 3, then 3, 2, 1 were popped from stack stored in RB, RA, RC. The test result corresponds to the steps so that the push functionality is proved to be working correctly.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277546.png" data-image-src="attachments/457375898/457277546.png" data-unresolved-comment-count="0" data-linked-resource-id="457277546" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="testpushmif.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(testpush.mif)</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277547.png" data-image-src="attachments/457375898/457277547.png" data-unresolved-comment-count="0" data-linked-resource-id="457277547" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="testpush.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(Test on testpush.mif)</p><p> </p><p>The third test is testcall.mif that tests a function call. 3 was moved to RA and 4 was moved to RB, then 3, 3, and 4 were put on the stack. Then the CPU calls the function is address 0B, conducting instructions until address 16, and return to execute instruction at address 06 until 0A. The detailed description is shown below in the comments next to instructions. The testing result proves the validity of the call functionality.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277548.png" data-image-src="attachments/457375898/457277548.png" data-unresolved-comment-count="0" data-linked-resource-id="457277548" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="testcallmif.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(testcall.mif)</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277549.png" data-image-src="attachments/457375898/457277549.png" data-unresolved-comment-count="0" data-linked-resource-id="457277549" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="testcall.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(Test on testcall.mif)</p><p> </p><p>Eventually I wrote a program that computes the first 10 values of Fibonacci numbers with for loop. RD is the loop variable that decreases by 1 in each loop, going from 10 to 0. In each loop, the two previous Fibonacci numbers stored in RB and RA were replaced RA+RB and RB, the result is put in RC and then to the CPU output. The output of the test result shows the Fibonacci numbers 0x0000=0, 0x0001=1, 0x0001=1, 0x0002=2, 0x0003=3, 0x0005=5, 0x0008=8, 0x000D=13, 0x0015=21, 0x0022=34, 0x0037=55. If excluding 0 then 55 would be the 10th Fibonacci number, otherwise 34 would be the 10th Fibonacci number. The test result below shows the correctness.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277550.png" data-image-src="attachments/457375898/457277550.png" data-unresolved-comment-count="0" data-linked-resource-id="457277550" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="fibonnacimif.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(fibonacci.mif)</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277551.png" data-image-src="attachments/457375898/457277551.png" data-unresolved-comment-count="0" data-linked-resource-id="457277551" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="fibonnaciGTK.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span>(Test on fibonacci.mif)</p><p> </p><p><u><strong>Extension</strong></u></p><p><strong>Extension 1</strong>: Simplifying cpu.vhd</p><p>I simplified cpu.vhd by combining the cases with the same codes together. For example, in exeSetup state, some ALU operations (add, subtract, and, or, xor) have very similar code in their cases and the only difference is the 3-bit ALU opcode, which was the same case for shift operation and rotate operation. So I merged these case together and directly connected ALU opcode with IR(14 downto 12). The changes are shown below.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277614.png" data-image-src="attachments/457375898/457277614.png" data-unresolved-comment-count="0" data-linked-resource-id="457277614" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 4.45.13 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277615.png" data-image-src="attachments/457375898/457277615.png" data-unresolved-comment-count="0" data-linked-resource-id="457277615" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 4.47.16 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></p><p>In exeWrite state, I did the same things for these ALU operations. By doing so, the number of lines in cpu.vhd dropped significantly. Originally cpu.vhd has 826 lines, which is shown below.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277611.png" data-image-src="attachments/457375898/457277611.png" data-unresolved-comment-count="0" data-linked-resource-id="457277611" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 4.37.10 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></p><p>After simplifying, the number of lines dropped to 500s, which made the file more readable.</p><p><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277613.png" data-image-src="attachments/457375898/457277613.png" data-unresolved-comment-count="0" data-linked-resource-id="457277613" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 4.49.38 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></p><p> </p><p><strong>Extension 2</strong>: <span style="color: rgb(34,51,68);">Download the CPU to the board and demonstrate it works properly with the Fibonacci program.</span></p><p><span style="color: rgb(34,51,68);">I tested the CPU program with the board. The slow clock is added to the CPU and four 7-segment displays units are added as outputs, which are connected to parts of the output bits respectively. The reset button is the rightmost pushbutton. The testing video shows the testing process with fibonacci.mif.</span></p><p><span style="color: rgb(34,51,68);"><div class="embeddedObject" >
<video src="/download/attachments/457375898/IMG_2311.MOV" height="380" width="480" controls>
Your browser does not support the HTML5 video element
</video>
</div>
<br/></span></p><p> </p><p><strong>Extension 3</strong>: <span style="color: rgb(34,51,68);">unsigned multiply program</span></p><p>I wrote an <span style="color: rgb(34,51,68);">unsigned multiply program in multiply.mif, which calculated 4*3 by adding three 4s together with a for loop. RA=4 is the base number and RB=3 is the multiplier and also the loop variable. RE is the accumulator and the value to be returned. The test result below shows the correctness, in which 0x000C=12 is returned from the output.</span></p><p><span style="color: rgb(34,51,68);"><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="301" src="attachments/457375898/457277700.png" data-image-src="attachments/457375898/457277700.png" data-unresolved-comment-count="0" data-linked-resource-id="457277700" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 9.22.55 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span></span></p><p><span style="color: rgb(34,51,68);"><span class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img class="confluence-embedded-image" draggable="false" width="500" src="attachments/457375898/457277701.png" data-image-src="attachments/457375898/457277701.png" data-unresolved-comment-count="0" data-linked-resource-id="457277701" data-linked-resource-version="1" data-linked-resource-type="attachment" data-linked-resource-default-alias="Screen Shot 2019-11-11 at 9.17.57 PM.png" data-base-url="https://wiki.colby.edu" data-linked-resource-content-type="image/png" data-linked-resource-container-id="457375898" data-linked-resource-container-version="13"></span><span style="color: rgb(51,51,51);"> </span></span></p><p> </p><p><u><strong>Acknowledgments</strong></u></p><p>TA: Mike Zheng</p><p>Student: Yixuan Qiu, Zixuan Wang, Qianhan Gao</p><p> </p>
</div>
<div class="pageSection group">
<div class="pageSectionHeader">
<h2 id="attachments" class="pageSectionTitle">Attachments:</h2>
</div>
<div class="greybox" align="left">
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277543.png">cpubench.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277544.png">alutest.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277545.png">programmif.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277546.png">testpushmif.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277547.png">testpush.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277548.png">testcallmif.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277549.png">testcall.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277550.png">fibonnacimif.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277551.png">fibonnaciGTK.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277553.png">Screen Shot 2019-11-11 at 8.04.04 AM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277611.png">Screen Shot 2019-11-11 at 4.37.10 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277613.png">Screen Shot 2019-11-11 at 4.49.38 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277614.png">Screen Shot 2019-11-11 at 4.45.13 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277615.png">Screen Shot 2019-11-11 at 4.47.16 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277700.png">Screen Shot 2019-11-11 at 9.22.55 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277701.png">Screen Shot 2019-11-11 at 9.17.57 PM.png</a> (image/png)
<br/>
<img src="images/icons/bullet_blue.gif" height="8" width="8" alt=""/>
<a href="attachments/457375898/457277728.mov">IMG_2311.MOV</a> (video/quicktime)
<br/>
</div>
</div>
</div> </div>
<div id="footer" role="contentinfo">
<section class="footer-body">
<p>Document generated by Confluence on Aug 29, 2022 09:29</p>
<div id="footer-logo"><a href="http://www.atlassian.com/">Atlassian</a></div>
</section>
</div>
</div> </body>
</html>