📄 i2ctop.v
字号:
next_state <= READ_REG2 ;
end
READ_REG2 : begin//read status
next_state <= READ_REG3 ;
end
READ_REG3 : begin//reset addr , return status/addr
if(cnt1==8)
next_state <= READ_REG4 ;
else
next_state <= READ_REG3 ;
end
READ_REG4 : begin//wait receive ack or nak
if(cnt1==0)
next_state <= READ_REG5 ;
else
next_state <= READ_REG4 ;
end
READ_REG5 : begin
next_state <= WAIT_STOP1 ;
end
*/
default : begin
next_state <= IDLE;
end
endcase
end
always @(posedge clk or negedge reset)
begin
if(!reset) begin
i2c_en <= 1 ;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
else begin
case(cur_state)
/* IDLE : begin//read 2nd Byte
i2c_en <=1;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0 ;
i2c_data_out <= 0 ;
end
START : begin//has received START signal , read 1st Byte
i2c_en <= 1 ;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
*/
IDLE : begin//read 2nd Byte
i2c_en <=1;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0 ;
i2c_data_out <= 0 ;
end
START : begin//has received START signal , read 1st Byte
i2c_en <= 1 ;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= i2c_data_in;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
COMP_ADDR_WR : begin //compare addr,send ack/nak
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
// data_out <= 0;
data_out <= data_out;
if(data_out== {4'b1011 , I2cAddr, 1'b0})
ack_out <= 0 ;//return ack
else
ack_out <= 1 ; //return nak
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
ADDRESS : begin//read 2nd Byte
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= i2c_data_in;
addr <= 0 ;
wr_reg <= 0 ;
i2c_data_out <= 0 ;
end
COMP_INS : begin
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
data_out <= data_out;
addr <= data_out[5:0];
wr_reg <= 0;
i2c_data_out <= 0 ;
end
//-----------------------------------------------------------------------------
//stop
/* WAIT_STOP1 : begin
data_out <= 0 ;
addr <= 0 ;
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
WAIT_STOP2 : begin
data_out <= 0 ;
addr <= 0 ;
i2c_en <=1;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
*/
//-----------------------------------------------------------------------------
//return ACK
SEND_ACK : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
addr <= addr ;
data_out <= data_out ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
//-----------------------------------------------------------------------------
//return NAK
SEND_NAK : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 1 ;
addr <= 0 ;
data_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
//--------------------------------------------------------------------------
//write reg
WRITE_REG1 : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
addr <= addr ;
data_out <= i2c_data_in ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
WRITE_REG2 : begin//Set wr_reg
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
addr <= addr ;
data_out <= data_out ;
wr_reg <= 1;
i2c_data_out <= 0 ;
end
WRITE_REG3 : begin//wait a clolk cycle
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
addr <= addr ;
data_out <= data_out ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
WRITE_REG4 : begin//wait a clolk cycle
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
addr <= addr+1 ;
data_out <= data_out ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
WRITE_REG5 : begin//reset wr_reg , and return ack
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
addr <= addr ;
data_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
//-------------------------------------------------------------------------------
//read device , wait re_start
/* WAIT_RESTART1 : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
addr <= addr ;
data_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
WAIT_RESTART2 : begin
i2c_en <=1;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
addr <= addr ;
data_out <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
RESTART : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
addr <= addr ;
data_out <= i2c_data_in ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
COMP_ADDR_RD : begin//compare addr ( read device ), and return ack or nak
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
if(data_out=={4'b1011 , I2cAddr, 1'b1})
ack_out <= 0 ;//return ack
else
ack_out <= 1 ; //return nak
data_out <= data_out;
addr <= addr ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
START_READ : begin
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
data_out <= 0;
addr <= addr ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
*/
//------------------------------------------------------------------------
//read status
/* READ_REG1 : begin//wait a clock cycle
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
data_out <= 0;
addr <= addr ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
READ_REG2 : begin//read status
i2c_en <=0;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
data_out <= 0;
addr <= addr ;
wr_reg <= 0;
i2c_data_out <= data_in ;
end
READ_REG3 : begin//reset addr , return status/addr
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 0 ;
reg_out <= 1;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= i2c_data_out ;
end
READ_REG4 : begin//wait receive ack or nak
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
READ_REG5 : begin
i2c_en <=1;
cnt_en <= 1 ;
reg_in <= 1 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
*/
default : begin
i2c_en <= 1 ;
cnt_en <= 0 ;
reg_in <= 0 ;
reg_out <= 0;
ack_out <= 0 ;
data_out <= 0;
addr <= 0 ;
wr_reg <= 0;
i2c_data_out <= 0 ;
end
endcase
end
end
endmodule
/************************************************************/
module m1(in,out,ctl);
input in ;
input ctl ;
output out ;
assign out=ctl?0:in ;
endmodule
/***********************************************************/
module movereg( clk , reset ,
in , out , cnt1 , i2c_clk,i2c_clk_posedge, i2c_clk_negedge ,
data_in , data_out , ack_in , ack_out , i2c_d_out_en ,
i2c_d_in , i2c_d_out,i2c_en_in , i2c_en_out );
input clk ;
input in , out ;
input [3:0] cnt1;
input i2c_clk_posedge , i2c_clk_negedge ;
input i2c_clk ;
input [7:0] data_in ;
input ack_in ;
input i2c_d_in ;
input i2c_en_in;
input reset ;
output [7:0] data_out ;
output ack_out ;
output i2c_d_out ;
output i2c_d_out_en ;
output i2c_en_out ;
reg [7:0] inbuf ;
reg i2c_d_out_en;
reg i2c_d_out_en1 ;
reg i2c_en_out ;
reg [3:0] delaycnt;
assign ack_out = inbuf[0];
assign i2c_d_out = inbuf[7];
assign data_out = inbuf;
always @(posedge clk or negedge reset)
begin
if(!reset)
delaycnt <= 0 ;
else if(i2c_d_out_en1==0)
delaycnt <= 0 ;
else if(delaycnt==10)
delaycnt <= delaycnt;
else
delaycnt <= delaycnt + 1;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
i2c_d_out_en <= 0;
else if(delaycnt!=10)
i2c_d_out_en <= 0;
else
i2c_d_out_en <= 1;
end
always @(posedge clk or negedge reset)
if(!reset)
inbuf <= 0 ;
else begin
if(in) begin
if(i2c_clk_posedge) begin
inbuf[7:1] <= inbuf[6:0] ;
inbuf[0] <= i2c_d_in ;
end
end
else if(out) begin
if(cnt1==0 && ~i2c_clk)
inbuf <= data_in ;
else if(i2c_clk_negedge) begin
if(cnt1==8)
inbuf[7] <= ack_in ;
else
inbuf[7:1] <= inbuf[6:0] ;
end
end
else begin
inbuf <= inbuf ;
end
end
always @(posedge clk or negedge reset)
if(!reset)
i2c_d_out_en1 <= 0 ;
else
if(~i2c_clk)
if(in)
i2c_d_out_en1 <= 0 ;
else if(out)
i2c_d_out_en1 <= 1 ;
else
i2c_d_out_en1 <= 0 ;
else
i2c_d_out_en1 <= i2c_d_out_en1 ;
always @(posedge clk or negedge reset)
if(!reset)
i2c_en_out <= 1 ;
else begin
if(~i2c_clk)
i2c_en_out <= i2c_en_in ;
else
i2c_en_out <= i2c_en_out ;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -