What is the minimum size of an address register for a computer with 5TB of memory? - hardware

There is this question that I'm having a bit a difficulty to answer
Here it is:
An n-bit register can hold 2^n distinct bit patterns. As such,
it can only be used to address a memory whose number of addressable units
(typically, bytes) is less than or equal to 2^n. In this question, register
sizes need not be a power of two. K = 2^10
a) What is the minimum size of an address register for a computer
with 5 TB of memory?
b) What is the minimum size of an address register for a computer
with 7 TBs of memory?
c) What is the minimum size of an address register for a computer
with 2.5 PBs of memory?
From the conversion, I know that:
1KB = $2^{10}$ bytes
1MB = $2^{20}$ bytes
1GB = $2^{30}$ bytes
1TB = $2^{40}$ bytes
If I convert 5TB into bytes we get 5,497,558,138,880 bytes
What would be the next step though? I know that 1 byte = 8 bits

This is how I would proceed:
1 TB = 2^40 bytes
Calculate the number of bytes in 5 TB = 5,497,558,138,880 bytes (assume this number is n);
The logarithmic function log(Base2)(n) = the minimum size of an address register and in this case it would be 42.321928095 bits which I would round up to 43 bits.
Same logic for the other questions.

I suggest you divide by 8.
5,497,558,138,880/8 = 687194767360
Using logarithms, 2^n = 687194767360 therefore log2(687194767360) = n
Therefore n = 39.321928095
The same steps can be used to achieve part b and c

Related

Difference between 1 and 1'b1 in Verilog

