module ws2812_ctrl( input sys_clk ,//系统时钟,50MHz input sys_rst_n ,//系统复位,下降沿有效 input bit ,//data_cfg给的bit input [3: 0] opcode , input [3: 0] data , input [1: 0] dev_id ,//设备地址 output reg [4: 0] bit_num ,//bit计数寄存器 output reg [6: 0] led_num ,//led计数寄存器 output reg [1: 0] frame ,//帧 output dout//点阵输出 ); parameter T0H = 4'd13,//0高电平时间 T0L = 5'd30,//0低电平时间 T1H = 5'd30,//1高电平时间 T1L = 5'd30,//1低电平时间 RST = 26'd5_000_000;//复位时间 parameter BIT = 5'd24, LED = 7'd64; reg [5: 0] cnt_0;//0bit计数寄存器 wire add_cnt_0; wire end_cnt_0; reg [5: 0] cnt_1;//1bit计数寄存器 wire add_cnt_1; wire end_cnt_1; reg [25: 0] cnt_rst;//复位计数寄存器 wire add_cnt_rst; wire end_cnt_rst; //bit计数寄存器 wire add_bit_num; wire end_bit_num; //led计数寄存器 wire add_led_num; wire end_led_num; reg rst_flag ;//复位标志 reg start_flag ; //开始信号 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin start_flag <= 1'b0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin start_flag <= 1'b0; end else if((dev_id == 2'd3) && (opcode == 4'b0010))begin start_flag <= 1'b1; end else begin start_flag <= start_flag; end end //bit0计数器设计 always @(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n)begin cnt_0 <= 6'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin cnt_0 <= 6'd0; end else if(add_cnt_0)begin if(end_cnt_0)begin cnt_0 <= 6'd0; end else begin cnt_0 <= cnt_0 + 1'd1; end end else begin cnt_0 <= cnt_0; end end assign add_cnt_0 = start_flag && ~bit && ~rst_flag; assign end_cnt_0 = add_cnt_0 && cnt_0 == T0H + T0L - 1'd1; //bit1计数器设计 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin cnt_1 <= 6'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin cnt_1 <= 6'd0; end else if(add_cnt_1)begin if(end_cnt_1)begin cnt_1 <= 6'd0; end else begin cnt_1 <= cnt_1 + 1'd1; end end else begin cnt_1 <= cnt_1; end end assign add_cnt_1 = start_flag && bit && ~rst_flag; assign end_cnt_1 = add_cnt_1 && cnt_1 == T1H + T1L - 1'd1; //bit计数器设计 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin bit_num <= 5'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin bit_num <= 5'd0; end else if(add_bit_num)begin if(end_bit_num)begin bit_num <= 5'd0; end else begin bit_num <= bit_num + 1'd1; end end else begin bit_num <= bit_num; end end assign add_bit_num = end_cnt_0 || end_cnt_1;//0bit或者1bit结束,bit计数器加1 assign end_bit_num = add_bit_num && bit_num == BIT - 1'd1; //led计数器设计 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin led_num <= 7'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin led_num <= 7'd0; end else if(add_led_num)begin if(end_led_num)begin led_num <= 7'd0; end else begin led_num <= led_num + 1'd1; end end else begin led_num <= led_num; end end assign add_led_num = end_bit_num; assign end_led_num = add_led_num && led_num == LED - 1'd1; //rst_flag约束 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin rst_flag <= 1'b0; end else if(end_led_num)begin rst_flag <= 1'b1; end else if(end_cnt_rst)begin rst_flag <= 1'b0; end else begin rst_flag <= rst_flag; end end //复位计数器设计 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin cnt_rst <= 26'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin cnt_rst <= 26'd0; end else if(add_cnt_rst)begin if(end_cnt_rst)begin cnt_rst <= 26'd0; end else begin cnt_rst <= cnt_rst + 1'd1; end end else begin cnt_rst <= cnt_rst; end end assign add_cnt_rst = rst_flag; assign end_cnt_rst = add_cnt_rst && cnt_rst == RST - 1'd1; //frame约束 always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin frame <= 2'd0; end else if((dev_id == 2'd3) && (opcode == 4'b0001))begin frame <= 2'd0; end else if((frame == 2'd3) && (end_cnt_rst))begin frame <= 2'd0; end else if(end_cnt_rst)begin frame <= frame + 1'd1; end else begin frame <= frame; end end ///////////////输出/////////////// assign dout = (rst_flag == 0) ? (((bit == 0 && cnt_0 < T0H) ? 1'b1 : 1'b0) | ((bit == 1 && cnt_1 < T1H) ? 1'b1 : 1'b0)): 1'b0; endmodule