Verilog语言“加减可控任意进制计数器”及“占空比50%的任意整数分频器”设计
今天(2017年12月28)考EDA实验,考的真是惊险刺激,最后实现了四分之三的功能。
今天的使用时设计一个可以实现使用指定拨码开关控制加减计数、使能、清零的13进制计数器,并且是由两位数码管显示结果,在加法计数器中,加法加到最大值12时需要点亮一盏LED,加法计数器中减到最小值0时也需要点亮一盏LED。下面是我的程序:
counter13.v文件:
/*
CLK位时钟输入,CLR为1异步清零,A_S_CTRL为加减控制端
*/
module counter12 (CLK, CLR,EN,A_S_CTRL,SHOW1,SHOW2,LED1,LED2);
input CLK,EN,CLR,A_S_CTRL;
output LED1,LED2;
wire[3:0] DISP1,DISP2;
output[6:0] SHOW1,SHOW2;
reg[3:0] DOUT;
reg LED1,LED2;
assign DISP1 = (DOUT < 10) ? DOUT : (DOUT - 10);
assign DISP2 = (DOUT >= 10) ? 1 : 0;
always@(posedge CLK or negedge CLR)
begin
if(!CLR)
DOUT = 0;
else if(EN)
begin
if(A_S_CTRL == 1 & DOUT == 12)
begin
DOUT = 0;
LED1 = 1;
end
else if(A_S_CTRL == 0 & DOUT == 0)
begin
DOUT = 12;
LED2 = 1;
end
else if(A_S_CTRL == 1)
begin
DOUT = DOUT + 1;
LED1 = 0;
end
else if(A_S_CTRL == 0)
begin
DOUT = DOUT - 1;
LED2 = 0;
end
end
end
display U1(.datain(DISP1),.sm_db(SHOW1));
display U2(.datain(DISP2),.sm_db(SHOW2));
endmodule
display.v文件:
module display(datain,sm_db);
input[3:0] datain;
output[6:0]sm_db;
reg[6:0]sm_db;
always@(datain)
begin
case(datain)
4'h0:sm_db <= 7'b0111111;
4'h1:sm_db <= 7'b0000110;
4'h2:sm_db <= 7'b1011011;
4'h3:sm_db <= 7'b1001111;
4'h4:sm_db <= 7'b1100110;
4'h5:sm_db <= 7'b1101101;
4'h6:sm_db <= 7'b1111101;
4'h7:sm_db <= 7'b0000111;
4'h8:sm_db <= 7'b1111111;
4'h9:sm_db <= 7'b1101111;
4'ha:sm_db <= 7'b1110111;
4'hb:sm_db <= 7'b1111100;
4'hc:sm_db <= 7'b0111001;
4'hd:sm_db <= 7'b1011110;
4'he:sm_db <= 7'b1111001;
4'hf:sm_db <= 7'b1110001;
default:;
endcase
end
endmodule
以上程序实现了这个功能。
以上程序是由一个加减可控的可预置的十进制计数器修改而成的,通过修改几个参数,既可以构成任意进制的计数器:
counter10.h文件:
module counter10 (DIN,CLK, CLR,EN,LOAD,A_S_CTRL,COUT,DOUT);
input [3:0] DIN;
input CLK,EN,CLR,LOAD,A_S_CTRL;
output[3:0] DOUT;
output COUT;
reg[3:0] DOUT;
reg COUT;
always@(posedge CLK or negedge CLR or negedge LOAD)
begin
if(!CLR)//asynchronous reset,low level actve
DOUT = 0;
else if(!LOAD)//asynchronous load,low level actve
DOUT = DIN;
else if(EN)//synchronous enable,high level actve
begin
if(A_S_CTRL == 1 & DOUT ==9)
begin
COUT = 1;
DOUT = 0;
end
else if(A_S_CTRL == 0 & DOUT ==0)
begin
COUT = 1;
DOUT = 9;
end
else if(A_S_CTRL == 1)// up counter
begin
COUT = 0;
DOUT = DOUT + 1;
end
else if(A_S_CTRL == 0)// down counter
begin
COUT = 0;
DOUT = DOUT - 1;
end
end
end
endmodule
以下是我修改的一个6进制计数器,可以对比看一下,只修改了很少的东西:
module counter6 (DIN, CLK, CLR, EN, LOAD, A_S_CTRL, COUT, DOUT);
input [3:0] DIN;
input CLK,EN,CLR,LOAD,A_S_CTRL;
output[3:0] DOUT;
output COUT;
reg[3:0] DOUT;
reg COUT;
always@(posedge CLK or negedge CLR or negedge LOAD)
begin
if(!CLR)//asynchronous reset,low level actve
DOUT = 0;
else if(!LOAD)//asynchronous load,low level actve
DOUT = DIN;
else if(EN)//synchronous enable,high level actve
begin
if(A_S_CTRL == 1 & DOUT == 5)
begin
COUT = 1;
DOUT = 0;
end
else if(A_S_CTRL == 0 & DOUT == 0)
begin
COUT = 1;
DOUT = 5;
end
else if(A_S_CTRL == 1)// up counter
begin
COUT = 0;
DOUT = DOUT + 1;
end
else if(A_S_CTRL == 0)// down counter
begin
COUT = 0;
DOUT = DOUT - 1;
end
end
end
endmodule
接下来设占空比为百分之50的任意整数分频器:
顶层文件:
module FrqDivder (fin,fout,m);
input fin;
output fout;
input[3:0] m;
wire foute,fouto;
EvenFrqDiv U1(.fin(fin),.fout(foute),.m(m));
OddFrqDiv U2(.fin(fin),.fout(fouto),.m(m));
mux21(.fin1(fouto), .fin2(foute), .ctrl(m), .fout(fout));
endmodule
偶数分频器:
EvenFrqDiv.v文件:
module EvenFrqDiv (fin,fout,m);
input fin;
input[3:0] m;
wire[3:0] n;
assign n = m/2;
output fout;
reg fout;
reg [3:0] q1;
always @ (posedge fin)
begin
q1=q1+1;
if(q1 >= n)
begin
q1=0;
fout=~fout;
end
end
endmodule
奇数分频器:
module OddFrqDiv (fin,fout,m);
input fin;
input[3:0] m;
wire[3:0] n;
output fout;
reg fout1,fout2;
reg [3:0] q1,q2;
assign n = (m+1) >> 1;
always @ (posedge fin)
begin
q1=q1+1;
if(q1 == n)
begin
fout1=~fout1;
end
else if(q1 == m)
begin
q1=0;
fout1=~fout1;
end
end
always @ (negedge fin)
begin
q2=q2+1;
if(q2 == n)
begin
fout2=~fout2;
end
else if(q2 == m)
begin
q2=0;
fout2=~fout2;
end
end
assign fout = fout1 | fout2;
endmodule
二选一多路选择器:
module mux21(fin1,fin2,ctrl,fout);
input fin1,fin2;
input [3:0] ctrl;
output fout;
assign fout = ctrl[0] ? fin1 : fin2;
endmodule
RTL图:
工程结构图:
今天(2017年12月28)考EDA实验,考的真是惊险刺激,最后实现了四分之三的功能。
这个过程中我做的很认真,自认为设计思路也是很好,但刚开始的方案不可行,后来改了一种方案,编译没有错。然后一步步的修改完善,把所有的功能一步一步往上加,把多余的功能一定一定删掉,使得整个程序简洁直观。最后的仿真很完美,然后准备下载。可是正当下载进去准备见证奇迹的时候,却发现毫无反应。时间已经到达最后关头,我还心里提醒自己:镇静,冷静找一下错误,仿真那么完美,不可能有错的,可能只是一个小错误。找了一会儿,还是没找出来,哎,先写报告吧,等老师验收的时候问一下老师吧。好来老师到了,我把情况说明了,老师也没马上找出原因。我说老师,我申请换一台实验箱,老师说那你换一下吧,可是换了实验箱仍然没有什么用。哎,为什么,老师突然说,你是不是绑定完引脚没有重新编译啊。我突然想起,是啊,平常在电脑上一直使用仿真,从来没有下载进去,好久没下载了,都忘记了绑定引脚要编译,唉,该死。重新编译下载进去后终于好了,数码管亮了,然后我略有慌乱的拨弄了控制开关,终于后面三个功能都实现了。
还剩第一个分频器,那个题目其实感觉很简单,因为我之前花了不少时间研究分频器,只是没实现那么高频率的分频。思路很清晰,20MHZ分频成1Hz,使用一个25位的计数器,2的25次方等于(33,554,432),计数到10乘以10的6次翻转一次电平就可以了,然后达到20兆分频了。我说老师,那个分频器窝可以在做一下吗,我改两个参数应该就可以了。老师说不行,没时间了。那好吧,老师对我也算仁至义尽了。于是我就坐在倒数第二排把没写完的报告写完。
过后的那种感觉真的很奇妙,就是有些事情你真的用心去做 了,努力了,你会真的很在乎它,你绝对不会吧失败看的风轻云淡,至少要有一些成果。遗憾也常常是有的,就是那种差一点就成功了,却不能够成功。但最终事后还是开心的,因为你问心无愧。真的努力过,结果一般都会有一些,可能只是没有达到期望的而已。
这让我想起了今年夏天的电赛,我的队长,他真的是很在乎这个比赛,他说他想去西安,参加国赛。他说这话的时候,很认真,他的话让我心里有些不安,因为我知道,我撑不起他的梦想,我太菜了。电赛期间,他经常通宵到半夜两三点,当然通宵也算他的一种习惯吧。后来实现了前面三项功能。在省赛区验收的时候,由于我们的电路板的工艺的问题,调试时实现的功能,有的没实现,而且偏差很大。队长很紧张,我可以看出来,他一直在咽口水,调试的手也在发抖。最终被封箱了,留作下一步评审,后来得了个省级二等奖。队长很不甘心,他说心里真不是滋味。但对于我这种菜鸡来说,已经挺不错的了。事后队长说,他调试那时候,紧张到肚子疼。现在我觉得我可以理解这种感觉了。唉,无奈,有时我也替队长惋惜,他选队友怎么会选我这种菜鸡,我真的是拖队长的后腿了。但是通过暑假电赛,说真的,我学到了很多,收获了很多,还认识了不少人,还沾队长和另一位队友的光得了个小奖(可是这也是我目前科技方面大学得的最高奖了,由此知道我有多菜了吧)。大家有没有发现我老是一口一个队长队长的,我的队长并不是有多突出,技术不是说有多厉害,是因为我感谢他,心里面敬重他,他可以说是我动手实践入门的“导师”。通过这次暑假电赛,我觉的我和队长也结下了不解的友缘,我觉的我的队长很真诚,乐于助人,不虚伪,没有那种很多人有的自以为是的盲目傲慢,我们也很熟了,我觉得队长真的算我大学里的一个朋友了。在此写了这么多,也表示对队长的感谢。
突然肚子咕噜一响,好像还没吃晚饭呢,哇,已经11点多了,该休息了。约到后面越写的不详细,改天在更吧,希望对大家有所帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)