This repository has been archived on 2024-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
study/pwm/rtl/ir_decoder.v
2020-06-09 15:48:03 +08:00

191 lines
3.3 KiB
Verilog

`timescale 1ns/1ns
module ir_decoder(
clk,
rst_n,
iIR,
irAddr,
irData,
Get_Flag
);
localparam s0= 3'b000,
s1= 3'b001,
s2= 3'b011,
s3= 3'b010;
input clk;
input rst_n;
input iIR;
output [15:0] irAddr;
output [15:0] irData;
output Get_Flag;
reg[18:0]cnt;
reg [2:0]iIR_r;
reg en;
reg [2:0]staus,next_status;
reg [5:0]data_cnt;
reg [31:0]data_tmp;
reg Get_Data_Done;
reg T9ms_ok,T4_5ms_ok,T_56ms_ok,T1_69ms_ok;
wire pedge,nedge;
assign nedge = iIR_r[2] & (!iIR_r[1]);
assign pedge = iIR_r[1] & (!iIR_r[2]);
assign irAddr = data_tmp[15:0];
assign irData = data_tmp[31:16];
assign Get_Flag = Get_Data_Done;
always @ (posedge clk)
if(!rst_n)
begin
Get_Data_Done <= 1'b0;
data_cnt <= 6'd0;
data_tmp <= 32'd0;
end
else if(staus == s3)
if(pedge & (data_cnt == 6'd32))
begin
data_cnt <= 6'd0;
Get_Data_Done <= 1'd1;
end
else
begin
Get_Data_Done <= 1'd0;
if(nedge)
begin
data_cnt <= data_cnt + 6'd1;
if(T_56ms_ok)
data_tmp[data_cnt] <= 1'b0;
else if(T1_69ms_ok)
data_tmp[data_cnt] <= 1'b1;
end
end
always @ (posedge clk or negedge rst_n)
if(!rst_n)
staus <= s0;//空闲
else
staus <= next_status;
always @ (*)
case(staus)
s0:
if(nedge)
next_status <= s1;
else
next_status <= s0;
s1:
if(pedge)
begin
if(T9ms_ok)
next_status <= s2;
else
next_status <= s0;
end
else
next_status <= s1;
s2:
if(nedge)
begin
if(T4_5ms_ok)
next_status <= s3;
else
next_status <= s0;
end
else
next_status <= s2;
s3:
if(pedge & (!T_56ms_ok))
next_status <= s0;
else if(nedge & (!T_56ms_ok) & (!T1_69ms_ok))
next_status <= s0;
else if(Get_Data_Done)
next_status <= s0;
else
next_status <= s3;
default:next_status<=s0;
endcase
always @ (*)
case(staus)
s0:
if(nedge)
en <= 1'b1;
else
en <= 1'b0;
s1:
if(pedge & T9ms_ok)
en <= 1'b0;
else
en <= 1'b1;
s2:
if(nedge & T4_5ms_ok)
en <= 1'b0;
else
en <= 1'b1;
s3:
if(pedge & T_56ms_ok)
en <= 1'b0;
else if(nedge & (T_56ms_ok | T1_69ms_ok))
en <= 1'b0;
else
en <= 1'b1;
default:en<=1'b0;
endcase
always@(posedge clk or negedge rst_n)
if(!rst_n)
T9ms_ok <= 1'b0;
else if(cnt > 19'd325000 && cnt <19'd495000)
T9ms_ok <= 1'b1;
else
T9ms_ok <= 1'b0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
T4_5ms_ok <= 1'b0;
else if(cnt > 19'd152500 && cnt <19'd277500)
T4_5ms_ok <= 1'b1;
else
T4_5ms_ok <= 1'b0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
T_56ms_ok <= 1'b0;
else if(cnt > 19'd20000 && cnt <19'd35000)
T_56ms_ok <= 1'b1;
else
T_56ms_ok <= 1'b0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
T1_69ms_ok <= 1'b0;
else if(cnt > 19'd75000 && cnt <19'd90000)
T1_69ms_ok <= 1'b1;
else
T1_69ms_ok <= 1'b0;
always @ (posedge clk)
if(!rst_n)
iIR_r <= 3'b111;
else
iIR_r <= {iIR_r[1:0],iIR};
always @ (posedge clk)
if(!rst_n)
cnt <= 19'd0;
else if(en)
cnt <= cnt+19'd1;
else
cnt <= 19'd0;
endmodule