You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
5.3 KiB
Coq

5 months ago
module ws2812_ctrl(
input sys_clk ,//50MHz
input sys_rst_n ,//沿
input bit ,//data_cfgbit
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;//0bit1bitbit1
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