FPGA入门三BCD计数器

BCD计数器

1.(1)编写4位计数器

BCD码计数器经常用在需要十进制计数,十进制格式输出的场合

module  BCD_counter(Clk,Rst_n,Cin,q,count);

   input Clk;//时钟基准端口
	input Rst_n;//复位端口
	input Cin; //脉冲一次计数一次 计数器进位输入
	output [3:0]q;//计数器计数值输出
	output reg count;//计数器进位输出
	
   reg [3:0] cnt;   //定义计数器寄存器
     
   always @(posedge Clk or  negedge Rst_n) //内部信号cnt计数
	  if(!Rst_n)
	   cnt <= 4'd0;
		else  if(Cin == 1'b1) begin
		   if(cnt == 4'd9)
			  cnt <= 4'd0;
			  else  cnt <= cnt + 4'b1;
		 end
		 else  cnt <= cnt;
   
   assign q = count;   
		
	always @(posedge Clk or  negedge Rst_n) //计数满溢出count
	  if(!Rst_n)
	   count <= 1'b0;
	else	 if(Cin == 1'b1 && cnt == 4'd9)
		   count <= 1'b1;
			else 
			  count <= 1'b0;
	
endmodule 

1.(2)编写仿真文件

`timescale 1ns/1ns
`define  period_clock  20
module BCD_counter_tb;

    reg  Clock;
	 reg Rst_n;
	 reg Cin;
	 wire q;
	 wire count;
	 
	 
   BCD_counter BCD_counter0(
	.Clk(Clock),
	.Rst_n(Rst_n),
	.Cin(Cin),
	.q(q),
	.count(count)
	);
	
	initial Clock = 1;
	always #(`period_clock/2) Clock = ~Clock;
	initial begin
	 Rst_n = 0;
	 #(`period_clock*10)
	 Rst_n = 1;
	 repeat(50) begin
	 Cin = 0;
	 #(`period_clock*5) Cin = 1;
	 #(`period_clock) Cin = 0; 
	 end 
	 #(`period_clock*100);
	 $stop;
	 end
	endmodule
	
仿真结果

在这里插入图片描述

2.(1)级联3个4位计数器

module  BCD_top(Clock,Rst_n,Cin,q,count);

   input Clock;//时钟基准端口
	input Rst_n;//复位端口
	input Cin; //脉冲一次计数一次 计数器进位输入
	output [11:0]q;//计数器计数值输出
	output  count;//计数器进位输出

    wire [3:0] q0,q1,q2;
	 wire count;
	 wire count0;
	 wire count1;

	 assign q = {q2,q1,q0}; //位拼接
	 
    BCD_Counter BCD_counter0(
	.Clk(Clock),
	.Rst_n(Rst_n),
	.Cin(Cin),
	.q(q0),
	.count(count0)
	);

	 BCD_Counter BCD_counter1(
	.Clk(Clock),
	.Rst_n(Rst_n),
	.Cin(count0),
	.q(q1),
	.count(count1)
	);
	 BCD_Counter BCD_counter2(
	.Clk(Clock),
	.Rst_n(Rst_n),
	.Cin(count1),
	.q(q2),
	.count(count)
	);
endmodule

2.(2)仿真文件

`timescale 1ns/1ns
`define Clock_period  20
module  BCD_top_tb;


    reg  Clk;   
	 reg Rst_n;
	 reg Cin;
	 wire [11:0]q;
	 wire count;

BCD_top BCD_top_tb0(
       .Clock(Clk),
		 .Rst_n(Rst_n),
		 .Cin(Cin),
		 .q(q),
		 .count(count)
);

  initial Clk = 1;
  always #(`Clock_period/2) Clk = ~Clk;
 
 initial begin
   #(`Clock_period*5);
	Rst_n = 1'b0;
	Cin=1'b1;
  	#(`Clock_period*10);
	Rst_n = 1'b1;
	#(`Clock_period*10);
	Cin=1'b1;
	#(`Clock_period*5000);
	 $stop;
   end

endmodule

仿真结果

在这里插入图片描述

问题:高位低位计数器计数数值满溢出count信号后产生cin信号延迟,导致总效果从999跳变990。
原因:同步时序逻辑电路存在D触发器延迟。

解决方法

更改底层 BCD_Counter模块、
将时序逻辑改为组合逻辑。

module  BCD_Counter(Clk,Rst_n,Cin,q,count);

   input Clk;//时钟基准端口
	input Rst_n;//复位端口
	input Cin; //脉冲一次计数一次 计数器进位输入
	output [3:0]q;//计数器计数值输出
	output  count;//计数器进位输出
	
   reg [3:0] cnt;   //定义计数器寄存器
     
   always @(posedge Clk or  negedge Rst_n) //内部信号cnt计数
	  if(!Rst_n)
	   cnt <= 4'd0;
		else  if(Cin == 1'b1) begin
		   if(cnt == 4'd9)
			  cnt <= 4'd0;
			  else  cnt <= cnt + 4'b1;
		 end
		 else  cnt <= cnt;
   
   assign q = cnt;   
   
	assign count = (Cin == 1'b1 && cnt == 4'd9);
	
endmodule 
仿真结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值