使用Vivado IIC IP流程的坏s_axi_bvalid、s_axi_wready和s_axi_awready信号[英] Bad s_axi_bvalid, s_axi_wready, and s_axi_awready signals using Vivado IIC IP Flow

本文是小编为大家收集整理的关于使用Vivado IIC IP流程的坏s_axi_bvalid、s_axi_wready和s_axi_awready信号的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我试图以重复启动为IIC主接收器编程.将设备地址写入tx_fifo s_axi_bvalid,s_axi_wwred和s_axi_awready之后,为'x'.我不确定发生了什么.我已经附上了时间表.感谢您的帮助.

在此处输入图像说明

测试设计

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   
);
    logic                                       iic2intc_irpt   =   1'b1;

    //AXI Global System Signals
    wire                                        s_axi_aclk      =   clk;
    logic                                       s_axi_aresetn   =   1'b0;

    //AXI Write Address Channel Signals
    logic       [31:0]                          s_axi_awaddr    =   '0;
    logic                                       s_axi_awvalid   =   1'b0;
    logic                                       s_axi_awready;

    //AXI Write Data Channel Signals
    logic       [31:0]                          s_axi_wdata     =   '0;
    logic       [3:0]                           s_axi_wstrb     =   '1;
    logic                                       s_axi_wvalid    =   '0;
    logic                                       s_axi_wready;

    //AXI Write Response Channel Signals
    logic       [1:0]                           s_axi_bresp;
    logic                                       s_axi_bvalid;
    logic                                       s_axi_bready    =   1'b0;

    //AXI Read Address Channel Signals
    logic       [31:0]                          s_axi_araddr    =   '0;
    logic                                       s_axi_arvalid   =   1'b0;
    logic                                       s_axi_arready;

    //AXI Read Data Channel Signals
    logic       [31:0]                          s_axi_rdata;
    logic       [1:0]                           s_axi_rresp;
    logic                                       s_axi_rvalid;
    logic                                       s_axi_rready    =   1'b0;

    //IIC signals
    logic                                       sda_i           =   1'b0;
    logic                                       sda_o;
    logic                                       sda_t;
    logic                                       scl_i           =   1'b0;
    logic                                       scl_o;
    logic                                       scl_t;
    logic                                       gpo             =   1'b0;

    logic                                       state_done;
    //i2C state
    (* KEEP = "TRUE" *) typedef enum logic [7:0]    {
        SET_TX_FIFO,
        SET_RX_FIFO_PIRQ,
        SET_CR_MSMS_TX,
        SET_CR_TXAK
    } state_type;

    (* KEEP = "TRUE" *) state_type    state = SET_TX_FIFO;

    //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_0 iic (
    .iic2intc_irpt(iic2intc_irpt),
    .s_axi_aclk(s_axi_aclk),
    .s_axi_aresetn(s_axi_aresetn),
    .s_axi_awaddr(s_axi_awaddr),
    .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_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.
function void set_a_axi_w (input [31:0] awaddr, wdata);
    s_axi_awaddr    <=  awaddr;
    s_axi_wdata     <=  wdata;
    s_axi_awvalid   <=  1'b1; 
    s_axi_bready    <=  1'b1;
    s_axi_wvalid    <=  1'b1;   
endfunction

//set the state of the operation. 
function void set_state (input state_type new_state);
    if(s_axi_awready) begin
        state           <=  new_state; 
    end
endfunction

//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'h10, 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'b00000100);
            //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
end

endmodule

测试台

module i2c_channel_tb();

//Parameters
parameter CLK_PERIOD = 10;

logic           clk;
logic           reset           =   1'b1;
logic   [6:0]   slave_address   =   '0;

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'b001_0000;
end

//psuedo-clock
always #(CLK_PERIOD/2.0) begin
    clk <= ~clk;
end
endmodule

推荐答案

您会注意到" axi_iic_0"实例缺少 *_axi_bready和 *_axi_rready端口.我添加了它们,一切都按预期工作.

本文地址:https://www.itbaoku.cn/post/2091016.html

问题描述

Im attempting to program an IIC Master Receiver with a Repeated Start. After writing the device address to the TX_FIFO s_axi_bvalid, s_axi_wready, and s_axi_awready are 'X'. I'm not sure whats happening. I've attached my timing diagram. Thanks for your help.

enter image description here

DESIGN UNDER TEST

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   
);
    logic                                       iic2intc_irpt   =   1'b1;

    //AXI Global System Signals
    wire                                        s_axi_aclk      =   clk;
    logic                                       s_axi_aresetn   =   1'b0;

    //AXI Write Address Channel Signals
    logic       [31:0]                          s_axi_awaddr    =   '0;
    logic                                       s_axi_awvalid   =   1'b0;
    logic                                       s_axi_awready;

    //AXI Write Data Channel Signals
    logic       [31:0]                          s_axi_wdata     =   '0;
    logic       [3:0]                           s_axi_wstrb     =   '1;
    logic                                       s_axi_wvalid    =   '0;
    logic                                       s_axi_wready;

    //AXI Write Response Channel Signals
    logic       [1:0]                           s_axi_bresp;
    logic                                       s_axi_bvalid;
    logic                                       s_axi_bready    =   1'b0;

    //AXI Read Address Channel Signals
    logic       [31:0]                          s_axi_araddr    =   '0;
    logic                                       s_axi_arvalid   =   1'b0;
    logic                                       s_axi_arready;

    //AXI Read Data Channel Signals
    logic       [31:0]                          s_axi_rdata;
    logic       [1:0]                           s_axi_rresp;
    logic                                       s_axi_rvalid;
    logic                                       s_axi_rready    =   1'b0;

    //IIC signals
    logic                                       sda_i           =   1'b0;
    logic                                       sda_o;
    logic                                       sda_t;
    logic                                       scl_i           =   1'b0;
    logic                                       scl_o;
    logic                                       scl_t;
    logic                                       gpo             =   1'b0;

    logic                                       state_done;
    //i2C state
    (* KEEP = "TRUE" *) typedef enum logic [7:0]    {
        SET_TX_FIFO,
        SET_RX_FIFO_PIRQ,
        SET_CR_MSMS_TX,
        SET_CR_TXAK
    } state_type;

    (* KEEP = "TRUE" *) state_type    state = SET_TX_FIFO;

    //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_0 iic (
    .iic2intc_irpt(iic2intc_irpt),
    .s_axi_aclk(s_axi_aclk),
    .s_axi_aresetn(s_axi_aresetn),
    .s_axi_awaddr(s_axi_awaddr),
    .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_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.
function void set_a_axi_w (input [31:0] awaddr, wdata);
    s_axi_awaddr    <=  awaddr;
    s_axi_wdata     <=  wdata;
    s_axi_awvalid   <=  1'b1; 
    s_axi_bready    <=  1'b1;
    s_axi_wvalid    <=  1'b1;   
endfunction

//set the state of the operation. 
function void set_state (input state_type new_state);
    if(s_axi_awready) begin
        state           <=  new_state; 
    end
endfunction

//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'h10, 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'b00000100);
            //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
end

endmodule

TEST BENCH

module i2c_channel_tb();

//Parameters
parameter CLK_PERIOD = 10;

logic           clk;
logic           reset           =   1'b1;
logic   [6:0]   slave_address   =   '0;

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'b001_0000;
end

//psuedo-clock
always #(CLK_PERIOD/2.0) begin
    clk <= ~clk;
end
endmodule

推荐答案

You'll notice that the "axi_iic_0" instance is missing *_axi_bready and *_axi_rready ports. I added them and everything worked as expected.