mirror of
https://github.com/UzixLS/TSConf_MiST.git
synced 2025-07-18 14:51:25 +03:00
Update the video to latest version.
This commit is contained in:
@ -20,6 +20,8 @@
|
|||||||
{ "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|gs:U15\|T80s:z80_unit\|T80:u0\|T80_Reg:Regs\|RegsH_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|gs:U15\|T80s:z80_unit\|T80:u0\|T80_Reg:Regs\|RegsH_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|gs:U15\|T80s:z80_unit\|T80:u0\|T80_Reg:Regs\|RegsL_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|gs:U15\|T80s:z80_unit\|T80:u0\|T80_Reg:Regs\|RegsL_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
|
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|T80s:CPU\|T80:u0\|T80_Reg:Regs\|RegsH_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
|
{ "" "" "" "Inferred RAM node \"emu:emu\|tsconf:tsconf\|T80s:CPU\|T80:u0\|T80_Reg:Regs\|RegsL_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
{ "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
{ "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
{ "" "" "" "sysmem_HPS_fpga_interfaces.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
|
{ "" "" "" "sysmem_HPS_fpga_interfaces.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
|
||||||
|
@ -361,12 +361,7 @@ set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl"
|
|||||||
set_global_assignment -name CDF_FILE jtag.cdf
|
set_global_assignment -name CDF_FILE jtag.cdf
|
||||||
set_global_assignment -name QIP_FILE sys/sys.qip
|
set_global_assignment -name QIP_FILE sys/sys.qip
|
||||||
set_global_assignment -name QSYS_FILE sys/vip.qsys
|
set_global_assignment -name QSYS_FILE sys/vip.qsys
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_Reg.vhd
|
set_global_assignment -name QIP_FILE src/t80/T80.qip
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80.vhd
|
|
||||||
set_global_assignment -name VHDL_FILE src/t80/T80s.vhd
|
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zports.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zports.v
|
||||||
set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
|
set_global_assignment -name VERILOG_FILE src/cpu/zmem.v
|
||||||
|
@ -96,7 +96,6 @@ module arbiter(
|
|||||||
// TS
|
// TS
|
||||||
input wire [23:0] ts_addr,
|
input wire [23:0] ts_addr,
|
||||||
input wire ts_req,
|
input wire ts_req,
|
||||||
input wire ts_z80_lp,
|
|
||||||
output wire ts_pre_next,
|
output wire ts_pre_next,
|
||||||
output wire ts_next,
|
output wire ts_next,
|
||||||
|
|
||||||
|
@ -256,12 +256,10 @@ wire video_next;
|
|||||||
wire video_pre_next;
|
wire video_pre_next;
|
||||||
wire next_video;
|
wire next_video;
|
||||||
wire video_strobe;
|
wire video_strobe;
|
||||||
wire video_next_strobe;
|
|
||||||
|
|
||||||
// TS
|
// TS
|
||||||
wire [20:0] ts_addr;
|
wire [20:0] ts_addr;
|
||||||
wire ts_req;
|
wire ts_req;
|
||||||
wire ts_z80_lp;
|
|
||||||
|
|
||||||
// IN
|
// IN
|
||||||
wire ts_pre_next;
|
wire ts_pre_next;
|
||||||
@ -518,7 +516,6 @@ arbiter TS07
|
|||||||
.video_pre_next(video_pre_next),
|
.video_pre_next(video_pre_next),
|
||||||
.video_next(video_next), // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe
|
.video_next(video_next), // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe
|
||||||
.video_strobe(video_strobe), // (c3) one-cycle strobe meaning that video_data is available
|
.video_strobe(video_strobe), // (c3) one-cycle strobe meaning that video_data is available
|
||||||
.video_next_strobe(video_next_strobe),
|
|
||||||
.next_vid(next_video), // used for TM prefetch
|
.next_vid(next_video), // used for TM prefetch
|
||||||
.cpu_addr({csvrom, 2'b00, cpu_addr_20}),
|
.cpu_addr({csvrom, 2'b00, cpu_addr_20}),
|
||||||
.cpu_wrdata(cpu_do_bus),
|
.cpu_wrdata(cpu_do_bus),
|
||||||
@ -537,7 +534,6 @@ arbiter TS07
|
|||||||
.dma_next(dma_next),
|
.dma_next(dma_next),
|
||||||
.ts_addr({3'b000, ts_addr}),
|
.ts_addr({3'b000, ts_addr}),
|
||||||
.ts_req(ts_req),
|
.ts_req(ts_req),
|
||||||
.ts_z80_lp(ts_z80_lp),
|
|
||||||
.ts_pre_next(ts_pre_next),
|
.ts_pre_next(ts_pre_next),
|
||||||
.ts_next(ts_next),
|
.ts_next(ts_next),
|
||||||
.tm_addr({3'b000, tm_addr}),
|
.tm_addr({3'b000, tm_addr}),
|
||||||
@ -564,7 +560,6 @@ video_top TS08
|
|||||||
.hblank(VGA_HBLANK),
|
.hblank(VGA_HBLANK),
|
||||||
.vblank(VGA_VBLANK),
|
.vblank(VGA_VBLANK),
|
||||||
.pix_stb(VGA_CEPIX),
|
.pix_stb(VGA_CEPIX),
|
||||||
.a(cpu_a_bus),
|
|
||||||
.d(cpu_do_bus),
|
.d(cpu_do_bus),
|
||||||
.zmd(zmd),
|
.zmd(zmd),
|
||||||
.zma(zma),
|
.zma(zma),
|
||||||
@ -607,10 +602,8 @@ video_top TS08
|
|||||||
.video_pre_next(video_pre_next),
|
.video_pre_next(video_pre_next),
|
||||||
.next_video(next_video),
|
.next_video(next_video),
|
||||||
.video_strobe(video_strobe),
|
.video_strobe(video_strobe),
|
||||||
.video_next_strobe(video_next_strobe),
|
|
||||||
.ts_addr(ts_addr),
|
.ts_addr(ts_addr),
|
||||||
.ts_req(ts_req),
|
.ts_req(ts_req),
|
||||||
.ts_z80_lp(ts_z80_lp),
|
|
||||||
.ts_pre_next(ts_pre_next),
|
.ts_pre_next(ts_pre_next),
|
||||||
.ts_next(ts_next),
|
.ts_next(ts_next),
|
||||||
.tm_addr(tm_addr),
|
.tm_addr(tm_addr),
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
-- Quartus II generated Memory Initialization File (.mif)
|
-- Quartus II generated Memory Initialization File (.mif)
|
||||||
|
|
||||||
WIDTH=15;
|
WIDTH=16;
|
||||||
DEPTH=256;
|
DEPTH=256;
|
||||||
|
|
||||||
ADDRESS_RADIX=HEX;
|
ADDRESS_RADIX=HEX;
|
||||||
|
@ -1,38 +1,33 @@
|
|||||||
// This module fetches video data from DRAM
|
// This module fetches video data from DRAM
|
||||||
|
|
||||||
module video_fetch (
|
module video_fetch
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
// control
|
// control
|
||||||
input wire [3:0] f_sel,
|
input wire [3:0] f_sel,
|
||||||
input wire [1:0] b_sel,
|
input wire [1:0] b_sel,
|
||||||
input wire fetch_stb,
|
input wire fetch_stb,
|
||||||
|
|
||||||
// video data
|
// video data
|
||||||
output reg [31:0] fetch_data,
|
output reg [31:0] fetch_data,
|
||||||
output reg [31:0] fetch_temp,
|
output reg [31:0] fetch_temp,
|
||||||
|
|
||||||
// DRAM interface
|
// DRAM interface
|
||||||
input wire video_strobe,
|
input wire video_strobe,
|
||||||
input wire [15:0] video_data
|
input wire [15:0] video_data
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// fetching data
|
// fetching data
|
||||||
|
always @(posedge clk) if (video_strobe)
|
||||||
|
begin
|
||||||
|
if (f_sel[0]) fetch_temp[ 7: 0] <= b_sel[0] ? video_data[15:8] : video_data[ 7:0];
|
||||||
|
if (f_sel[1]) fetch_temp[15: 8] <= b_sel[1] ? video_data[15:8] : video_data[ 7:0];
|
||||||
|
if (f_sel[2]) fetch_temp[23:16] <= video_data[ 7:0];
|
||||||
|
if (f_sel[3]) fetch_temp[31:24] <= video_data[15:8];
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge clk) if (video_strobe)
|
always @(posedge clk) if (fetch_stb) fetch_data <= fetch_temp;
|
||||||
begin
|
|
||||||
if (f_sel[0]) fetch_temp[ 7: 0] <= b_sel[0] ? video_data[15:8] : video_data[ 7:0];
|
|
||||||
if (f_sel[1]) fetch_temp[15: 8] <= b_sel[1] ? video_data[15:8] : video_data[ 7:0];
|
|
||||||
if (f_sel[2]) fetch_temp[23:16] <= video_data[ 7:0];
|
|
||||||
if (f_sel[3]) fetch_temp[31:24] <= video_data[15:8];
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clk) if (fetch_stb)
|
|
||||||
fetch_data <= fetch_temp;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@ -1,23 +1,28 @@
|
|||||||
|
|
||||||
// This module decodes video modes
|
// This module decodes video modes
|
||||||
|
|
||||||
module video_mode (
|
module video_mode
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk, f1, c3,
|
input wire clk, f1, c3,
|
||||||
|
|
||||||
// video config
|
// video config
|
||||||
input wire [7:0] vpage,
|
input wire [7:0] vpage,
|
||||||
input wire [7:0] vconf,
|
input wire [7:0] vconf,
|
||||||
|
input wire ts_rres_ext,
|
||||||
input wire v60hz,
|
input wire v60hz,
|
||||||
|
|
||||||
// video parameters & mode controls
|
// video parameters & mode controls
|
||||||
input wire [8:0] gx_offs,
|
input wire [8:0] gx_offs,
|
||||||
output wire [9:0] x_offs_mode,
|
output wire [9:0] x_offs_mode,
|
||||||
output wire [8:0] hpix_beg,
|
output wire [8:0] hpix_beg,
|
||||||
output wire [8:0] hpix_end,
|
output wire [8:0] hpix_end,
|
||||||
output wire [8:0] vpix_beg,
|
output wire [8:0] vpix_beg,
|
||||||
output wire [8:0] vpix_end,
|
output wire [8:0] vpix_end,
|
||||||
|
output wire [8:0] hpix_beg_ts,
|
||||||
|
output wire [8:0] hpix_end_ts,
|
||||||
|
output wire [8:0] vpix_beg_ts,
|
||||||
|
output wire [8:0] vpix_end_ts,
|
||||||
output wire [5:0] x_tiles,
|
output wire [5:0] x_tiles,
|
||||||
output wire [4:0] go_offs,
|
output wire [4:0] go_offs,
|
||||||
output wire [3:0] fetch_sel,
|
output wire [3:0] fetch_sel,
|
||||||
@ -31,202 +36,204 @@ module video_mode (
|
|||||||
output wire pix_stb,
|
output wire pix_stb,
|
||||||
output wire fetch_stb,
|
output wire fetch_stb,
|
||||||
|
|
||||||
// video data
|
// video data
|
||||||
input wire [15:0] txt_char,
|
input wire [15:0] txt_char,
|
||||||
|
|
||||||
// video counters
|
// video counters
|
||||||
input wire [7:0] cnt_col,
|
input wire [7:0] cnt_col,
|
||||||
input wire [8:0] cnt_row,
|
input wire [8:0] cnt_row,
|
||||||
input wire cptr,
|
input wire cptr,
|
||||||
|
|
||||||
// DRAM interface
|
// DRAM interface
|
||||||
output wire [20:0] video_addr,
|
output wire [20:0] video_addr,
|
||||||
output wire [ 4:0] video_bw
|
output wire [ 4:0] video_bw
|
||||||
);
|
);
|
||||||
|
|
||||||
|
wire [1:0] vmod = vconf[1:0];
|
||||||
wire [1:0] vmod = vconf[1:0];
|
wire [1:0] rres = vconf[7:6];
|
||||||
wire [1:0] rres = vconf[7:6];
|
|
||||||
|
|
||||||
// clocking strobe for pixels (TV)
|
// clocking strobe for pixels (TV)
|
||||||
assign pix_stb = tv_hires ? f1 : c3;
|
assign pix_stb = tv_hires ? f1 : c3;
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk) if (line_start_s) vga_hires <= tv_hires;
|
||||||
if (line_start_s)
|
|
||||||
vga_hires <= tv_hires;
|
|
||||||
|
|
||||||
// Modes
|
// Modes
|
||||||
localparam M_ZX = 2'h0; // ZX
|
localparam M_ZX = 2'h0; // ZX
|
||||||
localparam M_HC = 2'h1; // 16c
|
localparam M_HC = 2'h1; // 16c
|
||||||
localparam M_XC = 2'h2; // 256c
|
localparam M_XC = 2'h2; // 256c
|
||||||
localparam M_TX = 2'h3; // Text
|
localparam M_TX = 2'h3; // Text
|
||||||
|
|
||||||
|
|
||||||
// Render modes (affects 'video_render.v')
|
// Render modes (affects 'video_render.v')
|
||||||
localparam R_ZX = 2'h0;
|
localparam R_ZX = 2'h0;
|
||||||
localparam R_HC = 2'h1;
|
localparam R_HC = 2'h1;
|
||||||
localparam R_XC = 2'h2;
|
localparam R_XC = 2'h2;
|
||||||
localparam R_TX = 2'h3;
|
localparam R_TX = 2'h3;
|
||||||
|
|
||||||
|
|
||||||
// fetch strobes
|
// fetch strobes
|
||||||
wire ftch[0:3];
|
wire ftch[0:3];
|
||||||
assign fetch_stb = (pix_start | ftch[render_mode]) && c3;
|
assign fetch_stb = (pix_start | ftch[render_mode]) && c3;
|
||||||
assign ftch[R_ZX] = &fetch_cnt[3:0];
|
assign ftch[R_ZX] = &fetch_cnt[3:0];
|
||||||
assign ftch[R_HC] = &fetch_cnt[1:0];
|
assign ftch[R_HC] = &fetch_cnt[1:0];
|
||||||
assign ftch[R_XC] = fetch_cnt[0];
|
assign ftch[R_XC] = fetch_cnt[0];
|
||||||
assign ftch[R_TX] = &fetch_cnt[3:0];
|
assign ftch[R_TX] = &fetch_cnt[3:0];
|
||||||
|
|
||||||
|
|
||||||
// fetch window
|
// fetch window
|
||||||
wire [4:0] g_offs[0:3];
|
wire [4:0] g_offs[0:3];
|
||||||
// these values are from a thin air!!! recheck them occasionally!
|
// these values are from a thin air!!! recheck them occasionally!
|
||||||
assign g_offs[M_ZX] = 5'd18;
|
assign g_offs[M_ZX] = 5'd18;
|
||||||
assign g_offs[M_HC] = 5'd6;
|
assign g_offs[M_HC] = 5'd6;
|
||||||
assign g_offs[M_XC] = 5'd4;
|
assign g_offs[M_XC] = 5'd4;
|
||||||
assign g_offs[M_TX] = 5'd10;
|
assign g_offs[M_TX] = 5'd10;
|
||||||
assign go_offs = g_offs[vmod];
|
assign go_offs = g_offs[vmod];
|
||||||
|
|
||||||
|
|
||||||
// fetch selectors
|
// fetch selectors
|
||||||
// Attention: counter is already incremented at the time of video data fetching!
|
// Attention: counter is already incremented at the time of video data fetching!
|
||||||
|
|
||||||
// wire m_c = (vmod == M_HC) | (vmod == M_XC);
|
// wire m_c = (vmod == M_HC) | (vmod == M_XC);
|
||||||
// assign fetch_sel = vmod == M_TX ? f_txt_sel[cnt_col[1:0]] : {~cptr, ~cptr, cptr | m_c, cptr | m_c};
|
// assign fetch_sel = vmod == M_TX ? f_txt_sel[cnt_col[1:0]] : {~cptr, ~cptr, cptr | m_c, cptr | m_c};
|
||||||
|
|
||||||
// wire [3:0] f_sel[0:7];
|
// wire [3:0] f_sel[0:7];
|
||||||
wire [3:0] f_sel[0:3];
|
wire [3:0] f_sel[0:3];
|
||||||
assign f_sel[M_ZX] = {~cptr, ~cptr, cptr, cptr};
|
assign f_sel[M_ZX] = {~cptr, ~cptr, cptr, cptr};
|
||||||
assign f_sel[M_HC] = {~cptr, ~cptr, 2'b11};
|
assign f_sel[M_HC] = {~cptr, ~cptr, 2'b11};
|
||||||
assign f_sel[M_XC] = {~cptr, ~cptr, 2'b11};
|
assign f_sel[M_XC] = {~cptr, ~cptr, 2'b11};
|
||||||
assign f_sel[M_TX] = f_txt_sel[cnt_col[1:0]];
|
assign f_sel[M_TX] = f_txt_sel[cnt_col[1:0]];
|
||||||
assign fetch_sel = f_sel[vmod];
|
assign fetch_sel = f_sel[vmod];
|
||||||
|
|
||||||
assign fetch_bsl = (vmod == M_TX) ? f_txt_bsl[cnt_col[1:0]] : 2'b10;
|
assign fetch_bsl = (vmod == M_TX) ? f_txt_bsl[cnt_col[1:0]] : 2'b10;
|
||||||
|
|
||||||
// wire [1:0] f_bsl[0:7];
|
// wire [1:0] f_bsl[0:7];
|
||||||
// assign f_bsl[M_ZX] = 2'b10;
|
// assign f_bsl[M_ZX] = 2'b10;
|
||||||
// assign f_bsl[M_HC] = 2'b10;
|
// assign f_bsl[M_HC] = 2'b10;
|
||||||
// assign f_bsl[M_XC] = 2'b10;
|
// assign f_bsl[M_XC] = 2'b10;
|
||||||
// assign f_bsl[M_TX] = f_txt_bsl[cnt_col[1:0]];
|
// assign f_bsl[M_TX] = f_txt_bsl[cnt_col[1:0]];
|
||||||
// assign fetch_bsl = f_bsl[vmod];
|
// assign fetch_bsl = f_bsl[vmod];
|
||||||
|
|
||||||
wire [3:0] f_txt_sel[0:3];
|
wire [3:0] f_txt_sel[0:3];
|
||||||
assign f_txt_sel[1] = 4'b0011; // char
|
assign f_txt_sel[1] = 4'b0011; // char
|
||||||
assign f_txt_sel[2] = 4'b1100; // attr
|
assign f_txt_sel[2] = 4'b1100; // attr
|
||||||
assign f_txt_sel[3] = 4'b0001; // gfx0
|
assign f_txt_sel[3] = 4'b0001; // gfx0
|
||||||
assign f_txt_sel[0] = 4'b0010; // gfx1
|
assign f_txt_sel[0] = 4'b0010; // gfx1
|
||||||
|
|
||||||
wire [1:0] f_txt_bsl[0:3];
|
wire [1:0] f_txt_bsl[0:3];
|
||||||
assign f_txt_bsl[1] = 2'b10; // char
|
assign f_txt_bsl[1] = 2'b10; // char
|
||||||
assign f_txt_bsl[2] = 2'b10; // attr
|
assign f_txt_bsl[2] = 2'b10; // attr
|
||||||
assign f_txt_bsl[3] = {2{cnt_row[0]}}; // gfx0
|
assign f_txt_bsl[3] = {2{cnt_row[0]}}; // gfx0
|
||||||
assign f_txt_bsl[0] = {2{cnt_row[0]}}; // gfx1
|
assign f_txt_bsl[0] = {2{cnt_row[0]}}; // gfx1
|
||||||
|
|
||||||
|
|
||||||
// X offset
|
// X offset
|
||||||
assign x_offs_mode = {vmod == M_XC ? {gx_offs[8:1], 1'b0} : {1'b0, gx_offs[8:1]}, gx_offs[0]};
|
assign x_offs_mode = {vmod == M_XC ? {gx_offs[8:1], 1'b0} : {1'b0, gx_offs[8:1]}, gx_offs[0]};
|
||||||
|
|
||||||
|
|
||||||
// DRAM bandwidth usage
|
// DRAM bandwidth usage
|
||||||
localparam BW2 = 2'b00;
|
localparam BW2 = 2'b00;
|
||||||
localparam BW4 = 2'b01;
|
localparam BW4 = 2'b01;
|
||||||
localparam BW8 = 2'b11;
|
localparam BW8 = 2'b11;
|
||||||
|
|
||||||
localparam BU1 = 3'b001;
|
localparam BU1 = 3'b001;
|
||||||
localparam BU2 = 3'b010;
|
localparam BU2 = 3'b010;
|
||||||
localparam BU4 = 3'b100;
|
localparam BU4 = 3'b100;
|
||||||
|
|
||||||
// [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2
|
// [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2
|
||||||
// [2:0] - need cycles
|
// [2:0] - need cycles
|
||||||
wire [4:0] bw[0:3];
|
wire [4:0] bw[0:3];
|
||||||
assign bw[M_ZX] = {BW8, BU1}; // '1 of 8' (ZX)
|
assign bw[M_ZX] = {BW8, BU1}; // '1 of 8' (ZX)
|
||||||
assign bw[M_HC] = {BW4, BU1}; // '1 of 4' (16c)
|
assign bw[M_HC] = {BW4, BU1}; // '1 of 4' (16c)
|
||||||
assign bw[M_XC] = {BW2, BU1}; // '1 of 2' (256c)
|
assign bw[M_XC] = {BW2, BU1}; // '1 of 2' (256c)
|
||||||
assign bw[M_TX] = {BW8, BU4}; // '4 of 8' (text)
|
assign bw[M_TX] = {BW8, BU4}; // '4 of 8' (text)
|
||||||
assign video_bw = bw[vmod];
|
assign video_bw = bw[vmod];
|
||||||
|
|
||||||
|
|
||||||
// pixelrate
|
// pixelrate
|
||||||
wire [3:0] pixrate = 4'b1000; // change these if you change the modes indexes!
|
wire [3:0] pixrate = 4'b1000; // change these if you change the modes indexes!
|
||||||
assign tv_hires = pixrate[vmod];
|
assign tv_hires = pixrate[vmod];
|
||||||
|
|
||||||
|
|
||||||
// render mode
|
// render mode
|
||||||
// wire [1:0] r_mode[0:7];
|
// wire [1:0] r_mode[0:7];
|
||||||
wire [1:0] r_mode[0:3];
|
wire [1:0] r_mode[0:3];
|
||||||
assign r_mode[M_ZX] = R_ZX;
|
assign r_mode[M_ZX] = R_ZX;
|
||||||
assign r_mode[M_HC] = R_HC;
|
assign r_mode[M_HC] = R_HC;
|
||||||
assign r_mode[M_XC] = R_XC;
|
assign r_mode[M_XC] = R_XC;
|
||||||
assign r_mode[M_TX] = R_TX;
|
assign r_mode[M_TX] = R_TX;
|
||||||
assign render_mode = r_mode[vmod];
|
assign render_mode = r_mode[vmod];
|
||||||
|
|
||||||
|
|
||||||
// raster resolution
|
// raster resolution
|
||||||
wire [8:0] hp_beg[0:3];
|
wire [8:0] hp_beg[0:3];
|
||||||
wire [8:0] hp_end[0:3];
|
wire [8:0] hp_end[0:3];
|
||||||
wire [8:0] vp_beg[0:3];
|
wire [8:0] vp_beg[0:3];
|
||||||
wire [8:0] vp_end[0:3];
|
wire [8:0] vp_end[0:3];
|
||||||
wire [5:0] x_tile[0:3];
|
wire [5:0] x_tile[0:3];
|
||||||
|
|
||||||
assign hp_beg[0] = 9'd140; // 256 (88-52-256-52)
|
assign hp_beg[0] = 9'd140; // 256 (88-52-256-52)
|
||||||
assign hp_beg[1] = 9'd108; // 320 (88-20-320-20)
|
assign hp_beg[1] = 9'd108; // 320 (88-20-320-20)
|
||||||
assign hp_beg[2] = 9'd108; // 320 (88-20-320-20)
|
assign hp_beg[2] = 9'd108; // 320 (88-20-320-20)
|
||||||
assign hp_beg[3] = 9'd88; // 360 (88-0-360-0)
|
assign hp_beg[3] = 9'd88; // 360 (88-0-360-0)
|
||||||
|
|
||||||
assign hp_end[0] = 9'd396; // 256
|
assign hp_end[0] = 9'd396; // 256
|
||||||
assign hp_end[1] = 9'd428; // 320
|
assign hp_end[1] = 9'd428; // 320
|
||||||
assign hp_end[2] = 9'd428; // 320
|
assign hp_end[2] = 9'd428; // 320
|
||||||
assign hp_end[3] = 9'd448; // 360
|
assign hp_end[3] = 9'd448; // 360
|
||||||
|
|
||||||
assign vp_beg[0] = v60hz ? 9'd046 : 9'd080; // 192 (22-24-192-24)/(32-48-192-48) (blank-border-pixels-border)
|
assign vp_beg[0] = v60hz ? 9'd046 : 9'd080; // 192 (22-24-192-24)/(32-48-192-48) (blank-border-pixels-border)
|
||||||
assign vp_beg[1] = v60hz ? 9'd042 : 9'd076; // 200 (22-20-200-20)/(32-44-200-44)
|
assign vp_beg[1] = v60hz ? 9'd042 : 9'd076; // 200 (22-20-200-20)/(32-44-200-44)
|
||||||
assign vp_beg[2] = v60hz ? 9'd022 : 9'd056; // 240 (22-0-240-0)/(32-24-240-24)
|
assign vp_beg[2] = v60hz ? 9'd022 : 9'd056; // 240 (22-0-240-0)/(32-24-240-24)
|
||||||
assign vp_beg[3] = v60hz ? 9'd022 : 9'd032; // 288 (22-0-240-0)/(32-0-288-0)
|
assign vp_beg[3] = v60hz ? 9'd022 : 9'd032; // 288 (22-0-240-0)/(32-0-288-0)
|
||||||
|
|
||||||
assign vp_end[0] = v60hz ? 9'd238 : 9'd272; // 192
|
assign vp_end[0] = v60hz ? 9'd238 : 9'd272; // 192
|
||||||
assign vp_end[1] = v60hz ? 9'd242 : 9'd276; // 200
|
assign vp_end[1] = v60hz ? 9'd242 : 9'd276; // 200
|
||||||
assign vp_end[2] = v60hz ? 9'd262 : 9'd296; // 240
|
assign vp_end[2] = v60hz ? 9'd262 : 9'd296; // 240
|
||||||
assign vp_end[3] = v60hz ? 9'd262 : 9'd320; // 240/288
|
assign vp_end[3] = v60hz ? 9'd262 : 9'd320; // 240/288
|
||||||
|
|
||||||
assign x_tile[0] = 6'd34; // 256
|
assign x_tile[0] = 6'd34; // 256
|
||||||
assign x_tile[1] = 6'd42; // 320
|
assign x_tile[1] = 6'd42; // 320
|
||||||
assign x_tile[2] = 6'd42; // 320
|
assign x_tile[2] = 6'd42; // 320
|
||||||
assign x_tile[3] = 6'd47; // 360
|
assign x_tile[3] = 6'd47; // 360
|
||||||
|
|
||||||
assign hpix_beg = hp_beg[rres];
|
assign hpix_beg = hp_beg[rres];
|
||||||
assign hpix_end = hp_end[rres];
|
assign hpix_end = hp_end[rres];
|
||||||
assign vpix_beg = vp_beg[rres];
|
assign vpix_beg = vp_beg[rres];
|
||||||
assign vpix_end = vp_end[rres];
|
assign vpix_end = vp_end[rres];
|
||||||
assign x_tiles = x_tile[rres];
|
|
||||||
|
|
||||||
|
assign hpix_beg_ts = ts_rres_ext ? hp_beg[3] : hp_beg[rres];
|
||||||
|
assign hpix_end_ts = ts_rres_ext ? hp_end[3] : hp_end[rres];
|
||||||
|
assign vpix_beg_ts = ts_rres_ext ? vp_beg[3] : vp_beg[rres];
|
||||||
|
assign vpix_end_ts = ts_rres_ext ? vp_end[3] : vp_end[rres];
|
||||||
|
|
||||||
|
assign x_tiles = ts_rres_ext ? x_tile[3] : x_tile[rres];
|
||||||
|
|
||||||
// videomode addresses
|
// videomode addresses
|
||||||
wire [20:0] v_addr[0:3];
|
wire [20:0] v_addr[0:3];
|
||||||
assign v_addr[M_ZX] = addr_zx;
|
assign v_addr[M_ZX] = addr_zx;
|
||||||
assign v_addr[M_HC] = addr_16c;
|
assign v_addr[M_HC] = addr_16c;
|
||||||
assign v_addr[M_XC] = addr_256c;
|
assign v_addr[M_XC] = addr_256c;
|
||||||
assign v_addr[M_TX] = addr_text;
|
assign v_addr[M_TX] = addr_text;
|
||||||
assign video_addr = v_addr[vmod];
|
assign video_addr = v_addr[vmod];
|
||||||
|
|
||||||
// ZX
|
// ZX
|
||||||
wire [20:0] addr_zx = {vpage, 1'b0, ~cnt_col[0] ? addr_zx_gfx : addr_zx_atr};
|
wire [20:0] addr_zx = {vpage, 1'b0, ~cnt_col[0] ? addr_zx_gfx : addr_zx_atr};
|
||||||
wire [11:0] addr_zx_gfx = {cnt_row[7:6], cnt_row[2:0], cnt_row[5:3], cnt_col[4:1]};
|
wire [11:0] addr_zx_gfx = {cnt_row[7:6], cnt_row[2:0], cnt_row[5:3], cnt_col[4:1]};
|
||||||
wire [11:0] addr_zx_atr = {3'b110, cnt_row[7:3], cnt_col[4:1]};
|
wire [11:0] addr_zx_atr = {3'b110, cnt_row[7:3], cnt_col[4:1]};
|
||||||
|
|
||||||
// 16c
|
// 16c
|
||||||
wire [20:0] addr_16c = {vpage[7:3], cnt_row, cnt_col[6:0]};
|
wire [20:0] addr_16c = {vpage[7:3], cnt_row, cnt_col[6:0]};
|
||||||
|
|
||||||
// 256c
|
// 256c
|
||||||
wire [20:0] addr_256c = {vpage[7:4], cnt_row, cnt_col[7:0]};
|
wire [20:0] addr_256c = {vpage[7:4], cnt_row, cnt_col[7:0]};
|
||||||
|
|
||||||
// Textmode
|
// Textmode
|
||||||
wire [20:0] addr_text = {vpage[7:1], addr_tx[cnt_col[1:0]]};
|
wire [20:0] addr_text = {vpage[7:1], addr_tx[cnt_col[1:0]]};
|
||||||
wire [13:0] addr_tx[0:3];
|
wire [13:0] addr_tx[0:3];
|
||||||
assign addr_tx[0] = {vpage[0], cnt_row[8:3], 1'b0, cnt_col[7:2]}; // char codes, data[15:0]
|
assign addr_tx[0] = {vpage[0], cnt_row[8:3], 1'b0, cnt_col[7:2]}; // char codes, data[15:0]
|
||||||
assign addr_tx[1] = {vpage[0], cnt_row[8:3], 1'b1, cnt_col[7:2]}; // char attributes, data[31:16]
|
assign addr_tx[1] = {vpage[0], cnt_row[8:3], 1'b1, cnt_col[7:2]}; // char attributes, data[31:16]
|
||||||
assign addr_tx[2] = {~vpage[0], 3'b000, (txt_char[7:0]), cnt_row[2:1]}; // char0 graphics, data[7:0]
|
assign addr_tx[2] = {~vpage[0], 3'b000, (txt_char[7:0]), cnt_row[2:1]}; // char0 graphics, data[7:0]
|
||||||
assign addr_tx[3] = {~vpage[0], 3'b000, (txt_char[15:8]), cnt_row[2:1]}; // char1 graphics, data[15:8]
|
assign addr_tx[3] = {~vpage[0], 3'b000, (txt_char[15:8]), cnt_row[2:1]}; // char1 graphics, data[15:8]
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,76 +1,68 @@
|
|||||||
|
|
||||||
// This module generates video for DAC
|
// This module generates video for DAC
|
||||||
// MVV corrected 24bpp 24.08.2014
|
// (c)2015 TSL
|
||||||
|
|
||||||
module video_out (
|
module video_out
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk, f0, c3,
|
input wire clk, f0, c3,
|
||||||
|
|
||||||
// video controls
|
// video controls
|
||||||
input wire vga_on,
|
input wire vga_on,
|
||||||
input wire tv_blank,
|
input wire tv_blank,
|
||||||
input wire vga_blank,
|
input wire vga_blank,
|
||||||
input wire [1:0] plex_sel_in,
|
input wire [1:0] plex_sel_in,
|
||||||
|
|
||||||
// mode controls
|
// mode controls
|
||||||
input wire tv_hires,
|
input wire tv_hires,
|
||||||
input wire vga_hires,
|
input wire vga_hires,
|
||||||
input wire [3:0] palsel,
|
input wire [3:0] palsel,
|
||||||
|
|
||||||
// Z80 pins
|
// Z80 pins
|
||||||
input wire [14:0] cram_data_in,
|
input wire [15:0] cram_data_in,
|
||||||
input wire [7:0] cram_addr_in,
|
input wire [7:0] cram_addr_in,
|
||||||
input wire cram_we,
|
input wire cram_we,
|
||||||
|
|
||||||
// video data
|
// video data
|
||||||
input wire [7:0] vplex_in, //<====== INPUT
|
input wire [7:0] vplex_in,
|
||||||
input wire [7:0] vgaplex, //<====== INPUT VGA
|
input wire [7:0] vgaplex,
|
||||||
|
|
||||||
output wire [7:0] vred,
|
output wire [7:0] vred,
|
||||||
output wire [7:0] vgrn,
|
output wire [7:0] vgrn,
|
||||||
output wire [7:0] vblu,
|
output wire [7:0] vblu,
|
||||||
//---------------------
|
output wire vdac_mode
|
||||||
output wire [3:0] tst
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assign tst[0] = clk; ////phase[0];
|
|
||||||
assign tst[1] = cram_we; //phase[1];
|
|
||||||
assign tst[2] = cram_addr_in[0]; //
|
|
||||||
assign tst[3] = cram_data_in[0]; //pwm[3][{phase, 1'b0}]; //!pwm[igrn][{phase, 1'b1}];
|
|
||||||
|
|
||||||
|
|
||||||
// TV/VGA mux
|
// TV/VGA mux
|
||||||
reg [7:0] vplex;
|
reg [7:0] vplex;
|
||||||
always @(posedge clk) if (c3) vplex <= vplex_in;
|
always @(posedge clk) if (c3) vplex <= vplex_in;
|
||||||
|
|
||||||
wire [7:0] plex = vga_on ? vgaplex : vplex;
|
wire [7:0] plex = vga_on ? vgaplex : vplex;
|
||||||
wire plex_sel = vga_on ? plex_sel_in[0] : plex_sel_in[1];
|
wire plex_sel = vga_on ? plex_sel_in[0] : plex_sel_in[1];
|
||||||
wire hires = vga_on ? vga_hires : tv_hires;
|
wire hires = vga_on ? vga_hires : tv_hires;
|
||||||
wire [7:0] vdata = hires ? {palsel, plex_sel ? plex[3:0] : plex[7:4]} : plex;
|
wire [7:0] vdata = hires ? {palsel, plex_sel ? plex[3:0] : plex[7:4]} : plex;
|
||||||
|
|
||||||
// CRAM =====================================================================
|
|
||||||
wire [14:0] vpixel;
|
|
||||||
|
|
||||||
dpram #(.DATAWIDTH(15), .ADDRWIDTH(8), .MEM_INIT_FILE("src/video/video_cram.mif")) video_cram
|
// CRAM
|
||||||
|
wire [15:0] vpixel;
|
||||||
|
dpram #(.DATAWIDTH(16), .ADDRWIDTH(8), .MEM_INIT_FILE("src/video/video_cram.mif")) video_cram
|
||||||
(
|
(
|
||||||
.clock (clk),
|
.clock (clk),
|
||||||
.address_a(cram_addr_in),
|
.address_a(cram_addr_in),
|
||||||
.data_a (cram_data_in),
|
.data_a (cram_data_in),
|
||||||
.wren_a (cram_we),
|
.wren_a (cram_we),
|
||||||
.address_b(vdata), //-<INPUT
|
.address_b(vdata),
|
||||||
.q_b (vpixel)
|
.q_b (vpixel)
|
||||||
);
|
);
|
||||||
|
|
||||||
//=============VPIXEL=================================
|
|
||||||
|
|
||||||
reg blank;
|
reg blank;
|
||||||
always @(posedge clk) blank <= vga_on ? vga_blank : tv_blank;
|
always @(posedge clk) blank <= vga_on ? vga_blank : tv_blank;
|
||||||
|
|
||||||
wire [14:0] vpix = blank ? 15'b0 : vpixel; //OK for Spectrum mode // 5 bits for every color
|
wire [14:0] vpix = blank ? 15'b0 : vpixel[14:0];
|
||||||
|
|
||||||
assign vred = {vpix[14:10], vpix[14:12]};
|
assign vred = {vpix[14:10], vpix[14:12]};
|
||||||
assign vgrn = {vpix[ 9: 5], vpix[ 9: 7]};
|
assign vgrn = {vpix[ 9: 5], vpix[ 9: 7]};
|
||||||
assign vblu = {vpix[ 4: 0], vpix[ 4: 2]};
|
assign vblu = {vpix[ 4: 0], vpix[ 4: 2]};
|
||||||
|
assign vdac_mode = vpixel[15];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -1,44 +1,45 @@
|
|||||||
// This module latches all port parameters for video from Z80
|
// This module latches all port parameters for video from Z80
|
||||||
|
|
||||||
module video_ports (
|
|
||||||
|
|
||||||
// clocks
|
module video_ports
|
||||||
|
(
|
||||||
|
// clocks
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
input wire [ 7:0] d,
|
input wire [ 7:0] d,
|
||||||
input wire res,
|
input wire res,
|
||||||
input wire int_start,
|
input wire int_start,
|
||||||
input wire line_start_s,
|
input wire line_start_s,
|
||||||
|
|
||||||
// port write strobes
|
// port write strobes
|
||||||
input wire zborder_wr,
|
input wire zborder_wr,
|
||||||
input wire border_wr,
|
input wire border_wr,
|
||||||
input wire zvpage_wr,
|
input wire zvpage_wr,
|
||||||
input wire vpage_wr,
|
input wire vpage_wr,
|
||||||
input wire vconf_wr,
|
input wire vconf_wr,
|
||||||
input wire gx_offsl_wr,
|
input wire gx_offsl_wr,
|
||||||
input wire gx_offsh_wr,
|
input wire gx_offsh_wr,
|
||||||
input wire gy_offsl_wr,
|
input wire gy_offsl_wr,
|
||||||
input wire gy_offsh_wr,
|
input wire gy_offsh_wr,
|
||||||
input wire t0x_offsl_wr,
|
input wire t0x_offsl_wr,
|
||||||
input wire t0x_offsh_wr,
|
input wire t0x_offsh_wr,
|
||||||
input wire t0y_offsl_wr,
|
input wire t0y_offsl_wr,
|
||||||
input wire t0y_offsh_wr,
|
input wire t0y_offsh_wr,
|
||||||
input wire t1x_offsl_wr,
|
input wire t1x_offsl_wr,
|
||||||
input wire t1x_offsh_wr,
|
input wire t1x_offsh_wr,
|
||||||
input wire t1y_offsl_wr,
|
input wire t1y_offsl_wr,
|
||||||
input wire t1y_offsh_wr,
|
input wire t1y_offsh_wr,
|
||||||
input wire tsconf_wr,
|
input wire tsconf_wr,
|
||||||
input wire palsel_wr,
|
input wire palsel_wr,
|
||||||
input wire tmpage_wr,
|
input wire tmpage_wr,
|
||||||
input wire t0gpage_wr,
|
input wire t0gpage_wr,
|
||||||
input wire t1gpage_wr,
|
input wire t1gpage_wr,
|
||||||
input wire sgpage_wr,
|
input wire sgpage_wr,
|
||||||
input wire hint_beg_wr ,
|
input wire hint_beg_wr ,
|
||||||
input wire vint_begl_wr,
|
input wire vint_begl_wr,
|
||||||
input wire vint_begh_wr,
|
input wire vint_begh_wr,
|
||||||
|
|
||||||
// video parameters
|
// video parameters
|
||||||
output reg [7:0] border,
|
output reg [7:0] border,
|
||||||
output reg [7:0] vpage,
|
output reg [7:0] vpage,
|
||||||
output reg [7:0] vconf,
|
output reg [7:0] vconf,
|
||||||
@ -56,118 +57,93 @@ module video_ports (
|
|||||||
output reg [7:0] t0gpage,
|
output reg [7:0] t0gpage,
|
||||||
output reg [7:0] t1gpage,
|
output reg [7:0] t1gpage,
|
||||||
output reg [7:0] sgpage
|
output reg [7:0] sgpage
|
||||||
|
);
|
||||||
|
|
||||||
);
|
reg [7:0] vpage_r;
|
||||||
|
reg [7:0] vconf_r;
|
||||||
|
reg [7:0] t0gpage_r;
|
||||||
|
reg [7:0] t1gpage_r;
|
||||||
|
reg [8:0] gx_offs_r;
|
||||||
|
reg [8:0] t0x_offs_r;
|
||||||
|
reg [8:0] t1x_offs_r;
|
||||||
|
reg [7:0] palsel_r;
|
||||||
|
|
||||||
reg [7:0] vpage_r;
|
wire [8:0] vint_beg_inc = vint_beg + vint_inc;
|
||||||
reg [7:0] vconf_r;
|
wire [8:0] vint_beg_next = {(vint_beg_inc[8:6] == 3'b101) ? 3'b0 : vint_beg_inc[8:6], vint_beg_inc[5:0]}; // if over 319 lines, decrement 320
|
||||||
reg [7:0] t0gpage_r;
|
|
||||||
reg [7:0] t1gpage_r;
|
|
||||||
reg [8:0] gx_offs_r;
|
|
||||||
reg [8:0] t0x_offs_r;
|
|
||||||
reg [8:0] t1x_offs_r;
|
|
||||||
reg [7:0] palsel_r;
|
|
||||||
|
|
||||||
wire [8:0] vint_beg_inc = vint_beg + vint_inc;
|
reg [3:0] vint_inc;
|
||||||
wire [8:0] vint_beg_next = {(vint_beg_inc[8:6] == 3'b101) ? 3'b0 : vint_beg_inc[8:6], vint_beg_inc[5:0]}; // if over 319 lines, decrement 320
|
always @(posedge clk) begin
|
||||||
reg [3:0] vint_inc;
|
if (res) begin
|
||||||
always @(posedge clk)
|
vint_beg <= 9'd0;
|
||||||
if (res)
|
vint_inc <= 4'b0;
|
||||||
begin
|
end
|
||||||
vint_beg <= 9'd0;
|
else if (vint_begl_wr) vint_beg[7:0] <= d;
|
||||||
vint_inc <= 4'b0;
|
else if (vint_begh_wr) begin
|
||||||
end
|
vint_beg[8] <= d[0];
|
||||||
|
vint_inc <= d[7:4];
|
||||||
|
end
|
||||||
|
else if (int_start) vint_beg <= vint_beg_next;
|
||||||
|
end
|
||||||
|
|
||||||
else if (vint_begl_wr)
|
always @(posedge clk) begin
|
||||||
vint_beg[7:0] <= d;
|
if (res) begin
|
||||||
//vint_beg[7:0] <= 8'd0; //--- мигает vint_beg[8] <= 1'b0; //----
|
vpage_r <= 8'h05;
|
||||||
//vint_beg[7:0] <= 8'd10; //---мигает vint_beg[8] <= 1'b0; //----
|
vconf_r <= 8'h00;
|
||||||
//vint_beg[7:0] <= 8'd20; //---мигает vint_beg[8] <= 1'b0; //----
|
gx_offs_r <= 9'b0;
|
||||||
//vint_beg[7:0] <= 8'd50;--- нет картинки
|
palsel_r <= 8'h0F;
|
||||||
//vint_beg[7:0] <= 8'd255;
|
gy_offs <= 9'b0;
|
||||||
|
tsconf <= 8'b0;
|
||||||
else if (vint_begh_wr)
|
hint_beg <= 8'd1;
|
||||||
begin
|
end
|
||||||
vint_beg[8] <= d[0];
|
else begin
|
||||||
//vint_beg[8] <= 1'b0; //----
|
if (zborder_wr ) border <= {palsel[3:0], 1'b0, d[2:0]};
|
||||||
vint_inc <= d[7:4];
|
if (border_wr ) border <= d;
|
||||||
end
|
if (gy_offsl_wr ) gy_offs[7:0] <= d;
|
||||||
|
if (gy_offsh_wr ) gy_offs[8] <= d[0];
|
||||||
else if (int_start)
|
if (t0y_offsl_wr) t0y_offs[7:0] <= d;
|
||||||
vint_beg <= vint_beg_next;
|
if (t0y_offsh_wr) t0y_offs[8] <= d[0];
|
||||||
|
if (t1y_offsl_wr) t1y_offs[7:0] <= d;
|
||||||
always @(posedge clk)
|
if (t1y_offsh_wr) t1y_offs[8] <= d[0];
|
||||||
if (res)
|
if (tsconf_wr ) tsconf <= d;
|
||||||
begin
|
if (tmpage_wr ) tmpage <= d;
|
||||||
vpage_r <= 8'h05;
|
if (sgpage_wr ) sgpage <= d;
|
||||||
vconf_r <= 8'h00;
|
if (hint_beg_wr ) hint_beg <= d;
|
||||||
gx_offs_r <= 9'b0;
|
|
||||||
palsel_r <= 8'h0F;
|
|
||||||
gy_offs <= 9'b0;
|
|
||||||
tsconf <= 8'b0;
|
|
||||||
hint_beg <= 8'd1;
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if (zborder_wr ) border <= {5'b11110, d[2:0]};
|
|
||||||
if (border_wr ) border <= d;
|
|
||||||
if (gy_offsl_wr ) gy_offs[7:0] <= d;
|
|
||||||
if (gy_offsh_wr ) gy_offs[8] <= d[0];
|
|
||||||
if (t0y_offsl_wr) t0y_offs[7:0] <= d;
|
|
||||||
if (t0y_offsh_wr) t0y_offs[8] <= d[0];
|
|
||||||
if (t1y_offsl_wr) t1y_offs[7:0] <= d;
|
|
||||||
if (t1y_offsh_wr) t1y_offs[8] <= d[0];
|
|
||||||
if (tsconf_wr ) tsconf <= d;
|
|
||||||
if (tmpage_wr ) tmpage <= d;
|
|
||||||
if (sgpage_wr ) sgpage <= d;
|
|
||||||
if (hint_beg_wr ) hint_beg <= d;
|
|
||||||
|
|
||||||
if (zvpage_wr ) vpage_r <= {6'b000001, d[3], 1'b1};
|
|
||||||
if (vpage_wr ) vpage_r <= d;
|
|
||||||
if (vconf_wr ) vconf_r <= d;
|
|
||||||
if (gx_offsl_wr ) gx_offs_r[7:0] <= d;
|
|
||||||
if (gx_offsh_wr ) gx_offs_r[8] <= d[0];
|
|
||||||
if (palsel_wr ) palsel_r <= d;
|
|
||||||
if (t0x_offsl_wr) t0x_offs_r[7:0] <= d;
|
|
||||||
if (t0x_offsh_wr) t0x_offs_r[8] <= d[0];
|
|
||||||
if (t1x_offsl_wr) t1x_offs_r[7:0] <= d;
|
|
||||||
if (t1x_offsh_wr) t1x_offs_r[8] <= d[0];
|
|
||||||
if (t0gpage_wr ) t0gpage_r <= d;
|
|
||||||
if (t1gpage_wr ) t1gpage_r <= d;
|
|
||||||
// if (t0x_offsl_wr) t0x_offs[7:0] <= d;
|
|
||||||
// if (t0x_offsh_wr) t0x_offs[8] <= d[0];
|
|
||||||
// if (t1x_offsl_wr) t1x_offs[7:0] <= d;
|
|
||||||
// if (t1x_offsh_wr) t1x_offs[8] <= d[0];
|
|
||||||
// if (t0gpage_wr ) t0gpage <= d;
|
|
||||||
// if (t1gpage_wr ) t1gpage <= d;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if (zvpage_wr ) vpage_r <= {6'b000001, d[3], 1'b1};
|
||||||
|
if (vpage_wr ) vpage_r <= d;
|
||||||
|
if (vconf_wr ) vconf_r <= d;
|
||||||
|
if (gx_offsl_wr ) gx_offs_r[7:0] <= d;
|
||||||
|
if (gx_offsh_wr ) gx_offs_r[8] <= d[0];
|
||||||
|
if (palsel_wr ) palsel_r <= d;
|
||||||
|
if (t0x_offsl_wr) t0x_offs_r[7:0] <= d;
|
||||||
|
if (t0x_offsh_wr) t0x_offs_r[8] <= d[0];
|
||||||
|
if (t1x_offsl_wr) t1x_offs_r[7:0] <= d;
|
||||||
|
if (t1x_offsh_wr) t1x_offs_r[8] <= d[0];
|
||||||
|
if (t0gpage_wr ) t0gpage_r <= d;
|
||||||
|
if (t1gpage_wr ) t1gpage_r <= d;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// latching regs at line start, delaying hires for 1 line
|
// latching regs at line start, delaying hires for 1 line
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
if (res)
|
if (res)
|
||||||
begin
|
begin
|
||||||
vpage <= 8'h05;
|
vpage <= 8'h05;
|
||||||
vconf <= 8'h00;
|
vconf <= 8'h00;
|
||||||
gx_offs <= 9'b0;
|
gx_offs <= 9'b0;
|
||||||
palsel <= 8'h0F;
|
palsel <= 8'h0F;
|
||||||
end
|
end
|
||||||
|
else if (zvpage_wr) vpage <= {6'b000001, d[3], 1'b1};
|
||||||
|
else if (line_start_s) begin
|
||||||
|
vpage <= vpage_r;
|
||||||
|
vconf <= vconf_r;
|
||||||
|
gx_offs <= gx_offs_r;
|
||||||
|
palsel <= palsel_r;
|
||||||
|
t0x_offs <= t0x_offs_r;
|
||||||
|
t1x_offs <= t1x_offs_r;
|
||||||
|
t0gpage <= t0gpage_r;
|
||||||
|
t1gpage <= t1gpage_r;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
else if (zvpage_wr)
|
endmodule
|
||||||
vpage <= {6'b000001, d[3], 1'b1};
|
|
||||||
|
|
||||||
else if (line_start_s)
|
|
||||||
begin
|
|
||||||
vpage <= vpage_r;
|
|
||||||
vconf <= vconf_r;
|
|
||||||
gx_offs <= gx_offs_r;
|
|
||||||
palsel <= palsel_r;
|
|
||||||
t0x_offs <= t0x_offs_r;
|
|
||||||
t1x_offs <= t1x_offs_r;
|
|
||||||
t0gpage <= t0gpage_r;
|
|
||||||
t1gpage <= t1gpage_r;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
// This module renders video data for output
|
// This module renders video data for output
|
||||||
|
|
||||||
module video_render (
|
module video_render
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk, c1,
|
input wire clk, c1,
|
||||||
|
|
||||||
// video controls
|
// video controls
|
||||||
input wire hvpix,
|
input wire hvpix,
|
||||||
|
input wire hvtspix,
|
||||||
input wire nogfx,
|
input wire nogfx,
|
||||||
input wire notsu,
|
input wire notsu,
|
||||||
input wire gfxovr,
|
input wire gfxovr,
|
||||||
@ -15,71 +16,69 @@ module video_render (
|
|||||||
input wire [3:0] psel,
|
input wire [3:0] psel,
|
||||||
input wire [3:0] palsel,
|
input wire [3:0] palsel,
|
||||||
|
|
||||||
// mode controls
|
// mode controls
|
||||||
input wire [1:0] render_mode,
|
input wire [1:0] render_mode,
|
||||||
|
|
||||||
// video data
|
// video data
|
||||||
input wire [31:0] data,
|
input wire [31:0] data,
|
||||||
input wire [ 7:0] border_in,
|
input wire [ 7:0] border_in,
|
||||||
input wire [ 7:0] tsdata_in,
|
input wire [ 7:0] tsdata_in,
|
||||||
output wire [ 7:0] vplex_out
|
output wire [ 7:0] vplex_out
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam R_ZX = 2'h0;
|
localparam R_ZX = 2'h0;
|
||||||
localparam R_HC = 2'h1;
|
localparam R_HC = 2'h1;
|
||||||
localparam R_XC = 2'h2;
|
localparam R_XC = 2'h2;
|
||||||
localparam R_TX = 2'h3;
|
localparam R_TX = 2'h3;
|
||||||
|
|
||||||
// ZX graphics
|
// ZX graphics
|
||||||
wire [15:0] zx_gfx = data[15: 0];
|
wire [15:0] zx_gfx = data[15: 0];
|
||||||
wire [15:0] zx_atr = data[31:16];
|
wire [15:0] zx_atr = data[31:16];
|
||||||
wire zx_dot = zx_gfx[{psel[3], ~psel[2:0]}];
|
wire zx_dot = zx_gfx[{psel[3], ~psel[2:0]}];
|
||||||
wire [7:0] zx_attr = ~psel[3] ? zx_atr[7:0] : zx_atr[15:8];
|
wire [7:0] zx_attr = ~psel[3] ? zx_atr[7:0] : zx_atr[15:8];
|
||||||
wire [7:0] zx_pix = {palsel, zx_attr[6], zx_dot ^ (flash & zx_attr[7]) ? zx_attr[2:0] : zx_attr[5:3]};
|
wire [7:0] zx_pix = {palsel, zx_attr[6], zx_dot ^ (flash & zx_attr[7]) ? zx_attr[2:0] : zx_attr[5:3]};
|
||||||
|
|
||||||
// text graphics
|
// text graphics
|
||||||
// (it uses common renderer with ZX, but different attributes)
|
// (it uses common renderer with ZX, but different attributes)
|
||||||
wire [7:0] tx_pix = {palsel, zx_dot ? zx_attr[3:0] : zx_attr[7:4]};
|
wire [7:0] tx_pix = {palsel, zx_dot ? zx_attr[3:0] : zx_attr[7:4]};
|
||||||
|
|
||||||
// 16c graphics
|
// 16c graphics
|
||||||
wire [3:0] hc_dot[0:3];
|
wire [3:0] hc_dot[0:3];
|
||||||
assign hc_dot[0] = data[ 7: 4];
|
assign hc_dot[0] = data[ 7: 4];
|
||||||
assign hc_dot[1] = data[ 3: 0];
|
assign hc_dot[1] = data[ 3: 0];
|
||||||
assign hc_dot[2] = data[15:12];
|
assign hc_dot[2] = data[15:12];
|
||||||
assign hc_dot[3] = data[11: 8];
|
assign hc_dot[3] = data[11: 8];
|
||||||
wire [7:0] hc_pix = {palsel, hc_dot[psel[1:0]]};
|
wire [7:0] hc_pix = {palsel, hc_dot[psel[1:0]]};
|
||||||
|
|
||||||
// 256c graphics
|
// 256c graphics
|
||||||
wire [7:0] xc_dot[0:1];
|
wire [7:0] xc_dot[0:1];
|
||||||
assign xc_dot[0] = data[ 7: 0];
|
assign xc_dot[0] = data[ 7: 0];
|
||||||
assign xc_dot[1] = data[15: 8];
|
assign xc_dot[1] = data[15: 8];
|
||||||
wire [7:0] xc_pix = xc_dot[psel[0]];
|
wire [7:0] xc_pix = xc_dot[psel[0]];
|
||||||
|
|
||||||
// mode selects
|
// mode selects
|
||||||
wire [7:0] pix[0:3];
|
wire [7:0] pix[0:3];
|
||||||
assign pix[R_ZX] = zx_pix; // ZX
|
assign pix[R_ZX] = zx_pix; // ZX
|
||||||
assign pix[R_HC] = hc_pix; // 16c
|
assign pix[R_HC] = hc_pix; // 16c
|
||||||
assign pix[R_XC] = xc_pix; // 256c
|
assign pix[R_XC] = xc_pix; // 256c
|
||||||
assign pix[R_TX] = tx_pix; // text
|
assign pix[R_TX] = tx_pix; // text
|
||||||
|
|
||||||
wire pixv[0:3];
|
wire pixv[0:3];
|
||||||
assign pixv[R_ZX] = zx_dot ^ (flash & zx_attr[7]);
|
assign pixv[R_ZX] = zx_dot ^ (flash & zx_attr[7]);
|
||||||
assign pixv[R_HC] = |hc_dot[psel[1:0]];
|
assign pixv[R_HC] = |hc_dot[psel[1:0]];
|
||||||
assign pixv[R_XC] = |xc_dot[psel[0]];
|
assign pixv[R_XC] = |xc_dot[psel[0]];
|
||||||
assign pixv[R_TX] = zx_dot;
|
assign pixv[R_TX] = zx_dot;
|
||||||
|
|
||||||
// video plex muxer
|
// video plex muxer
|
||||||
wire tsu_visible = (|tsdata_in[3:0] && !notsu);
|
wire tsu_visible = (|tsdata_in[3:0] && !notsu);
|
||||||
wire gfx_visible = (pixv[render_mode] && !nogfx);
|
wire gfx_visible = (pixv[render_mode] && !nogfx);
|
||||||
wire [7:0] video1 = tsu_visible ? tsdata_in : (nogfx ? border_in : pix[render_mode]);
|
wire [7:0] video1 = tsu_visible ? tsdata_in : (nogfx ? border_in : pix[render_mode]);
|
||||||
wire [7:0] video2 = gfx_visible ? pix[render_mode] : (tsu_visible ? tsdata_in : border_in);
|
wire [7:0] video2 = gfx_visible ? pix[render_mode] : (tsu_visible ? tsdata_in : border_in);
|
||||||
wire [7:0] video = !hvpix ? border_in : (gfxovr ? video2 : video1);
|
wire [7:0] video = hvpix ? (gfxovr ? video2 : video1) : ((hvtspix && tsu_visible) ? tsdata_in : border_in);
|
||||||
assign vplex_out = hires ? {temp, video[3:0]} : video; // in hi-res plex contains two pixels 4 bits each
|
assign vplex_out = hires ? {temp, video[3:0]} : video; // in hi-res plex contains two pixels 4 bits each
|
||||||
|
|
||||||
reg [3:0] temp;
|
reg [3:0] temp;
|
||||||
always @(posedge clk) if (c1)
|
always @(posedge clk) if (c1) temp <= video[3:0];
|
||||||
temp <= video[3:0];
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -2,29 +2,33 @@
|
|||||||
// This module generates all video raster signals
|
// This module generates all video raster signals
|
||||||
|
|
||||||
|
|
||||||
module video_sync (
|
module video_sync
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk, f1, c0, c1, c3, pix_stb,
|
input wire clk, f1, c0, c1, c3, pix_stb,
|
||||||
|
|
||||||
// video parameters
|
// video parameters
|
||||||
input wire [8:0] hpix_beg,
|
input wire [8:0] hpix_beg,
|
||||||
input wire [8:0] hpix_end,
|
input wire [8:0] hpix_end,
|
||||||
input wire [8:0] vpix_beg,
|
input wire [8:0] vpix_beg,
|
||||||
input wire [8:0] vpix_end,
|
input wire [8:0] vpix_end,
|
||||||
|
input wire [8:0] hpix_beg_ts,
|
||||||
|
input wire [8:0] hpix_end_ts,
|
||||||
|
input wire [8:0] vpix_beg_ts,
|
||||||
|
input wire [8:0] vpix_end_ts,
|
||||||
input wire [4:0] go_offs,
|
input wire [4:0] go_offs,
|
||||||
input wire [1:0] x_offs,
|
input wire [1:0] x_offs,
|
||||||
input wire [7:0] hint_beg,
|
input wire [7:0] hint_beg,
|
||||||
input wire [8:0] vint_beg,
|
input wire [8:0] vint_beg,
|
||||||
input wire [7:0] cstart,
|
input wire [7:0] cstart,
|
||||||
input wire [8:0] rstart,
|
input wire [8:0] rstart,
|
||||||
|
|
||||||
// video syncs
|
// video syncs
|
||||||
output reg hsync,
|
output reg hsync,
|
||||||
output reg vsync,
|
output reg vsync,
|
||||||
output reg csync,
|
output reg csync,
|
||||||
|
|
||||||
// video controls
|
// video controls
|
||||||
input wire cfg_60hz,
|
input wire cfg_60hz,
|
||||||
input wire sync_pol,
|
input wire sync_pol,
|
||||||
input wire vga_on,
|
input wire vga_on,
|
||||||
@ -35,6 +39,7 @@ module video_sync (
|
|||||||
output wire vpix,
|
output wire vpix,
|
||||||
output wire v_ts,
|
output wire v_ts,
|
||||||
output wire hvpix,
|
output wire hvpix,
|
||||||
|
output wire hvtspix,
|
||||||
output wire tv_hblank,
|
output wire tv_hblank,
|
||||||
output wire tv_vblank,
|
output wire tv_vblank,
|
||||||
output reg vga_hblank,
|
output reg vga_hblank,
|
||||||
@ -47,7 +52,7 @@ module video_sync (
|
|||||||
output wire frame,
|
output wire frame,
|
||||||
output wire flash,
|
output wire flash,
|
||||||
|
|
||||||
// video counters
|
// video counters
|
||||||
output wire [9:0] vga_cnt_in,
|
output wire [9:0] vga_cnt_in,
|
||||||
output wire [9:0] vga_cnt_out,
|
output wire [9:0] vga_cnt_out,
|
||||||
output wire [8:0] ts_raddr,
|
output wire [8:0] ts_raddr,
|
||||||
@ -57,172 +62,152 @@ module video_sync (
|
|||||||
output reg cptr,
|
output reg cptr,
|
||||||
output reg [3:0] scnt,
|
output reg [3:0] scnt,
|
||||||
|
|
||||||
// DRAM
|
// DRAM
|
||||||
input wire video_pre_next,
|
input wire video_pre_next,
|
||||||
output reg video_go,
|
output reg video_go,
|
||||||
|
|
||||||
// ZX controls
|
// ZX controls
|
||||||
input wire y_offs_wr,
|
input wire y_offs_wr,
|
||||||
output wire int_start
|
output wire int_start
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam HSYNC_BEG = 9'd11;
|
localparam HSYNC_BEG = 9'd11;
|
||||||
localparam HSYNC_END = 9'd43;
|
localparam HSYNC_END = 9'd43;
|
||||||
localparam HBLNK_BEG = 9'd00;
|
localparam HBLNK_BEG = 9'd00;
|
||||||
localparam HBLNK_END = 9'd88;
|
localparam HBLNK_END = 9'd88;
|
||||||
localparam HSYNCV_BEG = 9'd5;
|
localparam HSYNCV_BEG = 9'd5;
|
||||||
localparam HSYNCV_END = 9'd31;
|
localparam HSYNCV_END = 9'd31;
|
||||||
localparam HBLNKV_END = 9'd42;
|
localparam HBLNKV_END = 9'd42;
|
||||||
localparam HPERIOD = 9'd448;
|
localparam HPERIOD = 9'd448;
|
||||||
|
|
||||||
localparam VSYNC_BEG_50 = 9'd08;
|
localparam VSYNC_BEG_50 = 9'd08;
|
||||||
localparam VSYNC_END_50 = 9'd11;
|
localparam VSYNC_END_50 = 9'd11;
|
||||||
localparam VBLNK_BEG_50 = 9'd00;
|
localparam VBLNK_BEG_50 = 9'd00;
|
||||||
localparam VBLNK_END_50 = 9'd32;
|
localparam VBLNK_END_50 = 9'd32;
|
||||||
localparam VPERIOD_50 = 9'd320;
|
localparam VPERIOD_50 = 9'd320;
|
||||||
|
|
||||||
localparam VSYNC_BEG_60 = 9'd04;
|
localparam VSYNC_BEG_60 = 9'd04;
|
||||||
localparam VSYNC_END_60 = 9'd07;
|
localparam VSYNC_END_60 = 9'd07;
|
||||||
localparam VBLNK_BEG_60 = 9'd00;
|
localparam VBLNK_BEG_60 = 9'd00;
|
||||||
localparam VBLNK_END_60 = 9'd22;
|
localparam VBLNK_END_60 = 9'd22;
|
||||||
localparam VPERIOD_60 = 9'd262;
|
localparam VPERIOD_60 = 9'd262;
|
||||||
|
|
||||||
wire [8:0] vsync_beg = v60hz ? VSYNC_BEG_60 : VSYNC_BEG_50;
|
wire [8:0] vsync_beg = v60hz ? VSYNC_BEG_60 : VSYNC_BEG_50;
|
||||||
wire [8:0] vsync_end = v60hz ? VSYNC_END_60 : VSYNC_END_50;
|
wire [8:0] vsync_end = v60hz ? VSYNC_END_60 : VSYNC_END_50;
|
||||||
wire [8:0] vblnk_beg = v60hz ? VBLNK_BEG_60 : VBLNK_BEG_50;
|
wire [8:0] vblnk_beg = v60hz ? VBLNK_BEG_60 : VBLNK_BEG_50;
|
||||||
wire [8:0] vblnk_end = v60hz ? VBLNK_END_60 : VBLNK_END_50;
|
wire [8:0] vblnk_end = v60hz ? VBLNK_END_60 : VBLNK_END_50;
|
||||||
wire [8:0] vperiod = v60hz ? VPERIOD_60 : VPERIOD_50;
|
wire [8:0] vperiod = v60hz ? VPERIOD_60 : VPERIOD_50;
|
||||||
|
|
||||||
// counters
|
// counters
|
||||||
reg [8:0] hcount = 0;
|
reg [8:0] hcount = 0;
|
||||||
reg [8:0] vcount = 0;
|
reg [8:0] vcount = 0;
|
||||||
reg [8:0] cnt_out = 0;
|
reg [8:0] cnt_out = 0;
|
||||||
|
|
||||||
// horizontal TV (7 MHz)
|
// horizontal TV (7 MHz)
|
||||||
always @(posedge clk) if (c3)
|
always @(posedge clk) if (c3) hcount <= line_start ? 9'b0 : hcount + 9'b1;
|
||||||
hcount <= line_start ? 9'b0 : hcount + 9'b1;
|
|
||||||
|
|
||||||
// vertical TV (15.625 kHz)
|
// vertical TV (15.625 kHz)
|
||||||
always @(posedge clk) if (line_start_s)
|
always @(posedge clk) if (line_start_s) vcount <= (vcount == (vperiod - 1)) ? 9'b0 : vcount + 9'b1;
|
||||||
vcount <= (vcount == (vperiod - 1)) ? 9'b0 : vcount + 9'b1;
|
|
||||||
|
|
||||||
// horizontal VGA (14MHz)
|
// horizontal VGA (14MHz)
|
||||||
always @(posedge clk) if (f1)
|
always @(posedge clk) if (f1) cnt_out <= vga_pix_start && c3 ? 9'b0 : cnt_out + 9'b1;
|
||||||
cnt_out <= vga_pix_start && c3 ? 9'b0 : cnt_out + 9'b1;
|
|
||||||
|
|
||||||
// column address for DRAM
|
// column address for DRAM
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
begin
|
if (line_start2) begin
|
||||||
if (line_start2)
|
cnt_col <= cstart;
|
||||||
begin
|
cptr <= 1'b0;
|
||||||
cnt_col <= cstart;
|
end
|
||||||
cptr <= 1'b0;
|
else if (video_pre_next) begin
|
||||||
end
|
cnt_col <= cnt_col + 8'b1;
|
||||||
|
cptr <= ~cptr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
else
|
// row address for DRAM
|
||||||
if (video_pre_next)
|
always @(posedge clk) begin if (c3)
|
||||||
begin
|
if (vis_start || (line_start && y_offs_wr_r)) cnt_row <= rstart;
|
||||||
cnt_col <= cnt_col + 8'b1;
|
else if (line_start && vpix) cnt_row <= cnt_row + 9'b1;
|
||||||
cptr <= ~cptr;
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
// row address for DRAM
|
// pixel counter
|
||||||
always @(posedge clk) if (c3)
|
always @(posedge clk) if (pix_stb) scnt <= pix_start ? 4'b0 : scnt + 4'b1; // f1 or c3
|
||||||
if (vis_start || (line_start && y_offs_wr_r))
|
|
||||||
cnt_row <= rstart;
|
assign vga_cnt_in = {vcount[0], hcount - HBLNK_END};
|
||||||
else
|
assign vga_cnt_out = {~vcount[0], cnt_out};
|
||||||
if (line_start && vpix)
|
|
||||||
cnt_row <= cnt_row + 9'b1;
|
|
||||||
|
|
||||||
|
|
||||||
// pixel counter
|
// TS-line counter
|
||||||
always @(posedge clk) if (pix_stb) // f1 or c3
|
assign ts_raddr = hcount - hpix_beg_ts;
|
||||||
scnt <= pix_start ? 4'b0 : scnt + 4'b1;
|
|
||||||
|
|
||||||
assign vga_cnt_in = {vcount[0], hcount - HBLNK_END};
|
|
||||||
assign vga_cnt_out = {~vcount[0], cnt_out};
|
|
||||||
|
|
||||||
|
|
||||||
// TS-line counter
|
|
||||||
assign ts_raddr = hcount - hpix_beg;
|
|
||||||
|
|
||||||
always @(posedge clk)
|
|
||||||
if (ts_start_coarse)
|
|
||||||
lcount <= vcount - vpix_beg + 9'b1;
|
|
||||||
|
|
||||||
|
always @(posedge clk) if (ts_start_coarse) lcount <= vcount - vpix_beg_ts + 9'b1;
|
||||||
|
|
||||||
// Y offset re-latch trigger
|
// Y offset re-latch trigger
|
||||||
reg y_offs_wr_r;
|
reg y_offs_wr_r;
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
if (y_offs_wr)
|
if (y_offs_wr) y_offs_wr_r <= 1'b1;
|
||||||
y_offs_wr_r <= 1'b1;
|
else if (line_start_s) y_offs_wr_r <= 1'b0;
|
||||||
else
|
end
|
||||||
if (line_start_s)
|
|
||||||
y_offs_wr_r <= 1'b0;
|
|
||||||
|
|
||||||
// FLASH generator
|
// FLASH generator
|
||||||
reg [4:0] flash_ctr;
|
reg [4:0] flash_ctr;
|
||||||
assign frame = flash_ctr[0];
|
assign frame = flash_ctr[0];
|
||||||
assign flash = flash_ctr[4];
|
assign flash = flash_ctr[4];
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
if (frame_start && c3)
|
if (frame_start && c3) begin
|
||||||
begin
|
v60hz <= !cfg_60hz; // re-sync of 60Hz mode selector
|
||||||
v60hz <= !cfg_60hz; // re-sync of 60Hz mode selector
|
flash_ctr <= flash_ctr + 5'b1;
|
||||||
flash_ctr <= flash_ctr + 5'b1;
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
// sync strobes
|
// sync strobes
|
||||||
wire hs = (hcount >= HSYNC_BEG) && (hcount < HSYNC_END);
|
wire hs = (hcount >= HSYNC_BEG) && (hcount < HSYNC_END);
|
||||||
wire vs = (vcount >= vsync_beg) && (vcount < vsync_end);
|
wire vs = (vcount >= vsync_beg) && (vcount < vsync_end);
|
||||||
|
|
||||||
assign tv_hblank = (hcount > HBLNK_BEG) && (hcount <= HBLNK_END);
|
assign tv_hblank = (hcount > HBLNK_BEG) && (hcount <= HBLNK_END);
|
||||||
assign tv_vblank = (vcount >= vblnk_beg) && (vcount < vblnk_end);
|
assign tv_vblank = (vcount >= vblnk_beg) && (vcount < vblnk_end);
|
||||||
|
|
||||||
wire vga_hblank1 = (cnt_out > 9'd359);
|
wire vga_hblank1 = (cnt_out > 9'd359);
|
||||||
always @(posedge clk) if (f1) // fix me - bydlocode !!!
|
always @(posedge clk) if (f1) vga_hblank <= vga_hblank1;
|
||||||
vga_hblank <= vga_hblank1;
|
|
||||||
|
|
||||||
wire hs_vga = ((hcount >= HSYNCV_BEG) && (hcount < HSYNCV_END)) ||
|
wire hs_vga = ((hcount >= HSYNCV_BEG) && (hcount < HSYNCV_END)) ||
|
||||||
((hcount >= (HSYNCV_BEG + HPERIOD/2)) && (hcount < (HSYNCV_END + HPERIOD/2)));
|
((hcount >= (HSYNCV_BEG + HPERIOD/2)) && (hcount < (HSYNCV_END + HPERIOD/2)));
|
||||||
|
|
||||||
wire vga_pix_start = ((hcount == (HBLNKV_END)) || (hcount == (HBLNKV_END + HPERIOD/2)));
|
wire vga_pix_start = ((hcount == (HBLNKV_END)) || (hcount == (HBLNKV_END + HPERIOD/2)));
|
||||||
|
|
||||||
assign vga_line = (hcount >= HPERIOD/2);
|
assign vga_line = (hcount >= HPERIOD/2);
|
||||||
|
|
||||||
assign hvpix = hpix && vpix;
|
assign hvpix = hpix && vpix;
|
||||||
|
|
||||||
assign hpix = (hcount >= hpix_beg) && (hcount < hpix_end);
|
assign hpix = (hcount >= hpix_beg) && (hcount < hpix_end);
|
||||||
|
|
||||||
assign vpix = (vcount >= vpix_beg) && (vcount < vpix_end); // vertical pixels window
|
assign vpix = (vcount >= vpix_beg) && (vcount < vpix_end);
|
||||||
assign v_ts = (vcount >= (vpix_beg - 1)) && (vcount < (vpix_end - 1)); // vertical TS window
|
|
||||||
assign v_pf = (vcount >= (vpix_beg - 17)) && (vcount < (vpix_end - 9)); // vertical tilemap prefetch window
|
|
||||||
|
|
||||||
always @(posedge clk)
|
assign hvtspix = htspix && vtspix;
|
||||||
video_go <= (hcount >= (hpix_beg - go_offs - x_offs)) && (hcount < (hpix_end - go_offs - x_offs + 4)) && vpix && !nogfx;
|
wire htspix = (hcount >= hpix_beg_ts) && (hcount < hpix_end_ts);
|
||||||
|
wire vtspix = (vcount >= vpix_beg_ts) && (vcount < vpix_end_ts);
|
||||||
|
|
||||||
wire line_start = hcount == (HPERIOD - 1);
|
assign v_ts = (vcount >= (vpix_beg_ts - 1)) && (vcount < (vpix_end_ts - 1)); // vertical TS window
|
||||||
assign line_start_s = line_start && c3;
|
assign v_pf = (vcount >= (vpix_beg_ts - 17)) && (vcount < (vpix_end_ts - 9)); // vertical tilemap prefetch window
|
||||||
wire line_start2 = hcount == (HSYNC_END - 1);
|
|
||||||
assign frame_start = line_start && (vcount == (vperiod - 1));
|
|
||||||
wire vis_start = line_start && (vcount == (vblnk_end - 1));
|
|
||||||
assign pix_start = hcount == (hpix_beg - x_offs - 1);
|
|
||||||
wire ts_start_coarse = hcount == (hpix_beg - 1);
|
|
||||||
assign ts_start = c3 && ts_start_coarse;
|
|
||||||
assign int_start = (hcount == {hint_beg, 1'b0}) && (vcount == vint_beg) && c0;
|
|
||||||
|
|
||||||
|
always @(posedge clk) video_go <= (hcount >= (hpix_beg - go_offs - x_offs)) && (hcount < (hpix_end - go_offs - x_offs + 4)) && vpix && !nogfx;
|
||||||
|
|
||||||
always @(posedge clk) if (line_start_s) // fix me - bydlocode !!!
|
wire line_start = hcount == (HPERIOD - 1);
|
||||||
vga_vblank <= tv_vblank;
|
assign line_start_s = line_start && c3;
|
||||||
|
wire line_start2 = hcount == (HSYNC_END - 1);
|
||||||
|
assign frame_start = line_start && (vcount == (vperiod - 1));
|
||||||
|
wire vis_start = line_start && (vcount == (vblnk_end - 1));
|
||||||
|
assign pix_start = hcount == (hpix_beg - x_offs - 1);
|
||||||
|
wire ts_start_coarse = hcount == (hpix_beg_ts - 1);
|
||||||
|
assign ts_start = c3 && ts_start_coarse;
|
||||||
|
assign int_start = (hcount == {hint_beg, 1'b0}) && (vcount == vint_beg) && c0;
|
||||||
|
|
||||||
|
always @(posedge clk) if (line_start_s) vga_vblank <= tv_vblank;
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
begin
|
hsync <= sync_pol ^ (vga_on ? hs_vga : hs);
|
||||||
hsync <= sync_pol ^ (vga_on ? hs_vga : hs);
|
vsync <= sync_pol ^ vs;
|
||||||
vsync <= sync_pol ^ vs;
|
csync <= ~(vs ^ hs);
|
||||||
csync <= ~(vs ^ hs);
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -15,6 +15,7 @@ module video_top
|
|||||||
output wire [7:0] vred,
|
output wire [7:0] vred,
|
||||||
output wire [7:0] vgrn,
|
output wire [7:0] vgrn,
|
||||||
output wire [7:0] vblu,
|
output wire [7:0] vblu,
|
||||||
|
output wire vdac_mode,
|
||||||
|
|
||||||
// video syncs
|
// video syncs
|
||||||
output wire hsync,
|
output wire hsync,
|
||||||
@ -25,7 +26,6 @@ module video_top
|
|||||||
output wire pix_stb,
|
output wire pix_stb,
|
||||||
|
|
||||||
// Z80 controls
|
// Z80 controls
|
||||||
input wire [15:0] a,
|
|
||||||
input wire [ 7:0] d,
|
input wire [ 7:0] d,
|
||||||
input wire [15:0] zmd,
|
input wire [15:0] zmd,
|
||||||
input wire [ 7:0] zma,
|
input wire [ 7:0] zma,
|
||||||
@ -74,10 +74,8 @@ module video_top
|
|||||||
input wire video_pre_next,
|
input wire video_pre_next,
|
||||||
input wire next_video,
|
input wire next_video,
|
||||||
input wire video_strobe,
|
input wire video_strobe,
|
||||||
input wire video_next_strobe,
|
|
||||||
output wire [20:0] ts_addr,
|
output wire [20:0] ts_addr,
|
||||||
output wire ts_req,
|
output wire ts_req,
|
||||||
output wire ts_z80_lp,
|
|
||||||
input wire ts_pre_next,
|
input wire ts_pre_next,
|
||||||
input wire ts_next,
|
input wire ts_next,
|
||||||
output wire [20:0] tm_addr,
|
output wire [20:0] tm_addr,
|
||||||
@ -87,14 +85,10 @@ module video_top
|
|||||||
// video controls
|
// video controls
|
||||||
input wire cfg_60hz,
|
input wire cfg_60hz,
|
||||||
input wire sync_pol,
|
input wire sync_pol,
|
||||||
input wire vga_on,
|
input wire vga_on
|
||||||
|
|
||||||
output wire [3:0] tst
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
assign ts_z80_lp = tsconf[4];
|
|
||||||
|
|
||||||
// video config
|
// video config
|
||||||
wire [7:0] vpage; // re-latched at line_start
|
wire [7:0] vpage; // re-latched at line_start
|
||||||
wire [7:0] vconf; //
|
wire [7:0] vconf; //
|
||||||
@ -116,6 +110,10 @@ wire [8:0] hpix_beg;
|
|||||||
wire [8:0] hpix_end;
|
wire [8:0] hpix_end;
|
||||||
wire [8:0] vpix_beg;
|
wire [8:0] vpix_beg;
|
||||||
wire [8:0] vpix_end;
|
wire [8:0] vpix_end;
|
||||||
|
wire [8:0] hpix_beg_ts;
|
||||||
|
wire [8:0] hpix_end_ts;
|
||||||
|
wire [8:0] vpix_beg_ts;
|
||||||
|
wire [8:0] vpix_end_ts;
|
||||||
wire [5:0] x_tiles;
|
wire [5:0] x_tiles;
|
||||||
wire [9:0] x_offs_mode;
|
wire [9:0] x_offs_mode;
|
||||||
wire [4:0] go_offs;
|
wire [4:0] go_offs;
|
||||||
@ -123,12 +121,9 @@ wire [1:0] render_mode;
|
|||||||
wire tv_hires;
|
wire tv_hires;
|
||||||
wire vga_hires;
|
wire vga_hires;
|
||||||
wire v60hz;
|
wire v60hz;
|
||||||
//===zx-evo-fpga-564db5e984ef ===
|
|
||||||
wire nogfx = vconf[5];
|
wire nogfx = vconf[5];
|
||||||
wire notsu = vconf[4];
|
wire notsu = vconf[4];
|
||||||
wire gfxovr = vconf[3];
|
wire gfxovr = vconf[3];
|
||||||
//wire gfxovr;
|
|
||||||
//===============================
|
|
||||||
wire tv_hblank;
|
wire tv_hblank;
|
||||||
wire tv_vblank;
|
wire tv_vblank;
|
||||||
wire vga_hblank;
|
wire vga_hblank;
|
||||||
@ -142,6 +137,7 @@ wire [3:0] scnt;
|
|||||||
wire [8:0] lcount;
|
wire [8:0] lcount;
|
||||||
|
|
||||||
// synchro
|
// synchro
|
||||||
|
wire frame_start;
|
||||||
wire pix_start;
|
wire pix_start;
|
||||||
wire tv_pix_start;
|
wire tv_pix_start;
|
||||||
wire vga_pix_start;
|
wire vga_pix_start;
|
||||||
@ -151,6 +147,7 @@ wire v_pf;
|
|||||||
wire hpix;
|
wire hpix;
|
||||||
wire vpix;
|
wire vpix;
|
||||||
wire hvpix;
|
wire hvpix;
|
||||||
|
wire hvtspix;
|
||||||
wire flash;
|
wire flash;
|
||||||
|
|
||||||
// fetcher
|
// fetcher
|
||||||
@ -177,9 +174,6 @@ wire [3:0] tsr_pal;
|
|||||||
wire tsr_rdy;
|
wire tsr_rdy;
|
||||||
|
|
||||||
// TS-line
|
// TS-line
|
||||||
// wire [8:0] ts_waddr = a[8:0];
|
|
||||||
// wire [7:0] ts_wdata = {d[7:1], 1'b1};
|
|
||||||
// wire ts_we = c3;
|
|
||||||
wire [8:0] ts_waddr;
|
wire [8:0] ts_waddr;
|
||||||
wire [7:0] ts_wdata;
|
wire [7:0] ts_wdata;
|
||||||
wire ts_we;
|
wire ts_we;
|
||||||
@ -189,7 +183,8 @@ wire [8:0] ts_raddr;
|
|||||||
wire [9:0] vga_cnt_in;
|
wire [9:0] vga_cnt_in;
|
||||||
wire [9:0] vga_cnt_out;
|
wire [9:0] vga_cnt_out;
|
||||||
|
|
||||||
video_ports video_ports (
|
video_ports video_ports
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.d (d),
|
.d (d),
|
||||||
.res (res),
|
.res (res),
|
||||||
@ -232,6 +227,7 @@ video_ports video_ports (
|
|||||||
.palsel (palsel),
|
.palsel (palsel),
|
||||||
.hint_beg (hint_beg),
|
.hint_beg (hint_beg),
|
||||||
.vint_beg (vint_beg),
|
.vint_beg (vint_beg),
|
||||||
|
.int_start (0),
|
||||||
.tsconf (tsconf),
|
.tsconf (tsconf),
|
||||||
.tmpage (tmpage),
|
.tmpage (tmpage),
|
||||||
.t0gpage (t0gpage),
|
.t0gpage (t0gpage),
|
||||||
@ -240,7 +236,8 @@ video_ports video_ports (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
video_mode video_mode (
|
video_mode video_mode
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.f1 (f1),
|
.f1 (f1),
|
||||||
.c3 (c3),
|
.c3 (c3),
|
||||||
@ -254,10 +251,15 @@ video_mode video_mode (
|
|||||||
.txt_char (fetch_temp[15:0]),
|
.txt_char (fetch_temp[15:0]),
|
||||||
.gx_offs (gx_offs),
|
.gx_offs (gx_offs),
|
||||||
.x_offs_mode (x_offs_mode),
|
.x_offs_mode (x_offs_mode),
|
||||||
|
.ts_rres_ext (tsconf[0]),
|
||||||
.hpix_beg (hpix_beg),
|
.hpix_beg (hpix_beg),
|
||||||
.hpix_end (hpix_end),
|
.hpix_end (hpix_end),
|
||||||
.vpix_beg (vpix_beg),
|
.vpix_beg (vpix_beg),
|
||||||
.vpix_end (vpix_end),
|
.vpix_end (vpix_end),
|
||||||
|
.hpix_beg_ts (hpix_beg_ts),
|
||||||
|
.hpix_end_ts (hpix_end_ts),
|
||||||
|
.vpix_beg_ts (vpix_beg_ts),
|
||||||
|
.vpix_end_ts (vpix_end_ts),
|
||||||
.x_tiles (x_tiles),
|
.x_tiles (x_tiles),
|
||||||
.go_offs (go_offs),
|
.go_offs (go_offs),
|
||||||
.cnt_col (cnt_col),
|
.cnt_col (cnt_col),
|
||||||
@ -274,7 +276,8 @@ video_mode video_mode (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
video_sync video_sync (
|
video_sync video_sync
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.f1 (f1),
|
.f1 (f1),
|
||||||
.c0 (c0),
|
.c0 (c0),
|
||||||
@ -284,6 +287,10 @@ video_sync video_sync (
|
|||||||
.hpix_end (hpix_end),
|
.hpix_end (hpix_end),
|
||||||
.vpix_beg (vpix_beg),
|
.vpix_beg (vpix_beg),
|
||||||
.vpix_end (vpix_end),
|
.vpix_end (vpix_end),
|
||||||
|
.hpix_beg_ts (hpix_beg_ts),
|
||||||
|
.hpix_end_ts (hpix_end_ts),
|
||||||
|
.vpix_beg_ts (vpix_beg_ts),
|
||||||
|
.vpix_end_ts (vpix_end_ts),
|
||||||
.go_offs (go_offs),
|
.go_offs (go_offs),
|
||||||
.x_offs (x_offs_mode[1:0]),
|
.x_offs (x_offs_mode[1:0]),
|
||||||
.y_offs_wr (gy_offsl_wr || gy_offsh_wr),
|
.y_offs_wr (gy_offsl_wr || gy_offsh_wr),
|
||||||
@ -311,12 +318,14 @@ video_sync video_sync (
|
|||||||
.ts_start (ts_start),
|
.ts_start (ts_start),
|
||||||
.cstart (x_offs_mode[9:2]),
|
.cstart (x_offs_mode[9:2]),
|
||||||
.rstart (gy_offs),
|
.rstart (gy_offs),
|
||||||
|
.frame_start (frame_start),
|
||||||
.int_start (int_start),
|
.int_start (int_start),
|
||||||
.v_pf (v_pf),
|
.v_pf (v_pf),
|
||||||
.hpix (hpix),
|
.hpix (hpix),
|
||||||
.v_ts (v_ts),
|
.v_ts (v_ts),
|
||||||
.vpix (vpix),
|
.vpix (vpix),
|
||||||
.hvpix (hvpix),
|
.hvpix (hvpix),
|
||||||
|
.hvtspix (hvtspix),
|
||||||
.nogfx (nogfx),
|
.nogfx (nogfx),
|
||||||
.cfg_60hz (cfg_60hz),
|
.cfg_60hz (cfg_60hz),
|
||||||
.sync_pol (sync_pol),
|
.sync_pol (sync_pol),
|
||||||
@ -327,7 +336,8 @@ video_sync video_sync (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
video_fetch video_fetch (
|
video_fetch video_fetch
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.f_sel (fetch_sel),
|
.f_sel (fetch_sel),
|
||||||
.b_sel (fetch_bsl),
|
.b_sel (fetch_bsl),
|
||||||
@ -338,7 +348,8 @@ video_fetch video_fetch (
|
|||||||
.video_data (dram_rdata)
|
.video_data (dram_rdata)
|
||||||
);
|
);
|
||||||
|
|
||||||
video_ts video_ts (
|
video_ts video_ts
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.start (ts_start),
|
.start (ts_start),
|
||||||
.line (lcount),
|
.line (lcount),
|
||||||
@ -378,8 +389,8 @@ video_ts video_ts (
|
|||||||
.sfile_we (sfile_we)
|
.sfile_we (sfile_we)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
video_ts_render video_ts_render
|
||||||
video_ts_render video_ts_render (
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
|
|
||||||
.reset (ts_start),
|
.reset (ts_start),
|
||||||
@ -406,10 +417,12 @@ video_ts_render video_ts_render (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
video_render video_render (
|
video_render video_render
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.c1 (c1),
|
.c1 (c1),
|
||||||
.hvpix (hvpix),
|
.hvpix (hvpix),
|
||||||
|
.hvtspix (hvtspix),
|
||||||
.nogfx (nogfx),
|
.nogfx (nogfx),
|
||||||
.notsu (notsu),
|
.notsu (notsu),
|
||||||
.gfxovr (gfxovr),
|
.gfxovr (gfxovr),
|
||||||
@ -424,7 +437,8 @@ video_render video_render (
|
|||||||
.vplex_out (vplex)
|
.vplex_out (vplex)
|
||||||
);
|
);
|
||||||
|
|
||||||
video_out video_out (
|
video_out video_out
|
||||||
|
(
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.f0 (f0),
|
.f0 (f0),
|
||||||
.c3 (c3),
|
.c3 (c3),
|
||||||
@ -436,14 +450,14 @@ video_out video_out (
|
|||||||
.tv_hires (tv_hires),
|
.tv_hires (tv_hires),
|
||||||
.vga_hires (vga_hires),
|
.vga_hires (vga_hires),
|
||||||
.cram_addr_in (zma),
|
.cram_addr_in (zma),
|
||||||
.cram_data_in (zmd[14:0]),
|
.cram_data_in (zmd[15:0]),
|
||||||
.cram_we (cram_we),
|
.cram_we (cram_we),
|
||||||
.vplex_in (vplex),
|
.vplex_in (vplex),
|
||||||
.vgaplex (vgaplex),
|
.vgaplex (vgaplex),
|
||||||
.vred (vred),
|
.vred (vred),
|
||||||
.vgrn (vgrn),
|
.vgrn (vgrn),
|
||||||
.vblu (vblu),
|
.vblu (vblu),
|
||||||
.tst (tst)
|
.vdac_mode (vdac_mode)
|
||||||
);
|
);
|
||||||
|
|
||||||
assign hblank = vga_on ? vga_hblank : tv_hblank;
|
assign hblank = vga_on ? vga_hblank : tv_hblank;
|
||||||
@ -453,12 +467,12 @@ assign vblank = vga_on ? vga_vblank : tv_vblank;
|
|||||||
// (2 altdprams)
|
// (2 altdprams)
|
||||||
wire tl_act0 = lcount[0];
|
wire tl_act0 = lcount[0];
|
||||||
wire tl_act1 = ~lcount[0];
|
wire tl_act1 = ~lcount[0];
|
||||||
wire [8:0] ts_waddr0 = tl_act0 ? ts_raddr : ts_waddr;
|
wire [8:0] ts_waddr0 = tl_act0 ? ts_raddr : ts_waddr;
|
||||||
wire [7:0] ts_wdata0 = tl_act0 ? 8'd0 : ts_wdata;
|
wire [7:0] ts_wdata0 = tl_act0 ? 8'd0 : ts_wdata;
|
||||||
wire ts_we0 = tl_act0 ? c3 : ts_we;
|
wire ts_we0 = tl_act0 ? c3 : ts_we;
|
||||||
wire [8:0] ts_waddr1 = tl_act1 ? ts_raddr : ts_waddr;
|
wire [8:0] ts_waddr1 = tl_act1 ? ts_raddr : ts_waddr;
|
||||||
wire [7:0] ts_wdata1 = tl_act1 ? 8'd0 : ts_wdata;
|
wire [7:0] ts_wdata1 = tl_act1 ? 8'd0 : ts_wdata;
|
||||||
wire ts_we1 = tl_act1 ? c3 : ts_we;
|
wire ts_we1 = tl_act1 ? c3 : ts_we;
|
||||||
wire [7:0] ts_rdata = tl_act0 ? ts_rdata0 : ts_rdata1;
|
wire [7:0] ts_rdata = tl_act0 ? ts_rdata0 : ts_rdata1;
|
||||||
wire [7:0] ts_rdata0, ts_rdata1;
|
wire [7:0] ts_rdata0, ts_rdata1;
|
||||||
|
|
||||||
|
@ -59,319 +59,296 @@ module video_ts
|
|||||||
output wire [20:0] dram_addr,
|
output wire [20:0] dram_addr,
|
||||||
output wire dram_req,
|
output wire dram_req,
|
||||||
input wire dram_next,
|
input wire dram_next,
|
||||||
input wire [15:0] dram_rdata,
|
input wire [15:0] dram_rdata
|
||||||
|
|
||||||
output wire [2:0] tst
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// config
|
// config
|
||||||
wire s_en = tsconf[7];
|
wire s_en = tsconf[7];
|
||||||
wire t1_en = tsconf[6];
|
wire t1_en = tsconf[6];
|
||||||
wire t0_en = tsconf[5];
|
wire t0_en = tsconf[5];
|
||||||
wire t1z_en = tsconf[3];
|
wire t1z_en = tsconf[3];
|
||||||
wire t0z_en = tsconf[2];
|
wire t0z_en = tsconf[2];
|
||||||
|
|
||||||
|
|
||||||
// TS renderer interface
|
// TS renderer interface
|
||||||
assign tsr_go = sprite_go || tile_go;
|
assign tsr_go = sprite_go || tile_go;
|
||||||
assign tsr_x = sprites ? sprites_x : tile_x;
|
assign tsr_x = sprites ? sprites_x : tile_x;
|
||||||
assign tsr_xs = sprites ? sprites_xs : 3'd0;
|
assign tsr_xs = sprites ? sprites_xs : 3'd0;
|
||||||
assign tsr_xf = sprites ? sprites_xf : t_xflp;
|
assign tsr_xf = sprites ? sprites_xf : t_xflp;
|
||||||
assign tsr_page = sprites ? sgpage : tile_page;
|
assign tsr_page = sprites ? sgpage : tile_page;
|
||||||
assign tsr_line = sprites ? sprites_line : tile_line;
|
assign tsr_line = sprites ? sprites_line : tile_line;
|
||||||
assign tsr_addr = sprites ? sprites_addr : tile_addr;
|
assign tsr_addr = sprites ? sprites_addr : tile_addr;
|
||||||
assign tsr_pal = sprites ? s_pal : tile_pal;
|
assign tsr_pal = sprites ? s_pal : tile_pal;
|
||||||
|
|
||||||
|
|
||||||
// Layer selectors control
|
// Layer selectors control
|
||||||
|
|
||||||
// DEBUG !!!
|
localparam LAYERS = 6; // Total number of layers to process
|
||||||
assign tst = lyr;
|
localparam TM = 0; // Individual layers
|
||||||
reg [2:0] lyr;
|
localparam S0 = 1;
|
||||||
always@*
|
localparam T0 = 2;
|
||||||
// if (layer_active[S0])
|
localparam S1 = 3;
|
||||||
// lyr = 2;
|
localparam T1 = 4;
|
||||||
// else if (layer_active[S1])
|
localparam S2 = 5;
|
||||||
// lyr = 6;
|
|
||||||
// else if (layer_active[S2])
|
|
||||||
// lyr = 4;
|
|
||||||
// else if (layer_active[TM])
|
|
||||||
// lyr = 1;
|
|
||||||
// else if (layer_active[T0])
|
|
||||||
// lyr = 3;
|
|
||||||
// else if (layer_active[T1])
|
|
||||||
// lyr = 5;
|
|
||||||
// else lyr = 0;
|
|
||||||
lyr = 0;
|
|
||||||
// lyr = sr_valid;
|
|
||||||
|
|
||||||
localparam LAYERS = 6; // Total number of layers to process
|
wire tmap = layer_active[TM];
|
||||||
localparam TM = 0; // Individual layers
|
wire sprites = layer_active[S0] || layer_active[S1] || layer_active[S2];
|
||||||
localparam S0 = 1;
|
wire tiles = layer_active[T0] || layer_active[T1];
|
||||||
localparam T0 = 2;
|
|
||||||
localparam S1 = 3;
|
|
||||||
localparam T1 = 4;
|
|
||||||
localparam S2 = 5;
|
|
||||||
|
|
||||||
wire tmap = layer_active[TM];
|
reg [LAYERS-1:0] layer;
|
||||||
wire sprites = layer_active[S0] || layer_active[S1] || layer_active[S2];
|
always @(posedge clk)
|
||||||
wire tiles = layer_active[T0] || layer_active[T1];
|
if (start)
|
||||||
|
layer <= 1;
|
||||||
|
else if (|(layer & layer_skip))
|
||||||
|
layer <= {layer[LAYERS-2:0], 1'b0};
|
||||||
|
|
||||||
reg [LAYERS-1:0] layer;
|
reg [LAYERS-1:0] layer_active;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
layer <= 1;
|
layer_active <= 0;
|
||||||
else if (|(layer & layer_skip))
|
else
|
||||||
layer <= {layer[LAYERS-2:0], 1'b0};
|
layer_active <= layer & ~layer_skip;
|
||||||
|
|
||||||
reg [LAYERS-1:0] layer_active;
|
wire [LAYERS-1:0] layer_enabled = {s_en, t1_en, s_en, t0_en, s_en, t1_en || t0_en};
|
||||||
always @(posedge clk)
|
wire [LAYERS-1:0] layer_allowed = {{5{v_ts}}, v_pf};
|
||||||
if (start)
|
wire [LAYERS-1:0] layer_end = {spr_end[2], tile_end[1], spr_end[1], tile_end[0], spr_end[0], tm_end};
|
||||||
layer_active <= 0;
|
|
||||||
else
|
|
||||||
layer_active <= layer & ~layer_skip;
|
|
||||||
|
|
||||||
wire [LAYERS-1:0] layer_enabled = {s_en, t1_en, s_en, t0_en, s_en, t1_en || t0_en};
|
reg [LAYERS-1:0] layer_skip;
|
||||||
wire [LAYERS-1:0] layer_allowed = {{5{v_ts}}, v_pf};
|
always @(posedge clk)
|
||||||
wire [LAYERS-1:0] layer_end = {spr_end[2], tile_end[1], spr_end[1], tile_end[0], spr_end[0], tm_end};
|
if (start)
|
||||||
|
layer_skip <= ~(layer_enabled & layer_allowed);
|
||||||
reg [LAYERS-1:0] layer_skip;
|
else
|
||||||
always @(posedge clk)
|
layer_skip <= layer_skip | layer_end;
|
||||||
if (start)
|
|
||||||
layer_skip <= ~(layer_enabled & layer_allowed);
|
|
||||||
else
|
|
||||||
layer_skip <= layer_skip | layer_end;
|
|
||||||
|
|
||||||
|
|
||||||
// --- Tile map prefetch ---
|
// --- Tile map prefetch ---
|
||||||
|
|
||||||
// DRAM controls
|
// DRAM controls
|
||||||
assign dram_addr = {tmpage, tm_b_row, tm_layer, tm_b_line, tm_num}; // 20:13 - page, 12:7 - row, 6 - layer, 5:0 - column (burst number : number in burst)
|
assign dram_addr = {tmpage, tm_b_row, tm_layer, tm_b_line, tm_num}; // 20:13 - page, 12:7 - row, 6 - layer, 5:0 - column (burst number : number in burst)
|
||||||
assign dram_req = tmap;
|
assign dram_req = tmap;
|
||||||
|
|
||||||
// TMB control
|
// TMB control
|
||||||
wire [8:0] tmb_waddr = {tm_line[4:3], tm_b_line, tm_num, tm_layer}; // 8:7 - buffer #, 6:4 - burst number (of 8 bursts), 3:1 - number in burst (8 tiles per burst), 0 - layer
|
wire [8:0] tmb_waddr = {tm_line[4:3], tm_b_line, tm_num, tm_layer}; // 8:7 - buffer #, 6:4 - burst number (of 8 bursts), 3:1 - number in burst (8 tiles per burst), 0 - layer
|
||||||
wire [8:0] tm_line = line + 9'd16;
|
wire [8:0] tm_line = line + 9'd16;
|
||||||
wire [2:0] tm_b_line = tm_line[2:0];
|
wire [2:0] tm_b_line = tm_line[2:0];
|
||||||
wire [5:0] tm_b_row = tm_line[8:3] + (tm_layer ? t1y_offs[8:3] : t0y_offs[8:3]);
|
wire [5:0] tm_b_row = tm_line[8:3] + (tm_layer ? t1y_offs[8:3] : t0y_offs[8:3]);
|
||||||
wire [2:0] tm_num = tm_x[2:0];
|
wire [2:0] tm_num = tm_x[2:0];
|
||||||
wire tm_layer = tm_x[3];
|
wire tm_layer = tm_x[3];
|
||||||
|
|
||||||
// internal layers control
|
// internal layers control
|
||||||
wire tm_end = tm_x == (t1_en ? 5'd16 : 5'd8);
|
wire tm_end = tm_x == (t1_en ? 5'd16 : 5'd8);
|
||||||
wire tm_next = dram_next && tmap;
|
wire tm_next = dram_next && tmap;
|
||||||
|
|
||||||
reg [1:0] m_layer;
|
reg [1:0] m_layer;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
m_layer <= 2'b1;
|
m_layer <= 2'b1;
|
||||||
else if (tm_end)
|
else if (tm_end)
|
||||||
m_layer <= {m_layer[0], 1'b0};
|
m_layer <= {m_layer[0], 1'b0};
|
||||||
|
|
||||||
// tilemap X coordinate
|
// tilemap X coordinate
|
||||||
reg [4:0] tm_x;
|
reg [4:0] tm_x;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
tm_x <= t0_en ? 5'd0 : 5'd8;
|
tm_x <= t0_en ? 5'd0 : 5'd8;
|
||||||
else if (tm_next)
|
else if (tm_next)
|
||||||
tm_x <= tm_x + 5'd1;
|
tm_x <= tm_x + 5'd1;
|
||||||
|
|
||||||
|
|
||||||
// --- Tiles ---
|
// --- Tiles ---
|
||||||
|
|
||||||
// tile descriptor fields
|
// tile descriptor fields
|
||||||
wire [11:0] t_tnum = tmb_rdata[11:0];
|
wire [11:0] t_tnum = tmb_rdata[11:0];
|
||||||
wire [1:0] t_pal = tmb_rdata[13:12];
|
wire [1:0] t_pal = tmb_rdata[13:12];
|
||||||
wire t_xflp = tmb_rdata[14];
|
wire t_xflp = tmb_rdata[14];
|
||||||
wire t_yflp = tmb_rdata[15];
|
wire t_yflp = tmb_rdata[15];
|
||||||
|
|
||||||
// TSR control
|
// TSR control
|
||||||
wire [7:0] tile_page = t_sel ? t0gpage : t1gpage;
|
wire [7:0] tile_page = t_sel ? t0gpage : t1gpage;
|
||||||
wire [8:0] tile_line = {t_tnum[11:6], (t_line[2:0] ^ {3{t_yflp}})};
|
wire [8:0] tile_line = {t_tnum[11:6], (t_line[2:0] ^ {3{t_yflp}})};
|
||||||
wire [5:0] tile_addr = t_tnum[5:0];
|
wire [5:0] tile_addr = t_tnum[5:0];
|
||||||
wire [8:0] tile_x = {(tx - 6'd1), 3'd0} - tx_offs[2:0];
|
wire [8:0] tile_x = {(tx - 6'd1), 3'd0} - tx_offs[2:0];
|
||||||
wire [3:0] tile_pal = {t_sel ? t0_palsel : t1_palsel, t_pal};
|
wire [3:0] tile_pal = {t_sel ? t0_palsel : t1_palsel, t_pal};
|
||||||
|
|
||||||
// TMB control
|
// TMB control
|
||||||
wire [8:0] tmb_raddr = {t_line[4:3], tx + tx_offs[8:3], ~t_sel};
|
wire [8:0] tmb_raddr = {t_line[4:3], tx + tx_offs[8:3], ~t_sel};
|
||||||
|
|
||||||
// layer parameter selectors
|
// layer parameter selectors
|
||||||
wire [8:0] tx_offs = t_sel ? t0x_offs : t1x_offs;
|
wire [8:0] tx_offs = t_sel ? t0x_offs : t1x_offs;
|
||||||
wire [3:0] ty_offs = t_sel ? t0y_offs[2:0] : t1y_offs[2:0];
|
wire [3:0] ty_offs = t_sel ? t0y_offs[2:0] : t1y_offs[2:0];
|
||||||
wire t_sel = t_layer[0];
|
wire t_sel = t_layer[0];
|
||||||
|
|
||||||
// internal layers control
|
// internal layers control
|
||||||
wire [1:0] tile_end = {2{t_layer_end}} & t_layer[1:0];
|
wire [1:0] tile_end = {2{t_layer_end}} & t_layer[1:0];
|
||||||
wire t_layer_end = tx == num_tiles;
|
wire t_layer_end = tx == num_tiles;
|
||||||
wire t_layer_start = start || t_layer_end;
|
wire t_layer_start = start || t_layer_end;
|
||||||
|
|
||||||
reg [1:0] t_layer;
|
reg [1:0] t_layer;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
t_layer <= t0_en ? 2'b01 : 2'b10;
|
t_layer <= t0_en ? 2'b01 : 2'b10;
|
||||||
else if (t_layer_end)
|
else if (t_layer_end)
|
||||||
t_layer <= {t_layer[0], 1'b0};
|
t_layer <= {t_layer[0], 1'b0};
|
||||||
|
|
||||||
// TMBUF control
|
// TMBUF control
|
||||||
// condition write to tx write to tm_valid
|
// condition write to tx write to tm_valid
|
||||||
// t_layer_start 0 TM_PRE_VALID
|
// t_layer_start 0 TM_PRE_VALID
|
||||||
// tm_pre_valid tx+1 TM_VALID
|
// tm_pre_valid tx+1 TM_VALID
|
||||||
// tile_skip tx+1 -
|
// tile_skip tx+1 -
|
||||||
// tile_go tx+1 TM_VALID
|
// tile_go tx+1 TM_VALID
|
||||||
// tile_wait tx-1 TM_PRE_VALID
|
// tile_wait tx-1 TM_PRE_VALID
|
||||||
|
|
||||||
localparam TM_PRE_VALID = 2'b01;
|
localparam TM_PRE_VALID = 2'b01;
|
||||||
localparam TM_VALID = 2'b10;
|
localparam TM_VALID = 2'b10;
|
||||||
|
|
||||||
wire tile_go = tile_good && tsr_allowed;
|
wire tile_go = tile_good && tsr_allowed;
|
||||||
wire tile_wait = tile_good && !tsr_allowed;
|
wire tile_wait = tile_good && !tsr_allowed;
|
||||||
wire tile_good = tm_valid && tile_valid;
|
wire tile_good = tm_valid && tile_valid;
|
||||||
wire tile_skip = tm_valid && !tile_valid;
|
wire tile_skip = tm_valid && !tile_valid;
|
||||||
wire tsr_allowed = tiles && tsr_rdy;
|
wire tsr_allowed = tiles && tsr_rdy;
|
||||||
wire tile_valid = |t_tnum || (t_sel ? t0z_en : t1z_en);
|
wire tile_valid = |t_tnum || (t_sel ? t0z_en : t1z_en);
|
||||||
|
|
||||||
wire tm_pre_valid = tm_valid_r[0];
|
wire tm_pre_valid = tm_valid_r[0];
|
||||||
wire tm_valid = tm_valid_r[1];
|
wire tm_valid = tm_valid_r[1];
|
||||||
|
|
||||||
reg [1:0] tm_valid_r;
|
reg [1:0] tm_valid_r;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (t_layer_start || tile_wait)
|
if (t_layer_start || tile_wait)
|
||||||
tm_valid_r <= TM_PRE_VALID;
|
tm_valid_r <= TM_PRE_VALID;
|
||||||
else if (tm_pre_valid || tile_go)
|
else if (tm_pre_valid || tile_go)
|
||||||
tm_valid_r <= TM_VALID;
|
tm_valid_r <= TM_VALID;
|
||||||
|
|
||||||
reg [5:0] tx;
|
reg [5:0] tx;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (t_layer_start)
|
if (t_layer_start)
|
||||||
tx <= 6'd0;
|
tx <= 6'd0;
|
||||||
else if (tm_pre_valid || tile_skip || tile_go)
|
else if (tm_pre_valid || tile_skip || tile_go)
|
||||||
tx <= tx + 6'd1;
|
tx <= tx + 6'd1;
|
||||||
else if (tile_wait)
|
else if (tile_wait)
|
||||||
tx <= tx - 6'd1;
|
tx <= tx - 6'd1;
|
||||||
|
|
||||||
// tile Y geometry
|
// tile Y geometry
|
||||||
wire [4:0] t_line = line[4:0] + ty_offs;
|
wire [4:0] t_line = line[4:0] + ty_offs;
|
||||||
|
|
||||||
|
|
||||||
// --- Sprites ---
|
// --- Sprites ---
|
||||||
|
|
||||||
// sprite descriptor fields
|
// sprite descriptor fields
|
||||||
// R0
|
// R0
|
||||||
wire [8:0] s_ycrd = sfile_rdata[8:0];
|
wire [8:0] s_ycrd = sfile_rdata[8:0];
|
||||||
wire [2:0] s_ysz = sfile_rdata[11:9];
|
wire [2:0] s_ysz = sfile_rdata[11:9];
|
||||||
wire s_act = sfile_rdata[13];
|
wire s_act = sfile_rdata[13];
|
||||||
wire s_leap = sfile_rdata[14];
|
wire s_leap = sfile_rdata[14];
|
||||||
wire s_yflp = sfile_rdata[15];
|
wire s_yflp = sfile_rdata[15];
|
||||||
// R1
|
// R1
|
||||||
wire [8:0] s_xcrd = sfile_rdata[8:0];
|
wire [8:0] s_xcrd = sfile_rdata[8:0];
|
||||||
wire [2:0] s_xsz = sfile_rdata[11:9];
|
wire [2:0] s_xsz = sfile_rdata[11:9];
|
||||||
wire s_xflp = sfile_rdata[15];
|
wire s_xflp = sfile_rdata[15];
|
||||||
// R2
|
// R2
|
||||||
wire [11:0] s_tnum = sfile_rdata[11:0];
|
wire [11:0] s_tnum = sfile_rdata[11:0];
|
||||||
wire [3:0] s_pal = sfile_rdata[15:12];
|
wire [3:0] s_pal = sfile_rdata[15:12];
|
||||||
|
|
||||||
// TSR control
|
// TSR control
|
||||||
reg [8:0] sprites_x;
|
reg [8:0] sprites_x;
|
||||||
reg [2:0] sprites_xs;
|
reg [2:0] sprites_xs;
|
||||||
reg sprites_xf;
|
reg sprites_xf;
|
||||||
wire [5:0] sprites_addr = s_tnum[5:0];
|
wire [5:0] sprites_addr = s_tnum[5:0];
|
||||||
|
|
||||||
// internal layers control
|
// internal layers control
|
||||||
wire [2:0] spr_end = ({3{s_layer_end}} & s_layer[2:0]) | {3{sprites_last}};
|
wire [2:0] spr_end = ({3{s_layer_end}} & s_layer[2:0]) | {3{sprites_last}};
|
||||||
wire s_layer_end = (sr0_valid && !spr_valid && s_leap) || (sprite_go && s_leap_r);
|
wire s_layer_end = (sr0_valid && !spr_valid && s_leap) || (sprite_go && s_leap_r);
|
||||||
wire sprites_last = sreg == 8'd255;
|
wire sprites_last = sreg == 8'd255;
|
||||||
|
|
||||||
reg [2:0] s_layer;
|
reg [2:0] s_layer;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
s_layer <= 3'b1;
|
s_layer <= 3'b1;
|
||||||
else if (s_layer_end)
|
else if (s_layer_end)
|
||||||
s_layer <= {s_layer[1:0], 1'b0};
|
s_layer <= {s_layer[1:0], 1'b0};
|
||||||
|
|
||||||
// SFile registers control
|
// SFile registers control
|
||||||
// condition write to sreg write to sr_valid action
|
// condition write to sreg write to sr_valid action
|
||||||
// start 0 SR0_PRE_VALID Start
|
// start 0 SR0_PRE_VALID Start
|
||||||
// sr0_pre_valid sreg+3 SR0_VALID SR0 pre-read
|
// sr0_pre_valid sreg+3 SR0_VALID SR0 pre-read
|
||||||
// sr0_valid && !spr_valid sreg+3 - Skip sprite
|
// sr0_valid && !spr_valid sreg+3 - Skip sprite
|
||||||
// sr0_valid && spr_valid sreg-2 SR1_PRE_VALID SR1 pre-read
|
// sr0_valid && spr_valid sreg-2 SR1_PRE_VALID SR1 pre-read
|
||||||
// sr1_pre_valid sreg+1 SR1_VALID SR1 read
|
// sr1_pre_valid sreg+1 SR1_VALID SR1 read
|
||||||
// sr1_valid sreg+1 SR2_VALID SR2 pre-read
|
// sr1_valid sreg+1 SR2_VALID SR2 pre-read
|
||||||
// sr2_valid && !tsr_rdy - - Wait for TSR ready
|
// sr2_valid && !tsr_rdy - - Wait for TSR ready
|
||||||
// sr2_valid && tsr_rdy sreg+1 SR0_PRE_VALID Next sprite
|
// sr2_valid && tsr_rdy sreg+1 SR0_PRE_VALID Next sprite
|
||||||
// sprites_last - NONE_VALID End
|
// sprites_last - NONE_VALID End
|
||||||
|
|
||||||
localparam NONE_VALID = 5'b00000;
|
localparam NONE_VALID = 5'b00000;
|
||||||
localparam SR0_PRE_VALID = 5'b00001;
|
localparam SR0_PRE_VALID = 5'b00001;
|
||||||
localparam SR0_VALID = 5'b00010;
|
localparam SR0_VALID = 5'b00010;
|
||||||
localparam SR1_PRE_VALID = 5'b00100;
|
localparam SR1_PRE_VALID = 5'b00100;
|
||||||
localparam SR1_VALID = 5'b01000;
|
localparam SR1_VALID = 5'b01000;
|
||||||
localparam SR2_VALID = 5'b10000;
|
localparam SR2_VALID = 5'b10000;
|
||||||
|
|
||||||
wire sprite_go = sr2_valid && sprites && tsr_rdy; // kick to renderer
|
wire sprite_go = sr2_valid && sprites && tsr_rdy; // kick to renderer
|
||||||
wire spr_valid = s_visible && s_act;
|
wire spr_valid = s_visible && s_act;
|
||||||
|
|
||||||
wire sr0_pre_valid = sr_valid[0];
|
wire sr0_pre_valid = sr_valid[0];
|
||||||
wire sr0_valid = sr_valid[1];
|
wire sr0_valid = sr_valid[1];
|
||||||
wire sr1_pre_valid = sr_valid[2];
|
wire sr1_pre_valid = sr_valid[2];
|
||||||
wire sr1_valid = sr_valid[3];
|
wire sr1_valid = sr_valid[3];
|
||||||
wire sr2_valid = sr_valid[4];
|
wire sr2_valid = sr_valid[4];
|
||||||
|
|
||||||
reg [4:0] sr_valid;
|
reg [4:0] sr_valid;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
sr_valid <= SR0_PRE_VALID;
|
sr_valid <= SR0_PRE_VALID;
|
||||||
else if (sprites_last)
|
else if (sprites_last)
|
||||||
sr_valid <= NONE_VALID;
|
sr_valid <= NONE_VALID;
|
||||||
else if (sr0_pre_valid)
|
else if (sr0_pre_valid)
|
||||||
sr_valid <= SR0_VALID;
|
sr_valid <= SR0_VALID;
|
||||||
else if (sr0_valid && spr_valid)
|
else if (sr0_valid && spr_valid)
|
||||||
sr_valid <= SR1_PRE_VALID;
|
sr_valid <= SR1_PRE_VALID;
|
||||||
else if (sr1_pre_valid)
|
else if (sr1_pre_valid)
|
||||||
sr_valid <= SR1_VALID;
|
sr_valid <= SR1_VALID;
|
||||||
else if (sr1_valid)
|
else if (sr1_valid)
|
||||||
sr_valid <= SR2_VALID;
|
sr_valid <= SR2_VALID;
|
||||||
else if (sprite_go)
|
else if (sprite_go)
|
||||||
sr_valid <= SR0_PRE_VALID;
|
sr_valid <= SR0_PRE_VALID;
|
||||||
|
|
||||||
reg [7:0] sreg;
|
reg [7:0] sreg;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (start)
|
if (start)
|
||||||
sreg <= 8'd0;
|
sreg <= 8'd0;
|
||||||
else if (sr0_pre_valid)
|
else if (sr0_pre_valid)
|
||||||
sreg <= sreg + 8'd3;
|
sreg <= sreg + 8'd3;
|
||||||
else if (sr0_valid)
|
else if (sr0_valid)
|
||||||
sreg <= spr_valid ? (sreg - 8'd2) : (sreg + 8'd3);
|
sreg <= spr_valid ? (sreg - 8'd2) : (sreg + 8'd3);
|
||||||
else if (sr1_pre_valid || sprite_go)
|
else if (sr1_pre_valid || sprite_go)
|
||||||
sreg <= sreg + 8'd1;
|
sreg <= sreg + 8'd1;
|
||||||
|
|
||||||
// SFile control
|
// SFile control
|
||||||
reg [5:0] s_bmline_offset_r;
|
reg [5:0] s_bmline_offset_r;
|
||||||
reg s_leap_r;
|
reg s_leap_r;
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk) begin
|
||||||
|
if (sr0_valid)
|
||||||
begin
|
begin
|
||||||
if (sr0_valid)
|
s_leap_r <= s_leap;
|
||||||
begin
|
s_bmline_offset_r <= s_bmline_offset;
|
||||||
s_leap_r <= s_leap;
|
|
||||||
s_bmline_offset_r <= s_bmline_offset;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (sr1_valid)
|
|
||||||
begin
|
|
||||||
sprites_x <= s_xcrd;
|
|
||||||
sprites_xs <= s_xsz;
|
|
||||||
sprites_xf <= s_xflp;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// sprite Y geometry
|
if (sr1_valid)
|
||||||
wire [8:0] s_line = line - s_ycrd; // visible line of sprite in current video line
|
begin
|
||||||
wire s_visible = (s_line <= s_ymax); // check if sprite line is within Y size
|
sprites_x <= s_xcrd;
|
||||||
wire [5:0] s_ymax = {s_ysz, 3'b111};
|
sprites_xs <= s_xsz;
|
||||||
|
sprites_xf <= s_xflp;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
wire [8:0] sprites_line = {s_tnum[11:6], 3'b0} + s_bmline_offset_r;
|
// sprite Y geometry
|
||||||
wire [5:0] s_bmline_offset = s_yflp ? (s_ymax - s_line[5:0]) : s_line[5:0];
|
wire [8:0] s_line = line - s_ycrd; // visible line of sprite in current video line
|
||||||
|
wire s_visible = (s_line <= s_ymax); // check if sprite line is within Y size
|
||||||
|
wire [5:0] s_ymax = {s_ysz, 3'b111};
|
||||||
|
|
||||||
|
wire [8:0] sprites_line = {s_tnum[11:6], 3'b0} + s_bmline_offset_r;
|
||||||
|
wire [5:0] s_bmline_offset = s_yflp ? (s_ymax - s_line[5:0]) : s_line[5:0];
|
||||||
|
|
||||||
|
|
||||||
// SFile
|
// SFile
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
// after TS request recognized and processed by DRAM controller.
|
// after TS request recognized and processed by DRAM controller.
|
||||||
// It is recommended to assert 'tsr_go' at 'c2'.
|
// It is recommended to assert 'tsr_go' at 'c2'.
|
||||||
|
|
||||||
module video_ts_render (
|
module video_ts_render
|
||||||
|
(
|
||||||
// clocks
|
// clocks
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
// controls
|
// controls
|
||||||
input wire reset, // line start strobe, inits the machine
|
input wire reset, // line start strobe, inits the machine
|
||||||
|
|
||||||
input wire [ 8:0] x_coord, // address in TS-line where render to, auto-flipped to match 'flip' times 'x_size'
|
input wire [ 8:0] x_coord, // address in TS-line where render to, auto-flipped to match 'flip' times 'x_size'
|
||||||
@ -34,122 +34,117 @@ module video_ts_render (
|
|||||||
input wire [ 3:0] pal, // palette selector, bits[7:4] of CRAM address
|
input wire [ 3:0] pal, // palette selector, bits[7:4] of CRAM address
|
||||||
output wire mem_rdy, // ready to receive new task
|
output wire mem_rdy, // ready to receive new task
|
||||||
|
|
||||||
// TS-Line interface
|
// TS-Line interface
|
||||||
output reg [ 8:0] ts_waddr,
|
output reg [ 8:0] ts_waddr,
|
||||||
output wire [ 7:0] ts_wdata,
|
output wire [ 7:0] ts_wdata,
|
||||||
output wire ts_we,
|
output wire ts_we,
|
||||||
|
|
||||||
// DRAM interface
|
// DRAM interface
|
||||||
output wire [20:0] dram_addr,
|
output wire [20:0] dram_addr,
|
||||||
output wire dram_req,
|
output wire dram_req,
|
||||||
input wire [15:0] dram_rdata,
|
input wire [15:0] dram_rdata,
|
||||||
input wire dram_pre_next,
|
input wire dram_pre_next,
|
||||||
input wire dram_next
|
input wire dram_next
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// DRAM request
|
// DRAM request
|
||||||
assign dram_req = tsr_go || !mem_rdy;
|
assign dram_req = tsr_go || !mem_rdy;
|
||||||
|
|
||||||
|
|
||||||
// DRAM addressing
|
// DRAM addressing
|
||||||
assign dram_addr = tsr_go ? addr_in : addr_next;
|
assign dram_addr = tsr_go ? addr_in : addr_next;
|
||||||
wire [20:0] addr_in = {addr_offset, addr, 1'b0};
|
wire [20:0] addr_in = {addr_offset, addr, 1'b0};
|
||||||
wire [13:0] addr_offset = {page[7:3], line};
|
wire [13:0] addr_offset = {page[7:3], line};
|
||||||
wire [20:0] addr_next = {addr_reg[20:7], addr_reg[6:0] + dram_next};
|
wire [20:0] addr_next = {addr_reg[20:7], addr_reg[6:0] + dram_next};
|
||||||
// as renderer can't move outside the single bitmap line, only 7 bits are processed
|
// as renderer can't move outside the single bitmap line, only 7 bits are processed
|
||||||
|
|
||||||
reg [20:0] addr_reg;
|
reg [20:0] addr_reg;
|
||||||
always @(posedge clk)
|
always @(posedge clk) addr_reg <= dram_addr;
|
||||||
addr_reg <= dram_addr;
|
|
||||||
|
|
||||||
|
|
||||||
// DRAM cycles counter
|
// DRAM cycles counter
|
||||||
assign mem_rdy = cyc[4];
|
assign mem_rdy = cyc[4];
|
||||||
|
|
||||||
reg [4:0] cyc;
|
reg [4:0] cyc;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (reset)
|
if (reset)
|
||||||
cyc <= 5'b10000;
|
cyc <= 5'b10000;
|
||||||
else if (tsr_go)
|
else if (tsr_go)
|
||||||
cyc <= {1'b0, x_size, 1'b1};
|
cyc <= {1'b0, x_size, 1'b1};
|
||||||
else if (dram_pre_next)
|
else if (dram_pre_next)
|
||||||
cyc <= cyc - 5'd1;
|
cyc <= cyc - 5'd1;
|
||||||
|
|
||||||
|
|
||||||
// DRAM data fetching
|
// DRAM data fetching
|
||||||
reg [15:0] data;
|
reg [15:0] data;
|
||||||
always @(posedge clk)
|
always @(posedge clk) if (dram_next) data <= dram_rdata;
|
||||||
if (dram_next)
|
|
||||||
data <= dram_rdata;
|
|
||||||
|
|
||||||
|
|
||||||
// pixel render counter
|
// pixel render counter
|
||||||
assign ts_we = render_on && |pix; // write signal for TS-line
|
assign ts_we = render_on && |pix; // write signal for TS-line
|
||||||
wire render_on = !cnt[2];
|
wire render_on = !cnt[2];
|
||||||
|
|
||||||
reg [2:0] cnt;
|
reg [2:0] cnt;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (reset)
|
if (reset)
|
||||||
cnt <= 3'b100;
|
cnt <= 3'b100;
|
||||||
else if (dram_next)
|
else if (dram_next)
|
||||||
cnt <= 3'b000;
|
cnt <= 3'b000;
|
||||||
else if (render_on)
|
else if (render_on)
|
||||||
cnt <= cnt + 3'd1;
|
cnt <= cnt + 3'd1;
|
||||||
|
|
||||||
|
|
||||||
// renderer reload
|
// renderer reload
|
||||||
reg tsr_rld;
|
reg tsr_rld;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (reset)
|
if (reset)
|
||||||
tsr_rld <= 1'b0;
|
tsr_rld <= 1'b0;
|
||||||
else if (tsr_go)
|
else if (tsr_go)
|
||||||
tsr_rld <= 1'b1;
|
tsr_rld <= 1'b1;
|
||||||
else if (dram_next)
|
else if (dram_next)
|
||||||
tsr_rld <= 1'b0;
|
tsr_rld <= 1'b0;
|
||||||
|
|
||||||
|
|
||||||
// delayed values
|
// delayed values
|
||||||
reg [8:0] x_coord_d;
|
reg [8:0] x_coord_d;
|
||||||
reg [3:0] pal_d;
|
reg [3:0] pal_d;
|
||||||
reg flip_d;
|
reg flip_d;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (tsr_go)
|
if (tsr_go)
|
||||||
begin
|
begin
|
||||||
x_coord_d <= x_coord + (flip ? {x_size, 3'b111} : 6'd0);
|
x_coord_d <= x_coord + (flip ? {x_size, 3'b111} : 6'd0);
|
||||||
pal_d <= pal;
|
pal_d <= pal;
|
||||||
flip_d <= flip;
|
flip_d <= flip;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// TS-line address
|
// TS-line address
|
||||||
wire [8:0] ts_waddr_mx = tsr_rld_stb ? x_coord_d : (render_on ? x_next : ts_waddr);
|
wire [8:0] ts_waddr_mx = tsr_rld_stb ? x_coord_d : (render_on ? x_next : ts_waddr);
|
||||||
wire [8:0] x_next = ts_waddr + {{8{flip_r}}, 1'b1};
|
wire [8:0] x_next = ts_waddr + {{8{flip_r}}, 1'b1};
|
||||||
wire tsr_rld_stb = tsr_rld && dram_next;
|
wire tsr_rld_stb = tsr_rld && dram_next;
|
||||||
|
|
||||||
always @(posedge clk)
|
always @(posedge clk) ts_waddr <= ts_waddr_mx;
|
||||||
ts_waddr <= ts_waddr_mx;
|
|
||||||
|
|
||||||
reg [3:0] pal_r;
|
reg [3:0] pal_r;
|
||||||
reg flip_r;
|
reg flip_r;
|
||||||
always @(posedge clk)
|
always @(posedge clk)
|
||||||
if (tsr_rld_stb)
|
if (tsr_rld_stb)
|
||||||
begin
|
begin
|
||||||
pal_r <= pal_d;
|
pal_r <= pal_d;
|
||||||
flip_r <= flip_d;
|
flip_r <= flip_d;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// renderer mux
|
// renderer mux
|
||||||
assign ts_wdata = {pal_r, pix};
|
assign ts_wdata = {pal_r, pix};
|
||||||
wire [3:0] pix = pix_m[cnt[1:0]];
|
wire [3:0] pix = pix_m[cnt[1:0]];
|
||||||
|
|
||||||
wire [3:0] pix_m[0:3];
|
wire [3:0] pix_m[0:3];
|
||||||
assign pix_m[0] = data[7:4];
|
assign pix_m[0] = data[7:4];
|
||||||
assign pix_m[1] = data[3:0];
|
assign pix_m[1] = data[3:0];
|
||||||
assign pix_m[2] = data[15:12];
|
assign pix_m[2] = data[15:12];
|
||||||
assign pix_m[3] = data[11:8];
|
assign pix_m[3] = data[11:8];
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Reference in New Issue
Block a user