HuC6272 BG video

Use microprogram to drive fetch
This commit is contained in:
David Hunter
2026-03-15 21:44:42 -07:00
parent 0ea919738d
commit 9840ace59a
6 changed files with 301 additions and 77 deletions

View File

@@ -94,15 +94,16 @@ logic scsi_int_req_act;
rf_bgm_t rf_bgm;
logic [3:0] mpa;
logic [8:0] mpd;
logic mpwr_pend, mpwr;
logic mpsw;
logic mpwr_pend;
logic [18:1] vid_ma_a;
logic [15:0] vid_ma_di, vid_ma_do;
logic [1:0] vid_ma_be;
logic vid_ma_wr, vid_ma_req, vid_ma_ack;
logic [18:1] vid_mb_a;
logic [15:0] vid_mb_di, vid_mb_do;
logic [1:0] vid_mb_be;
logic vid_mb_wr, vid_mb_req, vidMb_ack;
logic vid_mb_wr, vid_mb_req, vid_mb_ack;
//////////////////////////////////////////////////////////////////////
// CPU memory / I/O bus interface
@@ -126,7 +127,6 @@ always @(posedge CLK) if (CE) begin
scsi_dma_mode <= '0;
rf_bgm <= '0;
mpwr_pend <= '0;
mpwr <= '0;
end
else begin
if (~CSn & ~WRn) begin
@@ -169,13 +169,13 @@ always @(posedge CLK) if (CE) begin
rf_bgm.rsw <= DI[12];
end
7'h13: begin
mpa <= DI[3:0];
rf_bgm.mpwa <= DI[3:0];
end
7'h14: begin
mpd <= DI[8:0];
rf_bgm.mpwd <= DI[8:0];
mpwr_pend <= '1;
end
7'h15: mpsw <= DI[0];
7'h15: rf_bgm.mpsw <= DI[0];
7'h16: rf_bgm.sub_wrap <= DI[3:0];
7'h20: rf_bgm.bgp[0].bat <= DI[7:0];
7'h21: rf_bgm.bgp[0].cg <= DI[7:0];
@@ -227,11 +227,11 @@ always @(posedge CLK) if (CE) begin
else begin
if (mpwr_pend) begin
mpwr_pend <= '0;
mpwr <= '1;
rf_bgm.mpwr <= '1;
end
else if (mpwr) begin
mpwr <= '0;
mpa <= mpa + 1'd1;
else if (rf_bgm.mpwr) begin
rf_bgm.mpwr <= '0;
rf_bgm.mpwa <= rf_bgm.mpwa + 1'd1;
end
end
end
@@ -319,13 +319,13 @@ huc6272_dmc dmca
.CE(CE),
.RESn(RESn),
.A('0),
.DI(),
.DO('0),
.BE('0),
.WR('0),
.REQ('0),
.ACK(),
.A(vid_ma_a),
.DI(vid_ma_di),
.DO(vid_ma_do),
.BE(vid_ma_be),
.WR(vid_ma_wr),
.REQ(vid_ma_req),
.ACK(vid_ma_ack),
.R_DI(RA_DI),
.R_DO(RA_DO),
@@ -372,13 +372,13 @@ huc6272_video video
.rf_bgm(rf_bgm),
.MA_A(),
.MA_DI('0),
.MA_DO(),
.MA_BE(),
.MA_WR(),
.MA_REQ(),
.MA_ACK(),
.MA_A(vid_ma_a),
.MA_DI(vid_ma_di),
.MA_DO(vid_ma_do),
.MA_BE(vid_ma_be),
.MA_WR(vid_ma_wr),
.MA_REQ(vid_ma_req),
.MA_ACK(vid_ma_ack),
.MB_A(vid_mb_a),
.MB_DI(vid_mb_di),
@@ -475,4 +475,5 @@ endmodule
`include "huc6272_dmc.sv"
`include "huc6272_video.sv"
`include "huc6272_fetch.sv"
`include "huc6272_bgm.sv"

View File

@@ -14,22 +14,35 @@ module huc6272_bgm
// Register file
input rf_bgm_t rf_bgm,
// Render control interface
input DCK,
input FETCH,
input RENDER,
input [9:0] RENDER_BG_COL,
input MBA1,
input [15:0] MBD,
input MBACK,
input MDSA,
input [1:0] MDLA,
input [15:0] MDA,
input MDSB,
input [1:0] MDLB,
input [15:0] MDB,
output [23:0] PD,
output PDE
);
wire cgbank = rf_bgm.bgp[LAYER].cg[7];
wire format_clr_16m = ((rf_bgm.bgp[LAYER].format == BGF_INT_DOT_16M) |
(rf_bgm.bgp[LAYER].format == BGF_EXT_BLK_16M) |
(rf_bgm.bgp[LAYER].format == BGF_EXT_DOT_16M));
logic mds;
logic [15:0] md;
assign mds = cgbank ? MDSB : MDSA;
assign mdl = cgbank ? MDLB : MDLA;
assign md = cgbank ? MDB : MDA;
logic cgfce;
logic [15:0] cgrd_in;
logic [31:0] cgrd;
@@ -40,7 +53,7 @@ logic cgpdeo;
wire cgrce = DCK;
always @(posedge CLK)
cgfce <= MBACK;
cgfce <= mds & (mdl == LAYER);
always @(posedge CLK) begin
if (~RESn) begin
@@ -49,15 +62,18 @@ always @(posedge CLK) begin
cgrd_in <= '0;
end
else if (cgfce) begin
cgra <= MBA1;
cgrd_in <= MBD;
cgra <= ~cgra;
cgrd_in <= md;
if (format_clr_16m) begin
if (MBA1)
cgrd <= {cgrd_in, MBD};
if (cgra)
cgrd <= {cgrd_in, md};
end
else
cgrd <= {16'b0, cgrd_in};
end
else if (~(FETCH | RENDER)) begin
cgra <= '0;
end
end
always @* begin

110
rtl/huc6272_fetch.sv Normal file
View File

@@ -0,0 +1,110 @@
// HuC6272 (KING) video fetch engine, one bank
//
// Copyright (c) 2026 David Hunter
//
// This program is GPL licensed. See COPYING for the full license.
module huc6272_fetch
(
input CLK,
input CE,
input RESn,
// Register file
input rf_bgm_t rf_bgm,
// Render control interface
input DCK, // pixel clock enable
input FETCH,
input [9:0] FETCH_BG_ROW,
input [9:0] FETCH_BG_COL,
// Microprogram data store interface
input mpd_t MPRBUF,
// Memory client interface
output [18:1] M_A,
input [15:0] M_DI,
output [15:0] M_DO,
output [1:0] M_BE,
output M_WR,
output M_REQ,
input M_ACK,
// Fetched CG data
output MDS,
output [1:0] MDL,
output [15:0] MD
);
//////////////////////////////////////////////////////////////////////
// Microprogram engine
mpd_t mpe_d;
logic [18:1] mpe_ra;
logic mpe_ren;
logic [1:0] mpe_layer;
assign mpe_d = FETCH ? MPRBUF : 9'h100;
function [18:1] mpe_addr(mpd_t mpd);
logic [7:0] base;
rf_bgp_t bgp;
bgp = get_bgp(mpd.layer);
mpe_addr = '0;
if (~mpd.nop) begin
mpe_addr[16:10] = mpd.bat ? bgp.bat[6:0] : bgp.cg[6:0]; // [7] is A/-B
if (mpd.bat)
; // TODO
else // CG
mpe_addr += {FETCH_BG_ROW[7:0], FETCH_BG_COL[7:3], mpd.cgoff};
end
endfunction
always @(posedge CLK) begin
mpe_ren <= ~mpe_d.nop;
mpe_layer <= mpe_d.layer;
mpe_ra <= mpe_addr(mpe_d);
end
//////////////////////////////////////////////////////////////////////
// Bank A/B memory client interface
logic mtrg, mreq, mack;
logic [1:0] mdl;
logic [18:1] ma, ma_d;
logic [15:0] md;
assign ma = mpe_ra;
assign mtrg = mpe_ren & FETCH & DCK;
assign mack = M_REQ & M_ACK;
always @(posedge CLK) begin
if (~RESn) begin
ma_d <= '0;
mdl <= '0;
md <= '0;
mreq <= '0;
end
else begin
mreq <= M_REQ & ~M_ACK;
if (mtrg) begin
ma_d <= ma;
mdl <= mpe_layer;
end
if (mack)
md <= M_DI;
end
end
assign M_A = ma;
assign M_BE = '1;
assign M_WR = '0;
assign M_REQ = mreq | mtrg;
assign MDS = mack;
assign MDL = mdl;
assign MD = md;
endmodule

View File

@@ -29,9 +29,22 @@ typedef struct packed {
} rf_bgp_t;
typedef struct packed {
logic [3:0] mpwa;
logic [8:0] mpwd;
logic mpwr;
logic mpsw;
rf_bgp_t [4] bgp;
logic rsw;
logic sub_wrap;
logic [7:0] sub_bat0, sub_cg0;
logic [3:0] size_sub_m0, size_sub_n0;
} rf_bgm_t;
typedef struct packed {
logic nop;
logic [1:0] layer;
logic rotate;
logic bat; // BAT / -CG
logic ext; // EXT / -INT
logic [2:0] cgoff; // CG offset
} mpd_t;

View File

@@ -44,6 +44,16 @@ module huc6272_video
logic [9:0] row, col;
function rf_bgp_t get_bgp(input [1:0] layer);
case (layer)
2'd0: get_bgp = rf_bgm.bgp[0];
2'd1: get_bgp = rf_bgm.bgp[1];
2'd2: get_bgp = rf_bgm.bgp[2];
2'd3: get_bgp = rf_bgm.bgp[3];
default: get_bgp = 'X;
endcase
endfunction
//////////////////////////////////////////////////////////////////////
// Video counter
@@ -98,36 +108,83 @@ wire [9:0] render_bg_row = row - RENDER_ROW_START;
wire [9:0] render_bg_col = col - RENDER_COL_START;
//////////////////////////////////////////////////////////////////////
// Bank A/B memory client interfaces
// Microprogram data store
logic mbtrg, mbreq, mback;
logic [18:1] mba, mba_d;
logic [15:0] mbd;
mpd_t mpd [2][8];
mpd_t mprbufa, mprbufb;
logic [2:0] mpra;
assign mba = {fetch_bg_row[7:0], fetch_bg_col[7:0]};
assign mbtrg = fetch & DCK;
assign mback = MB_REQ & MB_ACK;
assign mpra = fetch ? fetch_bg_col[2:0] : '0;
always @(posedge CLK) begin
if (~RESn) begin
mba_d <= '0;
mbd <= '0;
mbreq <= '0;
end
else begin
mbreq <= MB_REQ & ~MB_ACK;
if (mbtrg)
mba_d <= mba;
if (mback)
mbd <= MB_DI;
end
mprbufa <= mpd[0][mpra];
mprbufb <= mpd[1][mpra];
if (rf_bgm.mpwr)
mpd[rf_bgm.mpwa[3]][rf_bgm.mpwa[2:0]] <= rf_bgm.mpwd;
end
assign MB_A = mba;
assign MB_BE = '1;
assign MB_WR = '0;
assign MB_REQ = mbreq | mbtrg;
//////////////////////////////////////////////////////////////////////
// Bank A/B microprogram engine and memory client interfaces
logic mdsa, mdsb;
logic [1:0] mdla, mdlb;
logic [15:0] mda, mdb;
huc6272_fetch vfea
(
.CLK(CLK),
.CE(CE),
.RESn(RESn),
.rf_bgm(rf_bgm),
.DCK(DCK),
.FETCH(fetch),
.FETCH_BG_ROW(fetch_bg_row),
.FETCH_BG_COL(fetch_bg_col),
.MPRBUF(mprbufa),
.M_A(MA_A),
.M_DI(MA_DI),
.M_DO(MA_DO),
.M_BE(MA_BE),
.M_WR(MA_WR),
.M_REQ(MA_REQ),
.M_ACK(MA_ACK),
.MDS(mdsa),
.MDL(mdla),
.MD(mda)
);
huc6272_fetch vfeb
(
.CLK(CLK),
.CE(CE),
.RESn(RESn),
.rf_bgm(rf_bgm),
.DCK(DCK),
.FETCH(fetch),
.FETCH_BG_ROW(fetch_bg_row),
.FETCH_BG_COL(fetch_bg_col),
.MPRBUF(mprbufb),
.M_A(MB_A),
.M_DI(MB_DI),
.M_DO(MB_DO),
.M_BE(MB_BE),
.M_WR(MB_WR),
.M_REQ(MB_REQ),
.M_ACK(MB_ACK),
.MDS(mdsb),
.MDL(mdlb),
.MD(mdb)
);
//////////////////////////////////////////////////////////////////////
// BG pipelines
@@ -144,12 +201,16 @@ huc6272_bgm #(0) bg0
.rf_bgm(rf_bgm),
.DCK(DCK),
.FETCH(fetch),
.RENDER(render),
.RENDER_BG_COL(render_bg_col),
.MBA1(mba_d[1]),
.MBD(mbd),
.MBACK(mback),
.MDSA(mdsa),
.MDLA(mdla),
.MDA(mda),
.MDSB(mdsb),
.MDLB(mdlb),
.MDB(mdb),
.PD(bg0_pd),
.PDE(bg0_pde)

View File

@@ -1,15 +1,15 @@
[*]
[*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI
[*] Sun Mar 15 21:23:29 2026
[*] Mon Mar 16 04:44:30 2026
[*]
[dumpfile] "/Users/dhunter/src/mister/PCFX_MiSTer/rtl/tb/huc6272_video_tb.vcd"
[dumpfile_mtime] "Sun Mar 15 21:23:23 2026"
[dumpfile_size] 5946693
[dumpfile_mtime] "Mon Mar 16 04:43:58 2026"
[dumpfile_size] 6247181
[savefile] "/Users/dhunter/src/mister/PCFX_MiSTer/rtl/tb/huc6272_video_tb.gtkw"
[timestart] 0
[timestart] 558159
[size] 1333 600
[pos] -1 -1
*-17.200001 13280 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
*-9.200001 559380 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[markername] AA
[markername] BB
[markername] CC
@@ -55,25 +55,48 @@ huc6272_video_tb.dut.video.fetch
@24
huc6272_video_tb.dut.video.fetch_bg_row[9:0]
huc6272_video_tb.dut.video.fetch_bg_col[9:0]
@28
huc6272_video_tb.dut.video.mbtrg
huc6272_video_tb.dut.video.mback
@c00200
-vfea
@22
huc6272_video_tb.dut.video.mba[18:1]
huc6272_video_tb.dut.video.mba_d[18:1]
huc6272_video_tb.dut.video.mbd[15:0]
huc6272_video_tb.dut.video.vfea.mpe_ra[18:1]
huc6272_video_tb.dut.video.vfea.mpe_d[8:0]
@28
huc6272_video_tb.dut.video.vfea.mtrg
huc6272_video_tb.dut.video.vfea.mack
@22
huc6272_video_tb.dut.video.vfea.ma[18:1]
huc6272_video_tb.dut.video.vfea.MD[15:0]
@28
huc6272_video_tb.dut.video.vfea.MDL[1:0]
@1401200
-vfea
@800200
-vfeb
@22
huc6272_video_tb.dut.video.vfeb.mpe_ra[18:1]
huc6272_video_tb.dut.video.vfeb.mpe_d[8:0]
@28
huc6272_video_tb.dut.video.vfeb.mtrg
huc6272_video_tb.dut.video.vfeb.mack
@22
huc6272_video_tb.dut.video.vfeb.ma[18:1]
huc6272_video_tb.dut.video.vfeb.MD[15:0]
@28
huc6272_video_tb.dut.video.vfeb.MDL[1:0]
@1000200
-vfeb
@800200
-bg0
@29
huc6272_video_tb.dut.video.bg0.cgfce
@28
huc6272_video_tb.dut.video.bg0.cgfce
huc6272_video_tb.dut.video.bg0.cgra
@22
huc6272_video_tb.dut.video.bg0.cgrd[31:0]
@28
huc6272_video_tb.dut.video.render
@24
@25
huc6272_video_tb.dut.video.render_bg_row[9:0]
@24
huc6272_video_tb.dut.video.render_bg_col[9:0]
@22
huc6272_video_tb.dut.video.bg0.cgpd[23:0]