所用:vivado 2018.3
一、原理图
二、调试ADV7391的I2C口,上Block design
三、上干货
module I2C_7391
(
input wire en_clk, //27MHz
// input reset_ok,
input wire rst_n,
output wire mreset,
output wire SCL,
inout wire SDA,
output wire [2:0] cnt_o,
output wire sda_r_out,
output wire [7:0] d_r_out,
output wire [23:0] data_out,
output wire led2
);
reg mreset_r;
reg reset1=0;
reg [31:0] Mdelay;
//assign mreset = mreset_r;
always @ (posedge en_clk or negedge rst_n) begin
//always @ (*) begin //27000/400=67.5 300/4=75 300/1 = 300
if ((rst_n==0)) begin
Mdelay <= 0;
mreset_r <= 1'b0;
reset1 <= 1'b0;
end else begin
if (Mdelay <= (32'd27_000_000*6)) begin // 延时 ?s
Mdelay <= Mdelay+1;
mreset_r <= 1'b0;
if (Mdelay == (32'd27_000_000*2)) reset1 <= 0;
else reset1 <= 1'b1;
end else begin
mreset_r <= 1'b1;
reset1 <= 1'b1;
end
end
end
//****************frequency******************
reg [8:0] cnt_delay;
reg [2:0]cnt;
//always @ (posedge CLK or negedge RST_N) begin
// if(!RST_N) begin
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0) begin
cnt_delay <= 9'd0;
end
//else if(cnt_delay>=9'd125) cnt_delay <=9'd0; //SCL = 400KHZ ; T=10us
else if(cnt_delay>=9'd240) cnt_delay <=9'd0; //270000/125=215 270000/240 `= 120 27000/300=90khz 27000/500 = 54khz
else cnt_delay <= cnt_delay +1'b1;
end
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0) cnt <=3'd0;
else begin
case (cnt_delay)
9'd60: cnt <= 3'd1; //SCL高电平中间采样点
9'd120: cnt <= 3'd2; //SCL下降沿
9'd180: cnt <= 3'd3; //SCL低电平中间采样点,用于数据的变化
9'd0: cnt <= 3'd0; //SCL上升沿
default : cnt <= 3'd5;
endcase
end
end
`define SCL_POS (cnt==3'd0)
`define SCL_HIG (cnt==3'd1)
`define SCL_NEG (cnt==3'd2)
`define SCL_LOW (cnt==3'd3)
reg scl_r; //定义SCL的时序脉冲,1为高电平,0为低电平
always @ (posedge en_clk/*CLK or negedge RST_N*/) begin
//if(!RST_N)
if (reset1==0)
scl_r <= 1'b0;
else if(cnt == 3'd2) scl_r<= 1'b0; //
else if(cnt == 3'd0) scl_r<= 1'b1; //
end
parameter IDLE = 4'd0,
Start = 4'd1,
Add1 = 4'd2,
Ack1 = 4'd3,
Add2 = 4'd4,
Ack2 = 4'd5,
Data = 4'd6,
Ack3 = 4'd7,
Ass = 4'd8,
End = 4'd9,
Ack4 = 4'd10;
reg [6:0]state; //状态寄存器
reg [7:0] db_r; //IIC上要传送的数据寄存器
reg sda_r; //输出数据寄存器
reg sda_link; //双向传输控制
reg [3:0]sda_num; //并转串数据发送计数器寄存器
//reg ack;
reg[23:0]data;
reg[1:0] state1;
reg[4:0] LUT_INDEX;
reg[15:0]LUT_DATA;
reg scl_bp_r = 0;
reg [7:0] num;
assign cnt_o = cnt;
assign SCL = scl_bp_r ? 1 : scl_r;
assign SDA = sda_link ? sda_r:1'bz;
parameter