今天的使用时设计一个可以实现使用指定拨码开关控制加减计数、使能、清零的13进制计数器,并且是由两位数码管显示结果,在加法计数器中,加法加到最大值12时需要点亮一盏LED,加法计数器中减到最小值0时也需要点亮一盏LED。下面是我的程序:
coun文件: /* 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;//最大值进位,最小值借位,用来满足题目对LED点亮的要求 wire[3:0] DISP1,DISP2;//中间变量,数码管要显示的数字 output[6:0] SHOW1,SHOW2;//输出变量,数码管的段码 reg[3:0] DOUT;//计数器计数输出,此处不需要输出,仅作为中间变量 reg LED1,LED2; assign DISP1 = (DOUT < 10) ? DOUT : (DOUT - 10);//小于10则,直接显示,大于10则减去10,只显示个位 assign DISP2 = (DOUT >= 10) ? 1 : 0;//大于等于10,则十位为1,否则十位为0 always@(posedge CLK or negedge CLR) begin if(!CLR)//asynchronous reset,low level actve DOUT = 0; else if(EN)//synchronous enable,high level actve 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)// up counter加法计数 begin DOUT = DOUT + 1; LED1 = 0; end else if(A_S_CTRL == 0)// down counter接法计数 begin DOUT = DOUT - 1; LED2 = 0; end end end display U1(.datain(DISP1),.sm_db(SHOW1));//例化语句调用显示模块 display U2(.datain(DISP2),.sm_db(SHOW2)); endmodule 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 di文件: /*显示0到9的数字,数码管译码器*/ 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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29以上程序实现了这个功能。
以上程序是由一个加减可控的可预置的十进制计数器修改而成的,通过修改几个参数,既可以构成任意进制的计数器:
coun文件: 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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40以下是我修改的一个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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40接下来设占空比为百分之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 1 2 3 4 5 6 7 8 9 10偶数分频器:
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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19奇数分频器:
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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36二选一多路选择器:
module mux21(fin1,fin2,ctrl,fout); input fin1,fin2; input [3:0] ctrl; output fout; assign fout = ctrl[0] ? fin1 : fin2; endmodule 1 2 3 4 5 6 7RTL图:
工程结构图:
今天(2017年12月28)考EDA实验,考的真是惊险刺激,最后实现了四分之三的功能。
这个过程中我做的很认真,自认为设计思路也是很好,但刚开始的方案不可行,后来改了一种方案,编译没有错。然后一步步的修改完善,把所有的功能一步一步往上加,把多余的功能一定一定删掉,使得整个程序简洁直观。最后的仿真很完美,然后准备下载。可是正当下载进去准备见证奇迹的时候,却发现毫无反应。时间已经到达最后关头,我还心里提醒自己:镇静,冷静找一下错误,仿真那么完美,不可能有错的,可能只是一个小错误。找了一会儿,还是没找出来,哎,先写报告吧,等老师验收的时候问一下老师吧。好来老师到了,我把情况说明了,老师也没马上找出原因。我说老师,我申请换一台实验箱,老师说那你换一下吧,可是换了实验箱仍然没有什么用。哎,为什么,老师突然说,你是不是绑定完引脚没有重新编译啊。我突然想起,是啊,平常在电脑上一直使用仿真,从来没有下载进去,好久没下载了,都忘记了绑定引脚要编译,唉,该死。重新编译下载进去后终于好了,数码管亮了,然后我略有慌乱的拨弄了控制开关,终于后面三个功能都实现了。
还剩第一个分频器,那个题目其实感觉很简单,因为我之前花了不少时间研究分频器,只是没实现那么高频率的分频。思路很清晰,20MHZ分频成1Hz,使用一个25位的计数器,2的25次方等于(33,554,432),计数到10乘以10的6次翻转一次电平就可以了,然后达到20兆分频了。我说老师,那个分频器窝可以在做一下吗,我改两个参数应该就可以了。老师说不行,没时间了。那好吧,老师对我也算仁至义尽了。于是我就坐在倒数第二排把没写完的报告写完。
过后的那种感觉真的很奇妙,就是有些事情你真的用心去做 了,努力了,你会真的很在乎它,你绝对不会吧失败看的风轻云淡,至少要有一些成果。遗憾也常常是有的,就是那种差一点就成功了,却不能够成功。但最终事后还是开心的,因为你问心无愧。真的努力过,结果一般都会有一些,可能只是没有达到期望的而已。
这让我想起了今年夏天的电赛,我的队长,他真的是很在乎这个比赛,他说他想去西安,参加国赛。他说这话的时候,很认真,他的话让我心里有些不安,因为我知道,我撑不起他的梦想,我太菜了。电赛期间,他经常通宵到半夜两三点,当然通宵也算他的一种习惯吧。后来实现了前面三项功能。在省赛区验收的时候,由于我们的电路板的工艺的问题,调试时实现的功能,有的没实现,而且偏差很大。队长很紧张,我可以看出来,他一直在咽口水,调试的手也在发抖。最终被封箱了,留作下一步评审,后来得了个省级二等奖。队长很不甘心,他说心里真不是滋味。但对于我这种菜鸡来说,已经挺不错的了。事后队长说,他调试那时候,紧张到肚子疼。现在我觉得我可以理解这种感觉了。唉,无奈,有时我也替队长惋惜,他选队友怎么会选我这种菜鸡,我真的是拖队长的后腿了。但是通过暑假电赛,说真的,我学到了很多,收获了很多,还认识了不少人,还沾队长和另一位队友的光得了个小奖(可是这也是我目前科技方面大学得的最高奖了,由此知道我有多菜了吧)。大家有没有发现我老是一口一个队长队长的,我的队长并不是有多突出,技术不是说有多厉害,是因为我感谢他,心里面敬重他,他可以说是我动手实践入门的“导师”。通过这次暑假电赛,我觉的我和队长也结下了不解的友缘,我觉的我的队长很真诚,乐于助人,不虚伪,没有那种很多人有的自以为是的盲目傲慢,我们也很熟了,我觉得队长真的算我大学里的一个朋友了。在此写了这么多,也表示对队长的感谢。
突然肚子咕噜一响,好像还没吃晚饭呢,哇,已经11点多了,该休息了。约到后面越写的不详细,改天在更吧,希望对大家有所帮助。