DLED_DISP程序
// --------------------------------------------------------------------
// >>>>>>>>>>>>>>>>>>>>>>>>> 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