Verilog 應用範例 : 計數器 ( 七段顯示器 ) 適用於DE2-115 (DE2-70)
程式( Top_Module ):
module Top_Module( CLK, RST,SEL_Out, DIG_Out );
input CLK, RST;
output [5:0] SEL_Out;
output [7:0] DIG_Out;
wire [3:0] Cnt_Up;
wire CLK_1Hz;
Freq_Divider Freq_Div_1Hz(
.CLK(CLK),
.RST(RST),
.CLK_Out(CLK_1Hz)
);
Counter_Up Counter_Up(
.CLK(CLK_1Hz),
.RST(RST),
.Cnt(Cnt_Up)
);
Seg_Seven DIG_SEG(
.SEL_In(Cnt_Up),
.DIG_In(Cnt_Up),
.SEL_Out(SEL_Out),
.DIG_Out(DIG_Out)
);
endmodule
程式( 除頻 1MHz ):
/* 除頻器 Use 50MHz OSC */
module Freq_Divider( CLK, RST, CLK_Out );
input CLK, RST;
output CLK_Out;
reg CLK_Out;
reg [DivW-1:0] CLK_Cnt = 0;
// 除頻設定 1Hz 1s
parameter Div = 26'd50_000_000; // 除頻數(Even)
parameter Div2 = 26'd25_000_000; // Div/2
parameter DivW = 26; // Divide寬度
always @( posedge CLK,negedge RST ) begin
if( !RST )
CLK_Cnt <= 0;
else if( CLK_Cnt == Div-1 )
CLK_Cnt <= 0;
else
CLK_Cnt <= CLK_Cnt + 1'b1;
end
always @( posedge CLK,negedge RST ) begin
if( !RST )
CLK_Out <= 0;
else if( CLK_Cnt <= Div2-1 )
CLK_Out <= 0;
else
CLK_Out <= 1'b1;
end
endmodule
程式( 上數計數器 ):
/* 上數計數器 */
module Counter_Up( CLK, RST, Cnt );
/* 計數資訊 */
parameter Cnt_SB = 4; // 計數寬度
parameter Cnt_UP = 1'b1; // 計數值
parameter Cnt_Min = 4'd0; // 計數最小值
parameter Cnt_Max = 4'd8; // 計數最大值
input CLK, RST;
output [Cnt_SB-1:0] Cnt;
reg [Cnt_SB-1:0] Cnt = Cnt_Min;
always @( posedge CLK or negedge RST ) begin
if( !RST )
Cnt <= Cnt_Min;
else if( Cnt == Cnt_Max )
Cnt <= Cnt_Min;
else
Cnt <= Cnt + Cnt_UP;
end
endmodule
程式( 七段顯示器解碼 ):
/* 七段顯示器解碼(共陽) */
module Seg_Seven( SEL_In, DIG_In, SEL_Out, DIG_Out );
input [2:0] SEL_In; // Use PNP
input [3:0] DIG_In; // MSB D, C, B, A LSB
output [5:0] SEL_Out; // 七段顯示器選擇
output [7:0] DIG_Out; // MSB dp, g, f, e, d, c, b, a LSB
reg [5:0] SEL_Out;
reg [7:0] DIG_Out;
always @( SEL_In ) begin
case( SEL_In )
3'b000: SEL_Out <= 6'b000000; // all on
3'b001: SEL_Out <= 6'b111110; // 1
3'b010: SEL_Out <= 6'b111101; // 2
3'b011: SEL_Out <= 6'b111011; // 3
3'b100: SEL_Out <= 6'b110111; // 4
3'b101: SEL_Out <= 6'b101111; // 5
3'b110: SEL_Out <= 6'b011111; // 6
3'b111: SEL_Out <= 6'b111111; // all off
endcase
end
always @( DIG_In ) begin
case( DIG_In )
4'b0000: DIG_Out <= 8'b11000000; // 0
4'b0001: DIG_Out <= 8'b11111001; // 1
4'b0010: DIG_Out <= 8'b10100100; // 2
4'b0011: DIG_Out <= 8'b10110000; // 3
4'b0100: DIG_Out <= 8'b10011001; // 4
4'b0101: DIG_Out <= 8'b10010010; // 5
4'b0110: DIG_Out <= 8'b10000011; // 6
4'b0111: DIG_Out <= 8'b11111000; // 7
4'b1000: DIG_Out <= 8'b10000000; // 8
4'b1001: DIG_Out <= 8'b10010000; // 9
4'b1010: DIG_Out <= 8'b01111111; // dp
default: DIG_Out <= 8'b11111111; // off
endcase
end
endmodule
//適用於DE2-115
module CNT_7Display(
input CLOCK_50, // 50 MHz clock
input [3:0] KEY, // Pushbutton[3:0]
input [17:0] SW, // Toggle Switch[17:0]
output [6:0] HEX0,HEX1,HEX2,HEX3,HEX4,HEX5,HEX6,HEX7, // Seven Segment Digits
output [8:0] LEDG, // LED Green
output [17:0] LEDR, // LED Red
inout [35:0] GPIO_0,GPIO_1, // GPIO Connections
// LCD Module 16X2
output LCD_ON, // LCD Power ON/OFF
output LCD_BLON, // LCD Back Light ON/OFF
output LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
output LCD_EN, // LCD Enable
output LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
inout [7:0] LCD_DATA, // LCD Data bus 8 bits
input [2:0] mess, // MESSAGE STATUS (see lcd_test)
input [1:0] isServer // SERVER STATUS (see lcd_test)
);
// All inout port turn to tri-state
assign GPIO_0 = 36'hzzzzzzzzz;
assign GPIO_1 = 36'hzzzzzzzzz;
// blank unused 7-segment digits
// blank unused 7-segment digits
//assign HEX0 = 7'b111_1111;
//assign HEX1 = 7'b111_1111;
//assign HEX2 = 7'b111_1111;
//assign HEX3 = 7'b111_1111;
//assign HEX4 = 7'b111_1111;
//assign HEX5 = 7'b111_1111;
assign HEX6 = 7'b111_1111;
assign HEX7 = 7'b111_1111;
reg [7:0] segout0; //HEX 0
reg [7:0] segout1; //HEX 1
reg [7:0] segout2; //HEX 2
reg [7:0] segout3; //HEX 3
reg [7:0] segout4; //HEX 4
reg [7:0] segout5; //HEX 5
assign HEX0 = segout0 ;
assign HEX1 = segout1 ;
assign HEX2 = segout2 ;
assign HEX3 = segout3 ;
assign HEX4 = segout4 ;
assign HEX5 = segout5 ;
wire [5:0] oSEL_Out;
wire [7:0] oDIG_Out;
Top_Module( CLOCK_50, KEY[0],oSEL_Out, oDIG_Out );
always @( oSEL_Out ) begin
case( oSEL_Out )
6'b000000: begin // all on
segout0 = 8'b0000_0000;
segout1 = 8'b000_0000;
segout2 = 8'b000_0000;
segout3 = 8'b000_0000;
segout4 = 8'b000_0000;
segout5 = 8'b000_0000;
end
6'b111110: begin // 1
segout0 = oDIG_Out;
end
6'b111101: begin // 2
segout1 = oDIG_Out;
end
6'b111011: begin // 3
segout2 = oDIG_Out;
end
6'b110111: begin // 4
segout3 = oDIG_Out;
end
6'b101111: begin // 5
segout4 = oDIG_Out;
end
6'b011111: begin // 6
segout5 = oDIG_Out;
end
6'b111111: begin // all off
segout0 = 7'b111_1111;
segout1 = 7'b111_1111;
segout2 = 7'b111_1111;
segout3 = 7'b111_1111;
segout4 = 7'b111_1111;
segout5 = 7'b111_1111;
end
endcase
end
endmodule
//程式( Top_Module ):
module Top_Module(CLK, RST,SEL_Out, DIG_Out );
input CLK, RST;
output [5:0] SEL_Out;
output [7:0] DIG_Out;
wire [3:0] Cnt_Up;
wire CLK_1Hz;
Freq_Divider Div_1Hz(
.CLK(CLK),
.RST(RST),
.CLK_Out(CLK_1Hz)
);
Counter_Up up(
.CLK(CLK_1Hz),
.RST(RST),
.Cnt(Cnt_Up)
);
Seg_Seven (
.SEL_In(Cnt_Up),
.DIG_In(Cnt_Up),
.SEL_Out(SEL_Out),
.DIG_Out(DIG_Out)
);
endmodule
//程式( 除頻 1MHz ):
/* 除頻器 Use 50MHz OSC */
module Freq_Divider( CLK, RST, CLK_Out );
input CLK, RST;
output CLK_Out;
reg CLK_Out;
reg [DivW-1:0] CLK_Cnt = 0;
// 除頻設定 1Hz 1s
parameter Div = 26'd50_000_000; // 除頻數(Even)
parameter Div2 = 26'd25_000_000; // Div/2
parameter DivW = 26; // Divide寬度
always @( posedge CLK,negedge RST ) begin
if( !RST )
CLK_Cnt <= 0;
else if( CLK_Cnt == Div-1 )
CLK_Cnt <= 0;
else
CLK_Cnt <= CLK_Cnt + 1'b1;
end
always @( posedge CLK,negedge RST ) begin
if( !RST )
CLK_Out <= 0;
else if( CLK_Cnt <= Div2-1 )
CLK_Out <= 0;
else
CLK_Out <= 1'b1;
end
endmodule
//程式( 上數計數器 ):
/* 上數計數器 */
module Counter_Up( CLK, RST, Cnt );
/* 計數資訊 */
parameter Cnt_SB = 4; // 計數寬度
parameter Cnt_UP = 1'b1; // 計數值
parameter Cnt_Min = 4'd0; // 計數最小值
parameter Cnt_Max = 4'd8; // 計數最大值
input CLK, RST;
output [Cnt_SB-1:0] Cnt;
reg [Cnt_SB-1:0] Cnt = Cnt_Min;
always @( posedge CLK or negedge RST ) begin
if( !RST )
Cnt <= Cnt_Min;
else if( Cnt == Cnt_Max )
Cnt <= Cnt_Min;
else
Cnt <= Cnt + Cnt_UP;
end
endmodule
//程式( 七段顯示器解碼 ):
/* 七段顯示器解碼(共陽) */
module Seg_Seven( SEL_In, DIG_In, SEL_Out, DIG_Out );
input [2:0] SEL_In; // Use PNP
input [3:0] DIG_In; // MSB D, C, B, A LSB
output [5:0] SEL_Out; // 七段顯示器選擇
output [7:0] DIG_Out; // MSB dp, g, f, e, d, c, b, a LSB
reg [5:0] SEL_Out;
reg [7:0] DIG_Out;
always @( SEL_In ) begin
case( SEL_In )
3'b000: SEL_Out <= 6'b000000; // all on
3'b001: SEL_Out <= 6'b111110; // 1
3'b010: SEL_Out <= 6'b111101; // 2
3'b011: SEL_Out <= 6'b111011; // 3
3'b100: SEL_Out <= 6'b110111; // 4
3'b101: SEL_Out <= 6'b101111; // 5
3'b110: SEL_Out <= 6'b011111; // 6
3'b111: SEL_Out <= 6'b111111; // all off
endcase
end
always @( DIG_In ) begin
case( DIG_In )
4'b0000: DIG_Out <= 8'b11000000; // 0
4'b0001: DIG_Out <= 8'b11111001; // 1
4'b0010: DIG_Out <= 8'b10100100; // 2
4'b0011: DIG_Out <= 8'b10110000; // 3
4'b0100: DIG_Out <= 8'b10011001; // 4
4'b0101: DIG_Out <= 8'b10010010; // 5
4'b0110: DIG_Out <= 8'b10000011; // 6
4'b0111: DIG_Out <= 8'b11111000; // 7
4'b1000: DIG_Out <= 8'b10000000; // 8
4'b1001: DIG_Out <= 8'b10010000; // 9
4'b1010: DIG_Out <= 8'b01111111; // dp
default: DIG_Out <= 8'b11111111; // off
endcase
end
endmodule
沒有留言:
張貼留言