FPGA学习笔记-------计数器结构01

计数器结构

计数器结构是通过一个或多个计数器,搭建成整个设计的框架,从而作为其他信号对齐的条件。计数器优秀的标准是:能用计数器指示任何一个时钟;能方便的被其他信号归纳使用。

以下为学习代码 ,尽量把时序逻辑跟组合逻辑分开

//计数器结构
//------------------------------------------------------------------------------------------------------------------------------------------------
//明德扬定义计数器
//计数器规则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
//------------------------------------------------------------------------------------------------------------------------------------------------
//组合逻辑与时序逻辑分开的计数器电路
//------------------------------------------------------------------------------------------------------------------------------------------------
//此模块为纯组合逻辑
//------------------------------------------------------------------------------------------------------------------------------------------------	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值