mirror of
https://github.com/MiSTer-devel/GBA_MiSTer.git
synced 2026-05-17 03:03:40 +00:00
- added 2x resolution mode
- updated framework - improved ddr3 access latency - 30Hz flickereduce option
This commit is contained in:
5
GBA.qsf
5
GBA.qsf
@@ -13,7 +13,7 @@ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "17.0.0 Lite Edition"
|
||||
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
@@ -49,7 +49,8 @@ set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON
|
||||
set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW
|
||||
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1.0
|
||||
set_global_assignment -name SEED 2
|
||||
set_global_assignment -name SEED 3
|
||||
set_global_assignment -name VERILOG_MACRO "USE_FB=1"
|
||||
|
||||
source sys/sys.tcl
|
||||
source sys/sys_analog.tcl
|
||||
|
||||
109
GBA.sv
109
GBA.sv
@@ -65,6 +65,7 @@ module emu
|
||||
// b[0]: osd button
|
||||
output [1:0] BUTTONS,
|
||||
|
||||
input CLK_AUDIO, // 24.576 MHz
|
||||
output [15:0] AUDIO_L,
|
||||
output [15:0] AUDIO_R,
|
||||
output AUDIO_S, // 1 - signed audio samples, 0 - unsigned
|
||||
@@ -121,7 +122,22 @@ module emu
|
||||
input [6:0] USER_IN,
|
||||
output [6:0] USER_OUT,
|
||||
|
||||
input OSD_STATUS
|
||||
input OSD_STATUS,
|
||||
|
||||
// Use framebuffer from DDRAM (USE_FB=1 in qsf)
|
||||
// FB_FORMAT:
|
||||
// [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp
|
||||
// [3] : 0=16bits 565 1=16bits 1555
|
||||
// [4] : 0=RGB 1=BGR (for 16/24/32 modes)
|
||||
//
|
||||
// stride is modulo 256 of bytes
|
||||
output FB_EN,
|
||||
output [4:0] FB_FORMAT,
|
||||
output [11:0] FB_WIDTH,
|
||||
output [11:0] FB_HEIGHT,
|
||||
output [31:0] FB_BASE,
|
||||
input FB_VBL,
|
||||
input FB_LL
|
||||
);
|
||||
|
||||
assign ADC_BUS = 'Z;
|
||||
@@ -141,6 +157,12 @@ assign VIDEO_ARY = status[1] ? 8'd9 : 8'd2;
|
||||
|
||||
assign {SD_SCK, SD_MOSI, SD_CS} = 'Z;
|
||||
|
||||
assign FB_EN = status[21] || status[22];
|
||||
assign FB_FORMAT = 5'b00110;
|
||||
assign FB_WIDTH = 12'd480;
|
||||
assign FB_HEIGHT = 12'd320;
|
||||
|
||||
|
||||
/////////////////////// CLOCK/RESET ///////////////////////////////////
|
||||
|
||||
wire pll_locked;
|
||||
@@ -163,7 +185,7 @@ wire reset = RESET | buttons[1] | status[0] | cart_download | bk_loading | hold_
|
||||
// 0 1 2 3 4 5 6
|
||||
// 0123456789012345678901234567890123456789012345678901234567890123
|
||||
// 0123456789ABCDEFGHIJKLMNOPQRSTUV0123456789ABCDEFGHIJKLMNOPQRSTUV
|
||||
// XXXXXXXXX XXXXXXXXXXXXXXXXXXXXX
|
||||
// XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXX
|
||||
|
||||
`include "build_id.v"
|
||||
parameter CONF_STR = {
|
||||
@@ -183,8 +205,9 @@ parameter CONF_STR = {
|
||||
"O1,Aspect Ratio,3:2,16:9;",
|
||||
"O24,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%;",
|
||||
"OOQ,Modify Colors,Off,GBA 2.2,GBA 1.6,NDS 1.6,VBA 1.4,75%,50%,25%;",
|
||||
"OJ,Flickerblend,Off,On;",
|
||||
"O9A,Flickerblend,Off,Blend,30Hz;",
|
||||
"OK,Spritelimit,Off,On;",
|
||||
"OLM,2XResolution,Off,Background,Sprites,Both;",
|
||||
"O78,Stereo Mix,None,25%,50%,100%;",
|
||||
"-;",
|
||||
"OEF,Storage,Auto,SDRAM,DDR3;",
|
||||
@@ -445,8 +468,10 @@ gba
|
||||
.memory_remap(memory_remap_quirk),
|
||||
.save_state(ss_save),
|
||||
.load_state(ss_load),
|
||||
.interframe_blend(status[19]),
|
||||
.interframe_blend(status[10:9]),
|
||||
.maxpixels(status[20]),
|
||||
.hdmode2x_bg(status[21]),
|
||||
.hdmode2x_obj(status[22]),
|
||||
.shade_mode(shadercolors),
|
||||
.specialmodule(gpio_quirk),
|
||||
.solar_in(status[31:29]),
|
||||
@@ -516,6 +541,14 @@ gba
|
||||
.pixel_out_data(pixel_data), // RGB data for framebuffer
|
||||
.pixel_out_we(pixel_we), // new pixel for framebuffer
|
||||
|
||||
.largeimg_out_base(FB_BASE),
|
||||
.largeimg_out_addr(fb_addr),
|
||||
.largeimg_out_data(fb_din),
|
||||
.largeimg_out_req(fb_req),
|
||||
.largeimg_out_done(fb_ack),
|
||||
.largeimg_newframe(FB_VBL),
|
||||
.largeimg_singlebuf(FB_LL),
|
||||
|
||||
.sound_out_left(AUDIO_L),
|
||||
.sound_out_right(AUDIO_R)
|
||||
);
|
||||
@@ -633,6 +666,11 @@ wire [31:0] sdr_sdram_dout1, sdr_sdram_dout2, sdr_bus_dout;
|
||||
wire [15:0] sdr_bram_din;
|
||||
wire sdr_sdram_ack, sdr_bus_ack, sdr_bram_ack;
|
||||
|
||||
wire [27:2] fb_addr;
|
||||
wire [63:0] fb_din;
|
||||
wire fb_req;
|
||||
wire fb_ack;
|
||||
|
||||
sdram sdram
|
||||
(
|
||||
.*,
|
||||
@@ -708,7 +746,13 @@ ddram ddram
|
||||
.ch4_dout(ss_dout),
|
||||
.ch4_req(ss_req),
|
||||
.ch4_rnw(ss_rnw),
|
||||
.ch4_ready(ss_ack)
|
||||
.ch4_ready(ss_ack),
|
||||
|
||||
.ch5_addr({fb_addr, 1'b0}),
|
||||
.ch5_din(fb_din),
|
||||
.ch5_req(fb_req),
|
||||
.ch5_ready(fb_ack)
|
||||
|
||||
);
|
||||
|
||||
wire [127:0] time_din_h = {32'd0, time_din, "RT"};
|
||||
@@ -718,20 +762,51 @@ wire bram_ack = sdram_en ? sdr_bram_ack : ddr_bram_ack;
|
||||
assign sd_buff_din = extra_data_addr ? (time_din_h[{sd_buff_addr[2:0], 4'b0000} +: 16]) : bram_buff_out;
|
||||
wire [15:0] bram_buff_out;
|
||||
|
||||
SyncRamDual #(16,8) bram
|
||||
altsyncram altsyncram_component
|
||||
(
|
||||
.clk(clk_sys),
|
||||
|
||||
.addr_a(bram_addr),
|
||||
.we_a(~bk_loading & bram_ack),
|
||||
.datain_a(bram_din),
|
||||
.dataout_a(bram_dout),
|
||||
|
||||
.addr_b(sd_buff_addr),
|
||||
.we_b(sd_buff_wr && ~extra_data_addr),
|
||||
.datain_b(sd_buff_dout),
|
||||
.dataout_b(bram_buff_out)
|
||||
.address_a (bram_addr),
|
||||
.address_b (sd_buff_addr),
|
||||
.clock0 (clk_sys),
|
||||
.clock1 (clk_sys),
|
||||
.data_a (bram_din),
|
||||
.data_b (sd_buff_dout),
|
||||
.wren_a (~bk_loading & bram_ack),
|
||||
.wren_b (sd_buff_wr && ~extra_data_addr),
|
||||
.q_a (bram_dout),
|
||||
.q_b (bram_buff_out),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1)
|
||||
);
|
||||
defparam
|
||||
altsyncram_component.address_reg_b = "CLOCK1",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.indata_reg_b = "CLOCK1",
|
||||
altsyncram_component.intended_device_family = "Cyclone V",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 256,
|
||||
altsyncram_component.numwords_b = 256,
|
||||
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "UNREGISTERED",
|
||||
altsyncram_component.outdata_reg_b = "UNREGISTERED",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.widthad_a = 8,
|
||||
altsyncram_component.widthad_b = 8,
|
||||
altsyncram_component.width_a = 16,
|
||||
altsyncram_component.width_b = 16,
|
||||
altsyncram_component.width_byteena_a = 1,
|
||||
altsyncram_component.width_byteena_b = 1,
|
||||
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1";
|
||||
|
||||
reg [7:0] bram_addr;
|
||||
reg bram_tx_start;
|
||||
|
||||
11
README.md
11
README.md
@@ -31,7 +31,7 @@ As the BIOS is already replaced at boot time, you must save this settings and ha
|
||||
- Savestates
|
||||
- FastForward - speed up game by factor 2-4
|
||||
- CPU Turbomode - give games additional CPU power
|
||||
- Flickerblend - turn on for games like F-Zero, Mario Kart or NES Classics to prevent flickering effects
|
||||
- Flickerblend - set to blend or 30Hz mode for games like F-Zero, Mario Kart or NES Classics to prevent flickering effects
|
||||
- Spritelimit - turn on to prevent wrong sprites for games that rely on the limit (opt-in)
|
||||
- Cheats
|
||||
- Color optimizations: shader colors and desaturate
|
||||
@@ -40,6 +40,7 @@ As the BIOS is already replaced at boot time, you must save this settings and ha
|
||||
- Solar Sensor: Set brightness in OSD
|
||||
- Gyro: use analog stick (map stick in Mister Main before)
|
||||
- RTC: automatically used, works with RTC board or internet connection
|
||||
- 2x Resolution: game is rendered at 480x320 instead of 240x160 pixels
|
||||
|
||||
# Savestates
|
||||
Core provides 4 slots to save the state. The first slot gets saved to disk and automatically loaded (but not applied)
|
||||
@@ -62,6 +63,14 @@ Currently there are only few games known that produce glitches without sprite pi
|
||||
- Gunstar Super Heroes
|
||||
- Famicon Mini Series Vol21 - Vol30
|
||||
|
||||
# 2x Resolution
|
||||
Improved rendering resolution for:
|
||||
- Affine background: "Mode7" games, typically racing games like Mario Kart
|
||||
- Affine sprites: games that scale or rotate sprites
|
||||
This rendering is experimental and can cause glitches, as not all game behavior can be supported.
|
||||
Those glitches can not be fixed without gamespecific hacks and therefore will not be fixed.
|
||||
Please don't add bugs in such cases.
|
||||
|
||||
# Cartridge Hardware supported games
|
||||
- RTC: Pokemon Sapphire+Ruby+Emerald, Boktai 1+2+3, Sennen Kazoku, Rockman EXE 4.5
|
||||
- Solar Sensor: Boktai 1+2+3
|
||||
|
||||
33
rtl/ddram.sv
33
rtl/ddram.sv
@@ -60,7 +60,13 @@ module ddram
|
||||
input [63:0] ch4_din,
|
||||
input ch4_req,
|
||||
input ch4_rnw,
|
||||
output ch4_ready
|
||||
output ch4_ready,
|
||||
|
||||
// framebuffer
|
||||
input [27:1] ch5_addr,
|
||||
input [63:0] ch5_din,
|
||||
input ch5_req,
|
||||
output ch5_ready
|
||||
);
|
||||
|
||||
reg [7:0] ram_burst;
|
||||
@@ -71,7 +77,7 @@ reg ram_read = 0;
|
||||
reg ram_write = 0;
|
||||
reg [7:0] ram_be;
|
||||
|
||||
reg [4:1] ready;
|
||||
reg [5:1] ready;
|
||||
|
||||
assign DDRAM_BURSTCNT = ram_burst;
|
||||
assign DDRAM_BE = ram_read ? 8'hFF : ram_be;
|
||||
@@ -88,18 +94,19 @@ assign ch1_ready = ready[1];
|
||||
assign ch2_ready = ready[2];
|
||||
assign ch3_ready = ready[3];
|
||||
assign ch4_ready = ready[4];
|
||||
assign ch5_ready = ready[5];
|
||||
|
||||
reg [63:0] next_q[2:1];
|
||||
reg [27:1] cache_addr[2:1];
|
||||
reg [1:0] state = 0;
|
||||
reg [2:1] cached = 0;
|
||||
reg [2:0] ch = 0;
|
||||
reg [4:1] ch_rq;
|
||||
reg [5:1] ch_rq;
|
||||
|
||||
always @(posedge DDRAM_CLK) begin
|
||||
|
||||
|
||||
ch_rq <= ch_rq | {ch4_req, ch3_req, ch2_req, ch1_req};
|
||||
ch_rq <= ch_rq | {ch5_req, ch4_req, ch3_req, ch2_req, ch1_req};
|
||||
ready <= 0;
|
||||
|
||||
if(!DDRAM_BUSY) begin
|
||||
@@ -107,7 +114,7 @@ always @(posedge DDRAM_CLK) begin
|
||||
ram_read <= 0;
|
||||
|
||||
case(state)
|
||||
0: if(ch_rq[1]) begin
|
||||
0: if(ch_rq[1] || ch1_req) begin
|
||||
ch_rq[1] <= 0;
|
||||
ch <= 1;
|
||||
ram_data <= {4{ch1_din}};
|
||||
@@ -141,7 +148,7 @@ always @(posedge DDRAM_CLK) begin
|
||||
state <= 1;
|
||||
end
|
||||
end
|
||||
else if(ch_rq[2]) begin
|
||||
else if(ch_rq[2] || ch2_req) begin
|
||||
ch_rq[2] <= 0;
|
||||
ch <= 2;
|
||||
ram_data <= {2{ch2_din}};
|
||||
@@ -175,7 +182,7 @@ always @(posedge DDRAM_CLK) begin
|
||||
state <= 1;
|
||||
end
|
||||
end
|
||||
else if(ch_rq[3]) begin
|
||||
else if(ch_rq[3] || ch3_req) begin
|
||||
ch_rq[3] <= 0;
|
||||
ch <= 3;
|
||||
ram_address <= {ch3_addr, 2'b00};
|
||||
@@ -192,7 +199,7 @@ always @(posedge DDRAM_CLK) begin
|
||||
state <= 1;
|
||||
end
|
||||
end
|
||||
else if(ch_rq[4]) begin
|
||||
else if(ch_rq[4] || ch4_req) begin
|
||||
ch_rq[4] <= 0;
|
||||
ch <= 4;
|
||||
ram_data <= ch4_din;
|
||||
@@ -207,6 +214,16 @@ always @(posedge DDRAM_CLK) begin
|
||||
ram_read <= 1;
|
||||
state <= 1;
|
||||
end
|
||||
end
|
||||
else if(ch_rq[5] || ch5_req) begin
|
||||
ch_rq[5] <= 0;
|
||||
ch <= 5;
|
||||
ram_data <= ch5_din;
|
||||
ram_be <= 8'hFF;
|
||||
ram_address <= ch5_addr;
|
||||
ram_write <= 1;
|
||||
ram_burst <= 1;
|
||||
ready[5] <= 1;
|
||||
end
|
||||
|
||||
1: if(DDRAM_DOUT_READY) begin
|
||||
|
||||
@@ -7,6 +7,7 @@ set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_dma_mo
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_merge.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_mode0.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_mode2.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_mode2_2x.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_mode345.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_drawer_obj.vhd ]
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) gba_gpu.vhd ]
|
||||
|
||||
@@ -3,6 +3,12 @@ use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity gba_drawer_mode2 is
|
||||
generic
|
||||
(
|
||||
DXYBITS : integer := 16;
|
||||
ACCURACYBITS : integer := 28;
|
||||
PIXELCOUNT : integer := 240
|
||||
);
|
||||
port
|
||||
(
|
||||
clk100 : in std_logic;
|
||||
@@ -17,16 +23,16 @@ entity gba_drawer_mode2 is
|
||||
wrapping : in std_logic;
|
||||
mosaic : in std_logic;
|
||||
Mosaic_H_Size : in unsigned(3 downto 0);
|
||||
refX : in signed(27 downto 0);
|
||||
refY : in signed(27 downto 0);
|
||||
refX : in signed;
|
||||
refY : in signed;
|
||||
refX_mosaic : in signed(27 downto 0);
|
||||
refY_mosaic : in signed(27 downto 0);
|
||||
dx : in signed(15 downto 0);
|
||||
dy : in signed(15 downto 0);
|
||||
dx : in signed(DXYBITS - 1 downto 0);
|
||||
dy : in signed(DXYBITS - 1 downto 0);
|
||||
|
||||
pixel_we : out std_logic := '0';
|
||||
pixeldata : buffer std_logic_vector(15 downto 0) := (others => '0');
|
||||
pixel_x : out integer range 0 to 239;
|
||||
pixel_x : out integer range 0 to (PIXELCOUNT - 1);
|
||||
|
||||
PALETTE_Drawer_addr : out integer range 0 to 127;
|
||||
PALETTE_Drawer_data : in std_logic_vector(31 downto 0);
|
||||
@@ -72,14 +78,14 @@ architecture arch of gba_drawer_mode2 is
|
||||
signal mapbaseaddr : integer;
|
||||
signal tilebaseaddr : integer;
|
||||
|
||||
signal realX : signed(27 downto 0);
|
||||
signal realY : signed(27 downto 0);
|
||||
signal realX : signed(ACCURACYBITS - 1 downto 0);
|
||||
signal realY : signed(ACCURACYBITS - 1 downto 0);
|
||||
signal xxx : signed(19 downto 0);
|
||||
signal yyy : signed(19 downto 0);
|
||||
signal xxx_pre : signed(19 downto 0);
|
||||
signal yyy_pre : signed(19 downto 0);
|
||||
|
||||
signal x_cnt : integer range 0 to 239;
|
||||
signal x_cnt : integer range 0 to (PIXELCOUNT - 1);
|
||||
signal scroll_mod : integer range 128 to 1024;
|
||||
signal tileinfo : std_logic_vector(7 downto 0) := (others => '0');
|
||||
|
||||
@@ -98,8 +104,8 @@ begin
|
||||
VRAM_Drawer_addr <= to_integer(VRAM_byteaddr(15 downto 2));
|
||||
PALETTE_Drawer_addr <= to_integer(unsigned(PALETTE_byteaddr(8 downto 2)));
|
||||
|
||||
xxx_pre <= realX(27 downto 8);
|
||||
yyy_pre <= realY(27 downto 8);
|
||||
xxx_pre <= realX(realX'left downto realX'left - 19);
|
||||
yyy_pre <= realY(realY'left downto realY'left - 19);
|
||||
|
||||
-- vramfetch
|
||||
process (clk100)
|
||||
@@ -112,12 +118,14 @@ begin
|
||||
|
||||
when IDLE =>
|
||||
if (line_trigger = '1') then
|
||||
if (mosaic = '1') then
|
||||
realX <= refX_mosaic;
|
||||
realY <= refY_mosaic;
|
||||
realX <= (others => '0');
|
||||
realY <= (others => '0');
|
||||
if (mosaic = '1' and unsigned(Mosaic_H_Size) > 0) then
|
||||
realX(realX'left downto realX'left - refX_mosaic'length + 1) <= refX_mosaic;
|
||||
realY(realY'left downto realY'left - refY_mosaic'length + 1) <= refY_mosaic;
|
||||
else
|
||||
realX <= refX;
|
||||
realY <= refY;
|
||||
realX(realX'left downto realX'left - refX'length + 1) <= refX;
|
||||
realY(realY'left downto realY'left - refY'length + 1) <= refY;
|
||||
end if;
|
||||
elsif (drawline = '1') then
|
||||
busy <= '1';
|
||||
@@ -150,7 +158,7 @@ begin
|
||||
xxx <= xxx_pre;
|
||||
yyy <= yyy_pre;
|
||||
if (xxx_pre < 0 or yyy_pre < 0 or xxx_pre >= scroll_mod or yyy_pre >= scroll_mod) then
|
||||
if (x_cnt < 239) then
|
||||
if (x_cnt < (PIXELCOUNT - 1)) then
|
||||
vramfetch <= CALCADDR1;
|
||||
x_cnt <= x_cnt + 1;
|
||||
else
|
||||
@@ -234,7 +242,7 @@ begin
|
||||
|
||||
when FETCHDONE =>
|
||||
if (palettefetch = IDLE) then
|
||||
if (x_cnt < 239) then
|
||||
if (x_cnt < (PIXELCOUNT - 1)) then
|
||||
vramfetch <= CALCADDR1;
|
||||
x_cnt <= x_cnt + 1;
|
||||
else
|
||||
|
||||
@@ -3,6 +3,12 @@ use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity gba_drawer_obj is
|
||||
generic
|
||||
(
|
||||
RESMULT : integer := 1;
|
||||
PIXELCOUNT : integer := 240;
|
||||
YMULTOFFSET : integer := 0
|
||||
);
|
||||
port
|
||||
(
|
||||
clk100 : in std_logic;
|
||||
@@ -26,7 +32,7 @@ entity gba_drawer_obj is
|
||||
pixeldata_color : out std_logic_vector(15 downto 0) := (others => '0');
|
||||
pixel_we_settings : out std_logic := '0';
|
||||
pixeldata_settings : out std_logic_vector(2 downto 0) := (others => '0');
|
||||
pixel_x : out integer range 0 to 239;
|
||||
pixel_x : out integer range 0 to (PIXELCOUNT - 1);
|
||||
pixel_objwnd : out std_logic := '0';
|
||||
|
||||
OAMRAM_Drawer_addr : buffer integer range 0 to 255;
|
||||
@@ -43,6 +49,8 @@ end entity;
|
||||
|
||||
architecture arch of gba_drawer_obj is
|
||||
|
||||
constant RESMULTACCDIV : integer := 256 * RESMULT;
|
||||
|
||||
-- Atr0
|
||||
constant OAM_Y_HI : integer := 7;
|
||||
constant OAM_Y_LO : integer := 0;
|
||||
@@ -158,13 +166,16 @@ architecture arch of gba_drawer_obj is
|
||||
signal x : integer range 0 to 255;
|
||||
signal realX : integer range -8388608 to 8388607;
|
||||
signal realY : integer range -8388608 to 8388607;
|
||||
signal target : integer range 0 to 239;
|
||||
signal target : integer range 0 to (PIXELCOUNT - 1);
|
||||
signal second_pix : std_logic;
|
||||
signal skippixel : std_logic;
|
||||
signal issue_pixel : std_logic;
|
||||
signal pixeladdr_x : unsigned(14 downto 0) := (others => '0');
|
||||
signal pixeladdr_x_noaff : unsigned(14 downto 0);
|
||||
|
||||
signal rescounter : integer range 0 to RESMULT - 1;
|
||||
signal rescounter_current: integer range 0 to RESMULT - 1;
|
||||
|
||||
signal pixeladdr_x_aff0 : unsigned(14 downto 0);
|
||||
signal pixeladdr_x_aff1 : unsigned(14 downto 0);
|
||||
signal pixeladdr_x_aff2 : unsigned(14 downto 0);
|
||||
@@ -182,17 +193,17 @@ architecture arch of gba_drawer_obj is
|
||||
objwnd : std_logic;
|
||||
end record;
|
||||
|
||||
type t_pixelarray is array(0 to 239) of tpixel;
|
||||
type t_pixelarray is array(0 to (PIXELCOUNT - 1)) of tpixel;
|
||||
signal pixelarray : t_pixelarray;
|
||||
|
||||
signal Pixel_wait : tpixel;
|
||||
signal Pixel_readback : tpixel;
|
||||
signal Pixel_merge : tpixel;
|
||||
|
||||
signal target_start : integer range 0 to 239;
|
||||
signal target_eval : integer range 0 to 239;
|
||||
signal target_wait : integer range 0 to 239;
|
||||
signal target_merge : integer range 0 to 239;
|
||||
signal target_start : integer range 0 to (PIXELCOUNT - 1);
|
||||
signal target_eval : integer range 0 to (PIXELCOUNT - 1);
|
||||
signal target_wait : integer range 0 to (PIXELCOUNT - 1);
|
||||
signal target_merge : integer range 0 to (PIXELCOUNT - 1);
|
||||
|
||||
signal enable_start : std_logic;
|
||||
signal enable_eval : std_logic;
|
||||
@@ -367,6 +378,7 @@ begin
|
||||
case (PIXELGen) is
|
||||
|
||||
when WAITOAM =>
|
||||
rescounter <= 0;
|
||||
if (OAMFetch = DONE) then
|
||||
PIXELGen <= CALCMOSAIC;
|
||||
Pixel_data0 <= OAM_data0;
|
||||
@@ -505,8 +517,12 @@ begin
|
||||
end if;
|
||||
|
||||
-- affine
|
||||
realX <= pixeladdr_pre_a0 - pixeladdr_pre_a1 - pixeladdr_pre_a2 + pixeladdr_pre_a3;
|
||||
realY <= pixeladdr_pre_a4 - pixeladdr_pre_a5 - pixeladdr_pre_a6 + pixeladdr_pre_a7;
|
||||
realX <= (pixeladdr_pre_a0 - pixeladdr_pre_a1 - pixeladdr_pre_a2 + pixeladdr_pre_a3) * resmult;
|
||||
realY <= (pixeladdr_pre_a4 - pixeladdr_pre_a5 - pixeladdr_pre_a6 + pixeladdr_pre_a7) * resmult;
|
||||
if (YMULTOFFSET = 1) then
|
||||
realX <= ((pixeladdr_pre_a0 - pixeladdr_pre_a1 - pixeladdr_pre_a2 + pixeladdr_pre_a3) * resmult) + dmx;
|
||||
realY <= ((pixeladdr_pre_a4 - pixeladdr_pre_a5 - pixeladdr_pre_a6 + pixeladdr_pre_a7) * resmult) + dmy;
|
||||
end if;
|
||||
|
||||
-- non affine
|
||||
if (Pixel_data1(OAM_VFLIP) = '1') then
|
||||
@@ -529,7 +545,13 @@ begin
|
||||
elsif (x >= fieldX) then
|
||||
PIXELGen <= WAITOAM;
|
||||
else
|
||||
x <= x + 1;
|
||||
rescounter_current <= rescounter;
|
||||
if (rescounter = RESMULT - 1) then
|
||||
x <= x + 1;
|
||||
rescounter <= 0;
|
||||
else
|
||||
rescounter <= rescounter + 1;
|
||||
end if;
|
||||
if (x + posX > 239) then -- end of line already reached
|
||||
PIXELGen <= WAITOAM;
|
||||
else
|
||||
@@ -552,16 +574,16 @@ begin
|
||||
end if;
|
||||
|
||||
if (Pixel_data0(OAM_AFFINE) = '1') then
|
||||
if (realX < 0 or (realX / 256) >= sizeX or realY < 0 or (realY / 256) >= sizeY) then
|
||||
if (realX < 0 or (realX / RESMULTACCDIV) >= sizeX or realY < 0 or (realY / RESMULTACCDIV) >= sizeY) then
|
||||
skippixel <= '1';
|
||||
end if;
|
||||
|
||||
-- synthesis translate_off
|
||||
if (realX >= 0 and (realX / 256) < sizeX and realY >= 0 and (realY / 256) < sizeY) then
|
||||
if (realX >= 0 and (realX / RESMULTACCDIV) < sizeX and realY >= 0 and (realY / RESMULTACCDIV) < sizeY) then
|
||||
-- synthesis translate_on
|
||||
|
||||
xxx := realX / 256;
|
||||
yyy := realY / 256;
|
||||
xxx := realX / RESMULTACCDIV;
|
||||
yyy := realY / RESMULTACCDIV;
|
||||
if (xxx mod 2 = 1) then second_pix <= '1'; else second_pix <= '0'; end if;
|
||||
|
||||
pixeladdr_x_aff0 <= to_unsigned(((yyy mod 8) * x_size), 15);
|
||||
@@ -650,7 +672,7 @@ begin
|
||||
|
||||
-- zero cycle - address for vram is written in this cycle
|
||||
enable_start <= issue_pixel;
|
||||
target_start <= target;
|
||||
target_start <= (target * RESMULT) + rescounter_current;
|
||||
readaddr_mux <= pixeladdr_x(1 downto 0);
|
||||
second_pix_start <= second_pix;
|
||||
|
||||
|
||||
@@ -23,17 +23,24 @@ entity gba_gpu is
|
||||
gb_bus : inout proc_bus_gb_type := ((others => 'Z'), (others => 'Z'), (others => 'Z'), 'Z', 'Z', 'Z', "ZZ", "ZZZZ", 'Z');
|
||||
|
||||
lockspeed : in std_logic;
|
||||
interframe_blend : in std_logic;
|
||||
interframe_blend : in std_logic_vector(1 downto 0);
|
||||
maxpixels : in std_logic;
|
||||
shade_mode : in std_logic_vector(2 downto 0);
|
||||
hdmode2x_bg : in std_logic;
|
||||
hdmode2x_obj : in std_logic;
|
||||
|
||||
bitmapdrawmode : out std_logic;
|
||||
|
||||
pixel_out_x : out integer range 0 to 239;
|
||||
pixel_out_2x : out integer range 0 to 479;
|
||||
pixel_out_y : out integer range 0 to 159;
|
||||
pixel_out_addr : out integer range 0 to 38399;
|
||||
pixel_out_data : out std_logic_vector(17 downto 0);
|
||||
pixel_out_we : out std_logic := '0';
|
||||
|
||||
pixel2_out_x : out integer range 0 to 479;
|
||||
pixel2_out_data : out std_logic_vector(17 downto 0);
|
||||
pixel2_out_we : out std_logic := '0';
|
||||
|
||||
new_cycles : in unsigned(7 downto 0);
|
||||
new_cycles_valid : in std_logic;
|
||||
@@ -86,11 +93,15 @@ architecture arch of gba_gpu is
|
||||
signal pixelpos : integer range 0 to 511;
|
||||
|
||||
signal pixel_x : integer range 0 to 239;
|
||||
signal pixel_2x : integer range 0 to 479;
|
||||
signal pixel_y : integer range 0 to 159;
|
||||
signal pixel_addr : integer range 0 to 38399;
|
||||
signal pixel_data : std_logic_vector(14 downto 0);
|
||||
signal pixel_we : std_logic := '0';
|
||||
|
||||
|
||||
signal pixel2_2x : integer range 0 to 479;
|
||||
signal pixel2_data : std_logic_vector(14 downto 0);
|
||||
signal pixel2_we : std_logic := '0';
|
||||
|
||||
signal vram_block_mode : std_logic;
|
||||
begin
|
||||
@@ -147,15 +158,22 @@ begin
|
||||
lockspeed => lockspeed,
|
||||
interframe_blend => interframe_blend,
|
||||
maxpixels => maxpixels,
|
||||
hdmode2x_bg => hdmode2x_bg ,
|
||||
hdmode2x_obj => hdmode2x_obj,
|
||||
|
||||
bitmapdrawmode => bitmapdrawmode,
|
||||
vram_block_mode => vram_block_mode,
|
||||
|
||||
pixel_out_x => pixel_x,
|
||||
pixel_out_x => pixel_x,
|
||||
pixel_out_2x => pixel_2x,
|
||||
pixel_out_y => pixel_y,
|
||||
pixel_out_addr => pixel_addr,
|
||||
pixel_out_data => pixel_data,
|
||||
pixel_out_we => pixel_we,
|
||||
|
||||
pixel2_out_x => pixel2_2x,
|
||||
pixel2_out_data => pixel2_data,
|
||||
pixel2_out_we => pixel2_we,
|
||||
|
||||
linecounter => linecounter_drawer,
|
||||
drawline => drawline,
|
||||
@@ -190,8 +208,8 @@ begin
|
||||
PALETTE_OAM_datain => PALETTE_OAM_datain,
|
||||
PALETTE_OAM_dataout => PALETTE_OAM_dataout,
|
||||
PALETTE_OAM_we => PALETTE_OAM_we
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
igba_gpu_colorshade : entity work.gba_gpu_colorshade
|
||||
port map
|
||||
(
|
||||
@@ -200,16 +218,40 @@ begin
|
||||
shade_mode => shade_mode,
|
||||
|
||||
pixel_in_x => pixel_x,
|
||||
pixel_in_2x => pixel_2x,
|
||||
pixel_in_y => pixel_y,
|
||||
pixel_in_addr => pixel_addr,
|
||||
pixel_in_data => pixel_data,
|
||||
pixel_in_we => pixel_we,
|
||||
|
||||
pixel_out_x => pixel_out_x,
|
||||
pixel_out_2x => pixel_out_2x,
|
||||
pixel_out_y => pixel_out_y,
|
||||
pixel_out_addr => pixel_out_addr,
|
||||
pixel_out_data => pixel_out_data,
|
||||
pixel_out_we => pixel_out_we
|
||||
);
|
||||
|
||||
igba_gpu_colorshade2 : entity work.gba_gpu_colorshade
|
||||
port map
|
||||
(
|
||||
clk100 => clk100,
|
||||
|
||||
shade_mode => shade_mode,
|
||||
|
||||
pixel_in_x => 0,
|
||||
pixel_in_2x => pixel2_2x,
|
||||
pixel_in_y => 0,
|
||||
pixel_in_addr => 0,
|
||||
pixel_in_data => pixel2_data,
|
||||
pixel_in_we => pixel2_we,
|
||||
|
||||
pixel_out_x => open,
|
||||
pixel_out_2x => pixel2_out_x,
|
||||
pixel_out_y => open,
|
||||
pixel_out_addr => open,
|
||||
pixel_out_data => pixel2_out_data,
|
||||
pixel_out_we => pixel2_out_we
|
||||
);
|
||||
|
||||
end architecture;
|
||||
|
||||
@@ -10,12 +10,14 @@ entity gba_gpu_colorshade is
|
||||
shade_mode : in std_logic_vector(2 downto 0); -- 0 = off, 1..4 modes
|
||||
|
||||
pixel_in_x : in integer range 0 to 239;
|
||||
pixel_in_2x : in integer range 0 to 479;
|
||||
pixel_in_y : in integer range 0 to 159;
|
||||
pixel_in_addr : in integer range 0 to 38399;
|
||||
pixel_in_data : in std_logic_vector(14 downto 0);
|
||||
pixel_in_we : in std_logic := '0';
|
||||
|
||||
pixel_out_x : out integer range 0 to 239;
|
||||
pixel_out_2x : out integer range 0 to 479;
|
||||
pixel_out_y : out integer range 0 to 159;
|
||||
pixel_out_addr : out integer range 0 to 38399;
|
||||
pixel_out_data : out std_logic_vector(17 downto 0);
|
||||
@@ -156,6 +158,7 @@ architecture arch of gba_gpu_colorshade is
|
||||
|
||||
-- shade processing
|
||||
signal pixel_1_x : integer range 0 to 239;
|
||||
signal pixel_1_2x : integer range 0 to 479;
|
||||
signal pixel_1_y : integer range 0 to 159;
|
||||
signal pixel_1_addr : integer range 0 to 38399;
|
||||
signal pixel_1_data : std_logic_vector(14 downto 0);
|
||||
@@ -165,6 +168,7 @@ architecture arch of gba_gpu_colorshade is
|
||||
signal color_linear_3 : integer range 0 to 1023;
|
||||
|
||||
signal pixel_2_x : integer range 0 to 239;
|
||||
signal pixel_2_2x : integer range 0 to 479;
|
||||
signal pixel_2_y : integer range 0 to 159;
|
||||
signal pixel_2_addr : integer range 0 to 38399;
|
||||
signal pixel_2_we : std_logic := '0';
|
||||
@@ -172,6 +176,7 @@ architecture arch of gba_gpu_colorshade is
|
||||
signal shade_precalc : t_shade_precalc := (others => (others => 0));
|
||||
|
||||
signal pixel_3_x : integer range 0 to 239;
|
||||
signal pixel_3_2x : integer range 0 to 479;
|
||||
signal pixel_3_y : integer range 0 to 159;
|
||||
signal pixel_3_addr : integer range 0 to 38399;
|
||||
signal pixel_3_we : std_logic := '0';
|
||||
@@ -179,6 +184,7 @@ architecture arch of gba_gpu_colorshade is
|
||||
signal shade_linear : t_shade_linear;
|
||||
|
||||
signal pixel_4_x : integer range 0 to 239;
|
||||
signal pixel_4_2x : integer range 0 to 479;
|
||||
signal pixel_4_y : integer range 0 to 159;
|
||||
signal pixel_4_addr : integer range 0 to 38399;
|
||||
signal pixel_4_we : std_logic := '0';
|
||||
@@ -186,6 +192,7 @@ architecture arch of gba_gpu_colorshade is
|
||||
signal clip_linear : t_clip_linear;
|
||||
|
||||
signal pixel_5_x : integer range 0 to 239;
|
||||
signal pixel_5_2x : integer range 0 to 479;
|
||||
signal pixel_5_y : integer range 0 to 159;
|
||||
signal pixel_5_addr : integer range 0 to 38399;
|
||||
signal pixel_5_we : std_logic := '0';
|
||||
@@ -262,6 +269,7 @@ begin
|
||||
|
||||
-- clock 1 - lookup linear color
|
||||
pixel_1_x <= pixel_in_x;
|
||||
pixel_1_2x <= pixel_in_2x;
|
||||
pixel_1_y <= pixel_in_y;
|
||||
pixel_1_addr <= pixel_in_addr;
|
||||
pixel_1_we <= pixel_in_we;
|
||||
@@ -273,6 +281,7 @@ begin
|
||||
|
||||
-- clock 2 - precalc shades
|
||||
pixel_2_x <= pixel_1_x;
|
||||
pixel_2_2x <= pixel_1_2x;
|
||||
pixel_2_y <= pixel_1_y;
|
||||
pixel_2_addr <= pixel_1_addr;
|
||||
pixel_2_we <= pixel_1_we;
|
||||
@@ -303,6 +312,7 @@ begin
|
||||
|
||||
-- clock 3 - apply shading
|
||||
pixel_3_x <= pixel_2_x;
|
||||
pixel_3_2x <= pixel_2_2x;
|
||||
pixel_3_y <= pixel_2_y;
|
||||
pixel_3_addr <= pixel_2_addr;
|
||||
pixel_3_we <= pixel_2_we;
|
||||
@@ -313,6 +323,7 @@ begin
|
||||
|
||||
-- clock 4 - clip
|
||||
pixel_4_x <= pixel_3_x;
|
||||
pixel_4_2x <= pixel_3_2x;
|
||||
pixel_4_y <= pixel_3_y;
|
||||
pixel_4_addr <= pixel_3_addr;
|
||||
pixel_4_we <= pixel_3_we;
|
||||
@@ -329,6 +340,7 @@ begin
|
||||
|
||||
-- clock 5 - lookup upper 3 bits of color
|
||||
pixel_5_x <= pixel_4_x;
|
||||
pixel_5_2x <= pixel_4_2x;
|
||||
pixel_5_y <= pixel_4_y;
|
||||
pixel_5_addr <= pixel_4_addr;
|
||||
pixel_5_we <= pixel_4_we;
|
||||
@@ -355,6 +367,7 @@ begin
|
||||
|
||||
-- clock 6 - lookup lower 3 bits of color
|
||||
pixel_out_x <= pixel_5_x;
|
||||
pixel_out_2x <= pixel_5_2x;
|
||||
pixel_out_y <= pixel_5_y;
|
||||
pixel_out_addr <= pixel_5_addr;
|
||||
pixel_out_we <= pixel_5_we;
|
||||
@@ -372,6 +385,7 @@ begin
|
||||
|
||||
else
|
||||
pixel_out_x <= pixel_in_x;
|
||||
pixel_out_2x <= pixel_in_2x;
|
||||
pixel_out_y <= pixel_in_y;
|
||||
pixel_out_addr <= pixel_in_addr;
|
||||
pixel_out_we <= pixel_in_we;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
238
rtl/gba_top.vhd
238
rtl/gba_top.vhd
@@ -2,6 +2,8 @@ library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
library MEM;
|
||||
|
||||
use work.pProc_bus_gba.all;
|
||||
use work.pReg_savestates.all;
|
||||
|
||||
@@ -33,9 +35,11 @@ entity gba_top is
|
||||
memory_remap : in std_logic;
|
||||
save_state : in std_logic;
|
||||
load_state : in std_logic;
|
||||
interframe_blend : in std_logic;
|
||||
interframe_blend : in std_logic_vector(1 downto 0); -- 0 = off, 1 = blend, 2 = 30hz
|
||||
maxpixels : in std_logic; -- limit pixels per line
|
||||
shade_mode : in std_logic_vector(2 downto 0); -- 0 = off, 1..4 modes
|
||||
hdmode2x_bg : in std_logic;
|
||||
hdmode2x_obj : in std_logic;
|
||||
specialmodule : in std_logic; -- 0 = off, 1 = use gamepak GPIO Port at address 0x080000C4..0x080000C8
|
||||
solar_in : in std_logic_vector(2 downto 0);
|
||||
tilt : in std_logic; -- 0 = off, 1 = use tilt at address 0x0E008200, 0x0E008300, 0x0E008400, 0x0E008500
|
||||
@@ -108,20 +112,28 @@ entity gba_top is
|
||||
GBA_BusReadData : out std_logic_vector(31 downto 0);
|
||||
GBA_Bus_written : in std_logic;
|
||||
-- display data
|
||||
pixel_out_x : out integer range 0 to 239;
|
||||
pixel_out_y : out integer range 0 to 159;
|
||||
pixel_out_addr : out integer range 0 to 38399; -- address for framebuffer
|
||||
pixel_out_data : out std_logic_vector(17 downto 0); -- RGB data for framebuffer
|
||||
pixel_out_we : out std_logic; -- new pixel for framebuffer
|
||||
-- sound
|
||||
sound_out_left : out std_logic_vector(15 downto 0) := (others => '0');
|
||||
sound_out_right : out std_logic_vector(15 downto 0) := (others => '0');
|
||||
-- debug
|
||||
debug_cpu_pc : out std_logic_vector(31 downto 0);
|
||||
debug_cpu_mixed : out std_logic_vector(31 downto 0);
|
||||
debug_irq : out std_logic_vector(31 downto 0);
|
||||
debug_dma : out std_logic_vector(31 downto 0);
|
||||
debug_mem : out std_logic_vector(31 downto 0)
|
||||
pixel_out_x : buffer integer range 0 to 239;
|
||||
pixel_out_y : buffer integer range 0 to 159;
|
||||
pixel_out_addr : buffer integer range 0 to 38399; -- address for framebuffer
|
||||
pixel_out_data : buffer std_logic_vector(17 downto 0); -- RGB data for framebuffer
|
||||
pixel_out_we : buffer std_logic; -- new pixel for framebuffer
|
||||
|
||||
largeimg_out_base : out std_logic_vector(31 downto 0) := x"38000000";
|
||||
largeimg_out_addr : buffer std_logic_vector(25 downto 0) := (others => '0');
|
||||
largeimg_out_data : out std_logic_vector(63 downto 0);
|
||||
largeimg_out_req : out std_logic := '0';
|
||||
largeimg_out_done : in std_logic;
|
||||
largeimg_newframe : in std_logic;
|
||||
largeimg_singlebuf : in std_logic;
|
||||
-- sound
|
||||
sound_out_left : out std_logic_vector(15 downto 0) := (others => '0');
|
||||
sound_out_right : out std_logic_vector(15 downto 0) := (others => '0');
|
||||
-- debug
|
||||
debug_cpu_pc : out std_logic_vector(31 downto 0);
|
||||
debug_cpu_mixed : out std_logic_vector(31 downto 0);
|
||||
debug_irq : out std_logic_vector(31 downto 0);
|
||||
debug_dma : out std_logic_vector(31 downto 0);
|
||||
debug_mem : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
@@ -322,6 +334,43 @@ architecture arch of gba_top is
|
||||
signal CyclesVsync : unsigned(31 downto 0) := (others => '0');
|
||||
signal bench_slow : integer range 0 to 1685375 := 0;
|
||||
|
||||
-- large image out
|
||||
signal pixel_out_2x : integer range 0 to 479;
|
||||
signal pixel_out_data2x : std_logic_vector(17 downto 0);
|
||||
signal pixel_out_we2x : std_logic := '0';
|
||||
signal pixel2_out_x : integer range 0 to 479;
|
||||
signal pixel2_out_data : std_logic_vector(17 downto 0);
|
||||
signal pixel2_out_we : std_logic;
|
||||
|
||||
signal pixel_write_addr : integer range 0 to 239;
|
||||
signal pixel_write_data : std_logic_vector(35 downto 0);
|
||||
signal pixel_write_ena : std_logic := '0';
|
||||
|
||||
signal pixel2_write_addr : integer range 0 to 239;
|
||||
signal pixel2_write_data : std_logic_vector(35 downto 0);
|
||||
signal pixel2_write_ena : std_logic := '0';
|
||||
|
||||
type tstate is
|
||||
(
|
||||
IDLE,
|
||||
READPIXEL,
|
||||
WRITEPIXEL
|
||||
);
|
||||
signal state : tstate := IDLE;
|
||||
|
||||
signal pixel_out_y_1 : integer range 0 to 159 := 0;
|
||||
signal pixelpos : integer range 0 to 240 := 0;
|
||||
signal pixelpos2 : integer range 0 to 240 := 0;
|
||||
signal pixelcnt : integer range 0 to 3 := 0;
|
||||
signal firstpixel : std_logic := '0';
|
||||
signal linebuffer_data : std_logic_vector(35 downto 0);
|
||||
signal linebuffer2_data : std_logic_vector(35 downto 0);
|
||||
signal pixeladdress : integer range 0 to 262143;
|
||||
|
||||
signal newframe_sreg : std_logic_vector(2 downto 0) := (others => '0');
|
||||
signal current_frame : integer range 0 to 2 := 0;
|
||||
signal frameoffset : integer range 0 to 2 := 0;
|
||||
|
||||
begin
|
||||
|
||||
-- dummy modules
|
||||
@@ -770,14 +819,21 @@ begin
|
||||
interframe_blend => interframe_blend,
|
||||
maxpixels => maxpixels,
|
||||
shade_mode => shade_mode,
|
||||
hdmode2x_bg => hdmode2x_bg,
|
||||
hdmode2x_obj => hdmode2x_obj,
|
||||
|
||||
bitmapdrawmode => bitmapdrawmode,
|
||||
|
||||
pixel_out_x => pixel_out_x,
|
||||
pixel_out_2x => pixel_out_2x,
|
||||
pixel_out_y => pixel_out_y,
|
||||
pixel_out_addr => pixel_out_addr,
|
||||
pixel_out_data => pixel_out_data,
|
||||
pixel_out_we => pixel_out_we,
|
||||
|
||||
pixel2_out_x => pixel2_out_x,
|
||||
pixel2_out_data => pixel2_out_data,
|
||||
pixel2_out_we => pixel2_out_we,
|
||||
|
||||
new_cycles => new_cycles,
|
||||
new_cycles_valid => new_cycles_valid,
|
||||
@@ -1030,6 +1086,158 @@ begin
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- large pixel out
|
||||
process (clk100)
|
||||
begin
|
||||
if rising_edge(clk100) then
|
||||
|
||||
pixel_write_ena <= '0';
|
||||
if (pixel_out_we = '1') then
|
||||
pixel_write_addr <= pixel_out_2x / 2;
|
||||
if (pixel_out_2x mod 2 = 0) then
|
||||
pixel_write_data(17 downto 0) <= pixel_out_data;
|
||||
else
|
||||
pixel_write_data(35 downto 18) <= pixel_out_data;
|
||||
pixel_write_ena <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
pixel2_write_ena <= '0';
|
||||
if (pixel2_out_we = '1') then
|
||||
pixel2_write_addr <= pixel2_out_x / 2;
|
||||
if (pixel2_out_x mod 2 = 0) then
|
||||
pixel2_write_data(17 downto 0) <= pixel2_out_data;
|
||||
else
|
||||
pixel2_write_data(35 downto 18) <= pixel2_out_data;
|
||||
pixel2_write_ena <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
ilinebuffer_hd0: entity MEM.SyncRamDual
|
||||
generic map
|
||||
(
|
||||
DATA_WIDTH => 36,
|
||||
ADDR_WIDTH => 8
|
||||
)
|
||||
port map
|
||||
(
|
||||
clk => clk100,
|
||||
|
||||
addr_a => pixel_write_addr,
|
||||
datain_a => pixel_write_data,
|
||||
dataout_a => open,
|
||||
we_a => pixel_write_ena,
|
||||
re_a => '0',
|
||||
|
||||
addr_b => pixelpos,
|
||||
datain_b => (35 downto 0 => '0'),
|
||||
dataout_b => linebuffer_data,
|
||||
we_b => '0',
|
||||
re_b => '1'
|
||||
);
|
||||
|
||||
ilinebuffer_hd1: entity MEM.SyncRamDual
|
||||
generic map
|
||||
(
|
||||
DATA_WIDTH => 36,
|
||||
ADDR_WIDTH => 8
|
||||
)
|
||||
port map
|
||||
(
|
||||
clk => clk100,
|
||||
|
||||
addr_a => pixel2_write_addr,
|
||||
datain_a => pixel2_write_data,
|
||||
dataout_a => open,
|
||||
we_a => pixel2_write_ena,
|
||||
re_a => '0',
|
||||
|
||||
addr_b => pixelpos2,
|
||||
datain_b => (35 downto 0 => '0'),
|
||||
dataout_b => linebuffer2_data,
|
||||
we_b => '0',
|
||||
re_b => '1'
|
||||
);
|
||||
|
||||
process (clk100)
|
||||
begin
|
||||
if rising_edge(clk100) then
|
||||
|
||||
largeimg_out_req <= '0';
|
||||
|
||||
newframe_sreg <= newframe_sreg(1 downto 0) & largeimg_newframe;
|
||||
if (newframe_sreg(2 downto 1) = "01") then
|
||||
largeimg_out_base <= (std_logic_vector(to_unsigned(16#38000000# + frameoffset * 16#400000#, 32)));
|
||||
end if;
|
||||
|
||||
case (state) is
|
||||
|
||||
when IDLE =>
|
||||
if (pixel_out_y_1 /= pixel_out_y and pixel_write_ena = '1' and (hdmode2x_bg = '1' or hdmode2x_obj = '1')) then
|
||||
pixel_out_y_1 <= pixel_out_y;
|
||||
state <= READPIXEL;
|
||||
pixelpos <= 0;
|
||||
pixelpos2 <= 0;
|
||||
pixeladdress <= pixel_out_y * 1024;
|
||||
if (pixel_out_y = 0) then
|
||||
frameoffset <= current_frame;
|
||||
--if (largeimg_singlebuf = '0') then
|
||||
if (current_frame < 2) then
|
||||
current_frame <= current_frame + 1;
|
||||
else
|
||||
current_frame <= 0;
|
||||
end if;
|
||||
--end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when READPIXEL =>
|
||||
state <= WRITEPIXEL;
|
||||
firstpixel <= '1';
|
||||
|
||||
when WRITEPIXEL =>
|
||||
firstpixel <= '0';
|
||||
if (largeimg_out_done = '1' or firstpixel = '1') then
|
||||
|
||||
if (pixelcnt = 0) then
|
||||
pixelcnt <= 1;
|
||||
pixelpos <= pixelpos + 1;
|
||||
else
|
||||
pixelcnt <= 0;
|
||||
pixelpos2 <= pixelpos2 + 1;
|
||||
if (pixelpos2 < 239) then
|
||||
pixeladdress <= pixeladdress + 2;
|
||||
else
|
||||
state <= IDLE;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
largeimg_out_req <= '1';
|
||||
case (pixelcnt) is
|
||||
when 0 =>
|
||||
largeimg_out_addr <= "1" & std_logic_vector(to_unsigned(pixeladdress + current_frame * 16#100000#, 25));
|
||||
largeimg_out_data(31 downto 0) <= x"00" & linebuffer_data( 5 downto 0) & "00" & linebuffer_data(11 downto 6) & "00" & linebuffer_data(17 downto 12) & "00";
|
||||
largeimg_out_data(63 downto 32) <= x"00" & linebuffer_data(23 downto 18) & "00" & linebuffer_data(29 downto 24) & "00" & linebuffer_data(35 downto 30) & "00";
|
||||
when 1 =>
|
||||
largeimg_out_addr <= "1" & std_logic_vector(to_unsigned(pixeladdress + 512 + current_frame * 16#100000#, 25));
|
||||
largeimg_out_data(31 downto 0) <= x"00" & linebuffer2_data( 5 downto 0) & "00" & linebuffer2_data(11 downto 6) & "00" & linebuffer2_data(17 downto 12) & "00";
|
||||
largeimg_out_data(63 downto 32) <= x"00" & linebuffer2_data(23 downto 18) & "00" & linebuffer2_data(29 downto 24) & "00" & linebuffer2_data(35 downto 30) & "00";
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
end if;
|
||||
|
||||
end case;
|
||||
|
||||
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end architecture;
|
||||
|
||||
|
||||
@@ -96,7 +96,6 @@ begin
|
||||
cmd_burst_save := DDRAM_BURSTCNT;
|
||||
cmd_din_save := DDRAM_DIN;
|
||||
cmd_be_save := DDRAM_BE;
|
||||
wait until rising_edge(DDRAM_CLK);
|
||||
for i in 0 to (to_integer(unsigned(cmd_burst_save)) - 1) loop
|
||||
if (cmd_be_save(7 downto 4) = x"F") then
|
||||
data(to_integer(unsigned(cmd_address_save)) * 2 + (i * 2) + 1) := to_integer(signed(cmd_din_save(63 downto 32)));
|
||||
|
||||
@@ -117,6 +117,12 @@ architecture arch of etb is
|
||||
signal pixel_out_y : integer range 0 to 159;
|
||||
signal pixel_out_data : std_logic_vector(17 downto 0);
|
||||
signal pixel_out_we : std_logic;
|
||||
|
||||
signal largeimg_out_addr : std_logic_vector(25 downto 0);
|
||||
signal largeimg_out_data : std_logic_vector(63 downto 0);
|
||||
signal largeimg_out_req : std_logic;
|
||||
signal largeimg_out_done : std_logic;
|
||||
signal largeimg_newframe : std_logic;
|
||||
|
||||
signal sound_out_left : std_logic_vector(15 downto 0);
|
||||
signal sound_out_right : std_logic_vector(15 downto 0);
|
||||
@@ -250,9 +256,11 @@ begin
|
||||
memory_remap => GBA_MemoryRemap(GBA_MemoryRemap'left),
|
||||
save_state => GBA_SaveState(GBA_SaveState'left),
|
||||
load_state => GBA_LoadState(GBA_LoadState'left),
|
||||
interframe_blend => '0', --GBA_FrameBlend(GBA_FrameBlend'left),
|
||||
interframe_blend => "00",
|
||||
maxpixels => '0',
|
||||
shade_mode => GBA_Pixelshade,
|
||||
shade_mode => "000",
|
||||
hdmode2x_bg => '1',
|
||||
hdmode2x_obj => '1',
|
||||
specialmodule => '0',
|
||||
solar_in => "000",
|
||||
tilt => '0',
|
||||
@@ -333,7 +341,14 @@ begin
|
||||
pixel_out_y => pixel_out_y,
|
||||
pixel_out_addr => open,
|
||||
pixel_out_data => pixel_out_data,
|
||||
pixel_out_we => pixel_out_we,
|
||||
pixel_out_we => pixel_out_we,
|
||||
|
||||
largeimg_out_addr => largeimg_out_addr,
|
||||
largeimg_out_data => largeimg_out_data,
|
||||
largeimg_out_req => largeimg_out_req,
|
||||
largeimg_out_done => largeimg_out_done,
|
||||
largeimg_newframe => largeimg_newframe,
|
||||
largeimg_singlebuf => '0',
|
||||
-- sound
|
||||
sound_out_left => sound_out_left,
|
||||
sound_out_right => sound_out_right,
|
||||
@@ -345,6 +360,7 @@ begin
|
||||
debug_mem => open --GBA_DEBUG_MEM
|
||||
);
|
||||
|
||||
largeimg_newframe <= '1' when unsigned(largeimg_out_addr(19 downto 0)) = 0 else '0';
|
||||
|
||||
ch1_addr <= '0' & sdram_read_addr & "0";
|
||||
ch1_req <= sdram_read_ena;
|
||||
@@ -406,7 +422,12 @@ begin
|
||||
ch4_din => ch4_din,
|
||||
ch4_req => ch4_req,
|
||||
ch4_rnw => ch4_rnw,
|
||||
ch4_ready => ch4_ready
|
||||
ch4_ready => ch4_ready,
|
||||
|
||||
ch5_addr => (27 downto 1 => '0'),
|
||||
ch5_din => (63 downto 0 => '0'),
|
||||
ch5_req => largeimg_out_req,
|
||||
ch5_ready => largeimg_out_done
|
||||
);
|
||||
|
||||
iddrram_model : entity tb.ddrram_model
|
||||
@@ -440,6 +461,21 @@ begin
|
||||
pixel_in_we => pixel_out_we
|
||||
);
|
||||
|
||||
iframebuffer_large : entity work.framebuffer_large
|
||||
generic map
|
||||
(
|
||||
FRAMESIZE_X => 480,
|
||||
FRAMESIZE_Y => 320
|
||||
)
|
||||
port map
|
||||
(
|
||||
clk100 => clk100,
|
||||
|
||||
pixel_in_addr => largeimg_out_addr,
|
||||
pixel_in_data => largeimg_out_data,
|
||||
pixel_in_we => largeimg_out_req,
|
||||
pixel_in_done => open
|
||||
);
|
||||
|
||||
iTestprocessor : entity procbus.eTestprocessor
|
||||
generic map
|
||||
|
||||
@@ -3,9 +3,9 @@ vcom -93 -quiet -work sim/tb ^
|
||||
src/tb/globals.vhd
|
||||
|
||||
vcom -93 -quiet -work sim/mem ^
|
||||
../src/SyncRam.vhd ^
|
||||
../src/SyncRamDual.vhd ^
|
||||
../src/SyncRamDualNotPow2.vhd ^
|
||||
../rtl/SyncRam.vhd ^
|
||||
../rtl/SyncRamDual.vhd ^
|
||||
../rtl/SyncRamDualNotPow2.vhd ^
|
||||
src/mem/SyncRamDualByteEnable.vhd ^
|
||||
src/mem/SyncFifo.vhd
|
||||
|
||||
@@ -23,55 +23,57 @@ vcom -quiet -work sim/reg_map ^
|
||||
src/reg_map/reg_gameboy.vhd
|
||||
|
||||
vcom -quiet -work sim/gba ^
|
||||
../src/proc_bus_gba.vhd ^
|
||||
../src/cache.vhd ^
|
||||
../src/reggba_timer.vhd ^
|
||||
../src/reggba_keypad.vhd ^
|
||||
../src/reggba_serial.vhd ^
|
||||
../src/reggba_sound.vhd ^
|
||||
../src/reggba_display.vhd ^
|
||||
../src/reggba_dma.vhd ^
|
||||
../src/reggba_system.vhd ^
|
||||
../src/reg_savestates.vhd ^
|
||||
../src/gba_bios_fast.vhd ^
|
||||
../src/gba_reservedregs.vhd ^
|
||||
../src/gba_sound_ch1.vhd ^
|
||||
../src/gba_sound_ch3.vhd ^
|
||||
../src/gba_sound_ch4.vhd ^
|
||||
../src/gba_sound_dma.vhd ^
|
||||
../src/gba_sound.vhd ^
|
||||
../src/gba_joypad.vhd ^
|
||||
../src/gba_serial.vhd ^
|
||||
../src/gba_dma_module.vhd ^
|
||||
../src/gba_dma.vhd ^
|
||||
../src/gba_memorymux.vhd ^
|
||||
../src/gba_timer_module.vhd ^
|
||||
../src/gba_timer.vhd ^
|
||||
../src/gba_gpu_timing.vhd ^
|
||||
../src/gba_drawer_mode0.vhd ^
|
||||
../src/gba_drawer_mode2.vhd ^
|
||||
../src/gba_drawer_mode345.vhd ^
|
||||
../src/gba_drawer_obj.vhd ^
|
||||
../src/gba_drawer_merge.vhd ^
|
||||
../src/gba_gpu_drawer.vhd ^
|
||||
../src/gba_gpu_colorshade.vhd ^
|
||||
../src/gba_gpu.vhd ^
|
||||
../src/gba_savestates.vhd ^
|
||||
../src/gba_statemanager.vhd ^
|
||||
../src/gba_cheats.vhd ^
|
||||
../src/gba_gpioRTCSolarGyro.vhd
|
||||
../rtl/proc_bus_gba.vhd ^
|
||||
../rtl/cache.vhd ^
|
||||
../rtl/reggba_timer.vhd ^
|
||||
../rtl/reggba_keypad.vhd ^
|
||||
../rtl/reggba_serial.vhd ^
|
||||
../rtl/reggba_sound.vhd ^
|
||||
../rtl/reggba_display.vhd ^
|
||||
../rtl/reggba_dma.vhd ^
|
||||
../rtl/reggba_system.vhd ^
|
||||
../rtl/reg_savestates.vhd ^
|
||||
../rtl/gba_bios_fast.vhd ^
|
||||
../rtl/gba_reservedregs.vhd ^
|
||||
../rtl/gba_sound_ch1.vhd ^
|
||||
../rtl/gba_sound_ch3.vhd ^
|
||||
../rtl/gba_sound_ch4.vhd ^
|
||||
../rtl/gba_sound_dma.vhd ^
|
||||
../rtl/gba_sound.vhd ^
|
||||
../rtl/gba_joypad.vhd ^
|
||||
../rtl/gba_serial.vhd ^
|
||||
../rtl/gba_dma_module.vhd ^
|
||||
../rtl/gba_dma.vhd ^
|
||||
../rtl/gba_memorymux.vhd ^
|
||||
../rtl/gba_timer_module.vhd ^
|
||||
../rtl/gba_timer.vhd ^
|
||||
../rtl/gba_gpu_timing.vhd ^
|
||||
../rtl/gba_drawer_mode0.vhd ^
|
||||
../rtl/gba_drawer_mode2.vhd ^
|
||||
../rtl/gba_drawer_mode2_2x.vhd ^
|
||||
../rtl/gba_drawer_mode345.vhd ^
|
||||
../rtl/gba_drawer_obj.vhd ^
|
||||
../rtl/gba_drawer_merge.vhd ^
|
||||
../rtl/gba_gpu_drawer.vhd ^
|
||||
../rtl/gba_gpu_colorshade.vhd ^
|
||||
../rtl/gba_gpu.vhd ^
|
||||
../rtl/gba_savestates.vhd ^
|
||||
../rtl/gba_statemanager.vhd ^
|
||||
../rtl/gba_cheats.vhd ^
|
||||
../rtl/gba_gpioRTCSolarGyro.vhd
|
||||
|
||||
vcom -2008 -quiet -work sim/gba ^
|
||||
../src/gba_cpu.vhd ^
|
||||
../src/gba_top.vhd
|
||||
../rtl/gba_cpu.vhd ^
|
||||
../rtl/gba_top.vhd
|
||||
|
||||
vlog -sv -quiet -work sim/top ^
|
||||
../ddram.sv
|
||||
../rtl/ddram.sv
|
||||
|
||||
vcom -quiet -work sim/tb ^
|
||||
src/tb/stringprocessor.vhd ^
|
||||
src/tb/tb_interpreter.vhd ^
|
||||
src/tb/ddrram_model.vhd ^
|
||||
src/tb/framebuffer.vhd ^
|
||||
src/tb/framebuffer_large.vhd ^
|
||||
src/tb/tb.vhd
|
||||
|
||||
|
||||
12
sys/alsa.sv
12
sys/alsa.sv
@@ -20,6 +20,9 @@
|
||||
//============================================================================
|
||||
|
||||
module alsa
|
||||
#(
|
||||
parameter CLK_RATE = 24576000
|
||||
)
|
||||
(
|
||||
input reset,
|
||||
input clk,
|
||||
@@ -139,17 +142,14 @@ always @(posedge clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
localparam F48K = 48000;
|
||||
localparam F50M = 50000000;
|
||||
|
||||
reg ce_sample;
|
||||
always @(posedge clk) begin
|
||||
reg [31:0] acc = 0;
|
||||
|
||||
ce_sample <= 0;
|
||||
acc <= acc + F48K + {hurryup,6'd0};
|
||||
if(acc >= F50M) begin
|
||||
acc <= acc - F50M;
|
||||
acc <= acc + 48000 + {hurryup,6'd0};
|
||||
if(acc >= CLK_RATE) begin
|
||||
acc <= acc - CLK_RATE;
|
||||
ce_sample <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,258 +2,6 @@
|
||||
//
|
||||
// Copyright (C) 2017-2020 Sorgelig
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
// DW:
|
||||
// 6 : 2R 2G 2B
|
||||
// 8 : 3R 3G 2B
|
||||
// 9 : 3R 3G 3B
|
||||
// 12 : 4R 4G 4B
|
||||
// 24 : 8R 8G 8B
|
||||
|
||||
module arcade_video #(parameter WIDTH=320, HEIGHT=240, DW=8, GAMMA=1)
|
||||
(
|
||||
input clk_video,
|
||||
input ce_pix,
|
||||
|
||||
input[DW-1:0] RGB_in,
|
||||
input HBlank,
|
||||
input VBlank,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
output VGA_CLK,
|
||||
output VGA_CE,
|
||||
output [7:0] VGA_R,
|
||||
output [7:0] VGA_G,
|
||||
output [7:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS,
|
||||
output VGA_DE,
|
||||
|
||||
output HDMI_CLK,
|
||||
output HDMI_CE,
|
||||
output [7:0] HDMI_R,
|
||||
output [7:0] HDMI_G,
|
||||
output [7:0] HDMI_B,
|
||||
output HDMI_HS,
|
||||
output HDMI_VS,
|
||||
output HDMI_DE,
|
||||
output [1:0] HDMI_SL,
|
||||
|
||||
input [2:0] fx,
|
||||
input forced_scandoubler,
|
||||
input no_rotate,
|
||||
input rotate_ccw,
|
||||
inout [21:0] gamma_bus
|
||||
);
|
||||
|
||||
wire [7:0] R,G,B;
|
||||
wire CE,HS,VS,HBL,VBL;
|
||||
|
||||
wire [DW-1:0] RGB_fix;
|
||||
wire VGA_HBL, VGA_VBL;
|
||||
arcade_vga #(DW) vga
|
||||
(
|
||||
.clk_video(clk_video),
|
||||
.ce_pix(ce_pix),
|
||||
|
||||
.RGB_in(RGB_in),
|
||||
.HBlank(HBlank),
|
||||
.VBlank(VBlank),
|
||||
.HSync(HSync),
|
||||
.VSync(VSync),
|
||||
|
||||
.RGB_out(RGB_fix),
|
||||
.VGA_CLK(VGA_CLK),
|
||||
.VGA_CE(CE),
|
||||
.VGA_R(R),
|
||||
.VGA_G(G),
|
||||
.VGA_B(B),
|
||||
.VGA_HS(HS),
|
||||
.VGA_VS(VS),
|
||||
.VGA_HBL(HBL),
|
||||
.VGA_VBL(VBL)
|
||||
);
|
||||
|
||||
wire [DW-1:0] RGB_out;
|
||||
wire rhs,rvs,rhblank,rvblank;
|
||||
|
||||
screen_rotate #(WIDTH,HEIGHT,DW,4) rotator
|
||||
(
|
||||
.clk(VGA_CLK),
|
||||
.ce(CE),
|
||||
|
||||
.ccw(rotate_ccw),
|
||||
|
||||
.video_in(RGB_fix),
|
||||
.hblank(HBL),
|
||||
.vblank(VBL),
|
||||
|
||||
.ce_out(CE | (~scandoubler & ~gamma_bus[19])),
|
||||
.video_out(RGB_out),
|
||||
.hsync(rhs),
|
||||
.vsync(rvs),
|
||||
.hblank_out(rhblank),
|
||||
.vblank_out(rvblank)
|
||||
);
|
||||
|
||||
generate
|
||||
if(DW == 6) begin
|
||||
wire [3:0] Rr = {RGB_out[5:4],RGB_out[5:4]};
|
||||
wire [3:0] Gr = {RGB_out[3:2],RGB_out[3:2]};
|
||||
wire [3:0] Br = {RGB_out[1:0],RGB_out[1:0]};
|
||||
end
|
||||
else if(DW == 8) begin
|
||||
wire [3:0] Rr = {RGB_out[7:5],RGB_out[7]};
|
||||
wire [3:0] Gr = {RGB_out[4:2],RGB_out[4]};
|
||||
wire [3:0] Br = {RGB_out[1:0],RGB_out[1:0]};
|
||||
end
|
||||
else if(DW == 9) begin
|
||||
wire [3:0] Rr = {RGB_out[8:6],RGB_out[8]};
|
||||
wire [3:0] Gr = {RGB_out[5:3],RGB_out[5]};
|
||||
wire [3:0] Br = {RGB_out[2:0],RGB_out[2]};
|
||||
end
|
||||
else if(DW == 12) begin
|
||||
wire [3:0] Rr = RGB_out[11:8];
|
||||
wire [3:0] Gr = RGB_out[7:4];
|
||||
wire [3:0] Br = RGB_out[3:0];
|
||||
end
|
||||
else begin // 24
|
||||
wire [7:0] Rr = RGB_out[23:16];
|
||||
wire [7:0] Gr = RGB_out[15:8];
|
||||
wire [7:0] Br = RGB_out[7:0];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign HDMI_CLK = VGA_CLK;
|
||||
assign HDMI_SL = sl[1:0];
|
||||
wire [2:0] sl = fx ? fx - 1'd1 : 3'd0;
|
||||
wire scandoubler = fx || forced_scandoubler;
|
||||
|
||||
video_mixer #(.LINE_LENGTH(WIDTH+4), .HALF_DEPTH(DW!=24), .GAMMA(GAMMA)) video_mixer
|
||||
(
|
||||
.clk_vid(HDMI_CLK),
|
||||
.ce_pix(CE | (~scandoubler & ~gamma_bus[19] & ~no_rotate)),
|
||||
.ce_pix_out(HDMI_CE),
|
||||
|
||||
.scandoubler(scandoubler),
|
||||
.hq2x(fx==1),
|
||||
.gamma_bus(gamma_bus),
|
||||
|
||||
.R(no_rotate ? ((DW!=24) ? R[7:4] : R) : Rr),
|
||||
.G(no_rotate ? ((DW!=24) ? G[7:4] : G) : Gr),
|
||||
.B(no_rotate ? ((DW!=24) ? B[7:4] : B) : Br),
|
||||
|
||||
.HSync (no_rotate ? HS : rhs),
|
||||
.VSync (no_rotate ? VS : rvs),
|
||||
.HBlank(no_rotate ? HBL : rhblank),
|
||||
.VBlank(no_rotate ? VBL : rvblank),
|
||||
|
||||
.VGA_R(HDMI_R),
|
||||
.VGA_G(HDMI_G),
|
||||
.VGA_B(HDMI_B),
|
||||
.VGA_VS(HDMI_VS),
|
||||
.VGA_HS(HDMI_HS),
|
||||
.VGA_DE(HDMI_DE)
|
||||
);
|
||||
|
||||
assign VGA_CE = no_rotate ? HDMI_CE : CE;
|
||||
assign VGA_R = no_rotate ? HDMI_R : R;
|
||||
assign VGA_G = no_rotate ? HDMI_G : G;
|
||||
assign VGA_B = no_rotate ? HDMI_B : B;
|
||||
assign VGA_HS = no_rotate ? HDMI_HS : HS;
|
||||
assign VGA_VS = no_rotate ? HDMI_VS : VS;
|
||||
assign VGA_DE = no_rotate ? HDMI_DE : ~(HBL | VBL);
|
||||
|
||||
endmodule
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
module arcade_vga #(parameter DW)
|
||||
(
|
||||
input clk_video,
|
||||
input ce_pix,
|
||||
|
||||
input [DW-1:0] RGB_in,
|
||||
input HBlank,
|
||||
input VBlank,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
output[DW-1:0] RGB_out,
|
||||
output VGA_CLK,
|
||||
output reg VGA_CE,
|
||||
output [7:0] VGA_R,
|
||||
output [7:0] VGA_G,
|
||||
output [7:0] VGA_B,
|
||||
output reg VGA_HS,
|
||||
output reg VGA_VS,
|
||||
output reg VGA_HBL,
|
||||
output reg VGA_VBL
|
||||
);
|
||||
|
||||
assign VGA_CLK = clk_video;
|
||||
|
||||
wire hs_fix,vs_fix;
|
||||
sync_fix sync_v(VGA_CLK, HSync, hs_fix);
|
||||
sync_fix sync_h(VGA_CLK, VSync, vs_fix);
|
||||
|
||||
reg [DW-1:0] RGB_fix;
|
||||
|
||||
always @(posedge VGA_CLK) begin
|
||||
reg old_ce;
|
||||
old_ce <= ce_pix;
|
||||
VGA_CE <= 0;
|
||||
if(~old_ce & ce_pix) begin
|
||||
VGA_CE <= 1;
|
||||
VGA_HS <= hs_fix;
|
||||
if(~VGA_HS & hs_fix) VGA_VS <= vs_fix;
|
||||
|
||||
RGB_fix <= RGB_in;
|
||||
VGA_HBL <= HBlank;
|
||||
if(VGA_HBL & ~HBlank) VGA_VBL <= VBlank;
|
||||
end
|
||||
end
|
||||
|
||||
assign RGB_out = RGB_fix;
|
||||
|
||||
generate
|
||||
if(DW == 6) begin
|
||||
assign VGA_R = {RGB_fix[5:4],RGB_fix[5:4],RGB_fix[5:4],RGB_fix[5:4]};
|
||||
assign VGA_G = {RGB_fix[3:2],RGB_fix[3:2],RGB_fix[3:2],RGB_fix[3:2]};
|
||||
assign VGA_B = {RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0]};
|
||||
end
|
||||
else if(DW == 8) begin
|
||||
assign VGA_R = {RGB_fix[7:5],RGB_fix[7:5],RGB_fix[7:6]};
|
||||
assign VGA_G = {RGB_fix[4:2],RGB_fix[4:2],RGB_fix[4:3]};
|
||||
assign VGA_B = {RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0]};
|
||||
end
|
||||
else if(DW == 9) begin
|
||||
assign VGA_R = {RGB_fix[8:6],RGB_fix[8:6],RGB_fix[8:7]};
|
||||
assign VGA_G = {RGB_fix[5:3],RGB_fix[5:3],RGB_fix[5:4]};
|
||||
assign VGA_B = {RGB_fix[2:0],RGB_fix[2:0],RGB_fix[2:1]};
|
||||
end
|
||||
else if(DW == 12) begin
|
||||
assign VGA_R = {RGB_fix[11:8],RGB_fix[11:8]};
|
||||
assign VGA_G = {RGB_fix[7:4],RGB_fix[7:4]};
|
||||
assign VGA_B = {RGB_fix[3:0],RGB_fix[3:0]};
|
||||
end
|
||||
else begin // 24
|
||||
assign VGA_R = RGB_fix[23:16];
|
||||
assign VGA_G = RGB_fix[15:8];
|
||||
assign VGA_B = RGB_fix[7:0];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Screen +90/-90 deg. rotation
|
||||
// Copyright (C) 2017-2019 Sorgelig
|
||||
//
|
||||
// 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)
|
||||
@@ -267,139 +15,278 @@ endmodule
|
||||
// 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.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//
|
||||
// Output timings are incompatible with any TV/VGA mode.
|
||||
// The output is supposed to be send to scaler input.
|
||||
//
|
||||
module screen_rotate #(parameter WIDTH=320, HEIGHT=240, DEPTH=8, MARGIN=4)
|
||||
//////////////////////////////////////////////////////////
|
||||
// DW:
|
||||
// 6 : 2R 2G 2B
|
||||
// 8 : 3R 3G 2B
|
||||
// 9 : 3R 3G 3B
|
||||
// 12 : 4R 4G 4B
|
||||
// 24 : 8R 8G 8B
|
||||
|
||||
module arcade_video #(parameter WIDTH=320, DW=8, GAMMA=1)
|
||||
(
|
||||
input clk,
|
||||
input ce,
|
||||
input clk_video,
|
||||
input ce_pix,
|
||||
|
||||
input ccw,
|
||||
input[DW-1:0] RGB_in,
|
||||
input HBlank,
|
||||
input VBlank,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
input [DEPTH-1:0] video_in,
|
||||
input hblank,
|
||||
input vblank,
|
||||
output CLK_VIDEO,
|
||||
output CE_PIXEL,
|
||||
output [7:0] VGA_R,
|
||||
output [7:0] VGA_G,
|
||||
output [7:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS,
|
||||
output VGA_DE,
|
||||
output [1:0] VGA_SL,
|
||||
|
||||
input ce_out,
|
||||
output [DEPTH-1:0] video_out,
|
||||
output reg hsync,
|
||||
output reg vsync,
|
||||
output reg hblank_out,
|
||||
output reg vblank_out
|
||||
input [2:0] fx,
|
||||
input forced_scandoubler,
|
||||
inout [21:0] gamma_bus
|
||||
);
|
||||
|
||||
localparam bufsize = WIDTH*HEIGHT;
|
||||
localparam memsize = bufsize*2;
|
||||
localparam aw = $clog2(memsize); // resolutions up to ~ 512x256
|
||||
assign CLK_VIDEO = clk_video;
|
||||
|
||||
reg [aw-1:0] addr_in, addr_out;
|
||||
reg we_in;
|
||||
reg buff = 0;
|
||||
wire hs_fix,vs_fix;
|
||||
sync_fix sync_v(CLK_VIDEO, HSync, hs_fix);
|
||||
sync_fix sync_h(CLK_VIDEO, VSync, vs_fix);
|
||||
|
||||
(* ramstyle="no_rw_check" *) reg [DEPTH-1:0] ram[memsize];
|
||||
always @ (posedge clk) if (en_we) ram[addr_in] <= video_in;
|
||||
always @ (posedge clk) out <= ram[addr_out];
|
||||
reg [DW-1:0] RGB_fix;
|
||||
|
||||
reg [DEPTH-1:0] out;
|
||||
reg [DEPTH-1:0] vout;
|
||||
reg CE,HS,VS,HBL,VBL;
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg old_ce;
|
||||
old_ce <= ce_pix;
|
||||
CE <= 0;
|
||||
if(~old_ce & ce_pix) begin
|
||||
CE <= 1;
|
||||
HS <= hs_fix;
|
||||
if(~HS & hs_fix) VS <= vs_fix;
|
||||
|
||||
assign video_out = vout;
|
||||
|
||||
wire en_we = ce & ~blank & en_x & en_y;
|
||||
wire en_x = (xpos<WIDTH);
|
||||
wire en_y = (ypos<HEIGHT);
|
||||
integer xpos, ypos;
|
||||
|
||||
wire blank = hblank | vblank;
|
||||
always @(posedge clk) begin
|
||||
reg old_blank, old_vblank;
|
||||
reg [aw-1:0] addr_row;
|
||||
|
||||
if(en_we) begin
|
||||
addr_in <= ccw ? addr_in-HEIGHT[aw-1:0] : addr_in+HEIGHT[aw-1:0];
|
||||
xpos <= xpos + 1;
|
||||
end
|
||||
|
||||
old_blank <= blank;
|
||||
old_vblank <= vblank;
|
||||
if(~old_blank & blank) begin
|
||||
xpos <= 0;
|
||||
ypos <= ypos + 1;
|
||||
addr_in <= ccw ? addr_row + 1'd1 : addr_row - 1'd1;
|
||||
addr_row <= ccw ? addr_row + 1'd1 : addr_row - 1'd1;
|
||||
end
|
||||
|
||||
if(~old_vblank & vblank) begin
|
||||
if(buff) begin
|
||||
addr_in <= ccw ? bufsize[aw-1:0]-HEIGHT[aw-1:0] : HEIGHT[aw-1:0]-1'd1;
|
||||
addr_row <= ccw ? bufsize[aw-1:0]-HEIGHT[aw-1:0] : HEIGHT[aw-1:0]-1'd1;
|
||||
end else begin
|
||||
addr_in <= ccw ? bufsize[aw-1:0]+bufsize[aw-1:0]-HEIGHT[aw-1:0] : bufsize[aw-1:0]+HEIGHT[aw-1:0]-1'd1;
|
||||
addr_row <= ccw ? bufsize[aw-1:0]+bufsize[aw-1:0]-HEIGHT[aw-1:0] : bufsize[aw-1:0]+HEIGHT[aw-1:0]-1'd1;
|
||||
end
|
||||
buff <= ~buff;
|
||||
ypos <= 0;
|
||||
xpos <= 0;
|
||||
RGB_fix <= RGB_in;
|
||||
HBL <= HBlank;
|
||||
if(HBL & ~HBlank) VBL <= VBlank;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg old_buff;
|
||||
reg hs;
|
||||
reg ced;
|
||||
wire [7:0] R,G,B;
|
||||
|
||||
integer vbcnt;
|
||||
integer xposo, yposo, xposd, yposd;
|
||||
|
||||
ced <= 0;
|
||||
if(ce_out) begin
|
||||
ced <= 1;
|
||||
|
||||
xposd <= xposo;
|
||||
yposd <= yposo;
|
||||
|
||||
if(xposo == (HEIGHT + 8)) hsync <= 1;
|
||||
if(xposo == (HEIGHT + 10)) hsync <= 0;
|
||||
|
||||
if((yposo>=MARGIN) && (yposo<WIDTH+MARGIN)) begin
|
||||
if(xposo < HEIGHT) addr_out <= addr_out + 1'd1;
|
||||
end
|
||||
|
||||
xposo <= xposo + 1;
|
||||
if(xposo > (HEIGHT + 16)) begin
|
||||
xposo <= 0;
|
||||
|
||||
if(yposo >= (WIDTH+MARGIN+MARGIN)) begin
|
||||
vblank_out <= 1;
|
||||
vbcnt <= vbcnt + 1;
|
||||
if(vbcnt == 10 ) vsync <= 1;
|
||||
if(vbcnt == 12) vsync <= 0;
|
||||
end
|
||||
else yposo <= yposo + 1;
|
||||
|
||||
old_buff <= buff;
|
||||
if(old_buff != buff) begin
|
||||
addr_out <= buff ? {aw{1'b0}} : bufsize[aw-1:0];
|
||||
yposo <= 0;
|
||||
vsync <= 0;
|
||||
vbcnt <= 0;
|
||||
vblank_out <= 0;
|
||||
end
|
||||
end
|
||||
generate
|
||||
if(DW == 6) begin
|
||||
assign R = {RGB_fix[5:4],RGB_fix[5:4],RGB_fix[5:4],RGB_fix[5:4]};
|
||||
assign G = {RGB_fix[3:2],RGB_fix[3:2],RGB_fix[3:2],RGB_fix[3:2]};
|
||||
assign B = {RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0]};
|
||||
end
|
||||
|
||||
if(ced) begin
|
||||
if((yposd<MARGIN) || (yposd>=WIDTH+MARGIN)) begin
|
||||
vout <= 0;
|
||||
end else begin
|
||||
vout <= out;
|
||||
else if(DW == 8) begin
|
||||
assign R = {RGB_fix[7:5],RGB_fix[7:5],RGB_fix[7:6]};
|
||||
assign G = {RGB_fix[4:2],RGB_fix[4:2],RGB_fix[4:3]};
|
||||
assign B = {RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0],RGB_fix[1:0]};
|
||||
end
|
||||
else if(DW == 9) begin
|
||||
assign R = {RGB_fix[8:6],RGB_fix[8:6],RGB_fix[8:7]};
|
||||
assign G = {RGB_fix[5:3],RGB_fix[5:3],RGB_fix[5:4]};
|
||||
assign B = {RGB_fix[2:0],RGB_fix[2:0],RGB_fix[2:1]};
|
||||
end
|
||||
else if(DW == 12) begin
|
||||
assign R = {RGB_fix[11:8],RGB_fix[11:8]};
|
||||
assign G = {RGB_fix[7:4],RGB_fix[7:4]};
|
||||
assign B = {RGB_fix[3:0],RGB_fix[3:0]};
|
||||
end
|
||||
else begin // 24
|
||||
assign R = RGB_fix[23:16];
|
||||
assign G = RGB_fix[15:8];
|
||||
assign B = RGB_fix[7:0];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign VGA_SL = sl[1:0];
|
||||
wire [2:0] sl = fx ? fx - 1'd1 : 3'd0;
|
||||
wire scandoubler = fx || forced_scandoubler;
|
||||
|
||||
video_mixer #(.LINE_LENGTH(WIDTH+4), .HALF_DEPTH(DW!=24), .GAMMA(GAMMA)) video_mixer
|
||||
(
|
||||
.clk_vid(CLK_VIDEO),
|
||||
.ce_pix(CE),
|
||||
.ce_pix_out(CE_PIXEL),
|
||||
|
||||
.scandoubler(scandoubler),
|
||||
.hq2x(fx==1),
|
||||
.gamma_bus(gamma_bus),
|
||||
|
||||
.R((DW!=24) ? R[7:4] : R),
|
||||
.G((DW!=24) ? G[7:4] : G),
|
||||
.B((DW!=24) ? B[7:4] : B),
|
||||
|
||||
.HSync (HS),
|
||||
.VSync (VS),
|
||||
.HBlank(HBL),
|
||||
.VBlank(VBL),
|
||||
|
||||
.VGA_R(VGA_R),
|
||||
.VGA_G(VGA_G),
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.VGA_DE(VGA_DE)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// Screen +90/-90 deg. rotation
|
||||
// Copyright (C) 2020 Sorgelig
|
||||
//
|
||||
// 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.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
module screen_rotate
|
||||
(
|
||||
input CLK_VIDEO,
|
||||
input CE_PIXEL,
|
||||
|
||||
input [7:0] VGA_R,
|
||||
input [7:0] VGA_G,
|
||||
input [7:0] VGA_B,
|
||||
input VGA_HS,
|
||||
input VGA_VS,
|
||||
input VGA_DE,
|
||||
|
||||
input rotate_ccw,
|
||||
input no_rotate,
|
||||
|
||||
output FB_EN,
|
||||
output [4:0] FB_FORMAT,
|
||||
output [11:0] FB_WIDTH,
|
||||
output [11:0] FB_HEIGHT,
|
||||
output [31:0] FB_BASE,
|
||||
input FB_VBL,
|
||||
input FB_LL,
|
||||
|
||||
output DDRAM_CLK,
|
||||
input DDRAM_BUSY,
|
||||
output [7:0] DDRAM_BURSTCNT,
|
||||
output [28:0] DDRAM_ADDR,
|
||||
output [63:0] DDRAM_DIN,
|
||||
output [7:0] DDRAM_BE,
|
||||
output DDRAM_WE,
|
||||
output DDRAM_RD
|
||||
);
|
||||
|
||||
assign DDRAM_CLK = CLK_VIDEO;
|
||||
assign DDRAM_BURSTCNT = 1;
|
||||
assign DDRAM_ADDR = {6'b001001, i_fb, ram_addr[23:3]}; // RAM at 0x24000000
|
||||
assign DDRAM_BE = ram_addr[2] ? 8'hF0 : 8'h0F;
|
||||
assign DDRAM_DIN = {ram_data,ram_data};
|
||||
assign DDRAM_WE = ram_wr;
|
||||
assign DDRAM_RD = 0;
|
||||
|
||||
assign FB_EN = ~no_rotate;
|
||||
assign FB_FORMAT = 5'b00110;
|
||||
assign FB_BASE = {6'b001001,o_fb,24'd0};
|
||||
assign FB_WIDTH = vsz;
|
||||
assign FB_HEIGHT = hsz;
|
||||
|
||||
function [1:0] buf_next;
|
||||
input [1:0] a,b;
|
||||
begin
|
||||
buf_next = 1;
|
||||
if ((a==0 && b==1) || (a==1 && b==0)) buf_next = 2;
|
||||
if ((a==1 && b==2) || (a==2 && b==1)) buf_next = 0;
|
||||
end
|
||||
endfunction
|
||||
|
||||
reg [1:0] i_fb,o_fb;
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg old_vbl,old_vs;
|
||||
old_vbl <= FB_VBL;
|
||||
old_vs <= VGA_VS;
|
||||
|
||||
if(FB_LL) begin
|
||||
if(~old_vbl & FB_VBL) o_fb<={1'b0,~i_fb[0]};
|
||||
if(~old_vs & VGA_VS) i_fb<={1'b0,~i_fb[0]};
|
||||
end
|
||||
else begin
|
||||
if(~old_vbl & FB_VBL) o_fb<=buf_next(o_fb,i_fb);
|
||||
if(~old_vs & VGA_VS) i_fb<=buf_next(i_fb,o_fb);
|
||||
end
|
||||
end
|
||||
|
||||
reg [11:0] hsz = 320, vsz = 240;
|
||||
reg [13:0] bwidth;
|
||||
reg [23:0] bufsize;
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg [11:0] hcnt = 0, vcnt = 0;
|
||||
reg old_vs, old_de;
|
||||
|
||||
if(CE_PIXEL) begin
|
||||
old_vs <= VGA_VS;
|
||||
old_de <= VGA_DE;
|
||||
|
||||
hcnt <= hcnt + 1'd1;
|
||||
if(~old_de & VGA_DE) begin
|
||||
hcnt <= 1;
|
||||
vcnt <= vcnt + 1'd1;
|
||||
end
|
||||
if(old_de & ~VGA_DE) hsz <= hcnt;
|
||||
if(~old_vs & VGA_VS) begin
|
||||
vsz <= vcnt;
|
||||
vcnt <= 0;
|
||||
end
|
||||
bwidth <= {vsz, 2'b00} + 14'd255;
|
||||
|
||||
if(old_vs & ~VGA_VS) bufsize <= hsz * stride;
|
||||
end
|
||||
end
|
||||
|
||||
wire [13:0] stride = {bwidth[13:8], 8'h00};
|
||||
|
||||
reg [23:0] ram_addr, next_addr;
|
||||
reg [31:0] ram_data;
|
||||
reg ram_wr;
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg [13:0] hcnt = 0;
|
||||
reg old_vs, old_de;
|
||||
|
||||
ram_wr <= 0;
|
||||
if(CE_PIXEL) begin
|
||||
old_vs <= VGA_VS;
|
||||
old_de <= VGA_DE;
|
||||
|
||||
if(~old_vs & VGA_VS) begin
|
||||
next_addr <= rotate_ccw ? (bufsize - stride) : {vsz-1'd1, 2'b00};
|
||||
hcnt <= rotate_ccw ? 3'd4 : {vsz-2'd2, 2'b00};
|
||||
end
|
||||
if(VGA_DE) begin
|
||||
ram_wr <= 1;
|
||||
ram_data <= {VGA_B,VGA_G,VGA_R};
|
||||
ram_addr <= next_addr;
|
||||
next_addr <= rotate_ccw ? (next_addr - stride) : (next_addr + stride);
|
||||
end
|
||||
if(old_de & ~VGA_DE) begin
|
||||
next_addr <= rotate_ccw ? (bufsize - stride + hcnt) : hcnt;
|
||||
hcnt <= rotate_ccw ? (hcnt + 3'd4) : (hcnt - 3'd4);
|
||||
end
|
||||
if(xposd == 0) hblank_out <= 0;
|
||||
if(xposd == HEIGHT) hblank_out <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -148,8 +148,9 @@ ENTITY ascal IS
|
||||
o_hs : OUT std_logic; -- H sync
|
||||
o_vs : OUT std_logic; -- V sync
|
||||
o_de : OUT std_logic; -- Display Enable
|
||||
o_vbl : OUT std_logic; -- V blank
|
||||
o_ce : IN std_logic; -- Clock Enable
|
||||
o_clk : IN std_logic; -- Output clock
|
||||
o_clk : IN std_logic; -- Output clock
|
||||
|
||||
-- Border colour R G B
|
||||
o_border : IN unsigned(23 DOWNTO 0) := x"000000";
|
||||
@@ -287,7 +288,7 @@ ARCHITECTURE rtl OF ascal IS
|
||||
TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0);
|
||||
TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255;
|
||||
TYPE arr_uint12 IS ARRAY (natural RANGE <>) OF uint12;
|
||||
|
||||
|
||||
----------------------------------------------------------
|
||||
-- Input image
|
||||
SIGNAL i_pvs,i_pfl,i_pde,i_pce : std_logic;
|
||||
@@ -385,12 +386,12 @@ ARCHITECTURE rtl OF ascal IS
|
||||
SIGNAL o_run : std_logic;
|
||||
SIGNAL o_mode,o_hmode,o_vmode : unsigned(4 DOWNTO 0);
|
||||
SIGNAL o_format : unsigned(5 DOWNTO 0);
|
||||
SIGNAL o_fb_pal_dr : unsigned(23 DOWNTO 0);
|
||||
SIGNAL o_fb_pal_dr_x2 : unsigned(47 DOWNTO 0);
|
||||
SIGNAL pal_idx: unsigned(7 DOWNTO 0);
|
||||
SIGNAL pal_idx_lsb: std_logic;
|
||||
SIGNAL pal_mem : arr_uv48(0 TO 127);
|
||||
ATTRIBUTE ramstyle of pal_mem : signal is "no_rw_check";
|
||||
SIGNAL o_fb_pal_dr : unsigned(23 DOWNTO 0);
|
||||
SIGNAL o_fb_pal_dr_x2 : unsigned(47 DOWNTO 0);
|
||||
SIGNAL pal_idx: unsigned(7 DOWNTO 0);
|
||||
SIGNAL pal_idx_lsb: std_logic;
|
||||
SIGNAL pal_mem : arr_uv48(0 TO 127);
|
||||
ATTRIBUTE ramstyle of pal_mem : signal is "no_rw_check";
|
||||
SIGNAL o_htotal,o_hsstart,o_hsend : uint12;
|
||||
SIGNAL o_hmin,o_hmax,o_hdisp : uint12;
|
||||
SIGNAL o_hsize,o_vsize : uint12;
|
||||
@@ -430,7 +431,7 @@ ARCHITECTURE rtl OF ascal IS
|
||||
|
||||
SIGNAL o_vfrac,o_hfrac,o_hfrac1,o_hfrac2,o_hfrac3,o_hfrac4 : unsigned(11 DOWNTO 0);
|
||||
SIGNAL o_hacc,o_hacc_ini,o_hacc_next,o_vacc,o_vacc_next,o_vacc_ini : natural RANGE 0 TO 4*OHRES-1;
|
||||
SIGNAL o_hsv,o_vsv,o_dev,o_pev : unsigned(0 TO 5);
|
||||
SIGNAL o_hsv,o_vsv,o_dev,o_pev,o_end : unsigned(0 TO 5);
|
||||
SIGNAL o_hsp,o_vss : std_logic;
|
||||
SIGNAL o_read,o_read_pre : std_logic;
|
||||
SIGNAL o_readlev,o_copylev : natural RANGE 0 TO 2;
|
||||
@@ -2049,10 +2050,10 @@ BEGIN
|
||||
pal_dr<=pal_mem(to_integer(pal_a));
|
||||
END IF;
|
||||
END PROCESS;
|
||||
|
||||
pal_idx <= shift_opack(o_acpt4,o_shift,o_dr,o_format)(0 TO 7);
|
||||
pal_idx_lsb <= pal_idx(0) WHEN rising_edge(o_clk);
|
||||
o_fb_pal_dr_x2 <= pal_mem(to_integer(pal_idx(7 DOWNTO 1))) WHEN rising_edge(o_clk);
|
||||
|
||||
pal_idx <= shift_opack(o_acpt4,o_shift,o_dr,o_format)(0 TO 7);
|
||||
pal_idx_lsb <= pal_idx(0) WHEN rising_edge(o_clk);
|
||||
o_fb_pal_dr_x2 <= pal_mem(to_integer(pal_idx(7 DOWNTO 1))) WHEN rising_edge(o_clk);
|
||||
o_fb_pal_dr <= o_fb_pal_dr_x2(47 DOWNTO 24) WHEN pal_idx_lsb = '1' ELSE o_fb_pal_dr_x2(23 DOWNTO 0);
|
||||
END GENERATE GenPal;
|
||||
|
||||
@@ -2152,7 +2153,7 @@ BEGIN
|
||||
o_copyv(1 TO 8)<=o_copyv(0 TO 7);
|
||||
|
||||
o_dcptv(1)<=o_dcpt;
|
||||
IF o_dcptv(1)>o_hsize THEN
|
||||
IF o_dcptv(1)>=o_hsize THEN
|
||||
o_copyv(2)<='0';
|
||||
END IF;
|
||||
o_dcptv(2)<=o_dcptv(1) MOD OHRES;
|
||||
@@ -2283,6 +2284,7 @@ BEGIN
|
||||
o_vcpt<=o_vcpt_pre;
|
||||
END IF;
|
||||
|
||||
o_end(0)<=to_std_logic(o_vcpt>=o_vdisp);
|
||||
o_dev(0)<=to_std_logic(o_hcpt<o_hdisp AND o_vcpt<o_vdisp);
|
||||
o_pev(0)<=to_std_logic(o_hcpt>=o_hmin AND o_hcpt<=o_hmax AND
|
||||
o_vcpt>=o_vmin AND o_vcpt<=o_vmax);
|
||||
@@ -2296,12 +2298,14 @@ BEGIN
|
||||
o_vsv(1 TO 5)<=o_vsv(0 TO 4);
|
||||
o_dev(1 TO 5)<=o_dev(0 TO 4);
|
||||
o_pev(1 TO 5)<=o_pev(0 TO 4);
|
||||
o_end(1 TO 5)<=o_end(0 TO 4);
|
||||
|
||||
IF o_run='0' THEN
|
||||
o_hsv(2)<='0';
|
||||
o_vsv(2)<='0';
|
||||
o_dev(2)<='0';
|
||||
o_pev(2)<='0';
|
||||
o_end(2)<='0';
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
@@ -2401,6 +2405,7 @@ BEGIN
|
||||
o_hs<=o_hsv(5);
|
||||
o_vs<=o_vsv(5);
|
||||
o_de<=o_dev(5);
|
||||
o_vbl<=o_end(5);
|
||||
o_r<=x"00";
|
||||
o_g<=x"00";
|
||||
o_b<=x"00";
|
||||
|
||||
243
sys/audio_out.v
243
sys/audio_out.v
@@ -1,7 +1,7 @@
|
||||
|
||||
module audio_out
|
||||
#(
|
||||
parameter CLK_RATE = 50000000
|
||||
parameter CLK_RATE = 24576000
|
||||
)
|
||||
(
|
||||
input reset,
|
||||
@@ -10,8 +10,24 @@ module audio_out
|
||||
//0 - 48KHz, 1 - 96KHz
|
||||
input sample_rate,
|
||||
|
||||
input [15:0] left_in,
|
||||
input [15:0] right_in,
|
||||
input [31:0] flt_rate,
|
||||
input [39:0] cx,
|
||||
input [7:0] cx0,
|
||||
input [7:0] cx1,
|
||||
input [7:0] cx2,
|
||||
input [23:0] cy0,
|
||||
input [23:0] cy1,
|
||||
input [23:0] cy2,
|
||||
|
||||
input [4:0] att,
|
||||
input [1:0] mix,
|
||||
|
||||
input is_signed,
|
||||
input [15:0] core_l,
|
||||
input [15:0] core_r,
|
||||
|
||||
input [15:0] alsa_l,
|
||||
input [15:0] alsa_r,
|
||||
|
||||
// I2S
|
||||
output i2s_bclk,
|
||||
@@ -56,19 +72,6 @@ always @(posedge clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
reg lpf_ce;
|
||||
always @(posedge clk) begin
|
||||
integer div;
|
||||
lpf_ce <= 0;
|
||||
if(mclk_ce) begin
|
||||
div <= div + 1;
|
||||
if(div == FILTER_DIV) begin
|
||||
div <= 0;
|
||||
lpf_ce <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
i2s i2s
|
||||
(
|
||||
.reset(reset),
|
||||
@@ -111,47 +114,183 @@ sigma_delta_dac #(15) sd_r
|
||||
.DACout(dac_r)
|
||||
);
|
||||
|
||||
wire [15:0] al, ar;
|
||||
lpf_aud lpf_l
|
||||
(
|
||||
.CLK(clk),
|
||||
.CE(lpf_ce),
|
||||
.IDATA(left_in),
|
||||
.ODATA(al)
|
||||
);
|
||||
reg sample_ce;
|
||||
always @(posedge clk) begin
|
||||
reg [8:0] div = 0;
|
||||
reg [1:0] add = 0;
|
||||
|
||||
lpf_aud lpf_r
|
||||
(
|
||||
.CLK(clk),
|
||||
.CE(lpf_ce),
|
||||
.IDATA(right_in),
|
||||
.ODATA(ar)
|
||||
);
|
||||
div <= div + add;
|
||||
if(!div) begin
|
||||
div <= 2'd1 << sample_rate;
|
||||
add <= 2'd1 << sample_rate;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module lpf_aud
|
||||
(
|
||||
input CLK,
|
||||
input CE,
|
||||
input [15:0] IDATA,
|
||||
output reg [15:0] ODATA
|
||||
);
|
||||
|
||||
reg [511:0] acc;
|
||||
reg [20:0] sum;
|
||||
|
||||
always @(*) begin
|
||||
integer i;
|
||||
sum = 0;
|
||||
for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]};
|
||||
sample_ce <= !div;
|
||||
end
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if(CE) begin
|
||||
acc <= {acc[495:0], IDATA};
|
||||
ODATA <= sum[20:5];
|
||||
reg flt_ce;
|
||||
always @(posedge clk) begin
|
||||
reg [31:0] cnt = 0;
|
||||
|
||||
flt_ce <= 0;
|
||||
cnt = cnt + {flt_rate[30:0],1'b0};
|
||||
if(cnt >= CLK_RATE) begin
|
||||
cnt = cnt - CLK_RATE;
|
||||
flt_ce <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [15:0] cl,cr;
|
||||
always @(posedge clk) begin
|
||||
reg [15:0] cl1,cl2;
|
||||
reg [15:0] cr1,cr2;
|
||||
|
||||
cl1 <= core_l; cl2 <= cl1;
|
||||
if(cl2 == cl1) cl <= cl2;
|
||||
|
||||
cr1 <= core_r; cr2 <= cr1;
|
||||
if(cr2 == cr1) cr <= cr2;
|
||||
end
|
||||
|
||||
reg a_en1 = 0, a_en2 = 0;
|
||||
always @(posedge clk, posedge reset) begin
|
||||
reg [1:0] dly1 = 0;
|
||||
reg [14:0] dly2 = 0;
|
||||
|
||||
if(reset) begin
|
||||
dly1 <= 0;
|
||||
dly2 <= 0;
|
||||
a_en1 <= 0;
|
||||
a_en2 <= 0;
|
||||
end
|
||||
else begin
|
||||
if(flt_ce) begin
|
||||
if(~&dly1) dly1 <= dly1 + 1'd1;
|
||||
else a_en1 <= 1;
|
||||
end
|
||||
|
||||
if(sample_ce) begin
|
||||
if(!dly2[13+sample_rate]) dly2 <= dly2 + 1'd1;
|
||||
else a_en2 <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [15:0] acl, acr;
|
||||
IIR_filter #(.use_params(0)) IIR_filter
|
||||
(
|
||||
.clk(clk),
|
||||
.reset(reset),
|
||||
|
||||
.ce(flt_ce & a_en1),
|
||||
.sample_ce(sample_ce),
|
||||
|
||||
.cx(cx),
|
||||
.cx0(cx0),
|
||||
.cx1(cx1),
|
||||
.cx2(cx2),
|
||||
.cy0(cy0),
|
||||
.cy1(cy1),
|
||||
.cy2(cy2),
|
||||
|
||||
.input_l({~is_signed ^ cl[15], cl[14:0]}),
|
||||
.input_r({~is_signed ^ cr[15], cr[14:0]}),
|
||||
.output_l(acl),
|
||||
.output_r(acr)
|
||||
);
|
||||
|
||||
wire [15:0] adl;
|
||||
DC_blocker dcb_l
|
||||
(
|
||||
.clk(clk),
|
||||
.ce(sample_ce),
|
||||
.sample_rate(sample_rate),
|
||||
.mute(~a_en2),
|
||||
.din(acl),
|
||||
.dout(adl)
|
||||
);
|
||||
|
||||
wire [15:0] adr;
|
||||
DC_blocker dcb_r
|
||||
(
|
||||
.clk(clk),
|
||||
.ce(sample_ce),
|
||||
.sample_rate(sample_rate),
|
||||
.mute(~a_en2),
|
||||
.din(acr),
|
||||
.dout(adr)
|
||||
);
|
||||
|
||||
wire [15:0] al, audio_l_pre;
|
||||
aud_mix_top audmix_l
|
||||
(
|
||||
.clk(clk),
|
||||
.ce(sample_ce),
|
||||
.att(att),
|
||||
.mix(mix),
|
||||
|
||||
.core_audio(adl),
|
||||
.pre_in(audio_r_pre),
|
||||
.linux_audio(alsa_l),
|
||||
|
||||
.pre_out(audio_l_pre),
|
||||
.out(al)
|
||||
);
|
||||
|
||||
wire [15:0] ar, audio_r_pre;
|
||||
aud_mix_top audmix_r
|
||||
(
|
||||
.clk(clk),
|
||||
.ce(sample_ce),
|
||||
.att(att),
|
||||
.mix(mix),
|
||||
|
||||
.core_audio(adr),
|
||||
.pre_in(audio_l_pre),
|
||||
.linux_audio(alsa_r),
|
||||
|
||||
.pre_out(audio_r_pre),
|
||||
.out(ar)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
module aud_mix_top
|
||||
(
|
||||
input clk,
|
||||
input ce,
|
||||
|
||||
input [4:0] att,
|
||||
input [1:0] mix,
|
||||
|
||||
input [15:0] core_audio,
|
||||
input [15:0] linux_audio,
|
||||
input [15:0] pre_in,
|
||||
|
||||
output reg [15:0] pre_out = 0,
|
||||
output reg [15:0] out = 0
|
||||
);
|
||||
|
||||
reg signed [16:0] a1, a2, a3, a4;
|
||||
always @(posedge clk) if (ce) begin
|
||||
|
||||
a1 <= {core_audio[15],core_audio};
|
||||
a2 <= a1 + {linux_audio[15],linux_audio};
|
||||
|
||||
pre_out <= a2[16:1];
|
||||
|
||||
case(mix)
|
||||
0: a3 <= a2;
|
||||
1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]);
|
||||
2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]);
|
||||
3: a3 <= {a2[16],a2[16:1]} + {pre_in[15],pre_in};
|
||||
endcase
|
||||
|
||||
if(att[4]) a4 <= 0;
|
||||
else a4 <= a3 >>> att[3:0];
|
||||
|
||||
//clamping
|
||||
out <= ^a4[16:15] ? {a4[16],{15{a4[15]}}} : a4[15:0];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -279,6 +279,7 @@ always@(posedge clk_sys) begin
|
||||
sd_ack_conf <= 0;
|
||||
io_dout <= 0;
|
||||
ps2skip <= 0;
|
||||
img_mounted <= 0;
|
||||
end
|
||||
else if(io_strobe) begin
|
||||
|
||||
@@ -297,10 +298,10 @@ always@(posedge clk_sys) begin
|
||||
'h2F: io_dout <= 1;
|
||||
'h32: io_dout <= gamma_bus[21];
|
||||
'h36: begin io_dout <= info_n; info_n <= 0; end
|
||||
'h39: io_dout <= 1;
|
||||
endcase
|
||||
|
||||
sd_buff_addr <= 0;
|
||||
img_mounted <= 0;
|
||||
if(io_din == 5) ps2_key_raw <= 0;
|
||||
end else begin
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.13.qip ]
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.13.qip ]
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_audio.13.qip ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_core.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_top.v ]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ]
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_audio.qip ]
|
||||
set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_cfg.qip ]
|
||||
|
||||
@@ -17,11 +17,12 @@ set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) a
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) audio_out.v ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) iir_filter.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) mcp23009.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ddr_svc.sv ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ]
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sd_card.sv ]
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ]
|
||||
|
||||
@@ -12,6 +12,8 @@ derive_clock_uncertainty
|
||||
set_clock_groups -exclusive \
|
||||
-group [get_clocks { *|pll|pll_inst|altera_pll_i|*[*].*|divclk}] \
|
||||
-group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \
|
||||
-group [get_clocks { pll_audio|pll_audio_inst|altera_pll_i|*[0].*|divclk}] \
|
||||
-group [get_clocks { spi_sck}] \
|
||||
-group [get_clocks { *|h2f_user0_clk}] \
|
||||
-group [get_clocks { FPGA_CLK1_50 }] \
|
||||
-group [get_clocks { FPGA_CLK2_50 }] \
|
||||
@@ -45,7 +47,8 @@ set_false_path -to {*_osd|half}
|
||||
|
||||
set_false_path -to {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
|
||||
set_false_path -from {WIDTH[*] HFP[*] HS[*] HBP[*] HEIGHT[*] VFP[*] VS[*] VBP[*]}
|
||||
set_false_path -to {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] FB_HMIN[*] FB_HMAX[*] FB_VMIN[*] FB_VMAX[*]}
|
||||
set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] FB_HMIN[*] FB_HMAX[*] FB_VMIN[*] FB_VMAX[*]}
|
||||
set_false_path -to {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]}
|
||||
set_false_path -from {FB_BASE[*] FB_BASE[*] FB_WIDTH[*] FB_HEIGHT[*] LFB_HMIN[*] LFB_HMAX[*] LFB_VMIN[*] LFB_VMAX[*]}
|
||||
set_false_path -to {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
|
||||
set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
|
||||
set_false_path -from {aflt_* acx* acy* areset*}
|
||||
|
||||
379
sys/sys_top.v
379
sys/sys_top.v
@@ -24,6 +24,13 @@
|
||||
`define USE_SDRAM
|
||||
`endif
|
||||
|
||||
`ifndef USE_DDRAM
|
||||
`ifdef USE_FB
|
||||
`define USE_DDRAM
|
||||
`endif
|
||||
`endif
|
||||
|
||||
|
||||
module sys_top
|
||||
(
|
||||
/////////// CLOCK //////////
|
||||
@@ -236,7 +243,10 @@ wire io_ss0 = gp_outr[18];
|
||||
wire io_ss1 = gp_outr[19];
|
||||
wire io_ss2 = gp_outr[20];
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire io_osd_hdmi = io_ss1 & ~io_ss0;
|
||||
`endif
|
||||
|
||||
wire io_fpga = ~io_ss1 & io_ss0;
|
||||
wire io_uio = ~io_ss1 & io_ss2;
|
||||
|
||||
@@ -276,11 +286,16 @@ cyclonev_hps_interface_mpu_general_purpose h2f_gp
|
||||
|
||||
reg [15:0] cfg;
|
||||
|
||||
reg cfg_got = 0;
|
||||
reg cfg_set = 0;
|
||||
wire vga_fb = cfg[12];
|
||||
wire [1:0] hdmi_limited = {cfg[11],cfg[8]};
|
||||
|
||||
`ifdef DEBUG_NOHDMI
|
||||
wire direct_video = 1;
|
||||
`else
|
||||
wire direct_video = cfg[10];
|
||||
`endif
|
||||
|
||||
wire dvi_mode = cfg[7];
|
||||
wire audio_96k = cfg[6];
|
||||
wire csync_en = cfg[3];
|
||||
@@ -312,12 +327,24 @@ reg vs_wait = 0;
|
||||
reg [11:0] vs_line = 0;
|
||||
|
||||
reg scaler_out = 0;
|
||||
|
||||
reg [31:0] aflt_rate = 7056000;
|
||||
reg [39:0] acx = 4258969;
|
||||
reg [7:0] acx0 = 3;
|
||||
reg [7:0] acx1 = 3;
|
||||
reg [7:0] acx2 = 1;
|
||||
reg [23:0] acy0 = -24'd6216759;
|
||||
reg [23:0] acy1 = 24'd6143386;
|
||||
reg [23:0] acy2 = -24'd2023767;
|
||||
reg areset = 0;
|
||||
|
||||
always@(posedge clk_sys) begin
|
||||
reg [7:0] cmd;
|
||||
reg has_cmd;
|
||||
reg old_strobe;
|
||||
reg [7:0] cnt = 0;
|
||||
reg vs_d0,vs_d1,vs_d2;
|
||||
reg [4:0] acx_att;
|
||||
|
||||
old_strobe <= io_strobe;
|
||||
coef_wr <= 0;
|
||||
@@ -325,6 +352,9 @@ always@(posedge clk_sys) begin
|
||||
if(~io_uio) begin
|
||||
has_cmd <= 0;
|
||||
cmd <= 0;
|
||||
areset <= 0;
|
||||
acx_att <= 0;
|
||||
acx <= acx >> acx_att;
|
||||
end
|
||||
else
|
||||
if(~old_strobe & io_strobe) begin
|
||||
@@ -333,6 +363,17 @@ always@(posedge clk_sys) begin
|
||||
cmd <= io_din[7:0];
|
||||
cnt <= 0;
|
||||
if(io_din[7:0] == 'h30) vs_wait <= 1;
|
||||
if(io_din[7:0] == 'h39) begin
|
||||
aflt_rate <= 7056000;
|
||||
acx <= 4258969;
|
||||
acx0 <= 3;
|
||||
acx1 <= 3;
|
||||
acx2 <= 1;
|
||||
acy0 <= -24'd6216759;
|
||||
acy1 <= 24'd6143386;
|
||||
acy2 <= -24'd2023767;
|
||||
areset <= 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if(cmd == 1) begin
|
||||
@@ -354,6 +395,7 @@ always@(posedge clk_sys) begin
|
||||
6: if(VS != io_din[11:0]) VS <= io_din[11:0];
|
||||
7: if(VBP != io_din[11:0]) VBP <= io_din[11:0];
|
||||
endcase
|
||||
`ifndef DEBUG_NOHDMI
|
||||
if(cnt == 1) begin
|
||||
cfg_custom_p1 <= 0;
|
||||
cfg_custom_p2 <= 0;
|
||||
@@ -369,20 +411,21 @@ always@(posedge clk_sys) begin
|
||||
cnt[2:0] <= 3'b100;
|
||||
end
|
||||
if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14];
|
||||
`endif
|
||||
end
|
||||
end
|
||||
if(cmd == 'h2F) begin
|
||||
cnt <= cnt + 1'd1;
|
||||
case(cnt[3:0])
|
||||
0: {FB_EN,FB_FLT,FB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
|
||||
1: FB_BASE[15:0] <= io_din[15:0];
|
||||
2: FB_BASE[31:16] <= io_din[15:0];
|
||||
3: FB_WIDTH <= io_din[11:0];
|
||||
4: FB_HEIGHT <= io_din[11:0];
|
||||
5: FB_HMIN <= io_din[11:0];
|
||||
6: FB_HMAX <= io_din[11:0];
|
||||
7: FB_VMIN <= io_din[11:0];
|
||||
8: FB_VMAX <= io_din[11:0];
|
||||
0: {LFB_EN,LFB_FLT,LFB_FMT} <= {io_din[15], io_din[14], io_din[5:0]};
|
||||
1: LFB_BASE[15:0] <= io_din[15:0];
|
||||
2: LFB_BASE[31:16] <= io_din[15:0];
|
||||
3: LFB_WIDTH <= io_din[11:0];
|
||||
4: LFB_HEIGHT <= io_din[11:0];
|
||||
5: LFB_HMIN <= io_din[11:0];
|
||||
6: LFB_HMAX <= io_din[11:0];
|
||||
7: LFB_VMIN <= io_din[11:0];
|
||||
8: LFB_VMAX <= io_din[11:0];
|
||||
endcase
|
||||
end
|
||||
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
|
||||
@@ -392,6 +435,26 @@ always@(posedge clk_sys) begin
|
||||
if(cmd == 'h2B) scaler_flt <= io_din[2:0];
|
||||
if(cmd == 'h37) {FREESCALE,HSET} <= {io_din[15],io_din[11:0]};
|
||||
if(cmd == 'h38) vs_line <= io_din[11:0];
|
||||
if(cmd == 'h39) begin
|
||||
cnt <= cnt + 1'd1;
|
||||
case(cnt[3:0])
|
||||
0: acx_att <= io_din[4:0];
|
||||
1: aflt_rate[15:0] <= io_din;
|
||||
2: aflt_rate[31:16] <= io_din;
|
||||
3: acx[15:0] <= io_din;
|
||||
4: acx[31:16] <= io_din;
|
||||
5: acx[39:32] <= io_din[7:0];
|
||||
6: acx0 <= io_din[7:0];
|
||||
7: acx1 <= io_din[7:0];
|
||||
8: acx2 <= io_din[7:0];
|
||||
9: acy0[15:0] <= io_din;
|
||||
10: acy0[23:16] <= io_din[7:0];
|
||||
11: acy1[15:0] <= io_din;
|
||||
12: acy1[23:16] <= io_din[7:0];
|
||||
13: acy2[15:0] <= io_din;
|
||||
14: acy2[23:16] <= io_din[7:0];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -402,16 +465,6 @@ always@(posedge clk_sys) begin
|
||||
if(~vs_d2 & vs_d1) vs_wait <= 0;
|
||||
end
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg vsd, vsd2;
|
||||
if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
|
||||
else begin
|
||||
vsd <= HDMI_TX_VS;
|
||||
vsd2 <= vsd;
|
||||
if(~vsd2 & vsd) cfg_got <= cfg_set;
|
||||
end
|
||||
end
|
||||
|
||||
cyclonev_hps_interface_peripheral_uart uart
|
||||
(
|
||||
.ri(0)
|
||||
@@ -466,8 +519,6 @@ always @(posedge FPGA_CLK2_50) begin
|
||||
end
|
||||
|
||||
wire clk_100m;
|
||||
wire clk_hdmi = hdmi_clk_out;
|
||||
wire clk_audio = FPGA_CLK3_50;
|
||||
wire clk_pal = FPGA_CLK3_50;
|
||||
|
||||
//////////////////// SYSTEM MEMORY & SCALER /////////////////////////
|
||||
@@ -574,7 +625,10 @@ wire [15:0] vbuf_byteenable;
|
||||
wire vbuf_write;
|
||||
|
||||
wire [23:0] hdmi_data;
|
||||
wire hdmi_vs, hdmi_hs, hdmi_de;
|
||||
wire hdmi_vs, hdmi_hs, hdmi_de, hdmi_vbl;
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire clk_hdmi = hdmi_clk_out;
|
||||
|
||||
ascal
|
||||
#(
|
||||
@@ -611,6 +665,7 @@ ascal
|
||||
.o_hs (hdmi_hs),
|
||||
.o_vs (hdmi_vs),
|
||||
.o_de (hdmi_de),
|
||||
.o_vbl (hdmi_vbl),
|
||||
.o_lltune (lltune),
|
||||
.htotal (WIDTH + HFP + HBP + HS),
|
||||
.hsstart (WIDTH + HFP),
|
||||
@@ -625,7 +680,7 @@ ascal
|
||||
.vmin (vmin),
|
||||
.vmax (vmax),
|
||||
|
||||
.mode ({~lowlat,FB_EN ? FB_FLT : |scaler_flt,2'b00}),
|
||||
.mode ({~lowlat,LFB_EN ? LFB_FLT : |scaler_flt,2'b00}),
|
||||
.poly_clk (clk_sys),
|
||||
.poly_a (coef_addr),
|
||||
.poly_dw (coef_data),
|
||||
@@ -653,18 +708,46 @@ ascal
|
||||
.avl_read (vbuf_read),
|
||||
.avl_byteenable (vbuf_byteenable)
|
||||
);
|
||||
`endif
|
||||
|
||||
reg LFB_EN = 0;
|
||||
reg LFB_FLT = 0;
|
||||
reg [5:0] LFB_FMT = 0;
|
||||
reg [11:0] LFB_WIDTH = 0;
|
||||
reg [11:0] LFB_HEIGHT = 0;
|
||||
reg [11:0] LFB_HMIN = 0;
|
||||
reg [11:0] LFB_HMAX = 0;
|
||||
reg [11:0] LFB_VMIN = 0;
|
||||
reg [11:0] LFB_VMAX = 0;
|
||||
reg [31:0] LFB_BASE = 0;
|
||||
|
||||
reg FB_EN = 0;
|
||||
reg FB_FLT = 0;
|
||||
reg [5:0] FB_FMT = 0;
|
||||
reg [11:0] FB_WIDTH = 0;
|
||||
reg [11:0] FB_HEIGHT = 0;
|
||||
reg [11:0] FB_HMIN = 0;
|
||||
reg [11:0] FB_HMAX = 0;
|
||||
reg [11:0] FB_VMIN = 0;
|
||||
reg [11:0] FB_VMAX = 0;
|
||||
reg [31:0] FB_BASE = 0;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
FB_EN <= LFB_EN | fb_en;
|
||||
if(LFB_EN) begin
|
||||
FB_FMT <= LFB_FMT;
|
||||
FB_WIDTH <= LFB_WIDTH;
|
||||
FB_HEIGHT <= LFB_HEIGHT;
|
||||
FB_BASE <= LFB_BASE;
|
||||
end
|
||||
else begin
|
||||
FB_FMT <= fb_fmt;
|
||||
FB_WIDTH <= fb_width;
|
||||
FB_HEIGHT <= fb_height;
|
||||
FB_BASE <= fb_base;
|
||||
end
|
||||
end
|
||||
|
||||
`ifdef USE_FB
|
||||
reg fb_vbl;
|
||||
always @(posedge clk_vid) fb_vbl <= hdmi_vbl;
|
||||
`endif
|
||||
|
||||
reg [11:0] hmin;
|
||||
reg [11:0] hmax;
|
||||
reg [11:0] vmin;
|
||||
@@ -684,11 +767,11 @@ always @(posedge clk_vid) begin
|
||||
|
||||
state <= state + 1'd1;
|
||||
case(state)
|
||||
0: if(FB_EN) begin
|
||||
hmin <= FB_HMIN;
|
||||
vmin <= FB_VMIN;
|
||||
hmax <= FB_HMAX;
|
||||
vmax <= FB_VMAX;
|
||||
0: if(LFB_EN) begin
|
||||
hmin <= LFB_HMIN;
|
||||
vmin <= LFB_VMIN;
|
||||
hmax <= LFB_HMAX;
|
||||
vmax <= LFB_VMAX;
|
||||
state<= 0;
|
||||
end
|
||||
else if(ARX && ARY && !FREESCALE) begin
|
||||
@@ -712,8 +795,8 @@ always @(posedge clk_vid) begin
|
||||
endcase
|
||||
end
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire [15:0] lltune;
|
||||
|
||||
pll_hdmi_adj pll_hdmi_adj
|
||||
(
|
||||
.clk(FPGA_CLK1_50),
|
||||
@@ -731,6 +814,9 @@ pll_hdmi_adj pll_hdmi_adj
|
||||
.o_address(cfg_address),
|
||||
.o_writedata(cfg_data)
|
||||
);
|
||||
`else
|
||||
assign led_locked = 0;
|
||||
`endif
|
||||
|
||||
wire [63:0] pal_data;
|
||||
wire [47:0] pal_d = {pal_data[55:32], pal_data[23:0]};
|
||||
@@ -750,7 +836,7 @@ end
|
||||
|
||||
|
||||
///////////////////////// HDMI output /////////////////////////////////
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire hdmi_clk_out;
|
||||
pll_hdmi pll_hdmi
|
||||
(
|
||||
@@ -760,6 +846,7 @@ pll_hdmi pll_hdmi
|
||||
.reconfig_from_pll(reconfig_from_pll),
|
||||
.outclk_0(hdmi_clk_out)
|
||||
);
|
||||
`endif
|
||||
|
||||
//1920x1080@60 PCLK=148.5MHz CEA
|
||||
reg [11:0] WIDTH = 1920;
|
||||
@@ -781,6 +868,7 @@ reg adj_write;
|
||||
reg [5:0] adj_address;
|
||||
reg [31:0] adj_data;
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
pll_cfg pll_cfg
|
||||
(
|
||||
.mgmt_clk(FPGA_CLK1_50),
|
||||
@@ -795,8 +883,18 @@ pll_cfg pll_cfg
|
||||
.reconfig_from_pll(reconfig_from_pll)
|
||||
);
|
||||
|
||||
reg cfg_ready = 0;
|
||||
reg cfg_got = 0;
|
||||
always @(posedge clk_sys) begin
|
||||
reg vsd, vsd2;
|
||||
if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set;
|
||||
else begin
|
||||
vsd <= HDMI_TX_VS;
|
||||
vsd2 <= vsd;
|
||||
if(~vsd2 & vsd) cfg_got <= cfg_set;
|
||||
end
|
||||
end
|
||||
|
||||
reg cfg_ready = 0;
|
||||
always @(posedge FPGA_CLK1_50) begin
|
||||
reg gotd = 0, gotd2 = 0;
|
||||
reg custd = 0, custd2 = 0;
|
||||
@@ -825,6 +923,12 @@ always @(posedge FPGA_CLK1_50) begin
|
||||
if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1;
|
||||
end
|
||||
|
||||
`else
|
||||
|
||||
wire cfg_ready = 1;
|
||||
|
||||
`endif
|
||||
|
||||
wire hdmi_config_done;
|
||||
hdmi_config hdmi_config
|
||||
(
|
||||
@@ -841,6 +945,7 @@ hdmi_config hdmi_config
|
||||
.ypbpr(ypbpr_en & direct_video)
|
||||
);
|
||||
|
||||
`ifndef DEBUG_NOHDMI
|
||||
wire [23:0] hdmi_data_sl;
|
||||
wire hdmi_de_sl, hdmi_vs_sl, hdmi_hs_sl;
|
||||
scanlines #(1) HDMI_scanlines
|
||||
@@ -861,6 +966,7 @@ scanlines #(1) HDMI_scanlines
|
||||
|
||||
wire [23:0] hdmi_data_osd;
|
||||
wire hdmi_de_osd, hdmi_vs_osd, hdmi_hs_osd;
|
||||
|
||||
osd hdmi_osd
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
@@ -884,6 +990,7 @@ osd hdmi_osd
|
||||
.osd_status(osd_status)
|
||||
`endif
|
||||
);
|
||||
`endif
|
||||
|
||||
wire hdmi_cs_osd;
|
||||
csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd);
|
||||
@@ -930,12 +1037,16 @@ always @(posedge clk_vid) begin
|
||||
end
|
||||
|
||||
wire hdmi_tx_clk;
|
||||
`ifndef DEBUG_NOHDMI
|
||||
cyclonev_clkselect hdmi_clk_sw
|
||||
(
|
||||
.clkselect({1'b1, ~vga_fb & direct_video}),
|
||||
.inclk({clk_vid, hdmi_clk_out, 2'b00}),
|
||||
.outclk(hdmi_tx_clk)
|
||||
);
|
||||
`else
|
||||
assign hdmi_tx_clk = clk_vid;
|
||||
`endif
|
||||
|
||||
altddio_out
|
||||
#(
|
||||
@@ -1082,65 +1193,60 @@ end
|
||||
assign SDCD_SPDIF =(SW[3] & ~spdif) ? 1'b0 : 1'bZ;
|
||||
|
||||
`ifndef DUAL_SDRAM
|
||||
wire anl,anr;
|
||||
wire analog_l, analog_r;
|
||||
|
||||
assign AUDIO_SPDIF = SW[3] ? 1'bZ : SW[0] ? HDMI_LRCLK : spdif;
|
||||
assign AUDIO_R = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S : anr;
|
||||
assign AUDIO_L = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK : anl;
|
||||
assign AUDIO_R = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S : analog_r;
|
||||
assign AUDIO_L = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK : analog_l;
|
||||
`endif
|
||||
|
||||
assign HDMI_MCLK = 0;
|
||||
assign HDMI_MCLK = clk_audio;
|
||||
wire clk_audio;
|
||||
|
||||
wire [15:0] audio_l, audio_l_pre;
|
||||
aud_mix_top audmix_l
|
||||
pll_audio pll_audio
|
||||
(
|
||||
.clk(clk_audio),
|
||||
.att(vol_att),
|
||||
.mix(audio_mix),
|
||||
.is_signed(audio_s),
|
||||
|
||||
.core_audio(audio_ls),
|
||||
.pre_in(audio_r_pre),
|
||||
.linux_audio(alsa_l),
|
||||
|
||||
.pre_out(audio_l_pre),
|
||||
.out(audio_l)
|
||||
);
|
||||
|
||||
wire [15:0] audio_r, audio_r_pre;
|
||||
aud_mix_top audmix_r
|
||||
(
|
||||
.clk(clk_audio),
|
||||
.att(vol_att),
|
||||
.mix(audio_mix),
|
||||
.is_signed(audio_s),
|
||||
|
||||
.core_audio(audio_rs),
|
||||
.pre_in(audio_l_pre),
|
||||
.linux_audio(alsa_r),
|
||||
|
||||
.pre_out(audio_r_pre),
|
||||
.out(audio_r)
|
||||
.refclk(FPGA_CLK3_50),
|
||||
.rst(0),
|
||||
.outclk_0(clk_audio)
|
||||
);
|
||||
|
||||
wire spdif;
|
||||
audio_out audio_out
|
||||
(
|
||||
.reset(reset),
|
||||
.reset(reset | areset),
|
||||
.clk(clk_audio),
|
||||
|
||||
.att(vol_att),
|
||||
.mix(audio_mix),
|
||||
.sample_rate(audio_96k),
|
||||
.left_in(audio_l),
|
||||
.right_in(audio_r),
|
||||
|
||||
.flt_rate(aflt_rate),
|
||||
.cx(acx),
|
||||
.cx0(acx0),
|
||||
.cx1(acx1),
|
||||
.cx2(acx2),
|
||||
.cy0(acy0),
|
||||
.cy1(acy1),
|
||||
.cy2(acy2),
|
||||
|
||||
.is_signed(audio_s),
|
||||
.core_l(audio_l),
|
||||
.core_r(audio_r),
|
||||
|
||||
.alsa_l(alsa_l),
|
||||
.alsa_r(alsa_r),
|
||||
|
||||
.i2s_bclk(HDMI_SCLK),
|
||||
.i2s_lrclk(HDMI_LRCLK),
|
||||
.i2s_data(HDMI_I2S),
|
||||
`ifndef DUAL_SDRAM
|
||||
.dac_l(anl),
|
||||
.dac_r(anr),
|
||||
.dac_l(analog_l),
|
||||
.dac_r(analog_r),
|
||||
`endif
|
||||
.spdif(spdif)
|
||||
);
|
||||
|
||||
|
||||
wire [28:0] alsa_address;
|
||||
wire [63:0] alsa_readdata;
|
||||
wire alsa_ready;
|
||||
@@ -1168,7 +1274,6 @@ alsa alsa
|
||||
.pcm_r(alsa_r)
|
||||
);
|
||||
|
||||
|
||||
//////////////// User I/O (USB 3.0 connector) /////////////////////////
|
||||
|
||||
assign USER_IO[0] = !user_out[0] ? 1'b0 : 1'bZ;
|
||||
@@ -1191,7 +1296,7 @@ assign user_in[6] = USER_IO[6];
|
||||
/////////////////// User module connection ////////////////////////////
|
||||
|
||||
wire clk_sys;
|
||||
wire [15:0] audio_ls, audio_rs;
|
||||
wire [15:0] audio_l, audio_r;
|
||||
wire audio_s;
|
||||
wire [1:0] audio_mix;
|
||||
wire [1:0] scanlines;
|
||||
@@ -1227,24 +1332,20 @@ wire [6:0] user_out, user_in;
|
||||
assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = {39'bZ};
|
||||
`endif
|
||||
|
||||
`ifdef ARCADE_SYS
|
||||
wire hvs_emu, hhs_emu;
|
||||
sync_fix hdmi_sync_v(clk_ihdmi, hvs_emu, hvs_fix);
|
||||
sync_fix hdmi_sync_h(clk_ihdmi, hhs_emu, hhs_fix);
|
||||
assign clk_ihdmi= clk_vid;
|
||||
assign ce_hpix = ce_pix;
|
||||
assign hr_out = r_out;
|
||||
assign hg_out = g_out;
|
||||
assign hb_out = b_out;
|
||||
assign hhs_fix = hs_fix;
|
||||
assign hvs_fix = vs_fix;
|
||||
assign hde_emu = de_emu;
|
||||
|
||||
`ifdef ARCADE_SYS
|
||||
assign audio_mix = 0;
|
||||
assign {ADC_SCK, ADC_SDI, ADC_CONVST} = 0;
|
||||
assign btn = 0;
|
||||
`else
|
||||
assign clk_ihdmi= clk_vid;
|
||||
assign ce_hpix = ce_pix;
|
||||
assign hr_out = r_out;
|
||||
assign hg_out = g_out;
|
||||
assign hb_out = b_out;
|
||||
assign hhs_fix = hs_fix;
|
||||
assign hvs_fix = vs_fix;
|
||||
assign hde_emu = de_emu;
|
||||
|
||||
wire uart_dtr;
|
||||
wire uart_dsr;
|
||||
wire uart_cts;
|
||||
@@ -1254,6 +1355,19 @@ assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQM
|
||||
wire osd_status;
|
||||
`endif
|
||||
|
||||
wire fb_en;
|
||||
wire [4:0] fb_fmt;
|
||||
wire [11:0] fb_width;
|
||||
wire [11:0] fb_height;
|
||||
wire [31:0] fb_base;
|
||||
|
||||
`ifndef USE_FB
|
||||
assign fb_en = 0;
|
||||
assign fb_fmt = 0;
|
||||
assign fb_width = 0;
|
||||
assign fb_height = 0;
|
||||
assign fb_base = 0;
|
||||
`endif
|
||||
|
||||
emu emu
|
||||
(
|
||||
@@ -1269,39 +1383,36 @@ emu emu
|
||||
.VGA_DE(de_emu),
|
||||
.VGA_F1(f1),
|
||||
|
||||
`ifdef ARCADE_SYS
|
||||
.VGA_CLK(clk_vid),
|
||||
.VGA_CE(ce_pix),
|
||||
.HDMI_CLK(clk_ihdmi),
|
||||
.HDMI_CE(ce_hpix),
|
||||
.HDMI_R(hr_out),
|
||||
.HDMI_G(hg_out),
|
||||
.HDMI_B(hb_out),
|
||||
.HDMI_HS(hhs_emu),
|
||||
.HDMI_VS(hvs_emu),
|
||||
.HDMI_DE(hde_emu),
|
||||
.HDMI_SL(scanlines),
|
||||
.HDMI_ARX(ARX),
|
||||
.HDMI_ARY(ARY),
|
||||
`else
|
||||
.CLK_VIDEO(clk_vid),
|
||||
.CE_PIXEL(ce_pix),
|
||||
.VGA_SL(scanlines),
|
||||
.VIDEO_ARX(ARX),
|
||||
.VIDEO_ARY(ARY),
|
||||
|
||||
.AUDIO_MIX(audio_mix),
|
||||
.ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}),
|
||||
`ifdef USE_FB
|
||||
.FB_EN(fb_en),
|
||||
.FB_FORMAT(fb_fmt),
|
||||
.FB_WIDTH(fb_width),
|
||||
.FB_HEIGHT(fb_height),
|
||||
.FB_BASE(fb_base),
|
||||
.FB_VBL(fb_vbl),
|
||||
.FB_LL(lowlat),
|
||||
`endif
|
||||
|
||||
.LED_USER(led_user),
|
||||
.LED_POWER(led_power),
|
||||
.LED_DISK(led_disk),
|
||||
|
||||
.AUDIO_L(audio_ls),
|
||||
.AUDIO_R(audio_rs),
|
||||
.CLK_AUDIO(clk_audio),
|
||||
.AUDIO_L(audio_l),
|
||||
.AUDIO_R(audio_r),
|
||||
.AUDIO_S(audio_s),
|
||||
|
||||
`ifndef ARCADE_SYS
|
||||
.AUDIO_MIX(audio_mix),
|
||||
.ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}),
|
||||
`endif
|
||||
|
||||
`ifdef USE_DDRAM
|
||||
.DDRAM_CLK(ram_clk),
|
||||
.DDRAM_ADDR(ram_address),
|
||||
@@ -1401,56 +1512,6 @@ endmodule
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
module aud_mix_top
|
||||
(
|
||||
input clk,
|
||||
|
||||
input [4:0] att,
|
||||
input [1:0] mix,
|
||||
input is_signed,
|
||||
|
||||
input [15:0] core_audio,
|
||||
input [15:0] linux_audio,
|
||||
input [15:0] pre_in,
|
||||
|
||||
output reg [15:0] pre_out,
|
||||
output reg [15:0] out
|
||||
);
|
||||
|
||||
reg [15:0] ca;
|
||||
always @(posedge clk) begin
|
||||
reg [15:0] d1,d2,d3;
|
||||
|
||||
d1 <= core_audio; d2<=d1; d3<=d2;
|
||||
if(d2 == d3) ca <= d2;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg signed [16:0] a1, a2, a3, a4;
|
||||
|
||||
a1 <= is_signed ? {ca[15],ca} : {2'b00,ca[15:1]};
|
||||
a2 <= a1 + {linux_audio[15],linux_audio};
|
||||
|
||||
pre_out <= a2[16:1];
|
||||
|
||||
case(mix)
|
||||
0: a3 <= a2;
|
||||
1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]);
|
||||
2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]);
|
||||
3: a3 <= {a2[16],a2[16:1]} + {pre_in[15],pre_in};
|
||||
endcase
|
||||
|
||||
if(att[4]) a4 <= 0;
|
||||
else a4 <= a3 >>> att[3:0];
|
||||
|
||||
//clamping
|
||||
out <= ^a4[16:15] ? {a4[16],{15{a4[15]}}} : a4[15:0];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CSync generation
|
||||
// Shifts HSync left by 1 HSync period during VSync
|
||||
|
||||
|
||||
Reference in New Issue
Block a user