Files
fpga6502/src/verilog6502_apb_adapter.sv
2026-04-14 21:34:37 -07:00

116 lines
3.6 KiB
Systemverilog

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