Sie sind auf Seite 1von 13

Owen Medina

Brian Pacia Lab 12


CS 152B Section A Beta Hardware
1 Theoretical Background

The central processing unit (CPU) of a computer is made up of three major components. Firstly, there is the
arithmetic and logic unit (ALU), a digital circuit that, as its name implies, performs all the arithmetic and logic
operations needed by the CPU and therefore, the computer as a whole. Next is the control unit that controls the
functioning of the different components of the CPU. It does this by taking an instruction from the memory unit and
then sending necessary inputs to the other components of the CPU based upon its interpretation of the instruction.
Lastly, the memory unit is the part of the CPU that stores intermediate results, data and instructions. For our
implementation of the CPU, the memory unit will be broken down into three parts: the register file, the instruction
memory and the data memory. Although the latter two actually comprise one unit, they are differentiated because
of their differences in use and thus were in a sense separated from one another and made to use separate caches.

Figure 1: Beta Processor Diagram

In the previous laboratory exercises, we were tasked to make the different components comprising the ALU
and in the most recent laboratory exercise, put all of these functioning units together. This merely leaves the

1
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

implementation of the control unit, memory unit and a special register called the program counter that determines
the next instruction to be fetched by the computer and the consolidation of all these components to complete our
CPU. It is important to note at this point that exceptions and certain ALU functions will not be implemented in
this CPU therefore certain adjustments in the implementation of our CPU were made.

To begin, the register file is a storage device composed of 32 different registers that stores 32 bits of data each.
The contents of registers 0 to 30 can be modified, however, register 31 will always hold a value of 0 regardless of
any reads and writes to the register file. The register file will have 2 5-bit read inputs that receives its data from
the output of the instruction memory. Given these independent read addresses, the register file outputs 2 separate
32-bit data to be used by the other components of the CPU. The register file also has 3 inputs for writing, namely
a 5-bit input for the address, a 32-bit input for the actual data and a write enable that determines whether a write
will happen. Lastly, a clock is required to be able to write data into the register file during the rising edge of the
clock.

As previously mentioned, the instruction memory and the data memory comprise one unit of memory albeit
their functional differences. This means that they will be using the same memory device during implementation.
This memory device will have 2 10-bit read inputs, one for the instruction memory address and one for the data
memory address. It also has 2 32-bit outputs, again, one for the instruction memory data and one for the data
memory data. For the data memory portion of the device, it can also be be written into. There is a 32-bit write
input for write data and a write enable that tells this portion of the device whether a read or a write will commence.
There will be no separate write address input as the address input for the data memory mentioned earlier will be
the one to determine where the new data will be written to. Similar to the register file, this will require a clock for
data to be written into the data memory during the rising edge of the clock.

For the program counter that holds the next instruction to be fetched and executed, it can either hold the next
instruction in the sequence which in this case is the previous PC added to 4 (4 since each location contains 4 bytes
and bsim traverses by byte), the jump address or the branch address (PC + 4 + 4*literal which is equivalent to
finding the corresponding location of the literal in memory). Since the program counter is essentially a register
holding the location of the next instruction, it suffices to use a 32-bit node to store what the program counter is
meant to point to and use a multiplexer to determine what it precisely needs to point to. Initially, however, an
inner reset function will override the result of this multiplexer so that the program counter is set to 0 before the
first rising edge of the clock. This then causes the instruction memory to fetch the very first instruction which then
sends this to multiple components including the control unit that then sends the appropriate signals to the other
components for them to begin doing what they are expected to do during the instruction.

Lastly, we have the control unit. As mentioned earlier, the control unit interprets the current instruction to be
able to send the appropriate control signals to the other components. The instruction can take on two forms. First
is the form that uses two registers as the operands. The opcode is what is interpreted by the control unit to set the
correct control signals. RA and RB represent the operands of the operation that will take place in the ALU while
RC is usually the register that holds the result of the entire instruction (except during a store where it provides the
data to be stored in the main memory).

OP CODE(6) rc(5) ra(5) rb(5) unused(11)

Figure 2: Two Register Operation Form

The second form is similar to the first except it uses only one register and a literal as the operands.

OP CODE(6) rc(5) ra(5) literal(16)

Figure 3: One Register One Literal Operation Form

2
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

