2020年2月29日 星期六

Verilog 應用範例 : 計數器 ( 七段顯示器 ) 適用於DE2-115 (DE2-70)

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




沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...