add tms9918, aci
This commit is contained in:
parent
d76ecb6a34
commit
41215bdd99
|
@ -154,7 +154,11 @@ set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
|
|||
|
||||
# end ENTITY(apple1_mist)
|
||||
# -----------------------
|
||||
set_global_assignment -name VERILOG_FILE rtl/aci.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/display_ram.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/tms9918/vram.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/tms9918/tms9918_async.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/tms9918/tms9918.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ram.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/downloader.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/display.v
|
||||
|
@ -183,4 +187,26 @@ set_global_assignment -name VERILOG_FILE rtl/ps2keyboard.v
|
|||
set_global_assignment -name VERILOG_FILE rtl/font_rom.v
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/apple1_mist.sv
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_sprite-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_sprite.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_pattern-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_pattern.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_pack-p.vhd"
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_hor_vert-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_hor_vert.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_ctrl-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_cpuio-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_cpuio.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_core-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_core_comp_pack-p.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_core.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_comp_pack-p.vhd"
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_col_pack-p.vhd"
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_col_mux-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_col_mux.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_clk_gen-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_clk_gen.vhd
|
||||
set_global_assignment -name VHDL_FILE "rtl/tms9918/vdp18/vdp18_addr_mux-c.vhd"
|
||||
set_global_assignment -name VHDL_FILE rtl/tms9918/vdp18/vdp18_addr_mux.vhd
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
|
@ -0,0 +1,35 @@
|
|||
// Apple-1 Audio cassette interface (ACI)
|
||||
|
||||
// A good explanation of ACI can be found at:
|
||||
// https://www.sbprojects.net/projects/apple1/aci.php
|
||||
|
||||
module ACI (
|
||||
input clk, // clock signal
|
||||
input cpu_clken, // CPU clock enable
|
||||
|
||||
input [15:0] address, // address bus
|
||||
output reg [7:0] dout, // 8-bit data bus (output)
|
||||
|
||||
output reg tape_out, // tape output
|
||||
input tape_in // tape input
|
||||
);
|
||||
|
||||
reg [7:0] rom_data[0:255];
|
||||
|
||||
initial
|
||||
$readmemh("roms/aci.hex", rom_data, 0, 255);
|
||||
|
||||
wire io_range = address >= 16'hC000 && address <= 16'hC0FF;
|
||||
|
||||
wire [7:0] read_address = io_range ? { address[7:1], address[0] & tape_in } : address[7:0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
if(cpu_clken & io_range)
|
||||
tape_out <= ~tape_out;
|
||||
|
||||
dout <= rom_data[read_address];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -4,19 +4,24 @@
|
|||
//
|
||||
//
|
||||
|
||||
// TODO use a CPU that allows illegal instructions
|
||||
// TODO make it work with SDRAM
|
||||
// TODO ram refresh lost cycles
|
||||
// TODO ram refresh lost CPU cycles
|
||||
// TODO power on-off key ? (init ram)
|
||||
// TODO ram powerup initial values
|
||||
// TODO reorganize file structure
|
||||
// TODO support ACI interface for load and save
|
||||
// TODO special expansion boards: TMS9918, SID, AY?
|
||||
// TODO ACI: create ROM
|
||||
// TODO ACI: implementation
|
||||
// TODO more accurate chip selection circuit
|
||||
// TODO check diff with updated data_io.v and other modules
|
||||
// TODO keyboard: use a PIA
|
||||
// TODO keyboard: isolate ps2 keyboard from apple1
|
||||
// TODO keyboard: check ps2 clock
|
||||
// TODO keyboard: reset key
|
||||
// TODO keyboard: make a true ascii keyboard
|
||||
// TODO keyboard: check backspace key
|
||||
// TODO osd menu yellow, why it doesn't work?
|
||||
// TODO display: remove char_seen
|
||||
// TODO display: check NTSC AD724 hsync problem
|
||||
// TODO display: powerup values
|
||||
// TODO display: simplify rom font
|
||||
|
@ -24,7 +29,10 @@
|
|||
// TODO display: check parameters vs real apple1
|
||||
// TODO display: check cursor blinking vs 555 timings
|
||||
// TODO display: emulate PIA registers
|
||||
|
||||
// TODO tms9918: fix video sync on composite and mist_video
|
||||
// TODO tms9918: make it selectable / use include in code
|
||||
// TODO tms9918: connect /INT
|
||||
// TODO sid: implement 6581
|
||||
|
||||
module apple1_mist(
|
||||
input CLOCK_27,
|
||||
|
@ -75,9 +83,8 @@ module apple1_mist(
|
|||
|
||||
localparam CONF_STR = {
|
||||
"APPLE 1;;", // 0 download index for "apple1.rom"
|
||||
"F,PRG,Load program;", // 1 download index for ".prg" files
|
||||
"F,ROM,Load firmware;", // 2 download index for ".rom" files
|
||||
"O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||
"F,PRG,Load program;", // 1 download index for ".prg" files
|
||||
"O2,TMS9918 output,Off,On;",
|
||||
"T6,Reset;",
|
||||
"V,v1.01.",`BUILD_DATE
|
||||
};
|
||||
|
@ -94,6 +101,8 @@ wire [31:0] status;
|
|||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
|
||||
wire st_tms9918_output = status[2];
|
||||
|
||||
wire scandoubler_disable;
|
||||
wire ypbpr;
|
||||
wire no_csync;
|
||||
|
@ -113,6 +122,7 @@ wire pll_locked;
|
|||
|
||||
wire sys_clock; // cpu x 7 x 8 system clock (sdram.v)
|
||||
wire osd_clock; // cpu x 7 x 2 for the OSD menu
|
||||
wire vdp_clock; // tms9918 x 2 for osd menu
|
||||
|
||||
pll pll
|
||||
(
|
||||
|
@ -121,7 +131,8 @@ pll pll
|
|||
|
||||
.c0( osd_clock ), // cpu x 7 x 2 video clock for OSD menu
|
||||
.c2( sys_clock ), // cpu x 7 x 8 system clock (sdram.v)
|
||||
.c3( SDRAM_CLK ) // cpu x 7 x 8 phase shifted -2.5 ns
|
||||
.c3( SDRAM_CLK ), // cpu x 7 x 8 phase shifted -2.5 ns
|
||||
.c4( vdp_clock ) // tms9918 x 2 for osd menu (10.738635 x 2 = 21.47727)
|
||||
);
|
||||
|
||||
/******************************************************************************************/
|
||||
|
@ -191,15 +202,6 @@ rom_wozmon rom_wozmon(
|
|||
.dout(rom_dout)
|
||||
);
|
||||
|
||||
/*
|
||||
// Basic ROM
|
||||
wire [7:0] basic_dout;
|
||||
rom_basic rom_basic(
|
||||
.clk(sys_clock),
|
||||
.address(cpu_addr[11:0]),
|
||||
.dout(basic_dout)
|
||||
);
|
||||
*/
|
||||
|
||||
// Basic RAM
|
||||
wire [7:0] basic_dout;
|
||||
|
@ -211,6 +213,42 @@ ram #(.SIZE(4096)) rom_basic(
|
|||
.dout (basic_dout)
|
||||
);
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @ACI *******************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
wire [7:0] aci_dout;
|
||||
wire CASOUT;
|
||||
ACI ACI(
|
||||
.clk(sys_clock),
|
||||
.cpu_clken(cpu_clken),
|
||||
.address(sdram_addr[15:0]),
|
||||
.dout(aci_dout),
|
||||
.tape_in(CASIN),
|
||||
.tape_out(CASOUT),
|
||||
);
|
||||
|
||||
// latches cassette audio input
|
||||
reg CASIN;
|
||||
always @(posedge sys_clock) begin
|
||||
CASIN <= ~UART_RX; // on the Mistica UART_RX is the audio input
|
||||
end
|
||||
|
||||
wire audio;
|
||||
dac #(.C_bits(16)) dac_AUDIO
|
||||
(
|
||||
.clk_i(sys_clock),
|
||||
.res_n_i(pll_locked),
|
||||
.dac_i({ CASOUT, 15'b0000000 }), // TODO not sure about polarity
|
||||
.dac_o(audio)
|
||||
);
|
||||
|
||||
always @(posedge sys_clock) begin
|
||||
AUDIO_L <= audio;
|
||||
AUDIO_R <= audio;
|
||||
end
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
@ -253,11 +291,15 @@ wire cpu_wr;
|
|||
|
||||
wire ram_cs = sdram_addr < 'h4000; // 0x0000 -> 0x3FFF
|
||||
wire sdram_cs = sdram_addr >= 'h4000 && sdram_addr <= 'hBFFF; // 0x4000 -> 0xBFFF
|
||||
wire aci_cs = sdram_addr >= 'hC000 && sdram_addr <= 'hC1FF; // 0xC000 -> 0xC1FF
|
||||
wire tms_cs = sdram_addr >= 'hCC00 && sdram_addr <= 'hCC01; // 0xCC00 -> 0xCC01
|
||||
wire basic_cs = sdram_addr >= 'hE000 && sdram_addr <= 'hEFFF; // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = sdram_addr >= 'hFF00; // 0xFF00 -> 0xFFFF
|
||||
|
||||
wire [7:0] bus_dout = rom_cs ? rom_dout :
|
||||
basic_cs ? basic_dout :
|
||||
tms_cs ? vdp_dout :
|
||||
aci_cs ? aci_dout :
|
||||
sdram_cs ? sdram_dout :
|
||||
ram_cs ? ram_dout :
|
||||
8'b0;
|
||||
|
@ -300,7 +342,9 @@ mist_video
|
|||
#(
|
||||
.COLOR_DEPTH(1), // 1 bit color depth
|
||||
.OSD_AUTO_CE(1), // OSD autodetects clock enable
|
||||
.OSD_COLOR(3'b110) // yellow menu color
|
||||
.OSD_COLOR(3'b110), // yellow menu color
|
||||
.SYNC_AND(1),
|
||||
.SD_HCNT_WIDTH(11)
|
||||
)
|
||||
mist_video
|
||||
(
|
||||
|
@ -329,11 +373,73 @@ mist_video
|
|||
.VSync(vs),
|
||||
|
||||
// video output signals that go into MiST hardware
|
||||
.VGA_R(VGA_R),
|
||||
.VGA_G(VGA_G),
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS)
|
||||
.VGA_R(apple1_R),
|
||||
.VGA_G(apple1_G),
|
||||
.VGA_B(apple1_B),
|
||||
.VGA_VS(apple1_VS),
|
||||
.VGA_HS(apple1_HS)
|
||||
);
|
||||
|
||||
wire [5:0] apple1_R;
|
||||
wire [5:0] apple1_G;
|
||||
wire [5:0] apple1_B;
|
||||
wire apple1_HS;
|
||||
wire apple1_VS;
|
||||
|
||||
// mix video
|
||||
assign VGA_R = st_tms9918_output ? tms_R : apple1_R ;
|
||||
assign VGA_G = st_tms9918_output ? tms_G : apple1_G ;
|
||||
assign VGA_B = st_tms9918_output ? tms_B : apple1_B ;
|
||||
assign VGA_HS = st_tms9918_output ? tms_HS & tms_VS : apple1_HS;
|
||||
assign VGA_VS = st_tms9918_output ? tms_VS : apple1_VS;
|
||||
|
||||
wire [5:0] tms_out_R;
|
||||
wire [5:0] tms_out_G;
|
||||
wire [5:0] tms_out_B;
|
||||
wire tms_out_HS;
|
||||
wire tms_out_VS;
|
||||
|
||||
mist_video
|
||||
#(
|
||||
.COLOR_DEPTH(6), // 1 bit color depth
|
||||
.OSD_AUTO_CE(1), // OSD autodetects clock enable
|
||||
.OSD_COLOR(3'b110), // yellow menu color
|
||||
.SYNC_AND(1),
|
||||
.SD_HCNT_WIDTH(11)
|
||||
)
|
||||
tms_mist_video
|
||||
(
|
||||
//.clk_sys(vdp_clock), // OSD needs 2x the VDP clock for the scandoubler
|
||||
.clk_sys(osd_clock),
|
||||
|
||||
// OSD SPI interface
|
||||
.SPI_DI(SPI_DI),
|
||||
.SPI_SCK(SPI_SCK),
|
||||
.SPI_SS3(SPI_SS3),
|
||||
|
||||
.scanlines(2'b00), // scanline emulation disabled for now
|
||||
.ce_divider(1), // non-scandoubled pixel clock divider 0 - clk_sys/4, 1 - clk_sys/2
|
||||
|
||||
.scandoubler_disable(scandoubler_disable), // disable scandoubler option from mist.ini
|
||||
.no_csync(no_csync), // csync option from mist.ini
|
||||
.ypbpr(ypbpr), // YPbPr option from mist.ini
|
||||
|
||||
.rotate(2'b00), // no ODS rotation
|
||||
.blend(0), // composite-like blending
|
||||
|
||||
// video input signals to mist_video
|
||||
.R (tms_R ),
|
||||
.G (tms_G ),
|
||||
.B (tms_B ),
|
||||
.HSync(tms_HS),
|
||||
.VSync(tms_vs),
|
||||
|
||||
// video output signals that go into MiST hardware
|
||||
.VGA_R(tms_out_R),
|
||||
.VGA_G(tms_out_G),
|
||||
.VGA_B(tms_out_B),
|
||||
.VGA_VS(tms_out_VS),
|
||||
.VGA_HS(tms_out_HS)
|
||||
);
|
||||
|
||||
/******************************************************************************************/
|
||||
|
@ -450,4 +556,85 @@ clock clock(
|
|||
.pixel_clken( pixel_clken ) // output: pixel clock enable
|
||||
);
|
||||
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @vdp *******************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
wire vram_we;
|
||||
wire [0:13] vram_a;
|
||||
wire [0:7] vram_din;
|
||||
wire [0:7] vram_dout;
|
||||
|
||||
vram vram
|
||||
(
|
||||
.clock ( vdp_clock ),
|
||||
.address( vram_a ),
|
||||
.data ( vram_din ),
|
||||
.wren ( vram_we ),
|
||||
.q ( vram_dout )
|
||||
);
|
||||
|
||||
wire [7:0] vdp_dout;
|
||||
wire VDP_INT_n; // TODO not connected yet
|
||||
|
||||
// divide by two the vdp_clock (which is doubled for the scandoubler)
|
||||
reg vdp_ena;
|
||||
always @(posedge vdp_clock) begin
|
||||
vdp_ena <= ~vdp_ena;
|
||||
end
|
||||
|
||||
wire csr = tms_cs & sdram_rd;
|
||||
wire csw = tms_cs & sdram_wr;
|
||||
|
||||
wire tms_HS;
|
||||
wire tms_VS;
|
||||
wire [5:0] tms_R;
|
||||
wire [5:0] tms_G;
|
||||
wire [5:0] tms_B;
|
||||
|
||||
tms9918_async
|
||||
#(
|
||||
.HORIZONTAL_SHIFT(-36) // -36 good empiric value to center the image on the screen
|
||||
)
|
||||
tms9918
|
||||
(
|
||||
// clock
|
||||
.RESET(reset_button),
|
||||
|
||||
.clk(vdp_clock),
|
||||
.ena(vdp_ena),
|
||||
|
||||
/*
|
||||
.clk(sys_clock),
|
||||
.ena(pixel_clken),
|
||||
*/
|
||||
|
||||
// control signals
|
||||
.csr_n ( ~csr ),
|
||||
.csw_n ( ~csw ),
|
||||
.mode ( sdram_addr[0] ),
|
||||
.int_n ( VDP_INT_n ),
|
||||
|
||||
// cpu I/O
|
||||
.cd_i ( sdram_din ),
|
||||
.cd_o ( vdp_dout ),
|
||||
|
||||
// vram
|
||||
.vram_we ( vram_we ),
|
||||
.vram_a ( vram_a ),
|
||||
.vram_d_o ( vram_din ),
|
||||
.vram_d_i ( vram_dout ),
|
||||
|
||||
// video
|
||||
.HS(tms_HS),
|
||||
.VS(tms_VS),
|
||||
.R (tms_R),
|
||||
.G (tms_G),
|
||||
.B (tms_B)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ module display (
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// Video RAM
|
||||
|
||||
vram vram(
|
||||
display_ram display_ram(
|
||||
.clk(sys_clock),
|
||||
.read_addr(vram_r_addr),
|
||||
.write_addr(vram_w_addr),
|
||||
|
@ -250,7 +250,7 @@ module display (
|
|||
|
||||
if (address == 1'b0) // address low == TX register
|
||||
begin
|
||||
if (cpu_clken & w_en & ~char_seen & ready)
|
||||
if (cpu_clken & w_en /*& ~char_seen*/ & ready)
|
||||
begin
|
||||
// incoming character
|
||||
char_seen <= 1;
|
||||
|
|
58
rtl/pll.v
58
rtl/pll.v
|
@ -43,6 +43,7 @@ module pll (
|
|||
c1,
|
||||
c2,
|
||||
c3,
|
||||
c4,
|
||||
locked);
|
||||
|
||||
input areset;
|
||||
|
@ -51,6 +52,7 @@ module pll (
|
|||
output c1;
|
||||
output c2;
|
||||
output c3;
|
||||
output c4;
|
||||
output locked;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
|
@ -61,25 +63,27 @@ module pll (
|
|||
`endif
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire3;
|
||||
wire [0:0] sub_wire8 = 1'h0;
|
||||
wire [2:2] sub_wire5 = sub_wire0[2:2];
|
||||
wire [0:0] sub_wire4 = sub_wire0[0:0];
|
||||
wire [3:3] sub_wire2 = sub_wire0[3:3];
|
||||
wire sub_wire6;
|
||||
wire [0:0] sub_wire9 = 1'h0;
|
||||
wire [3:3] sub_wire5 = sub_wire0[3:3];
|
||||
wire [4:4] sub_wire4 = sub_wire0[4:4];
|
||||
wire [2:2] sub_wire3 = sub_wire0[2:2];
|
||||
wire [0:0] sub_wire2 = sub_wire0[0:0];
|
||||
wire [1:1] sub_wire1 = sub_wire0[1:1];
|
||||
wire c1 = sub_wire1;
|
||||
wire c3 = sub_wire2;
|
||||
wire locked = sub_wire3;
|
||||
wire c0 = sub_wire4;
|
||||
wire c2 = sub_wire5;
|
||||
wire sub_wire6 = inclk0;
|
||||
wire [1:0] sub_wire7 = {sub_wire8, sub_wire6};
|
||||
wire c0 = sub_wire2;
|
||||
wire c2 = sub_wire3;
|
||||
wire c4 = sub_wire4;
|
||||
wire c3 = sub_wire5;
|
||||
wire locked = sub_wire6;
|
||||
wire sub_wire7 = inclk0;
|
||||
wire [1:0] sub_wire8 = {sub_wire9, sub_wire7};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.inclk (sub_wire7),
|
||||
.inclk (sub_wire8),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire3),
|
||||
.locked (sub_wire6),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
|
@ -131,6 +135,10 @@ module pll (
|
|||
altpll_component.clk3_duty_cycle = 50,
|
||||
altpll_component.clk3_multiply_by = 715909,
|
||||
altpll_component.clk3_phase_shift = "-2500",
|
||||
altpll_component.clk4_divide_by = 900000,
|
||||
altpll_component.clk4_duty_cycle = 50,
|
||||
altpll_component.clk4_multiply_by = 715909,
|
||||
altpll_component.clk4_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 37037,
|
||||
altpll_component.intended_device_family = "Cyclone III",
|
||||
|
@ -167,7 +175,7 @@ module pll (
|
|||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_USED",
|
||||
altpll_component.port_clk3 = "PORT_USED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_USED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
|
@ -208,14 +216,17 @@ endmodule
|
|||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "27"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR4 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE4 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "14.318180"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "7.159090"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "57.272720"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "57.272720"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE4 STRING "21.477270"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
|
@ -239,39 +250,47 @@ endmodule
|
|||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT3 STRING "ps"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT4 STRING "ps"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK3 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK4 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "25"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "25"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR3 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR4 NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "14.31818000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "7.15909000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "57.27272000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "57.27272000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ4 STRING "21.47727000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE3 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE4 STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT3 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT4 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT3 STRING "-2500.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT4 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT3 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT4 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
|
@ -297,6 +316,7 @@ endmodule
|
|||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK3 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK4 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
|
@ -304,10 +324,12 @@ endmodule
|
|||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK3 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK4 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA3 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA4 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
|
@ -328,6 +350,10 @@ endmodule
|
|||
// Retrieval info: CONSTANT: CLK3_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK3_MULTIPLY_BY NUMERIC "715909"
|
||||
// Retrieval info: CONSTANT: CLK3_PHASE_SHIFT STRING "-2500"
|
||||
// Retrieval info: CONSTANT: CLK4_DIVIDE_BY NUMERIC "900000"
|
||||
// Retrieval info: CONSTANT: CLK4_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK4_MULTIPLY_BY NUMERIC "715909"
|
||||
// Retrieval info: CONSTANT: CLK4_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
|
@ -363,7 +389,7 @@ endmodule
|
|||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
|
@ -383,6 +409,7 @@ endmodule
|
|||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
|
||||
// Retrieval info: USED_PORT: c3 0 0 0 0 OUTPUT_CLK_EXT VCC "c3"
|
||||
// Retrieval info: USED_PORT: c4 0 0 0 0 OUTPUT_CLK_EXT VCC "c4"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
|
||||
|
@ -392,6 +419,7 @@ endmodule
|
|||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
|
||||
// Retrieval info: CONNECT: c3 0 0 0 0 @clk 0 0 1 3
|
||||
// Retrieval info: CONNECT: c4 0 0 0 0 @clk 0 0 1 4
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
A9
|
||||
AA
|
||||
20
|
||||
EF
|
||||
FF
|
||||
A9
|
||||
8D
|
||||
20
|
||||
EF
|
||||
FF
|
||||
A0
|
||||
FF
|
||||
C8
|
||||
AD
|
||||
11
|
||||
D0
|
||||
10
|
||||
FB
|
||||
AD
|
||||
10
|
||||
D0
|
||||
99
|
||||
00
|
||||
02
|
||||
20
|
||||
EF
|
||||
FF
|
||||
C9
|
||||
9B
|
||||
F0
|
||||
E1
|
||||
C9
|
||||
8D
|
||||
D0
|
||||
E9
|
||||
A2
|
||||
FF
|
||||
A9
|
||||
00
|
||||
85
|
||||
24
|
||||
85
|
||||
25
|
||||
85
|
||||
26
|
||||
85
|
||||
27
|
||||
E8
|
||||
BD
|
||||
00
|
||||
02
|
||||
C9
|
||||
D2
|
||||
F0
|
||||
56
|
||||
C9
|
||||
D7
|
||||
F0
|
||||
35
|
||||
C9
|
||||
AE
|
||||
F0
|
||||
27
|
||||
C9
|
||||
8D
|
||||
F0
|
||||
20
|
||||
C9
|
||||
A0
|
||||
F0
|
||||
E8
|
||||
49
|
||||
B0
|
||||
C9
|
||||
0A
|
||||
90
|
||||
06
|
||||
69
|
||||
88
|
||||
C9
|
||||
FA
|
||||
90
|
||||
AD
|
||||
0A
|
||||
0A
|
||||
0A
|
||||
0A
|
||||
A0
|
||||
04
|
||||
0A
|
||||
26
|
||||
24
|
||||
26
|
||||
25
|
||||
88
|
||||
D0
|
||||
F8
|
||||
F0
|
||||
CC
|
||||
4C
|
||||
1A
|
||||
FF
|
||||
A5
|
||||
24
|
||||
85
|
||||
26
|
||||
A5
|
||||
25
|
||||
85
|
||||
27
|
||||
B0
|
||||
BF
|
||||
A9
|
||||
40
|
||||
20
|
||||
CC
|
||||
C1
|
||||
88
|
||||
A2
|
||||
00
|
||||
A1
|
||||
26
|
||||
A2
|
||||
10
|
||||
0A
|
||||
20
|
||||
DB
|
||||
C1
|
||||
D0
|
||||
FA
|
||||
20
|
||||
F1
|
||||
C1
|
||||
A0
|
||||
1E
|
||||
90
|
||||
EC
|
||||
A6
|
||||
28
|
||||
B0
|
||||
98
|
||||
20
|
||||
BC
|
||||
C1
|
||||
A9
|
||||
16
|
||||
20
|
||||
CC
|
||||
C1
|
||||
20
|
||||
BC
|
||||
C1
|
||||
A0
|
||||
1F
|
||||
20
|
||||
BF
|
||||
C1
|
||||
B0
|
||||
F9
|
||||
20
|
||||
BF
|
||||
C1
|
||||
A0
|
||||
3A
|
||||
A2
|
||||
08
|
||||
48
|
||||
20
|
||||
BC
|
||||
C1
|
||||
68
|
||||
2A
|
||||
A0
|
||||
39
|
||||
CA
|
||||
D0
|
||||
F5
|
||||
81
|
||||
26
|
||||
20
|
||||
F1
|
||||
C1
|
||||
A0
|
||||
35
|
||||
90
|
||||
EA
|
||||
B0
|
||||
CD
|
||||
20
|
||||
BF
|
||||
C1
|
||||
88
|
||||
AD
|
||||
81
|
||||
C0
|
||||
C5
|
||||
29
|
||||
F0
|
||||
F8
|
||||
85
|
||||
29
|
||||
C0
|
||||
80
|
||||
60
|
||||
86
|
||||
28
|
||||
A0
|
||||
42
|
||||
20
|
||||
E0
|
||||
C1
|
||||
D0
|
||||
F9
|
||||
69
|
||||
FE
|
||||
B0
|
||||
F5
|
||||
A0
|
||||
1E
|
||||
20
|
||||
E0
|
||||
C1
|
||||
A0
|
||||
2C
|
||||
88
|
||||
D0
|
||||
FD
|
||||
90
|
||||
05
|
||||
A0
|
||||
2F
|
||||
88
|
||||
D0
|
||||
FD
|
||||
BC
|
||||
00
|
||||
C0
|
||||
A0
|
||||
29
|
||||
CA
|
||||
60
|
||||
A5
|
||||
26
|
||||
C5
|
||||
24
|
||||
A5
|
||||
27
|
||||
E5
|
||||
25
|
||||
E6
|
||||
26
|
||||
D0
|
||||
02
|
||||
E6
|
||||
27
|
||||
60
|
|
@ -0,0 +1,116 @@
|
|||
module tms9918
|
||||
(
|
||||
input RESET,
|
||||
input clk,
|
||||
input ena,
|
||||
|
||||
// control signals
|
||||
input csr_n,
|
||||
input csw_n,
|
||||
input mode,
|
||||
output int_n,
|
||||
|
||||
// cpu I/O
|
||||
input [0:7] cd_i,
|
||||
output [0:7] cd_o,
|
||||
|
||||
// vram
|
||||
output vram_we,
|
||||
output [0:13] vram_a,
|
||||
output [0:7] vram_d_o,
|
||||
input [0:7] vram_d_i,
|
||||
|
||||
// video
|
||||
output HS,
|
||||
output VS,
|
||||
output [5:0] R,
|
||||
output [5:0] G,
|
||||
output [5:0] B
|
||||
);
|
||||
|
||||
vdp18_core
|
||||
|
||||
#(
|
||||
.is_pal_g(0) // NTSC
|
||||
)
|
||||
|
||||
vdp
|
||||
(
|
||||
.clk_i ( clk ),
|
||||
.clk_en_10m7_i ( ena ),
|
||||
.reset_n_i ( ~RESET ),
|
||||
|
||||
.csr_n_i ( csr_n ),
|
||||
.csw_n_i ( csw_n ),
|
||||
.mode_i ( mode ),
|
||||
.int_n_o ( int_n ),
|
||||
|
||||
.cd_i ( cd_i ),
|
||||
.cd_o ( cd_o ),
|
||||
|
||||
.vram_we_o ( vram_we ),
|
||||
.vram_a_o ( vram_a ),
|
||||
.vram_d_o ( vram_d_o ),
|
||||
.vram_d_i ( vram_d_i ),
|
||||
|
||||
.rgb_r_o ( vdp_r_ ),
|
||||
.rgb_g_o ( vdp_g_ ),
|
||||
.rgb_b_o ( vdp_b_ ),
|
||||
.hsync_n_o ( vdp_hs ),
|
||||
.vsync_n_o ( vdp_vs )
|
||||
|
||||
);
|
||||
|
||||
// video wires
|
||||
wire vdp_vs;
|
||||
wire vdp_hs;
|
||||
wire [0:7] vdp_r_;
|
||||
wire [0:7] vdp_g_;
|
||||
wire [0:7] vdp_b_;
|
||||
wire [5:0] vdp_r = { vdp_r_[0],vdp_r_[1],vdp_r_[2],vdp_r_[3],vdp_r_[4],vdp_r_[5] } ;
|
||||
wire [5:0] vdp_g = { vdp_g_[0],vdp_g_[1],vdp_g_[2],vdp_g_[3],vdp_g_[4],vdp_g_[5] } ;
|
||||
wire [5:0] vdp_b = { vdp_b_[0],vdp_b_[1],vdp_b_[2],vdp_b_[3],vdp_b_[4],vdp_b_[5] } ;
|
||||
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @test ******************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
reg [15:0] hcnt;
|
||||
reg [15:0] vcnt;
|
||||
reg flip = 0;
|
||||
|
||||
localparam EXTRA_PIXELS = 0; // 5
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(ena) begin
|
||||
if(RESET) begin
|
||||
hcnt <= -36;
|
||||
vcnt <= 0;
|
||||
end
|
||||
else begin
|
||||
flip = ~flip;
|
||||
if(flip) begin
|
||||
hcnt <= hcnt + 1;
|
||||
if(hcnt == 341+EXTRA_PIXELS) begin
|
||||
hcnt <= 0;
|
||||
vcnt <= vcnt + 1;
|
||||
if(vcnt == 260) vcnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign VS = 1 ? (vcnt < 4 ? 0 : 1) : vdp_hs;
|
||||
assign HS = 1 ? (hcnt < 20 ? 0 : 1) : vdp_vs;
|
||||
|
||||
wire blank = (vcnt < 8) || (hcnt < 60 || hcnt > 340);
|
||||
|
||||
assign R = 1 ? (blank ? 0 : vdp_r) : vdp_r;
|
||||
assign G = 1 ? (blank ? 0 : vdp_g) : vdp_r;
|
||||
assign B = 1 ? (blank ? 0 : vdp_b) : vdp_r;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,227 @@
|
|||
module tms9918_async
|
||||
(
|
||||
input RESET,
|
||||
input clk,
|
||||
input ena,
|
||||
|
||||
// control signals
|
||||
input csr_n,
|
||||
input csw_n,
|
||||
input mode,
|
||||
output int_n,
|
||||
|
||||
// cpu I/O
|
||||
input [0:7] cd_i,
|
||||
output [0:7] cd_o,
|
||||
|
||||
// vram
|
||||
output vram_we,
|
||||
output [0:13] vram_a,
|
||||
output [0:7] vram_d_o,
|
||||
input [0:7] vram_d_i,
|
||||
|
||||
// video
|
||||
output HS,
|
||||
output VS,
|
||||
output [5:0] R,
|
||||
output [5:0] G,
|
||||
output [5:0] B
|
||||
);
|
||||
|
||||
|
||||
// cross clock domain resolution, from CPU clock to VDP clock;
|
||||
|
||||
reg _metastable_csr_n;
|
||||
reg _metastable_csw_n;
|
||||
reg _metastable_mode;
|
||||
reg [0:7] _metastable_cd_i;
|
||||
reg [0:7] _metastable_cd_o;
|
||||
|
||||
reg _stable_csr_n;
|
||||
reg _stable_csw_n;
|
||||
reg _stable_mode;
|
||||
reg [0:7] _stable_cd_i;
|
||||
reg [0:7] _stable_cd_o;
|
||||
|
||||
reg [0:7] xcd_o;
|
||||
|
||||
assign cd_o = _stable_cd_o;
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
{ _stable_csr_n, _metastable_csr_n } <= { _metastable_csr_n, csr_n };
|
||||
{ _stable_csw_n, _metastable_csw_n } <= { _metastable_csw_n, csw_n };
|
||||
{ _stable_mode , _metastable_mode } <= { _metastable_mode , mode };
|
||||
{ _stable_cd_i , _metastable_cd_i } <= { _metastable_cd_i , cd_i };
|
||||
{ _stable_cd_o , _metastable_cd_o } <= { _metastable_cd_o , xcd_o };
|
||||
|
||||
end
|
||||
|
||||
localparam IS_PAL = 0;
|
||||
parameter HORIZONTAL_SHIFT = -36;
|
||||
|
||||
vdp18_core
|
||||
|
||||
#(
|
||||
.is_pal_g(IS_PAL) // PAL or NTSC
|
||||
)
|
||||
|
||||
vdp
|
||||
(
|
||||
.clk_i ( clk ),
|
||||
.clk_en_10m7_i ( ena ),
|
||||
.reset_n_i ( ~RESET ),
|
||||
|
||||
.csr_n_i ( _stable_csr_n ),
|
||||
.csw_n_i ( _stable_csw_n ),
|
||||
.mode_i ( _stable_mode ),
|
||||
.int_n_o ( int_n ),
|
||||
|
||||
.cd_i ( _stable_cd_i ),
|
||||
.cd_o ( xcd_o ),
|
||||
|
||||
.vram_we_o ( vram_we ),
|
||||
.vram_a_o ( vram_a ),
|
||||
.vram_d_o ( vram_d_o ),
|
||||
.vram_d_i ( vram_d_i ),
|
||||
|
||||
.rgb_r_o ( vdp_r_ ),
|
||||
.rgb_g_o ( vdp_g_ ),
|
||||
.rgb_b_o ( vdp_b_ ),
|
||||
.hsync_n_o ( vdp_hs ),
|
||||
.vsync_n_o ( vdp_vs )
|
||||
|
||||
);
|
||||
|
||||
// video wires
|
||||
wire vdp_vs;
|
||||
wire vdp_hs;
|
||||
wire [0:7] vdp_r_;
|
||||
wire [0:7] vdp_g_;
|
||||
wire [0:7] vdp_b_;
|
||||
wire [5:0] vdp_r = { vdp_r_[0],vdp_r_[1],vdp_r_[2],vdp_r_[3],vdp_r_[4],vdp_r_[5] } ;
|
||||
wire [5:0] vdp_g = { vdp_g_[0],vdp_g_[1],vdp_g_[2],vdp_g_[3],vdp_g_[4],vdp_g_[5] } ;
|
||||
wire [5:0] vdp_b = { vdp_b_[0],vdp_b_[1],vdp_b_[2],vdp_b_[3],vdp_b_[4],vdp_b_[5] } ;
|
||||
|
||||
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
/***************************************** @test ******************************************/
|
||||
/******************************************************************************************/
|
||||
/******************************************************************************************/
|
||||
|
||||
/*
|
||||
reg [15:0] hcnt;
|
||||
reg [15:0] vcnt;
|
||||
reg ena2 = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(ena) begin
|
||||
ena2 <= ~ena2;
|
||||
end
|
||||
end
|
||||
|
||||
// screen geometry
|
||||
// - NTSC: 342 x 261
|
||||
// - PAL: 342 x 312
|
||||
|
||||
localparam SCREEN_HWIDTH = 455;
|
||||
localparam SCREEN_NLINES = IS_PAL ? 312 : 262;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(ena) begin
|
||||
if(RESET) begin
|
||||
hcnt <= 0;
|
||||
vcnt <= 0;
|
||||
end
|
||||
else begin
|
||||
hcnt <= hcnt + 1;
|
||||
if(hcnt == (SCREEN_HWIDTH-1)) begin
|
||||
hcnt <= 0;
|
||||
vcnt <= vcnt + 1;
|
||||
if(vcnt == SCREEN_NLINES-1) vcnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire active = (hcnt >= 104 && hcnt < 424) && (vcnt >= 42 && vcnt < 234);
|
||||
|
||||
wire [2:0] bandcolor = (hcnt - 104) / 40;
|
||||
|
||||
assign HS = hcnt < 32 ? 0 : 1;
|
||||
assign VS = vcnt < 2 ? 0 : 1;
|
||||
assign R = active ? { bandcolor[0], 5'b0 } : 6'b0;
|
||||
assign G = active ? { bandcolor[1], 5'b0 } : 6'b0;
|
||||
assign B = active ? { bandcolor[2], 5'b0 } : 6'b0;
|
||||
*/
|
||||
|
||||
/*
|
||||
localparam raw_output = 0;
|
||||
|
||||
wire blank = (vcnt < 8) || (hcnt < 60 || hcnt > 340);
|
||||
|
||||
wire filtered_hs = (hcnt < 20 ? 0 : 1);
|
||||
wire filtered_vs = (vcnt < 4 ? 0 : 1);
|
||||
|
||||
wire [5:0] filtered_R = (blank ? 0 : vdp_r);
|
||||
wire [5:0] filtered_G = (blank ? 0 : vdp_g);
|
||||
wire [5:0] filtered_B = (blank ? 0 : vdp_b);
|
||||
|
||||
assign HS = raw_output ? vdp_hs : filtered_hs;
|
||||
assign VS = raw_output ? vdp_vs : filtered_vs;
|
||||
assign R = raw_output ? vdp_r : filtered_R;
|
||||
assign G = raw_output ? vdp_g : filtered_G;
|
||||
assign B = raw_output ? vdp_b : filtered_B;
|
||||
*/
|
||||
|
||||
reg [15:0] hcnt;
|
||||
reg [15:0] vcnt;
|
||||
reg flip = 0;
|
||||
|
||||
|
||||
// screen geometry
|
||||
// - NTSC: 342 x 261
|
||||
// - PAL: 342 x 312
|
||||
|
||||
localparam SCREEN_HWIDTH = 342;
|
||||
localparam SCREEN_NLINES = IS_PAL ? 312 : 261;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(ena) begin
|
||||
if(RESET) begin
|
||||
hcnt <= HORIZONTAL_SHIFT; // -36 is a good value for my CRT TV
|
||||
vcnt <= 0;
|
||||
end
|
||||
else begin
|
||||
flip = ~flip;
|
||||
if(flip) begin
|
||||
hcnt <= hcnt + 1;
|
||||
if(hcnt == (SCREEN_HWIDTH-1)) begin
|
||||
hcnt <= 0;
|
||||
vcnt <= vcnt + 1;
|
||||
if(vcnt == SCREEN_NLINES-1) vcnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
localparam raw_output = 0;
|
||||
|
||||
wire blank = (vcnt < 8) || (hcnt < 60 || hcnt > 340);
|
||||
|
||||
wire filtered_hs = (hcnt < 20 ? 0 : 1);
|
||||
wire filtered_vs = (vcnt < 4 ? 0 : 1);
|
||||
|
||||
wire [5:0] filtered_R = (blank ? 0 : vdp_r);
|
||||
wire [5:0] filtered_G = (blank ? 0 : vdp_g);
|
||||
wire [5:0] filtered_B = (blank ? 0 : vdp_b);
|
||||
|
||||
assign HS = raw_output ? vdp_hs : filtered_hs;
|
||||
assign VS = raw_output ? vdp_vs : filtered_vs;
|
||||
assign R = raw_output ? vdp_r : filtered_R;
|
||||
assign G = raw_output ? vdp_g : filtered_G;
|
||||
assign B = raw_output ? vdp_b : filtered_B;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,201 @@
|
|||
|
||||
A Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A
|
||||
==========================================================
|
||||
Version: $Date: 2006/06/18 19:28:06 $
|
||||
|
||||
Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
See the file COPYING.
|
||||
|
||||
|
||||
Integration
|
||||
-----------
|
||||
|
||||
The vdp18 design exhibits a set of interface signals that is compatible to the
|
||||
original chips. It mainly differs in the video and VRAM interfaces, which are
|
||||
tailored to better fit a modern SoC.
|
||||
|
||||
generic (
|
||||
is_pal_g : integer := 0;
|
||||
-- Select PAL or NTSC video timing.
|
||||
-- 0 = NTSC
|
||||
-- 1 = PAL
|
||||
|
||||
compat_rgb_g : integer := 0
|
||||
-- Select full or compatibility RGB palettes.
|
||||
-- Refer to vdp18_col_pack-p.vhd for details.
|
||||
|
||||
);
|
||||
port (
|
||||
-- Global Interface -------------------------------------------------------
|
||||
clk_i : in std_logic;
|
||||
-- Global clock input
|
||||
-- Equivalent to XTAL1/2 on TMS9918A.
|
||||
-- Drive with the target frequency of 10.7 MHz or any integer multiple.
|
||||
|
||||
clk_en_10m7_i : in std_logic;
|
||||
-- Clock enable
|
||||
-- A '1' on this input qualifies a valid rising edge on clk_i. A '0'
|
||||
-- disables the next rising clock edge, effectivley halting the design
|
||||
-- until the next enabled rising clock edge.
|
||||
-- Can be used to run the core at lower frequencies than applied on
|
||||
-- clk_i.
|
||||
|
||||
reset_n_i : in std_logic;
|
||||
-- Asynchronous low active reset input
|
||||
-- Sets all sequential elements to a known state.
|
||||
-- NOTE: SYNC operation not supported.
|
||||
|
||||
-- CPU Interface ----------------------------------------------------------
|
||||
csr_n_i : in std_logic;
|
||||
-- CPU-VDP read strobe, low active
|
||||
|
||||
csw_n_i : in std_logic;
|
||||
-- CPU-VDP write strobe, low active
|
||||
|
||||
mode_i : in std_logic;
|
||||
-- CPU interface mode select
|
||||
|
||||
int_n_o : out std_logic;
|
||||
-- CPU interrupt output, low active
|
||||
|
||||
cd_i : in std_logic_vector(0 to 7);
|
||||
-- CPU data bus input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
cd_o : out std_logic_vector(0 to 7);
|
||||
-- CPU data bus output
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
-- VRAM Interface ---------------------------------------------------------
|
||||
vram_we_o : out std_logic;
|
||||
-- VRAM write enable
|
||||
|
||||
vram_a_o : out std_logic_vector(0 to 13);
|
||||
-- VRAM address output
|
||||
-- MSB 0 ... 13 LSB
|
||||
|
||||
vram_d_o : out std_logic_vector(0 to 7);
|
||||
-- VRAM data output
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
-- VRAM data input
|
||||
-- MSB 0 ... 7 LSB
|
||||
|
||||
-- Video Interface --------------------------------------------------------
|
||||
col_o : out std_logic_vector(0 to 3);
|
||||
-- Color code output
|
||||
-- Encoded pixel color information
|
||||
|
||||
rgb_r_o : out std_logic_vector(0 to 7);
|
||||
-- Red color information
|
||||
|
||||
rgb_g_o : out std_logic_vector(0 to 7);
|
||||
-- Green color information
|
||||
|
||||
rgb_b_o : out std_logic_vector(0 to 7);
|
||||
-- Blue color information
|
||||
|
||||
hsync_n_o : out std_logic;
|
||||
-- Horizontal synchronization pulse, active low
|
||||
|
||||
vsync_n_o : out std_logic;
|
||||
-- Vertical synchronization pulse, active low
|
||||
|
||||
comp_sync_n_o : out std_logic
|
||||
-- Composite synchronization pulse, active low
|
||||
);
|
||||
|
||||
|
||||
All 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the MSB
|
||||
and bit 7 to be the LSB. This has been implemented according to TI's data
|
||||
sheet, thus all register/data format figures apply 1:1 for this design.
|
||||
Many systems will flip the system data bus bit wise before it is connected to
|
||||
this PSG. This is simply achieved with the following VHDL construct:
|
||||
|
||||
signal data_s : std_logic_vector(7 downto 0);
|
||||
|
||||
...
|
||||
cd_i => data_s,
|
||||
...
|
||||
|
||||
d_i and data_s will be assigned from left to right, resulting in the expected
|
||||
bit assignment:
|
||||
|
||||
cd_i data_s
|
||||
0 7
|
||||
1 6
|
||||
...
|
||||
6 1
|
||||
7 0
|
||||
|
||||
|
||||
As this design is fully synchronous, care has to be taken when the design
|
||||
replaces an TMS99x8 in asynchronous mode. No problems are expected when
|
||||
interfacing the code to other synchronous components.
|
||||
|
||||
|
||||
Design Hierarchy
|
||||
----------------
|
||||
|
||||
vdp18_core
|
||||
|
|
||||
+-- vdp18_clk_gen
|
||||
|
|
||||
+-- vdp18_hor_vert
|
||||
|
|
||||
+-- vdp18_ctrl
|
||||
|
|
||||
+-- vdp18_cpuio
|
||||
|
|
||||
+-- vdp18_addr_mux
|
||||
|
|
||||
+-- vdp18_pattern
|
||||
|
|
||||
+-- vdp18_sprite
|
||||
|
|
||||
\-- vdp18_col_mux
|
||||
|
||||
Resulting compolation sequence:
|
||||
|
||||
vdp18_pack-p.vhd
|
||||
vdp18_comp_pack-p.vhd
|
||||
vdp18_core.vhd
|
||||
vdp18_clk_gen.vhd
|
||||
vdp18_clk_gen-c.vhd
|
||||
vdp18_hor_vert.vhd
|
||||
vdp18_hor_vert-c.vhd
|
||||
vdp18_ctrl.vhd
|
||||
vdp18_ctrl-c.vhd
|
||||
vdp18_cpuio.vhd
|
||||
vdp18_cpuio-c.vhd
|
||||
vdp18_addr_mux.vhd
|
||||
vdp18_addr_mux-c.vhd
|
||||
vdp18_pattern.vhd
|
||||
vdp18_pattern-c.vhd
|
||||
vdp18_sprite.vhd
|
||||
vdp18_sprite-c.vhd
|
||||
vdp18_col_mux.vhd
|
||||
vdp18_col_mux-c.vhd
|
||||
vdp18_core-c.vhd
|
||||
vdp18_core_com_pack-p.vhd
|
||||
|
||||
Skip the files containing VHDL configurations when analyzing the code for
|
||||
synthesis.
|
||||
|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
* TI Data book TMS9918.pdf
|
||||
http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf
|
||||
|
||||
* Sean Young's tech article:
|
||||
http://bifi.msxnet.org/msxnet/tech/tms9918a.txt
|
||||
|
||||
* Paul Urbanus' discussion of the timing details
|
||||
http://bifi.msxnet.org/msxnet/tech/tmsposting.txt
|
||||
|
||||
* Richard F. Drushel's article series
|
||||
"This Week With My Coleco ADAM"
|
||||
http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_addr_mux-c.vhd,v 1.5 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_addr_mux_rtl_c0 of vdp18_addr_mux is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_addr_mux_rtl_c0;
|
|
@ -0,0 +1,228 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_addr_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Address Multiplexer / Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.vdp18_pack.access_t;
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
|
||||
entity vdp18_addr_mux is
|
||||
|
||||
port (
|
||||
access_type_i : in access_t;
|
||||
opmode_i : in opmode_t;
|
||||
num_line_i : in hv_t;
|
||||
reg_ntb_i : in std_logic_vector(0 to 3);
|
||||
reg_ctb_i : in std_logic_vector(0 to 7);
|
||||
reg_pgb_i : in std_logic_vector(0 to 2);
|
||||
reg_satb_i : in std_logic_vector(0 to 6);
|
||||
reg_spgb_i : in std_logic_vector(0 to 2);
|
||||
reg_size1_i : in boolean;
|
||||
cpu_vram_a_i : in std_logic_vector(0 to 13);
|
||||
pat_table_i : in std_logic_vector(0 to 9);
|
||||
pat_name_i : in std_logic_vector(0 to 7);
|
||||
spr_num_i : in std_logic_vector(0 to 4);
|
||||
spr_line_i : in std_logic_vector(0 to 3);
|
||||
spr_name_i : in std_logic_vector(0 to 7);
|
||||
vram_a_o : out std_logic_vector(0 to 13)
|
||||
);
|
||||
|
||||
end vdp18_addr_mux;
|
||||
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_addr_mux is
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process mux
|
||||
--
|
||||
-- Purpose:
|
||||
-- Generates the VRAM address based on the current access type.
|
||||
--
|
||||
mux: process (access_type_i, opmode_i,
|
||||
num_line_i,
|
||||
reg_ntb_i, reg_ctb_i, reg_pgb_i,
|
||||
reg_satb_i, reg_spgb_i,
|
||||
reg_size1_i,
|
||||
cpu_vram_a_i,
|
||||
pat_table_i, pat_name_i,
|
||||
spr_num_i, spr_name_i,
|
||||
spr_line_i)
|
||||
variable num_line_v : std_logic_vector(num_line_i'range);
|
||||
begin
|
||||
-- default assignment
|
||||
vram_a_o <= (others => '0');
|
||||
num_line_v := std_logic_vector(num_line_i);
|
||||
|
||||
case access_type_i is
|
||||
-- CPU Access -----------------------------------------------------------
|
||||
when AC_CPU =>
|
||||
vram_a_o <= cpu_vram_a_i;
|
||||
|
||||
-- Pattern Name Table Access --------------------------------------------
|
||||
when AC_PNT =>
|
||||
vram_a_o(0 to 3) <= reg_ntb_i;
|
||||
vram_a_o(4 to 13) <= pat_table_i;
|
||||
|
||||
-- Pattern Color Table Access -------------------------------------------
|
||||
when AC_PCT =>
|
||||
case opmode_i is
|
||||
when OPMODE_GRAPH1 =>
|
||||
vram_a_o( 0 to 7) <= reg_ctb_i;
|
||||
vram_a_o( 8) <= '0';
|
||||
vram_a_o( 9 to 13) <= pat_name_i(0 to 4);
|
||||
|
||||
when OPMODE_GRAPH2 =>
|
||||
vram_a_o( 0) <= reg_ctb_i(0);
|
||||
vram_a_o( 1 to 2) <= num_line_v(1 to 2) and
|
||||
-- remaining bits in CTB mask color
|
||||
-- lookups
|
||||
(reg_ctb_i(1) & reg_ctb_i(2));
|
||||
vram_a_o( 3 to 10) <= pat_name_i and
|
||||
-- remaining bits in CTB mask color
|
||||
-- lookups
|
||||
(reg_ctb_i(3) & reg_ctb_i(4) &
|
||||
reg_ctb_i(5) & reg_ctb_i(6) &
|
||||
reg_ctb_i(7) & "111");
|
||||
vram_a_o(11 to 13) <= num_line_v(6 to 8);
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- Pattern Generator Table Access ---------------------------------------
|
||||
when AC_PGT =>
|
||||
case opmode_i is
|
||||
when OPMODE_TEXTM |
|
||||
OPMODE_GRAPH1 =>
|
||||
vram_a_o( 0 to 2) <= reg_pgb_i;
|
||||
vram_a_o( 3 to 10) <= pat_name_i;
|
||||
vram_a_o(11 to 13) <= num_line_v(6 to 8);
|
||||
|
||||
when OPMODE_MULTIC =>
|
||||
vram_a_o( 0 to 2) <= reg_pgb_i;
|
||||
vram_a_o( 3 to 10) <= pat_name_i;
|
||||
vram_a_o(11 to 13) <= num_line_v(4 to 6);
|
||||
|
||||
when OPMODE_GRAPH2 =>
|
||||
vram_a_o( 0) <= reg_pgb_i(0);
|
||||
vram_a_o( 1 to 2) <= num_line_v(1 to 2) and
|
||||
-- remaining bits in PGB mask pattern
|
||||
-- lookups
|
||||
(reg_pgb_i(1) & reg_pgb_i(2));
|
||||
vram_a_o( 3 to 10) <= pat_name_i and
|
||||
-- remaining bits in CTB mask pattern
|
||||
-- lookups
|
||||
(reg_ctb_i(3) & reg_ctb_i(4) &
|
||||
reg_ctb_i(5) & reg_ctb_i(6) &
|
||||
reg_ctb_i(7) & "111");
|
||||
vram_a_o(11 to 13) <= num_line_v(6 to 8);
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- Sprite Test ----------------------------------------------------------
|
||||
when AC_STST |
|
||||
AC_SATY =>
|
||||
vram_a_o( 0 to 6) <= reg_satb_i;
|
||||
vram_a_o( 7 to 11) <= spr_num_i;
|
||||
vram_a_o(12 to 13) <= "00";
|
||||
|
||||
-- Sprite Attribute Table: X --------------------------------------------
|
||||
when AC_SATX =>
|
||||
vram_a_o( 0 to 6) <= reg_satb_i;
|
||||
vram_a_o( 7 to 11) <= spr_num_i;
|
||||
vram_a_o(12 to 13) <= "01";
|
||||
|
||||
-- Sprite Attribute Table: Name -----------------------------------------
|
||||
when AC_SATN =>
|
||||
vram_a_o( 0 to 6) <= reg_satb_i;
|
||||
vram_a_o( 7 to 11) <= spr_num_i;
|
||||
vram_a_o(12 to 13) <= "10";
|
||||
|
||||
-- Sprite Attribute Table: Color ----------------------------------------
|
||||
when AC_SATC =>
|
||||
vram_a_o( 0 to 6) <= reg_satb_i;
|
||||
vram_a_o( 7 to 11) <= spr_num_i;
|
||||
vram_a_o(12 to 13) <= "11";
|
||||
|
||||
-- Sprite Pattern, Upper Part -------------------------------------------
|
||||
when AC_SPTH =>
|
||||
vram_a_o( 0 to 2) <= reg_spgb_i;
|
||||
if not reg_size1_i then
|
||||
-- 8x8 sprite
|
||||
vram_a_o( 3 to 10) <= spr_name_i;
|
||||
vram_a_o(11 to 13) <= spr_line_i(1 to 3);
|
||||
else
|
||||
-- 16x16 sprite
|
||||
vram_a_o( 3 to 8) <= spr_name_i(0 to 5);
|
||||
vram_a_o( 9) <= '0';
|
||||
vram_a_o(10 to 13) <= spr_line_i;
|
||||
end if;
|
||||
|
||||
-- Sprite Pattern, Lower Part -------------------------------------------
|
||||
when AC_SPTL =>
|
||||
vram_a_o( 0 to 2) <= reg_spgb_i;
|
||||
vram_a_o( 3 to 8) <= spr_name_i(0 to 5);
|
||||
vram_a_o( 9) <= '1';
|
||||
vram_a_o(10 to 13) <= spr_line_i;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
|
||||
end process mux;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_clk_gen-c.vhd,v 1.5 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_clk_gen_rtl_c0 of vdp18_clk_gen is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_clk_gen_rtl_c0;
|
|
@ -0,0 +1,154 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_clk_gen.vhd,v 1.8 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Clock Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity vdp18_clk_gen is
|
||||
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in std_logic;
|
||||
reset_i : in boolean;
|
||||
clk_en_5m37_o : out boolean;
|
||||
clk_en_3m58_o : out boolean;
|
||||
clk_en_2m68_o : out boolean
|
||||
);
|
||||
|
||||
end vdp18_clk_gen;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
architecture rtl of vdp18_clk_gen is
|
||||
|
||||
signal cnt_q : unsigned(3 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
-- * clock counter
|
||||
--
|
||||
seq: process (clk_i, reset_i)
|
||||
variable cnt_v : integer range -256 to 255;
|
||||
begin
|
||||
if reset_i then
|
||||
cnt_q <= (others => '0');
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_10m7_i = '1' then
|
||||
if cnt_q = 11 then
|
||||
-- wrap after counting 12 clocks
|
||||
cnt_q <= (others => '0');
|
||||
else
|
||||
cnt_q <= cnt_q + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process clk_en
|
||||
--
|
||||
-- Purpose:
|
||||
-- Generates the derived clock enable signals.
|
||||
--
|
||||
clk_en: process (clk_en_10m7_i,
|
||||
cnt_q)
|
||||
variable cnt_v : integer range -256 to 255;
|
||||
begin
|
||||
cnt_v := to_integer(cnt_q);
|
||||
|
||||
-- 5.37 MHz clock enable --------------------------------------------------
|
||||
if clk_en_10m7_i = '1' then
|
||||
case cnt_v is
|
||||
when 1 | 3 | 5 | 7 | 9 | 11 =>
|
||||
clk_en_5m37_o <= true;
|
||||
when others =>
|
||||
clk_en_5m37_o <= false;
|
||||
end case;
|
||||
else
|
||||
clk_en_5m37_o <= false;
|
||||
end if;
|
||||
|
||||
-- 3.58 MHz clock enable --------------------------------------------------
|
||||
if clk_en_10m7_i = '1' then
|
||||
case cnt_v is
|
||||
when 2 | 5 | 8 | 11 =>
|
||||
clk_en_3m58_o <= true;
|
||||
when others =>
|
||||
clk_en_3m58_o <= false;
|
||||
end case;
|
||||
else
|
||||
clk_en_3m58_o <= false;
|
||||
end if;
|
||||
|
||||
-- 2.68 MHz clock enable --------------------------------------------------
|
||||
if clk_en_10m7_i = '1' then
|
||||
case cnt_v is
|
||||
when 3 | 7 | 11 =>
|
||||
clk_en_2m68_o <= true;
|
||||
when others =>
|
||||
clk_en_2m68_o <= false;
|
||||
end case;
|
||||
else
|
||||
clk_en_2m68_o <= false;
|
||||
end if;
|
||||
|
||||
end process clk_en;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_col_mux-c.vhd,v 1.3 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_col_mux_rtl_c0 of vdp18_col_mux is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_col_mux_rtl_c0;
|
|
@ -0,0 +1,184 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_col_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Color Information Multiplexer
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity vdp18_col_mux is
|
||||
|
||||
generic (
|
||||
compat_rgb_g : integer := 0
|
||||
);
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
vert_active_i : in boolean;
|
||||
hor_active_i : in boolean;
|
||||
blank_i : in boolean;
|
||||
reg_col0_i : in std_logic_vector(0 to 3);
|
||||
pat_col_i : in std_logic_vector(0 to 3);
|
||||
spr0_col_i : in std_logic_vector(0 to 3);
|
||||
spr1_col_i : in std_logic_vector(0 to 3);
|
||||
spr2_col_i : in std_logic_vector(0 to 3);
|
||||
spr3_col_i : in std_logic_vector(0 to 3);
|
||||
col_o : out std_logic_vector(0 to 3);
|
||||
rgb_r_o : out std_logic_vector(0 to 7);
|
||||
rgb_g_o : out std_logic_vector(0 to 7);
|
||||
rgb_b_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
|
||||
end vdp18_col_mux;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_col_pack.all;
|
||||
|
||||
architecture rtl of vdp18_col_mux is
|
||||
|
||||
signal col_s : std_logic_vector(0 to 3);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process col_mux
|
||||
--
|
||||
-- Purpose:
|
||||
-- Multiplexes the color information from different sources.
|
||||
--
|
||||
col_mux: process (blank_i,
|
||||
hor_active_i, vert_active_i,
|
||||
spr0_col_i, spr1_col_i,
|
||||
spr2_col_i, spr3_col_i,
|
||||
pat_col_i,
|
||||
reg_col0_i)
|
||||
begin
|
||||
if not blank_i then
|
||||
if hor_active_i and vert_active_i then
|
||||
-- priority decoder
|
||||
if spr0_col_i /= "0000" then
|
||||
col_s <= spr0_col_i;
|
||||
elsif spr1_col_i /= "0000" then
|
||||
col_s <= spr1_col_i;
|
||||
elsif spr2_col_i /= "0000" then
|
||||
col_s <= spr2_col_i;
|
||||
elsif spr3_col_i /= "0000" then
|
||||
col_s <= spr3_col_i;
|
||||
elsif pat_col_i /= "0000" then
|
||||
col_s <= pat_col_i;
|
||||
else
|
||||
col_s <= reg_col0_i;
|
||||
end if;
|
||||
|
||||
else
|
||||
-- display border
|
||||
col_s <= reg_col0_i;
|
||||
end if;
|
||||
|
||||
else
|
||||
-- blank color channels during horizontal and vertical
|
||||
-- trace back
|
||||
-- required to initialize colors for each new scan line
|
||||
col_s <= (others => '0');
|
||||
end if;
|
||||
end process col_mux;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process rgb_reg
|
||||
--
|
||||
-- Purpose:
|
||||
-- Converts the color information to simple RGB and saves these in
|
||||
-- output registers.
|
||||
--
|
||||
rgb_reg: process (clk_i, reset_i)
|
||||
variable col_v : natural range 0 to 15;
|
||||
variable rgb_r_v,
|
||||
rgb_g_v,
|
||||
rgb_b_v : rgb_val_t;
|
||||
variable rgb_table_v : rgb_table_t;
|
||||
begin
|
||||
if reset_i then
|
||||
rgb_r_o <= (others => '0');
|
||||
rgb_g_o <= (others => '0');
|
||||
rgb_b_o <= (others => '0');
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_5m37_i then
|
||||
-- select requested RGB table
|
||||
if compat_rgb_g = 1 then
|
||||
rgb_table_v := compat_rgb_table_c;
|
||||
else
|
||||
rgb_table_v := full_rgb_table_c;
|
||||
end if;
|
||||
|
||||
-- assign color to RGB channels
|
||||
col_v := to_integer(unsigned(col_s));
|
||||
rgb_r_v := rgb_table_v(col_v)(r_c);
|
||||
rgb_g_v := rgb_table_v(col_v)(g_c);
|
||||
rgb_b_v := rgb_table_v(col_v)(b_c);
|
||||
--
|
||||
rgb_r_o <= std_logic_vector(to_unsigned(rgb_r_v, 8));
|
||||
rgb_g_o <= std_logic_vector(to_unsigned(rgb_g_v, 8));
|
||||
rgb_b_o <= std_logic_vector(to_unsigned(rgb_b_v, 8));
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process rgb_reg;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
col_o <= col_s;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,83 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- $Id: vdp18_col_pack-p.vhd,v 1.3 2006/02/28 22:30:41 arnim Exp $
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package vdp18_col_pack is
|
||||
|
||||
constant r_c : natural := 0;
|
||||
constant g_c : natural := 1;
|
||||
constant b_c : natural := 2;
|
||||
|
||||
subtype rgb_val_t is natural range 0 to 255;
|
||||
type rgb_triple_t is array (natural range 0 to 2) of
|
||||
rgb_val_t;
|
||||
type rgb_table_t is array (natural range 0 to 15) of
|
||||
rgb_triple_t;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Simple RGB Value Array
|
||||
--
|
||||
-- Refer to http://junior.apk.net/~drushel/pub/coleco/twwmca/wk970202.html
|
||||
-- This is the MF & MdK variant. Note: only the upper three bits are used.
|
||||
--
|
||||
--
|
||||
constant compat_rgb_table_c : rgb_table_t := (
|
||||
-- R G B
|
||||
( 0, 0, 0), -- Transparent
|
||||
( 0, 0, 0), -- Black
|
||||
( 32, 192, 32), -- Medium Green
|
||||
( 96, 224, 96), -- Light Green
|
||||
( 32, 32, 224), -- Dark Blue
|
||||
( 64, 96, 224), -- Light Blue
|
||||
(160, 32, 32), -- Dark Red
|
||||
( 64, 192, 224), -- Cyan
|
||||
(224, 32, 32), -- Medium Red
|
||||
(224, 96, 96), -- Light Red
|
||||
(192, 192, 32), -- Dark Yellow
|
||||
(192, 192, 128), -- Light Yellow
|
||||
( 32, 128, 32), -- Dark Green
|
||||
(192, 64, 160), -- Magenta
|
||||
(160, 160, 160), -- Gray
|
||||
(224, 224, 224) -- White
|
||||
);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Full RGB Value Array
|
||||
--
|
||||
-- Refer to tms9928a.c of the MAME source distribution.
|
||||
--
|
||||
constant full_rgb_table_c : rgb_table_t := (
|
||||
-- R G B
|
||||
( 0, 0, 0), -- Transparent
|
||||
( 0, 0, 0), -- Black
|
||||
( 33, 200, 66), -- Medium Green
|
||||
( 94, 220, 120), -- Light Green
|
||||
( 84, 85, 237), -- Dark Blue
|
||||
(125, 118, 252), -- Light Blue
|
||||
(212, 82, 77), -- Dark Red
|
||||
( 66, 235, 245), -- Cyan
|
||||
(252, 85, 84), -- Medium Red
|
||||
(255, 121, 120), -- Light Red
|
||||
(212, 193, 84), -- Dark Yellow
|
||||
(230, 206, 128), -- Light Yellow
|
||||
( 33, 176, 59), -- Dark Green
|
||||
(201, 91, 186), -- Magenta
|
||||
(204, 204, 204), -- Gray
|
||||
(255, 255, 255) -- White
|
||||
);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end vdp18_col_pack;
|
|
@ -0,0 +1,199 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- $Id: vdp18_comp_pack-p.vhd,v 1.23 2006/02/28 22:30:41 arnim Exp $
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
use work.vdp18_pack.access_t;
|
||||
|
||||
package vdp18_comp_pack is
|
||||
|
||||
component vdp18_clk_gen
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in std_logic;
|
||||
reset_i : in boolean;
|
||||
clk_en_5m37_o : out boolean;
|
||||
clk_en_3m58_o : out boolean;
|
||||
clk_en_2m68_o : out boolean
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_hor_vert
|
||||
generic (
|
||||
is_pal_g : integer := 0
|
||||
);
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
num_pix_o : out hv_t;
|
||||
num_line_o : out hv_t;
|
||||
vert_inc_o : out boolean;
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
blank_o : out boolean
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_ctrl
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
num_pix_i : in hv_t;
|
||||
num_line_i : in hv_t;
|
||||
vert_inc_i : in boolean;
|
||||
reg_blank_i : in boolean;
|
||||
reg_size1_i : in boolean;
|
||||
stop_sprite_i : in boolean;
|
||||
clk_en_acc_o : out boolean;
|
||||
access_type_o : out access_t;
|
||||
vert_active_o : out boolean;
|
||||
hor_active_o : out boolean;
|
||||
irq_o : out boolean
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_cpuio
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
rd_i : in boolean;
|
||||
wr_i : in boolean;
|
||||
mode_i : in std_logic;
|
||||
cd_i : in std_logic_vector(0 to 7);
|
||||
cd_o : out std_logic_vector(0 to 7);
|
||||
cd_oe_o : out std_logic;
|
||||
access_type_i : in access_t;
|
||||
opmode_o : out opmode_t;
|
||||
vram_we_o : out std_logic;
|
||||
vram_a_o : out std_logic_vector(0 to 13);
|
||||
vram_d_o : out std_logic_vector(0 to 7);
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
spr_coll_i : in boolean;
|
||||
spr_5th_i : in boolean;
|
||||
spr_5th_num_i : in std_logic_vector(0 to 4);
|
||||
reg_ev_o : out boolean;
|
||||
reg_16k_o : out boolean;
|
||||
reg_blank_o : out boolean;
|
||||
reg_size1_o : out boolean;
|
||||
reg_mag1_o : out boolean;
|
||||
reg_ntb_o : out std_logic_vector(0 to 3);
|
||||
reg_ctb_o : out std_logic_vector(0 to 7);
|
||||
reg_pgb_o : out std_logic_vector(0 to 2);
|
||||
reg_satb_o : out std_logic_vector(0 to 6);
|
||||
reg_spgb_o : out std_logic_vector(0 to 2);
|
||||
reg_col1_o : out std_logic_vector(0 to 3);
|
||||
reg_col0_o : out std_logic_vector(0 to 3);
|
||||
irq_i : in boolean;
|
||||
int_n_o : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_addr_mux
|
||||
port (
|
||||
access_type_i : in access_t;
|
||||
opmode_i : in opmode_t;
|
||||
num_line_i : in hv_t;
|
||||
reg_ntb_i : in std_logic_vector(0 to 3);
|
||||
reg_ctb_i : in std_logic_vector(0 to 7);
|
||||
reg_pgb_i : in std_logic_vector(0 to 2);
|
||||
reg_satb_i : in std_logic_vector(0 to 6);
|
||||
reg_spgb_i : in std_logic_vector(0 to 2);
|
||||
reg_size1_i : in boolean;
|
||||
cpu_vram_a_i : in std_logic_vector(0 to 13);
|
||||
pat_table_i : in std_logic_vector(0 to 9);
|
||||
pat_name_i : in std_logic_vector(0 to 7);
|
||||
spr_num_i : in std_logic_vector(0 to 4);
|
||||
spr_line_i : in std_logic_vector(0 to 3);
|
||||
spr_name_i : in std_logic_vector(0 to 7);
|
||||
vram_a_o : out std_logic_vector(0 to 13)
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_pattern
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
access_type_i : in access_t;
|
||||
num_line_i : in hv_t;
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
vert_inc_i : in boolean;
|
||||
vsync_n_i : in std_logic;
|
||||
reg_col1_i : in std_logic_vector(0 to 3);
|
||||
reg_col0_i : in std_logic_vector(0 to 3);
|
||||
pat_table_o : out std_logic_vector(0 to 9);
|
||||
pat_name_o : out std_logic_vector(0 to 7);
|
||||
pat_col_o : out std_logic_vector(0 to 3)
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_sprite
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
access_type_i : in access_t;
|
||||
num_pix_i : in hv_t;
|
||||
num_line_i : in hv_t;
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
vert_inc_i : in boolean;
|
||||
reg_size1_i : in boolean;
|
||||
reg_mag1_i : in boolean;
|
||||
spr_5th_o : out boolean;
|
||||
spr_5th_num_o : out std_logic_vector(0 to 4);
|
||||
stop_sprite_o : out boolean;
|
||||
spr_coll_o : out boolean;
|
||||
spr_num_o : out std_logic_vector(0 to 4);
|
||||
spr_line_o : out std_logic_vector(0 to 3);
|
||||
spr_name_o : out std_logic_vector(0 to 7);
|
||||
spr0_col_o : out std_logic_vector(0 to 3);
|
||||
spr1_col_o : out std_logic_vector(0 to 3);
|
||||
spr2_col_o : out std_logic_vector(0 to 3);
|
||||
spr3_col_o : out std_logic_vector(0 to 3)
|
||||
);
|
||||
end component;
|
||||
|
||||
component vdp18_col_mux
|
||||
generic (
|
||||
compat_rgb_g : integer := 0
|
||||
);
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
vert_active_i : in boolean;
|
||||
hor_active_i : in boolean;
|
||||
blank_i : in boolean;
|
||||
reg_col0_i : in std_logic_vector(0 to 3);
|
||||
pat_col_i : in std_logic_vector(0 to 3);
|
||||
spr0_col_i : in std_logic_vector(0 to 3);
|
||||
spr1_col_i : in std_logic_vector(0 to 3);
|
||||
spr2_col_i : in std_logic_vector(0 to 3);
|
||||
spr3_col_i : in std_logic_vector(0 to 3);
|
||||
col_o : out std_logic_vector(0 to 3);
|
||||
rgb_r_o : out std_logic_vector(0 to 7);
|
||||
rgb_g_o : out std_logic_vector(0 to 7);
|
||||
rgb_b_o : out std_logic_vector(0 to 7)
|
||||
);
|
||||
end component;
|
||||
|
||||
end vdp18_comp_pack;
|
|
@ -0,0 +1,47 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_core-c.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_core_struct_c0 of vdp18_core is
|
||||
|
||||
for struct
|
||||
|
||||
for clk_gen_b: vdp18_clk_gen
|
||||
use configuration work.vdp18_clk_gen_rtl_c0;
|
||||
end for;
|
||||
|
||||
for hor_vert_b: vdp18_hor_vert
|
||||
use configuration work.vdp18_hor_vert_rtl_c0;
|
||||
end for;
|
||||
|
||||
for ctrl_b: vdp18_ctrl
|
||||
use configuration work.vdp18_ctrl_rtl_c0;
|
||||
end for;
|
||||
|
||||
for cpu_io_b: vdp18_cpuio
|
||||
use configuration work.vdp18_cpuio_rtl_c0;
|
||||
end for;
|
||||
|
||||
for addr_mux_b: vdp18_addr_mux
|
||||
use configuration work.vdp18_addr_mux_rtl_c0;
|
||||
end for;
|
||||
|
||||
for pattern_b: vdp18_pattern
|
||||
use configuration work.vdp18_pattern_rtl_c0;
|
||||
end for;
|
||||
|
||||
for sprite_b: vdp18_sprite
|
||||
use configuration work.vdp18_sprite_rtl_c0;
|
||||
end for;
|
||||
|
||||
for col_mux_b: vdp18_col_mux
|
||||
use configuration work.vdp18_col_mux_rtl_c0;
|
||||
end for;
|
||||
|
||||
end for;
|
||||
|
||||
end vdp18_core_struct_c0;
|
|
@ -0,0 +1,397 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_core.vhd,v 1.28 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Core Toplevel
|
||||
--
|
||||
-- Notes:
|
||||
-- This core implements a simple VRAM interface which is suitable for a
|
||||
-- synchronous SRAM component. There is currently no support of the
|
||||
-- original DRAM interface.
|
||||
--
|
||||
-- Please be aware that the colors might me slightly different from the
|
||||
-- original TMS9918. It is assumed that the simplified conversion to RGB
|
||||
-- encoding is equivalent to the compatability mode of the V9938.
|
||||
-- Implementing a 100% correct color encoding for RGB would require
|
||||
-- significantly more logic and 8-bit wide RGB DACs.
|
||||
--
|
||||
-- References:
|
||||
--
|
||||
-- * TI Data book TMS9918.pdf
|
||||
-- http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf
|
||||
--
|
||||
-- * Sean Young's tech article:
|
||||
-- http://bifi.msxnet.org/msxnet/tech/tms9918a.txt
|
||||
--
|
||||
-- * Paul Urbanus' discussion of the timing details
|
||||
-- http://bifi.msxnet.org/msxnet/tech/tmsposting.txt
|
||||
--
|
||||
-- * Richard F. Drushel's article series
|
||||
-- "This Week With My Coleco ADAM"
|
||||
-- http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity vdp18_core is
|
||||
|
||||
generic (
|
||||
is_pal_g : integer := 0;
|
||||
compat_rgb_g : integer := 0
|
||||
);
|
||||
port (
|
||||
-- Global Interface -------------------------------------------------------
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in std_logic;
|
||||
reset_n_i : in std_logic;
|
||||
-- CPU Interface ----------------------------------------------------------
|
||||
csr_n_i : in std_logic;
|
||||
csw_n_i : in std_logic;
|
||||
mode_i : in std_logic;
|
||||
int_n_o : out std_logic;
|
||||
cd_i : in std_logic_vector(0 to 7);
|
||||
cd_o : out std_logic_vector(0 to 7);
|
||||
-- VRAM Interface ---------------------------------------------------------
|
||||
vram_we_o : out std_logic;
|
||||
vram_a_o : out std_logic_vector(0 to 13);
|
||||
vram_d_o : out std_logic_vector(0 to 7);
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
-- Video Interface --------------------------------------------------------
|
||||
col_o : out std_logic_vector(0 to 3);
|
||||
rgb_r_o : out std_logic_vector(0 to 7);
|
||||
rgb_g_o : out std_logic_vector(0 to 7);
|
||||
rgb_b_o : out std_logic_vector(0 to 7);
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic
|
||||
);
|
||||
|
||||
end vdp18_core;
|
||||
|
||||
|
||||
use work.vdp18_comp_pack.all;
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
use work.vdp18_pack.access_t;
|
||||
use work.vdp18_pack.to_boolean_f;
|
||||
|
||||
architecture struct of vdp18_core is
|
||||
|
||||
signal reset_s : boolean;
|
||||
|
||||
signal clk_en_10m7_s,
|
||||
clk_en_5m37_s,
|
||||
clk_en_3m58_s,
|
||||
clk_en_acc_s : boolean;
|
||||
|
||||
signal opmode_s : opmode_t;
|
||||
|
||||
signal access_type_s : access_t;
|
||||
|
||||
signal num_pix_s,
|
||||
num_line_s : hv_t;
|
||||
signal hsync_n_s,
|
||||
vsync_n_s : std_logic;
|
||||
signal blank_s : boolean;
|
||||
|
||||
signal vert_inc_s : boolean;
|
||||
|
||||
signal reg_blank_s,
|
||||
reg_size1_s,
|
||||
reg_mag1_s : boolean;
|
||||
|
||||
signal spr_5th_s : boolean;
|
||||
signal spr_5th_num_s : std_logic_vector(0 to 4);
|
||||
|
||||
signal stop_sprite_s : boolean;
|
||||
signal vert_active_s,
|
||||
hor_active_s : boolean;
|
||||
|
||||
signal rd_s,
|
||||
wr_s : boolean;
|
||||
|
||||
signal reg_ntb_s : std_logic_vector(0 to 3);
|
||||
signal reg_ctb_s : std_logic_vector(0 to 7);
|
||||
signal reg_pgb_s : std_logic_vector(0 to 2);
|
||||
signal reg_satb_s : std_logic_vector(0 to 6);
|
||||
signal reg_spgb_s : std_logic_vector(0 to 2);
|
||||
signal reg_col1_s,
|
||||
reg_col0_s : std_logic_vector(0 to 3);
|
||||
signal cpu_vram_a_s : std_logic_vector(0 to 13);
|
||||
|
||||
signal pat_table_s : std_logic_vector(0 to 9);
|
||||
signal pat_name_s : std_logic_vector(0 to 7);
|
||||
signal pat_col_s : std_logic_vector(0 to 3);
|
||||
|
||||
signal spr_num_s : std_logic_vector(0 to 4);
|
||||
signal spr_line_s : std_logic_vector(0 to 3);
|
||||
signal spr_name_s : std_logic_vector(0 to 7);
|
||||
signal spr0_col_s,
|
||||
spr1_col_s,
|
||||
spr2_col_s,
|
||||
spr3_col_s : std_logic_vector(0 to 3);
|
||||
signal spr_coll_s : boolean;
|
||||
|
||||
signal irq_s : boolean;
|
||||
|
||||
signal false_s : boolean;
|
||||
|
||||
begin
|
||||
|
||||
-- temporary defaults
|
||||
false_s <= false;
|
||||
|
||||
clk_en_10m7_s <= to_boolean_f(clk_en_10m7_i);
|
||||
rd_s <= not to_boolean_f(csr_n_i);
|
||||
wr_s <= not to_boolean_f(csw_n_i);
|
||||
|
||||
reset_s <= reset_n_i = '0';
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Clock Generator
|
||||
-----------------------------------------------------------------------------
|
||||
clk_gen_b : vdp18_clk_gen
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_10m7_i => clk_en_10m7_i,
|
||||
reset_i => reset_s,
|
||||
clk_en_5m37_o => clk_en_5m37_s,
|
||||
clk_en_3m58_o => clk_en_3m58_s,
|
||||
clk_en_2m68_o => open
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Horizontal and Vertical Timing Generator
|
||||
-----------------------------------------------------------------------------
|
||||
hor_vert_b : vdp18_hor_vert
|
||||
generic map (
|
||||
is_pal_g => is_pal_g
|
||||
)
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_5m37_i => clk_en_5m37_s,
|
||||
reset_i => reset_s,
|
||||
opmode_i => opmode_s,
|
||||
num_pix_o => num_pix_s,
|
||||
num_line_o => num_line_s,
|
||||
vert_inc_o => vert_inc_s,
|
||||
hsync_n_o => hsync_n_s,
|
||||
vsync_n_o => vsync_n_s,
|
||||
blank_o => blank_s
|
||||
);
|
||||
|
||||
hsync_n_o <= hsync_n_s;
|
||||
vsync_n_o <= vsync_n_s;
|
||||
comp_sync_n_o <= not (hsync_n_s xor vsync_n_s);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Control Module
|
||||
-----------------------------------------------------------------------------
|
||||
ctrl_b : vdp18_ctrl
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_5m37_i => clk_en_5m37_s,
|
||||
reset_i => reset_s,
|
||||
opmode_i => opmode_s,
|
||||
num_pix_i => num_pix_s,
|
||||
num_line_i => num_line_s,
|
||||
vert_inc_i => vert_inc_s,
|
||||
reg_blank_i => reg_blank_s,
|
||||
reg_size1_i => reg_size1_s,
|
||||
stop_sprite_i => stop_sprite_s,
|
||||
clk_en_acc_o => clk_en_acc_s,
|
||||
access_type_o => access_type_s,
|
||||
vert_active_o => vert_active_s,
|
||||
hor_active_o => hor_active_s,
|
||||
irq_o => irq_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- CPU I/O Module
|
||||
-----------------------------------------------------------------------------
|
||||
cpu_io_b : vdp18_cpuio
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_10m7_i => clk_en_10m7_s,
|
||||
clk_en_acc_i => clk_en_acc_s,
|
||||
reset_i => reset_s,
|
||||
rd_i => rd_s,
|
||||
wr_i => wr_s,
|
||||
mode_i => mode_i,
|
||||
cd_i => cd_i,
|
||||
cd_o => cd_o,
|
||||
cd_oe_o => open,
|
||||
access_type_i => access_type_s,
|
||||
opmode_o => opmode_s,
|
||||
vram_we_o => vram_we_o,
|
||||
vram_a_o => cpu_vram_a_s,
|
||||
vram_d_o => vram_d_o,
|
||||
vram_d_i => vram_d_i,
|
||||
spr_coll_i => spr_coll_s,
|
||||
spr_5th_i => spr_5th_s,
|
||||
spr_5th_num_i => spr_5th_num_s,
|
||||
reg_ev_o => open,
|
||||
reg_16k_o => open,
|
||||
reg_blank_o => reg_blank_s,
|
||||
reg_size1_o => reg_size1_s,
|
||||
reg_mag1_o => reg_mag1_s,
|
||||
reg_ntb_o => reg_ntb_s,
|
||||
reg_ctb_o => reg_ctb_s,
|
||||
reg_pgb_o => reg_pgb_s,
|
||||
reg_satb_o => reg_satb_s,
|
||||
reg_spgb_o => reg_spgb_s,
|
||||
reg_col1_o => reg_col1_s,
|
||||
reg_col0_o => reg_col0_s,
|
||||
irq_i => irq_s,
|
||||
int_n_o => int_n_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- VRAM Address Multiplexer
|
||||
-----------------------------------------------------------------------------
|
||||
addr_mux_b : vdp18_addr_mux
|
||||
port map (
|
||||
access_type_i => access_type_s,
|
||||
opmode_i => opmode_s,
|
||||
num_line_i => num_line_s,
|
||||
reg_ntb_i => reg_ntb_s,
|
||||
reg_ctb_i => reg_ctb_s,
|
||||
reg_pgb_i => reg_pgb_s,
|
||||
reg_satb_i => reg_satb_s,
|
||||
reg_spgb_i => reg_spgb_s,
|
||||
reg_size1_i => reg_size1_s,
|
||||
cpu_vram_a_i => cpu_vram_a_s,
|
||||
pat_table_i => pat_table_s,
|
||||
pat_name_i => pat_name_s,
|
||||
spr_num_i => spr_num_s,
|
||||
spr_line_i => spr_line_s,
|
||||
spr_name_i => spr_name_s,
|
||||
vram_a_o => vram_a_o
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Pattern Generator
|
||||
-----------------------------------------------------------------------------
|
||||
pattern_b : vdp18_pattern
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_5m37_i => clk_en_5m37_s,
|
||||
clk_en_acc_i => clk_en_acc_s,
|
||||
reset_i => reset_s,
|
||||
opmode_i => opmode_s,
|
||||
access_type_i => access_type_s,
|
||||
num_line_i => num_line_s,
|
||||
vram_d_i => vram_d_i,
|
||||
vert_inc_i => vert_inc_s,
|
||||
vsync_n_i => vsync_n_s,
|
||||
reg_col1_i => reg_col1_s,
|
||||
reg_col0_i => reg_col0_s,
|
||||
pat_table_o => pat_table_s,
|
||||
pat_name_o => pat_name_s,
|
||||
pat_col_o => pat_col_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Sprite Generator
|
||||
-----------------------------------------------------------------------------
|
||||
sprite_b : vdp18_sprite
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_5m37_i => clk_en_5m37_s,
|
||||
clk_en_acc_i => clk_en_acc_s,
|
||||
reset_i => reset_s,
|
||||
access_type_i => access_type_s,
|
||||
num_pix_i => num_pix_s,
|
||||
num_line_i => num_line_s,
|
||||
vram_d_i => vram_d_i,
|
||||
vert_inc_i => vert_inc_s,
|
||||
reg_size1_i => reg_size1_s,
|
||||
reg_mag1_i => reg_mag1_s,
|
||||
spr_5th_o => spr_5th_s,
|
||||
spr_5th_num_o => spr_5th_num_s,
|
||||
stop_sprite_o => stop_sprite_s,
|
||||
spr_coll_o => spr_coll_s,
|
||||
spr_num_o => spr_num_s,
|
||||
spr_line_o => spr_line_s,
|
||||
spr_name_o => spr_name_s,
|
||||
spr0_col_o => spr0_col_s,
|
||||
spr1_col_o => spr1_col_s,
|
||||
spr2_col_o => spr2_col_s,
|
||||
spr3_col_o => spr3_col_s
|
||||
);
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Color Multiplexer
|
||||
-----------------------------------------------------------------------------
|
||||
col_mux_b : vdp18_col_mux
|
||||
generic map (
|
||||
compat_rgb_g => compat_rgb_g
|
||||
)
|
||||
port map (
|
||||
clk_i => clk_i,
|
||||
clk_en_5m37_i => clk_en_5m37_s,
|
||||
reset_i => reset_s,
|
||||
vert_active_i => vert_active_s,
|
||||
hor_active_i => hor_active_s,
|
||||
blank_i => blank_s,
|
||||
reg_col0_i => reg_col0_s,
|
||||
pat_col_i => pat_col_s,
|
||||
spr0_col_i => spr0_col_s,
|
||||
spr1_col_i => spr1_col_s,
|
||||
spr2_col_i => spr2_col_s,
|
||||
spr3_col_i => spr3_col_s,
|
||||
col_o => col_o,
|
||||
rgb_r_o => rgb_r_o,
|
||||
rgb_g_o => rgb_g_o,
|
||||
rgb_b_o => rgb_b_o
|
||||
);
|
||||
|
||||
end struct;
|
|
@ -0,0 +1,45 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- $Id: vdp18_core_comp_pack-p.vhd,v 1.10 2006/02/28 22:30:41 arnim Exp $
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
package vdp18_core_comp_pack is
|
||||
|
||||
component vdp18_core
|
||||
generic (
|
||||
is_pal_g : integer := 0;
|
||||
compat_rgb_g : integer := 0
|
||||
);
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in std_logic;
|
||||
reset_n_i : in std_logic;
|
||||
csr_n_i : in std_logic;
|
||||
csw_n_i : in std_logic;
|
||||
mode_i : in std_logic;
|
||||
int_n_o : out std_logic;
|
||||
cd_i : in std_logic_vector(0 to 7);
|
||||
cd_o : out std_logic_vector(0 to 7);
|
||||
vram_we_o : out std_logic;
|
||||
vram_a_o : out std_logic_vector(0 to 13);
|
||||
vram_d_o : out std_logic_vector(0 to 7);
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
col_o : out std_logic_vector(0 to 3);
|
||||
rgb_r_o : out std_logic_vector(0 to 7);
|
||||
rgb_g_o : out std_logic_vector(0 to 7);
|
||||
rgb_b_o : out std_logic_vector(0 to 7);
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
comp_sync_n_o : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
end vdp18_core_comp_pack;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_cpuio-c.vhd,v 1.5 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_cpuio_rtl_c0 of vdp18_cpuio is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_cpuio_rtl_c0;
|
|
@ -0,0 +1,570 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_cpuio.vhd,v 1.17 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- CPU I/O Interface Module
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.vdp18_pack.access_t;
|
||||
use work.vdp18_pack.opmode_t;
|
||||
|
||||
entity vdp18_cpuio is
|
||||
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_10m7_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
rd_i : in boolean;
|
||||
wr_i : in boolean;
|
||||
mode_i : in std_logic;
|
||||
cd_i : in std_logic_vector(0 to 7);
|
||||
cd_o : out std_logic_vector(0 to 7);
|
||||
cd_oe_o : out std_logic;
|
||||
access_type_i : in access_t;
|
||||
opmode_o : out opmode_t;
|
||||
vram_we_o : out std_logic;
|
||||
vram_a_o : out std_logic_vector(0 to 13);
|
||||
vram_d_o : out std_logic_vector(0 to 7);
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
spr_coll_i : in boolean;
|
||||
spr_5th_i : in boolean;
|
||||
spr_5th_num_i : in std_logic_vector(0 to 4);
|
||||
reg_ev_o : out boolean;
|
||||
reg_16k_o : out boolean;
|
||||
reg_blank_o : out boolean;
|
||||
reg_size1_o : out boolean;
|
||||
reg_mag1_o : out boolean;
|
||||
reg_ntb_o : out std_logic_vector(0 to 3);
|
||||
reg_ctb_o : out std_logic_vector(0 to 7);
|
||||
reg_pgb_o : out std_logic_vector(0 to 2);
|
||||
reg_satb_o : out std_logic_vector(0 to 6);
|
||||
reg_spgb_o : out std_logic_vector(0 to 2);
|
||||
reg_col1_o : out std_logic_vector(0 to 3);
|
||||
reg_col0_o : out std_logic_vector(0 to 3);
|
||||
irq_i : in boolean;
|
||||
int_n_o : out std_logic
|
||||
);
|
||||
|
||||
end vdp18_cpuio;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_cpuio is
|
||||
|
||||
type state_t is (ST_IDLE,
|
||||
ST_RD_MODE0, ST_WR_MODE0,
|
||||
ST_RD_MODE1,
|
||||
ST_WR_MODE1_1ST, ST_WR_MODE1_1ST_IDLE,
|
||||
ST_WR_MODE1_2ND_VREAD, ST_WR_MODE1_2ND_VWRITE,
|
||||
ST_WR_MODE1_2ND_RWRITE);
|
||||
signal state_s,
|
||||
state_q : state_t;
|
||||
|
||||
signal buffer_q : std_logic_vector(0 to 7);
|
||||
|
||||
signal addr_q : unsigned(0 to 13);
|
||||
|
||||
signal incr_addr_s,
|
||||
load_addr_s : boolean;
|
||||
|
||||
signal wrbuf_cpu_s : boolean;
|
||||
signal sched_rdvram_s,
|
||||
rdvram_sched_q,
|
||||
rdvram_q : boolean;
|
||||
signal abort_wrvram_s,
|
||||
sched_wrvram_s,
|
||||
wrvram_sched_q,
|
||||
wrvram_q : boolean;
|
||||
|
||||
signal write_tmp_s : boolean;
|
||||
signal tmp_q : std_logic_vector(0 to 7);
|
||||
signal write_reg_s : boolean;
|
||||
|
||||
-- control register bits ----------------------------------------------------
|
||||
type ctrl_reg_t is array (natural range 7 downto 0) of
|
||||
std_logic_vector(0 to 7);
|
||||
signal ctrl_reg_q : ctrl_reg_t;
|
||||
|
||||
-- status register ----------------------------------------------------------
|
||||
signal status_reg_s : std_logic_vector(0 to 7);
|
||||
signal destr_rd_status_s : boolean;
|
||||
signal sprite_5th_q : boolean;
|
||||
signal sprite_5th_num_q : std_logic_vector(0 to 4);
|
||||
signal sprite_coll_q : boolean;
|
||||
signal int_n_q : std_logic;
|
||||
|
||||
|
||||
type read_mux_t is (RDMUX_STATUS, RDMUX_READAHEAD);
|
||||
signal read_mux_s : read_mux_t;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clk_i, reset_i)
|
||||
variable incr_addr_v : boolean;
|
||||
begin
|
||||
if reset_i then
|
||||
state_q <= ST_IDLE;
|
||||
buffer_q <= (others => '0');
|
||||
addr_q <= (others => '0');
|
||||
rdvram_sched_q <= false;
|
||||
rdvram_q <= false;
|
||||
wrvram_sched_q <= false;
|
||||
wrvram_q <= false;
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
-- default assignments
|
||||
incr_addr_v := incr_addr_s;
|
||||
|
||||
if clk_en_10m7_i then
|
||||
-- update state vector ------------------------------------------------
|
||||
state_q <= state_s;
|
||||
|
||||
-- buffer and flag control --------------------------------------------
|
||||
if wrbuf_cpu_s then
|
||||
-- write read-ahead buffer from CPU bus
|
||||
buffer_q <= cd_i;
|
||||
-- immediately stop read-ahead
|
||||
rdvram_sched_q <= false;
|
||||
rdvram_q <= false;
|
||||
elsif clk_en_acc_i and
|
||||
rdvram_q and
|
||||
access_type_i = AC_CPU then
|
||||
-- write read-ahead buffer from VRAM during CPU access slot
|
||||
buffer_q <= vram_d_i;
|
||||
-- stop scanning for CPU data
|
||||
rdvram_q <= false;
|
||||
-- increment read-ahead address
|
||||
incr_addr_v := true;
|
||||
end if;
|
||||
|
||||
if sched_rdvram_s then
|
||||
-- immediately stop write-back
|
||||
wrvram_sched_q <= false;
|
||||
wrvram_q <= false;
|
||||
-- schedule read-ahead
|
||||
rdvram_sched_q <= true;
|
||||
end if;
|
||||
|
||||
if sched_wrvram_s then
|
||||
-- schedule write-back
|
||||
wrvram_sched_q <= true;
|
||||
end if;
|
||||
|
||||
if abort_wrvram_s then
|
||||
-- stop scanning for write-back
|
||||
wrvram_q <= false;
|
||||
end if;
|
||||
|
||||
if rdvram_sched_q and clk_en_acc_i then
|
||||
-- align scheduled read-ahead with access slot phase
|
||||
rdvram_sched_q <= false;
|
||||
rdvram_q <= true;
|
||||
end if;
|
||||
if wrvram_sched_q and clk_en_acc_i then
|
||||
-- align scheduled write-back with access slot phase
|
||||
wrvram_sched_q <= false;
|
||||
wrvram_q <= true;
|
||||
end if;
|
||||
|
||||
-- manage address -----------------------------------------------------
|
||||
if load_addr_s then
|
||||
addr_q(6 to 13) <= unsigned(tmp_q);
|
||||
addr_q(0 to 5) <= unsigned(cd_i(2 to 7));
|
||||
elsif incr_addr_v then
|
||||
addr_q <= addr_q + 1;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process wback_ctrl
|
||||
--
|
||||
-- Purpose:
|
||||
-- Write-back control.
|
||||
--
|
||||
wback_ctrl: process (clk_en_acc_i,
|
||||
access_type_i,
|
||||
wrvram_q)
|
||||
begin
|
||||
-- default assignments
|
||||
abort_wrvram_s <= false;
|
||||
incr_addr_s <= false;
|
||||
vram_we_o <= '0';
|
||||
|
||||
if wrvram_q then
|
||||
if access_type_i = AC_CPU then
|
||||
-- signal write access to VRAM
|
||||
vram_we_o <= '1';
|
||||
|
||||
if clk_en_acc_i then
|
||||
-- clear write-back flag and increment address
|
||||
abort_wrvram_s <= true;
|
||||
incr_addr_s <= true;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process wback_ctrl;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process reg_if
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the register interface.
|
||||
--
|
||||
reg_if: process (clk_i, reset_i)
|
||||
variable reg_addr_v : unsigned(0 to 2);
|
||||
begin
|
||||
if reset_i then
|
||||
tmp_q <= (others => '0');
|
||||
ctrl_reg_q <= (others => (others => '0'));
|
||||
sprite_coll_q <= false;
|
||||
sprite_5th_q <= false;
|
||||
sprite_5th_num_q <= (others => '0');
|
||||
int_n_q <= '1';
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_10m7_i then
|
||||
-- Temporary register -------------------------------------------------
|
||||
if write_tmp_s then
|
||||
tmp_q <= cd_i;
|
||||
end if;
|
||||
|
||||
-- Registers 0 to 7 ---------------------------------------------------
|
||||
if write_reg_s then
|
||||
reg_addr_v := unsigned(cd_i(5 to 7));
|
||||
ctrl_reg_q(to_integer(reg_addr_v)) <= tmp_q;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
-- Fifth sprite handling ------------------------------------------------
|
||||
if spr_5th_i and not sprite_5th_q then
|
||||
sprite_5th_q <= true;
|
||||
sprite_5th_num_q <= spr_5th_num_i;
|
||||
elsif destr_rd_status_s then
|
||||
sprite_5th_q <= false;
|
||||
end if;
|
||||
|
||||
-- Sprite collision flag ------------------------------------------------
|
||||
if spr_coll_i then
|
||||
sprite_coll_q <= true;
|
||||
elsif destr_rd_status_s then
|
||||
sprite_coll_q <= false;
|
||||
end if;
|
||||
|
||||
-- Interrupt ------------------------------------------------------------
|
||||
if irq_i then
|
||||
int_n_q <= '0';
|
||||
elsif destr_rd_status_s then
|
||||
int_n_q <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process reg_if;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process access_ctrl
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combinational logic for the CPU I/F FSM.
|
||||
-- Decodes the CPU I/F FSM state and generates the control signals for the
|
||||
-- register and VRAM logic.
|
||||
--
|
||||
access_ctrl: process (state_q,
|
||||
rd_i, wr_i,
|
||||
mode_i,
|
||||
cd_i)
|
||||
type transfer_mode_t is (TM_NONE,
|
||||
TM_RD_MODE0, TM_WR_MODE0,
|
||||
TM_RD_MODE1, TM_WR_MODE1);
|
||||
variable transfer_mode_v : transfer_mode_t;
|
||||
begin
|
||||
-- default assignments
|
||||
state_s <= state_q;
|
||||
sched_rdvram_s <= false;
|
||||
sched_wrvram_s <= false;
|
||||
wrbuf_cpu_s <= false;
|
||||
write_tmp_s <= false;
|
||||
write_reg_s <= false;
|
||||
load_addr_s <= false;
|
||||
read_mux_s <= RDMUX_STATUS;
|
||||
destr_rd_status_s <= false;
|
||||
|
||||
-- determine transfer mode
|
||||
transfer_mode_v := TM_NONE;
|
||||
if mode_i = '0' then
|
||||
if rd_i then
|
||||
transfer_mode_v := TM_RD_MODE0;
|
||||
end if;
|
||||
if wr_i then
|
||||
transfer_mode_v := TM_WR_MODE0;
|
||||
end if;
|
||||
else
|
||||
if rd_i then
|
||||
transfer_mode_v := TM_RD_MODE1;
|
||||
end if;
|
||||
if wr_i then
|
||||
transfer_mode_v := TM_WR_MODE1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- FSM state transitions
|
||||
case state_q is
|
||||
-- ST_IDLE: waiting for CPU access --------------------------------------
|
||||
when ST_IDLE =>
|
||||
case transfer_mode_v is
|
||||
when TM_RD_MODE0 =>
|
||||
state_s <= ST_RD_MODE0;
|
||||
when TM_WR_MODE0 =>
|
||||
state_s <= ST_WR_MODE0;
|
||||
when TM_RD_MODE1 =>
|
||||
state_s <= ST_RD_MODE1;
|
||||
when TM_WR_MODE1 =>
|
||||
state_s <= ST_WR_MODE1_1ST;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- ST_RD_MODE0: read from VRAM ------------------------------------------
|
||||
when ST_RD_MODE0 =>
|
||||
-- set read mux
|
||||
read_mux_s <= RDMUX_READAHEAD;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished read access:
|
||||
-- schedule new read-ahead and return to idle
|
||||
state_s <= ST_IDLE;
|
||||
sched_rdvram_s <= true;
|
||||
end if;
|
||||
|
||||
-- ST_WR_MODE0: write to VRAM -------------------------------------------
|
||||
when ST_WR_MODE0 =>
|
||||
-- write data from CPU to write-back/read-ahead buffer
|
||||
wrbuf_cpu_s <= true;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished write access:
|
||||
-- schedule new write-back and return to idle
|
||||
state_s <= ST_IDLE;
|
||||
sched_wrvram_s <= true;
|
||||
end if;
|
||||
|
||||
-- ST_RD_MODE1: read from status register -------------------------------
|
||||
when ST_RD_MODE1 =>
|
||||
-- set read mux
|
||||
read_mux_s <= RDMUX_STATUS;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished read access:
|
||||
-- destructive read of status register and return to IDLE
|
||||
destr_rd_status_s <= true;
|
||||
state_s <= ST_IDLE;
|
||||
end if;
|
||||
|
||||
-- ST_WR_MODE1_1ST: save first byte -------------------------------------
|
||||
when ST_WR_MODE1_1ST =>
|
||||
-- update temp register
|
||||
write_tmp_s <= true;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished write access:
|
||||
-- become idle but remember that the first byte of a paired write
|
||||
-- has been written
|
||||
state_s <= ST_WR_MODE1_1ST_IDLE;
|
||||
end if;
|
||||
|
||||
-- ST_WR_MODE1_1ST_IDLE: wait for next access ---------------------------
|
||||
when ST_WR_MODE1_1ST_IDLE =>
|
||||
-- determine type of next access
|
||||
case transfer_mode_v is
|
||||
when TM_RD_MODE0 =>
|
||||
state_s <= ST_RD_MODE0;
|
||||
when TM_WR_MODE0 =>
|
||||
state_s <= ST_WR_MODE0;
|
||||
when TM_RD_MODE1 =>
|
||||
state_s <= ST_RD_MODE1;
|
||||
when TM_WR_MODE1 =>
|
||||
case cd_i(0 to 1) is
|
||||
when "00" =>
|
||||
state_s <= ST_WR_MODE1_2ND_VREAD;
|
||||
when "01" =>
|
||||
state_s <= ST_WR_MODE1_2ND_VWRITE;
|
||||
when "10" | "11" =>
|
||||
state_s <= ST_WR_MODE1_2ND_RWRITE;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
-- ST_WR_MODE1_2ND_VREAD: write second byte of address, then read ahead -
|
||||
when ST_WR_MODE1_2ND_VREAD =>
|
||||
load_addr_s <= true;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished write access:
|
||||
-- schedule new read-ahead and return to idle
|
||||
sched_rdvram_s <= true;
|
||||
state_s <= ST_IDLE;
|
||||
end if;
|
||||
|
||||
-- ST_WR_MODE1_2ND_VWRITE: write second byte of address
|
||||
when ST_WR_MODE1_2ND_VWRITE =>
|
||||
load_addr_s <= true;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished write access:
|
||||
-- return to idle
|
||||
state_s <= ST_IDLE;
|
||||
end if;
|
||||
|
||||
-- ST_WR_MODE1_2ND_RWRITE: write to register ----------------------------
|
||||
when ST_WR_MODE1_2ND_RWRITE =>
|
||||
write_reg_s <= true;
|
||||
|
||||
if transfer_mode_v = TM_NONE then
|
||||
-- CPU finished write access:
|
||||
-- return to idle
|
||||
state_s <= ST_IDLE;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
|
||||
end process access_ctrl;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process mode_decode
|
||||
--
|
||||
-- Purpose:
|
||||
-- Decodes the display mode from the M1, M2, M3 bits.
|
||||
--
|
||||
mode_decode: process (ctrl_reg_q)
|
||||
variable mode_v : std_logic_vector(0 to 2);
|
||||
begin
|
||||
mode_v := ctrl_reg_q(1)(3) & -- M1
|
||||
ctrl_reg_q(1)(4) & -- M2
|
||||
ctrl_reg_q(0)(6); -- M3
|
||||
|
||||
case mode_v is
|
||||
when "000" =>
|
||||
opmode_o <= OPMODE_GRAPH1;
|
||||
when "001" =>
|
||||
opmode_o <= OPMODE_GRAPH2;
|
||||
when "010" =>
|
||||
opmode_o <= OPMODE_MULTIC;
|
||||
when "100" =>
|
||||
opmode_o <= OPMODE_TEXTM;
|
||||
when others =>
|
||||
opmode_o <= OPMODE_TEXTM;
|
||||
end case;
|
||||
end process mode_decode;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Build status register
|
||||
-----------------------------------------------------------------------------
|
||||
status_reg_s <= not int_n_q &
|
||||
to_std_logic_f(sprite_5th_q) &
|
||||
to_std_logic_f(sprite_coll_q) &
|
||||
sprite_5th_num_q;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
vram_a_o <= std_logic_vector(addr_q);
|
||||
vram_d_o <= buffer_q;
|
||||
|
||||
cd_o <= buffer_q
|
||||
when read_mux_s = RDMUX_READAHEAD else
|
||||
status_reg_s;
|
||||
cd_oe_o <= '1'
|
||||
when rd_i else
|
||||
'0';
|
||||
|
||||
reg_ev_o <= to_boolean_f(ctrl_reg_q(0)(7));
|
||||
reg_16k_o <= to_boolean_f(ctrl_reg_q(1)(0));
|
||||
reg_blank_o <= not to_boolean_f(ctrl_reg_q(1)(1));
|
||||
reg_size1_o <= to_boolean_f(ctrl_reg_q(1)(6));
|
||||
reg_mag1_o <= to_boolean_f(ctrl_reg_q(1)(7));
|
||||
reg_ntb_o <= ctrl_reg_q(2)(4 to 7);
|
||||
reg_ctb_o <= ctrl_reg_q(3);
|
||||
reg_pgb_o <= ctrl_reg_q(4)(5 to 7);
|
||||
reg_satb_o <= ctrl_reg_q(5)(1 to 7);
|
||||
reg_spgb_o <= ctrl_reg_q(6)(5 to 7);
|
||||
reg_col1_o <= ctrl_reg_q(7)(0 to 3);
|
||||
reg_col0_o <= ctrl_reg_q(7)(4 to 7);
|
||||
int_n_o <= int_n_q or not ctrl_reg_q(1)(2);
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_ctrl-c.vhd,v 1.5 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_ctrl_rtl_c0 of vdp18_ctrl is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_ctrl_rtl_c0;
|
|
@ -0,0 +1,374 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_ctrl.vhd,v 1.26 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Timing Controller
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
use work.vdp18_pack.access_t;
|
||||
|
||||
entity vdp18_ctrl is
|
||||
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
num_pix_i : in hv_t;
|
||||
num_line_i : in hv_t;
|
||||
vert_inc_i : in boolean;
|
||||
reg_blank_i : in boolean;
|
||||
reg_size1_i : in boolean;
|
||||
stop_sprite_i : in boolean;
|
||||
clk_en_acc_o : out boolean;
|
||||
access_type_o : out access_t;
|
||||
vert_active_o : out boolean;
|
||||
hor_active_o : out boolean;
|
||||
irq_o : out boolean
|
||||
);
|
||||
|
||||
end vdp18_ctrl;
|
||||
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_ctrl is
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- This enables a workaround for a bug in XST.
|
||||
-- ISE 8.1.02i implements wrong functionality otherwise :-(
|
||||
--
|
||||
constant xst_bug_wa_c : boolean := true;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
signal access_type_s : access_t;
|
||||
|
||||
-- pragma translate_off
|
||||
-- Testbench signals --------------------------------------------------------
|
||||
--
|
||||
signal ac_s : std_logic_vector(3 downto 0);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
-- pragma translate_on
|
||||
|
||||
signal vert_active_q,
|
||||
hor_active_q : boolean;
|
||||
signal sprite_active_q : boolean;
|
||||
signal sprite_line_act_q : boolean;
|
||||
|
||||
begin
|
||||
|
||||
-- pragma translate_off
|
||||
-- Testbench signals --------------------------------------------------------
|
||||
--
|
||||
ac_s <= enum_to_vec_f(access_type_s);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
-- pragma translate_on
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process decode_access
|
||||
--
|
||||
-- Purpose:
|
||||
-- Decode horizontal counter value to access type.
|
||||
--
|
||||
decode_access: process (opmode_i,
|
||||
num_pix_i,
|
||||
vert_active_q,
|
||||
sprite_line_act_q,
|
||||
reg_size1_i)
|
||||
variable num_pix_plus_6_v : hv_t;
|
||||
variable mod_6_v : hv_t;
|
||||
variable num_pix_plus_8_v : hv_t;
|
||||
variable num_pix_plus_32_v : hv_t;
|
||||
variable num_pix_spr_v : integer;
|
||||
begin
|
||||
-- default assignment
|
||||
access_type_s <= AC_CPU;
|
||||
|
||||
-- prepare number of pixels for pattern operations
|
||||
num_pix_plus_6_v := num_pix_i + 6;
|
||||
num_pix_plus_8_v := num_pix_i + 8;
|
||||
num_pix_plus_32_v := num_pix_i + 32;
|
||||
num_pix_spr_v := to_integer(num_pix_i and "111111110");
|
||||
|
||||
case opmode_i is
|
||||
-- Graphics I, II and Multicolor Mode -----------------------------------
|
||||
when OPMODE_GRAPH1 |
|
||||
OPMODE_GRAPH2 |
|
||||
OPMODE_MULTIC =>
|
||||
--
|
||||
-- Patterns
|
||||
--
|
||||
if vert_active_q then
|
||||
if num_pix_plus_8_v(0) = '0' then
|
||||
if not xst_bug_wa_c then
|
||||
|
||||
-- original code, we want this
|
||||
case num_pix_plus_8_v(6 to 7) is
|
||||
when "01" =>
|
||||
access_type_s <= AC_PNT;
|
||||
when "10" =>
|
||||
if opmode_i /= OPMODE_MULTIC then
|
||||
-- no access to pattern color table in multicolor mode
|
||||
access_type_s <= AC_PCT;
|
||||
end if;
|
||||
when "11" =>
|
||||
access_type_s <= AC_PGT;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
else
|
||||
|
||||
-- workaround for XST bug, we need this
|
||||
if num_pix_plus_8_v(6 to 7) = "01" then
|
||||
access_type_s <= AC_PNT;
|
||||
elsif num_pix_plus_8_v(6 to 7) = "10" then
|
||||
if opmode_i /= OPMODE_MULTIC then
|
||||
access_type_s <= AC_PCT;
|
||||
end if;
|
||||
elsif num_pix_plus_8_v(6 to 7) = "11" then
|
||||
access_type_s <= AC_PGT;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
--
|
||||
-- Sprite test
|
||||
--
|
||||
if sprite_line_act_q then
|
||||
if num_pix_i(0) = '0' and
|
||||
num_pix_i(0 to 5) /= "011111" and
|
||||
num_pix_i(6 to 7) = "00" and
|
||||
num_pix_i(4 to 5) /= "00" then
|
||||
-- sprite test interleaved with pattern accesses - 23 slots
|
||||
access_type_s <= AC_STST;
|
||||
end if;
|
||||
if num_pix_plus_32_v(0 to 4) = "00000" or
|
||||
num_pix_plus_32_v(0 to 7) = "00001000" then
|
||||
-- sprite tests before starting pattern phase - 9 slots
|
||||
access_type_s <= AC_STST;
|
||||
end if;
|
||||
|
||||
--
|
||||
-- Sprite Attribute Table and Sprite Pattern Table
|
||||
--
|
||||
case num_pix_spr_v is
|
||||
when 250 | -78 |
|
||||
-62 | -46 =>
|
||||
access_type_s <= AC_SATY;
|
||||
when 254 | -76 |
|
||||
-60 | -44 =>
|
||||
access_type_s <= AC_SATX;
|
||||
when 252 | -74 |
|
||||
-58 | -42 =>
|
||||
access_type_s <= AC_SATN;
|
||||
when -86 | -70 |
|
||||
-54 | -38 =>
|
||||
access_type_s <= AC_SATC;
|
||||
when -84 | -68 |
|
||||
-52 | -36 =>
|
||||
access_type_s <= AC_SPTH;
|
||||
when -82 | -66 |
|
||||
-50 | -34 =>
|
||||
if reg_size1_i then
|
||||
access_type_s <= AC_SPTL;
|
||||
end if;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- Text Mode ------------------------------------------------------------
|
||||
when OPMODE_TEXTM =>
|
||||
if vert_active_q and
|
||||
num_pix_plus_6_v(0) = '0' and
|
||||
num_pix_plus_6_v(0 to 4) /= "01111" then
|
||||
mod_6_v := mod_6_f(num_pix_plus_6_v);
|
||||
case mod_6_v(6 to 7) is
|
||||
when "00" =>
|
||||
access_type_s <= AC_PNT;
|
||||
when "10" =>
|
||||
access_type_s <= AC_PGT;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- Unknown --------------------------------------------------------------
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
|
||||
end process decode_access;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process vert_flags
|
||||
--
|
||||
-- Purpose:
|
||||
-- Track the vertical position with flags.
|
||||
--
|
||||
vert_flags: process (clk_i, reset_i)
|
||||
begin
|
||||
if reset_i then
|
||||
vert_active_q <= false;
|
||||
sprite_active_q <= false;
|
||||
sprite_line_act_q <= false;
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_5m37_i then
|
||||
-- line-local sprite processing
|
||||
if sprite_active_q then
|
||||
-- sprites are globally enabled
|
||||
if vert_inc_i then
|
||||
-- reload at beginning of every new line
|
||||
-- => scan with STST
|
||||
sprite_line_act_q <= true;
|
||||
end if;
|
||||
|
||||
if num_pix_i = hv_sprite_start_c then
|
||||
-- reload when access to sprite memory starts
|
||||
sprite_line_act_q <= true;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if vert_inc_i then
|
||||
-- global sprite processing
|
||||
if reg_blank_i then
|
||||
sprite_active_q <= false;
|
||||
sprite_line_act_q <= false;
|
||||
elsif num_line_i = -2 then
|
||||
-- start at line -1
|
||||
sprite_active_q <= true;
|
||||
-- initialize immediately
|
||||
sprite_line_act_q <= true;
|
||||
elsif num_line_i = 191 then
|
||||
-- stop at line 192
|
||||
sprite_active_q <= false;
|
||||
-- force stop
|
||||
sprite_line_act_q <= false;
|
||||
end if;
|
||||
|
||||
-- global vertical display
|
||||
if reg_blank_i then
|
||||
vert_active_q <= false;
|
||||
elsif num_line_i = -1 then
|
||||
-- start vertical display at line 0
|
||||
vert_active_q <= true;
|
||||
elsif num_line_i = 191 then
|
||||
-- stop at line 192
|
||||
vert_active_q <= false;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if stop_sprite_i then
|
||||
-- stop processing of sprites in this line
|
||||
sprite_line_act_q <= false;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process vert_flags;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process hor_flags
|
||||
--
|
||||
-- Purpose:
|
||||
-- Track the horizontal position.
|
||||
--
|
||||
hor_flags: process (clk_i, reset_i)
|
||||
begin
|
||||
if reset_i then
|
||||
hor_active_q <= false;
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_5m37_i then
|
||||
if not reg_blank_i and
|
||||
num_pix_i = -1 then
|
||||
hor_active_q <= true;
|
||||
end if;
|
||||
|
||||
if opmode_i = OPMODE_TEXTM then
|
||||
if num_pix_i = 239 then
|
||||
hor_active_q <= false;
|
||||
end if;
|
||||
else
|
||||
if num_pix_i = 255 then
|
||||
hor_active_q <= false;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process hor_flags;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Ouput mapping
|
||||
-----------------------------------------------------------------------------
|
||||
-- generate clock enable for flip-flops working on access_type
|
||||
clk_en_acc_o <= clk_en_5m37_i and num_pix_i(8) = '1';
|
||||
access_type_o <= access_type_s;
|
||||
vert_active_o <= vert_active_q;
|
||||
hor_active_o <= hor_active_q;
|
||||
irq_o <= vert_inc_i and num_line_i = 191;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_hor_vert-c.vhd,v 1.5 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_hor_vert_rtl_c0 of vdp18_hor_vert is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_hor_vert_rtl_c0;
|
|
@ -0,0 +1,217 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_hor_vert.vhd,v 1.11 2006/06/18 10:47:01 arnim Exp $
|
||||
--
|
||||
-- Horizontal / Vertical Timing Generator
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
|
||||
entity vdp18_hor_vert is
|
||||
|
||||
generic (
|
||||
is_pal_g : integer := 0
|
||||
);
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
num_pix_o : out hv_t;
|
||||
num_line_o : out hv_t;
|
||||
vert_inc_o : out boolean;
|
||||
hsync_n_o : out std_logic;
|
||||
vsync_n_o : out std_logic;
|
||||
blank_o : out boolean
|
||||
);
|
||||
|
||||
end vdp18_hor_vert;
|
||||
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_hor_vert is
|
||||
|
||||
signal last_line_s : hv_t;
|
||||
signal first_line_s : hv_t;
|
||||
|
||||
signal first_pix_s : hv_t;
|
||||
signal last_pix_s : hv_t;
|
||||
|
||||
signal cnt_hor_q : hv_t;
|
||||
signal cnt_vert_q : hv_t;
|
||||
|
||||
signal vert_inc_s : boolean;
|
||||
|
||||
signal hblank_q,
|
||||
vblank_q : boolean;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Prepare comparison signals for NTSC and PAL.
|
||||
--
|
||||
is_ntsc: if is_pal_g /= 1 generate
|
||||
first_line_s <= hv_first_line_ntsc_c;
|
||||
last_line_s <= hv_last_line_ntsc_c;
|
||||
end generate;
|
||||
--
|
||||
is_pal: if is_pal_g = 1 generate
|
||||
first_line_s <= hv_first_line_pal_c;
|
||||
last_line_s <= hv_last_line_pal_c;
|
||||
end generate;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process opmode_mux
|
||||
--
|
||||
-- Purpose:
|
||||
-- Generates the horizontal counter limits based on the current operating
|
||||
-- mode.
|
||||
--
|
||||
opmode_mux: process (opmode_i)
|
||||
begin
|
||||
if opmode_i = OPMODE_TEXTM then
|
||||
first_pix_s <= hv_first_pix_text_c;
|
||||
last_pix_s <= hv_last_pix_text_c;
|
||||
else
|
||||
first_pix_s <= hv_first_pix_graph_c;
|
||||
last_pix_s <= hv_last_pix_graph_c;
|
||||
end if;
|
||||
end process opmode_mux;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process counters
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the horizontal and vertical counters.
|
||||
--
|
||||
counters: process (clk_i, reset_i, first_line_s)
|
||||
begin
|
||||
if reset_i then
|
||||
cnt_hor_q <= hv_first_pix_text_c;
|
||||
cnt_vert_q <= first_line_s;
|
||||
hsync_n_o <= '1';
|
||||
vsync_n_o <= '1';
|
||||
hblank_q <= false;
|
||||
vblank_q <= false;
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_5m37_i then
|
||||
-- The horizontal counter ---------------------------------------------
|
||||
if cnt_hor_q = last_pix_s then
|
||||
cnt_hor_q <= first_pix_s;
|
||||
else
|
||||
cnt_hor_q <= cnt_hor_q + 1;
|
||||
end if;
|
||||
|
||||
-- The vertical counter -----------------------------------------------
|
||||
if cnt_vert_q = last_line_s then
|
||||
cnt_vert_q <= first_line_s;
|
||||
elsif vert_inc_s then
|
||||
-- increment when horizontal counter is at trigger position
|
||||
cnt_vert_q <= cnt_vert_q + 1;
|
||||
end if;
|
||||
|
||||
-- Horizontal sync ----------------------------------------------------
|
||||
if cnt_hor_q = -64 then
|
||||
hsync_n_o <= '0';
|
||||
elsif cnt_hor_q = -38 then
|
||||
hsync_n_o <= '1';
|
||||
end if;
|
||||
if cnt_hor_q = -72 then
|
||||
hblank_q <= true;
|
||||
elsif cnt_hor_q = -14 then
|
||||
hblank_q <= false;
|
||||
end if;
|
||||
|
||||
-- Vertical sync ------------------------------------------------------
|
||||
if is_pal_g = 1 then
|
||||
if cnt_vert_q = 244 then
|
||||
vsync_n_o <= '0';
|
||||
elsif cnt_vert_q = 247 then
|
||||
vsync_n_o <= '1';
|
||||
end if;
|
||||
else
|
||||
if cnt_vert_q = 218 then
|
||||
vsync_n_o <= '0';
|
||||
elsif cnt_vert_q = 221 then
|
||||
vsync_n_o <= '1';
|
||||
end if;
|
||||
|
||||
if cnt_vert_q = 215 then
|
||||
vblank_q <= true;
|
||||
elsif cnt_vert_q = first_line_s + 13 then
|
||||
vblank_q <= false;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process counters;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-- comparator for vertical line increment
|
||||
vert_inc_s <= clk_en_5m37_i and cnt_hor_q = hv_vertical_inc_c;
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
num_pix_o <= cnt_hor_q;
|
||||
num_line_o <= cnt_vert_q;
|
||||
vert_inc_o <= vert_inc_s;
|
||||
blank_o <= hblank_q or vblank_q;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,281 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- $Id: vdp18_pack-p.vhd,v 1.14 2006/02/22 23:07:05 arnim Exp $
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package vdp18_pack is
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Subtype for horizontal/vertical counters/positions.
|
||||
--
|
||||
subtype hv_t is signed(0 to 8);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Constants for first and last vertical line of NTSC and PAL mode.
|
||||
--
|
||||
constant hv_first_line_ntsc_c : hv_t := to_signed(-40, hv_t'length);
|
||||
constant hv_last_line_ntsc_c : hv_t := to_signed(221, hv_t'length);
|
||||
--
|
||||
constant hv_first_line_pal_c : hv_t := to_signed(-65, hv_t'length);
|
||||
constant hv_last_line_pal_c : hv_t := to_signed(247, hv_t'length);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Constants for first and last horizontal pixel in text and graphics.
|
||||
--
|
||||
constant hv_first_pix_text_c : hv_t := to_signed(-102, hv_t'length);
|
||||
constant hv_last_pix_text_c : hv_t := to_signed(239, hv_t'length);
|
||||
--
|
||||
constant hv_first_pix_graph_c : hv_t := to_signed(-86, hv_t'length);
|
||||
constant hv_last_pix_graph_c : hv_t := to_signed(255, hv_t'length);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Miscellaneous constants for horizontal phases.
|
||||
--
|
||||
constant hv_vertical_inc_c : hv_t := to_signed(-32, hv_t'length);
|
||||
constant hv_sprite_start_c : hv_t := to_signed(247, hv_t'length);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Operating modes of the VDP18 core.
|
||||
--
|
||||
type opmode_t is (OPMODE_GRAPH1, OPMODE_GRAPH2,
|
||||
OPMODE_MULTIC, OPMODE_TEXTM);
|
||||
--
|
||||
constant opmode_graph1_c : std_logic_vector(0 to 2) := "000";
|
||||
constant opmode_graph2_c : std_logic_vector(0 to 2) := "001";
|
||||
constant opmode_multic_c : std_logic_vector(0 to 2) := "010";
|
||||
constant opmode_textm_c : std_logic_vector(0 to 2) := "100";
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Access types.
|
||||
--
|
||||
type access_t is (-- pattern access
|
||||
-- read Pattern Name Table
|
||||
AC_PNT,
|
||||
-- read Pattern Generator Table
|
||||
AC_PGT,
|
||||
-- read Pattern Color Table
|
||||
AC_PCT,
|
||||
-- sprite access
|
||||
-- sprite test read (y coordinate)
|
||||
AC_STST,
|
||||
-- read Sprite Attribute Table/Y
|
||||
AC_SATY,
|
||||
-- read Sprite Attribute Table/X
|
||||
AC_SATX,
|
||||
-- read Sprite Attribute Table/N
|
||||
AC_SATN,
|
||||
-- read Sprite Attribute Table/C
|
||||
AC_SATC,
|
||||
-- read Sprite Pattern Table/high quadrant
|
||||
AC_SPTH,
|
||||
-- read Sprite Pattern Table/low quadrant
|
||||
AC_SPTL,
|
||||
--
|
||||
-- CPU access
|
||||
AC_CPU,
|
||||
--
|
||||
-- no access at all
|
||||
AC_NONE
|
||||
);
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function enum_to_vec_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Translate access_t enumeration type to std_logic_vector.
|
||||
--
|
||||
function enum_to_vec_f(enum : in access_t) return
|
||||
std_logic_vector;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function to_boolean_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Converts a std_logic value to boolean.
|
||||
--
|
||||
function to_boolean_f(val : in std_logic) return boolean;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function to_std_logic_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Converts a boolean value to std_logic.
|
||||
--
|
||||
function to_std_logic_f(val : in boolean) return std_logic;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function mod_6_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Calculate the modulo of 6.
|
||||
-- Only the positive part is considered.
|
||||
--
|
||||
function mod_6_f(val : in hv_t) return hv_t;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end vdp18_pack;
|
||||
|
||||
|
||||
package body vdp18_pack is
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function enum_to_vec_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Translate access_t enumeration type to std_logic_vector.
|
||||
--
|
||||
function enum_to_vec_f(enum : in access_t) return
|
||||
std_logic_vector is
|
||||
variable result_v : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
case enum is
|
||||
when AC_NONE =>
|
||||
result_v := "0000";
|
||||
when AC_PNT =>
|
||||
result_v := "0001";
|
||||
when AC_PGT =>
|
||||
result_v := "0010";
|
||||
when AC_PCT =>
|
||||
result_v := "0011";
|
||||
when AC_STST =>
|
||||
result_v := "0100";
|
||||
when AC_SATY =>
|
||||
result_v := "0101";
|
||||
when AC_SATX =>
|
||||
result_v := "0110";
|
||||
when AC_SATN =>
|
||||
result_v := "0111";
|
||||
when AC_SATC =>
|
||||
result_v := "1000";
|
||||
when AC_SPTL =>
|
||||
result_v := "1001";
|
||||
when AC_SPTH =>
|
||||
result_v := "1010";
|
||||
when AC_CPU =>
|
||||
result_v := "1111";
|
||||
when others =>
|
||||
result_v := "UUUU";
|
||||
end case;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function to_boolean_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Converts a std_logic value to boolean.
|
||||
--
|
||||
function to_boolean_f(val : in std_logic) return boolean is
|
||||
variable result_v : boolean;
|
||||
begin
|
||||
case to_X01(val) is
|
||||
when '1' =>
|
||||
result_v := true;
|
||||
when '0' =>
|
||||
result_v := false;
|
||||
when others =>
|
||||
result_v := false;
|
||||
end case;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function to_std_logic_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Converts a boolean value to std_logic.
|
||||
--
|
||||
function to_std_logic_f(val : in boolean) return std_logic is
|
||||
variable result_v : std_logic;
|
||||
begin
|
||||
case val is
|
||||
when true =>
|
||||
result_v := '1';
|
||||
when false =>
|
||||
result_v := '0';
|
||||
end case;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Function mod_6_f
|
||||
--
|
||||
-- Purpose:
|
||||
-- Calculate the modulo of 6.
|
||||
-- Only the positive part is considered.
|
||||
--
|
||||
function mod_6_f(val : in hv_t) return hv_t is
|
||||
variable mod_v : natural;
|
||||
variable result_v : hv_t;
|
||||
begin
|
||||
if val(0) = '0' then
|
||||
result_v := (others => '0');
|
||||
mod_v := 0;
|
||||
for idx in 0 to 255 loop
|
||||
if val = idx then
|
||||
result_v := to_signed(mod_v, hv_t'length);
|
||||
end if;
|
||||
|
||||
if mod_v < 5 then
|
||||
mod_v := mod_v + 1;
|
||||
else
|
||||
mod_v := 0;
|
||||
end if;
|
||||
end loop;
|
||||
else
|
||||
result_v := (others => '-');
|
||||
end if;
|
||||
|
||||
return result_v;
|
||||
end;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
end vdp18_pack;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_pattern-c.vhd,v 1.5 2006/06/18 10:47:06 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_pattern_rtl_c0 of vdp18_pattern is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_pattern_rtl_c0;
|
|
@ -0,0 +1,233 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_pattern.vhd,v 1.8 2006/06/18 10:47:06 arnim Exp $
|
||||
--
|
||||
-- Pattern Generation Controller
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.vdp18_pack.opmode_t;
|
||||
use work.vdp18_pack.access_t;
|
||||
use work.vdp18_pack.hv_t;
|
||||
|
||||
entity vdp18_pattern is
|
||||
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
opmode_i : in opmode_t;
|
||||
access_type_i : in access_t;
|
||||
num_line_i : in hv_t;
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
vert_inc_i : in boolean;
|
||||
vsync_n_i : in std_logic;
|
||||
reg_col1_i : in std_logic_vector(0 to 3);
|
||||
reg_col0_i : in std_logic_vector(0 to 3);
|
||||
pat_table_o : out std_logic_vector(0 to 9);
|
||||
pat_name_o : out std_logic_vector(0 to 7);
|
||||
pat_col_o : out std_logic_vector(0 to 3)
|
||||
);
|
||||
|
||||
end vdp18_pattern;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_pattern is
|
||||
|
||||
signal pat_cnt_q : unsigned(0 to 9);
|
||||
signal pat_name_q,
|
||||
pat_tmp_q,
|
||||
pat_shift_q,
|
||||
pat_col_q : std_logic_vector(0 to 7);
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements:
|
||||
-- * pattern shift register
|
||||
-- * pattern color register
|
||||
-- * pattern counter
|
||||
--
|
||||
seq: process (clk_i, reset_i)
|
||||
begin
|
||||
if reset_i then
|
||||
pat_cnt_q <= (others => '0');
|
||||
pat_name_q <= (others => '0');
|
||||
pat_tmp_q <= (others => '0');
|
||||
pat_shift_q <= (others => '0');
|
||||
pat_col_q <= (others => '0');
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
if clk_en_5m37_i then
|
||||
-- shift pattern with every pixel clock
|
||||
pat_shift_q(0 to 6) <= pat_shift_q(1 to 7);
|
||||
end if;
|
||||
|
||||
if clk_en_acc_i then
|
||||
-- determine register update based on current access type -------------
|
||||
case access_type_i is
|
||||
when AC_PNT =>
|
||||
-- store pattern name
|
||||
pat_name_q <= vram_d_i;
|
||||
-- increment pattern counter
|
||||
pat_cnt_q <= pat_cnt_q + 1;
|
||||
|
||||
when AC_PCT =>
|
||||
-- store pattern color in temporary register
|
||||
pat_tmp_q <= vram_d_i;
|
||||
|
||||
when AC_PGT =>
|
||||
if opmode_i = OPMODE_MULTIC then
|
||||
-- set shift register to constant value
|
||||
-- this value generates 4 bits of color1
|
||||
-- followed by 4 bits of color0
|
||||
pat_shift_q <= "11110000";
|
||||
-- set pattern color from pattern generator memory
|
||||
pat_col_q <= vram_d_i;
|
||||
else
|
||||
-- all other modes:
|
||||
-- store pattern line in shift register
|
||||
pat_shift_q <= vram_d_i;
|
||||
-- move pattern color from temporary register to color register
|
||||
pat_col_q <= pat_tmp_q;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
|
||||
end if;
|
||||
|
||||
if vert_inc_i then
|
||||
-- redo patterns of if there are more lines inside this pattern
|
||||
if num_line_i(0) = '0' then
|
||||
case opmode_i is
|
||||
when OPMODE_TEXTM =>
|
||||
if num_line_i(6 to 8) /= "111" then
|
||||
pat_cnt_q <= pat_cnt_q - 40;
|
||||
end if;
|
||||
|
||||
when OPMODE_GRAPH1 |
|
||||
OPMODE_GRAPH2 |
|
||||
OPMODE_MULTIC =>
|
||||
if num_line_i(6 to 8) /= "111" then
|
||||
pat_cnt_q <= pat_cnt_q - 32;
|
||||
end if;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if vsync_n_i = '0' then
|
||||
-- reset pattern counter at end of active display area
|
||||
pat_cnt_q <= (others => '0');
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process col_gen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Generates the color of the current pattern pixel.
|
||||
--
|
||||
col_gen: process (opmode_i,
|
||||
pat_shift_q,
|
||||
pat_col_q,
|
||||
reg_col1_i,
|
||||
reg_col0_i)
|
||||
variable pix_v : std_logic;
|
||||
begin
|
||||
-- default assignment
|
||||
pat_col_o <= "0000";
|
||||
pix_v := pat_shift_q(0);
|
||||
|
||||
case opmode_i is
|
||||
-- Text Mode ------------------------------------------------------------
|
||||
when OPMODE_TEXTM =>
|
||||
if pix_v = '1' then
|
||||
pat_col_o <= reg_col1_i;
|
||||
else
|
||||
pat_col_o <= reg_col0_i;
|
||||
end if;
|
||||
|
||||
-- Graphics I, II and Multicolor Mode -----------------------------------
|
||||
when OPMODE_GRAPH1 |
|
||||
OPMODE_GRAPH2 |
|
||||
OPMODE_MULTIC =>
|
||||
if pix_v = '1' then
|
||||
pat_col_o <= pat_col_q(0 to 3);
|
||||
else
|
||||
pat_col_o <= pat_col_q(4 to 7);
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
|
||||
end case;
|
||||
end process col_gen;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output Mapping
|
||||
-----------------------------------------------------------------------------
|
||||
pat_table_o <= std_logic_vector(pat_cnt_q);
|
||||
pat_name_o <= pat_name_q;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,14 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_sprite-c.vhd,v 1.3 2006/06/18 10:47:06 arnim Exp $
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
configuration vdp18_sprite_rtl_c0 of vdp18_sprite is
|
||||
|
||||
for rtl
|
||||
end for;
|
||||
|
||||
end vdp18_sprite_rtl_c0;
|
|
@ -0,0 +1,441 @@
|
|||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A.
|
||||
--
|
||||
-- $Id: vdp18_sprite.vhd,v 1.11 2006/06/18 10:47:06 arnim Exp $
|
||||
--
|
||||
-- Sprite Generation Controller
|
||||
--
|
||||
-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net)
|
||||
--
|
||||
-- All rights reserved
|
||||
--
|
||||
-- Redistribution and use in source and synthezised forms, with or without
|
||||
-- modification, are permitted provided that the following conditions are met:
|
||||
--
|
||||
-- Redistributions of source code must retain the above copyright notice,
|
||||
-- this list of conditions and the following disclaimer.
|
||||
--
|
||||
-- Redistributions in synthesized form must reproduce the above copyright
|
||||
-- notice, this list of conditions and the following disclaimer in the
|
||||
-- documentation and/or other materials provided with the distribution.
|
||||
--
|
||||
-- Neither the name of the author nor the names of other contributors may
|
||||
-- be used to endorse or promote products derived from this software without
|
||||
-- specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
|
||||
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
-- POSSIBILITY OF SUCH DAMAGE.
|
||||
--
|
||||
-- Please report bugs to the author, but before you do so, please
|
||||
-- make sure that this is not a derivative work and that
|
||||
-- you have the latest version of this file.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
use work.vdp18_pack.hv_t;
|
||||
use work.vdp18_pack.access_t;
|
||||
|
||||
entity vdp18_sprite is
|
||||
|
||||
port (
|
||||
clk_i : in std_logic;
|
||||
clk_en_5m37_i : in boolean;
|
||||
clk_en_acc_i : in boolean;
|
||||
reset_i : in boolean;
|
||||
access_type_i : in access_t;
|
||||
num_pix_i : in hv_t;
|
||||
num_line_i : in hv_t;
|
||||
vram_d_i : in std_logic_vector(0 to 7);
|
||||
vert_inc_i : in boolean;
|
||||
reg_size1_i : in boolean;
|
||||
reg_mag1_i : in boolean;
|
||||
spr_5th_o : out boolean;
|
||||
spr_5th_num_o : out std_logic_vector(0 to 4);
|
||||
stop_sprite_o : out boolean;
|
||||
spr_coll_o : out boolean;
|
||||
spr_num_o : out std_logic_vector(0 to 4);
|
||||
spr_line_o : out std_logic_vector(0 to 3);
|
||||
spr_name_o : out std_logic_vector(0 to 7);
|
||||
spr0_col_o : out std_logic_vector(0 to 3);
|
||||
spr1_col_o : out std_logic_vector(0 to 3);
|
||||
spr2_col_o : out std_logic_vector(0 to 3);
|
||||
spr3_col_o : out std_logic_vector(0 to 3)
|
||||
);
|
||||
|
||||
end vdp18_sprite;
|
||||
|
||||
|
||||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use work.vdp18_pack.all;
|
||||
|
||||
architecture rtl of vdp18_sprite is
|
||||
|
||||
subtype sprite_number_t is unsigned(0 to 4);
|
||||
type sprite_numbers_t is array (natural range 0 to 3) of sprite_number_t;
|
||||
signal sprite_numbers_q : sprite_numbers_t;
|
||||
|
||||
signal sprite_num_q : unsigned(0 to 4);
|
||||
signal sprite_idx_q : unsigned(0 to 2);
|
||||
signal sprite_name_q : std_logic_vector(0 to 7);
|
||||
|
||||
subtype sprite_x_pos_t is unsigned(0 to 7);
|
||||
type sprite_xpos_t is array (natural range 0 to 3) of sprite_x_pos_t;
|
||||
signal sprite_xpos_q : sprite_xpos_t;
|
||||
type sprite_ec_t is array (natural range 0 to 3) of std_logic;
|
||||
signal sprite_ec_q : sprite_ec_t;
|
||||
type sprite_xtog_t is array (natural range 0 to 3) of std_logic;
|
||||
signal sprite_xtog_q : sprite_xtog_t;
|
||||
|
||||
subtype sprite_col_t is std_logic_vector(0 to 3);
|
||||
type sprite_cols_t is array (natural range 0 to 3) of sprite_col_t;
|
||||
signal sprite_cols_q : sprite_cols_t;
|
||||
|
||||
subtype sprite_pat_t is std_logic_vector(0 to 15);
|
||||
type sprite_pats_t is array (natural range 0 to 3) of sprite_pat_t;
|
||||
signal sprite_pats_q : sprite_pats_t;
|
||||
|
||||
signal sprite_line_s,
|
||||
sprite_line_q : std_logic_vector(0 to 3);
|
||||
signal sprite_visible_s : boolean;
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process seq
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the sequential elements.
|
||||
--
|
||||
seq: process (clk_i, reset_i)
|
||||
variable sprite_idx_inc_v,
|
||||
sprite_idx_dec_v : unsigned(sprite_idx_q'range);
|
||||
variable sprite_idx_v : natural range 0 to 3;
|
||||
begin
|
||||
if reset_i then
|
||||
sprite_numbers_q <= (others => (others => '0'));
|
||||
sprite_num_q <= (others => '0');
|
||||
sprite_idx_q <= (others => '0');
|
||||
sprite_line_q <= (others => '0');
|
||||
sprite_name_q <= (others => '0');
|
||||
sprite_cols_q <= (others => (others => '0'));
|
||||
sprite_xpos_q <= (others => (others => '0'));
|
||||
sprite_ec_q <= (others => '0');
|
||||
sprite_xtog_q <= (others => '0');
|
||||
sprite_pats_q <= (others => (others => '0'));
|
||||
|
||||
elsif clk_i'event and clk_i = '1' then
|
||||
-- sprite index will be incremented during sprite tests
|
||||
sprite_idx_inc_v := sprite_idx_q + 1;
|
||||
-- sprite index will be decremented at end of sprite pattern data
|
||||
sprite_idx_dec_v := sprite_idx_q - 1;
|
||||
-- just save typing
|
||||
sprite_idx_v := to_integer(sprite_idx_q(1 to 2));
|
||||
|
||||
if clk_en_5m37_i then
|
||||
-- pre-decrement index counter when sprite reading starts
|
||||
if num_pix_i = hv_sprite_start_c and sprite_idx_q > 0 then
|
||||
sprite_idx_q <= sprite_idx_dec_v;
|
||||
end if;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- X position counters
|
||||
-----------------------------------------------------------------------
|
||||
for idx in 0 to 3 loop
|
||||
if num_pix_i(0) = '0' or
|
||||
(sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111") then
|
||||
if sprite_xpos_q(idx) /= 0 then
|
||||
-- decrement counter until 0
|
||||
sprite_xpos_q(idx) <= sprite_xpos_q(idx) - 1;
|
||||
else
|
||||
-- toggle magnification flag
|
||||
sprite_xtog_q(idx) <= not sprite_xtog_q(idx);
|
||||
end if;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
-- Sprite pattern shift registers
|
||||
-----------------------------------------------------------------------
|
||||
for idx in 0 to 3 loop
|
||||
if sprite_xpos_q(idx) = 0 then -- x counter elapsed
|
||||
-- decide when to shift pattern information
|
||||
-- case 1: pixel number is >= 0
|
||||
-- => active display area
|
||||
-- case 2: early clock bit is set and pixel number is between
|
||||
-- -32 and 0
|
||||
-- shift if
|
||||
-- magnification not enbled
|
||||
-- or
|
||||
-- magnification enabled and toggle marker true
|
||||
if (num_pix_i(0) = '0' or
|
||||
(sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111")) and
|
||||
(sprite_xtog_q(idx) = '1' or not reg_mag1_i) then
|
||||
--
|
||||
-- shift pattern left and fill vacated position with
|
||||
-- transparent information
|
||||
sprite_pats_q(idx)(0 to 14) <= sprite_pats_q(idx)(1 to 15);
|
||||
sprite_pats_q(idx)(15) <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- clear pattern at end of visible display
|
||||
-- this removes "left-overs" when a sprite overlaps the right border
|
||||
if num_pix_i = "011111111" then
|
||||
sprite_pats_q(idx) <= (others => '0');
|
||||
end if;
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
|
||||
if vert_inc_i then
|
||||
-- reset sprite num counter and sprite index counter
|
||||
sprite_num_q <= (others => '0');
|
||||
sprite_idx_q <= (others => '0');
|
||||
|
||||
elsif clk_en_acc_i then
|
||||
case access_type_i is
|
||||
when AC_STST =>
|
||||
-- increment sprite number counter
|
||||
sprite_num_q <= sprite_num_q + 1;
|
||||
|
||||
if sprite_visible_s then
|
||||
if sprite_idx_q < 4 then
|
||||
-- store sprite number
|
||||
sprite_numbers_q(sprite_idx_v) <= sprite_num_q;
|
||||
-- and increment index counter
|
||||
sprite_idx_q <= sprite_idx_inc_v;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when AC_SATY =>
|
||||
-- store sprite line
|
||||
sprite_line_q <= sprite_line_s;
|
||||
|
||||
when AC_SATX =>
|
||||
-- save x position
|
||||
sprite_xpos_q(sprite_idx_v) <= unsigned(vram_d_i);
|
||||
-- reset toggle flag for magnified sprites
|
||||
sprite_xtog_q(sprite_idx_v) <= '0';
|
||||
|
||||
when AC_SATN =>
|
||||
-- save sprite name
|
||||
sprite_name_q <= vram_d_i;
|
||||
|
||||
when AC_SATC =>
|
||||
-- save sprite color
|
||||
sprite_cols_q(sprite_idx_v) <= vram_d_i(4 to 7);
|
||||
-- and save early clock bit
|
||||
sprite_ec_q(sprite_idx_v) <= vram_d_i(0);
|
||||
|
||||
when AC_SPTH =>
|
||||
-- save upper pattern data
|
||||
sprite_pats_q(sprite_idx_v)(0 to 7)
|
||||
<= vram_d_i;
|
||||
-- set lower part to transparent
|
||||
sprite_pats_q(sprite_idx_v)(8 to 15)
|
||||
<= (others => '0');
|
||||
|
||||
if not reg_size1_i then
|
||||
-- decrement index counter in 8-bit mode
|
||||
sprite_idx_q <= sprite_idx_dec_v;
|
||||
end if;
|
||||
|
||||
when AC_SPTL =>
|
||||
-- save lower pattern data
|
||||
sprite_pats_q(sprite_idx_v)(8 to 15) <= vram_d_i;
|
||||
|
||||
-- always decrement index counter
|
||||
sprite_idx_q <= sprite_idx_dec_v;
|
||||
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process seq;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process calc_vert
|
||||
--
|
||||
-- Purpose:
|
||||
-- Calculates the displayed line of the sprite and determines whether it
|
||||
-- is visible on the current line or not.
|
||||
--
|
||||
calc_vert: process (clk_en_acc_i, access_type_i,
|
||||
vram_d_i,
|
||||
num_pix_i, num_line_i,
|
||||
sprite_num_q, sprite_idx_q,
|
||||
reg_size1_i, reg_mag1_i)
|
||||
variable sprite_line_v : signed(0 to 8);
|
||||
variable vram_d_v : signed(0 to 8);
|
||||
begin
|
||||
-- default assignments
|
||||
sprite_visible_s <= false;
|
||||
stop_sprite_o <= false;
|
||||
|
||||
vram_d_v := resize(signed(vram_d_i), 9);
|
||||
-- determine if y information from VRAM should be treated
|
||||
-- as a signed or unsigned number
|
||||
if vram_d_v < -31 then
|
||||
-- treat as unsigned number
|
||||
vram_d_v(0) := '0';
|
||||
end if;
|
||||
|
||||
sprite_line_v := num_line_i - vram_d_v;
|
||||
if reg_mag1_i then
|
||||
-- unmagnify line number
|
||||
sprite_line_v := shift_right(sprite_line_v, 1);
|
||||
end if;
|
||||
|
||||
-- check result bounds
|
||||
if sprite_line_v >= 0 then
|
||||
if reg_size1_i then
|
||||
-- double sized sprite: 16 data lines
|
||||
if sprite_line_v < 16 then
|
||||
sprite_visible_s <= true;
|
||||
end if;
|
||||
else
|
||||
-- standard sized sprite: 8 data lines
|
||||
if sprite_line_v < 8 then
|
||||
sprite_visible_s <= true;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- finally: line number of current sprite
|
||||
sprite_line_s <= std_logic_vector(sprite_line_v(5 to 8));
|
||||
|
||||
if clk_en_acc_i then
|
||||
-- determine when to stop sprite scanning
|
||||
if access_type_i = AC_STST then
|
||||
if vram_d_v = 208 then
|
||||
-- stop upon Y position 208
|
||||
stop_sprite_o <= true;
|
||||
end if;
|
||||
|
||||
if sprite_idx_q = 4 then
|
||||
-- stop when all sprite positions have been vacated
|
||||
stop_sprite_o <= true;
|
||||
end if;
|
||||
|
||||
if sprite_num_q = 31 then
|
||||
-- stop when all sprites have been read
|
||||
stop_sprite_o <= true;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- stop sprite reading when last active sprite has been processed
|
||||
if sprite_idx_q = 0 and
|
||||
( access_type_i = AC_SPTL or
|
||||
(access_type_i = AC_SPTH and not reg_size1_i)) then
|
||||
stop_sprite_o <= true;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- stop sprite reading when no sprite is active on current line
|
||||
if num_pix_i = hv_sprite_start_c and sprite_idx_q = 0 then
|
||||
stop_sprite_o <= true;
|
||||
end if;
|
||||
end process calc_vert;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process fifth
|
||||
--
|
||||
-- Purpose:
|
||||
-- Detects the fifth sprite.
|
||||
--
|
||||
fifth: process (clk_en_acc_i, access_type_i,
|
||||
sprite_visible_s,
|
||||
sprite_idx_q,
|
||||
sprite_num_q)
|
||||
begin
|
||||
-- default assignments
|
||||
spr_5th_o <= false;
|
||||
spr_5th_num_o <= (others => '0');
|
||||
|
||||
if clk_en_acc_i and access_type_i = AC_STST then
|
||||
if sprite_visible_s and sprite_idx_q = 4 then
|
||||
spr_5th_o <= true;
|
||||
spr_5th_num_o <= std_logic_vector(sprite_num_q);
|
||||
end if;
|
||||
end if;
|
||||
end process fifth;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process col_mux
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the color multiplexers.
|
||||
--
|
||||
col_mux: process (sprite_cols_q,
|
||||
sprite_pats_q,
|
||||
sprite_xpos_q)
|
||||
variable num_spr_pix_v : unsigned(0 to 2);
|
||||
begin
|
||||
-- default assignments
|
||||
-- sprite colors are set to transparent
|
||||
spr0_col_o <= (others => '0');
|
||||
spr1_col_o <= (others => '0');
|
||||
spr2_col_o <= (others => '0');
|
||||
spr3_col_o <= (others => '0');
|
||||
num_spr_pix_v := (others => '0');
|
||||
|
||||
if sprite_xpos_q(0) = 0 and sprite_pats_q(0)(0) = '1' then
|
||||
spr0_col_o <= sprite_cols_q(0);
|
||||
num_spr_pix_v := num_spr_pix_v + 1;
|
||||
end if;
|
||||
if sprite_xpos_q(1) = 0 and sprite_pats_q(1)(0) = '1' then
|
||||
spr1_col_o <= sprite_cols_q(1);
|
||||
num_spr_pix_v := num_spr_pix_v + 1;
|
||||
end if;
|
||||
if sprite_xpos_q(2) = 0 and sprite_pats_q(2)(0) = '1' then
|
||||
spr2_col_o <= sprite_cols_q(2);
|
||||
num_spr_pix_v := num_spr_pix_v + 1;
|
||||
end if;
|
||||
if sprite_xpos_q(3) = 0 and sprite_pats_q(3)(0) = '1' then
|
||||
spr3_col_o <= sprite_cols_q(3);
|
||||
num_spr_pix_v := num_spr_pix_v + 1;
|
||||
end if;
|
||||
|
||||
spr_coll_o <= num_spr_pix_v > 1;
|
||||
end process col_mux;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Output mapping
|
||||
-----------------------------------------------------------------------------
|
||||
spr_num_o <= std_logic_vector(sprite_num_q)
|
||||
when access_type_i = AC_STST else
|
||||
std_logic_vector(sprite_numbers_q(to_integer(sprite_idx_q(1 to 2))));
|
||||
spr_line_o <= sprite_line_q;
|
||||
spr_name_o <= sprite_name_q;
|
||||
|
||||
end rtl;
|
|
@ -0,0 +1,4 @@
|
|||
set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "vram.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "vram_bb.v"]
|
|
@ -0,0 +1,172 @@
|
|||
// megafunction wizard: %RAM: 1-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: vram.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2013 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module vram (
|
||||
address,
|
||||
clock,
|
||||
data,
|
||||
wren,
|
||||
q);
|
||||
|
||||
input [13:0] address;
|
||||
input clock;
|
||||
input [7:0] data;
|
||||
input wren;
|
||||
output [7:0] q;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 clock;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [7:0] sub_wire0;
|
||||
wire [7:0] q = sub_wire0[7:0];
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (address),
|
||||
.clock0 (clock),
|
||||
.data_a (data),
|
||||
.wren_a (wren),
|
||||
.q_a (sub_wire0),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.address_b (1'b1),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clock1 (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.data_b (1'b1),
|
||||
.eccstatus (),
|
||||
.q_b (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1),
|
||||
.wren_b (1'b0));
|
||||
defparam
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.intended_device_family = "Cyclone III",
|
||||
altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 16384,
|
||||
altsyncram_component.operation_mode = "SINGLE_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "CLOCK0",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.widthad_a = 14,
|
||||
altsyncram_component.width_a = 8,
|
||||
altsyncram_component.width_byteena_a = 1;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrByte NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrData NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clken NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: RegAddr NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegData NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegOutput NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: SingleClock NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WidthAddr NUMERIC "14"
|
||||
// Retrieval info: PRIVATE: WidthData NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
|
||||
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
|
||||
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram_bb.v TRUE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
|
@ -0,0 +1,123 @@
|
|||
// megafunction wizard: %RAM: 1-PORT%VBB%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: vram.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
//Copyright (C) 1991-2013 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
module vram (
|
||||
address,
|
||||
clock,
|
||||
data,
|
||||
wren,
|
||||
q);
|
||||
|
||||
input [13:0] address;
|
||||
input clock;
|
||||
input [7:0] data;
|
||||
input wren;
|
||||
output [7:0] q;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 clock;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrByte NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrData NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clken NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: RegAddr NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegData NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegOutput NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: SingleClock NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WidthAddr NUMERIC "14"
|
||||
// Retrieval info: PRIVATE: WidthData NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
|
||||
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
|
||||
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL vram_bb.v TRUE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
46
rtl/vram.v
46
rtl/vram.v
|
@ -1,46 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
// Description: Video RAM for system
|
||||
//
|
||||
// Author.....: Alan Garfield
|
||||
// Niels A. Moseley
|
||||
// Date.......: 26-1-2018
|
||||
//
|
||||
|
||||
module vram (
|
||||
input clk, // clock signal
|
||||
input [10:0] read_addr, // read address bus
|
||||
input [10:0] write_addr, // write address bus
|
||||
input r_en, // active high read enable strobe
|
||||
input w_en, // active high write enable strobe
|
||||
input [5:0] din, // 6-bit data bus (input)
|
||||
output reg [5:0] dout // 6-bit data bus (output)
|
||||
);
|
||||
|
||||
reg [5:0] ram_data[0:2047];
|
||||
|
||||
initial
|
||||
$readmemb("roms/vga_vram.bin", ram_data, 0, 2047);
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (r_en) dout <= ram_data[read_addr];
|
||||
if (w_en) ram_data[write_addr] <= din;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue