// -------------------------------------------------------------------- // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // -------------------------------------------------------------------- // Module: DLED_DISP // // Author: Step // // Description: Display with Nixie tube // // Web: www.ecbcamp.com // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.0 |2015/11/11 |Initial ver // -------------------------------------------------------------------- module DLED_DISP ( input clk_in, //25mhz input rst_n_in, //active with low output reg rclk_out, //74HC595 RCK output reg sclk_out, //74HC595 SCK output reg sdio_out //74HC595 SER ); parameter CLK_DIV_PERIOD=3900; //related with clk_div's frequency parameter DELAY_PERIOD=10000; //related with delay time and refresh frequency parameter CLK_DIV_PULSE_PERIOD=25000000; //related with clk_div_pulse_out's frequency parameter CLK_L=2'd0; parameter CLK_H=2'd1; parameter CLK_RISING_DEGE=2'd2; parameter CLK_FALLING_DEGE=2'd3; parameter IDLE=3'd0; parameter WRITE=3'd1; parameter DELAY=3'd2; parameter LOW =1'b0; parameter HIGH =1'b1; //initial for memory register reg[7:0] mem [15:0]; initial begin mem[0]= 8'h3f; // 0 mem[1]= 8'h06; // 1 mem[2]= 8'h5b; // 2 mem[3]= 8'h4f; // 3 mem[4]= 8'h66; // 4 mem[5]= 8'h6d; // 5 mem[6]= 8'h7d; // 6 mem[7]= 8'h07; // 7 mem[8]= 8'h7f; // 8 mem[9]= 8'h6f; // 9 mem[10]= 8'h77; // A mem[11]= 8'h40; // b mem[12]= 8'h39; // C mem[13]= 8'h5e; // d mem[14]= 8'h79; // E mem[15]= 8'h71; // F end //clk_div_1Hz = clk_in/CLK_DIV_PULSE_PERIOD reg[24:0] cnt; reg clk_div_1Hz; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) begin cnt<=0; clk_div_1Hz<=0; end else if(cnt==(CLK_DIV_PULSE_PERIOD-1)) begin cnt<=0; clk_div_1Hz<=1; end else begin cnt<=cnt+1; clk_div_1Hz<=0; end end reg [3:0] number = 0; reg [3:0] number_r = 1; reg [3:0] number_r1 = 2; reg [3:0] number_r2 = 3; //generate the number need to display every second always@(posedge clk_div_1Hz or negedge rst_n_in) begin if(!rst_n_in) begin number<=4'd3; number_r<=4'd2; number_r1<=4'd1; number_r2<=4'd0; end else begin number_r2<=number_r1; number_r1<=number_r; number_r<=number; if(number>=9) number<=0; else number<=number+1; end end //clk_div = clk_in/CLK_DIV_PERIOD reg clk_div; reg[11:0] clk_cnt=0; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) clk_cnt<=0; else begin clk_cnt<=clk_cnt+1; if(clk_cnt==(CLK_DIV_PERIOD-1)) clk_cnt<=0; if(clk_cnt<(CLK_DIV_PERIOD/2)) clk_div<=0; else clk_div<=1; end end //Divide clk_div 4 state, //RISING and FALLING state is keeped one cycle of clk_in, like a pulse. reg[1:0] clk_div_state=CLK_L; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) clk_div_state<=CLK_L; else case(clk_div_state) CLK_L: begin if (clk_div) clk_div_state<=CLK_RISING_DEGE; else clk_div_state<=CLK_L; end CLK_RISING_DEGE :clk_div_state<=CLK_H; CLK_H:begin if (!clk_div) clk_div_state<=CLK_FALLING_DEGE; else clk_div_state<=CLK_H; end CLK_FALLING_DEGE:clk_div_state<=CLK_L; default; endcase end //Finite State Machine, reg shift_flag = 0; reg[15:0] data_reg; reg[2:0] data_state=IDLE; reg[2:0] data_state_back; reg[3:0] data_state_cnt=0; reg[5:0] shift_cnt=0; reg[25:0] delay_cnt=0; always@(posedge clk_in or negedge rst_n_in) begin if(!rst_n_in) begin data_state<=IDLE; data_state_cnt<=0; end else begin case (data_state) IDLE: begin data_state_cnt<=data_state_cnt+1; case(data_state_cnt) 0: begin data_reg<={mem[number_r2],8'h2e}; data_state<=WRITE;data_state_back<=IDLE; end 1: begin data_reg<={mem[number_r1],8'h2d}; data_state<=WRITE;data_state_back<=IDLE; end 2: begin data_reg<={mem[number_r],8'h2b}; data_state<=WRITE;data_state_back<=IDLE; end 3: begin data_reg<={mem[number],8'h27}; data_state<=WRITE;data_state_back<=IDLE; end 4: begin data_state_cnt<=0; end default; endcase end WRITE: begin if(!shift_flag) begin if (clk_div_state==CLK_FALLING_DEGE) begin if (shift_cnt==10) rclk_out<=LOW; if (shift_cnt==16) begin shift_cnt<=0; rclk_out<=HIGH; data_state<=data_state_back; end else begin sclk_out<=LOW; sdio_out<=data_reg[15]; shift_flag <= 1; end end end else begin if (clk_div_state==CLK_RISING_DEGE) begin data_reg<={data_reg[14:0], data_reg[15]}; shift_cnt<=shift_cnt+1; sclk_out<=HIGH; shift_flag <= 0; end end end DELAY: begin if(delay_cnt==DELAY_PERIOD) begin data_state<=IDLE; delay_cnt<=0; end else delay_cnt<=delay_cnt+1; end default; endcase end end endmodule