Let's say that a jump instruction is located at memory address 0x20CE88C0. What is the highest (i.e., greatest) 32-bit memory address to which this jump can transfer control?
I know the highest address can be 2^26, but I see others saying 2^28. I don't understand the difference. Why is 2^28?
The J-Type instruction is very simple:
opcode target
6 26 // field size, as bit count
target := instruction[25:0]
JumpAddr := { PC+4[31:28], target, 2'b0 }
PC := JumpAddr
This is the description in the MIPS Green Sheet / Quick Reference Data. Though a somewhat funny notation (some kind of RTL), it tells us what we need to know about the possible range of jump instructions, by telling us how the processor decodes the J-Type instructions.
What this says is that the current PC+4 provides the upper 4 bits of the new PC address. Then the address field, sometimes called immediate otherwise called target — either way is 26 bits wide — provides the next 26 bits, and then 00 are the next 2 bits, for a total of 32 bit value for the next PC.
So, with that information, you can compute or form the largest possible address that can be reached from the given PC. Take PC+4's top 4 bits, and then (string/concatenate onto those 4 bits) a 26 bit max value — its 26 bits unsigned, so 26 all 1's is the max value — then concatenate a 00 (two zero bits) and to make the 32-bit value of the exact address of the maximum addressable location from the j/jal starting at the given PC.
Related
I'm reading a book of David Patterson and John Hennesy titled: Computer Organization and Design. In the RISC-V architecture set which the book is about there are two instruction formats related to jumping - SB-type and UJ-type. The former uses 12-bit constant to represent offset (in bytes) to jump from the current instruction and the latter uses 20-bit constant to represent the same. Then the author says the following:
Since the program counter (PC) contains the address of the current instruction, we can branch (SB-type) within +=2^10 words of the current instruction, or jump (UJ) within += 2^18 words of the current instruction, if we use the PC as the register to be added to the address.
I don't understand how they get those 2^10 and 2^18. Since the constant the instructions use is two's complement, then it can represent values from -2^11 to 2^11 - 1 in the first case and -2^19 to 2^19 - 1 in the second case. Since these constants represent bytes, but we want to know how many words we can jump over, therefore we need to divide max value of bytes by four, so the max which we can get is 2^11 / 2^2 = 2^9 words in the first case and 2^17 in the second one.
Could someone please take a look at my calculations above and point me out to what I'm missing and what's wrong with my calculations and thoughts?
UPDATE:
Probably I didn't understand the author correctly. May it be the case that they mean the lower-bound (-2^10) and upper-bound (+2^10)? So they mean that we can never jump beyond 2^10 from the current instruction?
I am trying to understand how the verilog branch statement works in an immediate instruction format for the MIPS processor. I am having trouble understanding what the following Verilog code does:
IR is the instruction so IR[31:26] would give the opcode.
reg[31:0] BT = PC + 4 + { 14{IR[15]}, IR[15:0], 2'b0};
I see bits and pieces such as we are updating the program counter and that we are taking the last 16 bits of the instruction to get the immediate address. Then we need a 32 bit word so we extend 16 more zeros.
Why is it PC + 4 instead of just PC?
What is 2'b0?
I have read something about sign extension but don't quite understand what is going on here.
Thanks for all the help!
1: Branch offsets in MIPS are calculated relative to the next instruction (since the instruction after the branch is also executed, as the branch delay slot). Thus, we have to use PC +4 for the base address calculation.
2: Since MIPS uses a bytewise memory addressing system (every byte in memory has a unique address), but uses 32-bit (4-byte) words, the specification requires that each instruction be word-aligned; thus, the last two bits of the address point at the bottom byte of the instruction (0x____00).
IN full, the instruction calculates the branch target address by taking the program counter, adding 4 to account for hte branch delay slot, and then adding the sign extended (because the branch offset could be either positive or negative; this is what the 14{IR[15]} does) offset to the target.
Numbers in Verilog can be represented using number of bits tick format of the following number.
2'b11; // 2 bit binary
3'd3 ; // 3 bit decimal
4'ha ; // 4 bit hex
The format describes the following number, the bit pattern used is not changed by the format. Ie 2'b11 is identical to 2'd3;
I was asked the following question on an assignment, but I'm not sure if I did it correctly.
"What is the largest memory space (i.e. program) that can be addressed by processors with the following number of address bits?
(c) 24 bits"
I put 011111111111111111111111 (0 followed by 23 1s). Is this correct? If not, how do I find the answer to this question? You can use a different amount of bits for an example if you want to. Thanks for any help.
No 011111111111111111111111 is not the correct answer. I'm assuming that you were calculating the largest number that can be represented by a signed 24 bit integer.
Memory address would be always unsigned so the answer is the number items that can be represented in 24 bits, which is 2^24 or 1000000000000000000000000 which is 1 followed by 24 zeros (assuming that I counted correctly) - since the address range includes 0 and goes to 1111111111111111111111 (24 1's).
2^N bytes, where N is number of bits in the address space.
For example, the 8088 processor had a 20 bit address space and so it could address 2^20 bytes = 1 MB.
Address space is unsigned so N is full number of bits, not number of bits minus 1.
An address in programming is usually something that represents a location in memory.
You can always represent as many locations as there are unique numbers.
How many locations can you address with a range from 1 to 10? 10.
How many locations can you address with a range from 1 to 2^24? 2^24.
So you can represent 2^24 locations and you didn't answer correctly.
You're on the wrong track.
Memory addresses are unsigned, so the size of the address space is 2^24 bytes, or 16Mb.
If you had 2 bits you could go from 00 to 11, 00, 01, 10, 11, four addresses. Four is 1 with two zeros 0. Two address bits one with two zeros is the number of addresses or 2 to the power 2. 3 bits 0b1000 or 8 addresses 2 to the power 3, 4 bits 0b10000 or 16 addresses, 2 to the power 4 and so on to whatever number of bits you want.
Please have a look at this Single Cycle Data Path in MIPS. The 26 bits of J type instruction are being Bit Extended to 28. I don't get the point. Shouldn't it be extended to 31 so it makes 32 bits overall. Please help me out to clear the concept.
Thanks
This is really no sign extension. Recall that the instructions in MIPS are 4-byte aligned.
This means that you can start an instruction at addresses which are 0 modulus 4 (i.e. 0, 4, 8, 12, ...)
Now, doing a shift left of 2 two bits is like multiplying by 4, which yields numbers which are always 0 modulus 4.
The actual address will be formed with:
- the 4 most significant bits of the nPC (that is PC+4) (lets call them PPPP)
- the 26 bits of the address field specified in the instruction, (lets call them AAA....AA)
- 00 as the two least significant bits (which yields the required instruction alignment)
Thus the address will be (binary) PPPPAAAAAAAAAAAAAAAAAAAAAAAAAA00
I am learning MIPS 32 bit. I wanted to ask that why do we Sign Extend the 16 bit offset (in Single Cycle Datapath) before sending it to the ALU in case of Store Word?
I am not sure if it's helpful for you now, but I am posting it anyway.
Let us consider in a very very general sense, an array of instructions in C++ i.e. A[0],A[1],A[2] .....
The "figurative" distance between any two instructions is 1 UNIT.
Lets take this analogy to MIPS. In MIPS, figuratively every instruction is separated by "1 UNIT", however, 1 UNIT = 4 Bytes in MIPS. Every instruction is 4 Bytes long and this is why when moving from instruction to instruction the PC is incremented by 4 i.e. PC+4. So that way the gap between instruction i and instruction i+2 is "figuratively" 2 but actually 2*4=8 i.e. PC+4+4
Coming back to offsets that are specified in Branch instructions, the offset represents the "figurative" distance from the next instruction(the instruction following the Branch). So to get the "real" distance, the offset is to be multiplied by 4. This is the reason we are instructed to "sign-extend" the offset by 2 bits to the 'LEFT', because, left shifting any binary value by n bits results in multiplying that value by 2^n. In our case 2^2 = 4
So the actual target address of a branch instruction is PC+4+4*Offset.
Hope this helps.
Sounds like the 16-bit offset is a signed 2's complement number, i.e. it can be either positive or negative.
When converting it to 32 bits, the most significant bit needs to be copied to the upper 16 bits in order to keep the sign information.
To the best of my knowledge,in load or store instructions the offset value is added to the value in temporary register,as temp. register is 32 bit and addition operation of 16 bit and 32 bit is not possible,the value is sign extended.
I think you are getting your concepts a little wrong here.
The 5 bits that you think are going inside the ALU, actually go inside the register memory to select one of the 32[2^5] registers.
Each register itself is of 32 bits. Hence, to add the offset to the register value, you need to sign extend it to 32 bits.
ALU operation is always between two registers of the same size in the single cycle datapath for MIPS.
In the hardware of a 32-bit machine most ALU's take 32-bit inputs, and all registers are 32-bit registers.
To work with your data it must be 32-bits wide, this why we SIGN-extend, however another approach would be to ZERO-extend, but SIGN-extend is used when you are dealing with immediates and offsets to preserve the sign in 2's complement.
Sign extension happens e.g. in case of M68xxx machines only in case of loading the address registers. Not so in case of data registers.
having e.g.
movea.w addr,a0
move addr,d0
addr:
dc.w $FFFF
leads in case of data register loading to $0000FFFF, in case of the
address register loading however to $FFFFFFFF.
To understand this, build the two complement of the signed negative
presentation, $FFFF, extend the number to 32 bit and redo the two-
complement, finding the corresponding representation in 32 bit.
Cheers and kind regards,
Stephan S.