AXI IIC总线:SDA上无数据波形



我在VIVADO上使用AXI IIC BUS IP CORE。即使我将相应的数据写入寄存器,sda数据线上也没有变化。 这是IP核的寄存器。 AXI IIC 注册

编程顺序如下。 序

似乎我只需要完成第一步和第二步,我可以看到SDA上的波浪变化 这是一个top.v(这不是我的原创,参考来自使用Vivado IIC IP Flow的坏s_axi_bvalid,s_axi_wready和s_axi_awready信号(

module i2c_channel #(
parameter                               CHANNEL_OUTPUT_WIDTH    =   16
)(
input                                   clk,
input                                   reset,
//the address of the slave;
input   [6:0]                           slave_address,
//The width of the message expected from the slave at the specified address;
input   [127:0]                         slave_message_width,
inout                                   sda,
inout                                   scl,
output  [CHANNEL_OUTPUT_WIDTH - 1:0]    channel_output   
);
wire                                       iic2intc_irpt  ;
//AXI Global System Signals
wire s_axi_aclk;
assign        s_axi_aclk      =   clk;
reg                                       s_axi_aresetn     ;
//AXI Write Address Channel Signals
reg       [31:0]                          s_axi_awaddr    ;
reg                                       s_axi_awvalid   ;
wire                                       s_axi_awready;
//AXI Write Data Channel Signals
reg       [31:0]                          s_axi_wdata     ;
reg       [3:0]                           s_axi_wstrb     ;
reg                                       s_axi_wvalid    ;
wire                                       s_axi_wready;
//AXI Write Response Channel Signals
wire       [1:0]                           s_axi_bresp;
wire                                      s_axi_bvalid;
reg                                       s_axi_bready    ;
//AXI Read Address Channel Signals
reg       [31:0]                          s_axi_araddr       ;
reg                                       s_axi_arvalid  ;
wire                                       s_axi_arready;
//AXI Read Data Channel Signals
wire       [31:0]                          s_axi_rdata;
wire       [1:0]                           s_axi_rresp;
wire                                       s_axi_rvalid;
reg                                       s_axi_rready  ;
//IIC signals
reg                                    sda_i          ;
wire                                       sda_o;
wire                                     sda_t;
reg                                       scl_i           ;
wire                                       scl_o;
wire                                       scl_t;
reg                                       gpo           ;
reg                                       state_done;
//i2C state
`define  SET_TX_FIFO 4'b0000
`define  SET_RX_FIFO_PIRQ 4'b0001
`define SET_CR_MSMS_TX 4'b0010
`define  SET_CR_TXAK 4'b0011
reg[3:0]state;
initial begin
state<=4'b0000;
end

//tri-state open-collector buffers to convert the iic signals to bi-directional inouts.
assign sda = sda_t ? sda_o : sda_i;
assign sda = scl_t ? scl_o : scl_i;
axi_iic_1 iic (
.iic2intc_irpt(),
.s_axi_aclk(s_axi_aclk),
.s_axi_aresetn(s_axi_aresetn),
.s_axi_awaddr(s_axi_awaddr[8:0]),
.s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
.s_axi_wdata(s_axi_wdata),
.s_axi_wstrb(s_axi_wstrb),
.s_axi_wvalid(s_axi_wvalid),
.s_axi_wready(s_axi_wready),
.s_axi_bresp(s_axi_bresp),
.s_axi_bready(s_axi_bready),
.s_axi_bvalid(s_axi_bvalid),
.s_axi_araddr(s_axi_araddr),
.s_axi_arvalid(s_axi_arvalid),
.s_axi_arready(s_axi_arready),
.s_axi_rdata(s_axi_rdata),
.s_axi_rvalid(s_axi_rvalid),
.s_axi_rresp(s_axi_rresp),
.sda_i(sda_i),
.sda_o(sda_o),
.sda_t(sda_t),
.scl_i(scl_i),
.scl_o(scl_o),
.scl_t(scl_t) 
);

always @(clk)  begin
s_axi_aresetn   <=  ~reset;
end
//Sets an axi data write operation.
task set_a_axi_w ;
input [31:0] awaddr;
input [31:0] wdata;
begin
s_axi_awaddr   =  awaddr;
s_axi_wdata     =  wdata;
s_axi_awvalid   =  1'b1; 
s_axi_bready    =  1'b1;
s_axi_wvalid    =  1'b1;  
end 
endtask
//set the state of the operation. 
task set_state ;
input[3:0] new_state;
if(s_axi_awready) begin
state           =  new_state; 
end
endtask
//when the module is initialized, write the i2c address of the target slave to the TX_FIFO register.
//Write the IIC peripheral device addresses for the first slave device to the TX_FIFO.
always @(posedge clk)  begin
case (state)
`SET_TX_FIFO : begin
set_a_axi_w(32'h108, slave_address);
set_state(`SET_RX_FIFO_PIRQ);
end 
`SET_RX_FIFO_PIRQ : begin
set_a_axi_w(32'h120, slave_message_width - 2);
set_state(`SET_CR_MSMS_TX); 
end
`SET_CR_MSMS_TX : begin
set_a_axi_w(32'h100, 8'b00000101);
set_state(`SET_CR_TXAK);
end
endcase
if(s_axi_awready) begin
//s_axi_awaddr    <=  '0;
s_axi_awvalid   <=  1'b0;
end
if(s_axi_wready)  begin
//s_axi_wdata    <=  '0;
s_axi_wvalid   <=  1'b0;    
end
if (s_axi_bvalid)  begin
s_axi_bready   <=  1'b0;    
end/**
else begin
s_axi_bready <=1'b0;
end**/
end
endmodule

下面是模拟文件:

module i2c_channel_tb();
//Parameters
parameter CLK_PERIOD = 10;
reg           clk      =   1'b1;
reg          reset           =   1'b1;
reg   [6:0]   slave_address   =   6'b0;
wire           sda;
wire           scl;

i2c_channel i2c_channel_1 (
.clk(clk),
.reset(reset),
.slave_address(slave_address),
.slave_message_width(128'd16),
.sda(sda),
.scl(scl)
);
/*
i2c_channel_slave_model i2c_channel_slave_model_1 (
.sda(sda),
.scl(scl)
);**/
initial begin
clk                 <=  1'b0;
reset               <=  1'b0;
slave_address       <=  7'b100_1011;
end
//psuedo-clock
always #10 begin
clk <= ~clk;
end
endmodule

波形结果如下: 结果波形

如图所示,数据写入寄存器,但sda_o和scl_o没有变化。

谁能告诉我为什么? 谢谢!

一个明显的错误是,SDA和SCL应该在初始状态下启动。

波形显示sda_o、sda_i、scl_o和scl_i在任何给定时间都不会上拉。所以也许你需要检查一下。(要么是要检查的硬件原理图,要么是要设置的 IO 约束。

最新更新