在此先感谢各路大神的帮忙,谢谢!这几天每天都要做家教,好心酸,想着我的的知识还没学完我就特别着急,可是为了生活没有办法,只能挤一挤时间了。做了几天的抢答器,借鉴了很多资料,现在我把它晒在这里,希望能帮到需要帮助的人,也希望和大家一起学习一起探讨,有问题可以及时指出哦~~不慎感谢!!
//************************************
//TOP module of 5 roads of responder
//************************************
`define ud #1
module RESPONDER_5(
//input ports
SYSCLK,
RST_B,
KEY,
//output ports
BUZZER,
LED,
SEG_SEL,
SEG_OUT
);
//input and output declaration
input SYSCLK;
input RST_B;
input [4:0] KEY;
output BUZZER;
output [3:0] LED;
output [1:0] SEG_SEL;
output [7:0] SEG_OUT;
//reg and wire declaration
wire SYSCLK;
wire RST_B;
wire [4:0] KEY;
wire BUZZER;
wire [3:0] LED;
wire [1:0] SEG_SEL;
wire [7:0] SEG_OUT;
//reg and wire in the module
reg [5:0] KEY_REG;
reg [5:0] KEY_REG_N;
reg [3:0] KEY_NUM;
reg SEG_LOCK;
reg SEG_LOCK_N;
reg LED_BUZZER_EN;
reg LED_BUZZER_EN_N;
reg [31:0] LED_BUZZER_TIME_CNT;
reg [31:0] LED_BUZZER_TIME_CNT_N;
reg [3:0] SECOND_L_NUM;
reg [3:0] SECOND_L_NUM_N;
reg [3:0] SECOND_H_NUM;
reg [3:0] SECOND_H_NUM_N;
wire [3:0] TIME_L_NUM;
wire [3:0] TIME_H_NUM;
wire [3:0] SECOND_L;
wire [3:0] SECOND_H;
//detect key action
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
KEY_REG <= `ud 5'b11111;
else
KEY_REG <= `ud KEY_REG_N;
end
always @ (*)
begin //****************************************
if(KEY_REG != 5'b11111) //detect the first key value is useable
KEY_REG_N = KEY_REG; //make sure the key press after the first
else if(KEY != 5'b11111) //is invalid
KEY_REG_N = KEY; //****************************************
else
KEY_REG_N = KEY_REG;
end
//key pressed decoder
always @ (*)
begin
case(KEY_REG)
5'b11110: KEY_NUM = 4'h1;
5'b11101: KEY_NUM = 4'h2;
5'b11011: KEY_NUM = 4'h3;
5'b10111: KEY_NUM = 4'h4;
5'b01111: KEY_NUM = 4'h5;
default : KEY_NUM = 4'h0;
endcase
end
//the number lock at 0 if nobody press the key
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
SEG_LOCK <= `ud 1'h0;
else
SEG_LOCK <= `ud SEG_LOCK_N;
end
always @ (*)
begin
if((KEY_REG == 5'b11111)&&(TIME_L_NUM == 4'h0)&&(TIME_H_NUM == 4'h0))
SEG_LOCK_N = 1'h1;
else
SEG_LOCK_N = SEG_LOCK;
end
//LED and BUZZER light up time counter
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
LED_BUZZER_TIME_CNT <= `ud 32'h0;
else
LED_BUZZER_TIME_CNT <= `ud LED_BUZZER_TIME_CNT_N;
end
always @ (*)
begin
if(LED_BUZZER_TIME_CNT == 32'h17D_7840)
LED_BUZZER_TIME_CNT_N = 32'h0;
else if (LED_BUZZER_EN)
LED_BUZZER_TIME_CNT_N = LED_BUZZER_TIME_CNT + 32'h1;
else
LED_BUZZER_TIME_CNT_N = LED_BUZZER_TIME_CNT;
end
//LED and BUZZER enable
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
LED_BUZZER_EN <= `ud 1'h1; //when count down begin ,led twinkle and buzzer bell
else
LED_BUZZER_EN <= `ud LED_BUZZER_EN_N;
end
always @ (*)
begin
if(LED_BUZZER_TIME_CNT == 32'h17D_7840) //1s
LED_BUZZER_EN_N = 1'h0;
else if((SEG_LOCK)||(KEY_REG ==5'b11111)&&(KEY_REG_N != 5'b11111))
LED_BUZZER_EN_N = 1'h1;
else
LED_BUZZER_EN_N = LED_BUZZER_EN;
end
//LED segment lower control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
SECOND_L_NUM <= `ud 4'h0;
else
SECOND_L_NUM <= `ud SECOND_L_NUM_N;
end
always @ (*)
begin
if(SEG_LOCK)
SECOND_L_NUM_N = 4'h0;
else if(KEY_REG == 5'b11111)
SECOND_L_NUM_N = TIME_L_NUM;
else
SECOND_L_NUM_N = KEY_NUM;
end
assign SECOND_L = SECOND_L_NUM;
//LED segment higher control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
SECOND_H_NUM <= `ud 1'h0;
else
SECOND_H_NUM <= `ud SECOND_H_NUM_N;
end
always @ (*)
begin
if(SEG_LOCK)
SECOND_H_NUM_N = 4'h0;
else if(KEY_REG == 5'b11111)
SECOND_H_NUM_N = TIME_H_NUM;
else
SECOND_H_NUM_N = 4'h0;
end
assign SECOND_H = SECOND_H_NUM;
//instance
//buzzer
BUZZER i1(
.SYSCLK(SYSCLK),
.RST_B(RST_B),
.BUZZER_EN(LED_BUZZER_EN),
.BUZZER(BUZZER)
);
//led
LED i2(
.SYSCLK(SYSCLK),
.RST_B(RST_B),
.LED_EN(LED_BUZZER_EN),
.LED(LED)
);
//led segment
SEGMENT i3(
.SYSCLK(SYSCLK),
.RST_B(RST_B),
.SEG_SCAN_TIME(32'h3D090),
.SECOND_L_NUM(SECOND_L),
.SECOND_H_NUM(SECOND_H),
.SEG_SEL(SEG_SEL),
.SEG_OUT(SEG_OUT)
);
//the lower second
COUNTER i4(
.SYSCLK(SYSCLK),
.RST_B(RST_B),
.NUM_UP_LIM(4'h9),
.CLK_DIV_NUM(32'h17D_783F),
.NUM_OUT(TIME_L_NUM)
);
//the higher second
COUNTER i5(
.SYSCLK(SYSCLK),
.RST_B(RST_B),
.NUM_UP_LIM(4'h1),
.CLK_DIV_NUM(32'hEE6_B280),
.NUM_OUT(TIME_H_NUM)
);
endmodule
//**********************************
//BUZZER module
//**********************************
`define ud #1
module BUZZER(
//input ports
SYSCLK,
RST_B,
BUZZER_EN,
//output ports
BUZZER
);
//input and output declaration
input SYSCLK;
input RST_B;
input BUZZER_EN;
output BUZZER;
//reg and wire declaration
wire SYSCLK;
wire RST_B;
wire BUZZER_EN;
reg BUZZER;
reg BUZZER_N;
//reg and wire in the module
reg [31:0] CLK_DIV_CNT;
reg [31:0] CLK_DIV_CNT_N;
//clock division for ring
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
CLK_DIV_CNT <= `ud 32'h0;
else
CLK_DIV_CNT <= `ud CLK_DIV_CNT_N;
end
always @ (*)
begin
if(CLK_DIV_CNT == 32'hFF80)
CLK_DIV_CNT_N = 32'h0;
else
CLK_DIV_CNT_N = CLK_DIV_CNT + 32'h1;
end
//buzzer control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
BUZZER <= `ud 1'h0;
else
BUZZER <= `ud BUZZER_N;
end
always @ (*)
begin
if((BUZZER_EN)&&(CLK_DIV_CNT == 32'hFF80))
BUZZER_N = ~BUZZER;
else
BUZZER_N = BUZZER;
end
endmodule
//****************************
//LED module
//****************************
`define ud #1
module LED(
//input ports
SYSCLK,
RST_B,
LED_EN,
//output ports
LED
);
//input and output declaration
input SYSCLK;
input RST_B;
input LED_EN;
output [3:0] LED;
//reg and wire declaration
wire SYSCLK;
wire RST_B;
wire LED_EN;
reg [3:0] LED;
//reg and wire in the module
reg [31:0] CLK_DIV_CNT;
reg [31:0] CLK_DIV_CNT_N;
reg [3:0] LED_N;
//clock division for twinkle
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
CLK_DIV_CNT <= `ud 32'h0;
else
CLK_DIV_CNT <= `ud CLK_DIV_CNT_N;
end
always @ (*)
begin
if(CLK_DIV_CNT == 32'h26_25A0)
CLK_DIV_CNT_N = 32'h0;
else
CLK_DIV_CNT_N = CLK_DIV_CNT + 32'h1;
end
//led control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
LED <= `ud 4'hf;
else
LED <= `ud LED_N;
end
always @ (*)
begin
if((LED_EN)&&(CLK_DIV_CNT == 32'h26_25A0))
LED_N = ~LED;
else if (LED_EN)
LED_N = LED;
else
LED_N = 4'hF;
end
endmodule
//***********************************
//LED segment module
//***********************************
`define ud #1
module SEGMENT(
//input ports
SYSCLK,
RST_B,
SEG_SCAN_TIME, //LED scan time ,10ms
SECOND_L_NUM, //value in the lower second
SECOND_H_NUM, //value in the higher second
//output ports
SEG_SEL,
SEG_OUT
);
//input and output declaration
input SYSCLK;
input RST_B;
input [31:0] SEG_SCAN_TIME;
input [3:0] SECOND_L_NUM;
input [3:0] SECOND_H_NUM;
output [1:0] SEG_SEL;
output [7:0] SEG_OUT;
//reg and wire declaration
wire SYSCLK;
wire RST_B;
wire [31:0] SEG_SCAN_TIME;
wire [3:0] SECOND_L_NUM;
wire [3:0] SECOND_H_NUM;
reg [1:0] SEG_SEL;
reg [7:0] SEG_OUT;
//reg and wire in the module
reg [31:0] SEG_SCAN_DIV_CNT;
reg [31:0] SEG_SCAN_DIV_CNT_N;
reg [1:0] SEG_SEL_NUM;
reg [1:0] SEG_SEL_NUM_N;
reg [3:0] SEG_OUT_NUM;
//LED segment scan frequency
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
SEG_SCAN_DIV_CNT <= `ud 32'h0;
else
SEG_SCAN_DIV_CNT <= `ud SEG_SCAN_DIV_CNT_N;
end
always @ (*)
begin
if(SEG_SCAN_DIV_CNT == SEG_SCAN_TIME)
SEG_SCAN_DIV_CNT_N = 32'h0;
else
SEG_SCAN_DIV_CNT_N = SEG_SCAN_DIV_CNT + 32'h1;
end
//LED segment select control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
SEG_SEL_NUM <= `ud 2'h0;
else
SEG_SEL_NUM <= `ud SEG_SEL_NUM_N;
end
always @ (*)
begin
if(SEG_SCAN_DIV_CNT == SEG_SCAN_TIME)
SEG_SEL_NUM_N = SEG_SEL_NUM + 2'h1;
else
SEG_SEL_NUM_N = SEG_SEL_NUM;
end
//LED segment select decoder
always @ (*)
begin
case(SEG_SEL_NUM)
2'h0: SEG_SEL = 2'b10;
2'h1: SEG_SEL = 2'b01;
default: SEG_SEL = 2'b11;
endcase
end
//numbers in the segment load
always @ (*)
begin
case(SEG_SEL_NUM)
2'b00: SEG_OUT_NUM = SECOND_L_NUM;
2'b01: SEG_OUT_NUM = SECOND_H_NUM;
default: SEG_OUT_NUM = 4'h0;
endcase
end
//LED segment numbers decoder
always @ (*)
begin
case(SEG_OUT_NUM)
4'h0 : SEG_OUT = 8'b0000_0011;
4'h1 : SEG_OUT = 8'b1001_1111;
4'h2 : SEG_OUT = 8'b0010_0101;
4'h3 : SEG_OUT = 8'b0000_1101;
4'h4 : SEG_OUT = 8'b1001_1001;
4'h5 : SEG_OUT = 8'b0100_1001;
4'h6 : SEG_OUT = 8'b0100_0001;
4'h7 : SEG_OUT = 8'b0001_1111;
4'h8 : SEG_OUT = 8'b0000_0001;
4'h9 : SEG_OUT = 8'b0000_1001;
default : SEG_OUT = 8'b1111_1111;
endcase
end
endmodule
//****************************************************
//counter module ,pretended at produce segment number
//****************************************************
`define ud #1
module COUNTER(
//input ports
SYSCLK,
RST_B,
NUM_UP_LIM,
CLK_DIV_NUM,
//output ports
NUM_OUT
);
//input and output declaration
input SYSCLK;
input RST_B;
input [3:0] NUM_UP_LIM;
input [31:0] CLK_DIV_NUM;
output [3:0] NUM_OUT;
//reg and wire declaration
wire SYSCLK;
wire RST_B;
wire [3:0] NUM_UP_LIM;
wire [31:0] CLK_DIV_NUM;
reg [3:0] NUM_OUT;
//reg and wire in the module
reg [31:0] TIME_DIV_CNT;
reg [31:0] TIME_DIV_CNT_N;
reg CLK;
reg CLK_N;
reg [3:0] NUM_OUT_N;
//clock divided to adaptable frequency
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
TIME_DIV_CNT <= `ud 32'h0;
else
TIME_DIV_CNT <= `ud TIME_DIV_CNT_N;
end
always @ (*)
begin
if(TIME_DIV_CNT == CLK_DIV_NUM)
TIME_DIV_CNT_N = 32'h0;
else
TIME_DIV_CNT_N = TIME_DIV_CNT + 32'h1;
end
//adaptable clock signal
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
CLK <= `ud 1'h0;
else
CLK <= `ud CLK_N;
end
always @ (*)
begin
if(TIME_DIV_CNT == CLK_DIV_NUM)
CLK_N = ~CLK;
else
CLK_N = CLK;
end
//number output control
always @ (posedge SYSCLK or negedge RST_B)
begin
if(!RST_B)
NUM_OUT <= `ud NUM_UP_LIM;
else
NUM_OUT <= `ud NUM_OUT_N;
end
always @ (*)
begin
if((NUM_OUT == 4'h0)&&(CLK == 1'h1)&&(CLK_N == 1'h0))
NUM_OUT_N = NUM_UP_LIM;
else if((CLK == 1'h1)&&(CLK_N == 1'h0))
NUM_OUT_N = NUM_OUT - 4'h1;
else
NUM_OUT_N = NUM_OUT;
end
endmodule
|
|