红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗 低,成本低,易实现等显著优点。
这个工程太久之前写的,没对知识点印象有点模糊就不显丑了。当时也没上板子验证,凑合着看。废话不多说直接给出rtl图粘贴代码
总体框图RTL:
top:
module top_inf_rcv(
input wire clk_sys ,
input wire rst_n_sys ,
input wire inf_in ,
output wire led ,
output wire ds ,
output wire oe ,
output wire sh_cp ,
output wire st_cp
);
parameter point =6'b0 ,
sign =1'b0 ,
en_seg=1'b0 ;
//output inf_rcv
wire [19:0]data ;
wire repeat_en ;
inf_rcv inf_rcv_inst(
.clk_sys (clk_sys ),
.rst_n_sys (rst_n_sys ),
.inf_in (inf_in ),
.repeat_en (repeat_en ),
.data (data )
);
led_ctrl led_ctrl_inst(
.clk_sys (clk_sys ),
.rst_n_sys (rst_n_sys ),
.repeat_en (repeat_en ),
.led (led )
);
seg_595_dynamic(
.clk_sys (clk_sys ),
.rst_n_sys (rst_n_sys ),
.data (data ),
.point (point ),
.sign (sign ),
.en_seg (en_seg ),
.ds (ds ),
.sh_cp (sh_cp ),
.st_cp (st_cp ),
.oe (oe ),
);
endmodule
inf_rcv:
module inf_rcv(
input wire clk_sys ,
input wire rst_n_sys ,
input wire inf_in ,
output reg repeat_en ,
output reg [19:0]data
);
parameter IDLE =5'B00_001 ,
TIME_9MS =5'B00_010 ,
ARBIT =5'B00_100 ,
DATA =5'B01_000 ,
REPEAT =5'B10_000 ;
parameter CNT_9A =19'D449_900 ,
CNT_9B =19'D450_010 ,
CNT_45A =19'D224_900 ,
CNT_45B =19'D225_010 ,
CNT_225A =19'D112_400 ,
CNT_225B =19'D112_510 ,
CNT_169A =19'D84_400 ,
CNT_169B =19'D84_510 ,
CNT_560A =19'D27_900 ,
CNT_560B =19'D28_010 ;
reg [4:0]state ;
reg [18:0]cnt ;
reg flag_9ms,flag_4_5ms,flag_560us,flag_1_69ms,flag_2_25ms;
reg [5:0]cnt_data ;
wire flag_fall,flag_rise ;
reg inf_in_reg1,inf_in_reg2,inf_in_reg3 ;
reg [31:0]data_reg ;
always @(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)begin
inf_in_reg1<= 1'b1 ;
inf_in_reg2<= 1'b1 ;
inf_in_reg3<= 1'b1 ;
end
else begin
inf_in_reg1<= inf_in ;
inf_in_reg2<= inf_in_reg1 ;
inf_in_reg3<= inf_in_reg2 ;
end
assign flag_fall=(~inf_in_reg2)&&(inf_in_reg3);
assign flag_rise=(~inf_in_reg3)&&(inf_in_reg2);
always @(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
state<= IDLE ;
else
case(state)
IDLE:
if(flag_fall==1'b1)
state<= TIME_9MS ;
else
state<= IDLE ;
TIME_9MS:
if (flag_9ms==1'b1 && flag_rise==1'b1)
state<= ARBIT ;
else if(flag_rise==1'b1 )
state<= IDLE ;
else
state<= state ;
ARBIT:
if(flag_fall==1'b1 && flag_4_5ms==1'b1)
state<= DATA ;
else if(flag_fall==1'b1 && flag_2_25ms==1'b1)
state<= REPEAT;
else if(flag_fall==1'b1)
state<= IDLE ;
else
state<= state ;
DATA:
if(cnt_data==6'd32 && flag_rise==1'b1)
state<= IDLE ;
else if((flag_fall==1'b1 && ((flag_560us==1'b1)||
(flag_1_69ms)))||(flag_rise==1'b1 && flag_560us))
state<= DATA ;
else if(flag_fall==1'b1 || flag_rise==1'b1)
state<= IDLE ;
else
state<=state ;
REPEAT:
if(flag_rise==1'b1)
state<=IDLE ;
else
state<=state ;
default:state<=IDLE ;
endcase
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
cnt<=19'd0 ;
else if (state==IDLE || flag_fall==1'b1 || flag_rise==1'b1)
cnt<=19'd0 ;
else
cnt<=cnt+1'b1 ;
//9
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
flag_9ms<=1'b0 ;
else if(state==TIME_9MS && cnt>=CNT_9A && cnt<CNT_9B)
flag_9ms<=1'b1 ;
else
flag_9ms<=1'b0 ;
//4.5
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
flag_4_5ms<=1'b0 ;
else if(state==ARBIT && cnt>=CNT_45A && cnt<CNT_45B)
flag_4_5ms<=1'b1 ;
else
flag_4_5ms<=1'b0 ;
//2.25
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
flag_2_25ms<=1'b0 ;
else if(state==ARBIT && cnt>=CNT_225A && cnt<CNT_225B)
flag_2_25ms<=1'b1 ;
else
flag_2_25ms<=1'b0 ;
//560
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
flag_560us<=1'b0 ;
else if(state==DATA && cnt>=CNT_560A && cnt<CNT_560B)
flag_560us<=1'b1 ;
else
flag_560us<=1'b0 ;
//169
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
flag_1_69ms<=1'b0 ;
else if(state==DATA && cnt>=CNT_169A && cnt<CNT_169B)
flag_1_69ms<=1'b1 ;
else
flag_1_69ms<=1'b0 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
cnt_data<=6'd0 ;
else if (state==DATA && flag_fall)
cnt_data<=cnt_data+1'b1 ;
else if (state==DATA )
cnt_data<=cnt_data ;
else
cnt_data<=6'd0 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
data_reg<=32'd0 ;
else if (flag_fall==1'b1 && state==DATA && cnt_data <=6'd31)
if (flag_1_69ms==1'b1)
data_reg[cnt_data]<=1'b1 ;
else if(flag_560us==1'b1)
data_reg[cnt_data]<=1'b0 ;
else
data_reg<=data_reg ;
else if(state==IDLE)
data_reg<=32'D0 ;
else
data_reg<=data_reg ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
data<=20'd0 ;
else if (data_reg[7:0]==~data_reg[15:8]
&& data_reg[31:24]==~data_reg[23:16]
&& cnt_data==6'd32)
data<={12'b0,data_reg[23:16]} ;
else
data<=20'd0 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
repeat_en<=1'b0 ;
else if(state==REPEAT && flag_rise==1'b1)
repeat_en<=1'b1 ;
else
repeat_en<=1'b0 ;
endmodule
seg :
module seg_595_dynamic(
input wire clk_sys ,
input wire rst_n_sys ,
input wire [19:0]data ,
input wire [5:0]point ,
input wire sign ,
input wire en_seg ,
output wire ds ,
output wire sh_cp ,
output wire st_cp ,
output wire oe
);
wire [7:0]seg ;
wire [5:0]sel ;
seg_dynamic seg_dynamic1(
.clk_sys (clk_sys),
.rst_n_sys (rst_n_sys),
.data (data),
.point (point) ,
.sign (sign) ,
.en_seg (en_seg),
.seg (seg),
.sel (sel)
);
hc595_ctrl hc595_ctrl1(
.clk_sys (clk_sys),
.rst_n_sys (rst_n_sys),
.seg (seg),
.sel (sel),
.ds (ds),
.sh_cp (sh_cp),
.st_cp (st_cp),
.oe (oe)
);
endmodule
module seg_dynamic(
input wire clk_sys ,
input wire rst_n_sys ,
input wire [19:0]data ,
input wire [5:0]point ,
input wire sign ,
input wire en_seg ,
output reg [7:0]seg ,
output reg [5:0]sel
);
wire [3:0] uint,ten,hun,tbo,h_hun,t_tbo;
reg [23:0] data_reg ;
reg [18:0] cnt_ms ;
wire flat_ms ;
reg [2:0] cnt_sel ;
reg [3:0] data_disp ;
reg dot_disp ;
reg [5:0] sel_reg ;
parameter fu_hao=4'd10 ;//符号
parameter empty =4'd11 ;//空
parameter CNT_MS_MAX=19'd49_999 ;
//parameter CNT_MS_MAX=19'd49 ;
parameter CNT_SEL_MAX=3'd5 ;
bcd_8421 bcd1(
.clk_sys (clk_sys ),
.rst_n_sys (rst_n_sys),
.data (data),
.uint (uint),
.ten (ten),
.hun (hun),
.tbo (tbo),
.t_tbo (t_tbo),
.h_hun (h_hun)
);
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
data_reg<=24'd0 ;
else if (h_hun || point[5])
data_reg<={h_hun,t_tbo,tbo,hun,ten,uint} ;
else if (t_tbo || point[4])
begin
if (sign==1'b1)
data_reg<={fu_hao, t_tbo, tbo, hun, ten, uint} ;
else
data_reg<={empty, t_tbo, tbo, hun, ten, uint} ;
end
else if (tbo || point[3])
begin
if (sign==1'b1)
data_reg<={empty, fu_hao,tbo, hun, ten, uint} ;
else
data_reg<={empty, empty, tbo, hun, ten, uint} ;
end
else if (hun || point[2])
begin
if (sign==1'b1)
data_reg<={empty, empty, fu_hao, hun, ten,uint} ;
else
data_reg<={empty, empty, empty , hun, ten,uint} ;
end
else if (ten || point[1])
begin
if (sign==1'b1)
data_reg<={empty, empty, empty, fu_hao, ten,uint} ;
else
data_reg<={empty, empty, empty , empty, ten,uint} ;
end
else if (uint)
begin
if (sign==1'b1)
data_reg<={empty, empty, empty, empty, fu_hao, uint} ;
else
data_reg<={empty, empty, empty , empty, empty, uint} ;
end
else
data_reg<= data_reg ;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
cnt_ms<=19'd0 ;
else if(cnt_ms==CNT_MS_MAX)
cnt_ms<=19'd0 ;
else
cnt_ms<=cnt_ms+1'b1 ;
assign flat_ms=(cnt_ms==CNT_MS_MAX)?1'b1:1'b0 ;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
cnt_sel<=3'd0 ;
else if (flat_ms==1'b1 && cnt_sel==CNT_SEL_MAX)
cnt_sel<=3'd0 ;
else if (flat_ms==1'b1)
cnt_sel<=cnt_sel+1'b1 ;
else
cnt_sel<=cnt_sel ;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
sel_reg<=6'd000_000 ;
else if(flat_ms==1'b1 && cnt_sel==3'b0)
sel_reg<=6'd000_001 ;
else if(flat_ms==1'b1)
sel_reg<=sel_reg<<1 ;
else
sel_reg<=sel_reg ;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
data_disp <=empty ;
else if (flat_ms==1'b1 && en_seg)
case(cnt_sel)
3'd0:data_disp<=data_reg[3:0] ;
3'd1:data_disp<=data_reg[7:4] ;
3'd2:data_disp<=data_reg[11:8] ;
3'd3:data_disp<=data_reg[15:12] ;
3'd4:data_disp<=data_reg[19:16] ;
3'd5:data_disp<=data_reg[23:20] ;
default:data_disp<=empty ;
endcase
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
dot_disp<=1'b1 ;
else if(flat_ms)
dot_disp<=~point[cnt_sel] ;
else
dot_disp<=dot_disp ;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
sel<=6'b0 ;
else
sel<=sel_reg;
always@(posedge clk_sys or negedge rst_n_sys)
if (~rst_n_sys)
seg<=8'd0 ;
else
case(data_disp)
4'd0: seg <= {dot_disp,7'b100_0000} ;
4'd1: seg <= {dot_disp,7'b111_1001} ;
4'd2: seg <= {dot_disp,7'b010_0100} ;
4'd3: seg <= {dot_disp,7'b011_0000} ;
4'd4: seg <= {dot_disp,7'b001_1001} ;
4'd5: seg <= {dot_disp,7'b001_0010} ;
4'd6: seg <= {dot_disp,7'b000_0010} ;
4'd7: seg <= {dot_disp,7'b111_1000} ;
4'd8: seg <= {dot_disp,7'b000_0000} ;
4'd9: seg <= {dot_disp,7'b001_0000} ;
4'd10: seg <= 8'b1011_1111 ;
4'd11: seg <= 8'b111_111 ;
default: seg <= 8'b1100_0000 ;
endcase
endmodule
module hc595_ctrl(
input wire clk_sys ,
input wire rst_n_sys ,
input wire [7:0]seg ,
input wire [5:0]sel ,
output reg ds ,
output reg sh_cp ,
output reg st_cp ,
output wire oe
);
wire [13:0]data ;
reg [1:0]cnt ;
reg [3:0]cnt_bit;
parameter CNT_MAX=2'D3 ;
parameter CNT_BIT_MAX=4'D13 ;
assign data={seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5:0]} ;
always@(posedge clk_sys or negedge rst_n_sys)
if(!rst_n_sys)
cnt<=2'd0 ;
else if (cnt==CNT_MAX)
cnt<=2'd0 ;
else
cnt<=cnt+1'b1 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(!rst_n_sys)
cnt_bit<=4'd0 ;
else if(cnt_bit==CNT_BIT_MAX && cnt==CNT_MAX)
cnt_bit<=4'd0 ;
else if(cnt==CNT_MAX)
cnt_bit<=cnt_bit+1'b1 ;
else
cnt_bit<=cnt_bit ;
always@(posedge clk_sys or negedge rst_n_sys)
if(!rst_n_sys)
ds<=1'b0 ;
else if (cnt==2'b0)
ds<=data[cnt_bit] ;
else
ds<=ds ;
always@(posedge clk_sys or negedge rst_n_sys)
if(!rst_n_sys)
sh_cp<=1'd0 ;
else if(cnt==2'd2)
sh_cp<=1'b1 ;
else if(cnt==2'd0)
sh_cp<=1'b0 ;
else
sh_cp<=sh_cp;
always@(posedge clk_sys or negedge rst_n_sys)
if(!rst_n_sys)
st_cp<=1'd0 ;
else if(cnt_bit==4'd0)
begin
if (cnt==2'd0)
st_cp<=1'b1 ;
else if(cnt==2'd2)
st_cp<=1'b0 ;
end
else
st_cp<=st_cp;
assign oe=1'b0 ;
endmodule
module bcd_8421(
input wire clk_sys ,
input wire rst_n_sys ,
input wire [19:0]data ,
output reg [3:0]uint ,
output reg [3:0]ten ,
output reg [3:0]hun ,
output reg [3:0]tbo ,
output reg [3:0]t_tbo ,
output reg [3:0]h_hun
);
reg shift_flat ;
reg [4:0]cnt_shift ;
reg [43:0]data_shift ;
parameter CNT_SHIFT_MAX =5'D21 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
shift_flat <=1'b0 ;
else
shift_flat <=~shift_flat ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
cnt_shift <=5'b0 ;
else if(shift_flat==1'b1 && cnt_shift==CNT_SHIFT_MAX)
cnt_shift <=5'd0 ;
else if(shift_flat==1'b1)
cnt_shift <=cnt_shift+1'b1 ;
else
cnt_shift <=cnt_shift ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
data_shift<=44'd0 ;
else if(cnt_shift==5'd0)
data_shift<={24'd0,data[19:0]} ;
else if(cnt_shift>0)
begin
if (shift_flat==1'b1 && cnt_shift<=5'd20)
data_shift<=data_shift<<1 ;
else if (shift_flat==1'b0 && cnt_shift<=5'd20)
begin
data_shift[23:20]<=(data_shift[23:20]>4'd4)?4'd3+data_shift[23:20]:data_shift[23:20];
data_shift[27:24]<=(data_shift[27:24]>4'd4)?4'd3+data_shift[27:24]:data_shift[27:24];
data_shift[31:28]<=(data_shift[31:28]>4'd4)?4'd3+data_shift[31:28]:data_shift[31:28];
data_shift[35:32]<=(data_shift[35:32]>4'd4)?4'd3+data_shift[35:32]:data_shift[35:32];
data_shift[39:36]<=(data_shift[39:36]>4'd4)?4'd3+data_shift[39:36]:data_shift[39:36];
data_shift[43:40]<=(data_shift[43:40]>4'd4)?4'd3+data_shift[43:40]:data_shift[43:40];
end
else
data_shift<=data_shift ;
end
else
data_shift<=data_shift ;
always@(posedge clk_sys or negedge rst_n_sys)
if(~rst_n_sys)
begin
uint<=4'd0 ;
ten<=4'd0 ;
hun<=4'd0 ;
tbo<=4'd0 ;
h_hun<=4'd0 ;
t_tbo<=4'd0 ;
end
else if (shift_flat==1'b0 && cnt_shift==5'd21)
begin
uint <= data_shift[23:20] ;
ten <= data_shift[27:24] ;
hun <= data_shift[31:28] ;
tbo <= data_shift[35:32] ;
h_hun <= data_shift[39:36] ;
t_tbo <= data_shift[43:40] ;
end
else
begin
uint <=uint ;
ten <=ten ;
hun <=hun ;
tbo <=tbo ;
h_hun <=h_hun ;
t_tbo <=t_tbo ;
end
//过于复杂
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// uint<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// uint<=data_shift[23:20] ;
// else
// uint<=uint ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// ten<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// ten<=data_shift[27:24] ;
// else
// ten<=ten ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// hun<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// hun<=data_shift[31:28] ;
// else
// hun<=hun ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// tbo<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// tbo<=data_shift[35:32] ;
// else
// tbo<=tbo ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// h_hun<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// h_hun<=data_shift[39:36] ;
// else
// h_hun<=h_hun ;
//
//always@(posedge clk_sys or negedge rst_n_sys)
// if(~rst_n_sys)
// t_tbo<=4'd0 ;
// else if (shift_flat==1'b0 && cnt_shift==5'd21)
// t_tbo<=data_shift[43:40] ;
// else
// t_tbo<=t_tbo ;
endmodule
led:
module led_ctrl(
input wire clk_sys ,
input wire rst_n_sys ,
input wire repeat_en ,
output reg led
);
parameter CNT_MAX = 2500_000;
wire repeat_en_rise ;
reg repeat_en_d1 ;
reg repeat_en_d2 ;
reg cnt_en ;
reg [21:0] cnt ;
assign repeat_en_rise = repeat_en_d1 & ~repeat_en_d2;
always@(posedge clk_sys or negedge rst_n_sys)
if(rst_n_sys == 1'b0)begin
repeat_en_d1 <= 1'b0 ;
repeat_en_d2 <= 1'b0 ;
end
else begin
repeat_en_d1 <= repeat_en ;
repeat_en_d2 <= repeat_en_d1 ;
end
always@(posedge clk_sys or negedge rst_n_sys)
if(rst_n_sys == 1'b0)
cnt_en <= 1'b0 ;
else if(cnt == CNT_MAX - 1)
cnt_en <= 1'b0 ;
else if(repeat_en_rise == 1'b1)
cnt_en <= 1'b1 ;
always@(posedge clk_sys or negedge rst_n_sys)
if(rst_n_sys == 1'b0)
cnt <= 22'b0;
else if(cnt_en == 1'b1)
cnt <= cnt + 1;
else
cnt <= 22'b0;
always@(posedge clk_sys or negedge rst_n_sys)
if(rst_n_sys == 1'b0)
led <= 1'b1;
else if(cnt > 0)
led <= 1'b0;
else
led <= 1'b1;
endmodule
总共七段代码