Rounding off with zero at the end - verilog

We can round off a number say 23 or 74 to 20 and 70 by seeing the numbers lsb(right most bit) and 26 or 78 to 30 and 80.. My doubt is if this is possible in verilog codes... I want to know after converting into digital will this concept be possible..

In case you just want to make the LSB of any register zero you can always do something like this
reg [7:0] a;
reg [7:0] b = 23;
a = {b[7:1], 1'b0};

In general to round off integers of base n you add n/2 and the divide by n (discarding the remainder) and then multiply by n. So your examples above:
(23+5)/10 * 10 = 20
(28+5)/10 * 10 = 30
Doing this with binary logic is a bit expensive since you need to divide and multiply. However, if you are working with base 2 numbers then those operations are free since it is just a bit shift.
For an example in binary, let's say you want to round 61 to the nearest multiple of 8, which would be 64. In binary, 61 is 6'b011101. Add 8/2 (6'b000100) to this and you get 6'b100001 which is 65. Now divide by 8 and multiply by 8. Since that is just shift right by 3 and then shift left by three we can simply zero out the 3 lsbs to get 6'b100000 which is 64.

Related

Why does EXIF geodata need so much precision?

According to spec, EXIF stores latitude and longitude with 192 precision each. But a simple calculation shows that you only need 32 bits to divide the circumference of Earth into segments of 9 mm:
r = 6378 km = 6.378 × 10^6 m
C = 2πr = 4.007 × 10^6 m
stepSize = C / 2^32 = 0.009 m = 9 mm
That's assuming you store the data in steps of equal size, so as an unsigned int. I can understand that would make handling code harder to write, so what the hell: let's use a double. At this precision, we can divide the Earth's circumference into steps of 2 picometers. A Helium atom has a diameter of 62 picometers. So at 64 bits, we have enough precision to divide the Earth's surface at subatomic scales.
What on Earth do we need 192 bits per angle?
The format stores latitude and longitude each as 6 32-bit integer values, which adds up to 192 bits. The 6 integers store each of degrees, minutes and seconds as rational numbers with a numerator and denominator.
Why this format? Presumably it's designed for very simple processors that can't handle floating point, and might not even be able to do division. The format is more than 25 years old (though I'm not sure when GPS data was added), and cameras weren't as smart back then. Cameras needed to be able to store lots of data (pictures are big), but they didn't need to do a lot of mathematical operations on it. So they wasted some bits to make manipulation easier.

How to compress an integer to a smaller string of text?

Given a random integer, for example, 19357982357627685397198. How can I compress these numbers into a string of text that has fewer characters?
The string of text must only contain numbers or alphabetical characters, both uppercase and lowercase.
I've tried Base64 and Huffman-coding that claim to compress, but none of them makes the string shorter when writing on a keyboard.
I also tried to make some kind of algorithm that tries to divide the integer by the numbers "2,3,...,10" and check if the last number in the result is the number it was divided by (looks for 0 in case of division by 10). So, when decrypting, you would just multiply the number by the last number in the integer. But that does not work because in some cases you can't divide by anything and the number would stay the same, and when it would be decrypted, it would just multiply it into a larger number than you started with.
I also tried to divide the integer into blocks of 2 numbers starting from left and giving a letter to them (a=1, b=2, o=15), and when it would get to z it would just roll back to a. This did not work because when it was decrypted, it would not know how many times the number rolled over z and therefore be a much smaller number than in the start.
I also tried some other common encryption strategies. For example Base32, Ascii85, Bifid Cipher, Baudot Code, and some others I can not remember.
It seems like an unsolvable problem. But because it starts with an integer, each number can contain 10 different combinations. While in the alphabet, letters can contain 26 different combinations. This makes it so that you can store more data in 5 alphabetical letters, than in a 5 digit integer. So it is possible to store more data in a string of characters than in an integer in mathematical means, but I just can't find anyone who has ever done it.
You switch from base 10 to eg. base 62 by repeatedly dividing by 62 and record the remainders from each step like this:
Converting 6846532136 to base62:
Operation Result Remainder
6846532136 / 62 110427937 42
110427937 / 62 1781095 47
1781095 / 62 28727 21
28727 / 62 463 21
463 / 62 7 29
7 / 62 0 7
Then you use the remainder as index in to a base62 alphabet of your choice eg:
0 1 2 3 4 5 6
01234567890123456789012345678901234567890123456789012345678901
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
Giving: H (7) d (29) V (21) V (21) v (47) q (42) = HdVVvq
------
It's called base10 to base62, there bunch of solutions and code on the internet.
Here is my favorite version: Base 62 conversion

How do the numbers and letters differ in hexadecimal colours?

I had a look at how hexadecimal colour codes work, for the most part, it seems pretty simple. But one thing I don't understand. If I have the code #37136F, how does the 6 and the F work together? Does this mean that the two number values are added together? So the blue value is 21? Or do they add together like: 615? If it is added together (which I feel like if the most logical way) then the maximum value you can get is 30, which gives me a range of 0-30... I feel like this isn't right, please enlighten me.
First you split the hex code into pairs of digits (so #37136F becomes 37, 13, and 6F), and those are the values for red, green, and blue respectively. Let's focus on the blue component, 6F.
6F is a two digit hexadecimal number (base 16). Just as 25 in base 10 is actually 2*10 + 5, 6F in hexadecimal is actually 6*16 + 15 = 111 in base 10. In general, if X and Y are hexadecimal digits (0 through F), then XY in base 16 is X*16 + Y.
Note that the minimum and maximum two-digit hex numbers are 00 and FF respectively, which equal 0*16 + 0 = 0 and 15*16 + 15 = 255 respectively. This is why RGB values range from 0 to 255 inclusive, when written in base 10.

A more natural color representation: Is it possible to convert RGBA color to a single float value?

Is it possible to represent an RGBA color to a single value that resembles the retinal stimulation? The idea is something like:
0.0 value for black (no stimulation)
1.0 for white (full stimulation)
The RGBA colors in between should be represented by values that capture the amount of stimulation they cause to the eye like:
a very light yellow should have a very high value
a very dark brown should have a low value
Any ideas on this? Is converting to grayscale the only solution?
Thanks in advance!
Assign specific bits of a single number to each part of RGBA to represent your number.
If each part is 8 bits, the first 8 bits can be assigned to R, the second 8 bits to G, the third 8 bits to B, and the final 8 bits to A.
Let's say your RGBA values are= 15,4,2,1. And each one is given 4 bits.
In binary, R is 1111, G is 0100, B is 0010, A is 0001.
In a simple concatenation, your final number would be 1111010000100001 in binary, which is 62497. To get G out of this, 62497 / 256, round it to an integer, then modulo 16. 256 is 16 to the second power because it is the 2nd position past the first from the right(R would need third power, B would need first power). 16 is 2 to the fourth power because I used 4 bits.
62497 / 256 = 244, 244 % 16 = 4.

Verilog - Floating points multiplication

We have a problem with Verilog.
We have to use multiplication with two floating points(binary), but it doesn't work 100% perfectly.
We have a Req m[31:0]. The first numbers (before the comma) are m[31:16] and the numbers after comma m[15:0] so we have like:
m[31:16] = 1000000000000000;
m[15:0] = 1000000000000000;
m[31:0] = 10000000000000000(.)1000000000000000;
The Problem is: we want to multiplicate numbers with decimal places, but we don't know how.
For example: m = 2.5 in binary. The result of m*m is 6.25.
The question does not fully cover what is understood about fixed-point numbers, therefore will cover a little background which might not be relevant to the OP.
The decimal weighting of unsigned binary (base 2) numbers, 4bit for the example follows this rule:
2^3 2^2 2^1 2^0 (Base 2)
8 4 2 1
Just for reference the powers stay the same and the base is changed. For 4 hex it would be:
16^3 16^2 16^1 16^0
4096 256 16 1
Back to base 2, for twos complement signed number the MSB (Most Significant Bit) becomes negative.
-2^3 2^2 2^1 2^0 (Base 2, Twos complement)
-8 4 2 1
When we insert a binary point or fractional bit the pattern continues. 4 Integer bits 4 fractional bits.
Base 2: Twos complement 4 integer, 4 bit frational
-2^3 2^2 2^1 2^0 . 2^-1 2^-2 2^-3 2^-4
-8 4 2 1 . 0.5 0.25 0.125 0.0625
Unfortunately Verilog does not have a fixed-point format so the user has to keep track of the binary point and worked with scaled numbers. Decimal points . can not be used in in verilog numbers stored as reg or logic as they are essentially integer formats. However verilog does ignore _ when placed in number declarations, so it can be used as the binary point in numbers. Its use is only symbolic and has no meaning to the language.
In the above format 2.5 would be represented by 8'b0010_1000, the question has 16 fractional bits therefore you need to place 16 bits after the _ to keep the binary point in the correct place.
Fixed-point Multiplication bit widths
If we have two numbers A and B the width of the result A*B will be:
Integer bits = A.integer_bits + B.integer_bits.
Fractional bits = A.fractional_bits + B.fractional_bits.
Therefore [4 Int, 4 Frac] * [4 Int, 4 Frac] => [8 Int, 8 Frac]
reg [7:0] a = 0010_1000;
reg [7:0] b = 0010_1000;
reg [15:0] sum;
always #* begin
sum = a * b ;
$displayb(sum); //Binary
$display(sum); //Decimal
end
// sum == 00000110_01000000; //Decimal->6.25
Example on EDA Playground.
From this you should be able to change the depths to suit any type of fixed point number. and cast ing back to a 16 Int 16 fractional number can be done by part selecting the correct bits. Be careful if you need to saturate instead of overflowing.
There is a related Q&A that has 22 fractional bits.

Resources