功能描述:按4*4键盘上的1,2,3...号按键可依次测出<br /> 25000000Hz ,12500000Hz ....的分频信号并显示在8个数码管上.<br />希望和初学者一起学习 163haole@163.com<br />本设计由以下四个模块组成.<br />freqtest.v -8位十进制频率计 (顶层模块)<br />KeyBoard.v -4*4键盘扫描模块 (选择不同的被测信号)<br />cnt10.v -十进制计数器模块 (测频计数)<br />scan_led.v -数码管动态扫描模块 (显示测量结果)<br /><br /><br />/* freqtest.v -8位十进制频率计*/<br /><br />/* Copyright 2008-2018 */<br /><br />/*<br />modification history<br />--------------------<br />01a,16jan08,52mcu 163haole@163.com<br />*/<br /><br />/*<br />DESCRIPTION<br />Cyclone II EP2C5Q208C<br /><br />*/<br />module freqtest(clock,freq_input,dig,seg,test,col,row,rstkey);<br />input clock; //系统时钟<br />inout freq_input; //被测信号时钟<br />output[2:0] dig; //数码管选择输出<br />output[7:0] seg; //数码管段输出引脚<br />output[9:0] test;//输出频率信号,用于测试<br /><br />output [3:0] col ;<br />input [3:0] row ;<br />input rstkey ;<br /><br />reg[25:0]counter; //时钟分频计数器<br />reg[31:0]freq_result; //频率测量结果寄存器<br />wire [31:0]pre_freq; //脉冲计数寄存器<br />reg rst;<br />wire divide_clk; //1Hz闸门信号<br />wire clk_scan; //数码管扫描时钟<br />wire cout1,cout2,cout3,cout4,cout5,cout6,cout7;<br /><br /><br /><br />assign clk_scan = counter[15]; //动态扫描时钟<br />assign test = counter[9:0];//输出频率信号,用于测试<br /><br />reg [31:0] Mega_cnt;<br />reg[3:0]key;<br />reg freq_input_r;<br /><br /><br />//时钟分频进程:分出1hz基准信号<br />always @(posedge clock)<br />begin<br /> if(divide_clk)<br /> counter<=26'd0;<br /> else <br /> counter<=counter+1'b1;<br />end<br /><br />assign divide_clk=(counter>=26'd50000000);//<br /><br /><br /><br />//锁存测量值进程<br />always @(posedge clock)<br />begin<br /> if(divide_clk)<br /> freq_result<=pre_freq;<br />end<br /><br />//产生计数器复信号<br />always @(posedge clock)<br />begin<br /> if(divide_clk)<br /> rst<=1'b1;<br /> else<br /> rst<=1'b0;<br />end<br /><br />//产生被测频率信号<br /><br />//assign freq_input=counter[1];<br />assign freq_input= freq_input_r;<br /><br />always @(posedge clock ) //sys_clk 50Mhz<br />begin<br /><br />if(Mega_cnt>32'd48) //50-2<br /> begin <br /> Mega_cnt<=32'd0;<br /> end <br />else<br /> Mega_cnt<=Mega_cnt+1;<br />end<br /><br />assign clk_1Mhz = Mega_cnt[5];//1Mhz <br /><br />KeyBoard (.code(key),.col(col),.valid(valid),.row(row),.sys_clk(clk_1Mhz),.rst(rstkey));<br /><br />always @(key)<br />begin<br /> <br /> case(key)<br /> 4'd1: freq_input_r=counter[0];//25000000<br /> 4'd2: freq_input_r=counter[1];<br /> 4'd3: freq_input_r=counter[2];<br /> 4'd4: freq_input_r=counter[3];<br /> 4'd5: freq_input_r=counter[4];<br /> 4'd6: freq_input_r=counter[5];<br /> 4'd7: freq_input_r=counter[6];<br /> 4'd8: freq_input_r=counter[7];<br /> 4'd9: freq_input_r=counter[8];<br /> 4'd10:freq_input_r=counter[9];<br /> 4'd11:freq_input_r=counter[10];<br /> 4'd12:freq_input_r=counter[11];<br /> 4'd13:freq_input_r=counter[12];<br /> 4'd14:freq_input_r=counter[13];<br /> 4'd15:freq_input_r=counter[14];<br /> 4'd0:freq_input_r=counter[15]; //762.939453125Hz<br /> default:freq_input_r=counter[0];<br /> endcase<br /><br />end<br /><br />//8位十进制模块:由8个十进制计数模块构成<br />//*<br />cnt10 u1(.clock(freq_input),.rst(rst),.cin(1'b1), .cout(cout1),.dout(pre_freq[3:0]));<br />cnt10 u2(.clock(freq_input),.rst(rst),.cin(cout1),.cout(cout2),.dout(pre_freq[7:4]));<br />cnt10 u3(.clock(freq_input),.rst(rst),.cin(cout2),.cout(cout3),.dout(pre_freq[11:8]));<br />cnt10 u4(.clock(freq_input),.rst(rst),.cin(cout3),.cout(cout4),.dout(pre_freq[15:12]));<br />cnt10 u5(.clock(freq_input),.rst(rst),.cin(cout4),.cout(cout5),.dout(pre_freq[19:16]));<br />cnt10 u6(.clock(freq_input),.rst(rst),.cin(cout5),.cout(cout6),.dout(pre_freq[23:20]));<br />cnt10 u7(.clock(freq_input),.rst(rst),.cin(cout6),.cout(cout7),.dout(pre_freq[27:24]));<br />cnt10 u8(.clock(freq_input),.rst(rst),.cin(cout7),.cout(), .dout(pre_freq[31:28]));<br />//*/<br />//数码管显示模块<br />scan_led u9(.clk_1k(clk_scan),.d(freq_result),.dig(dig),.seg(seg));<br /><br />endmodule<br /><br /><br />/* KeyBoard.v -4*4键盘扫描模块*/<br /><br />/* Copyright 2008-2018 */<br /><br />/*<br />modification history<br />--------------------<br />01a,20jan08,52mcu modified comment 163haole@163.com<br />01a,13jan08,52mcu added comment<br />*/<br /><br />/*<br />DESCRIPTION<br />Cyclone II EP2C5Q208C<br /><br />*/<br />module KeyBoard(<br /> code ,<br /> col ,<br /> valid ,<br /> row ,<br /> sys_clk ,<br /> rst <br /> );<br /> output [3:0] col ;<br /> output valid ;<br /> output [3:0] code ;<br /> <br /> input [3:0] row ;<br /> input sys_clk,rst ;<br /> <br /> reg [3:0] col,code;<br /> reg [5:0] state,next_state;<br /> <br /> parameter S_0 = 6'b000001,<br /> S_1 = 6'b000010,<br /> S_2 = 6'b000100,<br /> S_3 = 6'b001000,<br /> S_4 = 6'b010000,<br /> S_5 = 6'b100000;<br /> reg S_row ; <br /> reg [3:0] count,row_reg,col_reg;<br /> reg clk2,clk4;<br /> <br /> <br /> reg [24:0] Mega_cnt;<br /> wire clk;<br />/**************************************/<br />always @(posedge sys_clk or negedge rst) //sys_clk 1Mhz<br />begin<br />if(!rst)<br /> begin<br /> Mega_cnt<=0;<br /> end<br />else<br /> begin<br /> Mega_cnt<=Mega_cnt+1;<br /> end<br />end<br /><br />assign clk = Mega_cnt[4]; //clk 1Mhz/2^(4+1)=31.25Khz<br />/**************************************/ <br /> <br /> always @ (posedge clk) //clk2 clk/2=62.5Khz/2=15.625Khz<br /> clk2 <= ~clk2;<br /> <br /> always @ (posedge clk2) //clk4 clk2/2=15.625Khz/2=7.8125Khz 0.128ms<br /> clk4 <= ~clk4;<br /> <br /> always @ (posedge clk4 or negedge rst)<br /> if(!rst)<br /> begin<br /> count <= 0;<br /> S_row <= 0;<br /> end<br /> else<br /> begin<br /> if(!(row[0]&row[1]&row[2]&row[3]))<br /> begin<br /> if(count < 'd4)<br /> count <= count +1 ;<br /> else<br /> S_row <= 1;<br /> end<br /> else if(state[5]||state[0])<br /> begin<br /> count <= 0;<br /> S_row <= 0;<br /> end<br /> end<br /> <br /> assign valid = ((state == S_1)||(state == S_2)||(state == S_3)||(state == S_4)) && (!(row[3]&row[2]&row[1]&row[0])) ;<br /> <br /> always @ (negedge clk) //clk 1Mhz/2^(4+1)=31.25Khz<br /> if(valid)<br /> begin<br /> row_reg <= row ;<br /> col_reg <= col ;<br /> end<br /> else<br /> begin<br /> row_reg <= row_reg ;<br /> col_reg <= col_reg ;<br /> end<br /> <br /> always @ (row_reg or col_reg or clk)<br /> case({row_reg,col_reg})<br /> 8'b1110_1110: code = 13;<br /> 8'b1110_1101: code = 9 ;<br /> 8'b1110_1011: code = 5 ;<br /> 8'b1110_0111: code = 1 ;<br /> <br /> 8'b1101_1110: code = 14;<br /> 8'b1101_1101: code = 10;<br /> 8'b1101_1011: code = 6 ;<br /> 8'b1101_0111: code = 2 ;<br /> <br /> 8'b1011_1110: code = 15 ;<br /> 8'b1011_1101: code = 11 ;<br /> 8'b1011_1011: code = 7;<br /> 8'b1011_0111: code = 3;<br /> <br /> 8'b0111_1110: code = 0;<br /> 8'b0111_1101: code = 12;<br /> 8'b0111_1011: code = 8;<br /> 8'b0111_0111: code = 4; <br /> endcase<br /> <br /> always @ (posedge clk4 or negedge rst) //clk4 clk2/2=15.625Khz/2=7.8125Khz 0.128ms<br /> if(!rst)<br /> state <= S_0 ;<br /> else<br /> state <= next_state ;<br /> <br /> always @ ( state or row or S_row)<br /> begin<br /> // next_state = state ; <br /> col =0;<br /> case(state)<br /> S_0 : begin<br /> col = 4'b0000;<br /> if(S_row)<br /> next_state = S_1;<br /> else<br /> next_state = S_0;<br /> end<br /> S_1 : begin<br /> col = 4'b1110;<br /> if(row!='hf)<br /> next_state = S_5;<br /> else<br /> next_state = S_2;<br /> end<br /> S_2 : begin<br /> col = 4'b1101;<br /> if(row!='hf)<br /> next_state = S_5;<br /> else<br /> next_state = S_3;<br /> end <br /> S_3 : begin<br /> col = 4'b1011;<br /> if(row!='hf)<br /> next_state = S_5;<br /> else<br /> next_state = S_4;<br /> end <br /> S_4 : begin<br /> col = 4'b0111;<br /> if(row!='hf)<br /> next_state = S_5;<br /> else<br /> next_state = S_0;<br /> end <br /> S_5 : begin<br /> col = 4'b0000;<br /> if(row == 4'b1111) <br /> next_state = S_0;<br /> else <br /> next_state = S_5;<br /> end<br /> default: next_state = S_0;<br /> endcase<br /> end<br />endmodule<br /><br />/* cnt10.v -十进制计数器*/<br /><br />/* Copyright 2008-2018 */<br /><br />/*<br />modification history<br />--------------------<br />01a,16jan08,52mcu 163haole@163.com<br />*/<br /><br />/*<br />DESCRIPTION<br />Cyclone II EP2C5Q208C<br /><br />*/<br />module cnt10(clock,rst,cin,cout,dout);//十进制计数器<br />input clock;//计数时钟<br />input cin;//进位输入<br />input rst;// 复位信号<br />output cout;//进位输出<br />output[3:0]dout;//计数输出<br />reg[3:0]counter; //寄存器<br />assign dout=counter;<br /><br />assign cout=cin&&(counter>=4'd9); //进位输出<br />always @(posedge clock or posedge rst)<br />begin<br /> if(rst)<br /> counter<=4'd0;//计数器复位<br /> else if(cin) //进位输入<br /> begin<br /> if(cout)<br /> counter<=4'd0;<br /> else <br /> counter<=counter+1'b1;<br /> end<br />end<br />endmodule<br /><br /><br />/* scan_led.v -数码管动态扫描 */<br /><br />/* Copyright 2008-2018 */<br /><br />/*<br />modification history<br />--------------------<br />01a 15jan08 52mcu solve the dig problem 163haole@163.com<br />01a,10jan08,52mcu<br />*/<br /><br />/*<br />DESCRIPTION<br />Cyclone II EP2C5Q208C<br /><br />*/<br /><br />module scan_led(clk_1k,d,dig,seg);<br />input clk_1k;<br />input[31:0]d;<br /><br />output[2:0]dig;<br />output[7:0]seg;<br /><br />reg[7:0]seg_r;<br />reg[2:0]dig_r;<br />reg[3:0]disp_dat;<br />reg[2:0]count;<br /><br />assign dig=dig_r;<br />assign seg = seg_r;<br /><br /><br />always @(posedge clk_1k)<br />begin<br /> count<=count+1'b1;<br />end<br /><br />always @(posedge clk_1k)<br />begin<br /> case(count)<br /> 3'd0:disp_dat=d[31:28];<br /> 3'd1:disp_dat=d[27:24];<br /> 3'd2:disp_dat=d[23:20];<br /> 3'd3:disp_dat=d[19:16];<br /> 3'd4:disp_dat=d[15:12];<br /> 3'd5:disp_dat=d[11:8];<br /> 3'd6:disp_dat=d[7:4];<br /> 3'd7:disp_dat=d[3:0];<br /> endcase<br /> dig_r = count;<br /> <br />end<br /> <br /> always @(disp_dat)<br />begin<br /> case(disp_dat)<br /> 4'h0:seg_r = 8'b00111111;// '0'8'b00000001;// '-' <br /> 4'h1:seg_r = 8'b00000110;// '1'<br /> 4'h2:seg_r = 8'b01011011;// '2' <br /> 4'h3:seg_r = 8'b01001111;// '3' <br /> 4'h4:seg_r = 8'b01100110;// '4'<br /> 4'h5:seg_r = 8'b01101101;// '5'<br /> 4'h6:seg_r = 8'b01111101;// '6'<br /> 4'h7:seg_r = 8'b00000111;// '7'<br /> 4'h8:seg_r = 8'b01111111;// '8'<br /> 4'h9:seg_r = 8'b01101111;// '9'<br /> 4'ha:seg_r = 8'b01110111;// 'a'<br /> 4'hb:seg_r = 8'b01111100;// 'b'<br /> 4'hc:seg_r = 8'b00111001;// 'c'<br /> 4'hd:seg_r = 8'b01011110;// 'd'<br /> 4'he:seg_r = 8'b01111001;// 'e'<br /> 4'hf:seg_r = 8'b01110001;// 'f'<br /> endcase<br />end<br />endmodule<br /><br /> |
|