一、D触发器
D触发器在时钟的上升沿或下降沿存储数据,输出与时钟跳变之间输入信号状态相同。
top.v
module top(d,clk,q);
input d;
input clk;
output reg q;
always @(posedge clk)
begin
q <= d;
end
endmodule
top_tb.v
module top_tb(
);
reg d;
reg clk;
wire q;
initial
begin
d = 0;
clk = 0;
forever
begin
#({$random}%100)
d = ~d;
end
end
always #10 clk = ~clk;
top t0(.d(d),.clk(clk),.q(q));
endmodule
二、两级D触发器
软件是按照两级D触发器的模型进行时序分析的,具体可以分析在同一时刻两个D触发器输出的数据有何不同。
top.v
module top(d,clk,q,q1
);
input d;
input clk;
output reg q;
output reg q1;
always @ (posedge clk)
begin
q <= d;
end
always @(posedge clk)
begin
q1 <= q;
end
endmodule
top_tb.v
module top_tb(
);
reg d;
reg clk;
wire q;
wire q1;
initial
begin
d = 0;
clk = 0;
forever
begin
#({$random}%100)
d = ~d;
end
end
always #10 clk = ~clk;
top t0(.d(d),.clk(clk),.q(q),.q1(q1));
endmodule
三、带一部复位的D触发器
异步复位指独立于时钟,一旦异步复位信号有效,就触发复位操作。电路图如下
注意需要把异步复位信号放在敏感列表里面,如果低电平复位,即为negedge,如果是高电平复位,则是posedge
top.v
module top(d,rst,clk,q
);
input d;
input rst;
input clk;
output reg q;
always @(posedge clk or negedge rst)
begin
if(rst == 1'b0)
q <= 0;
else
q <= d;
end
endmodule
top_tb.v
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/21 16:25:12
// Design Name:
// Module Name: top_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top_tb(
);
reg d;
reg rst;
reg clk;
wire q;
initial
begin
d = 0;
clk = 0;
forever
begin
#({$random}%100)
d = ~d;
end
end
initial
begin
rst = 0;
#200 rst = 1;
end
always #10 clk = ~clk;
top t0(.d(d),.rst(rst),.clk(clk),.q(q));
endmodule
四、带异步复位同步清零的D触发器
前面讲到异步复位独立于时钟操作,而同步清零则是同步于时钟信号下的操作,当然也不仅限于同步清零,也可以是其他的同步操作,其RTL图如下:
代码如下,不同于异步复位,同步操作不能把信号放到敏感列表里
代码
top.v
module top(d,rst,clr,clk,q
);
input d;
input rst;
input clr;
input clk;
output reg q;
always @(posedge clk or negedge rst)
begin
if(rst == 1'b0)
q <= 0;
else if(clr == 1'b1)
q <= 0;
else
q <= d;
end
endmodule
top_tb.v
module top_tb(
);
reg d;
reg rst;
reg clr;
reg clk;
wire q;
initial
begin
d = 0;
clk = 0;
forever
begin
#({$random}%100)
d = ~d;
end
end
initial
begin
rst = 0;
clr = 0;
#200 rst = 1;
#200 clr = 1;
#100 clr = 0;
end
always #10 clk = ~clk;
top t0(.d(d),.rst(rst),.clr(clr),.clk(clk),.q(q));
endmodule
五、以为寄存器
移位寄存器是指在每个时钟脉冲来时,向左或向右移动一位,由于D触发器的特性,数据输出同步于时钟边沿,其结构如下,每个时钟来临,每个D触发器的输出q等于前一个D触发器输出的值,从而实现移动的功能。
top.v
module top(
d,rst,clk,q
);
input d;
input rst;
input clk;
output reg [7:0]q;
always @(posedge clk or negedge rst)
begin
if(rst == 1'b0)
q<=0;
else
q <= {q[6:0],d};
end
endmodule
top_tb.v
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/11/22 13:05:41
// Design Name:
// Module Name: top_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module top_tb(
);
reg d;
reg rst;
reg clk;
wire[7:0] q;
initial
begin
d = 0;
clk = 0;
forever
begin
#({$random}%100)
d = ~d;
end
end
initial
begin
rst = 0;
#200 rst = 1;
end
always #10 clk=~clk;
top t0(.d(d),.rst(rst),.clk(clk),.q(q));
endmodule