芯片设计验证社区·芯片爱好者聚集地·硬件相关讨论社区·数字verifier星球 四社区联合力荐!近500篇数字IC精品文章收录!
一、前言
本系列旨在提供100%准确的数字IC设计/验证手撕代码环节的题目,原理,RTL设计,Testbench和参考仿真波形,每篇文章的内容都经过仿真核对。快速导航链接如下:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
应当说,手撕代码环节是面试流程中既重要又简单的一个环节,跟软件类的岗位相比起来,数字IC的手撕代码题目固定,数量有限,属于整个面试中必得分的一个环节,在这个系列以外,笔者同样推荐数字IC求职者使用“HdlBits”进行代码的训练 链接如下
二、题目
使用verilog语言,完成4bit二进制输入的格雷码的转换
三、原理
格雷码想要解决什么?、
生活中我们最常接触到的是natural code也可以称为8421码,在这种码制中,十进制的3和4分别在二进制中表示为011和100,在naturalcode中由3转换到4的过程中,可以发现一共有3位发生变化,因为不同的位 改变(指0到1或1到0)到达的时间可能不相同,所以采样的时候可能 采到正确的结果 100,也可能 采样到错误的结果 比如111/101等
什么是格雷码
因为这个问题,我们提出了一种新的码值,他的特点就是相邻两位只有单bit发生改变,这里提前引用格雷码中的3和4的表示0010和0110,这个时候采样从3到4,只有可能采样到0010和0110,即前一个结果和后一个结果,不会出现这两者之外的错位结果,格雷码的优势由此体现,也正是因为格雷码的优势,它广泛的应用在包括FIFO,跨时钟域的通信,纠错等内容中。
格雷码的转换表
在这里其实就可以发现,格雷码的转换其实是在纯组合逻辑下的由natural code转换到gray code的过程。
四、RTL设计
module gray_change(binary_code, gray _code); input [3:0] binary_code; output [3:0] gray_code; assign gray_code = binary_code ^ (binary_code >> 1); endmodule
这里再稍微讨论一下“自身” 与 “自身右移一位” 取异或,生成格雷码的方法,这个方法只适用于2^N情况,因为格雷码的一个重要应用就是FIFO,这个生成方法对于FIFO的深度约束起到了重要的作用,即FIFO的深度只能是8位16位32位64位这种情况,假如我们想使用一个偶数深度,比如10位,14位,我们需要其他的方式来生成格雷码,这里我们按下不表,以后再更新一篇如何生成非2次方项的格雷码。
五、Testbench
`timescale 1ns /1ps module gray_code_tb(); reg [3:0] binary_code; wire [3:0] gray_code; gray_code u1(.binary_code(binary_code),.gray_code(gray_code)); initial begin binary_code = 4b1001; #30 binary_code = 4b1010; #30; $stop; end endmodule
六、仿真结果分析
比较了两个值,换成了十进制,上面的是natural code,下面的是gray_code,发现结果正确
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/292363.html