CS计算机代考程序代写 Project 2 Details

Project 2 Details
Check out the ISA here.
You may use any built-in Logisim component to build your CPU! You don’t have to build the ALU out of 500 gates or the registers out of flip flops. Explore the stuff in the component pane… many, many things are done for you!
Just don’t use any circuits someone else made, because that’s cheating, duh. (You can look at my example circuits, but your versions will be quite different.)
Here are the main parts of the CPU, ordered vaguely by increasing difficulty:
1. Thedisplayunit
2. TheprogramROManddataRAM 3. TheALU
4. Theregisterfile
5. Theprogramcountercontrol
6. Theinterconnect
7. Thecontrol
1. The display unit
On your main circuit, place four Input/Output > Hex Digit Display components next to each other. If you change the colors, please make sure it’s easy to read!
Now, to control those, make a display unit component like this:
INPUTS:
1-bit Clock
(that means this is a sequential circuit –
it’ll have a register inside!) 1-bit Write Enable
16-bit Data OUTPUTS:
4 x 4-bit Digit values
do not put the digit displays inside this
component! BEHAVIOR:
It holds a 16-bit value in a register
It outputs that stored 16-bit value, split into groups of 4 bits
If Write Enable = 0 , the register should not change.
If Write Enable = 1 , the register should store the value of the Data input.
You can test this component without any other circuitry built. Plop down the display component, wire it up to the digits, and put some inputs next to it. Poke the inputs, clock it, see if it works.
2. The program ROM and data RAM On your main circuit, place a Memory > ROM
component with these settings:
Address Bit Width: 8 Data Bit Width: 20
That will give you 256 20-bit instructions.
The ROM is super simple to use: put address (value of PC register) into the left side, get instructions out the right side.
Then place a Memory > RAM component with these settings:
Address Bit Width: 16
Data Bit Width: 16
Data Interface: Separate load and store ports
That last option is important.
This will give you 65,536 words of RAM. This is a word- addressable machine – each memory address refers to 2 bytes of data.
The address and data to store go in the left side, the clock in the bottom (the triangle), and the data to load comes out the right side.
You can ignore the sel , ld , and clr inputs! The str input is the memory’s write enable signal.
Most instructions don’t write to the memory, so you’ll have to hook something up to it.
And that’s it for those… for now!
3. The ALU
The ALU is a combinational circuit. Remember, you’re allowed to use any of the built-in Logisim components – adders, subtractors, shifters, bit extenders etc.
Make an ALU component like this: INPUTS:
16-bit A
16-bit B
3-bit Operation
There are 7 possible values this can take. It’s up to you which binary value means which operation, but write it down somewhere! You’ll need it later.
OUTPUTS:
16-bit Result
BEHAVIOR:
The Result output depends on what
Operation is chosen: Add: A+B
Subtract A – B
AND: A&B
OR: A | B
NOT: ~A ( B is ignored)
Shift Left: A << B[3:0] (see below) Shift Right: A >> B[3:0] (logical, not arithmetic)
Notes:
the syntax B[3:0] means “bits 3, 2, 1, and 0 of B”. It’s commonly used in hardware design.
(so, use a splitter.)
AND, OR, and NOT gates also have a “Data Bits” property.
Test it out thoroughly!!! It’s so easy to accidentally connect things to the wrong places. Make sure it does what you expect for every operation. You can just poke the inputs inside the ALU circuit to test it.
4. The register file
The register file is pretty straightforward. It will work just like the one we looked at in class, except it has 8 registers instead of 4. Feel free to use the example circuit as well. Details:
1 write port ( rd )
2 read ports (rs and rt)
8 registers, 16 bits per register
but register 0 is not a register – just a constant 0
Test it out thoroughly!!! Do this for every component you make, ok?
5. The program counter control
Remember from class that the PC can move ahead by 1 instruction, or jump to other places, or conditionally branch. That’s what this component is for.
The PC is a register which holds the address of the current instruction. Since your instruction memory uses 8-bit addresses, what size should the PC be?
You could put your PC register inside or outside this component, it doesn’t really matter.
There are so many ways to implement this. Check out the control flow instruction list here to see what ways the PC can change (instructions that do PC <- ... ). The basic behaviors should be something like this: It needs a Halt input. If this input is 1, the PC is disabled (no longer changes). There are 4 places it can go: 1. PC + 1 (by default, or for conditional branches when their condition is false) 2. PC + imm8 (for conditional branches when their condition is true) 3. imm8(forjandjal) 4. REG[rs] (for jr ) Notes on the conditional branches The PC should get set to PC + imm8 only when: The current instruction is a branch, AND The branch’s condition is satisfied. It’s easy to only check for one of these and forget to check the other. This component already needs REG[rs] for the jr instruction; why not do the branch condition checks here as well? 6. The teletype (TTY) output and keyboard input On the main circuit, place down one of each of these: Input/Output >
TTY
Input/Output > Keyboard
Notice both have triangles on them. Both components have built-in memory, so they need the clock like any other.
They keyboard component lets you type in anything and stores it in a buffer. Try poking it with the hand tool and typing. The characters it displays are the buffer.
The far left input on the bottom of the keyboard is the read enable. When this is 1, the first character from the buffer is taken out and sent out the far right output on the bottom.
The TTY (teletype) component is a screen of text. (Look up the history of teletypes! That’s what our command line interfaces descend from.) It has a write enable on the bottom, the leftmost input. Its data input is on the left above the clock. It only accepts 7-bit ASCII data.
7. The Interconnect
The interconnect won’t really be a component of its own. It’ll be a collection of multiplexers and wires/tunnels that hook everything else together.
Now you can go on the main circuit, and plop down one of each of your components you made. To connect them together, you make the interconnect. Remember the “interconnect matrix” from the class slides? Think about that.
Treat the 2 ALU inputs as separate “destinations.” (The slide showed ALU A and ALU B for that
reason.)
Treat the memory address and data inputs as separate “destinations” too.
Use tunnels. Tunnels will let you name your wires and move the parts of your CPU around independently.
Copy and paste your tunnels. This will avoid naming mistakes (e.g. naming one end PC and the other end
pc , which are different names).
Every time you put a MUX down, make a tunnel for its select signal and name it like “___Src”, e.g. “RegSrc” or “TTYSrc” or “ALUSrcB”. You can also use the tunnel colors to make the control signals stand out (like coloring them blue). For example, here’s a tiny piece of mine:
Here I used red for registers, orange for the ALU, yellow for the immediates, and blue for control signals.
Testing it
What I like to do is find all the control signals (selects and write enables), make copies of all those tunnels, and gather them up in one place.
Then, just like in lab 7, I can put inputs on them and “manually drive” the CPU. So I can e.g. load an immediate into a register by setting rd , turning on
RegWrite , setting RegDataSrc to use the immediate, and then ticking the clock. Then I can set
rs to the same register and make sure the same value is coming out.
Once you’re kinda sure your interconnect is working, you can remove the fake inputs and replace them with…
8. The control
Your control component is a combinational circuit whose input is the program ROM output (the current instruction) and its output is all the control signals for the entire CPU. It’s gonna be a big component.
It will also output the source/destination register indices and the immediate value extracted from the instruction.
There are three main stages to making the control:
1. Splituptheinstruction.
Use splitters to split the instruction into its fields.
Like on the slides, extract all possible fields from all possible formats.
You only have to extract each field once. e.g. you don’t have to extract 2 copies of rs . After splitting you should have:
a bit saying whether or not it’s I-type the opcode (5 bits)
rs, rt, and rd (all 3 bits, and they just go right out of the control)
a 5-bit imm5 and an 8-bit imm8 (see the section below…)
2. Decodetheopcode.
5-bit opcode into a 5-bit decoder. boom. Look at the ISA to see which opcodes correspond to which instructions.
That page lists them all in numerical order.
Try to keep the opcode and its decoded versions inside the control unit. Don’t send the opcode all over the CPU and decode it elsewhere! That’ll make it way harder to find and fix problems. Just like in software: the more encapsulated things are, the easier they are to work with.
3. Comeupwiththecontrolsignals.
Make one output for each control signal you need to produce.
Again, like on the slides: after you’ve decoded the opcode, it’s just a matter of coming up with circuits for each of those outputs, based on what the opcode is.
For multi-bit control signals, see below.
Dealing with the immediates
There are two sizes of immediate, imm5 and imm8 . Beyond that, some instructions use a sign-extended
version of the immediate, and some use a zero- extended version.
Rather than sending out all possible immediate values to the rest of the CPU, I have my control deal with it all and just output a single 16-bit “imm” value.
You can tell what size immediate should be used by the most significant bit of the encoded instruction.
if it’s 1, use imm8 ; otherwise, use imm5 . You can also figure out whether to use zero- or
sign-extension from the opcode.
If the instruction description says sxt() ,
use sign-extension; otherwise, use zero- extension.
Do all the things and pick the thing you need.
Dealing with multi-bit control signals
Signals like ALUOp and RegDataSrc can be 2 or more bits. There are a few approaches to this.
With any approach, you should write down a list of the values for that control signal and what they mean. This comes from your multiplexers! So let’s say I hooked up the ALU’s operation multiplexer like:
ALUOp:
Now, to come up with the circuit for this…
1. Youcouldtreateachbitasitsowncontrolsignal, and use OR gates like usual.
e.g. in the above, ALUOp0 is 1 when we’re subtracting, ORing, or shifting left.
So find all the instructions that subtract, OR, or shift left, and OR their decoded instruction values together.
This works, but it’s pretty awkward, and gives a hard-to-understand circuit.
2. Or,youcoulduseaPlexers>PriorityEncoder, which is like a reverse decoder.
With a decoder, you give it a number and it turns on one output.
With a priority encoder, you turn on one input, and it gives you a number.
For the above, I’d set it up like this:
See how I have a constant 1 going into the first input? Do that. Without it, you might get XXX on the output and blue wires and screaming and crying and oh no
Now, for each input on the left (other than the first one, which is a constant 1), I will OR together the instructions that need that operation. Input 1 is subtraction, so I would OR together the sub and sbi tunnels (from the opcode decoder) for that, like this:
So if the opcode is sub or sbi , the output of this priority encoder will be 1, which is exactly what my ALU
needs!
Then repeat the process for the other inputs. (It’s fine to have some inputs unused.)
Check out the ISA here. Test Programs
Assembled programs for you to load into your machine to test it.
Leave it at 8 rows and 32 columns, please.
000 = add
001 = subtract
010 = AND
011 = OR
100 = NOT
101 = << 110 = >>
111 = (unused!!)
© 2016-2021 Jarrett Billingsley