module omdazz_WS2812b #( parameter integer WS2812_NUM = 10 - 1, parameter integer WS2812_WIDTH = 24, parameter integer CLK_FRE = 50_000_000 )( input wire CLOCK_50, output reg WS2812 ); localparam integer DELAY_1_HIGH = 40 - 1; // 0.8 us @ 50 MHz localparam integer DELAY_1_LOW = 22 - 1; // 0.45 us @ 50 MHz localparam integer DELAY_0_HIGH = 20 - 1; // 0.4 us @ 50 MHz localparam integer DELAY_0_LOW = 43 - 1; // 0.85 us @ 50 MHz localparam integer DELAY_RESET = 3000 - 1; // 60 us @ 50 MHz localparam RESET = 2'd0; localparam DATA_SEND = 2'd1; localparam BIT_SEND_HIGH = 2'd2; localparam BIT_SEND_LOW = 2'd3; reg [1:0] state = RESET; reg [8:0] bit_send = 0; reg [8:0] data_send = 0; reg [31:0] clk_count = 0; // Формат WS2812: обычно GRB, отправка старшим битом вперёд reg [23:0] WS2812_data = 24'h000001; always @(posedge CLOCK_50) begin case (state) RESET: begin WS2812 <= 1'b0; if (clk_count < DELAY_RESET) clk_count <= clk_count + 1'b1; else begin clk_count <= 0; // Смена цвета после передачи очередного кадра WS2812_data <= {WS2812_data[22:0], WS2812_data[23]}; state <= DATA_SEND; end end DATA_SEND: begin if ((data_send == WS2812_NUM) && (bit_send == WS2812_WIDTH)) begin data_send <= 0; bit_send <= 0; state <= RESET; end else if (bit_send < WS2812_WIDTH) begin state <= BIT_SEND_HIGH; end else begin data_send <= data_send + 1'b1; bit_send <= 0; state <= BIT_SEND_HIGH; end end BIT_SEND_HIGH: begin WS2812 <= 1'b1; if (WS2812_data[WS2812_WIDTH - 1 - bit_send]) begin if (clk_count < DELAY_1_HIGH) clk_count <= clk_count + 1'b1; else begin clk_count <= 0; state <= BIT_SEND_LOW; end end else begin if (clk_count < DELAY_0_HIGH) clk_count <= clk_count + 1'b1; else begin clk_count <= 0; state <= BIT_SEND_LOW; end end end BIT_SEND_LOW: begin WS2812 <= 1'b0; if (WS2812_data[WS2812_WIDTH - 1 - bit_send]) begin if (clk_count < DELAY_1_LOW) clk_count <= clk_count + 1'b1; else begin clk_count <= 0; bit_send <= bit_send + 1'b1; state <= DATA_SEND; end end else begin if (clk_count < DELAY_0_LOW) clk_count <= clk_count + 1'b1; else begin clk_count <= 0; bit_send <= bit_send + 1'b1; state <= DATA_SEND; end end end default: state <= RESET; endcase end endmodule