计数器结构
计数器结构是通过一个或多个计数器,搭建成整个设计的框架,从而作为其他信号对齐的条件。计数器优秀的标准是:能用计数器指示任何一个时钟;能方便的被其他信号归纳使用。
以下为学习代码 ,尽量把时序逻辑跟组合逻辑分开
//计数器结构
//------------------------------------------------------------------------------------------------------------------------------------------------
//明德扬定义计数器
//计数器规则1:计数器逐一考虑3要素:初值、加一条件、结束值
//计数器规则2:计数器初值必须为零
//计数器规则3:使用某一计数器值,必须同时满足加一条件
//计数器规则4:结束条件必须同时满足加一条件
//计数器规则5:当取某个数时,assign的形式必须为:(加一条件)&&(cnt==计数值-1);
//计数器规则6:结束后必须回到0;
//计数器规则7:若要限定范围,则推荐使用">=“和”<"两种符号;
//计数器规则8:设计步骤是,先写计数器的always段,条件用名字代替,然后用assign写出加1条件;最后用assign写出结束条件;
//计数器规则9:加1条件必须与计数器严格对齐,其他信号一律向计数器对齐;
//计数器规则10:命名规则必须符合规范,比如:add_cnt表示加1条件;end_cnt表示结束条件;
//计数器规则11:减1计数器暂时不用。
//计数器八步法
// 第一步:功能明确
// 第二步:功能波形
// 第三步:计数结构 ------根据波形找出实现时序需要的计数器数量和结构
// 第四步:加1和结束条件
// 第五步:定义特殊点
// 第六步:完整性检查
// 第七步:计数器代码
// 第八步:功能代码
//定义计数器cnt
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
cnt <= 0; //计数器初值
end
else if(add_cnt)
begin
if(end_cnt)
cnt <= 0;
else
cnt <= cnt + 1;
end
end
assign add_cnt = flag == 1'b1; //加一条件
assign end_cnt = add_cnt && cnt == x + y -1;//结束值
//定义计数器cnt_t
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
cnt_c <= 0;
end
else if(add_cnt_c)
begin
if(end_cnt_c)
cnt_c <= 0;
else
cnt_c <= cnt_c + 1;
end
end
assign add_cnt_c = end_cnt;
assign end_cnt_c = add_cnt && cnt_c == 4 -1;
//------------------------------------------------------------------------------------------------------------------------------------------------
//组合逻辑与时序逻辑分开的计数器电路
//------------------------------------------------------------------------------------------------------------------------------------------------
//定义计数器cnt
//时序逻辑
always @ (posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0) //判断复位
cnt <= 1'b0; //初始化cnt值
else
cnt <= cnt_n; //用来给cnt赋值
end
//组合电路,实现1s的定时计数器
always @ (*)
begin
if(end_cnt) //结束值
cnt_n = 1'b0;
else if(add_cnt) //加一条件
cnt_n = cnt_n + 1'b1;
else
cnt_n = cnt;
end
assign add_cnt = flag == 1'b1;
assign end_cnt = add_cnt && cnt == x + y -1;
//--------------------------------------------------------------------------------------------
//定义计数器cnt_c
//时序逻辑
always @ (posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0) //判断复位
cnt_c <= 1'b0; //初始化cnt_c值
else
cnt_c <= cnt_c_n; //用来给cnt_c赋值
end
//组合电路,实现1s的定时计数器
always @ (*)
begin
if(end_cnt_c) //结束值
cnt_c_n = 1'b0;
else if(add_cnt_c) //加一条件
cnt_c_n = cnt_c_n + 1'b1;
else
cnt_c_n = cnt_c;
end
assign add_cnt_c = end_cnt;
assign end_cnt_c = add_cnt && cnt_c == 4 -1;
//------------------------------------------------------------------------------------------------------------------------------------------------
//功能代码
//------------------------------------------------------------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
dout <= 0;
end
else if(dout_12h)
begin
dout <= 1;
end
else if (end_cnt)
begin
dout <= 0;
end
assign dout_12h = add_cnt && cnt == x - 1;
//------------------------------------------------------------------------------------------------------------------------------------------------
//组合逻辑与时序逻辑分开的计数器电路
//------------------------------------------------------------------------------------------------------------------------------------------------
//时序逻辑
always @ (posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
dout <= 0;
else
dout <= dout_n;
end
//组合电路,实现1s的定时计数器
always @ (*)
begin
if(dout_12h)
dout_n = 1;
else if(end_cnt)
dout_n = 0;
else
dout_n = dout;
end
assign dout_12h = add_cnt && cnt == x - 1;
//--------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
flag <= 0;
end
else if(en)
begin
flag <= 1;
end
else if(end_cnt_c)
begin
flag <= 0;
end
end
//------------------------------------------------------------------------------------------------------------------------------------------------
//组合逻辑与时序逻辑分开的计数器电路
//------------------------------------------------------------------------------------------------------------------------------------------------
//时序逻辑
always @ (posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
flag <= 0;
else
flag <= flag_n;
end
//组合电路,实现1s的定时计数器
always @ (*)
begin
if(en)
flag_n = 1;
else if(end_cnt_c)
flag = 0;
else
flag_n = flag;
end
//--------------------------------------------------------------------------------------------
always @(*)
begin
if(cnt_c == 0)
begin
x = 1;
y = 1;
end
else if(cnt_c == 1)
begin
x = 1;
y = 2;
end
else if(cnt_c == 2)
begin
x = 1;
y = 3;
end
else if(cnt_c == 3)
begin
x = 1;
y = 4;
end
else
begin
x = 0;
y = 0;
end
end
//------------------------------------------------------------------------------------------------------------------------------------------------
//组合逻辑与时序逻辑分开的计数器电路
//------------------------------------------------------------------------------------------------------------------------------------------------
//此模块为纯组合逻辑
//------------------------------------------------------------------------------------------------------------------------------------------------