mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 23:24:15 +01:00
96 lines
3.1 KiB
Verilog
96 lines
3.1 KiB
Verilog
module n64_pi (
|
|
input i_clk,
|
|
input i_reset,
|
|
|
|
input [1:0] i_n64_pi_alel,
|
|
input [1:0] i_n64_pi_aleh,
|
|
input i_n64_pi_read,
|
|
input i_n64_pi_write,
|
|
input [15:0] i_n64_pi_ad,
|
|
output reg [15:0] o_n64_pi_ad,
|
|
output o_n64_pi_ad_mode,
|
|
|
|
output reg o_read_rq,
|
|
output reg o_write_rq,
|
|
input i_ack,
|
|
output reg [31:0] o_address,
|
|
input [31:0] i_data,
|
|
output reg [31:0] o_data,
|
|
|
|
input i_address_valid
|
|
);
|
|
|
|
reg r_last_n64_pi_alel;
|
|
reg r_last_n64_pi_aleh;
|
|
reg r_last_n64_pi_read;
|
|
reg r_last_n64_pi_write;
|
|
|
|
reg r_first_transfer;
|
|
reg r_word_select;
|
|
reg [31:0] r_data_i_buffer;
|
|
reg [15:0] r_word_buffer;
|
|
reg r_address_valid;
|
|
reg r_address_valid_buffer;
|
|
|
|
wire w_aleh_valid = (&i_n64_pi_alel) && (&i_n64_pi_aleh);
|
|
wire w_alel_valid = (&i_n64_pi_alel) && (~|i_n64_pi_aleh);
|
|
wire w_address_op = r_last_n64_pi_alel && !i_n64_pi_alel[0] && !i_n64_pi_aleh[0];
|
|
wire w_read_op = r_last_n64_pi_read && !i_n64_pi_read;
|
|
wire w_write_op = r_last_n64_pi_write && !i_n64_pi_write;
|
|
wire w_bus_read_op = w_read_op && r_word_select;
|
|
wire w_bus_write_op = w_write_op && !r_word_select;
|
|
|
|
wire w_address_increment = w_bus_read_op || (w_bus_write_op && !r_first_transfer);
|
|
|
|
assign o_n64_pi_ad_mode = !i_reset && !i_n64_pi_alel[0] && !i_n64_pi_aleh[0] && !i_n64_pi_read && !r_last_n64_pi_read && r_address_valid;
|
|
|
|
always @(posedge i_clk) begin
|
|
r_last_n64_pi_alel <= i_n64_pi_alel[0];
|
|
r_last_n64_pi_aleh <= i_n64_pi_aleh[0];
|
|
r_last_n64_pi_read <= i_n64_pi_read;
|
|
r_last_n64_pi_write <= i_n64_pi_write;
|
|
|
|
o_read_rq <= 1'b0;
|
|
o_write_rq <= 1'b0;
|
|
|
|
if (!i_reset) begin
|
|
o_read_rq <= w_bus_read_op || w_address_op;
|
|
o_write_rq <= w_bus_write_op;
|
|
|
|
if (w_aleh_valid) begin
|
|
o_address <= {i_n64_pi_ad, o_address[15:0]};
|
|
end
|
|
if (w_alel_valid) begin
|
|
o_address <= {o_address[31:16], i_n64_pi_ad[15:1], 1'b0};
|
|
end
|
|
if (w_address_op) begin
|
|
r_first_transfer <= 1'b1;
|
|
r_word_select <= 1'b1;
|
|
end
|
|
if (w_read_op || w_write_op) begin
|
|
r_word_select <= ~r_word_select;
|
|
o_address <= {o_address[31:10], (o_address[9:0] + {w_address_increment, 2'b00})};
|
|
end
|
|
if (w_write_op && !r_word_select) begin
|
|
r_first_transfer <= 1'b0;
|
|
end
|
|
if (w_read_op) begin
|
|
{o_n64_pi_ad, r_word_buffer} <= r_word_select ? r_data_i_buffer : {r_word_buffer, 16'hXXXX};
|
|
end
|
|
if (w_write_op) begin
|
|
o_data <= {o_data[15:0], i_n64_pi_ad};
|
|
end
|
|
if (w_bus_read_op) begin
|
|
r_address_valid <= r_address_valid_buffer;
|
|
end
|
|
if (o_read_rq) begin
|
|
r_address_valid_buffer <= i_address_valid;
|
|
end
|
|
if (i_ack) begin
|
|
r_data_i_buffer <= i_data;
|
|
end
|
|
end
|
|
end
|
|
|
|
endmodule
|