module top (
input wire sys_clk ,
input wire sys_rst_n ,
input wire inf_in ,
output wire led ,
output wire ds ,
output wire oe ,
output wire shcp ,
output wire stcp
);
// 例化连线
wire [7:0] data ;
wire sign ;
wire [19:00] data_w ;
assign data_w = {12'd0,data} ;
wire [05:00] point_w ;
assign point_w = 6'b000000 ;
wire sign_w ;
assign sign_w = 1'b0 ;
wire seg_en_w ;
assign seg_en_w = 1'b1 ;
inf_rcv inf_rcv_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.inf_in ( inf_in ) ,
.data ( data ) ,
.sign ( sign )
);
led led_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.key_in ( sign ) ,
.led_out ( led )
);
seg_595_dynamic seg_595_dynamic_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.data ( data_w ) ,
.point ( point_w ) ,
.sign ( sign_w ) ,
.seg_en ( seg_en_w ) ,
.ds ( ds ) ,
.oe ( oe ) ,
.shcp ( shcp ) ,
.stcp ( stcp )
);
endmodule
module inf_rcv (
input wire sys_clk ,
input wire sys_rst_n ,
input wire inf_in ,
output reg [7:0] data ,
output reg sign
);
// parameter degine
parameter T_9MS = 19'd450_000 ,
T_4_5MS = 18'd225_000 ,
T_2_225MS= 17'd112_500 ,
T_560US = 15'd28_000 ,
T_1_69MS = 17'd84_500 ;
// parameter degine
localparam IDLE = 5'b0_0001 ,
TIME_9MS = 5'b0_0010 ,
ARBITE = 5'b0_0100 ,
DATA = 5'b0_1000 ,
REPEAT = 5'b1_0000 ;
// wire signal define
wire nege ;
wire pose ;
// reg signal define
reg inf_in_reg0 ;
reg inf_in_reg1 ;
reg inf_in_reg2 ;
reg [ 4:0] state ;
reg [19:0] cnt ; // 虽然最大计数9ms只需19位宽,但还是定义20位宽。
reg flag_9ms ; // 由于设备制造精度与环境因素影响,这个标志信号在指定目标附近拉高即可。
reg flag_4_5ms ;
reg flag_2_25ms ;
reg flag_560us ;
reg flag_1_69ms ;
reg [ 5:0] cnt_bit ; // 32 bit 数据
reg [31:0] data_reg ;
// // reg signal define
// reg inf_in_reg0 ;
// reg inf_in_reg1 ;
// reg inf_in_reg2 ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
inf_in_reg0 <= 1'b1 ;
inf_in_reg1 <= 1'b1 ;
inf_in_reg2 <= 1'b1 ;
end else begin
inf_in_reg0 <= inf_in ;
inf_in_reg1 <= inf_in_reg0 ;
inf_in_reg2 <= inf_in_reg1 ;
end
end
// // wire signal define
// wire nege ;
// wire pose ;
assign nege = ~inf_in_reg1 && inf_in_reg2 ;
assign pose = inf_in_reg1 && ~inf_in_reg2 ;
// reg [ 4:0] state ;
always @(posedge sys_clk or negedge sys_rst_n)
if(~sys_rst_n)
state <= IDLE ;
else case (state)
IDLE :if (nege == 1'b1)
state <= TIME_9MS ;
else
state <= IDLE ;
TIME_9MS:if(pose == 1'b1 && flag_9ms == 1'b1) //T_9MS - 19'd100
state <= ARBITE ;
else if(pose == 1'b1 && flag_9ms == 1'b0)
state <= IDLE ;
else
state <= TIME_9MS ;
ARBITE :if(nege == 1'b1 && flag_4_5ms == 1'b1) // 说明是引导码
state <= DATA ;
else if(nege == 1'b1 && flag_2_25ms == 1'b1) // 说明是重复码
state <= REPEAT ;
else if(nege == 1'b1 && flag_4_5ms == 1'b0 && flag_2_25ms == 1'b0)
state <= IDLE ;
else
state <= ARBITE ;
DATA :if((pose == 1'b1 && flag_560us == 1'b1 && cnt_bit == 6'd32)
|| (pose == 1'b1 && flag_560us == 1'b0)
|| (nege == 1'b1 && ( flag_560us == 1'b0 && flag_1_69ms == 1'b0)))
state <= IDLE ;
else
state <= DATA ;
REPEAT :if(pose == 1'b1 )
state <= IDLE ;
else
state <= REPEAT ;
default : state <= IDLE ;
endcase
// reg [19:0] cnt ; // 虽然最大计数9ms只需19位宽,但还是定义20位宽。
// reg flag_9ms ; // 由于设备制造精度与环境因素影响,这个标志信号在指定目标附近拉高即可。
// reg flag_4_5ms ;
// reg flag_2_25ms ;
// reg flag_560us ;
// reg flag_1_69ms ;
// reg [ 5:0] cnt_bit ; // 32 bit 数据
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt <= 20'd0 ;
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end else begin
case (state)
IDLE :begin
cnt <= 20'd0 ;
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end
TIME_9MS:begin
if(pose == 1'b1) begin
cnt <= 20'd0 ;
end else begin
cnt <= cnt + 1'b1 ;
end
if(cnt >= T_9MS - 19'd8000 && cnt <= T_9MS + 19'd8000) // 9ms附近拉高。不能太“离谱”。
flag_9ms <= 1'b1 ;
else
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end
ARBITE :begin
if(nege == 1'b1)
cnt <= 20'd0 ;
else
cnt <= cnt + 1'b1 ;
if(cnt >= T_4_5MS - 18'd8000 && cnt <= T_4_5MS + 18'd8000)
flag_4_5ms <= 1'b1 ;
else
flag_4_5ms <= 1'b0 ;
if(cnt >= T_2_225MS - 17'd8000 && cnt <= T_2_225MS + 17'd8000)
flag_2_25ms <= 1'b1 ;
else
flag_2_25ms <= 1'b0 ;
flag_9ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end
DATA :begin
if(nege == 1'b1 || pose == 1'b1)
cnt <= 20'd0 ;
else
cnt <= cnt + 1'b1 ;
if(cnt >= T_560US - 15'd8000 && cnt <= T_560US + 15'd8000)
flag_560us <= 1'b1 ;
else
flag_560us <= 1'b0 ;
if(cnt >= T_1_69MS - 15'd8000 && cnt <= T_1_69MS + 15'd8000)
flag_1_69ms <= 1'b1 ;
else
flag_1_69ms <= 1'b0 ;
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
if(pose == 1'b1 && flag_560us == 1'b1 && cnt_bit == 6'd32)
cnt_bit <= 'd0 ;
else if(nege == 1'b1)
cnt_bit <= cnt_bit + 1'b1 ;
else
cnt_bit <= cnt_bit ;
end
REPEAT :begin
cnt <= 20'd0 ;
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end
default:begin
cnt <= 20'd0 ;
flag_9ms <= 1'b0 ;
flag_4_5ms <= 1'b0 ;
flag_2_25ms <= 1'b0 ;
flag_560us <= 1'b0 ;
flag_1_69ms <= 1'b0 ;
cnt_bit <= 6'd0 ;
end
endcase
end
end
// reg [31:0] data_reg ;
always @(posedge sys_clk or negedge sys_rst_n)
if(~sys_rst_n)
data_reg <= 31'd0 ;
else if(state == DATA && nege == 1'b1 && cnt_bit <= 6'd31 && flag_1_69ms == 1'b1)
data_reg[cnt_bit] <= 1'b1 ;
else if(state == DATA && nege == 1'b1 && cnt_bit <= 6'd31 && flag_560us == 1'b1)
data_reg[cnt_bit] <= 1'b0 ;
else
data_reg <= data_reg ;
// output signal
// reg [7:0] data ,
always @(posedge sys_clk or negedge sys_rst_n)
if(~sys_rst_n)
data <= 8'd0 ;
else if((data_reg[23:16] == ~data_reg[31:24]) && (data_reg[7:0] == ~data_reg[15:8]))
data <= data_reg[23:16] ;
else
data <= data ;
// reg sign
always @(posedge sys_clk or negedge sys_rst_n)
if(~sys_rst_n)
sign <= 1'b0 ;
else if(state == REPEAT)
sign <= 1'b1 ;
else
sign <= 1'b0 ;
endmodule
module led(
input sys_clk ,
input sys_rst_n ,
input key_in ,
output wire led_out
);
reg key_in_reg1 ;
reg key_in_reg2 ;
wire pose ;
reg [24:0] cnt_500ms ; // 24_999_999
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
key_in_reg1 <= 1'b0 ;
key_in_reg2 <= 1'b0 ;
end else begin
key_in_reg1 <= key_in ;
key_in_reg2 <= key_in_reg1 ;
end
end
assign pose = ~key_in_reg2 && key_in_reg1 ;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(~sys_rst_n) begin
cnt_500ms <= 25'd0 ;
end else begin
if(cnt_500ms == 25'd0 && pose == 1'b1) begin
cnt_500ms <= 25'd24_999_999 ;
end else begin
if(cnt_500ms == 25'd0) begin
cnt_500ms <= cnt_500ms ;
end else begin
cnt_500ms <= cnt_500ms - 1'b1 ;
end
end
end
end
assign led_out = (cnt_500ms == 0) ? 1'b1 : 1'b0 ; // 低电平亮。
endmodule
`timescale 1ns/1ns
module test_inf_rcv();
reg sys_clk ;
reg sys_rst_n ;
reg inf_in ;
wire [7:0] data ;
wire sign ;
// Instantiation
inf_rcv inf_rcv_insert(
.sys_clk ( sys_clk ) ,
.sys_rst_n ( sys_rst_n ) ,
.inf_in ( inf_in ) ,
.data ( data ) ,
.sign ( sign )
);
parameter CYCLE = 20 ;
initial begin
sys_clk = 1'b1 ;
sys_rst_n <= 1'b0 ;
inf_in <= 1'b1 ;
#( CYCLE * 10 ) ;
sys_rst_n <= 1'b1 ;
#( CYCLE * 500 ) ;
// 引导码
inf_in <= 1'b0 ;
#(9_000_000) ;
inf_in <= 1'b1 ;
#(4_500_000) ;
// 地址码 8'h57 0101_0111 1110_1010
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
// 地址反码 8'hA8 1010_1000 0001_0101
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
// 数据码 8'h22 0010_0010 0100_0100
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
// 数据反码 8'hDD 1101_1101 1011_1011
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 0
#(560_000) ;
inf_in <= 1'b1 ;
#(560_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
inf_in <= 1'b0 ; // 1
#(560_000) ;
inf_in <= 1'b1 ;
#(1690_000) ;
// 结束码
inf_in <= 1'b0 ;
#(560_000) ;
inf_in <= 1'b1 ;
#(1_000_000) ;
// 重复码
inf_in <= 1'b0 ;
#(9_000_000) ;
inf_in <= 1'b1 ;
#(2_250_000) ;
// 结束码
inf_in <= 1'b0 ;
#(560_000) ;
inf_in <= 1'b1 ;
#(1_000_000) ;
$stop ;
end
always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
endmodule
其他模块是之前的。
已上板验证成功。