📄 seven_seg.v
字号:
//***********************************************************************************
//* File Name: seven_seg.v
//* File Hierarchy: Low level module
//* Dependencies: None
//*
//*
//* Description: This module does the following:
//* 1. Creates a 1-second enable signal with a logic counter
//* 2. Based on PUSH[2]:
//* Held down : Counts 0-9 on 7-segment display
//* Released : Displays 4-bit binary DIP switch value in hex
//* 3. PUSH[1] serves as the system reset
//* 4. LEDs count 0-9
//*
//************************************************************************************
module seven_seg (CLK, PUSH, DIP, DISPLAY, LED);
// Input Declarations
input CLK; //surface-mount 50MHz oscillator
input [2:1] PUSH; //push-button switches
input [3:0] DIP; //DIP[3] is SW3[1] on the board
// Output Declarations
output [6:0] DISPLAY; //7-segment display DD1
output [4:1] LED; //user LEDs
// Input Registers
reg [3:0] DIP_r [3:0]; // 4x4 array to hold registered versions of DIP
reg [3:0] DIP_d; // debounced DIP
reg [3:0] PUSH1_r; // registered version of PUSH1
reg [3:0] PUSH2_r; // registered version of PUSH2
reg PUSH1_d; // debounced PUSH1
reg PUSH2_d; // debounced PUSH2
// Output Registers
reg [4:1] LED;
reg [6:0] DISPLAY;
// Other Registers
reg [22:0] led_count;
reg [3:0] led_seg_count;
reg reset; // high-asserted reset
// Internal signals
wire led_count_en;
wire clk_i, clk_fb, clk0, clkdv, clk_div16;
integer i;
/* Using CLKDLL to divide the input 50 MHz clock by 16
resulting in a 3.125 MHz internal clock */
IBUFG U1 ( .I(CLK), .O(clk_i));
CLKDLL dll_div_by_16 ( .CLKIN(clk_i), .CLKFB(clk_fb), .RST(1'b0),
.CLK0(clk0), .CLK90(), .CLK180(), .CLK270(),
.CLK2X(), .CLKDV(clkdv), .LOCKED());
BUFG U3 ( .I(clk0), .O(clk_fb));
BUFG U4 ( .I(clkdv), .O(clk_div16));
// Register and debounce push buttons and switches
// If the bouncy signal is high, 4 consecutive lows required to pull it low
// If the bouncy signal is low, 4 consecutive highs required to pull it high
always @(posedge clk_div16)
begin
PUSH1_r[0] <= PUSH[1];
PUSH1_r[1] <= PUSH1_r[0];
PUSH1_r[2] <= PUSH1_r[1];
PUSH1_r[3] <= PUSH1_r[2];
if(PUSH1_d)
PUSH1_d <= |PUSH1_r;
else
PUSH1_d <= &PUSH1_r;
reset <= ~PUSH1_d;
PUSH2_r[0] <= PUSH[2];
PUSH2_r[1] <= PUSH2_r[0];
PUSH2_r[2] <= PUSH2_r[1];
PUSH2_r[3] <= PUSH2_r[2];
if(PUSH2_d)
PUSH2_d <= |PUSH2_r;
else
PUSH2_d <= &PUSH2_r;
// Register the 4-bit DIP switch 4 times
DIP_r[0] <= DIP;
DIP_r[1] <= DIP_r[0];
DIP_r[2] <= DIP_r[1];
DIP_r[3] <= DIP_r[2];
// Debounce the DIPs based on the register contents
// For each bit, 0 through 3, switch polarity only when 4 opposite
// polarity is seen for four consecutive clocks.
for (i = 0; i < 4; i = i+1) begin
if(DIP_d[i])
DIP_d[i] <= DIP_r[0][i] | DIP_r[1][i] | DIP_r[2][i] | DIP_r[3][i];
else
DIP_d[i] <= DIP_r[0][i] & DIP_r[1][i] & DIP_r[2][i] & DIP_r[3][i];
end
end
// Segment diagram for the 7-segment LED display (low-enabled).
//
// 0
// -------
// 5| |1
// | |
// ---6---
// 4| |2
// | |
// -------
// 3
// Register outputs
always @(posedge clk_div16)
begin
if(reset) //synchronous reset
begin
DISPLAY <= 7'h7f; //turn off displays during reset
LED <= 4'hf; //turn off LEDs during reset
end
else
begin
// LEDs count binary 0-9 based on led_seg_count
LED <= ~led_seg_count;
// If PUSH2 is pushed (connecting it with GND), encode a
// binary number (0-9) from the counter and displays it
// on the 7-segment LED Display.
// Otherwise, read the DIP switch and output the hex
// value on the 7-segment LED Display
if (!PUSH2_d)
begin
case (led_seg_count)
0: DISPLAY <= ~(7'b0111111);
1: DISPLAY <= ~(7'b0000110);
2: DISPLAY <= ~(7'b1011011);
3: DISPLAY <= ~(7'b1001111);
4: DISPLAY <= ~(7'b1100110);
5: DISPLAY <= ~(7'b1101101);
6: DISPLAY <= ~(7'b1111101);
7: DISPLAY <= ~(7'b0000111);
8: DISPLAY <= ~(7'b1111111);
9: DISPLAY <= ~(7'b1101111);
default: DISPLAY <= 7'b1111111;
endcase
end
else
begin
case (~DIP_d)
0: DISPLAY <= ~(7'b0111111);
1: DISPLAY <= ~(7'b0000110);
2: DISPLAY <= ~(7'b1011011);
3: DISPLAY <= ~(7'b1001111);
4: DISPLAY <= ~(7'b1100110);
5: DISPLAY <= ~(7'b1101101);
6: DISPLAY <= ~(7'b1111101);
7: DISPLAY <= ~(7'b0000111);
8: DISPLAY <= ~(7'b1111111);
9: DISPLAY <= ~(7'b1101111);
4'hA: DISPLAY <= ~(7'b1110111);
4'hb: DISPLAY <= ~(7'b1111100);
4'hC: DISPLAY <= ~(7'b0111001);
4'hd: DISPLAY <= ~(7'b1011110);
4'hE: DISPLAY <= ~(7'b1111001);
4'hF: DISPLAY <= ~(7'b1110001);
default: DISPLAY <= 7'b1111111;
endcase
end // end else (!PUSH2_d)
end // end else (reset)
end // end always block
// The following block generates numbers 0-9 to be displayed on the 7-segment
// display. This 4-bit counter is loaded with the binary value of the on-board
// DIP switch on reset. Once the reset goes inactive, the count will begin. The
// counter will hold its last count when the count_hold_n signal goes active. This
// 4-bit counter will only count 0-9 and is reset to zero when the counter reaches
// decimal 9.
always @(posedge clk_div16)
begin
if (reset)
led_seg_count <= 4'hf;
else if ((led_seg_count == 4'h9) & (led_count_en == 1'b1))
led_seg_count <= 0;
else if (led_count_en == 1'b1)
led_seg_count <= led_seg_count + 1;
end
// The following counter is used as a prescaler to the above 4-bit counter.
// The input clock is divided to enable the 4-bit counter once per second.
always @(posedge clk_div16)
begin
if (reset)
led_count <= 0;
else
if (led_count_en)
led_count <= 0;
else
led_count <= led_count + 1;
end
assign led_count_en = (led_count == 22'd3_125_000); // Create 1-second count
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -