initial commit
This commit is contained in:
130
src/verilog6502_addr_decoder.sv
Normal file
130
src/verilog6502_addr_decoder.sv
Normal file
@@ -0,0 +1,130 @@
|
||||
module verilog6502_addr_decoder(
|
||||
input i_clk,
|
||||
input i_rst,
|
||||
|
||||
input logic [15:0] i_cpu_addr,
|
||||
input logic [7:0] i_cpu_data,
|
||||
output logic [7:0] o_cpu_data,
|
||||
input logic i_cpu_we,
|
||||
/* verilator lint_off UNOPTFLAT */
|
||||
output logic o_cpu_rdy,
|
||||
/* verilator lint_on UNOPTFLAT */
|
||||
|
||||
|
||||
output logic [15:0] o_mem_addr,
|
||||
output logic [7:0] o_mem_data,
|
||||
input logic [7:0] i_mem_data,
|
||||
output logic o_mem_rd,
|
||||
output logic o_mem_we,
|
||||
input logic i_mem_rdy,
|
||||
|
||||
output logic [15:0] o_external_addr,
|
||||
output logic [7:0] o_external_data,
|
||||
input logic [7:0] i_external_data,
|
||||
output logic o_external_rd,
|
||||
output logic o_external_we,
|
||||
input logic i_external_rdy,
|
||||
|
||||
output logic [15:0] o_io_addr,
|
||||
output logic [7:0] o_io_data,
|
||||
input logic [7:0] i_io_data,
|
||||
output logic o_io_rd,
|
||||
output logic o_io_we,
|
||||
input logic i_io_rdy
|
||||
);
|
||||
|
||||
enum logic [1:0] {NONE, MEM, EXT, IO} prev_addr, prev_addr_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
prev_addr <= NONE;
|
||||
end else begin
|
||||
prev_addr <= prev_addr_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
prev_addr_next = prev_addr;
|
||||
|
||||
o_mem_addr = '0;
|
||||
o_mem_data = '0;
|
||||
o_mem_rd = '0;
|
||||
o_mem_we = '0;
|
||||
|
||||
o_external_addr = '0;
|
||||
o_external_data = '0;
|
||||
o_external_rd = '0;
|
||||
o_external_we = '0;
|
||||
|
||||
o_io_addr = '0;
|
||||
o_io_data = '0;
|
||||
o_io_rd = '0;
|
||||
o_io_we = '0;
|
||||
|
||||
case (prev_addr)
|
||||
NONE: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
|
||||
MEM: begin
|
||||
o_cpu_rdy = i_mem_rdy;
|
||||
o_cpu_data = i_mem_data;
|
||||
end
|
||||
|
||||
EXT: begin
|
||||
o_cpu_rdy = i_external_rdy;
|
||||
o_cpu_data = i_external_data;
|
||||
end
|
||||
|
||||
IO: begin
|
||||
o_cpu_rdy = i_io_rdy;
|
||||
o_cpu_data = i_io_data;
|
||||
end
|
||||
|
||||
default: begin
|
||||
o_cpu_rdy = '1;
|
||||
o_cpu_data = '0;
|
||||
end
|
||||
endcase
|
||||
|
||||
if (o_cpu_rdy) begin
|
||||
if (i_cpu_addr < 16'hE000) begin
|
||||
o_mem_addr = i_cpu_addr;
|
||||
o_mem_data = i_cpu_data;
|
||||
o_mem_we = i_cpu_we & o_cpu_rdy;
|
||||
o_mem_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = MEM;
|
||||
// o_cpu_rdy = i_mem_rdy;
|
||||
// o_cpu_data = i_mem_data;
|
||||
end else if (i_cpu_addr < 16'hF000) begin
|
||||
o_external_addr = {4'b0, i_cpu_addr[11:0]};
|
||||
o_external_data = i_cpu_data;
|
||||
o_external_we = i_cpu_we & o_cpu_rdy;
|
||||
o_external_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = EXT;
|
||||
// o_cpu_rdy = i_external_rdy;
|
||||
// o_cpu_data = i_external_data;
|
||||
end else begin
|
||||
o_io_addr = {4'b0, i_cpu_addr[11:0]};
|
||||
o_io_data = i_cpu_data;
|
||||
o_io_we = i_cpu_we & o_cpu_rdy;
|
||||
o_io_rd = ~i_cpu_we & o_cpu_rdy;
|
||||
prev_addr_next = IO;
|
||||
// o_cpu_rdy = i_io_rdy;
|
||||
// o_cpu_data = i_io_data;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_rst) begin
|
||||
o_mem_rd = 0;
|
||||
o_mem_we = 0;
|
||||
o_external_rd = 0;
|
||||
o_external_we = 0;
|
||||
o_io_rd = 0;
|
||||
o_io_we = 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user