diff --git a/ZX-Spectrum.qsf b/ZX-Spectrum.qsf index 7a481c6..7b04cdc 100644 --- a/ZX-Spectrum.qsf +++ b/ZX-Spectrum.qsf @@ -47,8 +47,8 @@ set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON set_global_assignment -name ECO_OPTIMIZE_TIMING ON set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON -set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW -set_global_assignment -name SEED 2 +set_global_assignment -name ALM_REGISTER_PACKING_EFFORT MEDIUM +set_global_assignment -name SEED 1 source sys/sys.tcl source sys/sys_analog.tcl diff --git a/sys/alsa.sv b/sys/alsa.sv index e3aaa50..061a287 100644 --- a/sys/alsa.sv +++ b/sys/alsa.sv @@ -1,7 +1,7 @@ //============================================================================ // // ALSA sound support for MiSTer -// (c)2019 Sorgelig +// (c)2019,2020 Alexey Melnikov // // 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 @@ -22,111 +22,135 @@ module alsa ( input reset, - - output reg en_out, - input en_in, - - input ram_clk, - output reg [28:0] ram_address, - output reg [7:0] ram_burstcount, - input ram_waitrequest, - input [63:0] ram_readdata, - input ram_readdatavalid, - output reg ram_read, + input clk, + + output reg [31:3] ram_address, + input [63:0] ram_data, + output reg ram_req = 0, + input ram_ready, input spi_ss, input spi_sck, input spi_mosi, + output spi_miso, output reg [15:0] pcm_l, output reg [15:0] pcm_r ); -reg spi_new = 0; -reg [127:0] spi_data; +reg [60:0] buf_info; +reg [6:0] spicnt = 0; always @(posedge spi_sck, posedge spi_ss) begin - reg [7:0] mosi; - reg [6:0] spicnt = 0; + reg [95:0] spi_data; if(spi_ss) spicnt <= 0; else begin - mosi <= {mosi[6:0],spi_mosi}; - + spi_data[{spicnt[6:3],~spicnt[2:0]}] <= spi_mosi; + if(&spicnt) buf_info <= {spi_data[82:67],spi_data[50:35],spi_data[31:3]}; spicnt <= spicnt + 1'd1; - if(&spicnt[2:0]) begin - spi_data[{spicnt[6:3],3'b000} +:8] <= {mosi[6:0],spi_mosi}; - spi_new <= &spicnt; - end end end -reg [31:0] buf_addr; -reg [31:0] buf_len; -reg [31:0] buf_wptr = 0; +assign spi_miso = spi_out[{spicnt[4:3],~spicnt[2:0]}]; -always @(posedge ram_clk) begin - reg n1,n2,n3; - reg [127:0] data1,data2; +reg [31:0] spi_out = 0; +always @(posedge clk) if(spi_ss) spi_out <= {buf_rptr, hurryup, 8'h00}; - n1 <= spi_new; - n2 <= n1; - n3 <= n2; - data1 <= spi_data; +reg [31:3] buf_addr; +reg [18:3] buf_len; +reg [18:3] buf_wptr = 0; + +always @(posedge clk) begin + reg [60:0] data1,data2; + + data1 <= buf_info; data2 <= data1; - - if(~n3 & n2) {buf_wptr,buf_len,buf_addr} <= data2[95:0]; + if(data2 == data1) {buf_wptr,buf_len,buf_addr} <= data2; end -reg [31:0] buf_rptr = 0; -always @(posedge ram_clk) begin - reg got_first = 0; - reg ready = 0; - reg ud = 0; - reg [31:0] readdata; +reg [2:0] hurryup = 0; +reg [18:3] buf_rptr = 0; - if(~ram_waitrequest) ram_read <= 0; - if(ram_readdatavalid && ram_burstcount) begin - ram_burstcount <= 0; - ready <= 1; - readdata <= ud ? ram_readdata[63:32] : ram_readdata[31:0]; - if(buf_rptr[31:2] >= buf_len[31:2]) buf_rptr <= 0; - end +always @(posedge clk) begin + reg [18:3] len = 0; + reg [1:0] ready = 0; + reg [63:0] readdata; + reg got_first = 0; + reg [7:0] ce_cnt = 0; + reg [1:0] state = 0; - if(reset) {ready, got_first, ram_burstcount} <= 0; - else - if(buf_rptr[31:2] != buf_wptr[31:2]) begin - if(~got_first) begin - buf_rptr <= buf_wptr; - got_first <= 1; - end - else - if(!ram_burstcount && ~ram_waitrequest && ~ready && en_out == en_in) begin - ram_address <= buf_addr[31:3] + buf_rptr[31:3]; - ud <= buf_rptr[2]; - ram_burstcount <= 1; - ram_read <= 1; - buf_rptr <= buf_rptr + 4; - end + if(reset) begin + ready <= 0; + ce_cnt <= 0; + state <= 0; + got_first <= 0; + len <= 0; end + else begin - if(ready & ce_48k) begin - {pcm_r,pcm_l} <= readdata; - ready <= 0; + //ramp up + if(len[18:14] && (hurryup < 1)) hurryup <= 1; + if(len[18:16] && (hurryup < 2)) hurryup <= 2; + if(len[18:17] && (hurryup < 4)) hurryup <= 4; + + //ramp down + if(!len[18:15] && (hurryup > 2)) hurryup <= 2; + if(!len[18:13] && (hurryup > 1)) hurryup <= 1; + if(!len[18:10]) hurryup <= 0; + + if(ce_sample && ~&ce_cnt) ce_cnt <= ce_cnt + 1'd1; + + case(state) + 0: if(!ce_sample) begin + if(ready) begin + if(ce_cnt) begin + {readdata[31:0],pcm_r,pcm_l} <= readdata; + ready <= ready - 1'd1; + ce_cnt <= ce_cnt - 1'd1; + end + end + else if(buf_rptr != buf_wptr) begin + if(~got_first) begin + buf_rptr <= buf_wptr; + got_first <= 1; + end + else begin + ram_address <= buf_addr + buf_rptr; + ram_req <= ~ram_req; + buf_rptr <= buf_rptr + 1'd1; + len <= (buf_wptr < buf_rptr) ? (buf_len + buf_wptr - buf_rptr) : (buf_wptr - buf_rptr); + state <= 1; + end + end + else begin + len <= 0; + ce_cnt <= 0; + hurryup <= 0; + end + end + 1: if(ram_ready) begin + ready <= 2; + readdata <= ram_data; + if(buf_rptr >= buf_len) buf_rptr <= buf_rptr - buf_len; + state <= 0; + end + endcase end - - if(ce_48k) en_out <= ~en_out; end -reg ce_48k; -always @(posedge ram_clk) begin - reg [15:0] acc = 0; +localparam F48K = 48000; +localparam F50M = 50000000; - ce_48k <= 0; - acc <= acc + 16'd48; - if(acc >= 50000) begin - acc <= acc - 16'd50000; - ce_48k <= 1; +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; + ce_sample <= 1; end end diff --git a/sys/arcade_video.v b/sys/arcade_video.v new file mode 100644 index 0000000..ba86c9b --- /dev/null +++ b/sys/arcade_video.v @@ -0,0 +1,406 @@ +//============================================================================ +// +// 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) +// 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. +//============================================================================ + +// +// 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) +( + input clk, + input ce, + + input ccw, + + input [DEPTH-1:0] video_in, + input hblank, + input vblank, + + input ce_out, + output [DEPTH-1:0] video_out, + output reg hsync, + output reg vsync, + output reg hblank_out, + output reg vblank_out +); + +localparam bufsize = WIDTH*HEIGHT; +localparam memsize = bufsize*2; +localparam aw = $clog2(memsize); // resolutions up to ~ 512x256 + +reg [aw-1:0] addr_in, addr_out; +reg we_in; +reg buff = 0; + +(* 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 [DEPTH-1:0] out; +reg [DEPTH-1:0] vout; + +assign video_out = vout; + +wire en_we = ce & ~blank & en_x & en_y; +wire en_x = (xpos=MARGIN) && (yposo (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 + end + + if(ced) begin + if((yposd=WIDTH+MARGIN)) begin + vout <= 0; + end else begin + vout <= out; + end + if(xposd == 0) hblank_out <= 0; + if(xposd == HEIGHT) hblank_out <= 1; + end +end + +endmodule diff --git a/sys/ascal.vhd b/sys/ascal.vhd index a0ef9cf..0f89a9e 100644 --- a/sys/ascal.vhd +++ b/sys/ascal.vhd @@ -164,9 +164,9 @@ ENTITY ascal IS -- Framebuffer palette in 8bpp mode pal_clk : IN std_logic :='0'; - pal_dw : IN unsigned(23 DOWNTO 0) :=x"000000"; -- R G B - pal_dr : OUT unsigned(23 DOWNTO 0) :=x"000000"; - pal_a : IN unsigned(7 DOWNTO 0) :=x"00"; -- Colour index + pal_dw : IN unsigned(47 DOWNTO 0) :=x"000000000000"; -- R1 G1 B1 R0 G0 B0 + pal_dr : OUT unsigned(47 DOWNTO 0) :=x"000000000000"; + pal_a : IN unsigned(6 DOWNTO 0) :="0000000"; -- Colour index/2 pal_wr : IN std_logic :='0'; ------------------------------------ @@ -283,11 +283,11 @@ ARCHITECTURE rtl OF ascal IS SUBTYPE uint12 IS natural RANGE 0 TO 4095; SUBTYPE uint13 IS natural RANGE 0 TO 8191; - TYPE arr_uv24 IS ARRAY (natural RANGE <>) OF unsigned(23 DOWNTO 0); + TYPE arr_uv48 IS ARRAY (natural RANGE <>) OF unsigned(47 DOWNTO 0); 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,8 +385,11 @@ 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 pal_mem : arr_uv24(0 TO 255); + 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; @@ -2046,10 +2049,11 @@ BEGIN pal_dr<=pal_mem(to_integer(pal_a)); END IF; END PROCESS; - - o_fb_pal_dr<= - pal_mem(to_integer(shift_opack(o_acpt4,o_shift,o_dr,o_format)(0 TO 7))) - 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; GenNoPal:IF NOT PALETTE GENERATE diff --git a/sys/ddr_svc.sv b/sys/ddr_svc.sv new file mode 100644 index 0000000..ed24d4e --- /dev/null +++ b/sys/ddr_svc.sv @@ -0,0 +1,108 @@ +// +// Copyright (c) 2020 Alexey Melnikov +// +// +// This source file 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 3 of the License, or +// (at your option) any later version. +// +// This source file 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, see . +// +// ------------------------------------------ +// + +// 16-bit version + +module ddr_svc +( + input clk, + + input ram_waitrequest, + output [7:0] ram_burstcnt, + output [28:0] ram_addr, + input [63:0] ram_readdata, + input ram_read_ready, + output reg ram_read, + output [63:0] ram_writedata, + output [7:0] ram_byteenable, + output reg ram_write, + + output [7:0] ram_bcnt, + + input [31:3] ch0_addr, + input [7:0] ch0_burst, + output [63:0] ch0_data, + input ch0_req, + output ch0_ready, + + input [31:3] ch1_addr, + input [7:0] ch1_burst, + output [63:0] ch1_data, + input ch1_req, + output ch1_ready +); + +assign ram_burstcnt = ram_burst; +assign ram_byteenable = 8'hFF; +assign ram_addr = ram_address; +assign ram_writedata = 0; + +assign ch0_data = ram_q[0]; +assign ch1_data = ram_q[1]; +assign ch0_ready = ready[0]; +assign ch1_ready = ready[1]; + +reg [7:0] ram_burst; +reg [63:0] ram_q[2]; +reg [31:3] ram_address; +reg [1:0] ack = 0; +reg [1:0] ready; +reg state = 0; +reg ch = 0; + +always @(posedge clk) begin + ready <= 0; + + if(!ram_waitrequest) begin + ram_read <= 0; + ram_write <= 0; + + case(state) + 0: if(ch0_req != ack[0]) begin + ack[0] <= ch0_req; + ram_address <= ch0_addr; + ram_burst <= ch0_burst; + ram_read <= 1; + ch <= 0; + ram_bcnt <= 8'hFF; + state <= 1; + end + else if(ch1_req != ack[1]) begin + ack[1] <= ch1_req; + ram_address <= ch1_addr; + ram_burst <= ch1_burst; + ram_read <= 1; + ch <= 1; + ram_bcnt <= 8'hFF; + state <= 1; + end + 1: begin + if(ram_read_ready) begin + ram_bcnt <= ram_bcnt + 1'd1; + ram_q[ch] <= ram_readdata; + ready[ch] <= 1; + if ((ram_bcnt+2'd2) == ram_burst) state <= 0; + end + end + endcase + end +end + +endmodule diff --git a/sys/fbpal.sv b/sys/fbpal.sv deleted file mode 100644 index 30a7512..0000000 --- a/sys/fbpal.sv +++ /dev/null @@ -1,86 +0,0 @@ -//============================================================================ -// -// Framebuffer Palette support for MiSTer -// (c)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) -// 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 fbpal -( - input reset, - - input en_in, - output reg en_out, - - input ram_clk, - output reg [28:0] ram_address, - output reg [7:0] ram_burstcount, - input ram_waitrequest, - input [63:0] ram_readdata, - input ram_readdatavalid, - output reg ram_read, - - input [31:0] fb_address, - - input pal_en, - output reg [7:0] pal_a, - output reg [23:0] pal_d, - output reg pal_wr -); - -reg [31:0] base_addr; -always @(posedge ram_clk) base_addr <= fb_address - 4096; - -reg [6:0] buf_rptr = 0; -always @(posedge ram_clk) begin - reg [23:0] odd_d; - - if(~pal_a[0] & pal_wr) {pal_a[0], pal_d} <= {1'b1, odd_d}; - else pal_wr <= 0; - - if(~ram_waitrequest) ram_read <= 0; - - if(pal_en & ~reset) begin - if(ram_burstcount) begin - if(ram_readdatavalid) begin - ram_burstcount <= 0; - - odd_d <= ram_readdata[55:32]; - pal_d <= ram_readdata[23:0]; - pal_a <= {buf_rptr, 1'b0}; - pal_wr <= 1; - - en_out <= en_in; - buf_rptr <= buf_rptr + 1'd1; - end - end - else begin - if(~ram_waitrequest && en_out != en_in) begin - ram_address <= base_addr[31:3] + buf_rptr; - ram_burstcount <= 1; - ram_read <= 1; - end - end - end - else begin - en_out <= en_in; - buf_rptr <= 0; - ram_burstcount <= 0; - end -end - -endmodule diff --git a/sys/hps_io.v b/sys/hps_io.v index 9b4fdb8..eab005e 100644 --- a/sys/hps_io.v +++ b/sys/hps_io.v @@ -51,12 +51,16 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0) output [1:0] buttons, output forced_scandoubler, + output direct_video, output reg [63:0] status, input [63:0] status_in, input status_set, input [15:0] status_menumask, + input info_req, + input [7:0] info, + //toggle to force notify of video mode change input new_vmode, @@ -151,12 +155,13 @@ assign HPS_BUS[36] = clk_sys; assign HPS_BUS[32] = io_wide; assign HPS_BUS[15:0] = io_dout; -reg [7:0] cfg; +reg [15:0] cfg; assign buttons = cfg[1:0]; //cfg[2] - vga_scaler handled in sys_top //cfg[3] - csync handled in sys_top assign forced_scandoubler = cfg[4]; //cfg[5] - ypbpr handled in sys_top +assign direct_video = cfg[10]; // command byte read by the io controller wire [15:0] sd_cmd = @@ -182,6 +187,7 @@ video_calc video_calc ( .clk_100(HPS_BUS[43]), .clk_vid(HPS_BUS[42]), + .clk_sys(clk_sys), .ce_pix(HPS_BUS[41]), .de(HPS_BUS[40]), .hs(HPS_BUS[39]), @@ -218,6 +224,8 @@ always@(posedge clk_sys) begin reg old_status_set = 0; reg [7:0] cd_req = 0; reg old_cd = 0; + reg old_info = 0; + reg [7:0] info_n = 0; old_status_set <= status_set; if(~old_status_set & status_set) begin @@ -225,6 +233,9 @@ always@(posedge clk_sys) begin status_req <= status_in; end + old_info <= info_req; + if(~old_info & info_req) info_n <= info; + old_cd <= cd_in[48]; if(old_cd ^ cd_in[48]) cd_req <= cd_req + 1'd1; @@ -271,6 +282,7 @@ always@(posedge clk_sys) begin 'h2F: io_dout <= 1; 'h32: io_dout <= gamma_bus[21]; 'h34: io_dout <= cd_req; + 'h36: begin io_dout <= info_n; info_n <= 0; end endcase sd_buff_addr <= 0; @@ -280,7 +292,7 @@ always@(posedge clk_sys) begin case(cmd) // buttons and switches - 'h01: cfg <= io_din[7:0]; + 'h01: cfg <= io_din; 'h02: if(byte_cnt==1) joystick_0[15:0] <= io_din; else joystick_0[31:16] <= io_din; 'h03: if(byte_cnt==1) joystick_1[15:0] <= io_din; else joystick_1[31:16] <= io_din; 'h10: if(byte_cnt==1) joystick_2[15:0] <= io_din; else joystick_2[31:16] <= io_din; @@ -452,7 +464,7 @@ end generate if(PS2DIV) begin reg clk_ps2; - always @(negedge clk_sys) begin + always @(posedge clk_sys) begin integer cnt; cnt <= cnt + 1'd1; if(cnt == PS2DIV) begin @@ -731,6 +743,8 @@ module video_calc ( input clk_100, input clk_vid, + input clk_sys, + input ce_pix, input de, input hs, @@ -743,22 +757,22 @@ module video_calc output reg [15:0] dout ); -always @(*) begin +always @(posedge clk_sys) begin case(par_num) - 1: dout = {|vid_int, vid_nres}; - 2: dout = vid_hcnt[15:0]; - 3: dout = vid_hcnt[31:16]; - 4: dout = vid_vcnt[15:0]; - 5: dout = vid_vcnt[31:16]; - 6: dout = vid_htime[15:0]; - 7: dout = vid_htime[31:16]; - 8: dout = vid_vtime[15:0]; - 9: dout = vid_vtime[31:16]; - 10: dout = vid_pix[15:0]; - 11: dout = vid_pix[31:16]; - 12: dout = vid_vtime_hdmi[15:0]; - 13: dout = vid_vtime_hdmi[31:16]; - default dout = 0; + 1: dout <= {|vid_int, vid_nres}; + 2: dout <= vid_hcnt[15:0]; + 3: dout <= vid_hcnt[31:16]; + 4: dout <= vid_vcnt[15:0]; + 5: dout <= vid_vcnt[31:16]; + 6: dout <= vid_htime[15:0]; + 7: dout <= vid_htime[31:16]; + 8: dout <= vid_vtime[15:0]; + 9: dout <= vid_vtime[31:16]; + 10: dout <= vid_pix[15:0]; + 11: dout <= vid_pix[31:16]; + 12: dout <= vid_vtime_hdmi[15:0]; + 13: dout <= vid_vtime_hdmi[31:16]; + default dout <= 0; endcase end diff --git a/sys/sys.qip b/sys/sys.qip index 1591959..3a594df 100644 --- a/sys/sys.qip +++ b/sys/sys.qip @@ -3,13 +3,13 @@ set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) s set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) fbpal.sv ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) gamma_corr.sv ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ] @@ -21,6 +21,7 @@ set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) l 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 VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ] diff --git a/sys/sys.tcl b/sys/sys.tcl index 4a96f46..c12cfee 100644 --- a/sys/sys.tcl +++ b/sys/sys.tcl @@ -218,7 +218,6 @@ set_location_assignment PIN_W20 -to SW[3] set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sys_top -to uart -set_location_assignment FRACTIONALPLL_X89_Y1_N0 -to emu:emu|pll:pll|pll_0002:pll_inst|altera_pll:altera_pll_i|altera_cyclonev_pll:cyclonev_pll|altera_cyclonev_pll_base:fpll_0|fpll set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl" diff --git a/sys/sys_top.v b/sys/sys_top.v index 6997370..1c5c38b 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -1,7 +1,7 @@ //============================================================================ // // MiSTer hardware abstraction module -// (c)2017-2019 Alexey Melnikov +// (c)2017-2020 Alexey Melnikov // // 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 @@ -19,6 +19,11 @@ // //============================================================================ +`ifndef ARCADE_SYS + `define USE_DDRAM + `define USE_SDRAM +`endif + module sys_top ( /////////// CLOCK ////////// @@ -125,25 +130,33 @@ module sys_top ); ////////////////////// Secondary SD /////////////////////////////////// +wire SD_CS, SD_CLK, SD_MOSI; -wire sd_miso; -wire SD_CS, SD_CLK, SD_MOSI, SD_MISO; +`ifdef ARCADE_SYS + assign SD_CS = 1'bZ; + assign SD_CLK = 1'bZ; + assign SD_MOSI = 1'bZ; +`else + `ifndef DUAL_SDRAM + wire sd_miso = SW[3] | SDIO_DAT[0]; + `else + wire sd_miso = 1; + `endif + wire SD_MISO = mcp_sdcd ? sd_miso : SD_SPI_MISO; +`endif `ifndef DUAL_SDRAM assign SDIO_DAT[2:1]= 2'bZZ; assign SDIO_DAT[3] = SW[3] ? 1'bZ : SD_CS; assign SDIO_CLK = SW[3] ? 1'bZ : SD_CLK; assign SDIO_CMD = SW[3] ? 1'bZ : SD_MOSI; - assign sd_miso = SW[3] ? 1'b1 : SDIO_DAT[0]; assign SD_SPI_CS = mcp_sdcd ? ((~VGA_EN & sog & ~cs1) ? 1'b1 : 1'bZ) : SD_CS; `else - assign sd_miso = 1'b1; assign SD_SPI_CS = mcp_sdcd ? 1'bZ : SD_CS; `endif -assign SD_SPI_CLK = mcp_sdcd ? 1'bZ : SD_CLK; -assign SD_SPI_MOSI = mcp_sdcd ? 1'bZ : SD_MOSI; -assign SD_MISO = mcp_sdcd ? sd_miso : SD_SPI_MISO; +assign SD_SPI_CLK = mcp_sdcd ? 1'bZ : SD_CLK; +assign SD_SPI_MOSI = mcp_sdcd ? 1'bZ : SD_MOSI; ////////////////////// LEDs/Buttons /////////////////////////////////// @@ -266,6 +279,7 @@ 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]}; wire direct_video = cfg[10]; wire dvi_mode = cfg[7]; @@ -395,7 +409,9 @@ end cyclonev_hps_interface_peripheral_uart uart ( - .ri(0), + .ri(0) +`ifndef ARCADE_SYS + , .dsr(uart_dsr), .dcd(uart_dsr), .dtr(uart_dtr), @@ -404,14 +420,15 @@ cyclonev_hps_interface_peripheral_uart uart .rts(uart_rts), .rxd(uart_rxd), .txd(uart_txd) +`endif ); -wire aspi_sck,aspi_mosi,aspi_ss; +wire aspi_sck,aspi_mosi,aspi_ss,aspi_miso; cyclonev_hps_interface_peripheral_spi_master spi ( .sclk_out(aspi_sck), .txd(aspi_mosi), // mosi - .rxd(1), // miso + .rxd(aspi_miso), // miso .ss_0_n(aspi_ss), .ss_in_n(1) @@ -461,6 +478,7 @@ sysmem_lite sysmem //DE10-nano has no reset signal on GPIO, so core has to emulate cold reset button. .reset_hps_cold_req(btn_r), +`ifdef USE_DDRAM //64-bit DDR3 RAM access .ram1_clk(ram_clk), .ram1_address(ram_address), @@ -472,18 +490,19 @@ sysmem_lite sysmem .ram1_writedata(ram_writedata), .ram1_byteenable(ram_byteenable), .ram1_write(ram_write), +`endif //64-bit DDR3 RAM access .ram2_clk(clk_audio), - .ram2_address((ap_en1 == ap_en2) ? aram_address : pram_address), - .ram2_burstcount((ap_en1 == ap_en2) ? aram_burstcount : pram_burstcount), - .ram2_waitrequest(aram_waitrequest), - .ram2_readdata(aram_readdata), - .ram2_readdatavalid(aram_readdatavalid), - .ram2_read((ap_en1 == ap_en2) ? aram_read : pram_read), - .ram2_writedata(0), - .ram2_byteenable(8'hFF), - .ram2_write(0), + .ram2_address(ram2_address), + .ram2_burstcount(ram2_burstcount), + .ram2_waitrequest(ram2_waitrequest), + .ram2_readdata(ram2_readdata), + .ram2_readdatavalid(ram2_readdatavalid), + .ram2_read(ram2_read), + .ram2_writedata(ram2_writedata), + .ram2_byteenable(ram2_byteenable), + .ram2_write(ram2_write), //128-bit DDR3 RAM access // HDMI frame buffer @@ -499,6 +518,46 @@ sysmem_lite sysmem .vbuf_read(vbuf_read) ); +wire [28:0] ram2_address; +wire [7:0] ram2_burstcount; +wire [7:0] ram2_byteenable; +wire ram2_waitrequest; +wire [63:0] ram2_readdata; +wire [63:0] ram2_writedata; +wire ram2_readdatavalid; +wire ram2_read; +wire ram2_write; +wire [7:0] ram2_bcnt; + +ddr_svc ddr_svc +( + .clk(clk_audio), + + .ram_waitrequest(ram2_waitrequest), + .ram_burstcnt(ram2_burstcount), + .ram_addr(ram2_address), + .ram_readdata(ram2_readdata), + .ram_read_ready(ram2_readdatavalid), + .ram_read(ram2_read), + .ram_writedata(ram2_writedata), + .ram_byteenable(ram2_byteenable), + .ram_write(ram2_write), + .ram_bcnt(ram2_bcnt), + + .ch0_addr(alsa_address), + .ch0_burst(1), + .ch0_data(alsa_readdata), + .ch0_req(alsa_req), + .ch0_ready(alsa_ready), + + .ch1_addr(pal_addr), + .ch1_burst(128), + .ch1_data(pal_data), + .ch1_req(pal_req), + .ch1_ready(pal_wr) +); + + wire [27:0] vbuf_address; wire [7:0] vbuf_burstcount; wire vbuf_waitrequest; @@ -524,15 +583,15 @@ ascal .run (1), .freeze (0), - .i_clk (clk_vid), - .i_ce (ce_pix), - .i_r (r_out), - .i_g (g_out), - .i_b (b_out), - .i_hs (hs_fix), - .i_vs (vs_fix), + .i_clk (clk_ihdmi), + .i_ce (ce_hpix), + .i_r (hr_out), + .i_g (hg_out), + .i_b (hb_out), + .i_hs (hhs_fix), + .i_vs (hvs_fix), .i_fl (f1), - .i_de (de_emu), + .i_de (hde_emu), .iauto (1), .himin (0), .himax (0), @@ -668,37 +727,21 @@ pll_hdmi_adj pll_hdmi_adj .o_writedata(cfg_data) ); -wire [23:0] pal_d; -wire [7:0] pal_a; +wire [63:0] pal_data; +wire [47:0] pal_d = {pal_data[55:32], pal_data[23:0]}; +wire [6:0] pal_a = ram2_bcnt[6:0]; wire pal_wr; -wire ap_en1, ap_en2; +reg [28:0] pal_addr; +reg pal_req = 0; +always @(posedge clk_pal) begin + reg old_vs; -wire [28:0] pram_address; -wire [7:0] pram_burstcount; -wire pram_read; + pal_addr <= FB_BASE[31:3] - 29'd512; -fbpal fbpal -( - .reset(reset), - .en_in(ap_en2), - .en_out(ap_en1), - - .ram_clk(clk_pal), - .ram_address(pram_address), - .ram_burstcount(pram_burstcount), - .ram_waitrequest(aram_waitrequest), - .ram_readdata(aram_readdata), - .ram_readdatavalid(aram_readdatavalid), - .ram_read(pram_read), - - .fb_address(FB_BASE), - - .pal_en(~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN), - .pal_a(pal_a), - .pal_d(pal_d), - .pal_wr(pal_wr) -); + old_vs <= hdmi_vs; + if(~old_vs & hdmi_vs & ~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN) pal_req <= ~pal_req; +end ///////////////////////// HDMI output ///////////////////////////////// @@ -830,11 +873,16 @@ osd hdmi_osd .dout(hdmi_data_osd), .hs_out(hdmi_hs_osd), .vs_out(hdmi_vs_osd), - .de_out(hdmi_de_osd), - + .de_out(hdmi_de_osd) +`ifndef ARCADE_SYS + , .osd_status(osd_status) +`endif ); +wire hdmi_cs_osd; +csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd); + reg [23:0] dv_data; reg dv_hs, dv_vs, dv_de; always @(posedge clk_vid) begin @@ -879,7 +927,7 @@ end wire hdmi_tx_clk; cyclonev_clkselect hdmi_clk_sw ( - .clkselect({1'b1, direct_video}), + .clkselect({1'b1, ~vga_fb & direct_video}), .inclk({clk_vid, hdmi_clk_out, 2'b00}), .outclk(hdmi_tx_clk) ); @@ -918,10 +966,10 @@ always @(posedge hdmi_tx_clk) begin reg hs,vs,de; reg [23:0] d; - hs <= direct_video ? dv_hs : hdmi_hs_osd; - vs <= direct_video ? dv_vs : hdmi_vs_osd; - de <= direct_video ? dv_de : hdmi_de_osd; - d <= direct_video ? dv_data : hdmi_data_osd; + hs <= (~vga_fb & direct_video) ? dv_hs : (direct_video & csync_en) ? hdmi_cs_osd : hdmi_hs_osd; + vs <= (~vga_fb & direct_video) ? dv_vs : hdmi_vs_osd; + de <= (~vga_fb & direct_video) ? dv_de : hdmi_de_osd; + d <= (~vga_fb & direct_video) ? dv_data : hdmi_data_osd; hdmi_out_hs <= hs; hdmi_out_vs <= vs; @@ -985,15 +1033,12 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd); .ypbpr_full(0), .ypbpr_en(ypbpr_en), .dout(vga_o), - .din(vga_scaler ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd) + .din((vga_fb | vga_scaler) ? {24{hdmi_de_osd}} & hdmi_data_osd : vga_data_osd) ); - wire hdmi_cs_osd; - csync csync_hdmi(clk_hdmi, hdmi_hs_osd, hdmi_vs_osd, hdmi_cs_osd); - - wire vs1 = vga_scaler ? hdmi_vs_osd : vga_vs_osd; - wire hs1 = vga_scaler ? hdmi_hs_osd : vga_hs_osd; - wire cs1 = vga_scaler ? hdmi_cs_osd : vga_cs_osd; + wire vs1 = (vga_fb | vga_scaler) ? hdmi_vs_osd : vga_vs_osd; + wire hs1 = (vga_fb | vga_scaler) ? hdmi_hs_osd : vga_hs_osd; + wire cs1 = (vga_fb | vga_scaler) ? hdmi_cs_osd : vga_cs_osd; assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : csync_en ? 1'b1 : ~vs1; assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : csync_en ? ~cs1 : ~hs1; @@ -1066,32 +1111,28 @@ audio_out audio_out .spdif(spdif) ); -wire [28:0] aram_address; -wire [7:0] aram_burstcount; -wire aram_waitrequest; -wire [63:0] aram_readdata; -wire aram_readdatavalid; -wire aram_read; +wire [28:0] alsa_address; +wire [63:0] alsa_readdata; +wire alsa_ready; +wire alsa_req; +wire alsa_late; wire [15:0] alsa_l, alsa_r; alsa alsa ( .reset(reset), - .en_in(ap_en1), - .en_out(ap_en2), + .clk(clk_audio), - .ram_clk(clk_audio), - .ram_address(aram_address), - .ram_burstcount(aram_burstcount), - .ram_waitrequest(aram_waitrequest), - .ram_readdata(aram_readdata), - .ram_readdatavalid(aram_readdatavalid), - .ram_read(aram_read), + .ram_address(alsa_address), + .ram_data(alsa_readdata), + .ram_req(alsa_req), + .ram_ready(alsa_ready), .spi_ss(aspi_ss), .spi_sck(aspi_sck), .spi_mosi(aspi_mosi), + .spi_miso(aspi_miso), .pcm_l(alsa_l), .pcm_r(alsa_r) @@ -1119,52 +1160,76 @@ assign user_in[6] = USER_IO[6]; /////////////////// User module connection //////////////////////////// +wire clk_sys; wire [15:0] audio_ls, audio_rs; wire audio_s; wire [1:0] audio_mix; -wire [7:0] r_out, g_out, b_out; -wire vs_fix, hs_fix, de_emu, f1; wire [1:0] scanlines; -wire clk_sys, clk_vid, ce_pix; +wire [7:0] r_out, g_out, b_out, hr_out, hg_out, hb_out; +wire vs_fix, hs_fix, de_emu, vs_emu, hs_emu, f1; +wire hvs_fix, hhs_fix, hde_emu; +wire clk_vid, ce_pix, clk_ihdmi, ce_hpix; -wire ram_clk; -wire [28:0] ram_address; -wire [7:0] ram_burstcount; -wire ram_waitrequest; -wire [63:0] ram_readdata; -wire ram_readdatavalid; -wire ram_read; -wire [63:0] ram_writedata; -wire [7:0] ram_byteenable; -wire ram_write; +`ifdef USE_DDRAM + wire ram_clk; + wire [28:0] ram_address; + wire [7:0] ram_burstcount; + wire ram_waitrequest; + wire [63:0] ram_readdata; + wire ram_readdatavalid; + wire ram_read; + wire [63:0] ram_writedata; + wire [7:0] ram_byteenable; + wire ram_write; +`endif wire led_user; wire [1:0] led_power; wire [1:0] led_disk; wire [1:0] btn; -wire vs_emu, hs_emu; sync_fix sync_v(clk_vid, vs_emu, vs_fix); sync_fix sync_h(clk_vid, hs_emu, hs_fix); -wire uart_dtr; -wire uart_dsr; -wire uart_cts; -wire uart_rts; -wire uart_rxd; -wire uart_txd; -wire osd_status; - wire [6:0] user_out, user_in; +`ifndef USE_SDRAM +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 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; + wire uart_rts; + wire uart_rxd; + wire uart_txd; + wire osd_status; +`endif + + emu emu ( .CLK_50M(FPGA_CLK2_50), .RESET(reset), - .HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_vid, ce_pix, de_emu, hs_fix, vs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}), - - .CLK_VIDEO(clk_vid), - .CE_PIXEL(ce_pix), + .HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_ihdmi, ce_hpix, hde_emu, hhs_fix, hvs_fix, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}), .VGA_R(r_out), .VGA_G(g_out), @@ -1173,23 +1238,41 @@ emu emu .VGA_VS(vs_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}), +`endif .LED_USER(led_user), .LED_POWER(led_power), .LED_DISK(led_disk), - .BUTTONS(btn), - - .VIDEO_ARX(ARX), - .VIDEO_ARY(ARY), .AUDIO_L(audio_ls), .AUDIO_R(audio_rs), .AUDIO_S(audio_s), - .AUDIO_MIX(audio_mix), - - .ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}), +`ifdef USE_DDRAM .DDRAM_CLK(ram_clk), .DDRAM_ADDR(ram_address), .DDRAM_BURSTCNT(ram_burstcount), @@ -1200,7 +1283,9 @@ emu emu .DDRAM_DIN(ram_writedata), .DDRAM_BE(ram_byteenable), .DDRAM_WE(ram_write), +`endif +`ifdef USE_SDRAM .SDRAM_DQ(SDRAM_DQ), .SDRAM_A(SDRAM_A), .SDRAM_DQML(SDRAM_DQML), @@ -1212,6 +1297,7 @@ emu emu .SDRAM_nCAS(SDRAM_nCAS), .SDRAM_CLK(SDRAM_CLK), .SDRAM_CKE(SDRAM_CKE), +`endif `ifdef DUAL_SDRAM .SDRAM2_DQ(SDRAM2_DQ), @@ -1225,6 +1311,9 @@ emu emu .SDRAM2_EN(SW[3]), `endif +`ifndef ARCADE_SYS + .BUTTONS(btn), + .OSD_STATUS(osd_status), .SD_SCK(SD_CLK), .SD_MOSI(SD_MOSI), .SD_MISO(SD_MISO), @@ -1241,11 +1330,10 @@ emu emu .UART_TXD(uart_rxd), .UART_DTR(uart_dsr), .UART_DSR(uart_dtr), +`endif .USER_OUT(user_out), - .USER_IN(user_in), - - .OSD_STATUS(osd_status) + .USER_IN(user_in) ); endmodule