可变计数器

2019-04-13 13:12发布

手工绘制的RTL电路如下图所示:


设计使得思路是,首先设计一个计数器,在技术的过程中判断输出的值与想要的最大计数值之间的关系,由此来控制计数器的归零和重设最大值。

使用Quartus生成的RTL电路图如下图所示:


软件生成的RTL电路图有很多的内部细节,比如将前面的计数器单元和比较单元的具体构成显现了出来。

计数器输出的波形如下图所示:

这里写图片描述

具体的VerligHDL代码是:

module counter(clk, rst, out); input clk, rst; output [3:0] out; reg [3:0] out; reg [3:0] max_cou = 4'b0110;//最大计数值 always @ (posedge clk ) begin if(rst == 0) //同步清零 begin max_cou = 4'b0110; out = 4'b0000; end else if(out < max_cou) begin out = out + 1'b1; end else if(max_cou == 4'b1001)//最大计数值到9,从6开始 begin max_cou = 4'b0110; out = 4'b0000; end else begin //最大计数没有到9,最大计数值增加 max_cou=max_cou + 1'b1; out = 4'b0000; end end endmodule

另一种设计方法

设计思路:使用case语句,通过设置一个变量控制case语句的选择,整框图如下所示:

设计生成的RTL电路如下图所示:

这里写图片描述

输出的波形如图所示:

这里写图片描述

程序代码:

module test(CLK,OUT); input CLK; output [3:0] OUT; reg [3:0] OUT, max_cou = 4'b0110; reg [1:0] M; //计数器选择 always @ (posedge CLK) begin case(M) 2'b00:begin //6进制计数器 if(OUT != max_cou) OUT = OUT + 1'b1; else begin OUT = 0; //计满,改变M,选择下一计数器 M = 2'b01; max_cou = 4'b0111; end end 2'b01:begin //7进制计数器 if(OUT != max_cou) OUT = OUT + 1'b1; else begin OUT = 0; M = 2'b10; max_cou = 4'b1000; end end 2'b10:begin //8进制计数 if(OUT != max_cou) OUT = OUT + 1'b1; else begin OUT = 0; M = 2'b11; max_cou = 4'b1001; end end 2'b11:begin //9进制计数器 if(OUT != max_cou) OUT = OUT + 1'b1; else begin OUT = 0; M = 2'b00; max_cou = 4'b0110; end end endcase end endmodule