The 7 control signals that the control unit outputs are PCSEL, RA2SEL, BSEL, WDSEL, ALUFN, Wr and
WERF. PCSEL tells the program counter which of its values to store in the program counter. RA2SEL selects
whether the second read address of the register file should be RB or RC. BSEL determines whether the second
operand for the ALU should be the second read data from the register file or the literal directly taken from the
instruction memory. WDSEL dictates what write data will be written into the register file. ALUFN tells the
ALU which of its arithmetic or logic operations to execute. Wr determines whether the data memory will be read
from or written into. Lastly, WERF tells the register file whether a write will also commence. In implementation,
the control unit is essentially a lookup table. Therefore, it will be a memory device that stores multiple 14-bit
sequences of control signals. Each sequence in the table will be mapped to the pair of inputs it corresponds to,
ergo, its address will be both of the inputs concatenated. The two inputs of the control unit are the operation code
from the instruction memory and the z variable from the register file that dictates whether the first register file
read data is a zero or a non-zero. Despite there being two inputs, the second input will only matter for branching
instructions therefore the control signals will mainly depend on which instruction (dictated by the opcode) is being
executed. Each set of values for the control signals determines one operation or class of operations in the datapath.
For instance, the ALU register-register operations has a PCSEL of 00 because no special instruction traversing
occurs. RA2SEL is 0 since we make use of the RB address in the instruction data. BSEL is 0 since we use the
second register data from the register file as the second operand in the ALU. WDSEL is 1 since we write the result
of the ALU to the register with address RC. ALUFN will be the corresponding ALU code for the instruction to be
executed. Wr is a 0 since we do not want to write to the data memory. WERF is 1 since we do want to write the
result into address RC in the register file.

In figure 3, we see all the corresponding control signal values for each operation that our CPU can execute. Note
that OP and OPC refer to the supported arithmetic and logic operations.

OP OP C LD ST BEQ BN E JM P
P CSEL 0 0 0 0 Z Z! 2
RA2SEL 0 ∗ ∗ 1 ∗ ∗ ∗
BSEL 0 1 1 1 ∗ ∗ ∗
W DSEL 1 1 2 ∗ 0 0 0
ALU F N OP OP ADDOP ADDOP ∗ ∗ ∗
Wr 0 0 0 1 0 0 0
W ERF 1 1 1 0 1 1 1

Figure 4: Control Unit Output Signals

In figure 4, we see the corresponding control unit input values for each operation that our CPU can execute.
Hence, if we take the specific ADD address in this table and find the sequence of bits corresponding to this address
in the control unit lookup table, we will find a similar sequence of bits as the example in the previous paragraph
(just replace ALUFN with the ALU code for addition).

000 001 010 011 100 101 110


011 LD ST JM P BEQ BN E
100 ADD SU B CM P EQ CM P LT CM P LE
101 AN D OR XOR SHL SHR SRA
110 ADDC SU BC CM P EQC CM P LT C CM P LEC
111 AN DC ORC XORC SHLC SHRC SRAC

Figure 5: Control Unit Inputs

3
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

2 Methodology

In order to create a beta hardware, we need to create the four new components, the control logic unit, the
program counter, the register file, and the main memory.

a.) Control Logic Unit

Firstly, we have the control logic unit (CLU) which is a lookup table that is used to set the control signals
all around the beta hardware and its other components, allowing the datapath to function. In order to make the
table, we make use of JSIM’s memory device with 1 read port and no write ports since we are just looking up
values. The inputs to the CLU include a 6-bit opcode or memory address and a 1-bit z. Both dictate which line to
get in the memory/lookup table however the value of the z bit (the leftmost bit) is only important for branching
instructions. Hence, for non-branching instructions it is a DON’T CARE value. This, then, results in a duplication
of the non-branching instructions since z can either be 0 or 1 and the instruction would still be the same. Each line
then contains the appropriate values for the control signals in the order below and following the sample CLU table
above.

Code 1: Control Logic Unit Code


1 // C o n t r o l L o g i c Unit
2 . s u b c k t c l u addr [ 5 : 0 ] z a l u f n [ 5 : 0 ] p c s e l [ 1 : 0 ] r a 2 s e l b s e l w d s e l [ 1 : 0 ] wr w e r f
3 Xctl
4 + vdd 0 0 addr [ 5 : 0 ] z // ( r e a d )
5 + ALUFN [ 5 : 0 ] p c s e l [ 1 : 0 ] r a 2 s e l b s e l w d s e l [ 1 : 0 ] wr w e r f // output
6 + $memory width=14 n l o c a t i o n s =128 c o n t e n t s =(
7 + 0 b00000000000000 //DONT CARE
8 + 0 b00000000000000 //DONT CARE
9 + 0 b00000000000000 //DONT CARE
10 + 0 b00000000000000 //DONT CARE
11 + 0 b00000000000000 //DONT CARE
12 + 0 b00000000000000 //DONT CARE
13
14 + 0 b00000000000000 //DONT CARE
15 + 0 b00000000000000 //DONT CARE
16 + 0 b00000000000000 //DONT CARE
17 + 0 b00000000000000 //DONT CARE
18 + 0 b00000000000000 //DONT CARE
19 + 0 b00000000000000 //DONT CARE
20
21 + 0 b00000000000000 //DONT CARE
22 + 0 b00000000000000 //DONT CARE
23 + 0 b00000000000000 //DONT CARE
24 + 0 b00000000000000 //DONT CARE
25 + 0 b00000000000000 //DONT CARE
26 + 0 b00000000000000 //DONT CARE
27
28 + 0 b00000000000000 //DONT CARE
29 + 0 b00000000000000 //DONT CARE
30 + 0 b00000000000000 //DONT CARE
31 + 0 b00000000000000 //DONT CARE
32 + 0 b00000000000000 //DONT CARE
33 + 0 b00000000000000 //DONT CARE 23
34
35 + 0 b00000000000000 //DONT CARE
36 + 0 b00000000000000 //DONT CARE

4
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

37 + 0 b00000000000000 //DONT CARE


38 + 0 b00000000000000 //DONT CARE
39 + 0 b00000000000000 //DONT CARE
40 + 0 b00000000000000 //DONT CARE
41
42 + 0 b00000000000000 //DONT CARE
43 + 0 b00000000000000 //DONT CARE
44 + 0 b00000000000000 //DONT CARE
45 + 0 b00000000000000 //DONT CARE
46 + 0 b00000000000000 //DONT CARE
47 + 0 b00000000000000 //DONT CARE
48
49 + 0 b00000000000000 //DONT CARE
50 + 0 b00000000000000 //DONT CARE
51 + 0 b00000000000000 //DONT CARE
52 + 0 b00000000000000 //DONT CARE
53 + 0 b00000000000000 //DONT CARE
54 + 0 b00000000000000 //DONT CARE
55
56 + 0 b00000000000000 //DONT CARE
57 + 0 b00000000000000 //DONT CARE
58 + 0 b00000000000000 //DONT CARE
59 + 0 b00000000000000 //DONT CARE
60 + 0 b00000000000000 //DONT CARE
61 + 0 b00000000000000 //DONT CARE 47
62
63 + 0 b00000000011001 //LD 48
64 + 0 b00000000011001 //LD 49
65 + 0 b00000000110010 //ST 50
66 + 0 b00000000110010 //ST 51
67 + 0 b00000000000000 //DONT CARE 52
68 + 0 b00000000000000 //DONT CARE 53
69 + 0 b00000010000001 //JMP 54
70 + 0 b00000010000001 //JMP 55
71 + 0 b00000000000000 //DONT CARE 56
72 + 0 b00000000000000 //DONT CARE 57
73 + 0 b00000000000001 //BEQ 58
74 + 0 b00000001000001 //BEQ 59
75 + 0 b00000001000001 //BNE 60
76 + 0 b00000000000001 //BNE 61
77 + 0 b00000000000000 //DONT CARE 62
78 + 0 b00000000000000 //DONT CARE 63
79 + 0 b00000000000101 //ADD 64
80 + 0 b00000000000101 //ADD 65
81 + 0 b00000100000101 //SUB 66
82 + 0 b00000100000101 //SUB 67
83 + 0 b00000000000000 //DONT CARE 68
84 + 0 b00000000000000 //DONT CARE 69
85 + 0 b00000000000000 //DONT CARE 70
86 + 0 b00000000000000 //DONT CARE 71
87 + 0 b11001100000101 //CMPEQ 72
88 + 0 b11001100000101 //CMPEQ 73
89 + 0 b11010100000101 //CMPLT 74
90 + 0 b11010100000101 //CMPLT 75

5
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

91 + 0 b11011100000101 // CMPLE 76
92 + 0 b11011100000101 // CMPLE 77
93 + 0 b00000000000000 // DONT CARE 78
94 + 0 b00000000000000 // DONT CARE 79
95
96 + 0 b01100000000101 // AND 80
97 + 0 b01100000000101 // AND 81
98 + 0 b01111000000101 // OR 82
99 + 0 b01111000000101 // OR 83
100 + 0 b01011000000101 // XOR 84
101 + 0 b01011000000101 // XOR 85
102 + 0 b00000000000000 // DONT CARE 86
103 + 0 b00000000000000 // DONT CARE 87
104 + 0 b10000000000101 // SHL 88
105 + 0 b10000000000101 // SHL 89
106 + 0 b10000100000101 // SHR 90
107 + 0 b10000100000101 // SHR 91
108 + 0 b10001100000101 // SRA 92
109 + 0 b10001100000101 // SRA 93
110 + 0 b00000000000000 // DONT CARE 94
111 + 0 b00000000000000 // DONT CARE 95
112 + 0 b00000000010101 // ADDC 96
113 + 0 b00000000010101 // ADDC 97
114 + 0 b00000100010101 // SUBC 98
115 + 0 b00000100010101 // SUBC 99
116 + 0 b00000000000000 // DONT CARE 100
117 + 0 b00000000000000 // DONT CARE 101
118 + 0 b00000000000000 // DONT CARE 102
119 + 0 b00000000000000 // DONT CARE 103
120 + 0 b11001100010101 // CMPEQC 104
121 + 0 b11001100010101 // CMPEQC 105
122 + 0 b11010100010101 // CMPLTC 106
123 + 0 b11010100010101 // CMPLTC 107
124 + 0 b11011100010101 // CMPLEC 108
125 + 0 b11011100010101 // CMPLEC 108
126 + 0 b00000000000000 // DONT CARE 110
127 + 0 b00000000000000 // DONT CARE 111
128
129 + 0 b01100000010101 // ANDC 112
130 + 0 b01100000010101 // ANDC 113
131 + 0 b01111000010101 // ORC 114
132 + 0 b01111000010101 // ORC 115
133 + 0 b01011000010101 // XORC 116
134 + 0 b01011000010101 // XORC 117
135 + 0 b00000000000000 // DONT CARE 118
136 + 0 b00000000000000 // DONT CARE 119
137 + 0 b10000000010101 // SHLC 120
138 + 0 b10000000010101 // SHLC 121
139 + 0 b10000100010101 // SHRC 122
140 + 0 b10000100010101 // SHRC 123
141 + 0 b10001100010101 // SRAC 124
142 + 0 b10001100010101 // SRAC 125
143 + 0 b00000000000000 // DONT CARE 126
144 + 0 b00000000000000 // DONT CARE 127

6
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

145 + )
146
147 . ends

