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