前言:本章内容主要是演示Vivado下利用Verilog语言进行电路设计、仿真、综合和下载
示例:触发器电路
目录
Ⅰ. 前置知识
0x00 利用7400搭建RS触发器
0x01 D触发器
0x02 带复位的D触发器
0x03 带置位/复位的D触发器
Ⅱ. Verilog实现
0x00 RS触发器(上升沿触发)
0x01 D触发器 (上升沿触发)
0x02 带复位的D触发器
0x03 同步置位/复位端口的上升沿 D 触发器
0x04 异步置位/复位端口的上升沿 D 触发器
注意:
a、由于 时触发器输出保持,因此若初始状态,仿真启动时会报错或状态不定。
得出RS触发器的真值表如下:
输 入 |
输 出 |
||
Q |
|||
0 |
0 |
保持不变 |
|
0 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1(0) |
1(0) |
在数字电路中,D触发器是最为简单也是最为常用的一种基本时序逻辑电路,它是构成数字电路系统的基础。
大体可分为如下几类:基本的D触发器;同步复位的D触发器;异步复位的D触发器;同步置位/复位的D触发器;异步置位/复位的D触发器。
设计上升沿触发的D触发器,即当检测到时钟上升沿到来时,触发器根据真值表输出:
触发器 |
D |
CP |
Q |
Q’ |
D |
X |
0 |
保持 |
保持 |
D |
X |
1 |
保持 |
保持 |
D |
0 |
上升沿 |
0 |
1 |
D |
1 |
上升沿 |
1 |
0 |
在数字电路中,一种常见的带有复位控制端口的上升沿D触发器的功能表如表所示:
触发器 |
R |
D |
CP |
Q |
Q’ |
D |
0 |
X |
上升沿(同步复位) |
0 |
1 |
D |
0 |
X |
X(异步复位) |
0 |
1 |
D |
1 |
X |
0 |
保持 |
保持 |
D |
1 |
X |
1 |
保持 |
保持 |
D |
1 |
0 |
上升沿 |
0 |
1 |
D |
1 |
1 |
上升沿 |
1 |
0 |
不难看出,同步复位意味着只有在时钟信号的上升沿到来并且复位控制端口的信号有效时,D触发器才进行复位操作,即将输出端口Q的值置为逻辑0,而把输出端口Q的值置为逻辑1;异步复位在于只要复位控制端口的信号有效,D触发器就会立即进行复位操作,这时的复位操作是与时钟信号无关的。
带有同步置位/复位端口的上升沿D触发器的逻辑电路符号如图所示:
它的功能表如表所示:
触发器 |
S |
R |
D |
CP |
Q |
Q’ |
D |
1 |
0 |
X |
上升沿(同步复位) |
0 |
1 |
D |
0 |
1 |
X |
上升沿(同步复位) |
1 |
0 |
D |
1 |
1 |
X |
0 |
保持 |
保持 |
D |
1 |
1 |
X |
1 |
保持 |
保持 |
D |
1 |
1 |
0 |
上升沿 |
0 |
1 |
D |
1 |
1 |
1 |
上升沿 |
1 |
0 |
不难看出,只有在时钟信号的上升沿到来并且同步置位/复位端口的信号有效时,D触发器才可以进行置位或者复位操作。
设计代码:
module RS(clk,R,S,q,qb);
input clk,R,S;
output q,qb;
reg q;
assign qb=~q;
always@(posedge clk)
case({R,S})
2'b01: q<=0;
2'b10: q<=1;
2'b00: q<=1'bx;
endcase
endmodule
仿真代码:
module test();
reg clk,R,S;
wire q,qb;
RS uut(
.R(R),
.S(S),
.clk(clk),
.q(q),
.qb(qb)
); initial
begin
clk=0;
end
always #10 clk=~clk;
initial
begin
R=0;S=0;
#10 R=0;S=1;
#20 R=1;S=0;
#20 R=1;S=1;
#20 $finish;
end
endmodule
仿真波形:
设计文件:
module async_rddf(clk, d,q,qb);
input clk, d;
output q,qb;
reg q,qb;
always @(posedge clk) begin
q<=d; qb<=~d;
end
endmodule
仿真文件:
`timescale 1ns / 1ns
module test;
reg clk; reg d;
wire q; wire qb;
async_rddf uut (.clk(clk), .d(d), .q(q), .qb(qb));
initial begin
clk = 0;
d = 0;
#100;
end
always #20 clk=~clk;
always #30 d=~d;
endmodule
仿真波形:
设计文件:
module sync_rddf(clk,reset,d,q,qb);
input clk,reset,d;
output q,qb;
reg q,qb;
always @(posedge clk) begin
if(!reset) begin
q<=0;
qb<=1;
end
else begin
q<=d;
qb<=~d;
end
end
endmodule
仿真文件:
`timescale 1ns / 1ns
module test;
reg clk; reg d;reg reset;
wire q; wire qb;
sync_rddf uut (.reset(reset),.clk(clk), .d(d), .q(q), .qb(qb));
initial begin
clk = 0;
d = 0;
reset = 0;
#100;
end
always #25 reset=~reset;
always #20 clk=~clk;
always #30 d=~d;
endmodule
仿真波形:
设计代码:
module sync_rsddf(clk,reset,set,d,q,qb);
input clk,reset,set;
input d;
output q,qb;
reg q,qb;
always @(posedge clk) begin
if(!set && reset) begin
q<=1;
qb<=0;
end
else if(set && !reset) begin
q<=0;
qb<=1;
end
else begin
q<=d;
qb<=~d;
end
end
endmodule
仿真代码:
`timescale 1ns / 1ns
module test;
reg clk; reg d;reg reset;reg set;
wire q; wire qb;
sync_rsddf uut (.set(set),.reset(reset),.clk(clk), .d(d), .q(q), .qb(qb));
initial begin
clk = 0;
d = 0;
reset = 0;
set = 0;
#100;
end
always #25 reset=~reset;
always #10 set=~set;
always #20 clk=~clk;
always #30 d=~d;
endmodule
仿真波形:
设计代码:
module set_D(clk,n_reset,n_set,d,q,qb);
input clk,n_reset,n_set;
input d;
output q,qb;
reg q,qb;
always @(posedge clk or negedge n_reset or negedge n_set)
begin
if(!n_set && n_reset)
begin
q<=1;
qb<=0;
end
else if(n_set && !n_reset)
begin
q<=0;
qb<=1;
end
else
begin
q<=d;
qb<=~d;
end
end
endmodule
仿真代码:
module sim_set_D();
reg clk,n_reset,n_set;
reg d;
wire q,qb;
set_D uu1(clk,n_reset,n_set,d,q,qb);
initial {clk,n_reset,n_set,d}=4'b0000;
always #20 clk=~clk;
always #40 n_reset=~n_reset;
always #80 n_set=~n_set;
always #30 d=~d;
endmodule
仿真波形: