前言:
D触发器
基本D触发器
//DFF1 基本D触发器
module DFF1 (CLK,D,Q);
output Q;
input CLK , D;
reg Q;
always @(posedge CLK)
Q <= D ;
endmodule
含异步复位和时钟使能的D触发器
//DFF2 含异步复位和时钟使能的D触发器
module DFF1 (CLK , D, Q, RST,EN);
output Q;
input CLK,D,RST,EN;
reg Q;
always @(posedge CLK or negedge RST)
begin
if (!RST ) Q<= 0;
else if (EN) Q <= D;
end
endmodule
含同步复位控制的D触发器
//DFF3 含同步复位控制的D触发器
module DFF1 (CLK,D,Q,RST);
output Q;
input CLK,D,RST;
reg Q;
always @(posedge CLK )
if (RST == 1) Q = 0;
else if (RST == 0) Q = D;
endmodule
/*
module DFF1 (CLK,D,Q,RST);
output Q;
input CLK,D,RST;
reg Q,Q1;
always @(RST)
if (RST == 1) Q1 = 0;
else Q1 = D;
always @(posedge CLK )
Q <= Q1;
endmodule
*/
/*
module DFF1 (input CLK, input D,input RST, output reg Q);
always @(posedge CLK)
Q <= RST ? 1'b0 : D;
endmodule
*/
仿真结果采用的是第一种
基本锁存器
含同步预置的移位寄存器设计
module SHFT1 (CLK,LOAD,DIN,QB,DOUT);
output QB;
output [7:0] DOUT;
input CLK,LOAD;
input [7:0] DIN;
reg [7:0] REG8;
always @(posedge CLK)
if(LOAD) REG8<=DIN;
else REG8[6:0]<=REG8[7:1];
assign QB =REG8[0];
assign DOUT=REG8;
endmodule
自动预置型计数器设计
同步加载计数器
//同步加载计数器
module FDIV0 (input CLK,RST,
input [3:0]D,
output PM,
output[3:0]DOUT,
output LD1);
reg[3:0]Q1;reg FULL;
(* synthesis,keep *)wire LD;//设定LD为仿真可测试属性
always @(posedge CLK or negedge RST)
if(!RST) begin Q1<=0;FULL<=0;end
else if (LD) begin Q1<=D;FULL<=1;end
else begin Q1<=Q1+1;FULL<=0;end
assign LD=(Q1==4'B1111);assign PM=FULL;assign DOUT=Q1;
assign LD1=LD;
endmodule
如果是按照书上来说,理应是会产生毛刺的,是因为软件问题吗,我这里没看到毛刺(待验证)
异步加载计数器
//异步加载计数器
module fdiv1 (CLK,PM,D,DOUT,RST,LD1);
input CLK;input RST;input [3:0] D;
output PM;output [3:0] DOUT;
reg [3:0] Q1;reg FULL;
output LD1;
(* synthesis ,probe_port,keep *) wire LD;
always @(posedge CLK or posedge LD or negedge RST)
if(!RST) begin Q1<=0;FULL<=0;end
else if(LD) begin Q1<=D;FULL<=1;end
else begin Q1<=Q1+1;FULL<=0;end
assign LD =(Q1==4'B0000);
assign PM = FULL;
assign DOUT=Q1;
assign LD1=LD;
endmodule
异步清0加载计数器
//异步清0加载计数器
module fdiv1 (CLK,PM,D,Q,DOUT);
input CLK;
input [3:0] D;
output PM;
reg FULL;
output [3:0] Q;
output DOUT;
(* synthesis ,probe_port,keep *) reg [3:0] Q1;
(* synthesis ,probe_port,keep *) wire RST;
always @(posedge CLK or posedge RST)
if(RST)
begin
Q1<=0;
FULL<=1;
end
else
begin
Q1<=Q1+1;
FULL<=0;
end
assign RST = (Q1==D);
assign PM = FULL;
assign Q=Q1;
assign DOUT = RST;
endmodule
同步清0加载计数器
把上述代码的敏感信号改为
always @(posedge CLK)
//10进制同步(复位使能加载)的计数器
//10进制同步复位使能加载的计数器
module FDIV0 (
// 输入端口
input CLK, // 时钟信号,用于同步操作
input RST, // 复位信号,用于将计数器复位到初始状态
input LOAD_EN, // 加载使能信号,用于控制是否加载新的计数初值
input [9:0] D, // 输入数据,用于在 LOAD_EN 为高时加载到计数器中
// 输出端口
output PM, // 满标志输出,当计数器满时输出高电平
output [9:0] DOUT, // 计数器输出,显示当前计数器的值
output LD1 // 溢出标志输出,当计数器达到最大值时输出高电平
);
// 定义寄存器和线网
reg [9:0] Q1; // 存储计数器的当前值
reg FULL; // 满标志,用于指示计数器是否已满
wire LD; // 溢出标志,用于指示计数器是否达到最大值
always @(posedge CLK or negedge RST)// 同步过程块,在时钟上升沿或复位信号下降沿触发
begin
if (~RST) begin Q1 <= 10'b0;FULL <= 0;end// 如果复位信号为低(即复位),则将计数器清零,满标志置为低
else if (LOAD_EN) begin Q1 <= D;FULL <= 1;end// 如果加载使能信号为高,则加载输入数据到计数器,满标志置为高
else if (FULL) begin Q1 <= Q1 + 1;end// 如果满标志为高,则计数器加一
end
assign LD = (Q1 == 10'b1111_111111);// 连续赋值语句,当计数器的值等于最大值时,LD 信号置为高
assign PM = FULL;// 连续赋值语句,PM 输出满标志的状态
assign DOUT = Q1;// 连续赋值语句,DOUT 输出计数器的当前值
assign LD1 = LD;// 连续赋值语句,LD1 输出溢出标志的状态
endmodule // 模块定义结束