ARM assembly question wiht hexidecimal values - math

If i have 0x00000065 stored in a register, is that the same as having 0X65 in my register?
Thank you so much.

Yes, it's the same two hexadecimal values:
0x00000065 = 5*(16^0) + 6*(16^1) + 0*(16^2) + ... + 0*(16^7) = 5*(16^0) + 6*(16^1) = 0x65
(Note: the symbol '^' denotes the power operator)

Registers are 32 bits long so you can't have 0x65 in one, only 0x00000065.
But of course, these are equal numbers.

Related

crc ip hdr checksum in verilog

I am implementing a task that i can use to obtain checksum from modified ip hdr. This is what i got:
task checksum_calc;
input [159:0] IP_hdr_data;
output [15:0] IP_chksum;
reg [19:0] IP_chksum_temp;
reg [19:0] IP_chksum_temp1;
reg [19:0] IP_chksum_temp2;
begin
IP_chksum_temp = IP_hdr_data[15:0] + IP_hdr_data[31:16] + IP_hdr_data[47:32] + IP_hdr_data[63:48] + IP_hdr_data[79:64] + IP_hdr_data[111:96] + IP_hdr_data[127:112] + IP_hdr_data[143:128] + IP_hdr_data[159:144];
IP_chksum_temp1 = IP_chksum_temp[15:0] + IP_chksum_temp[19:16];
IP_chksum_temp2 = IP_chksum_temp1[15:0] + IP_chksum_temp1[19:16];
IP_chksum = ! IP_chksum_temp2[15:0];
end
endtask
It's that correct? Or it will be some timing problems due to using cominational logic?
Looks like all you are doing is some combination logic calculation. A functions is a better choice. The primary purpose of a function is to return a value that is to be used in an expression.
This is huge combo logic, which in most of the scenario's will cause trouble for timing.
Better to run it through synthesis and timings check to know the exact result.
One suggestion as
IP_chksum_temp1 = IP_chksum_temp[15:0] + IP_chksum_temp[19:16];
can only generate flip the 16th bit. Hence, there is no need of 20 bits in next addition.
IP_chksum_temp2 = IP_chksum_temp1[15:0] + IP_chksum_temp1[19:16];
This can be done :-
reg [16:0] IP_chksum_temp1;
reg [16:0] IP_chksum_temp2;

Twos complement on hex

Given:
int number = 0xFFFFFF87;
number = ~number + 1;
printf ("%x", number);
Why does 'number' become '79' instead of '87'? How can i make it '87' ?
It is 0x79 because ~0xFFFFFF87 = 0x00000078 and when 1 is added you get 0x00000079.
To get 0x87, you should use:
int number = 0xFFFFFF87 & 0xFF;
which will select only the least significant byte and mask the other bytes with zero.
~ negates every bit, not only the ones with hex group of 0xF.
To make it 0x87 just reverse the operation, i.e.:
int number = ~(0x87-1); // which is 0xFFFFFF79

understanding checksum of ascii string

I am reading a manual on sending commands via serial to a device as shown:
Assume that my equipment address is 000. I would send a command like:
">000P**cr".
what would **, my checksum be? According to the manual, I need the last two digits of the total char code of "000P".
Isn't that just the hex value of "P"? I can't seem to understand this.
Yes it's a bit confused, but my guess would be:
total = ascii('0') + ascii('0') + ascii('0') + ascii('P')
total = 48 + 48 + 48 + 80
total = 224
cksum = last2digits(total) = 24
If it does not work as is, maybe try in hexadecimal notation:
hex(total) = E0
hex_cksum = last2digits(hex(total)) = E0

ADC transfer function

