Verilog uses Big Endian Bytes?

L

lingwitt

Guest
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?
 
On Apr 4, 4:11 pm, "lingwitt" <lingw...@gmail.com> wrote:
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?
Erm. I'm not sure if it's really "big endian" (i.e. the term may not
match correctly), but strings in Verilog are arranged such that the
first character of the string is at the leftmost bit. This will
depend also on your numbering of the vector that stores the string.
For that matter, you can do something nasty like:
reg [31:0] vec;
initial begin
vec = "BM";
$display("%s", vec);
$finish; end

The output will be:
BM
Note that there are two spaces at the beginning of the output string.
Since the "BM" is only 16-bit, it's assigned to the lowest 16 bits of
the vec, and then zero extended. The two spaces are actually null
characters, which some systems will actually still print as spaces
(some may not, though).

Really, though, string handling in Verilog is a bit of a pain, and
should be avoided if at all possible. Presumably, since you're
asking, it isn't avoidable in your case, so my recommendation would be
to use something like:
reg [1:maxstring*8] string;

This lets you count characters from offset 1-8, 9-16, etc. But take
note that if you assign a shorter string to a longer vector, it will
be right aligned!

Sincerely,
AmkG
 
lingwitt wrote:
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?
The order is maintained. Big endian or little endian would both
preserve the order.

You can declare reg [15:0] Normal or you can declare reg [0:15] Reverse.

In these cases, Normal+1 gives you a toggle on bit [0] while Revers+1
gives you a toggle on bit [15]. Does this arithmetic example give you a
better idea of endianism?

Sadly, I can't declare "Normal=Reverse" (or similar assignment) to match
bit[0] to bit[0] for an order swizzle but a for loop could be used to
make the exchange easily enough.
 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

lingwitt wrote:
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?
Verilog doesn't deal with bytes at all.

It is a feature of $display that values are printed MS*bit* first,
but that says nothing of any supposed endianness of Verilog per se.
Note that you can number the *bits* of a vector is little- or big-
endian order, but Verilog internally thinks in terms of bit
significance, and not your arbitrary labels.

Strings are defined to be placed in the least significant *bits*
of a vector, with the last character of the string in the least
least significant bits. Since there are not "bytes" in verilog,
strings are defined to take up 8 bits at a time. The "%s" format
of $display is aware of this rule, and displays accordingly.

(Strings are a bit hokey in Verilog. Hardware doesn't normally
deal in strings:)

- --
Steve Williams "The woods are lovely, dark and deep.
steve at icarus.com But I have promises to keep,
http://www.icarus.com and lines to code before I sleep,
http://www.picturel.com And lines to code before I sleep."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFGE8U1rPt1Sc2b3ikRArFPAJ4lX4uBSKh1ffmRdF307ECD7fCOTQCg2PfM
W/yfghCtg9sx2ymKgjp9O/0=
=Gasa
-----END PGP SIGNATURE-----
 
On Apr 4, 4:55 am, "alan" <almkg...@gmail.com> wrote:
On Apr 4, 4:11 pm, "lingwitt" <lingw...@gmail.com> wrote:

Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?

Erm. I'm not sure if it's really "big endian" (i.e. the term may not
match correctly), but strings in Verilog are arranged such that the
first character of the string is at the leftmost bit. This will
depend also on your numbering of the vector that stores the string.
For that matter, you can do something nasty like:
reg [31:0] vec;
initial begin
vec = "BM";
$display("%s", vec);
$finish; end

The output will be:
BM
Note that there are two spaces at the beginning of the output string.
Since the "BM" is only 16-bit, it's assigned to the lowest 16 bits of
the vec, and then zero extended. The two spaces are actually null
characters, which some systems will actually still print as spaces
(some may not, though).

Really, though, string handling in Verilog is a bit of a pain, and
should be avoided if at all possible. Presumably, since you're
asking, it isn't avoidable in your case, so my recommendation would be
to use something like:
reg [1:maxstring*8] string;

This lets you count characters from offset 1-8, 9-16, etc. But take
note that if you assign a shorter string to a longer vector, it will
be right aligned!

Sincerely,
AmkG
Very interesting example.

Our numbers are written in a kind of big endian form, with the
most significant figure "on the left". In particular, binary
numbers are written with the MSB "on the left". Naturally then,
Verilog treats bit vectors with the MSB "on the left".

In any case, Verilog is only bit-centric; it knows nothing really
of bytes (and for good reason!), execept when it comes to strings,
the characters of which are implicitly 8-bit bytes.

Then, when verilog converts a string to a bit vector,
the one character (byte) is always "on the left"
with respect to the next byte.

Your example of assigning "BM" to a 32-bit vector is interesting,
because such a thing cannot really be expressed in another language
like C. In this case, Verilog treats the string like a number formed
by concatenating the code for the first character with the code for
the second character.

vec = "BM" = 32'h0000424D 32'b0000_0000_0000_0000_0100_0010_0100_1101

the bit vector form of which is stored as is, "from left to right",
achieving
the same results that a Big Endian system would when storing that
number.

Consider the following analogous C code:

#include <stdio.h>

