实验内容
本次实验要设计一个计数器,并在数码管上面显示计数器的计数过程。
根据实验要求,程序大体可分为三个部分:分频部分,计数部分, 显示部分。
由于开发板提供的时钟频率是50MHz,人眼睛没法达到这个速度,四个数码管也
不好显示这么高频率计数后得到的巨大数字,所以要先对50MHz进行分频,这样才能
保证计数器每计一个数的周期在一秒左右。
计数部分由多个寄存器构成,每个时钟的上升沿,寄存器里面的数值就加一,计数
器复位数值是0000,当计满到9999的时候,计数器返回0000状态,重新开始计数。
module counter(clk,rst_n,
seg_en0,
seg_en1,
seg_en2,
seg_en3,
data0,
data1,
data2,
data3,
data4,
data5,
data6,
data7
);
input clk,rst_n ;
output seg_en0,seg_en1,seg_en2,seg_en3 ;
output data0,data1,data2,data3 ;
output data4,data5,data6,data7 ;
reg seg_en0,seg_en1,seg_en2,seg_en3 ;
reg [24:0 ] clk_cnt ;
reg [3 :0 ] cnt0,cnt1,cnt2,cnt3 ;
reg [7 :0 ] data_out ;
reg [3 :0 ] state ;
wire data0,data1,data2,data3 ;
wire data4,data5,data6,data7 ;
wire data_en0,data_en1,data_en2,data_en3;
wire clk_24,clk_15 ;
wire cntin0 = 4'b0000 ;
wire cntin1 = 4'b0000 ;
wire cntin2 = 4'b0000 ;
wire cntin3 = 4'b0000 ;
parameter SHOW0 = 4'b0001 ,
SHOW1 = 4'b0010 ,
SHOW2 = 4'b0100 ,
SHOW3 = 4'b1000 ;
function [7 :0 ] translater3_8 ;
input [3 :0 ] cnt ;
begin
case ( cnt )
4'b0000: translater3_8 = 8'b1111_1100 ;
4'b0001: translater3_8 = 8'b0110_0000 ;
4'b0010: translater3_8 = 8'b1101_1010 ;
4'b0011: translater3_8 = 8'b1111_0010 ;
4'b0100: translater3_8 = 8'b0110_0110 ;
4'b0101: translater3_8 = 8'b1011_0110 ;
4'b0110: translater3_8 = 8'b1011_1110 ;
4'b0111: translater3_8 = 8'b1110_0000 ;
4'b1000: translater3_8 = 8'b1111_1110 ;
4'b1001: translater3_8 = 8'b1111_0110 ;
endcase
end
endfunction
always @ ( posedge clk or negedge rst_n )
if( !rst_n )
begin
clk_cnt <= 25'b0_0000_0000_0000_0000_0000_0000 ;
end
else
begin
clk_cnt <= clk_cnt + 25'b0_0000_0000_0000_0000_0000_0001 ;
end
assign clk_24 = clk_cnt[21] ;
assign clk_15 = clk_cnt[14] ;
always @ ( posedge clk_24 or negedge rst_n )
if( !rst_n )
begin
cnt0 <= cntin0 ;
cnt1 <= cntin1 ;
cnt2 <= cntin2 ;
cnt3 <= cntin3 ;
end
else
begin
if( (4'b1001 == cnt3) && (4'b1001 == cnt2) && (4'b1001 == cnt1) && (4'b1001 == cnt0) )
begin
cnt0 <= 4'b0000 ;
cnt1 <= 4'b0000 ;
cnt2 <= 4'b0000 ;
cnt3 <= 4'b0000 ;
end
else
begin
if( (4'b1001 == cnt2) && (4'b1001 == cnt1) && (4'b1001 == cnt0) )
begin
cnt0 <= 4'b0000 ;
cnt1 <= 4'b0000 ;
cnt2 <= 4'b0000 ;
cnt3 <= cnt3 + 4'b0001 ;
end
else
begin
if( (4'b1001 == cnt1) && (4'b1001 == cnt0) )
begin
cnt0 <= 4'b0000 ;
cnt1 <= 4'b0000 ;
cnt2 <= cnt2 + 4'b0001 ;
cnt3 <= cnt3 ;
end
else
begin
if( 4'b1001 == cnt0 )
begin
cnt0 <= 4'b0000 ;
cnt1 <= cnt1 + 4'b0001 ;
cnt2 <= cnt2 ;
cnt3 <= cnt3 ;
end
else
begin
cnt0 <= cnt0 + 4'b0001 ;
cnt1 <= cnt1 ;
cnt2 <= cnt2 ;
cnt3 <= cnt3 ;
end
end
end
end
end
assign data_en0 = (cnt0||cnt1||cnt2||cnt3) ? 1'b1 : 1'b0 ;
assign data_en1 = (cnt1||cnt2||cnt3) ? 1'b1 : 1'b0 ;
assign data_en2 = (cnt2||cnt3) ? 1'b1 : 1'b0 ;
assign data_en3 = (cnt3) ? 1'b1 : 1'b0 ;
//assign data_en0 = cnt0 ? 1'b0 : 1'b1 ;
//assign data_en1 = cnt1 ? 1'b0 : 1'b1 ;
//assign data_en2 = cnt2 ? 1'b0 : 1'b1 ;
//assign data_en3 = cnt3 ? 1'b0 : 1'b1 ;
always @ ( posedge clk_15 or negedge rst_n )
if( !rst_n )
begin
state <= SHOW0 ;
seg_en0 <= 1'b0 ;
seg_en1 <= 1'b0 ;
seg_en2 <= 1'b0 ;
seg_en3 <= 1'b0 ;
data_out <= 8'b0000_0000 ;
end
else
begin
case( state )
SHOW0:
begin
seg_en0 <= data_en0 ;
seg_en1 <= 1'b0 ;
seg_en2 <= 1'b0 ;
seg_en3 <= 1'b0 ;
data_out[7:0] <= translater3_8(cnt0) ;
state <= SHOW1 ;
end
SHOW1:
begin
seg_en0 <= 1'b0 ;
seg_en1 <= data_en1 ;
seg_en2 <= 1'b0 ;
seg_en3 <= 1'b0 ;
data_out[7:0] <= translater3_8(cnt1) ;
state <= SHOW2 ;
end
SHOW2:
begin
seg_en0 <= 1'b0 ;
seg_en1 <= 1'b0 ;
seg_en2 <= data_en2 ;
seg_en3 <= 1'b0 ;
data_out[7:0] <= translater3_8(cnt2) ;
state <= SHOW3 ;
end
SHOW3:
begin
seg_en0 <= 1'b0 ;
seg_en1 <= 1'b0 ;
seg_en2 <= 1'b0 ;
seg_en3 <= data_en3 ;
data_out[7:0] <= translater3_8(cnt3) ;
state <= SHOW0 ;
end
default: state <= SHOW0 ;
endcase
end
assign data0 = data_out[0] ;
assign data1 = data_out[1] ;
assign data2 = data_out[2] ;
assign data3 = data_out[3] ;
assign data4 = data_out[4] ;
assign data5 = data_out[5] ;
assign data6 = data_out[6] ;
assign data7 = data_out[7] ;
endmodule
/*
module test;
reg clk,rst_n ;
wire seg_en0,seg_en1,seg_en2,seg_en3 ;
wire data0,data1,data2,data3 ;
wire data4,data5,data6,data7 ;
initial
begin
clk = 0 ;
rst_n = 1 ;
#10 rst_n = 0 ;
#10 rst_n = 1 ;
#100000000 $stop;
end
always #5 clk = ~clk ;
counter cc_coun(.clk(clk),.rst_n(rst_n),
.seg_en0(seg_en0),
.seg_en1(seg_en1),
.seg_en2(seg_en2),
.seg_en3(seg_en3),
.data0(data0),
.data1(data1),
.data2(data2),
.data3(data3),
.data4(data4),
.data5(data5),
.data6(data6),
.data7(data7)
);
endmodule
*/