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.
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'm reading about the Instruction Decode (ID) phase in the MIPS datapath, and I've got the following quote: "Once operands are known, read the actual data (from registers) or extend the data to 32 bits (immediates)."
Can someone explain what the "extend the data to 32 bits (immediates)" part means? I know that registers all contain 32 bits, and I know what an immediate is. I just don't understand why you need to extend the immediate from 26 to 32 bits.
Thanks!
26-bit immediates are only in jump instructions, and aren't sign- or zero-extended to 32 bit, because they're not displacements to be added/subtracted.
I-type instructions with 16-bit immediates are different.
addi / addiu immediates are sign-extended (by duplicating the top/sign bit of the immediate to all higher bits).
https://en.wikipedia.org/wiki/Two%27s_complement#Sign_extension
This allows 2's complement numbers from -2^15 .. +2^15-1 to be encoded.
(0xFFFF8000 to 0x00007FFF)
ori/andi/xori boolean immediates are zero-extended (by setting all higher bits to zero)
This allows unsigned / 2's complement numbers from 0 .. 2^16-1 to be encoded.
(0x00000000 to 0x0000FFFF)
For other instructions see this instruction-set reference which breaks down each instruction showing 016 || [I15..0] for zero-extension or [I15]16 || [I15..0] for sign-extension.
This makes it possible to use 16-bit immediates as inputs to a 32-bit binary operation that only makes sense with 2 equal-width inputs. (In a simple classic MIPS pipeline, the decode stage fetches operands from registers and/or immediates. Register inputs are always going to be 32-bit, so the ALU is wired up for 32-bit inputs. Extending immediates to 32-bit means the rest of the CPU doesn't have to care whether the data came from an immediate or a register.)
Also sign-extended:
offsets in the reg+imm16 addressing mode used by lw/sw and other load/store instructions
relative branches (PC += imm16<<2)
maybe others, check the manual for instructions I didn't mention to see if they sign- or zero- extend.
You might be wondering "why does addiu sign-extend its immediate even though it's unsigned?"
Remember that there's no subiu, only addiu with a negative immediate. Being able to add or subtract numbers in the range -2^15 .. +2^15-1 is more useful than only being able to add 0 .. 2^16-1.
And usually you don't want to raise an exception on signed overflow, so normally compilers use addu / addiu even on signed integers. addu is badly named: it's not "for unsigned integers", it's just a wrapping-allowed / never-faulting version of add/addi. It sort of makes sense if you think of C, where signed overflow is undefined behaviour (and thus could use add and raise an exception in that case if the compiler wanted to implement it that way), but unsigned integers have well-defined overflow behaviour: base 2 wraparound.
On a 32-bit CPU, most of the operations you do (like adding, subtracting, dereferencing a pointer) are done with 32-bit numbers. When you have a number with fewer bits, you need to somehow decide what those other bits are going to be when you want to use that number in one of those operations. The act of deciding what those new high bits are is called "extending".
Assuming you are just doing a standard zero extension or sign extension, extending is very cheap. However, it does require some circuitry, so it makes sense that a description of the MIPS datapath would mention it.
Im trying to work out an answer for a question about meassuring pressures.
The meassurments are supposed to be stored in binary floating point format and my task is to determine the minimum number of bits required to do so with some constraints;
Maximum pressure is 1e+07 Pa
Minimum pressure is 10 Pa
Accuracy of meassurments is 0.001 %
So if I understand it correctly, I could happen to measssure
1e+07 + 0.00001 * 1e+07 = 10000100 Pa
and would want to store it precisely. This would mean I would need 24 bits, since
2^23< 10000100 <2^24-1.
Is this including the 1 bit for a negative sign? Since we don't meassure negative pressures, would a more accurate answer be 23 bits?
And also for the minimum pressure, I could happen to meassure 9.9999 Pa and would want to store this correctly, so 4 decimals.
Since I could do the same type of calculation and end up with
2^13<9999<2^14-1
Is this already covered in the 23-24 bits I chose first?
I'm very new to this so any help or just clarification would be appreciated.
Unless you are asking this question for (i.) academic interest or (ii.) are really short on storage - neither of which I am going to address - I would strongly advocate that you don't worry about the numbers of bits and instead use a standard float (4 bytes) or double (8 bytes). Databases and software packages understand floats and doubles. If you try to craft your own floating point format using the minimum number of bits then you are adding a lot of work for yourself.
A float will hold 7 significant digits, whereas a double will hold 16. If you want to get technical a float (single precision) uses 8 bits for the exponent, 1 bit for the sign and the remaining 23 bits for the significand, whilst a double (double precision) uses 11 bits for the exponent, 1 bit for the sign and 52 bits for the significand.
So I suggest you focus instead on whether a float or a double best meets your needs.
I know this doesn't answer your question, but I hope it addresses what you need.
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 read this:
Recall that paging is implemented by
breaking up an address into a page and
offset number. It is most efficient to
break the address into X page bits and
Y offset bits, rather than perform
arithmetic on the address to calculate
the page number and offset. Because
each bit position represents a power
of 2, splitting an address between
bits results in a page size that is a
power of 2.
I don't quite understand this answer, can anyone give a simpler explanation?
If you are converting a (linear) address to page:offset, you want to divide the address by the page size and take the integer answer as the page, and the reminder as the offset.
This is done using integer division and modulus (MOD, "%") operators in your programming language.
A computer represents an address as a number, stored as binary bits.
Here's an example address: 12 is 1100 in binary.
If the page size is 3, then we'd need to calculate 12/3 and 12%3 to find the page and offset (4:0 respectively).
However, if the page size is 4 (a power of 2), then 4 in binary is 100, and integer division and modulus can be computed using special 'shortcuts': you can strip the last two binary digits to divide, and you can keep only the last two binary digits for modulus. So:
12/4 == 12>>2 (shifting to remove the last two digits)
12%4 == 12&(4-1) (4-1=3 is binary 11, and the '&' (AND) operator only keeps those)
Working with powers of two leads to more efficient hardware so that's what hardware designers do. Consider a cpu with a 32-bit address, and an n-bit page number:
+----------------------+--------------------+
| page number (n bits) | byte offset (32-n) |
+----------------------+--------------------+
This address is sent to the virtual memory unit, which directly separates the page number and byte offset without any arithmetic operations at all. Ie, it treats the 32-bit value as an array of bits, and has (more or less) a wire running directly to each bit. This allows the memory hardware to extract the page number and byte offset in parallel, without performing any arithmetic operations.
At the same time, this approach requires splitting on a bit boundary, which leads directly to power-of-2 page sizes.
If you have n binary digits at your disposal, then you can encode 2n different values.
Given an address, your description states some bits will be used for the page, and some for the offset. As you're using a whole number of binary bits for the for offset Y, then the page size is naturally a power of 2, specifically 2Y.
Because the representation of the data. The page offset sets the size of the page, and since the data is represented in binary, you will have a number n of bits to define the offset, so you will have pages with a size of 2^n.
Let's suppose you have an address like this 10011001, and you split it in 1001:1001 for page:offset. Since you have 4 bits to define the offset, your page's size is 2⁴.
If it is not exact power of 2 then some memory address will be invalid. eg if the page size is 5 byte then to distinguish each byte we need 3 bit in the offset part of the address. Because using 2 bit only 4 byte can be addressed. But using 3 bit offset for 5 byte page keep two address unused. thats why page size should be .......
since all addresses are in binary and are divided into f and d, f=frame no, d=offset. due to be the size in power of 2 a human no need to go for huge mathematical calculation, just by watching the address bits you can identify the f and d. If page size was 2^n the in physical address last n bits represents the offset and remaining bits represent page numbers.
Hopefully this answer will help you.
I realized what I didn't get was how the page sizes are a power of 2. I found out afterwards:
At the smallest level, the page is 1 bit (0 or 1) and the offset is 1 bit (0 or 1). Combining these together, the page size would be 2 x 2 (or 2^2), because of the number of bits they both have (2 each, so 2 x 2).
Now if the page/offset were larger, then it would be n x n -- n being the number of bits they both have.
The page no. is always in the power of 2 as (2^n).
There are several reasons:
1.The memory address is also in 2^n so it will be more easy to move a page.
2.There are two bits which represent the page:
a.Page no. b.Offset no
So,This is also the reason.
3.Memory is in quantised form like charge(q).