Verilog系列:大小端
在计算机系统设计的过程中,经常会遇到数据存放的大小端(Endian)问题,也即数据在存储器中的存放顺序问题.如果没有对数据在存储器中存放的大小端没有正确的理解,那么极有可能导致想要的结果与期望不一样.为了加深对于大小端的理解,我们可以通过一个小故事来了解大小端的来历. “endian”一词来源于十八世纪爱尔兰作家乔纳森·斯威夫特(Jonathan Swift)的小说《格列佛游记》(Gulliver's Travels)。小说中,小人国为水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开而争论,区别在于一派要求从鸡蛋的大头把鸡蛋打破,另一派要求从鸡蛋的小头把鸡蛋打破,争论的双方分别被称为“大端派”和“小端派”。作者借由该小说讽刺英国的政党之争。就像大小国而在实际的应用过程中,人们对于使用哪种字节的排序还是存在着各种分歧.在1980年,丹尼·科恩(Danny Cohen),一位网络协议的早期开发者,在其著名的论文"OnHoly Wars and a Plea for Peace"中,为平息一场关于字节该以什么样的顺序传送的争论,而第一次引用了该词。
在哪种字节顺序更合适的问题上,人们表现得非常情绪化,实际上,就像鸡蛋的问题一样,没有技术上的原因来选择字节顺序规则,因此,争论沦为关于社会政治问题的争论,只要选择了一种规则并且始终如一地坚持,其实对于哪种字节排序的选择是任意的。
在计算机系统中,每个地址单元对应着一个字节,一般情况下一个字节为8位,但是在C语言中除了8位的char之外,还有16位的short型\32位的long型(不同编译器可能不同),对于数据存储位数大于8位的处理器(16位或者32位等)来说,那么必然存在如何将多个字节的数据进行顺序存储.在具体应用过程中出现了大小端的数据存储方式.例如, X86架构的处理器采用的的是小端模式(目前Intel X86是唯一坚持使用小端模式的架构),C51采用的是大端模式,大部分ARM和DSP均采用小端模式,有些ARM处理器可以随时在程序中对大小端模式进行切换,MIPS等要么全部采用大端方式要么提供选项支持大端模式,即大小端可切换.另外,在C语言中,默认采用的是小端模式,JAVA采用的是大端模式.
【示例】
   
、下面将上述数据按照大小端方式分别进行存储。
【Big-Endian】:低地址存放数据高位
|       高位地址  |           addr[3]  |           data[7:0]  |           'h78  |    
|       |           addr[2]  |           data[15:8]  |           'h56  |    
|       addr[1]  |           data[23:16]  |           'h34  |    |
|       低位地址  |           addr[0]  |           data[31:24]  |           'h12  |    
如果按照不同的数据传输类型,那么每次传输的数据格式如下:
|       传输类型  |           偏移地址  |           'h12  |           'h34  |           'h56  |           'h78  |    
|       data[31:24]  |           data[23:16]  |           data[15:8]  |           data[7:0]  |    ||
|       字  |           0  |           √  |           √  |           √  |           √  |    
|       半字  |           0  |           √  |           √  |           -  |           -  |    
|       半字  |           2  |           -  |           -  |           √  |           √  |    
|       字节  |           0  |           √  |           -  |           -  |           -  |    
|       字节  |           1  |           -  |           √  |           -  |           -  |    
|       字节  |           2  |           -  |           -  |           √  |           -  |    
|       字节  |           3  |           -  |           -  |           -  |           √  |    
【Little-Endian】:低地址存放数据低位
|       高位地址  |           addr[3]  |           data[31:24]  |           'h12  |    
|       |           addr[2]  |           data[23:16]  |           'h34  |    
|       addr[1]  |           data[15:8]  |           'h56  |    |
|       低位地址  |           addr[0]  |           data[7:0]  |           'h78  |    
如果按照不同的数据传输类型,那么每次传输的数据格式如下:
|       传输类型  |           偏移地址  |           'h12  |           'h34  |           'h56  |           'h78  |    
|       data[31:24]  |           data[23:16]  |           data[15:8]  |           data[7:0]  |    ||
|       字  |           0  |           √  |           √  |           √  |           √  |    
|       半字  |           0  |           |           |           √  |           √  |    
|       半字  |           2  |           √  |           √  |           |           |    
|       字节  |           0  |           -  |           -  |           -  |           √  |    
|       字节  |           1  |           -  |           -  |           √  |           -  |    
|       字节  |           2  |           -  |           √  |           -  |           -  |    
|       字节  |           3  |           √  |           -  |           -  |           -  |    

查看22道真题和解析