概述
在数电中
异步指输入信号和时钟无关
同步指输入信号和始终相关
异步复位(比同步复位增加了一个下降沿的输入信号):
always @ (posedge clk or negedgerst_n)
if(!rst) b <=1'b0;
else b<=a;
同步复位:
always @ (posedge clk)
if(!rst) b<=1'b0
else b <= a;
![](https://i-blog.csdnimg.cn/blog_migrate/784bf5ed1674693cf9b2cc1f9395a978.png)
如上图所示异步复位的周期要比同步复位的周期要更长
对于同步复位来说 复位的一个周期一定要大于时钟信号的周期,这样可以保证可以复位
![](https://i-blog.csdnimg.cn/blog_migrate/1e0df4cc55f1bc46cbc172310dfcaf18.png)
无法完成复位的情况是当clk的上升沿信号正好和rst的下降信号重合时,
同步复位的话此时无法判断rst信号的是高电平还是低电平
异步复位的话只要读到rst有下降沿就会进行复位
处理竞争冒险最好的方法是:异步复位,同步释放
(1条消息) 异步复位、同步释放_小小verifier的博客-CSDN博客_同步复位异步释放
【数字IC手撕代码】Verilog异步复位同步释放|题目|原理|设计|仿真_myhhhhhhhh的博客-CSDN博客_verilog dff亚稳态仿真
释放信号的定义:将复位信号从低电平向高电平拉高
产生竞争冒险的原因:rst信号无法判断是时钟信号先到还是复位信号先到,rst下降沿和clk信号的上升沿交叉
![](https://i-blog.csdnimg.cn/blog_migrate/aa75f4300fe177bfa29b49aae7ff189d.png)
同步清零:
module dff(d,clk,clr,q);
input d,clk,clr;
output reg q;
always @ (posedge clk)
if(!clr)q<=0;
else q<=d;
endmodule
异步清零:
module dff(d,clk,clr,q);
input d,clk,clr;
output q;
reg q;
always@(posedge clk or negedge clr)
if(!clr)q<=0;
else q<=d;
endmodule
同步复位和异步复位的同步的区别就在于前者的复合信号不能出现在always语句的敏感信号表中:
无论是同步复位还是异步复位,always语句的结构都是if(Reset)...else...否则,综合工具将不能正确的综合
case条件语句-多分支语句
当敏感表达式取不同的值时,执行不同的语句
功能:当某个(控制)信号取不同的值时,给另一个(输出)信号赋不同的值。常用于多条件译码电路(如译码器、数据选择器、状态机等)
case语句有三种形式:case、casez、casex
![](https://i-blog.csdnimg.cn/blog_migrate/bf93cfe12baedcd80664a45b7b5fc38b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/9e692f656fb7129fd81067d37b156ddf.png)
建议加上default语句(删掉也是可以的)
四选一多路选择器
四选一多路选择器-电路图
![](https://i-blog.csdnimg.cn/blog_migrate/c7319035281748a939ee62888705d9e9.png)
四选一多路选择器-verilog代码(选择器要用阻塞赋值)
module mux4_to_1(out,i0,i1,i2,i3,s1,s0);
output out;
input i0,i1,i2,i3;//输入信号可以是wire型
input s1,s0
output out;
reg out;
always @(s1,s0,i0,i1,i2,i3)
begin
case({s1,s0})
2'b00:out = i0;//在alway@块中被赋值的out一定是reg型
2'b01:out = i1;
2'b10:out = i2;
2'b11:out = i3;
default:out = 1'b?;//?可以表示一个高阻态
endcase
end
endmodule
ps:高阻态值得是:既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。
组合逻辑用阻塞赋值,时序逻辑要用非阻塞赋值;
多路选择器
module my_mux(
input [2:0] a,b,c,d,e,
input [2:0] sel,
output reg [2:0] out
);
always @ (a,b,c,d,e,sel)
begin
case(sel)
3'b000:out = a;
3'b001:out = b;
3'b010:out = c;
3'b011:out = d;
3'b100:out = e;
default :out = 1'b?//一位的可以赋值给一个三位的out
endcase
end
endmodule
casez与casex语句
在case语句中,分支表达式每一位的值都是确定的(或者为0,或者为1);
在casez语句中,若分支表达式某些位的值为高阻态z,则不考虑对这些位的比较;
在casex语句中,若分支表达式某些位的值为z或不定值x,则不考虑对这些位的比较
在分支表达式中,可用“?”来标识z
![](https://i-blog.csdnimg.cn/blog_migrate/126d775445445a85cad172ab1a40a99f.png)
条件语句-case语句
用case描述的数据选择器
module mux_z(out,a,b,c,d,sel);
output out;
input a,b,c,d;
input[3:0] sel;
reg out;//必须声明
always@ (sel[3:0],a,b,c,d)
begin
casez(sel)
4'b???1: out = a;
4'b??1?: out = b;
4'b?1??: out = c;
4'b 1???: out = d;
default : out = 1‘bx//为不定态
endcase
end
endmodule
若sel为0001则out=a;
若sel为0011则out=a;
若sel为0010则out=b;
若sel为0000则 out = 1’bx为不定态
在组合电路设计中,应避免生成隐含锁存器,有效的方法是在if-else语句最后写上else项;
在case语句最后写上default项
一般很少用casex语句
case的描述,匹配都是从上到下进行的
if-else语句生成锁存器
![](https://i-blog.csdnimg.cn/blog_migrate/f1d8113bf9fb368e7c6dbb6eb10a434e.png)
case-endcase生成锁存器
![](https://i-blog.csdnimg.cn/blog_migrate/a89b1982fc95a44e137c55864dc5e66f.png)
将make file文件中的gui删掉后,不会吊起make all的图形界面,只会跑仿真,跑出语法错误
![](https://i-blog.csdnimg.cn/blog_migrate/bc91ee00e0f83fb2686d111e5ef0d602.png)