I took over the project from someone who had gone a long time ago.
I am now looking at ADC modules, but I don't get what the codes mean by.
MCU: LM3S9B96
ADC: AD7609 ( 18bit/8 channel)
Instrumentation Amp : INA114
Process: Reading volts(0 ~ +10v) --> Amplifier(INA114) --> AD7609.
Here is codes for that:
After complete conversion of 8 channels which stored in data[9]
Convert data to micro volts??
//convert to microvolts and store the readings
// unsigned long temp[], data[]
temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003);
temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F);
temp[2] = ((data[2]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F);
temp[3] = ((data[3]<<8)& 0x3FF00) + ((data[4]>>8)& 0x00FF);
temp[4] = ((data[4]<<10)& 0x3FC00) + ((data[5]>>6)& 0x03FF);
temp[5] = ((data[5]<<12) & 0x3F000) + ((data[6]>>4)& 0x0FFF);
temp[6] = ((data[6]<<14)& 0x3FFF0) + ((data[7]>>2)& 0x3FFF);
temp[7] = ((data[7]<<16)& 0x3FFFC) + (data[8]& 0xFFFF);
I don't get what these codes are doing...? I know it shifts but how they become micro data format?
transfer function
//store the final value in the raw data array adstor[]
adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
131072 = 2^(18-1) but I don't know where other values come from
AD7609 datasheet says The FSR for the AD7609 is 40 V for the ±10 V range and 20 V for the ±5 V range, so I guessed he chose 20vdescribed in the above and it somehow turned to be 2000???
Does anyone have any clues??
Thanks
-------------------Updated question from here ---------------------
I don't get how 18bit concatenated value of data[0] + 16bit concatenated value of data[1] turn to be microvolt after ADC transfer function.
data[9]
+---+---+--- +---+---+---+---+---+---++---+---+---++---+---+---++
analog volts | 1.902v | 1.921v | 1.887v | 1.934v |
+-----------++-----------+------------+------------+------------+
digital value| 12,464 | 12,589 | 12,366 | 12,674 |
+---+---+---++---+---+---++---+---+---++---+---+---++---+---+---+
I just make an example from data[3:0]
1 resolution = 20v/2^17-1 = 152.59 uV/bit and 1.902v/152.59uv = 12,464
Now get thru concatenation:
temp[0] = ((data[0]<<2)& 0x3FFFC) + ((data[1]>>14)& 0x0003) = C2C0
temp[1] = ((data[1]<<4)& 0x3FFF0) + ((data[2]>>12)& 0x000F) = 312D3
temp[2] = ((data[1]<<6)& 0x3FFC0) + ((data[3]>>10)& 0x003F) = 138C
Then put those into transfer function and get microvolts
adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
adstor[0]= 7,607,421 with temp[0] !=1.902*e6
adstor[1]= 30,735,321 with temp[1] != 1.921*e6
adstor[2]= 763,549 with temp[2]
As you notice, they are quite different from the analog value in table.
I don't understand why data need to bit-shifting and <<,>> and added up with two data[]??
Thanks,
Please note that the maximum 18-bit value is 2^18-1 = $3FFFF = 262143
For [2] it appears that s/he splits 18-bit word concatenated values into longs for easier manipulation by step [3].
[3]: Regarding adstor[i] = (signed long)(((temp[i]*2000)/131072)*10000);
To convert from raw A/D reading to volts s/he multiplies with the expected volts and divides by the maximum possible A/D value (in this case, $3FFFF) so there seems to be an error in the code as s/he divides by 2^17-1 and not 2^18-1. Another possibility is s/he uses half the range of the A/D and compensates for that this way.
If you want 20V to become microvolts you need to multiply it by 1e6. But to avoid overflow of the long s/he splits the multiplication into two parts (*2000 and *10000). Because of the intermediate division the number gets small enough to be multiplied at the end by 10000 without overflowing at the expense of possibly losing some least significant bit(s) of the result.
P.S. (I use $ as equivalent to 0x due to many years of habit in certain assembly languages)

Prove possible key for Mono alphabetic Cipher

I am currently learning the Mono alphabetic Cipher Encryption. For an example, for 26 letters substitution ciphers.
Suppose the letter identified with each other.
So the total possible key is 26!
And the can I know how to prove that: 26!>= 4*10^26 ????
Thanks!
log_10(26!) = log_10(26) + log_10(25) + ... + log_10(2) + log_10(1)
= 26.60562
Thus,
26! = 10 ^ (26.60562) = (10 ^ 0.60562) * 10^26
Since
log_10(4) = 0.6020
We could get 26! > 4 * 10^26.

Resources