commit c752d460f1dc702ab4bdf151ab4394d9a56c852e Author: lincaigui <18166451309@163.com> Date: Mon Apr 22 14:55:26 2024 +0800 animation diff --git a/doc/ws2812时序图.vsdx b/doc/ws2812时序图.vsdx new file mode 100644 index 0000000..3ca7da4 Binary files /dev/null and b/doc/ws2812时序图.vsdx differ diff --git a/doc/协议规定.txt b/doc/协议规定.txt new file mode 100644 index 0000000..b5b9738 --- /dev/null +++ b/doc/协议规定.txt @@ -0,0 +1,6 @@ +T0H=4'd15; +T0L=6'd40; +T1H=6'd40; +T1L=6'd40; +RST=14'd15000; +GRB 24比特,高位先发(msb); \ No newline at end of file diff --git a/doc/说明文档.docx b/doc/说明文档.docx new file mode 100644 index 0000000..4cc9b93 Binary files /dev/null and b/doc/说明文档.docx differ diff --git a/rtl/data_cfg.v b/rtl/data_cfg.v new file mode 100644 index 0000000..a90204f --- /dev/null +++ b/rtl/data_cfg.v @@ -0,0 +1,74 @@ +module data_cfg( + input wire [4: 0] cnt_bit, + input wire [6: 0] cnt_led, + + output wire bit +); +wire [23: 0] data[63: 0];//数据 +assign bit = data[cnt_led][23 - cnt_bit]; +assign data[00] = {8'hff, 8'hff, 8'hff};//GRB +assign data[01] = {8'h00, 8'h00, 8'h00};//GRB +assign data[02] = {8'h00, 8'hff, 8'h00};//GRB +assign data[03] = {8'h00, 8'h00, 8'h00};//GRB +assign data[04] = {8'h00, 8'h00, 8'h00};//GRB +assign data[05] = {8'h00, 8'h00, 8'h00};//GRB +assign data[06] = {8'h00, 8'h00, 8'h00};//GRB +assign data[07] = {8'h00, 8'h00, 8'h00};//GRB +assign data[08] = {8'h00, 8'h00, 8'h00};//GRB +assign data[09] = {8'h00, 8'h00, 8'h00};//GRB +assign data[10] = {8'h00, 8'h00, 8'h00};//GRB +assign data[11] = {8'h00, 8'h00, 8'h00};//GRB +assign data[12] = {8'h00, 8'h00, 8'h00};//GRB +assign data[13] = {8'h00, 8'h00, 8'h00};//GRB +assign data[14] = {8'h00, 8'h00, 8'h00};//GRB +assign data[15] = {8'h00, 8'h00, 8'h00};//GRB +assign data[16] = {8'h00, 8'h00, 8'h00};//GRB +assign data[17] = {8'h00, 8'h00, 8'h00};//GRB +assign data[18] = {8'h00, 8'h00, 8'h00};//GRB +assign data[19] = {8'h00, 8'h00, 8'h00};//GRB +assign data[20] = {8'h00, 8'h00, 8'h00};//GRB +assign data[21] = {8'h00, 8'h00, 8'h00};//GRB +assign data[22] = {8'h00, 8'h00, 8'h00};//GRB +assign data[23] = {8'h00, 8'h00, 8'h00};//GRB +assign data[24] = {8'h00, 8'h00, 8'h00};//GRB +assign data[25] = {8'h00, 8'h00, 8'h00};//GRB +assign data[26] = {8'h00, 8'h00, 8'h00};//GRB +assign data[27] = {8'h00, 8'h00, 8'h00};//GRB +assign data[28] = {8'h00, 8'h00, 8'h00};//GRB +assign data[29] = {8'h00, 8'h00, 8'h00};//GRB +assign data[30] = {8'h00, 8'h00, 8'h00};//GRB +assign data[31] = {8'h00, 8'h00, 8'h00};//GRB +assign data[32] = {8'h00, 8'h00, 8'h00};//GRB +assign data[33] = {8'h00, 8'h00, 8'h00};//GRB +assign data[34] = {8'h00, 8'h00, 8'h00};//GRB +assign data[35] = {8'h00, 8'h00, 8'h00};//GRB +assign data[36] = {8'h00, 8'h00, 8'h00};//GRB +assign data[37] = {8'h00, 8'h00, 8'h00};//GRB +assign data[38] = {8'h00, 8'h00, 8'h00};//GRB +assign data[39] = {8'h00, 8'h00, 8'h00};//GRB +assign data[40] = {8'h00, 8'h00, 8'h00};//GRB +assign data[41] = {8'h00, 8'h00, 8'h00};//GRB +assign data[42] = {8'h00, 8'h00, 8'h00};//GRB +assign data[43] = {8'h00, 8'h00, 8'h00};//GRB +assign data[44] = {8'h00, 8'h00, 8'h00};//GRB +assign data[45] = {8'h00, 8'h00, 8'h00};//GRB +assign data[46] = {8'h00, 8'h00, 8'h00};//GRB +assign data[47] = {8'h00, 8'h00, 8'h00};//GRB +assign data[48] = {8'h00, 8'h00, 8'h00};//GRB +assign data[49] = {8'h00, 8'h00, 8'h00};//GRB +assign data[50] = {8'h00, 8'h00, 8'h00};//GRB +assign data[51] = {8'h00, 8'h00, 8'h00};//GRB +assign data[52] = {8'h00, 8'h00, 8'h00};//GRB +assign data[53] = {8'h00, 8'h00, 8'h00};//GRB +assign data[54] = {8'h00, 8'h00, 8'h00};//GRB +assign data[55] = {8'h00, 8'h00, 8'h00};//GRB +assign data[56] = {8'h00, 8'h00, 8'h00};//GRB +assign data[57] = {8'h00, 8'h00, 8'h00};//GRB +assign data[58] = {8'h00, 8'h00, 8'h00};//GRB +assign data[59] = {8'h00, 8'h00, 8'h00};//GRB +assign data[60] = {8'h00, 8'h00, 8'h00};//GRB +assign data[61] = {8'h00, 8'h00, 8'h00};//GRB +assign data[62] = {8'h00, 8'h00, 8'h00};//GRB +assign data[63] = {8'h00, 8'h00, 8'h00};//GRB + +endmodule \ No newline at end of file diff --git a/rtl/ws2812_ctrl.v b/rtl/ws2812_ctrl.v new file mode 100644 index 0000000..503a30d --- /dev/null +++ b/rtl/ws2812_ctrl.v @@ -0,0 +1,154 @@ +module ws2812_ctrl( + input wire sys_clk , + input wire sys_rst_n , + input wire bit , + + output wire dout , + output reg [4: 0] cnt_bit , + output reg [6: 0] cnt_led +); +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) ? (((bit == 0 && cnt_0 < T0H) ? 1'b1 : 1'b0) | ((bit == 1 && cnt_1 < T1H) ? 1'b1 : 1'b0)): 1'b0; +endmodule \ No newline at end of file diff --git a/rtl/ws2812_top.v b/rtl/ws2812_top.v new file mode 100644 index 0000000..6efafbe --- /dev/null +++ b/rtl/ws2812_top.v @@ -0,0 +1,27 @@ +module ws2812_top( + input wire sys_clk , + input wire sys_rst_n , + + output wire dout +); +wire bit ; +wire [4: 0] cnt_bit; +wire [6: 0] cnt_led; + +ws2812_ctrl ws2812_ctrl_inst( +.sys_clk (sys_clk), +.sys_rst_n (sys_rst_n), +.bit (bit), + +.dout (dout), +.cnt_bit (cnt_bit), +.cnt_led (cnt_led) +); + +data_cfg data_cfg_inst( +.cnt_bit (cnt_bit), +.cnt_led (cnt_led), + +.bit (bit) +); +endmodule \ No newline at end of file diff --git a/tcl/ws2812_led.tcl b/tcl/ws2812_led.tcl new file mode 100644 index 0000000..2991202 --- /dev/null +++ b/tcl/ws2812_led.tcl @@ -0,0 +1,23 @@ +# Copyright (C) 2018 Intel Corporation. All rights reserved. +# Your use of Intel Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Intel Program License +# Subscription Agreement, the Intel Quartus Prime License Agreement, +# the Intel FPGA IP License Agreement, or other applicable license +# agreement, including, without limitation, that your use is for +# the sole purpose of programming logic devices manufactured by +# Intel and sold by Intel or its authorized distributors. Please +# refer to the applicable agreement for further details. + +# Quartus Prime Version 18.1.0 Build 625 09/12/2018 SJ Standard Edition +# File: C:\Users\Stark-lin\Desktop\ws2812_led\tcl\ws2812_led.tcl +# Generated on: Mon Apr 22 10:12:26 2024 + +package require ::quartus::project + +set_location_assignment PIN_K6 -to dout +set_location_assignment PIN_E1 -to sys_clk +set_location_assignment PIN_E15 -to sys_rst_n