📄 i2c_master.v
字号:
// ********************************************************************* //
// Filename: i2c_master.v //
// Projects: STiMi-Receiver //
// Author : XQ-Wang //
// Date : 2007-06-25 //
// Version : 1.0 //
// ********************************************************************* //
`timescale 1ns/1ps
module i2c_master(SYS_CLK, RST, RD, WR, DATA, DTyp, DNum, SCL, SDA, ACK);
input SYS_CLK ;
wire SYS_CLK ;
input RST ;
wire RST ;
input RD ;
wire RD ;
input WR ;
wire WR ;
inout [7:0] DATA ;
wire [7:0] DATA ;
input [2:0] DTyp ;
wire [2:0] DTyp;
input [7:0] DNum ;
wire [7:0] DNum ;
output SCL ;
wire SCL ;
inout SDA ;
wire SDA ;
output ACK ;
wire ACK ;
//output SDA_SEL ;
wire SDA_SEL ;
//------------------------------------------------
reg [7:0] chip_id_slave;
reg [7:0] addr_slave;
reg [7:0] data_to_slave;
wire [7:0] data_from_slave;
wire SDA_in;
wire SDA_out;
reg [7:0] dnum_cnt;
reg [2:0] dtype;
reg [9:0] data_cnt;
reg [7:0] clk_cnt;
//----------- Generate SCL ---------------------
parameter CLK_PERIOD = 8'b10010110; //60M/400K=150
always @(negedge SYS_CLK)
begin
if(RST)
clk_cnt <= 8'b0;
else
begin
if(clk_cnt==CLK_PERIOD)
clk_cnt <= 8'b00000001;
else
clk_cnt <= clk_cnt + 1;
end
end
i2c_core INST_I2C(
.SYS_CLK(SYS_CLK) ,
.RST(RST) ,
.RD(RD) ,
.WR(WR) ,
.Chip_id(chip_id_slave),
.Addr(addr_slave) ,
.DATA_in(data_to_slave),
.DTyp(DTyp) ,
.DNum(DNum) ,
.DATA_out(data_from_slave),
.SCL(SCL) ,
.SDA_in(SDA_in) ,
.SDA_out(SDA_out) ,
.SDA_sel(SDA_SEL) ,
.ACK(ACK)
);
//---------------- Data Output -----------------
assign SDA = SDA_SEL ? 1'bz : SDA_out;
assign SDA_in = SDA_SEL ? SDA : 1'b1 ;
//assign DATA = (link_read) ? data_from_slave : 8'hzz;
//----------- Data Buf --------------------------
always @(posedge SYS_CLK, posedge RST)
begin
if(RST)
begin
dtype <= 3'b0;
dnum_cnt <= 8'b0;
end
else if(WR || RD)
begin
dtype <= DTyp;
dnum_cnt <= DNum;
end
else if(!WR && !RD)
begin
chip_id_slave <= 8'b0;
addr_slave <= 8'b0;
data_to_slave <= 8'b0;
data_cnt <= 10'b0;
dtype <= 3'b0;
dnum_cnt <= 8'b0;
end
end
always @(posedge SYS_CLK, posedge RST)
begin
if(RST)
begin
chip_id_slave <= 8'b0;
addr_slave <= 8'b0;
data_to_slave <= 8'b0;
data_cnt <= 10'b0;
end
else if(clk_cnt==(CLK_PERIOD>>1))
begin
if(WR)
begin
case(dtype)
4'b001: begin
if(data_cnt==0)
begin
chip_id_slave <= DATA;
data_cnt <= data_cnt + 1;
end
else if(!ACK)
begin
if(data_cnt[0] && data_cnt<(dnum_cnt<<1+1))
begin
addr_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(!data_cnt[0] && data_cnt<(dnum_cnt<<1+1))
begin
data_to_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt==(dnum_cnt<<1+1))
data_cnt <= 10'b0;
end
end
4'b010: begin
if(data_cnt==0)
begin
addr_slave <= DATA;
data_cnt <= data_cnt + 1;
end
if(!ACK)
begin
if(!data_cnt[0] && data_cnt<(dnum_cnt<<1))
begin
addr_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt[0] && data_cnt<(dnum_cnt<<1))
begin
data_to_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt==(dnum_cnt<<1))
data_cnt <= 10'b0;
end
end
4'b101: begin
if(data_cnt==0)
begin
chip_id_slave <= DATA;
data_cnt <= data_cnt + 1;
end
else if(!ACK)
begin
if(data_cnt==1)
begin
addr_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt<(dnum_cnt+2))
begin
data_to_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt==(dnum_cnt+2))
data_cnt <= 10'b0;
end
end
4'b110: begin
if(data_cnt==0)
begin
addr_slave <= DATA;
data_cnt <= data_cnt + 1;
end
else if(!ACK)
begin
if(data_cnt<(dnum_cnt+2))
begin
data_to_slave <= DATA;
data_cnt <= data_cnt +1;
end
else if(data_cnt==(dnum_cnt+2))
data_cnt <= 10'b0;
end
end
endcase
end
end
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -