Adding a new command to MIPS - mips

I was in an interview and got the following question:
We would like to create a new MIPS command called foo with the following syntax:
foo rt, rs, immediate
Assume that rt and rs are not equal and immediate can be positive, negative or zero with a length of 16 bits.
The command does the following:
rt = immediate
rs = immediate + 4
Answer the following questions:
If we would like to implement this command in single-cycle MIPS, what minimal changes should we do? What if we want in Multi-cycle MIPS?
Create a pseudo-command of the with the basic MIPS commands to create foo.
I thought that the changes should be in the ALU only for both single and multi but I was wrong. I didn't get the opportunity to answer the second question because I blew the first one (I don't know the answer for it). I hope they will give me another chance so now I'm trying to study this material. How can I answer these questions?

For the second question, a pseudo-instruction can given by the following:
ADDI $rt, $0, immediate
ADDI $rs, $rt, 4
First you want to set rt to immediate value, which can be done by adding a zero to the immediate and writing the value back to rt.
Second you need need to add 4 to the immediate and write it back to rs, note that the immediate value is already stored in rt register (by the previous instruction), Now you need to take the value in rt and add an immediate value to it (i.e 4), and write the result back to rs.

Related

effects of different scenarios on a single cycle datapath (beq command)

I am stuck and unsure regarding the following situation.
I have the following datacycle:
and I know that in 0x3000 I have the following command: beq $t1,$t2,home - where home is 0x30AC, $t1=$t2=0x2000.
For some reason, I cannot translate it into hexa using online converters. The command I tried is: beq 0x2000, 0x2000, 0x30AC. Since the syntax of a beq command, as far as I know is: BEQ rs, rt, offset [I-type], then I don't understand why it doesn't work.
Anyways, my main problem are with the following cases:
If the control line of ALUSrc is stuck on 1, what will the command do?
If MemWrite is stuck on 1, what will the command do?
If ALUOp is stuck on the value 10 (binary), what will the command do?
What I think:
If alusrc equals one, then the lower 16 bits will be taken (with sign extenstion) from the command and added to $rs (0x2000).
If Memwrite equals one, then the data memory will be written unexpectedly.
I really don't know what will happen if ALUop will be stuck on 10. would really appreciate explanations regarding this situation.
I tried to elaborate as much as I can to make it understandable and also provide my attempts and insights (if correct, hope that some are lol).

What is the correct syntax of MIPS instruction sll?

Should the shift amount be an immediate value, or a value stored in a register? Does both work?
I've had different websites tell me different things and am confused.
Based on my research the sll (shift left logical) instruction should be used like this:
sll $d, $t, h
Which makes $d = $t shifted left h times.
I've been told that h should be a immediate value, but I was wondering if a register could be used as the third argument, and the value inside that register used as the shift amount. Would that also work?
You are correct.
sll is specific in that it is a R-format instruction where only two registers are used, rd and rs (destination and source), and the shamt field is a immediate value (a constant).
There is another instruction sllv which uses a third register where you specify shift by variable (the register).
Let me clear the point Shift left logical in MIPS 32 bit has following syntax:
SLL destination, Target, Shift amount(Should be immediate value)
Where as in 8086 if we want shift amount more than 1 we have to use a register to store the value of shift amount!

How would one go about implementing an add immediate in Verilog for an ALU?

I'm working with a 32-bit ALU for a MIPS processor.
I've read Pong Chu's book on verilog and other texts but I haven't really come across a concrete answer as to how exactly I would implement an add immediate with verilog?
for example with the asm code:
addi Y, A, immediate
add is as simple as y = a + b
but how do i interpret an immediate operand?
In overview, you can implement different operand capability for a function such as this in the following way:
Implement an add function where the operands are fed via a multiplexer. The multiplexer will have a few inputs, one of which will be an immediate value from your instruction word. Use the op code part of your instruction word to select which multiplexer input to use for the addition.
Other inputs to the multiplexer might be the output of a 'registers' memory, a forwarding path from somewhere else in your processor, etc.
I have not provided any code, but this would be completely dependent on what existing structure you already had. hopefully this overview will be enough to put you on the right track.
The wikipedia page on the MIPS architecture has a diagram showing multiplexers used in this way.

the set of all bit patterns that can be placed in a desired register using a single instruction

Given the following set of MiniMIPS instructions:
Load upper immediate
Add
Subtract
Set less than
Add immediate
Set less than immediate
Add
OR
XOR
NOR
AND immediate
OR immediate
XOR immediate
Load word
Store word
In MiniMips instructions, It's possible for some actions such as initializing a register to zero-bit pattern (all bits are zero) to have more than one instruction with the ability of doing that.
My question is, What are the set of all bit patterns that can be placed in a desired register using a single instruction from the given instruction set.
Since you allow "load word" and you include MIPS64 in your tags, the answer is any 64 bit integer can be loaded into a register using a single instruction from your instruction list.

Using MIPS to find sum of array

So Im having trouble with a problem. Im givin that a is an array of words and the base address of a is saved in $a0. So for int a[10] find the sum of this array using mips. I really don't know where to start can someone help me start and I think I should be able to finish it. Thanks a bunch!
Since you are given the address of the start of the array, you know that is also your first element. Since this is an array of int, I will assume it means it will use a storage space the size of a word on mips32 which is 4 bytes. Therefore a[1] is located at the address of a[0]+4bytes. A[2] is located at the address of a[0]+8bytes or a[1]+4bytes etc...
From that it follows that all you have to do is just loop 10 times, loading a word each time and adding the value.
The basic flow is:
Let count = 0, sum = 0 (sum is your return value, so $v0)
Load a word value from $a0 into a register
Set $a0 = $a0 + 4 (move from a[count] to a[count+1], integer is 4 bytes on mips32)
Set sum = sum + the register you loaded the word value into
count = count + 1
if count < 10? (set less than, branch) go to #2
jump and link (assuming our sum is already in $v0)
Note: The base address you are given MUST be word-aligned.
Optimization note: You can optimize the number of instructions executed by setting some register to $a0 + 40 before step 1. This means you can get rid of step 5 and step 6 will be a check if $a0 is less than that register you set before step 1. (The last optimization is moving step 4 to step 6's delay slot. If you are using a simulator, this might not be supported though)