东莞高端网站建设公司哪家好,桂林黄页大全桂林本地信息网,福建中江建设公司网站,福田瑞沃e3自卸车FPGA设计中锁存器产生、避免与消除 一、锁存器的产生1.1 组合逻辑中使用保持状态1.2 组合逻辑中的if-else语句或case语句未列出所有可能性1.3 小结 二、锁存器的避免三、锁存器的消除3.1 情况一 一、锁存器的产生 锁存器的产生主要有以下两种情况#xff1a;#xff08;11组合逻辑中使用保持状态2组合逻辑中的if-else语句或case语句未列出所有可能性
1.1 组合逻辑中使用保持状态
assign data_out valid ? data_in : data_out; //变量保持当前值always (*) beginif(valid)data_out data_in;elsedata_out data_out; //变量保持当前值
end1.2 组合逻辑中的if-else语句或case语句未列出所有可能性 对于组合逻辑中如果使用if-else语句未补全else语句则默认在其他条件下数据均保持为原来的状态那么也会产生锁存器。
//if-else语句缺少else
always (*) beginif(valid)data_out data_in;
end而如果在组合逻辑中使用case语句未列出case中条件所有的可能性则相当于对于未列出的那些情况数据均保持为原来的状态也会产生锁存器。
//case语句未列出所有可能性
always (*) begincase(sel)2b00: data_out 2b00;2b01: data_out data_in;endcase
end1.3 小结 那么总而言之言而总之。对于锁存器其产生的原因可以总结为一点想要通过组合逻辑保持数据不变。对于组合逻辑的实现我们可以认为它是用很多门电路搭建而成的那么门电路与寄存器不同其不具有保持当前状态的功能。也就是说构成当前组合逻辑的电路中任何一个信号发生改变都会导致输出结果发生改变。如果要通过组合逻辑实现保持数据的不变那就只能产生锁存器了可以参考《数字电子技术基础》第五版的SR触发器。
二、锁存器的避免 我们知道了锁存器的产生原因就可以对症下药在编写Verilog代码时注意编码风格即可避免锁存器的产生。
1在组合逻辑中使用if-else语句时补全else语句
always (*) beginif(sel)data_out data_in;elsedata_out 2b00;
end2在组合逻辑中使用case语句时设置默认状态default并默认状态下的数据进行赋值
always (*) begincase(sel)xxx: data_out 2b01;xxx: data_out data_in;default: data_out 2b00;endcase
end3在组合逻辑中不可一个变量赋值给变量自身
//错误示例
always (*) beginif(sel)data_out data_in;elsedata_out data_out; //变量赋值给变量自身
end//正确示例
always (*) beginif(sel)data_out data_in;elsedata_out 2b00; //需要赋值一个准确的数值或者其他变量
end三、锁存器的消除 在FPGA设计过程中有可能出现一些情况必须使用组合逻辑保证其实时性且需要保持数据不变保证其他运算的正确性。那么又该如何处理
3.1 情况一 假如我们要实现如下面时序图所示功能输出data_out在有效信号valid的上升沿处锁存输入data_in的值那么要如何实现 最开始考虑的是采用时序逻辑进行实现代码如下。
always (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)data_out d0;else if(valid)data_out data_in;elsedata_out data_out;
end那么采用时序逻辑实现会导致延迟一怕无法在有效信号valid的上升沿锁存数据如下图所示。 于是考虑使用组合逻辑进行实现代码如下。
assign data_out valid ? data_in : data_out;但是组合逻辑要实现保持状态必然会产生锁存器。综合后会再Messages界面会警告出现锁存器同时在Schematic中也可以看到出现了锁存器如下图所示。而在我们的设计中我们是不希望出现锁存器的因为其不利于时序分析。 那么也可以采用组合逻辑时序逻辑的方式实现通过多使用一部分寄存器资源来实现在valid上升沿处进行数据采样且不产生锁存器代码如下。重新综合后可见锁存器消失同时可以对齐进行仿真时序符合前面的要求。
reg [3:0] r_data_in;always (posedge sys_clk or negedge sys_rst_n)if(!sys_rst_n)r_data_in d0;elser_data_in data_in;assign data_out valid ? data_in ? r_data_in;