|
|
module ws2812_ctrl(
|
|
|
input wire sys_clk ,
|
|
|
input wire sys_rst_n ,
|
|
|
input wire bit ,
|
|
|
|
|
|
output wire dout
|
|
|
);
|
|
|
parameter T0H = 4'd15 ,//bit0的高电平
|
|
|
T0L = 6'd40 ,//bit0的低电平
|
|
|
T1H = 6'd40 ,//bit1的高电平
|
|
|
T1L = 6'd40 ,//bit1的低电平
|
|
|
RST = 14'd15000 ;//64个led数据发完的复位信号时间,低电平0
|
|
|
|
|
|
reg [5: 0] cnt_0;//bit0计数寄存器
|
|
|
wire add_cnt0;//bit0开始计数条件
|
|
|
wire end_cnt0;//bit0结束计数条件
|
|
|
|
|
|
reg [6: 0] cnt_1;//bit1计数寄存器
|
|
|
wire add_cnt1;//bit1开始计数条件
|
|
|
wire end_cnt1;//bit1结束计数条件
|
|
|
|
|
|
reg [4: 0] cnt_bit;//24个bit计数寄存器
|
|
|
wire add_cnt_bit;//24bit计数器开始计数条件
|
|
|
wire end_cnt_bit;//24bit计数器结束计数条件
|
|
|
|
|
|
reg [6: 0] cnt_led;//64个led计数寄存器
|
|
|
wire add_cnt_led;//64个led计数器开始计数条件
|
|
|
wire end_cnt_led;//64个led计数器结束计数条件
|
|
|
|
|
|
reg [13: 0] cnt_rst;//复位计数寄存器
|
|
|
wire add_cnt_rst;//复位计数器开始计数条件
|
|
|
wire end_cnt_rst;//复位计数器结束计数条件
|
|
|
|
|
|
reg flag_rst;//复位信号开始寄存器
|
|
|
//bit0计数器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n) begin
|
|
|
if(!sys_rst_n)begin
|
|
|
cnt_0 <= 6'd0;
|
|
|
end
|
|
|
else if(add_cnt0)begin
|
|
|
if(end_cnt0)begin
|
|
|
cnt_0 <= 6'd0;
|
|
|
end
|
|
|
else begin
|
|
|
cnt_0 <= cnt_0 + 1'd1;
|
|
|
end
|
|
|
end
|
|
|
else begin
|
|
|
cnt_0 <= 6'd0;
|
|
|
end
|
|
|
end
|
|
|
assign add_cnt0 = ~bit && flag_rst == 0;//如果bit是0,并且复位计数器没有开启,则计数器开始计数
|
|
|
assign end_cnt0 = add_cnt0 && (cnt_0 == T0H + T0L-1);
|
|
|
|
|
|
//cnt_1计数器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
|
if(!sys_rst_n)begin
|
|
|
cnt_1 <= 7'd0;
|
|
|
end
|
|
|
else if(add_cnt1)begin
|
|
|
if(end_cnt1)begin
|
|
|
cnt_1 <= 7'd0;
|
|
|
end
|
|
|
else begin
|
|
|
cnt_1 <= cnt_1 + 1'd1;
|
|
|
end
|
|
|
end
|
|
|
else begin
|
|
|
cnt_1 <= 7'd0;
|
|
|
end
|
|
|
end
|
|
|
assign add_cnt1 = bit && flag_rst == 0;//如果bit是1,并且复位计数器没有开启,则计数器开始计数
|
|
|
assign end_cnt1 = add_cnt1 && (cnt_1 == T1H + T1L-1);
|
|
|
|
|
|
//cnt_bit计数器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
|
if(!sys_rst_n)begin
|
|
|
cnt_bit <= 5'd0;
|
|
|
end
|
|
|
else if(add_cnt_bit)begin
|
|
|
if(end_cnt_bit)begin
|
|
|
cnt_bit <= 5'd0;
|
|
|
end
|
|
|
else begin
|
|
|
cnt_bit <= cnt_bit + 1'd1;
|
|
|
end
|
|
|
end
|
|
|
else begin
|
|
|
cnt_bit <= cnt_bit;//其他时刻保持cnt_bit
|
|
|
end
|
|
|
end
|
|
|
assign add_cnt_bit = end_cnt0 || end_cnt1;//bit0或者bit1结束计数条件成立
|
|
|
assign end_cnt_bit = add_cnt_bit && (cnt_bit == 5'd23);//24个bit结束计数条件成立
|
|
|
|
|
|
//cnt_led计数器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
|
if(!sys_rst_n)begin
|
|
|
cnt_led <= 7'd0;
|
|
|
end
|
|
|
else if(add_cnt_led)begin
|
|
|
if(end_cnt_led)begin
|
|
|
cnt_led <= 7'd0;
|
|
|
end
|
|
|
else begin
|
|
|
cnt_led <= cnt_led + 1'd1;
|
|
|
end
|
|
|
end
|
|
|
else begin
|
|
|
cnt_led <= cnt_led;
|
|
|
end
|
|
|
end
|
|
|
assign add_cnt_led = end_cnt_bit;
|
|
|
assign end_cnt_led = add_cnt_led && (cnt_led == 7'd63);
|
|
|
|
|
|
//cnt_rst计数器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
|
if(!sys_rst_n)begin
|
|
|
cnt_rst <= 14'd0;
|
|
|
end
|
|
|
else if(add_cnt_rst)begin
|
|
|
if(end_cnt_rst)begin
|
|
|
cnt_rst <= 14'd0;
|
|
|
end
|
|
|
else begin
|
|
|
cnt_rst <= cnt_rst + 1'd1;
|
|
|
end
|
|
|
end
|
|
|
else begin
|
|
|
cnt_rst <= cnt_rst;
|
|
|
end
|
|
|
end
|
|
|
assign add_cnt_rst = flag_rst;
|
|
|
assign end_cnt_rst = add_cnt_rst && (cnt_rst == RST - 1);
|
|
|
|
|
|
//flag_rst寄存器设计
|
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
|
if(!sys_rst_n)begin
|
|
|
flag_rst <= 1'b0;//初始化0,复位计数器关闭
|
|
|
end
|
|
|
else if(end_cnt_led)begin//64个led数据发送完成,复位计数器打开
|
|
|
flag_rst <= 1'b1;
|
|
|
end
|
|
|
else if(end_cnt_rst)begin//复位计数器结束,复位计数器关闭
|
|
|
flag_rst <= 1'b0;
|
|
|
end
|
|
|
else begin
|
|
|
flag_rst <= flag_rst;//其他时刻保持flag_rst
|
|
|
end
|
|
|
end
|
|
|
//dout输出逻辑
|
|
|
assign dout = (flag_rst == 0) ? ((cnt_0 < T0H ? 1'b0 : 1'b1) | (cnt_1 < T1H ? 1'b0 : 1'b1)): 1'b0;
|
|
|
endmodule
|