|
|
|
|
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
|