📄 i2cslave.v
字号:
各位朋友,以下是我的一个模拟I2C从设备的 verilog代码,但是在maxplux下老是编译不通过,有兴趣的朋友,能否一起探讨一下。联系方式:pjultra@163.com
`timescale 1ns/1ns
`define timeslice 100
module i2c_slave(main_rst_,scl,sda,s_rst,fan_ctrl,fan_alter);
input [2:0] fan_ctrl,fan_alter;
output [7:0] s_rst;
input scl,main_rst_;
inout sda;
reg [7:0] s_rst;
reg out_flag; //SDA数据输出的控制信号
reg [7:0] memory_buf;
reg [7:0] ctrl_byte;
reg [7:0] addr_byte;
reg [7:0] sda_buf;
reg [7:0] shift;
reg [1:0] state;
parameter cpld_addr_r=8'b10011001,
cpld_addr_w=8'b10011000;
parameter reg1=8'b00000000,reg2=8'b11111111;
//-----------输出SDA-------
assign sda=(out_flag==1)?sda_buf[7]:1'bz;
//----------启动信号-----------
always@(negedge sda or negedge main_rst_) begin
if(!main_rst_) begin //--------------寄存器和存储器初始化--------------------
addr_byte<=0; ctrl_byte<=0; out_flag<=0;
sda_buf<=0; memory_buf<=0;
shift<=0; s_rst<=1; state<=2'b00;
end
else if(scl==1) begin
state=state&&2'b01;
if (state==2'b11)
disable write_to_cpld;
end
end
//------主机状态------------------
always@(posedge sda or negedge main_rst_)
begin
if(!main_rst_)begin //--------------寄存器和存储器初始化--------------------
addr_byte<=0; ctrl_byte<=0; out_flag<=0;
sda_buf<=0; memory_buf<=0;
shift<=0; s_rst<=1; state<=2'b00;
end
else if(scl==1) begin
state<=2'b00;
addr_byte<=0;
ctrl_byte<=0;
out_flag=0;
sda_buf=0;
end
else begin
casex(state)
2'b01:begin
read_in;
if(ctrl_byte==cpld_addr_w) begin
state=2'b10;
write_to_cpld; //写操作
end
else state=2'b00;
end
2'b11: read_from_cpld; //--读操作
default: state=2'b00;
endcase
end //主状机结束
end
//-------操作停止------------
//----读进控制字和存储器单元地址---------
task read_in;
begin
shift_in(ctrl_byte);
shift_in(addr_byte);
end
endtask
//------CPLD的写操作-------------------
task write_to_cpld;
begin
shift_in(memory_buf);
if(addr_byte==reg1)
s_rst=memory_buf;
else s_rst=8'b11111111;
state=2'b00; //回到0状态
end
endtask
//-------CPLD的读操作-----------
task read_from_cpld;
begin
shift_in(ctrl_byte);
if(ctrl_byte==cpld_addr_r)
begin
if(addr_byte==reg2);
sda_buf={fan_ctrl,fan_alter,2'b00};
shift_out;
state=2'b00;
end
end
endtask
//----SDA数据线上的数据存入寄存器,数据在SCL的高电平有?---------
task shift_in;
output[7:0] shift;
begin
@(posedge scl) shift[7]=sda;
@(posedge scl) shift[6]=sda;
@(posedge scl) shift[5]=sda;
@(posedge scl) shift[4]=sda;
@(posedge scl) shift[3]=sda;
@(posedge scl) shift[2]=sda;
@(posedge scl) shift[1]=sda;
@(posedge scl) shift[0]=sda;
@(negedge scl) begin
#`timeslice;
out_flag=1;
sda_buf=0;
end
@(negedge scl) #`timeslice out_flag=0;
end
endtask
//------CPLD存储器中的数据通过SDA数据线输出,数据在SCL低电平时变化
task shift_out;
begin
out_flag=1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf=sda_buf<<1;
@(negedge scl) #`timeslice sda_buf[7]=1;
@(negedge scl) #`timeslice out_flag=0;
end
endtask
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -