diff --git a/omdazz_WS2812b.qsf b/omdazz_WS2812b.qsf index 979fa47..677dfb6 100644 --- a/omdazz_WS2812b.qsf +++ b/omdazz_WS2812b.qsf @@ -38,7 +38,7 @@ set_global_assignment -name FAMILY "Cyclone IV E" set_global_assignment -name DEVICE EP4CE6E22C8 -set_global_assignment -name TOP_LEVEL_ENTITY omdazz_WS2812b +set_global_assignment -name TOP_LEVEL_ENTITY top set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1" set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:00:54 AUGUST 07, 2026" set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1" @@ -48,21 +48,20 @@ set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V -set_global_assignment -name VERILOG_FILE omdazz_WS2812b.v set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" -set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top -set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top -set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "2.5 V" set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CLOCK_50 set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to D_INP[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to WS2812 set_location_assignment PIN_23 -to CLOCK_50 set_location_assignment PIN_31 -to D_INP[4] -set_location_assignment PIN_42 -to WS2812 -set_global_assignment -name CDF_FILE output_files/Chain1.cdf -set_global_assignment -name CDF_FILE output_files/Chain3.cdf -set_global_assignment -name CDF_FILE output_files/Chain5.cdf +set_global_assignment -name SDC_FILE omdazz_WS2812b.sdc set_global_assignment -name VERILOG_FILE top.v +set_global_assignment -name VERILOG_FILE omdazz_WS2812b.v +set_global_assignment -name CDF_FILE output_files/Chain1.cdf +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_location_assignment PIN_42 -to WS2812_OUT +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to WS2812_OUT set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/omdazz_WS2812b.sdc b/omdazz_WS2812b.sdc new file mode 100644 index 0000000..fc7063b --- /dev/null +++ b/omdazz_WS2812b.sdc @@ -0,0 +1,3 @@ +create_clock -period 20 -name CLOCK_50 [get_ports CLOCK_50] + + diff --git a/omdazz_WS2812b.v b/omdazz_WS2812b.v index 109b884..b6a83cd 100644 --- a/omdazz_WS2812b.v +++ b/omdazz_WS2812b.v @@ -7,105 +7,95 @@ module omdazz_WS2812b #( 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; +parameter F_SCALE = 50 / 27; // conversion factor from 27 MHz to 50 MHz - reg [1:0] state = RESET; - reg [8:0] bit_send = 0; - reg [8:0] data_send = 0; - reg [31:0] clk_count = 0; +parameter DELAY_1_HIGH = (CLK_FRE / 1_000_000 * 85 / 100 * F_SCALE) - 1; +parameter DELAY_1_LOW = (CLK_FRE / 1_000_000 * 40 / 100 * F_SCALE) - 1; +parameter DELAY_0_HIGH = (CLK_FRE / 1_000_000 * 40 / 100 * F_SCALE) - 1; +parameter DELAY_0_LOW = (CLK_FRE / 1_000_000 * 85 / 100 * F_SCALE) - 1; +parameter DELAY_RESET = (CLK_FRE / 10 * F_SCALE) - 1; - // Формат WS2812: обычно GRB, отправка старшим битом вперёд - reg [23:0] WS2812_data = 24'h000001; +parameter RESET = 0; // state machine declaration +parameter DATA_SEND = 1; +parameter BIT_SEND_HIGH = 2; +parameter BIT_SEND_LOW = 3; - always @(posedge CLOCK_50) begin - case (state) +reg [ 1:0] state = 0; // synthesis preserve // main state machine control +reg [ 8:0] bit_send = 0; // amount of bits sent // increase it for larger LED strips/matrix +reg [ 8:0] data_send = 0; // amount of data words sent // increase it for larger LED strips/matrix +reg [31:0] clk_count = 0; // delay control +reg [23:0] WS2812_data = 24'd1; // WS2812 color data - RESET: begin - WS2812 <= 1'b0; +always@(posedge CLOCK_50) + case (state) + RESET:begin + WS2812 <= 0; - 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 + if (clk_count < DELAY_RESET) + clk_count <= clk_count + 1; + else begin + clk_count <= 0; + WS2812_data <= {WS2812_data[22:0],WS2812_data[23]};// color shifting for cyclic + 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 + DATA_SEND: + 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// if (bit_send == WS2812_WIDTH) + data_send <= data_send + 1; + bit_send <= 0; + state <= BIT_SEND_HIGH; + end + + BIT_SEND_HIGH:begin + WS2812 <= 1; - BIT_SEND_HIGH: begin - WS2812 <= 1'b1; + if (WS2812_data[bit_send]) + if (clk_count < DELAY_1_HIGH) + clk_count <= clk_count + 1; + else begin + clk_count <= 0; + state <= BIT_SEND_LOW; + end + else + if (clk_count < DELAY_0_HIGH) + clk_count <= clk_count + 1; + else begin + clk_count <= 0; + state <= BIT_SEND_LOW; + end + end - 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 <= 0; - BIT_SEND_LOW: begin - WS2812 <= 1'b0; + if (WS2812_data[bit_send]) + if (clk_count < DELAY_1_LOW) + clk_count <= clk_count + 1; + else begin + clk_count <= 0; - 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 \ No newline at end of file + bit_send <= bit_send + 1; + state <= DATA_SEND; + end + else + if (clk_count < DELAY_0_LOW) + clk_count <= clk_count + 1; + else begin + clk_count <= 0; + + bit_send <= bit_send + 1; + state <= DATA_SEND; + end + end + endcase +endmodule diff --git a/top.v b/top.v index 491b265..76e314f 100644 --- a/top.v +++ b/top.v @@ -1,3 +1,4 @@ +top module module top( input wire CLOCK_50, input wire [4:4] D_INP,