我正在尝试使用重复启动对 IIC 主接收器进行编程。将设备地址写入 TX_FIFO 后,s_axi_bvalid、s_axi_wready 和 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