目录:
0. 前言
本次更新注意是针对于计数器而言,怎么评价计数器呢?其实我觉得,计数器不难,但是你还离不开计数器这个东西,包括实现一些任意占空比的任意分频啊,这些都得用得着计数器的。所以说,有必要单独拿出来和大家分享一下下呢!!!
1. VL50 简易秒表
1.1 题目描述
请编写一个模块,实现简易秒表的功能:具有两个输出,当输出端口second从1-60循环计数,每当second计数到60,输出端口minute加一,一直到minute=60,暂停计数。
1.1.1 信号示意图
1.1.2 波形示意图
1.1.3 输入描述
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
1.1.4 输出描述
second:6比特位宽,秒表的秒读数
minute:6比特位宽,秒表的分读数
1.2 解题思路
该题的思路类似于生活中的时钟,就是 秒 计时从1开始(注意复位是从0开始的哦!!!);分从0开始,秒 每满60个数,分自动加一,秒自动置1,依次类推,直到分为60,停止计数。
1.3 代码实现
`timescale 1ns/1ns
module count_module(
input clk,
input rst_n,
output reg [5:0]second,
output reg [5:0]minute
);
//second
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
second <= 6'd0;
end
else begin
if(second == 6'd60) begin //second从1-60循环计数
second <= 6'd1;
end
else if (minute == 6'd60) begin //一直到minute=60,暂停计数
second <= 6'd0;
end
else begin
second <= second + 1'b1;
end
end
end
//minute
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
minute <= 6'd0;
end
else begin
if(second == 6'd60) begin //每当second计数到60,输出端口minute加一
minute <= minute + 6'd1;
end
else begin
minute <= minute; //一直到minute=60,暂停计数
end
end
end
endmodule
1.4 测试文件
待更。。。
1.5 仿真波形
待更。。。
2. VL51 可置位计数器
2.1 题目描述
请编写一个十六进制计数器模块,计数器输出信号递增每次到达0,给出指示信号zero,当置位信号set 有效时,将当前输出置为输入的数值set_num。
2.1.1 信号示意图
2.1.2 波形示意图
2.1.3 输入描述
clk:时钟信号
rst_n:复位信号,低电平有效
set:置位指示信号,当该信号有效时,表示将输出信号强制置为set_num
set_num:4比特信号,当set信号有效时,将该信号的数字赋予输出信号number
2.1.4 输出描述
zero:过零指示信号,当number计数到0时,该信号为1,其余时刻为0
number:4比特位宽,表示计数器的当前读数
2.2 解题思路
该题相比于之前多了一个置位功能,实现起来也比较简单,正常情况下,有如下代码便可实现一个可置位的计数器!!!但这个题有点小小的不一样(不知道是出题人故意这么设定的呢?还是这是一个巧合呢?哈哈哈)!!!
`timescale 1ns/1ns
module count_module(
input clk,
input rst_n,
input set,
input [3:0] set_num,
output reg [3:0]number,
output reg zero
);
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
number <= 4'd0;
end
else begin
if(set) begin
number <= set_num;
end
else begin
number <= number + 1'b1;
end
end
end
//zero
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
zero <= 1'b0;
end
else begin
if(number == 1'b0) begin
zero <= 1'b1;
end
else begin
zero <= 1'b0;
end
end
end
endmodule
为什么会有number_reg呢?
如果只是实现一个可置位的计数器,很简单,不用临时寄存但是,该题的标准答案不行呢,必须实现的是number和zero同时拉起来,这就要求有一个变量可以提前为0,来指示number和zero的信号。这就有了如下答案:
2.3 代码实现
`timescale 1ns/1ns
module count_module(
input clk,
input rst_n,
input set,
input [3:0] set_num,
output reg [3:0]number,
output reg zero
);
/*
为什么会有number_reg呢?
如果只是实现一个可置位的计数器,很简单,不用临时寄存
但是,该题的标准答案不行呢,必须实现的是number和zero同时拉起来
这就要求有一个变量可以提前为0,来指示number和zero的信号。
*/
reg [3:0] number_reg;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
number_reg <= 4'd0;
end
else begin
if(set) begin
number_reg <= set_num;
end
else begin
number_reg <= number_reg + 1'b1;
end
end
end
// number
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
number <= 4'd0;
end
else begin
number <= number_reg;
end
end
//zero
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
zero <= 1'b0;
end
else begin
if(number_reg == 1'b0) begin
zero <= 1'b1;
end
else begin
zero <= 1'b0;
end
end
end
endmodule
2.4 测试文件
待更。。。
2.5 仿真波形
待更。。。
3. VL52 加减计数器
3.1 题目描述
请编写一个十进制计数器模块,当mode信号为1,计数器输出信号递增,当mode信号为0,计数器输出信号递减。每次到达0,给出指示信号zero。
3.1.1 信号示意图
3.1.2 波形示意图
3.1.3 输入描述
clk:系统时钟信号
rst_n:复位信号,低电平有效
mode:模式选择信号,当该信号为1,计数器每个时钟加一;为0,则每个时钟减一。
3.1.4 输出描述
number:4比特位宽,计数器当前输出读数。
zero:过零指示信号,当number为0时,该信号为1,其他时刻为0.
3.2 解题思路
该题的思路类似于上一个题,也是需要输出同步拉高的,所以也需要一个寄存器暂存起来,话不多说,开干!!!
3.3 代码实现
`timescale 1ns/1ns
module count_module(
input clk,
input rst_n,
input mode,
output reg [3:0]number,
output reg zero
);
/*
和 51题,可置位计数器极其类似啊!!!
*/
reg [3:0] number_temp;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
number_temp <= 4'd0;
end
else begin
if(mode) begin
if(number_temp == 4'd9) begin
number_temp <= 4'd0;
end
else begin
number_temp <= number_temp + 1'b1;
end
end
else begin
if(number_temp == 4'd0) begin
number_temp <= 4'd9;
end
else begin
number_temp <= number_temp - 1'b1;
end
end
end
end
// number
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
number <= 4'd0;
end
else begin
number <= number_temp;
end
end
//zero
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
zero <= 1'd0;
end
else begin
if(number_temp == 1'd0) begin
zero <= 1'd1;
end
else begin
zero <= 1'd0;
end
end
end
endmodule
3.4 测试文件
待更。。。
3.5 仿真波形
待更。。。
声明
本人所有系列的文章,仅供学习,不可商用,如有侵权,请告知,立删!!!
本人主要是记录学习过程,以供自己回头复习,再就是提供给后人参考,不喜勿喷!!!
如果觉得对你有用的话,记得收藏+评论!!!