💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] >## 硬件原则 **硬件原则**主要针对HDL代码编写而言:Verilog是采用了C语言形式的硬件的抽象,它的本质作用在于描述硬件,它的最终实现结果是芯片内部的实际电路。**所以评判一段HDL代码的优劣的最终标准是:其描述并实现的硬件电路的性能,包括面积和速度两个方面**。</br> 初学者片面追求代码的整洁、简短,是错误的,是与HDL的标准背道而驰的。正确的编码方法,首先要做到**对所需实现的硬件电路胸有成竹**,对该部分的硬件的结构和连接十分清晰,然后再用适当的HDL语句表达出来即可。 >## 几个典型的例子 ### 异步复位 ``` module test ( input clk, input rst_n, input data_in, output reg out ); always @ (posedge clk or negedge rst_n) if(!rst_n) out <= 1'b0; else out <= data_in; endmodule ``` ![](https://img.kancloud.cn/e9/50/e95006566b43c19acd1f9f832f504647_380x196.png) 可以看到FPGA的寄存器都有一个异步的清零端(CLR),在异步复位的设计中这个端口一般就是接低电平有效的复位信号rst_n。 即使说你的设计中是高电平复位,那么实际综合后会把你的复位信号反向后接这个CLR端。 ### 同步复位 ``` module test ( input clk, input rst_n, input data_in, output reg out ); always @ (posedge clk ) if(!rst_n) out <= 1'b0; else out <= data_in; endmodule ``` ![](https://img.kancloud.cn/d6/f9/d6f958de3e55070f3e9b4c3de6811560_487x182.png) 和异步复位相比,同步复位没有用上寄存器的CLR端口,综合出来的实际电路只是把复位信号rst_n作为了输入逻辑的使能信号。那么,这样的同步复位势必会额外增加FPGA内部的资源消耗</br> 那么同步复位和异步复位到底孰优孰劣呢? 只能说,各有优缺点。同步复位的好在于它只在时钟信号clk的上升沿触发进行系统是否复位的判断,这降低了亚稳态出现的概率;它的不好上面也说了,在于它需要消耗更多的器件资源,这是我们不希望看到的。FPGA的寄存器有支持异步复位专用的端口,采用异步复位的端口无需额外增加器件资源的消耗,但是异步复位也存在着隐患。异步时钟域的亚稳态问题同样的存在与异步复位信号和系统时钟信号之间。 ### 两级寄存器异步复位 ``` module test ( input clk, input rst_n, input a, output reg c ); reg b; always @ (posedge clk or negedge rst_n) if(!rst_n) b <= 1'b0; else b <= a; always @ (posedge clk or negedge rst_n) if(!rst_n) c <= 1'b0; else c <= b; endmodule ``` ![](https://img.kancloud.cn/06/40/06403b23ba986113e9b1ac030303fc46_512x224.png) ### 异步复位、同步释放 ``` module test ( input clk, input rst_n, input a, output reg c ); reg b,rst_nr; always @ (posedge clk) rst_nr <= rst_n; always @ (posedge clk or negedge rst_nr) if(!rst_nr) b <= 1'b0; else b <= a; always @ (posedge clk or negedge rst_nr) if(!rst_nr) c <= 1'b0; else c <= b; endmodule ``` ![](https://img.kancloud.cn/be/c8/bec83a82b6bf8bab24641d5894bb4a02_637x234.png) 如此一来,既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。 **最好的异步复位、同步释放--------复位方法**