b.) Program Counter

The program counter as mentioned before is a register that holds the next instruction to be fetched. Its inputs
include a reset value, the clock, PCSEL, JT, the input address (current value of the counter), a 32 bit node for the
next value (PC + 4), and the constant C for branches. For simply getting the next instruction, we have to add 4
to the current value in the register and this is done using the ripple-carry adder in the ALU. If we want to branch,
we have to make use of adding an additional value which is the offset (4 x C) where C is the literal for the next
location in the memory. Since there is no multiplier implemented in the ALU, we make use of shifting to the left
twice in order to multiply by 4. The constant is also just 16 bits so we have to use sign extension and pad bits 16 to
31 with bit 15, which is the sign of the constant. Lastly, we have the jump case, which is simply the actual location
to jump to and is one of the inputs to the counter. There are three cases described (next, jump, branch) and this
is handled by implementing a multiplexer that outputs the correct value depending on the value of PCSEL (00 =
PC + 4, 01 = PC + 4 + 4C, 10 = Jump, 11 = DON’T CARE).

Since it is a register, it is implemented with a dreg component. The reset value is handled using a mux2 and
dreg to handle the beginning as initially, the counter must be set to 0 before the first rising edge of the clock. After
that, the input address will now contain the instructions to be fetched from the memory.

Code 2: Program Counter Code


