I2C Verilog 의 실현 (1)
`timescale 1ns / 1ps
module test(
sda
);
reg scl;
inout sda;
reg sda_out;
wire sda_in;
reg [7:0] data;
reg start_flag, stop_flag;
assign sda = sda_out ? 1'bz : 1'b0;
assign sda_in = sda;
pullup( sda );
I2CTEST testmine(.SDA(sda), .SCL(scl));
initial
begin
scl = 0;
sda_out = 0;
data = 8'h27;
start_flag = 0;
#160000;
start ( );
end
always
begin
#50000 scl = ~scl;
end
always @ (posedge start_flag)
begin
repeat (8)
begin
wait ( scl == 0 );
#20000;
sda_out = data[7];
#40000;
data = data << 1;
end
wait (~ scl);
#20000;
sda_out = 1;
#160000;
stop ( );
end
always @ ( posedge stop_flag)
begin
// sda_out = 0;
// #50000;
sda_out = 1;
end
task start;
begin
wait (scl == 0);
#20000;
sda_out = 1;
wait ( scl == 1 );
#20000;
sda_out = 0;
start_flag = 1;
end
endtask
task stop;
begin
wait ( scl == 0 );
#20000;
sda_out = 0;
wait ( scl ==1 );
#20000;
sda_out = 1;
stop_flag = 1;
end
endtask
endmodule
I2C 프로그램
`timescale 1ns / 1ps
module I2CTEST(
SDA, SCL
);
input SCL;
inout SDA;
// The 7-bits address that we want for our I2C slave
parameter I2C_ADR = 7'h13;
//---------------------------------------------
//start,stop condition judgement
//---------------------------------------------
wire start, stop;
reg sda1, sda2;
reg sda11;
always @ ( posedge SCL )
sda1 <= SDA;
always @ ( negedge SCL )
sda2 <= SDA;
always @ ( negedge SCL )
sda11 <= sda1;
assign start = sda11 & (!sda2);
assign stop = sda2 & ( !sda11 );
//----------------------------------------------
//count setting
//----------------------------------------------
reg [3:0] bitcont;
wire bit_ack = bitcont[3];
always @ ( posedge SCL or posedge start)
begin
if ( start )
bitcont <= 4'h6;
else
begin
if (bit_ack)
bitcont <= 4'h6;
else
bitcont <= bitcont -4'h1;
end
end
//-------------------------------------
//get sda using posedge scl
//-------------------------------------
reg sdar;
always @ ( posedge SCL ) sdar <= SDA;
//----------------------------------------
//address match
//----------------------------------------
reg addr_match, op_read;
always @ ( negedge SCL or posedge start )
begin
if ( start )
begin
addr_match <= 1'h1;
op_read <= 1'h0;
end
else
begin
if( (bitcont == 6) & (sdar != I2C_ADR[6])) addr_match <= 1'h0;
if( (bitcont == 5) & (sdar != I2C_ADR[5])) addr_match <= 1'h0;
if( (bitcont == 4) & (sdar != I2C_ADR[4])) addr_match <= 1'h0;
if( (bitcont == 3) & (sdar != I2C_ADR[3])) addr_match <= 1'h0;
if( (bitcont == 2) & (sdar != I2C_ADR[2])) addr_match <= 1'h0;
if( (bitcont == 1) & (sdar != I2C_ADR[1])) addr_match <= 1'h0;
if( (bitcont == 0) & (sdar != I2C_ADR[0])) addr_match <= 1'h0;
if( bitcont == 0 ) op_read <= sdar;
end
end
//-----------------------------------------------------------------------
//send ack
//-----------------------------------------------------------------------
reg ack_assert;
always @ ( negedge SCL )
begin
if ( bit_ack & addr_match & op_read )
ack_assert <= 1'h1;
else
ack_assert <= 1'h0;
end
//-------------------------------------------------------------------------
//control SDA line
//-------------------------------------------------------------------------
assign SDA = ack_assert ? 1'h0 : 1'hz;
pullup ( SDA );
endmodule
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.