作业3:
利用LED、KEY和Segment LED,实现下面的功能;
(1)实现6位的10进制计数器计数,并在Segment LED显示计数器的次数;
即4盏LED一秒内循环点亮, 10进制计数器加1,同时在Segment LED上显示计数的次数;
(2)实现Reset 按键功能,按下按键后全部清零;
(3)功能按键1——按下功能按键1,暂停计数器计数,Segment LED维持当前数值显示,此时,4盏LED同时(同步)闪烁点亮;
(4)当再次按下功能按键1,计数器恢复计数功能, 4盏LED恢复一秒内循环点亮。
(5)功能按键2——按下功能按键2,自动完成功能:先暂停计数器计数(1秒),然后实现6位10进制计数器加10并显示,最后恢复计数器计数。
代码分了五个.v文件
`timescale 1ns / 1ps
//*******************************************************************************/
module seg_test(
input clk,
input rst_n,
output[5:0]seg_sel,
output[7:0]seg_data,
input [1:0] key,
output [3:0] led
);
reg[31:0] timer_cnt;
reg en_1hz; //1 second , 1 counter enable
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
en_1hz <= 1'b0;
timer_cnt <= 32'd0;
end
else if(timer_cnt >= 32'd49_999_999)
begin
en_1hz <= 1'b1;
timer_cnt <= 32'd0;
end
else
begin
en_1hz <= 1'b0;
timer_cnt <= timer_cnt + 32'd1;
end
end
led_test led_test0
(
.clk (clk), // system clock 50Mhz on board
.rst_n (rst_n), // reset ,low active
.key (key[0]),
.led (led) // LED,use for control the LED signal on board
);
wire[3:0] count0;
wire t0;
count_m10 count10_m0(
.clk (clk),
.rst_n (rst_n),
.en (en_1hz),
.clr (1'b0),
.key (key),
.data (count0),
.t (t0)
);
wire[3:0] count1;
wire t1;
count_m10 count10_m1(
.clk (clk),
.rst_n (rst_n),
.en (t0),
.clr (1'b0),
.key (2'b11),
.data (count1),
.t (t1)
);
wire[3:0] count2;
wire t2;
count_m10 count10_m2(
.clk (clk),
.rst_n (rst_n),
.en (t1),
.clr (1'b0),
.key (2'b11),
.data (count2),
.t (t2)
);
wire[3:0] count3;
wire t3;
count_m10 count10_m3(
.clk (clk),
.rst_n (rst_n),
.en (t2),
.clr (1'b0),
.key (2'b11),
.data (count3),
.t (t3)
);
wire[3:0] count4;
wire t4;
count_m10 count10_m4(
.clk (clk),
.rst_n (rst_n),
.en (t3),
.clr (1'b0),
.key (2'b11),
.data (count4),
.t (t4)
);
wire[3:0] count5;
wire t5;
count_m10 count10_m5(
.clk (clk),
.rst_n (rst_n),
.en (t4),
.clr (1'b0),
.key (2'b11),
.data (count5),
.t (t5)
);
wire[6:0] seg_data_0;
seg_decoder seg_decoder_m0(
.bin_data (count5),
.seg_data (seg_data_0)
);
wire[6:0] seg_data_1;
seg_decoder seg_decoder_m1(
.bin_data (count4),
.seg_data (seg_data_1)
);
wire[6:0] seg_data_2;
seg_decoder seg_decoder_m2(
.bin_data (count3),
.seg_data (seg_data_2)
);
wire[6:0] seg_data_3;
seg_decoder seg_decoder_m3(
.bin_data (count2),
.seg_data (seg_data_3)
);
wire[6:0] seg_data_4;
seg_decoder seg_decoder_m4(
.bin_data (count1),
.seg_data (seg_data_4)
);
wire[6:0] seg_data_5;
seg_decoder seg_decoder_m5(
.bin_data (count0),
.seg_data (seg_data_5)
);
seg_scan seg_scan_m0(
.clk (clk),
.rst_n (rst_n),
.seg_sel (seg_sel),
.seg_data (seg_data),
.seg_data_0 ({1'b1,seg_data_0}), //The decimal point at the highest bit,and low level effecitve
.seg_data_1 ({1'b1,seg_data_1}),
.seg_data_2 ({1'b1,seg_data_2}),
.seg_data_3 ({1'b1,seg_data_3}),
.seg_data_4 ({1'b1,seg_data_4}),
.seg_data_5 ({1'b1,seg_data_5})
);
endmodule
//LED 灯控制
module led_test
(
input clk, // system clock 50Mhz on board
input rst_n, // reset ,low active
input [1:0] key,
output reg[3:0] led // LED,use for control the LED signal on board
);
//define the time counter
reg [31:0] timer;
reg [3:0] count;
///按键防抖
reg [0:0] flag;
reg cnt_full;
reg [19:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 20'd0;
else if(cnt == 20'd999_999)
cnt <= 20'd0;
else
cnt <= cnt + 1'b1;
end
//计数满信号
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_full <= 1'b0;
else if(cnt == 20'd999_999)
cnt_full <= 1'b1;
else
cnt_full <= 1'b0;
end
reg [0:0] key_in_r;
reg [0:0] key_in_r_next;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
key_in_r_next <= 1'b1;
else if(cnt_full)
key_in_r_next <= key;
else
key_in_r_next <= key_in_r_next;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
key_in_r <= 1'b1;
else
key_in_r <= key_in_r_next;
end
wire [0:0] key_out;
assign key_out = key_in_r & (~key_in_r_next);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
flag <= 1'd0;
else if (key_out==1'd1)
flag <= ~flag;
end
流水灯/
always@(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
timer <= 32'd0;
else if(timer == 32'd49_999_999)
timer <= 32'd0;
else
timer <= timer + 32'd1;
end
// LED control
always@(posedge clk or negedge rst_n)
begin
if (rst_n == 1'b0)
begin
led <= 4'b0000;
count <= 4'd0;
end
else if (flag == 0)
begin
if (timer == 32'd0)
led <= 4'b0001;
else if (timer == 32'd12_499_999)
led <= 4'b0010;
else if (timer == 32'd24_999_999)
led <= 4'b0100;
else if (timer == 32'd37_499_999)
led <= 4'b1000;
else if (timer == 32'd49_999_999)
led <= 4'b0000;
end
else
begin
if (timer == 32'd0)
led <= 4'b0000;
else if(timer == 32'd24_999_999)
led <= 4'b1111;
end
end
endmodule
//扫描模块
module seg_scan(
input clk,
input rst_n,
output reg[5:0] seg_sel, //digital led chip select
output reg[7:0] seg_data, //eight segment digital tube output,MSB is the decimal point
input[7:0] seg_data_0,
input[7:0] seg_data_1,
input[7:0] seg_data_2,
input[7:0] seg_data_3,
input[7:0] seg_data_4,
input[7:0] seg_data_5
);
parameter SCAN_FREQ = 200; //scan frequency
parameter CLK_FREQ = 50000000; //clock frequency
parameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ * 6) - 1;
reg[31:0] scan_timer; //scan time counter
reg[3:0] scan_sel; //Scan select counter
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
scan_timer <= 32'd0;
scan_sel <= 4'd0;
end
else if(scan_timer >= SCAN_COUNT)
begin
scan_timer <= 32'd0;
if(scan_sel == 4'd5)
scan_sel <= 4'd0;
else
scan_sel <= scan_sel + 4'd1;
end
else
begin
scan_timer <= scan_timer + 32'd1;
end
end
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
seg_sel <= 6'b111111;
seg_data <= 8'hff;
end
else
begin
case(scan_sel)
//first digital led
4'd0:
begin
seg_sel <= 6'b11_1110;
seg_data <= seg_data_0;
end
//second digital led
4'd1:
begin
seg_sel <= 6'b11_1101;
seg_data <= seg_data_1;
end
//...
4'd2:
begin
seg_sel <= 6'b11_1011;
seg_data <= seg_data_2;
end
4'd3:
begin
seg_sel <= 6'b11_0111;
seg_data <= seg_data_3;
end
4'd4:
begin
seg_sel <= 6'b10_1111;
seg_data <= seg_data_4;
end
4'd5:
begin
seg_sel <= 6'b01_1111;
seg_data <= seg_data_5;
end
default:
begin
seg_sel <= 6'b11_1111;
seg_data <= 8'hff;
end
endcase
end
end
endmodule
module seg_decoder
(
input[3:0] bin_data, // bin data input
output reg[6:0] seg_data // seven segments LED output
);
always@(*)
begin
case(bin_data)
4'd0:seg_data <= 7'b100_0000;
4'd1:seg_data <= 7'b111_1001;
4'd2:seg_data <= 7'b010_0100;
4'd3:seg_data <= 7'b011_0000;
4'd4:seg_data <= 7'b001_1001;
4'd5:seg_data <= 7'b001_0010;
4'd6:seg_data <= 7'b000_0010;
4'd7:seg_data <= 7'b111_1000;
4'd8:seg_data <= 7'b000_0000;
4'd9:seg_data <= 7'b001_0000;
4'ha:seg_data <= 7'b000_1000;
4'hb:seg_data <= 7'b000_0011;
4'hc:seg_data <= 7'b100_0110;
4'hd:seg_data <= 7'b010_0001;
4'he:seg_data <= 7'b000_0110;
4'hf:seg_data <= 7'b000_1110;
default:seg_data <= 7'b111_1111;
endcase
end
endmodule
module count_m10(
input clk,
input rst_n,
input en, //Counter enable
input clr, //Counter synchronous reset
input [1:0] key,
output reg[3:0]data, //counter value
output reg t // carry enable signal
);
/
按键防抖
reg [0:0] flag;
reg [0:0] flag2;
reg cnt_full;
reg [19:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt <= 20'd0;
else if(cnt == 20'd999_999)
cnt <= 20'd0;
else
cnt <= cnt + 1'b1;
end
//计数满信号
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_full <= 1'b0;
else if(cnt == 20'd999_999)
cnt_full <= 1'b1;
else
cnt_full <= 1'b0;
end
reg [1:0] key_in_r;
reg [1:0] key_in_r_next;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
key_in_r_next <= 2'b11;
else if(cnt_full)
key_in_r_next <= key;
else
key_in_r_next <= key_in_r_next;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
key_in_r <= 2'b11;
else
key_in_r <= key_in_r_next;
end
wire [1:0] key_out;
assign key_out = key_in_r & (~key_in_r_next);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin flag <= 1'd0;
// flag2 <= 1'd0;
end
else if (key_out[0]==1)
flag <= ~flag; //按键1标志位
// else if(key_out[1]==1)
// flag2 <= ~flag2; //增加按键2标志位
end
///count_10m///
always@(posedge clk or negedge rst_n)
begin
if(rst_n==0)
begin
data <= 4'd0;
t <= 1'd0; flag2 <= 1'd0;
end
else if(clr)
begin
data <= 4'd0;
t <= 1'd0;
end
else if(key_out[1]==1)
flag2 <= ~flag2;
else if(en) //1秒钟使能一次,计数en_1hz满
begin
if(data==4'd9)
begin
t<= 1'b1; //进位使能,data满9,前一位使能可以执行一次操作:data+1
data <= 4'd0;
end
********改动部分**********///
else
begin
if ((flag == 0)&&(flag2 == 0)) //按键1和2,有一个按下就停止计数
data <= data + 4'd1;
else
begin
if (flag2 == 1) //按键2标志位
begin
t<= 1'b1;
flag2 <= ~flag2;
end
else
t <= 1'b0;
end
end
end
else
t <= 1'b0;
end
endmodule
//不要白嫖,点个赞吧*-*