基于Verilog的任意模长可加减计数器设计Word文件下载.docx
《基于Verilog的任意模长可加减计数器设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于Verilog的任意模长可加减计数器设计Word文件下载.docx(7页珍藏版)》请在冰豆网上搜索。
input clk;
ﻩﻩ // 外部时钟
inputrst_input;
ﻩﻩ//外部清零(异步)
input en;
ﻩﻩﻩﻩﻩ//计数使能
inputadd_sub;
ﻩ // 计数方向
input[3:
0] data_input;
//计数器模长输入
outputreg full;
ﻩ //计完当前模长
output[3:
0]data_output;
//计数器输出
reg[3:
0]current_counter;
// 当前计数值(输出)
regupdate_length_en;
//改变模长的使能信号
//当前计数周期与上个计数周期的模长输入
reg[3:
0] current_clk_data_input,
last_clk_data_input;
reg [3:
0]counter_length;
//下个计数周期的模长
reg [1:
0]k;
always@(posedgeclk,negedge rst_input)
ﻩbegin
ﻩif(!
rst_input) //异步清零
ﻩﻩbegin
ﻩﻩfull=0;
ﻩcurrent_counter=0;
ﻩend
elseif(en) // 计数使能
begin
ﻩﻩif(add_sub) //加法器
begin
ﻩﻩﻩﻩif(current_counter<
(counter_length-1))
ﻩﻩﻩbegin
ﻩﻩ ﻩcurrent_counter=
current_counter+1;
ﻩﻩﻩfull=0;
ﻩﻩﻩﻩend
ﻩﻩﻩelse
//加法器计数完产生full脉冲以触发
// 判断下个计数周期的模长是否变化
ﻩﻩﻩﻩﻩbegin
ﻩﻩﻩﻩﻩcurrent_counter=0;
ﻩﻩfull=1;
//full输出
ﻩﻩﻩﻩﻩﻩend
ﻩﻩﻩﻩend
ﻩelse //减法器
ﻩbegin
ﻩif(current_counter>
0)
ﻩﻩﻩbegin
ﻩﻩﻩﻩcurrent_counter=
current_counter-1;
ﻩﻩﻩﻩfull=0;
ﻩﻩﻩend
ﻩﻩﻩelse//减法器计数完
ﻩﻩbegin
current_counter=
counter_length-1;
ﻩﻩﻩfull=1;
ﻩﻩﻩﻩﻩﻩﻩend
end
ﻩﻩﻩend
end
//驱动当前计数输出
assigndata_output=current_counter;
initial
begin
ﻩk=1;
//k=1 表示启动计数器的第一个计数周期
end
always @(posedgefull)//加法器/减法器完成当前周期计数
ﻩ//计完当前周期(即full有效)才更新
begin
ﻩlast_clk_data_input<
=data_input;
//上个周期的模长
current_clk_data_input=data_input;
//当前周期的模长
update_length_en<
=last_clk_data_input^
current_clk_data_input;
//update_length_en为更新计数器模长的使能端,
// 异或运算使能端为0代表模长变化1不变
k=k+1;
//k的初值为1,k变化说明计数模长更改过了
if(k==2'
d3)
ﻩﻩk=2;
end
always @(posedge clk)
begin
ﻩﻩif(update_length_en)//使能有效计数模长变化
ﻩﻩcounter_length=current_clk_data_input;
ﻩﻩelse
ﻩbegin
ﻩﻩif(k>=2)
//下个周期计数器模长不变(保持上次更改的)
ﻩﻩcounter_length=last_clk_data_input;
ﻩif(k==1)
ﻩ//整个计数器系统,最初的模长(一次没更改过)
ﻩﻩﻩcounter_length=data_input;
end
end
endmodule
测试激励文件testbench:
`timescale 1 ps/1ps
modulePrj_vlg_tst();
reg add_sub;
reg clk;
reg [3:
0]data_input;
regen;
regrst_input;
wire [3:
0]data_output;
wirefull;
Prj i1 (
ﻩ.add_sub(add_sub),
ﻩ.clk(clk),
ﻩ.data_input(data_input),
.data_output(data_output),
ﻩ.en(en),
ﻩ.full(full),
.rst_input(rst_input)
);
parameterclk_period=10;
//时钟周期
initial //初始化使能端、清零端和时钟信号
begin
en=1;
rst_input=1;
clk=1;
#(46*clk_period)en=0;
#(3*clk_period) en=1;
#(4*clk_period)rst_input=0;
#(2*clk_period) rst_input=1;
end
always#(clk_period/2)clk=~clk;
initial
begin
//计数器模长分别为64 5 3
//左边为上一模长持续的时钟个数
data_input=4'
b0110;
#(22*clk_period)data_input=4'b0100;
#(12*clk_period)data_input=4'b0101;
#(12*clk_period)data_input=4'
b0011;
#(5*clk_period);
end
initial
begin
//计数器计数方向的改变
//左边为递增递减持续的时钟个数
add_sub=1;
#(9*clk_period)add_sub=0;
#(10*clk_period)add_sub=1;
#(13*clk_period)add_sub=0;
#(4*clk_period)add_sub=1;
end
endmodule
四、仿真结果
如图1所示,最开始计数器输入的模长data_input为6,在计数方向控制端add_sub为高电平的情况下,可以从0计数到5,在add_sub为低电平的情况下,可以实现计数器的递减;
当计数器模长data_input变为4的时候,先计完当前周期的模长(0到5),才开始模长为4的计数(0到3)。
如图2所示,当计数器模长变为5时,第二个计数周期计数到2,使能端en无效计数器输出保持不变;
当计数器模长变为3时,计数器计数到1,清零信号rst_input有效,计数器输出为0
综上,本次设计实现了计数器的随时启动、异步清零、加减可控以及任意计数模长的功能。
图1
图2