77 lines
1.6 KiB
Systemverilog
77 lines
1.6 KiB
Systemverilog
module ppu_ioregs (
|
|
input logic clk,
|
|
input logic nreset,
|
|
|
|
input logic [15:0] cpu_addr_i,
|
|
output logic [ 7:0] cpu_rdata_o,
|
|
input logic cpu_we_i,
|
|
input logic [ 7:0] cpu_wdata_i,
|
|
|
|
output logic display_enable_o,
|
|
output logic tilemap_base_sel_o,
|
|
output logic [ 8:0] ly_o,
|
|
output logic [ 7:0] lx_o
|
|
);
|
|
|
|
`define IOREG_DECL(name) \
|
|
logic [ 7:0] name``_r; \
|
|
logic [ 7:0] name``_next; \
|
|
logic name``_we; \
|
|
logic name``_sel;
|
|
|
|
`define IOREG_DEF(name, addr, rstval) \
|
|
always_ff @(posedge clk or negedge nreset) begin \
|
|
if (!nreset) \
|
|
name``_r <= rstval; \
|
|
else if (name``_we) \
|
|
name``_r <= name``_next; \
|
|
end \
|
|
assign name``_sel = (cpu_addr_i == addr); \
|
|
assign name``_we = name``_sel & cpu_we_i;
|
|
|
|
typedef struct packed {
|
|
logic lcd_en;
|
|
logic win_tilemap_sel;
|
|
logic win_en;
|
|
logic tiledata_sel;
|
|
logic bg_tilemap_sel;
|
|
logic obj_size;
|
|
logic obj_display;
|
|
logic bgwin_display;
|
|
} lcdc_t;
|
|
|
|
lcdc_t lcdc;
|
|
logic [3:0] [1:0] bgp;
|
|
|
|
`IOREG_DECL(lcdc);
|
|
`IOREG_DECL(ly);
|
|
`IOREG_DECL(sy);
|
|
`IOREG_DECL(bgp);
|
|
|
|
`IOREG_DEF (lcdc, 16'hFF40, '0);
|
|
`IOREG_DEF ( sy, 16'hFF42, '0);
|
|
`IOREG_DEF ( bgp, 16'hFF47, '0);
|
|
|
|
assign lcdc_next = cpu_wdata_i;
|
|
assign sy_next = cpu_wdata_i;
|
|
assign bgp_next = cpu_wdata_i;
|
|
|
|
assign lcdc = lcdc_r;
|
|
assign bgp = bgp_r;
|
|
|
|
|
|
assign cpu_rdata_o =
|
|
{8{lcdc_sel}} & lcdc_r |
|
|
{8{ sy_sel}} & sy_r;
|
|
|
|
assign display_enable_o = lcdc.lcd_en;
|
|
|
|
assign tilemap_base_sel_o = lcdc.bg_tilemap_sel;
|
|
|
|
`ifdef SVA_ENABLE
|
|
logic sva_sel;
|
|
assign sva_sel = lcdc_sel | sy_sel;
|
|
`endif /* SVA_ENABLE */
|
|
|
|
endmodule : ppu_ioregs
|