京东商城网站域名,二手网站建设方案,wordpress在哪儿打开,ie打不开建设企业网站相关阅读
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言#xff0c;Verilog HDL常常需要使用语句描述并行执行的电路#xff0c;但其实在仿真器的底层#xff0c;这些并行执行的语句是有先后顺序…相关阅读
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言Verilog HDL常常需要使用语句描述并行执行的电路但其实在仿真器的底层这些并行执行的语句是有先后顺序的然而Verilog标准并没有将这些事件调度的顺序定死而是给予了仿真器厂商一定的自由去实现自己的产品这就导致了设计者如果不遵循一定的编程习惯会导致意想不到的仿真结果下面是一些相关的规则。
2、在创建分频时钟时使用阻塞赋值 在描述一个对时钟沿敏感的时序逻辑时普遍的建议是使用非阻塞赋值去描述寄存器操作。但这不是绝对的当这个寄存器操作的对象是生成时钟时如果使用了非阻塞赋值就有可能造成仿真出现错误下面就是一个时钟竞争的例子。
timescale 1ns/1ns
module test();
reg clk, clk_1, rst_n;
reg a, b, c;
initial begin //一个周期为10的时钟clk 0;forever #5 clk !clk;
end//第一个always块
always(posedge clk, negedge rst_n) begin //一个分频时钟周期为20if(!rst_n) beginclk_1 1b0;endelse beginclk_1 !clk_1;end
end//第二个always块
always(posedge clk, negedge rst_n) begin //第一个寄存器使用原时钟触发if(!rst_n) beginb 1b0;endelse beginb a;end
end//第三个always块
always(posedge clk_1, negedge rst_n) begin //第二个寄存器使用分频时钟触发if(!rst_n) beginc 1b0;endelse beginc b;end
endinitial beginrst_n 0;#3 rst_n 1;
endinitial begina 1;#24 a 0;
end
endmodule 上面是一个很简单的例子即两个寄存器对输入打两拍不过第一个寄存器使用10ns的周期第二个寄存器使用20ns的周期。竞争会出现在两个时钟的上升沿重合时此时可能的事件调度过程分析如下。
initial块中的clk取反后为高电平触发第一个always块和第二个always块。如Verilog基础时序调度中的竞争一所说这两个块的执行顺序是不定的。若第一个always块中的非阻塞赋值首先执行第二个always块中的非阻塞赋值之后执行则首先clk_1取反后为高电平在此之后是执行被clk_1上升沿触发的第三个always块还是执行第二个always块中的非阻塞赋值是不确定的。若先执行第二个always块后再执行第三个always块则c会直接得到a的值而不会有任何等待。若先执行第三个always块后执行第二个always块则是正常打拍。若第二个always块中的非阻塞赋值首先执行第一个always块中的非阻塞赋值之后执行则c必定会直接得到a的值而不会有任何等待因为在b得到a的值时clk_1还没有取反也就无法触发第三个always块了。 因为在25ns时两个时钟的上升沿重合所以在24ns时我们将a拉低测试波形如图1所示。 图1 一个有竞争的波形图 可以看到在a0后的下一个上升沿b和c同时被拉低这就是竞争所导致的结果。解决这个问题也很简单只需要将第一个always块中的非阻塞赋值改为阻塞赋值即可如下所示。
always(posedge clk, negedge rst_n) begin //一个分频时钟周期为20if(!rst_n) beginclk_1 1b0;endelse beginclk_1 !clk_1;end
end 这样做有什么用这样能保证在第二个always块的非阻塞赋值真正完成前非阻塞赋值分为两步第一步为右值计算第二步为真正完成第三个always块已被触发。下面是修改后没有竞争的波形。