可变模加/减法计数器的设计
仿真代码
module variable_counter(
input clk, // 时钟信号
input reset, // 复位信号
input[3:0]mode, // 模数选择信号
input up_down, //计数方向选择信号
output [3:0]counter //计数器输出信号
);
//记录计数器当前状态
reg[3:0]current_count;
//模数计算
reg[3:0]modulus;
always @*
case (mode)
4'h0: modulus= 4'h1; //模数为1
4'h1: modulus= 4'h2; //模数为2
4'h2: modulus= 4'h3; //模数为3
4'h3: modulus= 4'h4; //模数为4
4'h4: modulus= 4'h5; //模数为5
4'h5: modulus= 4'h6; //模数为6
4'h6: modulus= 4'h7; //模数为7
4'h7: modulus= 4'h8; //模数为8
4'h8: modulus= 4'h9; //模数为9
4'h9: modulus= 4'hA; //模数为10
4'hA: modulus= 4'hB; //模数为11
4'hB: modulus= 4'hC; //模数为12
4'hC: modulus= 4'hD; //模数为13
4'hD: modulus= 4'hE; //模数为14
4'hE: modulus= 4'hF; //模数为15
4'hF: modulus= 4'h0; //模数为16
endcase
//计数器逻辑
always @(posedge clk or posedge reset)
begin
if (reset) //复位信号为高电平begin
begin
current_count<=4'h0; //计数器复位为0
end
else
begin
if(up_down) //计数方向选择信号为高电平,计数器为加法
begin
if (current_count==modulus- 1) //如果当前计数器值达到了模数减1,需要将计数器重置为0
begin
current_count<= 4'h0;
end
else //否则计数器加1
begin
current_count<=current_count + 4'h1;
end
end
else //计数器为减法
begin
if (current_count==4'h0) //如果当前计数器值为0,需要将计数器重置为模数减1
begin
current_count<=modulus - 4'h1;
end
else //否则计数器减1
begin
current_count<=current_count - 4'h1;
end
end
end
end
//输出计数器值
assign counter=current_count;
endmodule
仿真波形
- 模为4的仿真图
- 模为8的仿真图
- 模为16的仿真图
波形图说明:当模选择为4时,在每个时钟“clk”为上升沿时。up_down选择为高电平,计数器为加法器,则输出counter开始递增,当计数器遇到复位信号“reset”为高电平时,计数器会自动清零,计数器即会变成“0”,然后又重新从“0”开始计数。up_down选择为低电平,计数器为减法器,则输出counter开始递减;模为“1到16”中任何一值时,其过程如同上述。