int main(int argc, char* argv[])
{
int vec = 0x0000424D;

printf("%s", (char*)&vec);

return 0;
}

On a big endian machine, vec looks like this:

byte 0: 0
byte 1: 0
byte 2: 0x42
byte 3: 0x4D

so that the output is nothing, as the "string" vec
is immediately null terminated. Of course, if the
zeros were treated as spaces--as in Verilog--the
output would be as with your example: " BM"

On a little endian machine, vec looks like this:

byte 0: 0x4D
byte 1: 0x42
byte 2: 0
byte 3: 0

so that the out is "MB". Of course, if the zeros
were treated as spaces, the output would be: "MB "

So, verilog rights numbers like we do, "from left to right".
Then, since it treats strings as numbers, those too are written
"from left to right" in the same way that big endian numbers are
stored.

I suppose then, Verilog uses big endian byte order when converting
strings,
and that's the only case in which bytes ever come up, because strings
are
expressed in bytes.
 
On Apr 4, 9:50 am, John_H <newsgr...@johnhandwork.com> wrote:
lingwitt wrote:
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?

The order is maintained. Big endian or little endian would both
preserve the order.

You can declare reg [15:0] Normal or you can declare reg [0:15] Reverse.

In these cases, Normal+1 gives you a toggle on bit [0] while Revers+1
gives you a toggle on bit [15]. Does this arithmetic example give you a
better idea of endianism?

Sadly, I can't declare "Normal=Reverse" (or similar assignment) to match
bit[0] to bit[0] for an order swizzle but a for loop could be used to
make the exchange easily enough.
I agree. I was unpleasantly surprised to find that couldn't make a bit
slice
in any direction I pleased. That fould be really nice for some logic.
 
On Apr 4, 11:33 am, Stephen Williams <spamt...@icarus.com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



lingwitt wrote:
Consider the following:

module test;
initial
begin
$display("%s", 16'h42_4D);
$display("%h", "BM");
$finish;
end
endmodule

Output on any system:
BM
424d

Thus, the most significant byte is always the first byte.
Does it state this somewhere officially?

Verilog doesn't deal with bytes at all.

It is a feature of $display that values are printed MS*bit* first,
but that says nothing of any supposed endianness of Verilog per se.
Note that you can number the *bits* of a vector is little- or big-
endian order, but Verilog internally thinks in terms of bit
significance, and not your arbitrary labels.

Strings are defined to be placed in the least significant *bits*
of a vector, with the last character of the string in the least
least significant bits. Since there are not "bytes" in verilog,
strings are defined to take up 8 bits at a time. The "%s" format
of $display is aware of this rule, and displays accordingly.

(Strings are a bit hokey in Verilog. Hardware doesn't normally
deal in strings:)
Indeed.

Take a look at my reply to Alan; I think I cover the issue fairly
thoroughly.
 
On Apr 4, 11:53 am, "lingwitt" <lingw...@gmail.com> wrote:
I suppose then, Verilog uses big endian byte order when converting
strings, and that's the only case in which bytes ever come up,
because strings are expressed in bytes.
Actually, I take it back.

Anytime a number has to be interpreted as bytes, verilog vectors
must be treated as in big endian byte order.

Simply put: Verilog uses Big Endian byte ordering, even when
bits are in little endian ordering.
 
lingwitt wrote:
Simply put: Verilog uses Big Endian byte ordering, even when
bits are in little endian ordering.
I think you are causing confusion by using nonstandard
terminology. The term "Big Endian" is generally used to
refer to the order that a particular computer architecture
uses for multi-byte values in the underlying memory
storage. In the C language, this is visible to the programmer
through certain constructs, such as unions and pointer
type casting. In Verilog, this is not visible.

You are talking about a Verilog language convention.
When numeric values are specified with string literals,
or printed with a string format, the rightmost character in
the string corresponds to the least significant bits in the
numeric value. This is independent of the endianness
of the underlying representation on the machine.
 
On Apr 5, 1:54 pm, s...@cadence.com wrote:
lingwitt wrote:

Simply put: Verilog uses Big Endian byte ordering, even when
bits are in little endian ordering.

I think you are causing confusion by using nonstandard
terminology. The term "Big Endian" is generally used to
refer to the order that a particular computer architecture
uses for multi-byte values in the underlying memory
storage. In the C language, this is visible to the programmer
through certain constructs, such as unions and pointer
type casting. In Verilog, this is not visible.

You are talking about a Verilog language convention.
When numeric values are specified with string literals,
or printed with a string format, the rightmost character in
the string corresponds to the least significant bits in the
numeric value. This is independent of the endianness
of the underlying representation on the machine.
To be fair, I never referenced the underlying machine representation.

In any case, perhaps I was a little zealous in saying that Verilog
uses Big Endian byte ordering,
because there are no explicit constructs for working with bytes.

To the contrary, strings are such an explicit construct, and my
statement holds:

"Verilog uses big endian byte order when converting strings,
and that's the only case in which bytes ever come up, because strings
are expressed in bytes."
 

Welcome to EDABoard.com

Sponsor

Back
Top