1 //PC
2 . subckt pctr r e s e t c l k p c s e l [ 1 : 0 ] j t [ 3 1 : 0 ] i a [ 3 1 : 0 ] i a p f o u r [ 3 1 : 0 ] const [ 3 1 : 0 ]
3 // i n c r e m e n t pc by 4 (PC + 4 )
4 Xadd4 i a [ 3 1 : 0 ] 0#29 vdd 0#2 c o u t 1 [ 3 1 : 0 ] i a p f o u r [ 3 1 : 0 ] 0#32 r i p p l e A d d e r C k t
5 // i n c r e m e n t with 4C ( s o s i g n extend and s h i f t t o t h e l e f t by 2 t o mul by 4 )
6 Xadd4C i a p f o u r [ 3 1 : 0 ] c o n s t 3 1 #14 c o n s t [ 1 5 : 0 ] 0#2 c o u t 2 [ 3 1 : 0 ]
7 + i a p c o n s t [ 3 1 : 0 ] 0#32 r i p p l e A d d e r C k t
8 // M u l t i p l e x e r 4 t o know which PC t o s e l e c t
9 X p c s e l p c s e l 0 #32 p c s e l 1 #32 i a p f o u r [ 3 1 : 0 ] i a p c o n s t [ 3 1 : 0 ] j t [ 3 1 : 0 ]
10 + 0#32 pc [ 3 1 : 0 ] mux4
11 // Reset
12 X r e s e t r e s e t #32 pc [ 3 1 : 0 ] 0#32 r e s e t R e s [ 3 1 : 0 ] mux2
13 Xdreg r e s e t R e s [ 3 1 : 0 ] c l k #32 i a [ 3 1 : 0 ] d r e g
14 . ends

c.) Register File

Next up is the Register File. We again make use of JSIM’s memory device as it contains the value of each
register from 0 to 30. The inputs include a clock, the control signals WERF and RA2SEL, the register addresses
for Ra, Rb, and Rc, the data to be written if ever, and two 32-bit nodes for the read data.

It has 2 read ports for reading from Ra and one of Rb and Rc. In order to know which register to read from
for the second port, we make use of RA2SEL and a 2-way multiplexer. There is also one write port to Rc during a
case when WERF is 1 and enables it. We then create 31 32-bit registers from R0 to R30. Take note that we only
make 31 because R31 is a special register than only contains 0 and is handled separately.

Code 3: Register File Code


1 // R e g i s t e r f i l e
2 . s u b c k t r f c l k w e r f r a 2 s e l r a [ 4 : 0 ] rb [ 4 : 0 ] r c [ 4 : 0 ] wd [ 3 1 : 0 ] ra1d [ 3 1 : 0 ] ra2d [ 3 1 : 0 ]
3 // u s e mux t o check i f u s i n g rb o r r c
4 Xrborrc r a 2 s e l #5 rb [ 4 : 0 ] r c [ 4 : 0 ] ratwo [ 4 : 0 ] mux2

7
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

5
6 Xregfile
7 + vdd 0 0 r a [ 4 : 0 ] adata [ 3 1 : 0 ] // r e a d p o r t f o r r a
8 + vdd 0 0 ratwo [ 4 : 0 ] bcdata [ 3 1 : 0 ] // r e a d p o r t f o r rb o r r c
9 + 0 c l k w e r f r c [ 4 : 0 ] wd [ 3 1 : 0 ] // w r i t e p o r t t o r c
10 + $memory width = 32 n l o c a t i o n s = 31
11 + contents = ( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 )

We have to check whether any of the registers are the 31st. In binary 31 is 0b11111 or just 1s hence we just
AND all the bits of the register address with vdd (1). We then make use of a multiplexer to direct the data. If it
is indeed R31, we simply output 0. Otherwise just output the actual data of the register.
1 // I f a d d r e s s i s 3 1 , send 0
2 // r a and rb a r e 31 i f a l l 5 b i t s a r e 1
3 Xrega r a [ 3 : 0 ] vdd r a a and4
4 Xregaa r a 4 r a a r a a a and2
5
6 Xregb ratwo [ 3 : 0 ] vdd rbb and4
7 Xregbb ratwo4 rbb rbbb and2
8
9 // output 0 i f r 3 1
10 Xouta r a a a#32 adata [ 3 1 : 0 ] 0#32 ra1d [ 3 1 : 0 ] mux2
11 Xoutb rbbb#32 bcdata [ 3 1 : 0 ] 0#32 ra2d [ 3 1 : 0 ] mux2
12
13 . ends