What is the difference between just giving 1 and giving 1'b1 in verilog code?
The 1 is 32 bits wide, thus is the equivalent of 32'b00000000_00000000_00000000_00000001
The 1'b1 is one bit wide.
There are several places where you should be aware of the difference in length but the one most likely to catch you out is in concatenations. {}
reg [ 7:0] A;
reg [ 8:0] B;
assign A = 8'b10100101;
assign B = {1'b1,A}; // B is 9'b110100101
assign B = {1,A}; // B is 9'b110100101
assign B = {A,1'b1}; // B is 9'b101001011
assign B = {A,1}; // B is 9'b000000001 !!!!
So, what's the difference between, say,
logic [7:0] count;
...
count <= count + 1'b1;
and
logic [7:0] count;
...
count <= count + 1;
Not a lot. In the first case your simulator/synthesiser will do this:
i) expand the 1'b1 to 8'b1 (because count is 8 bits wide)
ii) do all the maths using 8 bits (because now everything is 8 bits wide).
In the second case your simulator/synthesiser will do this:
i) do all the maths using 32 bits (because 1 is 32 bits wide)
ii) truncate the 32-bit result to 8 bits wide (because count is 8 bits wide)
The behaviour will be the same. However, that is not always the case. This:
count <= (count * 8'd255) >> 8;
and this:
count <= (count * 255) >> 8;
will behave differently. In the first case, 8 bits will be used for the multiplication (the width of the 8 in the >> 8 is irrelevant) and so the multiplication will overflow; in the second case, 32 bits will be used for the multiplication and so everything will be fine.
1'b1 is an binary, unsigned, 1-bit wide integral value. In the original verilog specification, 1 had the same type as integer. It was signed, but its width was unspecified. A tool could choose the width base on its host implementation of the int type.
Since Verilog 2001 and SystemVerilog 2005, the width of integer and int was fixed at 32-bits. However, because of this original unspecified width, and the fact that so many people write 0 or 1 without realizing that it is now 32-bits wide, the standard does not allow you to use an unbased literal inside a concatenation. {A,1} is illegal.

how many bits represent the value 2G

When we say 4K in hardware it is equal to the value 4096 which is 11 bits. What would be the value for 2G and how many bits represent this value?
Thanks
Often in CS we deal with number that are necessarily power of two (all addressable quantities for example).
In this context is it more useful to have prefixes that instead of being multiple of ten, like the decimal K = 10^3, M = 10^6, G = 10^9, are multiple of two.
Since the power of two closest to 1000, which is decimal K, is 1024 = 2^10, we can make the analogy that in CS K 1024 instead of 1000.
This is rather confusing as some quantities (like disk sizes or transmission channel parameters) are not bound to be power of two and can be given with either the decimal K or the CS K.
To avoid further confusion the CS now use appropriate binary prefixes, for example the CS K now is the Ki.
So as in decimal G is 10^9 = (10^3)^3 which you can think of as K^3 then G in binary (better called Gi) is Ki^3 = (2^10)^3 = 2^30.
To represent 4Ki quantities you need 12 bits as log2(4Ki) = log2(2^2 * 2^10) = 12.
To represent 2Gi quantities you need log2(2Gi) = log2(2 * 2^30) = 31 bits.
Note I used the phrase "To represent 4Ki quantities" rather then "To represent the 4Ki quantity", the latter is different and need one more bit. This is analogous to saying that to represent 1000 quantities we need 3 decimal digits (from 000 to 999) but to represent the number 1000 itself we need 4 digits (1, 0, 0 and 0).

32-bit fractional multiplication with cross-multiplication method (no 64-bit intermediate result)

I am programming a fixed-point speech enhancement algorithm on a 16-bit processor. At some point I need to do 32-bit fractional multiplication. I have read other posts about doing 32-bit multiplication byte by byte and I see why this works for Q0.31 formats. But I use different Q formats with varying number of fractional bits.
So I have found out that for fractional bits less than 16, this works:
(low*low >> N) + low*high + high*low + (high*high << N)
where N is the number of fractional bits. I have read that the low*low result should be unsigned as well as the low bytes themselves. In general this gives exactly the result I want in any Q format with less than 16 fractional bits.
Now it gets tricky when the fractional bits are more than 16. I have tried out several numbers of shifts, different shifts for low*low and high*high I have tried to put it on paper, but I can't figure it out.
I know it may be very simple but the whole idea eludes me and I would be grateful for some comments or guidelines!
It's the same formula. For N > 16, the shifts just mean you throw out a whole 16-bit word which would have over- or underflowed. low*low >> N means just shift N-16 bit in the high word of the 32-bit result of the multiply and add to the low word of the result. high * high << N means just use the low word of the multiply result shifted left N-16 and add to the high word of the result.
There are a few ideas at play.
First, multiplication of 2 shorter integers to produce a longer product. Consider unsigned multiplication of 2 32-bit integers via multiplications of their 16-bit "halves", each of which produces a 32-bit product and the total product is 64-bit:
a * b = (a_hi * 216 + a_lo) * (b_hi * 216 + b_lo) =
a_hi * b_hi * 232 + (a_hi * b_lo + a_lo * b_hi) * 216 + a_lo * b_lo.
Now, if you need a signed multiplication, you can construct it from unsigned multiplication (e.g. from the above).
Supposing a < 0 and b >= 0, a *signed b must be equal
264 - ((-a) *unsigned b), where
-a = 232 - a (because this is 2's complement)
IOW,
a *signed b =
264 - ((232 - a) *unsigned b) =
264 + (a *unsigned b) - (b * 232), where 264 can be discarded since we're using 64 bits only.
In exactly the same way you can calculate a *signed b for a >= 0 and b < 0 and must get a symmetric result:
(a *unsigned b) - (a * 232)
You can similarly show that for a < 0 and b < 0 the signed multiplication can be built on top of the unsigned multiplication this way:
(a *unsigned b) - ((a + b) * 232)
So, you multiply a and b as unsigned first, then if a < 0, you subtract b from the top 32 bits of the product and if b < 0, you subtract a from the top 32 bits of the product, done.
Now that we can multiply 32-bit signed integers and get 64-bit signed products, we can finally turn to the fractional stuff.
Suppose now that out of those 32 bits in a and b N bits are used for the fractional part. That means that if you look at a and b as at plain integers, they are going to be 2N times greater than what they really represent, e.g. 1.0 is going to look like 2N (or 1 << N).
So, if you multiply two such integers the product is going to be 2N*2N = 22*N times greater than what it should represent, e.g. 1.0 * 1.0 is going to look like 22*N (or 1 << (2*N)). IOW, plain integer multiplication is going to double the number of fractional bits. If you want the product to
have the same number of fractional bits as in the multiplicands, what do you do? You divide the product by 2N (or shift it arithmetically N positions right). Simple.
A few words of caution, just in case...
In C (and C++) you cannot legally shift a variable left or right by the same or greater number of bits contained in the variable. The code will compile, but not work as you may expect it to. So, if you want to shift a 32-bit variable, you can shift it by 0 through 31 positions left or right (31 is the max, not 32).
If you shift signed integers left, you cannot overflow the result legally. All signed overflows result in undefined behavior. So, you may want to stick to unsigned.
Right shifts of negative signed integers are implementation-specific. They can either do an arithmetic shift or a logical shift. Which one, it depends on the compiler. So, if you need one of the two you need to either ensure that your compiler just supports it directly
or implement it in some other ways.

How structure padding works?

My Questing is regarding structure padding? Can any one tell me what's logic behind structure padding.
Example:
structure Node{
char c1;
short s1;
char c2;
int i1;
};
Can any one tell me how structure padding will apply on this structure?
Assumption: Integer takes 4 Byte.
Waiting for the answer.
How padding works depends entirely on the implementation.
For implementations where you have a two-byte short and four-byte int and types have to be aligned to a multiple of their size, you will have:
Offset Var Size
------ ---- ----
0 c1 1
1 ?? 1
2 s1 2
4 c2 1
5 ?? 3
8 i1 4
12 next
An implementation is free to insert padding between fields of a structure and following the last field (but not before the first field) for any reason whatsoever. The ability to pad after a structure is important for aligning subsequent elements in an array. For example:
struct { int i1; char c1; };
may give you:
Offset Var Size
------ ---- ----
0 i1 4
4 c1 1
5 ?? 3
8 next
Padding is usually done because either aligned data works faster, or misaligned data is illegal (some CPU architectures disallow misaligned access).
There is no simple answer to this, except "It depends".
It could be as little as 8 bytes, assuming two byte shorts, or it could take 12 bytes, or it could take 42 bytes on a suitably bizarre implementation. It depends on at least the underlying architecture, the compiler and the compiler flags. Check your tool's manual for information.
Inside a struct, each member's offset in memory is based on their size and alignment. Note that this is implementation specific
E.g. if char takes 1 byte, short takes 2 bytes and int takes 4 bytes:
structure Node{
char c1; // 1 byte
// 1 byte padding (next member requires 2 byte alignment)
short s1; // 2 bytes
char c2; // 1 byte
// 3 bytes padding (since next member requires 4 byte alignment)
int i1; // 4 bytes
};
This also depends on your compiler settings and architecture, and can also be modified.
If you packed this structure properly (by rearranging the order of members), you could fit it into 8 bytes, not 12 bytes (by switching c2 with s1).
The reason for alignment enforcement is that the hardware can do certain operations faster with data that have a natural alignment; otherwise it would have to perform some bitmasking, shifting and ORing to construct the data before operating on it.

varchar(255) v tinyblob v tinytext

My side question is there really any difference between tinyblob & tinytext?
Buy my real question is what reason, if any, would I choose varchar(255) over tinyblob or tinytext?
Primarily storage requirements and memory handling/speed:
In the following table, M represents the declared column length in characters for nonbinary string types and bytes for binary string types. L represents the actual length in bytes of a given string value.
VARCHAR(M), VARBINARY(M):
L + 1
bytes if column values require 0 – 255
bytes,
L + 2 bytes if values may
require more than 255 bytes
TINYBLOB, TINYTEXT:
L + 1 bytes, where L < 28
Additionally, see this post:
For each table in use, MySQL allocates
memory for 4 rows. For each of these
rows CHAR(X)/VARCHAR(X) column takes
up the X characters.
A TEXT/BLOB on the other hand is
represented by a 8 byte pointer + a
1-4 byte length (depending on the
BLOB/TEXT type). The BLOB/TEXT is
allocated dynamicly on use. This will
use less memory, but in some cases it
may fragment your memory in the long
run.
Edit: As an aside, blobs store binary data and text stores ASCII, thats the only difference between TINYBLOB and TINYTEXT.
VARCHAR(255) is more SQL standard than tinyblob or tinytext. So your script, and application would be more portable across database vendors.
You can't apply CHARACTER SET to TINYTEXT, but you can to VARCHAR(255)