module verilog6502_apb_adapter( input i_clk, input i_rst, input logic [15:0] i_addr, input logic [7:0] i_data, output logic [7:0] o_data, input logic i_rd, input logic i_we, output logic o_rdy, taxi_apb_if.mst m_apb ); enum logic {IDLE, ENABLE} state, state_next; logic [15:0] latched_addr, latched_addr_next; logic [15:0] second_addr, second_addr_next; logic second_we, second_rd, second_we_next, second_rd_next; logic [7:0] latched_data, latched_data_next; logic [7:0] second_data, second_data_next; logic latched_pwrite, latched_pwrite_next; always_ff @(posedge i_clk) begin if (i_rst) begin state <= IDLE; latched_addr <= '0; second_addr <= '0; second_we <= '0; second_rd <= '0; latched_data <= '0; latched_pwrite <= '0; second_data <= '0; end else begin state <= state_next; latched_addr <= latched_addr_next; second_addr <= second_addr_next; second_we <= second_we_next; second_rd <= second_rd_next; latched_data <= latched_data_next; latched_pwrite <= latched_pwrite_next; second_data <= second_data_next; end end always_comb begin case (state) IDLE: begin if (i_rd | i_we) begin m_apb.pprot = '0; m_apb.paddr = {16'b0, i_addr} & 32'hfffc; // 32 bit address m_apb.psel = '1; m_apb.pwrite = i_we; m_apb.pstrb = 4'h1 << i_addr[1:0]; // shift based on lower 2 bits m_apb.pwdata = {24'b0, i_data} << i_addr[1:0]; o_rdy = '0; m_apb.penable = '0; state_next = ENABLE; latched_addr_next = i_addr; latched_data_next = i_data; latched_pwrite_next = i_we; end else if (second_rd | second_we) begin m_apb.pprot = '0; m_apb.paddr = {16'b0, second_addr} & 32'hfffc; // 32 bit address m_apb.psel = '1; m_apb.pwrite = second_we; m_apb.pstrb = 4'h1 << second_addr[1:0]; // shift based on lower 2 bits m_apb.pwdata = {24'b0, second_data} << second_addr[1:0]; o_rdy = '0; m_apb.penable = '0; state_next = ENABLE; latched_addr_next = second_addr; latched_data_next = second_data; latched_pwrite_next = second_we; end else begin m_apb.pprot = '0; m_apb.paddr = '0; m_apb.psel = '0; m_apb.pwrite = '0; m_apb.pstrb = '0; m_apb.pwdata = '0; o_rdy = '0; end end ENABLE: begin m_apb.penable = '1; second_we_next = i_we; second_rd_next = i_rd; second_addr_next = i_addr; second_data_next = i_data; m_apb.pprot = '0; m_apb.paddr = {16'b0, latched_addr} & 32'hfffc; // 32 bit address m_apb.psel = '1; m_apb.pwrite = latched_pwrite; m_apb.pstrb = 4'h1 << latched_addr[1:0]; // shift based on lower 2 bits m_apb.pwdata = {24'b0, latched_data} << latched_addr[1:0]; if (m_apb.pready) begin state_next = IDLE; o_data = m_apb.prdata[8 * latched_addr[1:0] +: 8]; o_rdy = '1; end end endcase end endmodule