d.) Main Memory

Finally, we have to create the main memory. As said before the main memory can be broken down into the
instruction memory and the data memory for easier understanding and usage. With memory in its name, we again
make use of JSIM’s memory device.

The inputs include a clock, the control signal WR, the instruction address, the memory address, a 32-bit node
to carry the memory data, and a 32-bit node for data to be written if needed. There are 3 ports. 2 read ports
for the instruction and data memory and 1 write port for the data memory. For this lab, we are to create 1024
locations for 32-bit memory lines. We also make use of a bin or binary file to load the memory contents (will be
explained later)

NOTE: Each line is a multiple of 4. Since there are 1024 locations we need 10 bits for the location. Each
memory address, however, is a multiple of 4 so instead of ia[9:0] and ma[9:0], we use ia[11:2] and ma[11:2] to ignore
the last two bits.
Code 4: Main Memory Code
1 //Memory
2 . s u b c k t memory c l k wr i a [ 1 1 : 2 ] i d [ 3 1 : 0 ] ma [ 1 1 : 2 ] mrd [ 3 1 : 0 ] mwd [ 3 1 : 0 ]
3 Xmem
4 + vdd 0 0 i a [ 1 1 : 2 ] i d [ 3 1 : 0 ] // ( r e a d ) i n s t r u c t i o n mem
5 + vdd 0 0 ma [ 1 1 : 2 ] mrd [ 3 1 : 0 ] // ( r e a d ) program / data mem ( LDs )
6 + 0 c l k wr ma [ 1 1 : 2 ] mwd [ 3 1 : 0 ] // ( w r i t e ) program data mem ( STs )
7 + $memory width=32 n l o c a t i o n s =1024
8 + f i l e = ” Lab11 Medina Pacia . b i n ”
9 . ends

e.) Beta Processor

8
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

Now that we have all of the components, we can assemble the processor and put everything together. We
instantiate the four components above as well as the ALU. For components that have writing capabilities, a clock
must be made to ensure that it occurs during the first rising edge of the clock. A 4-way multiplexer at the end is
implemented to know which data is to be written to the Register File.

Code 5: Beta Processor Code


1 // Beta p r o c e s s o r
2 . s u b c k t cpu c l k r e s e t i a [ 3 1 : 0 ] i d [ 3 1 : 0 ] mrd [ 3 1 : 0 ] mwd [ 3 1 : 0 ]
3 //Make PC
4 Xpc r e s e t c l k p c s e l [ 1 : 0 ] j t [ 3 1 : 0 ] i a [ 3 1 : 0 ] i a p f o u r [ 3 1 : 0 ] i d [ 3 1 : 0 ] p c t r
5
6 //Make memory with wr = 0 b e f o r e f i r s t r i s i n g edge o f c l o c k
7 Wreset resetW n r z ( 0 , 5 , 4 0 ns , 0 ns , 0 . 1 ns , 0 . 1 ns ) 0 1
8 Xwrreset resetW wr wrr and2
9 Xmem c l k wrr i a [ 1 1 : 2 ] i d [ 3 1 : 0 ] ma [ 1 1 : 2 ] mrd [ 3 1 : 0 ] mwd [ 3 1 : 0 ] memory
10
11 //Make r e g i s t e r f i l e
12 X w e r f r e s e t resetW w e r f w e r f f and2
13 Xrf c l k w e r f f r a 2 s e l i d [ 2 0 : 1 6 ] i d [ 1 5 : 1 1 ] i d [ 2 5 : 2 1 ] wd [ 3 1 : 0 ]
14 + ra1d [ 3 1 : 0 ] ra2d [ 3 1 : 0 ] r f
15
16 //Make CLU
17 Xclu i d [ 3 1 : 2 6 ] z a l u f n [ 5 : 0 ] p c s e l [ 1 : 0 ] r a 2 s e l b s e l w d s e l [ 1 : 0 ] wr w e r f c l u
18
19 //ALU
20 Xzero ra1d [ 3 1 : 0 ] z zeroCkt
21 Xconn1 ra1d [ 3 1 : 0 ] j t [ 3 1 : 0 ] conn
22 Xconn2 ra2d [ 3 1 : 0 ] mwd [ 3 1 : 0 ] conn
23 Xb b s e l #32 ra2d [ 3 1 : 0 ] i d 1 5 #16 i d [ 1 5 : 0 ] b [ 3 1 : 0 ] mux2
24 Xalu ra1d [ 3 1 : 0 ] b [ 3 1 : 0 ] a l u f n [ 5 : 0 ] r e s [ 3 1 : 0 ] a l u c k t
25
26 // Connects and w d s e l
27 Xc r e s [ 3 1 : 0 ] ma [ 3 1 : 0 ] conn
28 Xwdsel w d s e l 0#32 w d s e l 1#32 i a p f o u r [ 3 1 : 0 ] r e s [ 3 1 : 0 ] mrd [ 3 1 : 0 ] 0#32 wd [ 3 1 : 0 ] mux4
29
30 . ends

