module execlc4(
input wire clk,
input wire rst_n,
input wire en,
output reg dout
);
reg [3:0] cnt1,cnt0;
wire add_cnt1,add_cnt0;
wire end_cnt0,end_cnt1;
reg flag_add;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt0<=0;
else if(add_cnt0)begin
if(end_cnt0)
cnt0<=0;
else
cnt0<=cnt0+1;
end
end
assign add_cnt0=flag_add==1;
assign end_cnt0=add_cnt0&&cnt0==3-1;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt1<=0;
else if(add_cnt1)begin
if(end_cnt1)
cnt1<=0;
else
cnt1<=cnt1+1;
end
end
assign add_cnt1=end_cnt0==1;
assign end_cnt1=add_cnt1&&cnt1==3-1;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
dout<=0;
else if(add_cnt0&&cnt0==0)
dout<=1;
else if(end_cnt0)
dout<=0;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
flag_add<=0;
else if(en==1)
flag_add<=1;
else if(end_cnt1)
flag_add<=0;
end
endmodule
module execlc3(
input wire clk,
input wire rst_n,
input wire en1,
input wire en2,
output reg dout
);
reg [3:0] cnt;
wire add_cnt;
wire end_cnt;
reg [3:0]x;
reg flag_sel;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt<=0;
else if(add_cnt)begin
if(end_cnt)
cnt<=0;
else
cnt<=cnt+1;
end
end
assign add_cnt=dout==1;
assign end_cnt=add_cnt&&cnt==x-1;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
dout<=0;
else if(en1||en2)
dout<=1;
else if(end_cnt)
dout<=0;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
flag_sel<=0;
else if(en1)
flag_sel<=0;
else if(en2)
flag_sel<=1;
end
always@(*)begin
if(flag_sel==0)
x=3;
else
x=2;
end
endmodule
module execlc2(
input wire clk,
input wire rst_n,
input wire en,
output reg dout
);
reg [4:0] cnt;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt<=0;
else if(en)
cnt<=0;
else
cnt<=cnt+1;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
dout<=0;
else if(cnt==5'd2||cnt==5'd3)
dout<=1;
else if(cnt==5'd4)
dout<=0;
else
dout<=0;
end
endmodule
module execlc(
input wire clk,
input wire rst_n,
input wire en,
output reg dout
);
reg [3:0] cnt;
wire add_cnt;
wire end_cnt;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt<=0;
else if(add_cnt)begin
if(end_cnt)
cnt<=0;
else
cnt<=cnt+1;
end
end
assign add_cnt=dout==1;
assign end_cnt=add_cnt&&cnt==10-1;
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
dout<=0;
else if(en==1)
dout<=1;
else if(end_cnt)
dout<=0;
end
endmodule
/*
计数器八步法
1.明确信号
2.功能波形
3.计数结构
4.加一结束条件
5.定义特殊点
6.完整性检查
7.计数器代码
8.功能代码
design1:当收到en后,dout产生一个宽度为10个时钟周期的高电平脉冲
design2:功能要求:当收到en=1,dout间隔3个时钟后,产生宽度为2个时钟周期的高电平脉冲
design3:功能要求:
当收到en=1,dout产生3个时钟周期的高电平脉冲,
当收到en2=1,dout产生2个时钟周期的高电平脉冲,
design4;
当收到en=1,dout间隔1个时钟后,产生宽度为2个时钟周期的高电平脉冲,并且重复三次
module tb_test;
reg clk,rst_n,en;
reg [5:0] cnt;
initial begin
clk<=0;
rst_n<=0;
#100
rst_n<=1;
end
always #10 clk<=~clk;
execlc4 u_exelc4(
.clk(clk),
.rst_n(rst_n),
.en(en),
.dout(dout)
);
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
en<=0;
else if(cnt==6'd60)
en<=1;
else
en<=0;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)
cnt<=0;
else if(cnt==6'd60)
cnt<=0;
else
cnt<=cnt+1;
end
endmodule