Notice that the 2nd to the last line makes use of a connect function that was made so that the output of the
ALU also goes to the data memory address node.

Code 6: Connect Subcircuit Code


1 . s u b c k t conn a b
2 . connect a b
3 . ends

f.) Testing

In order to test the beta processor, let us load some assembly programs and see if the final contents of the
memory are correct. As mentioned before, JSIM can load the contents to the memory through the bin or binary
file. This is the file produced by BSIM where we can code in assembly language. Below is as sample BSIM code
used in Lab 9 for getting the first N Fibonacci numbers.

Code 7: BSIM Fibonacci Code

9
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

1 . i n c l u d e b e t a . uasm
2
3 fib :
4 LD(N, R1)
5 CMOVE( 2 , R0)
6 CMOVE(N, R9)
7 CMOVE( 1 , R2)
8 ADDC(R9 , 4 , R9)
9 ST(R2 , 0 , R9)
10 CMOVE( 1 , R3)
11 ADDC(R9 , 4 , R9)
12 ST(R3 , 0 , R9)
13
14 loop :
15 CMPLT(R0 , R1 , R5)
16 BF(R5 , done )
17 ADD(R2 , R3 , R4)
18 ADDC(R9 , 4 , R9)
19 ST(R4 , 0 , R9)
20 MOVE(R3 , R2)
21 MOVE(R4 , R3)
22 ADDC(R0 , 1 , R0)
23 BR( l o o p )
24
25 done :
26 HALT( )
27
28 . = 0 x100
29 N: LONG( 1 0 )
30
31 . = 0 x400

Below is a screenshot of the final contents of the main memory after running the code above in BSIM.

10
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

Figure 6: BSIM Results

3 Results

To fully test the beta processor, we now check the JSIM results with the expected results above. Performing a
gate-level simulation, we get the following waveforms and outputs.

Below is a screenshot of the final contents of the main memory after running the code above in BSIM.

11
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

Figure 7: Final state of the memory (from 0x0)

We can see here that the step-by-step execution of the instructions (betaop(id[31:26])) match the BSIM assembly
code above.

Now let us check if the processor truly ran the code and the main memory contains the correct values.

12
Owen Medina
Brian Pacia Lab 12
CS 152B Section A Beta Hardware

Figure 8: Final state of the memory (from 0x100)

Again, we can see that JSIM contains the correct output as the first 10 Fibonacci numbers are shown.

4 Analysis and Discussion

Running the Fibonnaci program on BSim and on the Beta CPU we created in JSim, we see that the memory
addresses contain the same data. With this, we can verify the logic and the functionality of the CPU.

Additionally, running the program on our CPU in JSim shows that the CPU has 1393 gates and has a circuit
size of 309904 microns2 . This is composed of all the components of the ALU, the register file, the program counter,
the control logic unit and the main memory (instruction and data memory).

5 Conclusion

In summary, we were able to successfully implement a Beta Processer using JSIM. Through the help of com-
ponents from previous labs, namely the ALU and BSIM assembly code, as well as creating the other necessary
components for this lab, the processor was built. BSIM was used to generate the bin file and JSIM was used to
connect the components and necessary circuitry. The results from both JSIM and BSIM verify its correctnes and
thus comply with the requirements and objectives of the final lab.

13

Das könnte Ihnen auch gefallen