diff --git a/TSConf.sv b/TSConf.sv
index eefae4d..91bcaff 100644
--- a/TSConf.sv
+++ b/TSConf.sv
@@ -188,8 +188,7 @@ pll pll
(
.refclk(CLK_50M),
.outclk_0(clk_sys),
- .outclk_1(SDRAM_CLK),
- .outclk_2(clk_vid)
+ .outclk_1(clk_vid)
);
reg ce_28m;
@@ -213,6 +212,7 @@ wire [24:0] ps2_mouse;
wire [10:0] ps2_key;
wire forced_scandoubler;
+wire [21:0] gamma_bus;
wire [31:0] sd_lba;
wire sd_rd;
@@ -249,6 +249,7 @@ hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io
.buttons(buttons),
.status(status),
.forced_scandoubler(forced_scandoubler),
+ .gamma_bus(gamma_bus),
.RTC(RTC),
@@ -299,6 +300,7 @@ tsconf tsconf
.SDRAM_nRAS(SDRAM_nRAS),
.SDRAM_CKE(SDRAM_CKE),
.SDRAM_nCS(SDRAM_nCS),
+ .SDRAM_CLK(SDRAM_CLK),
.VGA_R(R),
.VGA_G(G),
@@ -393,10 +395,9 @@ end
wire [1:0] scale = status[2:1];
assign VGA_SL = {scale == 3, scale == 2};
-video_mixer video_mixer
+video_mixer #(.GAMMA(1)) video_mixer
(
.*,
- .clk_sys(clk_vid),
.ce_pix_out(CE_PIXEL),
.scanlines(0),
diff --git a/files.qip b/files.qip
index 82d365c..060f82a 100644
--- a/files.qip
+++ b/files.qip
@@ -1,36 +1,36 @@
-set_global_assignment -name QIP_FILE src/t80/T80.qip
-set_global_assignment -name VERILOG_FILE src/memory/dma.v
-set_global_assignment -name VERILOG_FILE src/memory/arbiter.v
-set_global_assignment -name QIP_FILE src/memory/sdram.qip
-set_global_assignment -name SYSTEMVERILOG_FILE src/memory/ddram.sv
-set_global_assignment -name VERILOG_FILE src/memory/dpram.v
-set_global_assignment -name VERILOG_FILE src/common/zsignals.v
-set_global_assignment -name VERILOG_FILE src/common/zports.v
-set_global_assignment -name VERILOG_FILE src/common/zmem.v
-set_global_assignment -name VERILOG_FILE src/common/zmaps.v
-set_global_assignment -name VERILOG_FILE src/common/zint.v
-set_global_assignment -name VERILOG_FILE src/common/zclock.v
-set_global_assignment -name VERILOG_FILE src/rtc/mc146818a.v
-set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd
-set_global_assignment -name QIP_FILE src/sound/jt12/jt12.qip
-set_global_assignment -name SYSTEMVERILOG_FILE src/sound/ym2149.sv
-set_global_assignment -name SYSTEMVERILOG_FILE src/sound/ym2203.sv
-set_global_assignment -name SYSTEMVERILOG_FILE src/sound/turbosound.sv
-set_global_assignment -name VERILOG_FILE src/sound/gs.v
-set_global_assignment -name SYSTEMVERILOG_FILE src/sound/saa1099.sv
-set_global_assignment -name SYSTEMVERILOG_FILE src/sound/compressor.sv
-set_global_assignment -name VERILOG_FILE src/video/video_ts_render.v
-set_global_assignment -name VERILOG_FILE src/video/video_ts.v
-set_global_assignment -name VERILOG_FILE src/video/video_sync.v
-set_global_assignment -name VERILOG_FILE src/video/video_render.v
-set_global_assignment -name VERILOG_FILE src/video/video_ports.v
-set_global_assignment -name VERILOG_FILE src/video/video_out.v
-set_global_assignment -name VERILOG_FILE src/video/video_mode.v
-set_global_assignment -name VERILOG_FILE src/video/video_fetch.v
-set_global_assignment -name VERILOG_FILE src/video/video_top.v
-set_global_assignment -name VHDL_FILE src/keyboard.vhd
-set_global_assignment -name VERILOG_FILE src/kempston_mouse.v
-set_global_assignment -name VERILOG_FILE src/spi.v
-set_global_assignment -name VERILOG_FILE src/clock.v
-set_global_assignment -name VERILOG_FILE src/tsconf.v
+set_global_assignment -name QIP_FILE rtl/T80/T80.qip
+set_global_assignment -name VERILOG_FILE rtl/memory/dma.v
+set_global_assignment -name VERILOG_FILE rtl/memory/arbiter.v
+set_global_assignment -name VERILOG_FILE rtl/memory/sdram.v
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/memory/ddram.sv
+set_global_assignment -name VERILOG_FILE rtl/memory/dpram.v
+set_global_assignment -name VERILOG_FILE rtl/common/zsignals.v
+set_global_assignment -name VERILOG_FILE rtl/common/zports.v
+set_global_assignment -name VERILOG_FILE rtl/common/zmem.v
+set_global_assignment -name VERILOG_FILE rtl/common/zmaps.v
+set_global_assignment -name VERILOG_FILE rtl/common/zint.v
+set_global_assignment -name VERILOG_FILE rtl/common/zclock.v
+set_global_assignment -name VERILOG_FILE rtl/rtc/mc146818a.v
+set_global_assignment -name VHDL_FILE rtl/sound/soundrive.vhd
+set_global_assignment -name QIP_FILE rtl/sound/jt12/jt12.qip
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound/ym2149.sv
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound/ym2203.sv
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound/turbosound.sv
+set_global_assignment -name VERILOG_FILE rtl/sound/gs.v
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound/saa1099.sv
+set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound/compressor.sv
+set_global_assignment -name VERILOG_FILE rtl/video/video_ts_render.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_ts.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_sync.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_render.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_ports.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_out.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_mode.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_fetch.v
+set_global_assignment -name VERILOG_FILE rtl/video/video_top.v
+set_global_assignment -name VHDL_FILE rtl/keyboard.vhd
+set_global_assignment -name VERILOG_FILE rtl/kempston_mouse.v
+set_global_assignment -name VERILOG_FILE rtl/spi.v
+set_global_assignment -name VERILOG_FILE rtl/clock.v
+set_global_assignment -name VERILOG_FILE rtl/tsconf.v
set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv
diff --git a/rtl/T80/T80.qip b/rtl/T80/T80.qip
new file mode 100644
index 0000000..df5c769
--- /dev/null
+++ b/rtl/T80/T80.qip
@@ -0,0 +1,6 @@
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.vhd ]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80pa.vhd ]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vhd ]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ]
diff --git a/src/t80/T80.vhd b/rtl/T80/T80.vhd
similarity index 99%
rename from src/t80/T80.vhd
rename to rtl/T80/T80.vhd
index e1302e0..813f64c 100644
--- a/src/t80/T80.vhd
+++ b/rtl/T80/T80.vhd
@@ -79,7 +79,6 @@ library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
-use work.T80_Pack.all;
entity T80 is
generic(
@@ -260,7 +259,7 @@ begin
else DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) &
std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC;
- mcode : T80_MCode
+ mcode : work.T80_MCode
generic map(
Mode => Mode,
Flag_C => Flag_C,
@@ -328,7 +327,7 @@ begin
Write => Write,
XYbit_undoc => XYbit_undoc);
- alu : T80_ALU
+ alu : work.T80_ALU
generic map(
Mode => Mode,
Flag_C => Flag_C,
@@ -920,7 +919,7 @@ begin
end if;
end process;
- Regs : T80_Reg
+ Regs : work.T80_Reg
port map(
Clk => CLK_n,
CEN => ClkEn,
diff --git a/src/t80/T80_ALU.vhd b/rtl/T80/T80_ALU.vhd
similarity index 100%
rename from src/t80/T80_ALU.vhd
rename to rtl/T80/T80_ALU.vhd
diff --git a/src/t80/T80_MCode.vhd b/rtl/T80/T80_MCode.vhd
similarity index 99%
rename from src/t80/T80_MCode.vhd
rename to rtl/T80/T80_MCode.vhd
index 6b43ef4..7d4bbc3 100644
--- a/src/t80/T80_MCode.vhd
+++ b/rtl/T80/T80_MCode.vhd
@@ -74,7 +74,6 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.T80_Pack.all;
entity T80_MCode is
generic(
diff --git a/src/t80/T80_Reg.vhd b/rtl/T80/T80_Reg.vhd
similarity index 100%
rename from src/t80/T80_Reg.vhd
rename to rtl/T80/T80_Reg.vhd
diff --git a/src/t80/T80pa.vhd b/rtl/T80/T80pa.vhd
similarity index 96%
rename from src/t80/T80pa.vhd
rename to rtl/T80/T80pa.vhd
index bacbc60..2b20b28 100644
--- a/src/t80/T80pa.vhd
+++ b/rtl/T80/T80pa.vhd
@@ -56,7 +56,6 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.T80_Pack.all;
entity T80pa is
generic(
@@ -108,7 +107,7 @@ begin
BUSAK_n <= BUSAK;
- u0 : T80
+ u0 : work.T80
generic map(
Mode => Mode,
IOWait => 1
diff --git a/src/t80/T80s.vhd b/rtl/T80/T80s.vhd
similarity index 66%
rename from src/t80/T80s.vhd
rename to rtl/T80/T80s.vhd
index c30031c..8c82f69 100644
--- a/src/t80/T80s.vhd
+++ b/rtl/T80/T80s.vhd
@@ -68,34 +68,34 @@
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.T80_Pack.all;
+use IEEE.STD_LOGIC_UNSIGNED.all;
entity T80s is
generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
- IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
+ Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
+ T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2
+ IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle
);
port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- CEN : in std_logic := '1';
- WAIT_n : in std_logic := '1';
- INT_n : in std_logic := '1';
- NMI_n : in std_logic := '1';
- BUSRQ_n : in std_logic := '1';
- M1_n : out std_logic;
- MREQ_n : out std_logic;
- IORQ_n : out std_logic;
- RD_n : out std_logic;
- WR_n : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
- A : out std_logic_vector(15 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0)
+ RESET_n : in std_logic;
+ CLK : in std_logic;
+ CEN : in std_logic := '1';
+ WAIT_n : in std_logic := '1';
+ INT_n : in std_logic := '1';
+ NMI_n : in std_logic := '1';
+ BUSRQ_n : in std_logic := '1';
+ M1_n : out std_logic;
+ MREQ_n : out std_logic;
+ IORQ_n : out std_logic;
+ RD_n : out std_logic;
+ WR_n : out std_logic;
+ RFSH_n : out std_logic;
+ HALT_n : out std_logic;
+ BUSAK_n : out std_logic;
+ OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
+ A : out std_logic_vector(15 downto 0);
+ DI : in std_logic_vector(7 downto 0);
+ DO : out std_logic_vector(7 downto 0)
);
end T80s;
@@ -111,36 +111,36 @@ architecture rtl of T80s is
begin
- u0 : T80
- generic map(
- Mode => Mode,
- IOWait => IOWait)
- port map(
- CEN => CEN,
- M1_n => M1_n,
- IORQ => IORQ,
- NoRead => NoRead,
- Write => Write,
- RFSH_n => RFSH_n,
- HALT_n => HALT_n,
- WAIT_n => Wait_n,
- INT_n => INT_n,
- NMI_n => NMI_n,
- RESET_n => RESET_n,
- BUSRQ_n => BUSRQ_n,
- BUSAK_n => BUSAK_n,
- CLK_n => CLK_n,
- A => A,
- DInst => DI,
- DI => DI_Reg,
- DO => DO,
- MC => MCycle,
- TS => TState,
- OUT0 => OUT0,
- IntCycle_n => IntCycle_n
- );
+ u0 : work.T80
+ generic map(
+ Mode => Mode,
+ IOWait => IOWait)
+ port map(
+ CEN => CEN,
+ M1_n => M1_n,
+ IORQ => IORQ,
+ NoRead => NoRead,
+ Write => Write,
+ RFSH_n => RFSH_n,
+ HALT_n => HALT_n,
+ WAIT_n => Wait_n,
+ INT_n => INT_n,
+ NMI_n => NMI_n,
+ RESET_n => RESET_n,
+ BUSRQ_n => BUSRQ_n,
+ BUSAK_n => BUSAK_n,
+ CLK_n => CLK,
+ A => A,
+ DInst => DI,
+ DI => DI_Reg,
+ DO => DO,
+ MC => MCycle,
+ TS => TState,
+ OUT0 => OUT0,
+ IntCycle_n => IntCycle_n
+ );
- process (RESET_n, CLK_n)
+ process (RESET_n, CLK)
begin
if RESET_n = '0' then
RD_n <= '1';
@@ -148,45 +148,45 @@ begin
IORQ_n <= '1';
MREQ_n <= '1';
DI_Reg <= "00000000";
- elsif rising_edge(CLK_n) then
+ elsif rising_edge(CLK) then
if CEN = '1' then
RD_n <= '1';
WR_n <= '1';
IORQ_n <= '1';
MREQ_n <= '1';
- if MCycle = "001" then
- if TState = "001" or (TState = "010" and Wait_n = '0') then
+ if MCycle = 1 then
+ if TState = 1 or (TState = 2 and Wait_n = '0') then
RD_n <= not IntCycle_n;
MREQ_n <= not IntCycle_n;
IORQ_n <= IntCycle_n;
end if;
- if TState = "011" then
+ if TState = 3 then
MREQ_n <= '0';
end if;
else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then
+ if (TState = 1 or (TState = 2 and Wait_n = '0')) and NoRead = '0' and Write = '0' then
RD_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
if T2Write = 0 then
- if TState = "010" and Write = '1' then
+ if TState = 2 and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
else
- if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then
+ if (TState = 1 or (TState = 2 and Wait_n = '0')) and Write = '1' then
WR_n <= '0';
IORQ_n <= not IORQ;
MREQ_n <= IORQ;
end if;
end if;
end if;
- if TState = "010" and Wait_n = '1' then
+ if TState = 2 and Wait_n = '1' then
DI_Reg <= DI;
end if;
- end if;
+ end if;
end if;
end process;
end;
diff --git a/src/clock.v b/rtl/clock.v
similarity index 100%
rename from src/clock.v
rename to rtl/clock.v
diff --git a/src/common/zclock.v b/rtl/common/zclock.v
similarity index 100%
rename from src/common/zclock.v
rename to rtl/common/zclock.v
diff --git a/src/common/zint.v b/rtl/common/zint.v
similarity index 100%
rename from src/common/zint.v
rename to rtl/common/zint.v
diff --git a/src/common/zmaps.v b/rtl/common/zmaps.v
similarity index 100%
rename from src/common/zmaps.v
rename to rtl/common/zmaps.v
diff --git a/src/common/zmem.v b/rtl/common/zmem.v
similarity index 100%
rename from src/common/zmem.v
rename to rtl/common/zmem.v
diff --git a/src/common/zports.v b/rtl/common/zports.v
similarity index 100%
rename from src/common/zports.v
rename to rtl/common/zports.v
diff --git a/src/common/zsignals.v b/rtl/common/zsignals.v
similarity index 100%
rename from src/common/zsignals.v
rename to rtl/common/zsignals.v
diff --git a/src/kempston_mouse.v b/rtl/kempston_mouse.v
similarity index 100%
rename from src/kempston_mouse.v
rename to rtl/kempston_mouse.v
diff --git a/src/keyboard.vhd b/rtl/keyboard.vhd
similarity index 100%
rename from src/keyboard.vhd
rename to rtl/keyboard.vhd
diff --git a/src/memory/arbiter.v b/rtl/memory/arbiter.v
similarity index 100%
rename from src/memory/arbiter.v
rename to rtl/memory/arbiter.v
diff --git a/src/memory/ddram.sv b/rtl/memory/ddram.sv
similarity index 100%
rename from src/memory/ddram.sv
rename to rtl/memory/ddram.sv
diff --git a/src/memory/dma.v b/rtl/memory/dma.v
similarity index 100%
rename from src/memory/dma.v
rename to rtl/memory/dma.v
diff --git a/src/memory/dpram.v b/rtl/memory/dpram.v
similarity index 100%
rename from src/memory/dpram.v
rename to rtl/memory/dpram.v
diff --git a/src/memory/sdram.v b/rtl/memory/sdram.v
similarity index 84%
rename from src/memory/sdram.v
rename to rtl/memory/sdram.v
index 97f5103..1bb5f51 100644
--- a/src/memory/sdram.v
+++ b/rtl/memory/sdram.v
@@ -24,9 +24,10 @@ module sdram
output SDRAM_nCAS,
output SDRAM_nRAS,
output SDRAM_nWE,
- output SDRAM_CKE
+ output SDRAM_CKE,
+ output SDRAM_CLK
);
-
+
reg [2:0] sdr_cmd;
localparam SdrCmd_xx = 3'b111; // no operation
@@ -117,4 +118,29 @@ assign SDRAM_nWE = sdr_cmd[0];
assign SDRAM_DQML = SDRAM_A[11];
assign SDRAM_DQMH = SDRAM_A[12];
+altddio_out
+#(
+ .extend_oe_disable("OFF"),
+ .intended_device_family("Cyclone V"),
+ .invert_output("OFF"),
+ .lpm_hint("UNUSED"),
+ .lpm_type("altddio_out"),
+ .oe_reg("UNREGISTERED"),
+ .power_up_high("OFF"),
+ .width(1)
+)
+sdramclk_ddr
+(
+ .datain_h(1'b0),
+ .datain_l(1'b1),
+ .outclock(clk),
+ .dataout(SDRAM_CLK),
+ .aclr(1'b0),
+ .aset(1'b0),
+ .oe(1'b1),
+ .outclocken(1'b1),
+ .sclr(1'b0),
+ .sset(1'b0)
+);
+
endmodule
diff --git a/sys/pll.qip b/rtl/pll.qip
similarity index 95%
rename from sys/pll.qip
rename to rtl/pll.qip
index d6f295f..2d65bd5 100644
--- a/sys/pll.qip
+++ b/rtl/pll.qip
@@ -35,17 +35,17 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::ZmFsc2U=::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz"
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::Mw==::TnVtYmVyIE9mIENsb2Nrcw=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mw==::bnVtYmVyX29mX2Nsb2Nrcw=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::Mg==::TnVtYmVyIE9mIENsb2Nrcw=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mg==::bnVtYmVyX29mX2Nsb2Nrcw=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::ODQuMA==::RGVzaXJlZCBGcmVxdWVuY3k="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::MjM=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::MjIzMzM4Mjk5NA==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::MTQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::MTA=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::MzQzNTk3Mzg0::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::Ng==::QWN0dWFsIERpdmlkZSBGYWN0b3I="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ="
@@ -53,23 +53,23 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy"
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::ODQuMA==::RGVzaXJlZCBGcmVxdWVuY3k="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::NTYuMA==::RGVzaXJlZCBGcmVxdWVuY3k="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::MjM=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::MjIzMzM4Mjk5NA==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::MTA=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::MzQzNTk3Mzg0::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::OQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::LTQzNTA=::UGhhc2UgU2hpZnQ="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MTgwLjA=::UGhhc2UgU2hpZnQ="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::NTYuMA==::RGVzaXJlZCBGcmVxdWVuY3k="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MjM=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MjIzMzM4Mjk5NA==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MjE=::QWN0dWFsIERpdmlkZSBGYWN0b3I="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MTA=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MzQzNTk3Mzg0::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::OQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ="
@@ -259,10 +259,10 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::ODQuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::ODQuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::LTQzNTcgcHM=::cGhhc2Vfc2hpZnQx"
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::NTYuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::NTYuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM="
@@ -317,8 +317,8 @@ set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAM
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU="
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz"
-set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::MTIsMTEsMjU2LDI1NixmYWxzZSx0cnVlLHRydWUsZmFsc2UsNyw3LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDcsNyw5LDcscGhfbXV4X2NsayxmYWxzZSxmYWxzZSwxMSwxMCwxLDAscGhfbXV4X2NsayxmYWxzZSx0cnVlLDEsMjAsNDAwMCwxMTc2LjAgTUh6LDIyMzMzODI5OTQsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2Nsayx0cnVl::UGFyYW1ldGVyIFZhbHVlcw=="
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz"
+set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NSw1LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSwzLDMsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsNSw0LDEsMCxwaF9tdXhfY2xrLGZhbHNlLHRydWUsMiwyMCw0MDAwLDUwNC4wIE1IeiwzNDM1OTczODQsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2Nsayx0cnVl::UGFyYW1ldGVyIFZhbHVlcw=="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc="
set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u"
diff --git a/sys/pll.v b/rtl/pll.v
similarity index 96%
rename from sys/pll.v
rename to rtl/pll.v
index 7b3d7b5..b07c373 100644
--- a/sys/pll.v
+++ b/rtl/pll.v
@@ -2,15 +2,14 @@
// GENERATION: XML
// pll.v
-// Generated using ACDS version 17.0 598
+// Generated using ACDS version 17.0 602
`timescale 1 ps / 1 ps
module pll (
input wire refclk, // refclk.clk
input wire rst, // reset.reset
output wire outclk_0, // outclk0.clk
- output wire outclk_1, // outclk1.clk
- output wire outclk_2 // outclk2.clk
+ output wire outclk_1 // outclk1.clk
);
pll_0002 pll_inst (
@@ -18,7 +17,6 @@ module pll (
.rst (rst), // reset.reset
.outclk_0 (outclk_0), // outclk0.clk
.outclk_1 (outclk_1), // outclk1.clk
- .outclk_2 (outclk_2), // outclk2.clk
.locked () // (terminated)
);
@@ -29,7 +27,7 @@ endmodule
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
// ************************************************************
-// Copyright (C) 1991-2018 Altera Corporation
+// Copyright (C) 1991-2020 Altera Corporation
// Any megafunction design, and related net list (encrypted or decrypted),
// support information, device programming or simulation file, and any other
// associated documentation or information provided by Altera or a partner
@@ -64,7 +62,7 @@ endmodule
// Retrieval info:
// Retrieval info:
// Retrieval info:
-// Retrieval info:
+// Retrieval info:
// Retrieval info:
// Retrieval info:
// Retrieval info:
@@ -78,11 +76,11 @@ endmodule
// Retrieval info:
// Retrieval info:
// Retrieval info:
-// Retrieval info:
+// Retrieval info:
// Retrieval info:
// Retrieval info:
// Retrieval info:
-// Retrieval info:
+// Retrieval info:
// Retrieval info:
// Retrieval info:
// Retrieval info:
diff --git a/sys/pll/pll_0002.qip b/rtl/pll/pll_0002.qip
similarity index 100%
rename from sys/pll/pll_0002.qip
rename to rtl/pll/pll_0002.qip
diff --git a/sys/pll/pll_0002.v b/rtl/pll/pll_0002.v
similarity index 85%
rename from sys/pll/pll_0002.v
rename to rtl/pll/pll_0002.v
index a8e1ca3..d78465a 100644
--- a/sys/pll/pll_0002.v
+++ b/rtl/pll/pll_0002.v
@@ -13,9 +13,6 @@ module pll_0002(
// interface 'outclk1'
output wire outclk_1,
- // interface 'outclk2'
- output wire outclk_2,
-
// interface 'locked'
output wire locked
);
@@ -24,14 +21,14 @@ module pll_0002(
.fractional_vco_multiplier("true"),
.reference_clock_frequency("50.0 MHz"),
.operation_mode("direct"),
- .number_of_clocks(3),
+ .number_of_clocks(2),
.output_clock_frequency0("84.000000 MHz"),
.phase_shift0("0 ps"),
.duty_cycle0(50),
- .output_clock_frequency1("84.000000 MHz"),
- .phase_shift1("-4357 ps"),
+ .output_clock_frequency1("56.000000 MHz"),
+ .phase_shift1("0 ps"),
.duty_cycle1(50),
- .output_clock_frequency2("56.000000 MHz"),
+ .output_clock_frequency2("0 MHz"),
.phase_shift2("0 ps"),
.duty_cycle2(50),
.output_clock_frequency3("0 MHz"),
@@ -83,7 +80,7 @@ module pll_0002(
.pll_subtype("General")
) altera_pll_i (
.rst (rst),
- .outclk ({outclk_2, outclk_1, outclk_0}),
+ .outclk ({outclk_1, outclk_0}),
.locked (locked),
.fboutclk ( ),
.fbclk (1'b0),
diff --git a/src/rtc/CMOS.bin b/rtl/rtc/CMOS.bin
similarity index 100%
rename from src/rtc/CMOS.bin
rename to rtl/rtc/CMOS.bin
diff --git a/src/rtc/CMOS.mif b/rtl/rtc/CMOS.mif
similarity index 100%
rename from src/rtc/CMOS.mif
rename to rtl/rtc/CMOS.mif
diff --git a/src/rtc/mc146818a.v b/rtl/rtc/mc146818a.v
similarity index 99%
rename from src/rtc/mc146818a.v
rename to rtl/rtc/mc146818a.v
index feb751a..4e1031c 100644
--- a/src/rtc/mc146818a.v
+++ b/rtl/rtc/mc146818a.v
@@ -236,7 +236,7 @@ always @(posedge CLK) begin
end
// 50 Bytes of General Purpose RAM
-dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("src/rtc/CMOS.mif")) CMOS
+dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("rtl/rtc/CMOS.mif")) CMOS
(
.clock (CLK),
.address_a (A),
diff --git a/src/sound/compressor.sv b/rtl/sound/compressor.sv
similarity index 100%
rename from src/sound/compressor.sv
rename to rtl/sound/compressor.sv
diff --git a/src/sound/gs.v b/rtl/sound/gs.v
similarity index 100%
rename from src/sound/gs.v
rename to rtl/sound/gs.v
diff --git a/src/sound/gs105b.mif b/rtl/sound/gs105b.mif
similarity index 100%
rename from src/sound/gs105b.mif
rename to rtl/sound/gs105b.mif
diff --git a/rtl/sound/jt12/jt12.qip b/rtl/sound/jt12/jt12.qip
new file mode 100644
index 0000000..0b87eb7
--- /dev/null
+++ b/rtl/sound/jt12/jt12.qip
@@ -0,0 +1,21 @@
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_acc.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_clksync.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_eg.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_exprom.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_kon.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_lfo.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_limitamp.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mmr.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_mod.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_op.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_opram.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_pg.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_phrom.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_reg.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh_rst.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sh24.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_sumch.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_syn.v ]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt12_timers.v ]
diff --git a/src/sound/jt12/jt12.v b/rtl/sound/jt12/jt12.v
similarity index 100%
rename from src/sound/jt12/jt12.v
rename to rtl/sound/jt12/jt12.v
diff --git a/src/sound/jt12/jt12_acc.v b/rtl/sound/jt12/jt12_acc.v
similarity index 100%
rename from src/sound/jt12/jt12_acc.v
rename to rtl/sound/jt12/jt12_acc.v
diff --git a/src/sound/jt12/jt12_clksync.v b/rtl/sound/jt12/jt12_clksync.v
similarity index 100%
rename from src/sound/jt12/jt12_clksync.v
rename to rtl/sound/jt12/jt12_clksync.v
diff --git a/src/sound/jt12/jt12_eg.v b/rtl/sound/jt12/jt12_eg.v
similarity index 100%
rename from src/sound/jt12/jt12_eg.v
rename to rtl/sound/jt12/jt12_eg.v
diff --git a/src/sound/jt12/jt12_exprom.v b/rtl/sound/jt12/jt12_exprom.v
similarity index 100%
rename from src/sound/jt12/jt12_exprom.v
rename to rtl/sound/jt12/jt12_exprom.v
diff --git a/src/sound/jt12/jt12_kon.v b/rtl/sound/jt12/jt12_kon.v
similarity index 100%
rename from src/sound/jt12/jt12_kon.v
rename to rtl/sound/jt12/jt12_kon.v
diff --git a/src/sound/jt12/jt12_lfo.v b/rtl/sound/jt12/jt12_lfo.v
similarity index 100%
rename from src/sound/jt12/jt12_lfo.v
rename to rtl/sound/jt12/jt12_lfo.v
diff --git a/src/sound/jt12/jt12_limitamp.v b/rtl/sound/jt12/jt12_limitamp.v
similarity index 100%
rename from src/sound/jt12/jt12_limitamp.v
rename to rtl/sound/jt12/jt12_limitamp.v
diff --git a/src/sound/jt12/jt12_mmr.v b/rtl/sound/jt12/jt12_mmr.v
similarity index 100%
rename from src/sound/jt12/jt12_mmr.v
rename to rtl/sound/jt12/jt12_mmr.v
diff --git a/src/sound/jt12/jt12_mmr_sim.vh b/rtl/sound/jt12/jt12_mmr_sim.vh
similarity index 100%
rename from src/sound/jt12/jt12_mmr_sim.vh
rename to rtl/sound/jt12/jt12_mmr_sim.vh
diff --git a/src/sound/jt12/jt12_mod.v b/rtl/sound/jt12/jt12_mod.v
similarity index 100%
rename from src/sound/jt12/jt12_mod.v
rename to rtl/sound/jt12/jt12_mod.v
diff --git a/src/sound/jt12/jt12_op.v b/rtl/sound/jt12/jt12_op.v
similarity index 100%
rename from src/sound/jt12/jt12_op.v
rename to rtl/sound/jt12/jt12_op.v
diff --git a/src/sound/jt12/jt12_opram.v b/rtl/sound/jt12/jt12_opram.v
similarity index 100%
rename from src/sound/jt12/jt12_opram.v
rename to rtl/sound/jt12/jt12_opram.v
diff --git a/src/sound/jt12/jt12_pg.v b/rtl/sound/jt12/jt12_pg.v
similarity index 100%
rename from src/sound/jt12/jt12_pg.v
rename to rtl/sound/jt12/jt12_pg.v
diff --git a/src/sound/jt12/jt12_phrom.v b/rtl/sound/jt12/jt12_phrom.v
similarity index 100%
rename from src/sound/jt12/jt12_phrom.v
rename to rtl/sound/jt12/jt12_phrom.v
diff --git a/src/sound/jt12/jt12_reg.v b/rtl/sound/jt12/jt12_reg.v
similarity index 100%
rename from src/sound/jt12/jt12_reg.v
rename to rtl/sound/jt12/jt12_reg.v
diff --git a/src/sound/jt12/jt12_sh.v b/rtl/sound/jt12/jt12_sh.v
similarity index 100%
rename from src/sound/jt12/jt12_sh.v
rename to rtl/sound/jt12/jt12_sh.v
diff --git a/src/sound/jt12/jt12_sh24.v b/rtl/sound/jt12/jt12_sh24.v
similarity index 100%
rename from src/sound/jt12/jt12_sh24.v
rename to rtl/sound/jt12/jt12_sh24.v
diff --git a/src/sound/jt12/jt12_sh_rst.v b/rtl/sound/jt12/jt12_sh_rst.v
similarity index 100%
rename from src/sound/jt12/jt12_sh_rst.v
rename to rtl/sound/jt12/jt12_sh_rst.v
diff --git a/src/sound/jt12/jt12_sumch.v b/rtl/sound/jt12/jt12_sumch.v
similarity index 100%
rename from src/sound/jt12/jt12_sumch.v
rename to rtl/sound/jt12/jt12_sumch.v
diff --git a/src/sound/jt12/jt12_syn.v b/rtl/sound/jt12/jt12_syn.v
similarity index 100%
rename from src/sound/jt12/jt12_syn.v
rename to rtl/sound/jt12/jt12_syn.v
diff --git a/src/sound/jt12/jt12_timers.v b/rtl/sound/jt12/jt12_timers.v
similarity index 100%
rename from src/sound/jt12/jt12_timers.v
rename to rtl/sound/jt12/jt12_timers.v
diff --git a/src/sound/jt12/lut.vh b/rtl/sound/jt12/lut.vh
similarity index 100%
rename from src/sound/jt12/lut.vh
rename to rtl/sound/jt12/lut.vh
diff --git a/src/sound/saa1099.sv b/rtl/sound/saa1099.sv
similarity index 100%
rename from src/sound/saa1099.sv
rename to rtl/sound/saa1099.sv
diff --git a/src/sound/soundrive.vhd b/rtl/sound/soundrive.vhd
similarity index 100%
rename from src/sound/soundrive.vhd
rename to rtl/sound/soundrive.vhd
diff --git a/src/sound/turbosound.sv b/rtl/sound/turbosound.sv
similarity index 100%
rename from src/sound/turbosound.sv
rename to rtl/sound/turbosound.sv
diff --git a/src/sound/ym2149.sv b/rtl/sound/ym2149.sv
similarity index 100%
rename from src/sound/ym2149.sv
rename to rtl/sound/ym2149.sv
diff --git a/src/sound/ym2203.sv b/rtl/sound/ym2203.sv
similarity index 100%
rename from src/sound/ym2203.sv
rename to rtl/sound/ym2203.sv
diff --git a/src/spi.v b/rtl/spi.v
similarity index 100%
rename from src/spi.v
rename to rtl/spi.v
diff --git a/src/tsbios.mif b/rtl/tsbios.mif
similarity index 100%
rename from src/tsbios.mif
rename to rtl/tsbios.mif
diff --git a/src/tsconf.v b/rtl/tsconf.v
similarity index 98%
rename from src/tsconf.v
rename to rtl/tsconf.v
index 23406d6..48d9407 100644
--- a/src/tsconf.v
+++ b/rtl/tsconf.v
@@ -70,6 +70,7 @@ module tsconf
output SDRAM_nRAS,
output SDRAM_nWE,
output SDRAM_CKE,
+ output SDRAM_CLK,
// VGA
output [7:0] VGA_R,
@@ -329,7 +330,7 @@ always @(posedge clk) zclk_r <= zclk;
T80s CPU
(
.RESET_n(~reset),
- .CLK_n(clk),
+ .CLK(clk),
.CEN(~zclk_r & zclk),
.INT_n(cpu_int_n_TS),
.M1_n(cpu_m1_n),
@@ -675,7 +676,7 @@ zint TS13
// BIOS
wire [7:0] bios_do_bus;
-dpram #(.ADDRWIDTH(16), .MEM_INIT_FILE("src/tsbios.mif")) BIOS
+dpram #(.ADDRWIDTH(16), .MEM_INIT_FILE("rtl/tsbios.mif")) BIOS
(
.clock(clk),
.address_a({cpu_addr_20[14:0],cpu_wrbsel}),
@@ -710,7 +711,8 @@ sdram SE4
.SDRAM_nCAS(SDRAM_nCAS),
.SDRAM_nRAS(SDRAM_nRAS),
.SDRAM_nWE(SDRAM_nWE),
- .SDRAM_CKE(SDRAM_CKE)
+ .SDRAM_CKE(SDRAM_CKE),
+ .SDRAM_CLK(SDRAM_CLK)
);
@@ -826,7 +828,7 @@ wire [14:0] gs_r;
wire [7:0] gs_do_bus;
wire gs_sel = ~cpu_iorq_n & cpu_m1_n & (cpu_a_bus[7:4] == 'hB && cpu_a_bus[2:0] == 'h3);
-gs #("src/sound/gs105b.mif") U15
+gs #("rtl/sound/gs105b.mif") U15
(
.RESET(reset),
.CLK(clk),
diff --git a/src/video/video_cram.mif b/rtl/video/video_cram.mif
similarity index 100%
rename from src/video/video_cram.mif
rename to rtl/video/video_cram.mif
diff --git a/src/video/video_fetch.v b/rtl/video/video_fetch.v
similarity index 100%
rename from src/video/video_fetch.v
rename to rtl/video/video_fetch.v
diff --git a/src/video/video_mode.v b/rtl/video/video_mode.v
similarity index 100%
rename from src/video/video_mode.v
rename to rtl/video/video_mode.v
diff --git a/src/video/video_out.v b/rtl/video/video_out.v
similarity index 94%
rename from src/video/video_out.v
rename to rtl/video/video_out.v
index 70e2b9a..679c1ec 100644
--- a/src/video/video_out.v
+++ b/rtl/video/video_out.v
@@ -37,7 +37,7 @@ wire [7:0] vdata = tv_hires ? {palsel, plex_sel_in[1] ? vplex[3:0] : vplex[7:4]}
// CRAM
wire [15:0] vpixel;
-dpram #(.DATAWIDTH(16), .ADDRWIDTH(8), .MEM_INIT_FILE("src/video/video_cram.mif")) video_cram
+dpram #(.DATAWIDTH(16), .ADDRWIDTH(8), .MEM_INIT_FILE("rtl/video/video_cram.mif")) video_cram
(
.clock (clk),
.address_a(cram_addr_in),
diff --git a/src/video/video_ports.v b/rtl/video/video_ports.v
similarity index 100%
rename from src/video/video_ports.v
rename to rtl/video/video_ports.v
diff --git a/src/video/video_render.v b/rtl/video/video_render.v
similarity index 100%
rename from src/video/video_render.v
rename to rtl/video/video_render.v
diff --git a/src/video/video_sync.v b/rtl/video/video_sync.v
similarity index 100%
rename from src/video/video_sync.v
rename to rtl/video/video_sync.v
diff --git a/src/video/video_top.v b/rtl/video/video_top.v
similarity index 100%
rename from src/video/video_top.v
rename to rtl/video/video_top.v
diff --git a/src/video/video_ts.v b/rtl/video/video_ts.v
similarity index 100%
rename from src/video/video_ts.v
rename to rtl/video/video_ts.v
diff --git a/src/video/video_ts_render.v b/rtl/video/video_ts_render.v
similarity index 100%
rename from src/video/video_ts_render.v
rename to rtl/video/video_ts_render.v
diff --git a/src/memory/sdram.qip b/src/memory/sdram.qip
deleted file mode 100644
index e4df29b..0000000
--- a/src/memory/sdram.qip
+++ /dev/null
@@ -1,2 +0,0 @@
-set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sdram.v ]
-set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sdram.sdc ]
diff --git a/src/memory/sdram.sdc b/src/memory/sdram.sdc
deleted file mode 100644
index 664d0d2..0000000
--- a/src/memory/sdram.sdc
+++ /dev/null
@@ -1,12 +0,0 @@
-derive_pll_clocks
-
-create_generated_clock -source [get_pins -compatibility_mode {*|pll|pll_inst|altera_pll_i|*[1].*|divclk}] \
- -name SDRAM_CLK [get_ports {SDRAM_CLK}]
-
-derive_clock_uncertainty
-
-# Set acceptable delays for SDRAM chip (See correspondent chip datasheet)
-set_input_delay -max -clock SDRAM_CLK 6.4ns [get_ports SDRAM_DQ[*]]
-set_input_delay -min -clock SDRAM_CLK 3.7ns [get_ports SDRAM_DQ[*]]
-set_output_delay -max -clock SDRAM_CLK 1.6ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
-set_output_delay -min -clock SDRAM_CLK -0.9ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
diff --git a/src/sound/jt12/jt12.qip b/src/sound/jt12/jt12.qip
deleted file mode 100644
index 6225f7d..0000000
--- a/src/sound/jt12/jt12.qip
+++ /dev/null
@@ -1,21 +0,0 @@
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_acc.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_clksync.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_eg.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_exprom.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_kon.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_lfo.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_limitamp.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_mmr.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_mod.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_op.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_opram.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_pg.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_phrom.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_reg.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_sh.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_sh_rst.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_sh24.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_sumch.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_syn.v
-set_global_assignment -name VERILOG_FILE src/sound/jt12/jt12_timers.v
diff --git a/src/t80/T80.qip b/src/t80/T80.qip
deleted file mode 100644
index 1c5d369..0000000
--- a/src/t80/T80.qip
+++ /dev/null
@@ -1,7 +0,0 @@
-set_global_assignment -name VHDL_FILE src/t80/T80_Reg.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80pa.vhd
-set_global_assignment -name VHDL_FILE src/t80/T80s.vhd
diff --git a/src/t80/T80_Pack.vhd b/src/t80/T80_Pack.vhd
deleted file mode 100644
index 1b7f522..0000000
--- a/src/t80/T80_Pack.vhd
+++ /dev/null
@@ -1,236 +0,0 @@
---------------------------------------------------------------------------------
--- ****
--- T80(c) core. Attempt to finish all undocumented features and provide
--- accurate timings.
--- Version 350.
--- Copyright (c) 2018 Sorgelig
--- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr
--- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as
--- correct implementation is still unclear.
---
--- ****
--- T80(b) core. In an effort to merge and maintain bug fixes ....
---
---
--- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010
--- Ver 300 started tidyup
--- MikeJ March 2005
--- Latest version from www.fpgaarcade.com (original www.opencores.org)
---
--- ****
---
--- Z80 compatible microprocessor core
---
--- Version : 0242
---
--- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org)
---
--- All rights reserved
---
--- Redistribution and use in source and synthezised forms, with or without
--- modification, are permitted provided that the following conditions are met:
---
--- Redistributions of source code must retain the above copyright notice,
--- this list of conditions and the following disclaimer.
---
--- Redistributions in synthesized form must reproduce the above copyright
--- notice, this list of conditions and the following disclaimer in the
--- documentation and/or other materials provided with the distribution.
---
--- Neither the name of the author nor the names of other contributors may
--- be used to endorse or promote products derived from this software without
--- specific prior written permission.
---
--- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
--- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
--- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
--- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
--- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
--- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
--- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
--- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
--- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
--- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
--- POSSIBILITY OF SUCH DAMAGE.
---
--- Please report bugs to the author, but before you do so, please
--- make sure that this is not a derivative work and that
--- you have the latest version of this file.
---
--- The latest version of this file can be found at:
--- http://www.opencores.org/cvsweb.shtml/t80/
---
--- Limitations :
---
--- File history :
---
-
-library IEEE;
-use IEEE.std_logic_1164.all;
-
-package T80_Pack is
-
- component T80
- generic(
- Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
- IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- RESET_n : in std_logic;
- CLK_n : in std_logic;
- CEN : in std_logic;
- WAIT_n : in std_logic;
- INT_n : in std_logic;
- NMI_n : in std_logic;
- BUSRQ_n : in std_logic;
- M1_n : out std_logic;
- IORQ : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic;
- RFSH_n : out std_logic;
- HALT_n : out std_logic;
- BUSAK_n : out std_logic;
- A : out std_logic_vector(15 downto 0);
- DInst : in std_logic_vector(7 downto 0);
- DI : in std_logic_vector(7 downto 0);
- DO : out std_logic_vector(7 downto 0);
- MC : out std_logic_vector(2 downto 0);
- TS : out std_logic_vector(2 downto 0);
- IntCycle_n : out std_logic;
- IntE : out std_logic;
- out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255
- Stop : out std_logic;
- REG : out std_logic_vector(207 downto 0) -- IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A
- );
- end component;
-
- component T80_Reg
- port(
- Clk : in std_logic;
- CEN : in std_logic;
- WEH : in std_logic;
- WEL : in std_logic;
- AddrA : in std_logic_vector(2 downto 0);
- AddrB : in std_logic_vector(2 downto 0);
- AddrC : in std_logic_vector(2 downto 0);
- DIH : in std_logic_vector(7 downto 0);
- DIL : in std_logic_vector(7 downto 0);
- DOAH : out std_logic_vector(7 downto 0);
- DOAL : out std_logic_vector(7 downto 0);
- DOBH : out std_logic_vector(7 downto 0);
- DOBL : out std_logic_vector(7 downto 0);
- DOCH : out std_logic_vector(7 downto 0);
- DOCL : out std_logic_vector(7 downto 0);
- DOR : out std_logic_vector(127 downto 0)
- );
- end component;
-
- component T80_MCode
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- IR : in std_logic_vector(7 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- MCycle : in std_logic_vector(2 downto 0);
- F : in std_logic_vector(7 downto 0);
- NMICycle : in std_logic;
- IntCycle : in std_logic;
- XY_State : in std_logic_vector(1 downto 0);
- MCycles : out std_logic_vector(2 downto 0);
- TStates : out std_logic_vector(2 downto 0);
- Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD
- Inc_PC : out std_logic;
- Inc_WZ : out std_logic;
- IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc
- Read_To_Reg : out std_logic;
- Read_To_Acc : out std_logic;
- Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F
- Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0
- ALU_Op : out std_logic_vector(3 downto 0);
- -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None
- Save_ALU : out std_logic;
- PreserveC : out std_logic;
- Arith16 : out std_logic;
- Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI
- IORQ : out std_logic;
- Jump : out std_logic;
- JumpE : out std_logic;
- JumpXY : out std_logic;
- Call : out std_logic;
- RstP : out std_logic;
- LDZ : out std_logic;
- LDW : out std_logic;
- LDSPHL : out std_logic;
- Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None
- ExchangeDH : out std_logic;
- ExchangeRp : out std_logic;
- ExchangeAF : out std_logic;
- ExchangeRS : out std_logic;
- I_DJNZ : out std_logic;
- I_CPL : out std_logic;
- I_CCF : out std_logic;
- I_SCF : out std_logic;
- I_RETN : out std_logic;
- I_BT : out std_logic;
- I_BC : out std_logic;
- I_BTR : out std_logic;
- I_RLD : out std_logic;
- I_RRD : out std_logic;
- I_INRC : out std_logic;
- SetWZ : out std_logic_vector(1 downto 0);
- SetDI : out std_logic;
- SetEI : out std_logic;
- IMode : out std_logic_vector(1 downto 0);
- Halt : out std_logic;
- NoRead : out std_logic;
- Write : out std_logic;
- XYbit_undoc : out std_logic
- );
- end component;
-
- component T80_ALU
- generic(
- Mode : integer := 0;
- Flag_C : integer := 0;
- Flag_N : integer := 1;
- Flag_P : integer := 2;
- Flag_X : integer := 3;
- Flag_H : integer := 4;
- Flag_Y : integer := 5;
- Flag_Z : integer := 6;
- Flag_S : integer := 7
- );
- port(
- Arith16 : in std_logic;
- Z16 : in std_logic;
- WZ : in std_logic_vector(15 downto 0);
- XY_State : in std_logic_vector(1 downto 0);
- ALU_Op : in std_logic_vector(3 downto 0);
- IR : in std_logic_vector(5 downto 0);
- ISet : in std_logic_vector(1 downto 0);
- BusA : in std_logic_vector(7 downto 0);
- BusB : in std_logic_vector(7 downto 0);
- F_In : in std_logic_vector(7 downto 0);
- Q : out std_logic_vector(7 downto 0);
- F_Out : out std_logic_vector(7 downto 0)
- );
- end component;
-
-end;
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 23336d7..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,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 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;
SIGNAL o_hsize,o_vsize : uint12;
@@ -422,7 +426,8 @@ ARCHITECTURE rtl OF ascal IS
SIGNAL o_wr : unsigned(3 DOWNTO 0);
SIGNAL o_hcpt,o_vcpt,o_vcpt_pre,o_vcpt_pre2,o_vcpt_pre3 : uint12;
SIGNAL o_ihsize,o_ivsize : uint12;
-
+ SIGNAL o_ihsize_temp, o_ihsize_temp2 : natural RANGE 0 TO 32767;
+
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);
@@ -1709,8 +1714,9 @@ BEGIN
o_format<=o_fb_format;
END IF;
- o_hburst<=(o_ihsize * (to_integer(o_format(2 DOWNTO 0)) - 2) +
- N_BURST - 1) / N_BURST;
+ o_ihsize_temp <= o_ihsize * to_integer(o_format(2 DOWNTO 0) - 2);
+ o_ihsize_temp2 <= (o_ihsize_temp + N_BURST - 1);
+ o_hburst <= o_ihsize_temp2 / N_BURST;
IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup0='1' THEN
o_obuf0<=buf_next(o_obuf0,o_ibuf0);
@@ -2043,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/build_id.tcl b/sys/build_id.tcl
index 3705e4c..b43b9d9 100644
--- a/sys/build_id.tcl
+++ b/sys/build_id.tcl
@@ -1,25 +1,29 @@
# Build TimeStamp Verilog Module
# Jeff Wiencrot - 8/1/2011
+# Sorgelig - 02/11/2019
proc generateBuildID_Verilog {} {
# Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
- set buildDate [ clock format [ clock seconds ] -format %y%m%d ]
- set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
+ set buildDate "`define BUILD_DATE \"[clock format [ clock seconds ] -format %y%m%d]\""
# Create a Verilog file for output
set outputFileName "build_id.v"
- set outputFile [open $outputFileName "w"]
+
+ set fileData ""
+ if { [file exists $outputFileName]} {
+ set outputFile [open $outputFileName "r"]
+ set fileData [read $outputFile]
+ close $outputFile
+ }
- # Output the Verilog source
- puts $outputFile "`define BUILD_DATE \"$buildDate\""
- puts $outputFile "`define BUILD_TIME \"$buildTime\""
- close $outputFile
-
- # Send confirmation message to the Messages window
- post_message "Generated build identification Verilog module: [pwd]/$outputFileName"
- post_message "Date: $buildDate"
- post_message "Time: $buildTime"
+ if {$buildDate ne $fileData} {
+ set outputFile [open $outputFileName "w"]
+ puts -nonewline $outputFile $buildDate
+ close $outputFile
+ # Send confirmation message to the Messages window
+ post_message "Generated: [pwd]/$outputFileName: $buildDate"
+ }
}
# Build CDF file
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/gamma_corr.sv b/sys/gamma_corr.sv
new file mode 100644
index 0000000..7fd9368
--- /dev/null
+++ b/sys/gamma_corr.sv
@@ -0,0 +1,122 @@
+module gamma_corr
+(
+ input clk_sys,
+ input clk_vid,
+ input ce_pix,
+ input gamma_en,
+ input gamma_wr,
+ input [9:0] gamma_wr_addr,
+ input [7:0] gamma_value,
+ input HSync,
+ input VSync,
+ input HBlank,
+ input VBlank,
+ input [23:0] RGB_in,
+ output reg HSync_out,
+ output reg VSync_out,
+ output reg HBlank_out,
+ output reg VBlank_out,
+ output reg [23:0] RGB_out
+);
+
+(* ramstyle="no_rw_check" *) reg [7:0] gamma_curve[768];
+
+always @(posedge clk_sys) if (gamma_wr) gamma_curve[gamma_wr_addr] <= gamma_value;
+always @(posedge clk_vid) gamma <= gamma_curve[gamma_index];
+
+reg [9:0] gamma_index;
+reg [7:0] gamma;
+
+always @(posedge clk_vid) begin
+ reg [7:0] R_in, G_in, B_in;
+ reg [7:0] R_gamma, G_gamma;
+ reg hs,vs,hb,vb;
+ reg [1:0] ctr = 0;
+
+ if(ce_pix) begin
+ {R_in,G_in,B_in} <= RGB_in;
+ hs <= HSync; vs <= VSync;
+ hb <= HBlank; vb <= VBlank;
+
+ RGB_out <= gamma_en ? {R_gamma,G_gamma,gamma} : {R_in,G_in,B_in};
+ HSync_out <= hs; VSync_out <= vs;
+ HBlank_out <= hb; VBlank_out <= vb;
+
+ ctr <= 1;
+ gamma_index <= {2'b00,RGB_in[23:16]};
+ end
+
+ if (|ctr) ctr <= ctr + 1'd1;
+
+ case(ctr)
+ 1: begin gamma_index <= {2'b01,G_in}; end
+ 2: begin R_gamma <= gamma; gamma_index <= {2'b10,B_in}; end
+ 3: begin G_gamma <= gamma; end
+ endcase
+end
+
+endmodule
+
+module gamma_fast
+(
+ input clk_vid,
+ input ce_pix,
+
+ inout [21:0] gamma_bus,
+
+ input HSync,
+ input VSync,
+ input HBlank,
+ input VBlank,
+ input DE,
+ input [23:0] RGB_in,
+
+ output reg HSync_out,
+ output reg VSync_out,
+ output reg HBlank_out,
+ output reg VBlank_out,
+ output reg DE_out,
+ output reg [23:0] RGB_out
+);
+
+(* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_r[256];
+(* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_g[256];
+(* ramstyle="no_rw_check" *) reg [7:0] gamma_curve_b[256];
+
+assign gamma_bus[21] = 1;
+wire clk_sys = gamma_bus[20];
+wire gamma_en = gamma_bus[19];
+wire gamma_wr = gamma_bus[18];
+wire [9:0] gamma_wr_addr = gamma_bus[17:8];
+wire [7:0] gamma_value = gamma_bus[7:0];
+
+always @(posedge clk_sys) if (gamma_wr) begin
+ case(gamma_wr_addr[9:8])
+ 0: gamma_curve_r[gamma_wr_addr[7:0]] <= gamma_value;
+ 1: gamma_curve_g[gamma_wr_addr[7:0]] <= gamma_value;
+ 2: gamma_curve_b[gamma_wr_addr[7:0]] <= gamma_value;
+ endcase
+end
+
+reg [7:0] gamma_index_r,gamma_index_g,gamma_index_b;
+
+always @(posedge clk_vid) begin
+ reg [7:0] R_in, G_in, B_in;
+ reg [7:0] R_gamma, G_gamma;
+ reg hs,vs,hb,vb,de;
+
+ if(ce_pix) begin
+ {gamma_index_r,gamma_index_g,gamma_index_b} <= RGB_in;
+ hs <= HSync; vs <= VSync;
+ hb <= HBlank; vb <= VBlank;
+ de <= DE;
+
+ RGB_out <= gamma_en ? {gamma_curve_r[gamma_index_r],gamma_curve_g[gamma_index_g],gamma_curve_b[gamma_index_b]}
+ : {gamma_index_r,gamma_index_g,gamma_index_b};
+ HSync_out <= hs; VSync_out <= vs;
+ HBlank_out <= hb; VBlank_out <= vb;
+ DE_out <= de;
+ end
+end
+
+endmodule
diff --git a/sys/hps_io.v b/sys/hps_io.v
index d4d87cb..1f37785 100644
--- a/sys/hps_io.v
+++ b/sys/hps_io.v
@@ -2,7 +2,7 @@
// hps_io.v
//
// Copyright (c) 2014 Till Harbaum
-// Copyright (c) 2017-2019 Alexey Melnikov
+// Copyright (c) 2017-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
@@ -18,14 +18,11 @@
// along with this program. If not, see .
//
///////////////////////////////////////////////////////////////////////
+// altera message_off 10665
//
// Use buffer to access SD card. It's time-critical part.
//
-// for synchronous projects default value for PS2DIV is fine for any frequency of system clock.
-// clk_ps2 = CLK_SYS/(PS2DIV*2)
-//
-
// WIDE=1 for 16 bit file I/O
// VDNUM 1-4
module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
@@ -36,12 +33,15 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
// parameter STRLEN and the actual length of conf_str have to match
input [(8*STRLEN)-1:0] conf_str,
+ // buttons up to 32
output reg [31:0] joystick_0,
output reg [31:0] joystick_1,
output reg [31:0] joystick_2,
output reg [31:0] joystick_3,
output reg [31:0] joystick_4,
output reg [31:0] joystick_5,
+
+ // analog -127..+127, Y: [15:8], X: [7:0]
output reg [15:0] joystick_analog_0,
output reg [15:0] joystick_analog_1,
output reg [15:0] joystick_analog_2,
@@ -49,14 +49,34 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
output reg [15:0] joystick_analog_4,
output reg [15:0] joystick_analog_5,
+ // paddle 0..255
+ output reg [7:0] paddle_0,
+ output reg [7:0] paddle_1,
+ output reg [7:0] paddle_2,
+ output reg [7:0] paddle_3,
+ output reg [7:0] paddle_4,
+ output reg [7:0] paddle_5,
+
+ // spinner [7:0] -128..+127, [8] - toggle with every update
+ output reg [8:0] spinner_0,
+ output reg [8:0] spinner_1,
+ output reg [8:0] spinner_2,
+ output reg [8:0] spinner_3,
+ output reg [8:0] spinner_4,
+ output reg [8:0] spinner_5,
+
output [1:0] buttons,
output forced_scandoubler,
+ output direct_video,
- output reg [31:0] status,
- input [31:0] status_in,
+ 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,
@@ -126,31 +146,42 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
// [24] - toggles with every event
output reg [24:0] ps2_mouse = 0,
- output reg [15:0] ps2_mouse_ext = 0 // 15:8 - reserved(additional buttons), 7:0 - wheel movements
+ output reg [15:0] ps2_mouse_ext = 0, // 15:8 - reserved(additional buttons), 7:0 - wheel movements
+
+ inout [21:0] gamma_bus,
+
+ // for core-specific extensions
+ inout [35:0] EXT_BUS
);
+assign EXT_BUS[31:16] = HPS_BUS[31:16];
+assign EXT_BUS[35:33] = HPS_BUS[35:33];
+
+localparam MAX_W = $clog2((512 > (STRLEN+1)) ? 512 : (STRLEN+1))-1;
+
localparam DW = (WIDE) ? 15 : 7;
localparam AW = (WIDE) ? 7 : 8;
localparam VD = VDNUM-1;
-wire io_wait = ioctl_wait;
-wire io_enable= |HPS_BUS[35:34];
-wire io_strobe= HPS_BUS[33];
+wire io_strobe= HPS_BUS[33];
+wire io_enable= HPS_BUS[34];
+wire fp_enable= HPS_BUS[35];
wire io_wide = (WIDE) ? 1'b1 : 1'b0;
wire [15:0] io_din = HPS_BUS[31:16];
reg [15:0] io_dout;
-assign HPS_BUS[37] = io_wait;
+assign HPS_BUS[37] = ioctl_wait;
assign HPS_BUS[36] = clk_sys;
assign HPS_BUS[32] = io_wide;
-assign HPS_BUS[15:0] = io_dout;
+assign HPS_BUS[15:0] = EXT_BUS[32] ? EXT_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 =
@@ -169,129 +200,51 @@ wire [15:0] sd_cmd =
sd_rd[0]
};
-///////////////// calc video parameters //////////////////
+/////////////////////////////////////////////////////////
-wire clk_100 = HPS_BUS[43];
-wire clk_vid = HPS_BUS[42];
-wire ce_pix = HPS_BUS[41];
-wire de = HPS_BUS[40];
-wire hs = HPS_BUS[39];
-wire vs = HPS_BUS[38];
-wire vs_hdmi = HPS_BUS[44];
-wire f1 = HPS_BUS[45];
-
-reg [31:0] vid_hcnt = 0;
-reg [31:0] vid_vcnt = 0;
-reg [7:0] vid_nres = 0;
-reg [1:0] vid_int = 0;
-integer hcnt;
-
-always @(posedge clk_vid) begin
- integer vcnt;
- reg old_vs= 0, old_de = 0, old_vmode = 0;
- reg [3:0] resto = 0;
- reg calch = 0;
-
- if(ce_pix) begin
- old_vs <= vs;
- old_de <= de;
-
- if(~vs & ~old_de & de) vcnt <= vcnt + 1;
- if(calch & de) hcnt <= hcnt + 1;
- if(old_de & ~de) calch <= 0;
-
- if(old_vs & ~vs) begin
- vid_int <= {vid_int[0],f1};
- if(~f1) begin
- if(hcnt && vcnt) begin
- old_vmode <= new_vmode;
-
- //report new resolution after timeout
- if(resto) resto <= resto + 1'd1;
- if(vid_hcnt != hcnt || vid_vcnt != vcnt || old_vmode != new_vmode) resto <= 1;
- if(&resto) vid_nres <= vid_nres + 1'd1;
- vid_hcnt <= hcnt;
- vid_vcnt <= vcnt;
- end
- vcnt <= 0;
- hcnt <= 0;
- calch <= 1;
- end
- end
- end
-end
-
-reg [31:0] vid_htime = 0;
-reg [31:0] vid_vtime = 0;
-reg [31:0] vid_pix = 0;
-
-always @(posedge clk_100) begin
- integer vtime, htime, hcnt;
- reg old_vs, old_hs, old_vs2, old_hs2, old_de, old_de2;
- reg calch = 0;
-
- old_vs <= vs;
- old_hs <= hs;
-
- old_vs2 <= old_vs;
- old_hs2 <= old_hs;
-
- vtime <= vtime + 1'd1;
- htime <= htime + 1'd1;
-
- if(~old_vs2 & old_vs) begin
- vid_pix <= hcnt;
- vid_vtime <= vtime;
- vtime <= 0;
- hcnt <= 0;
- end
-
- if(old_vs2 & ~old_vs) calch <= 1;
-
- if(~old_hs2 & old_hs) begin
- vid_htime <= htime;
- htime <= 0;
- end
-
- old_de <= de;
- old_de2 <= old_de;
-
- if(calch & old_de) hcnt <= hcnt + 1;
- if(old_de2 & ~old_de) calch <= 0;
-end
-
-reg [31:0] vid_vtime_hdmi;
-always @(posedge clk_100) begin
- integer vtime;
- reg old_vs, old_vs2;
-
- old_vs <= vs_hdmi;
- old_vs2 <= old_vs;
-
- vtime <= vtime + 1'd1;
-
- if(~old_vs2 & old_vs) begin
- vid_vtime_hdmi <= vtime;
- vtime <= 0;
- end
-end
+wire [15:0] vc_dout;
+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]),
+ .vs(HPS_BUS[38]),
+ .vs_hdmi(HPS_BUS[44]),
+ .f1(HPS_BUS[45]),
+ .new_vmode(new_vmode),
+ .par_num(byte_cnt[3:0]),
+ .dout(vc_dout)
+);
/////////////////////////////////////////////////////////
+assign gamma_bus[20:0] = {clk_sys, gamma_en, gamma_wr, gamma_wr_addr, gamma_value};
+reg gamma_en;
+reg gamma_wr;
+reg [9:0] gamma_wr_addr;
+reg [7:0] gamma_value;
+
reg [31:0] ps2_key_raw = 0;
wire pressed = (ps2_key_raw[15:8] != 8'hf0);
wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0));
+reg [MAX_W:0] byte_cnt;
+
always@(posedge clk_sys) begin
reg [15:0] cmd;
- reg [9:0] byte_cnt; // counts bytes
reg [2:0] b_wr;
- reg [2:0] stick_idx;
+ reg [3:0] stick_idx;
+ reg [3:0] pdsp_idx;
reg ps2skip = 0;
reg [3:0] stflg = 0;
- reg [31:0] status_req;
+ reg [63:0] status_req;
reg old_status_set = 0;
+ reg old_info = 0;
+ reg [7:0] info_n = 0;
old_status_set <= status_set;
if(~old_status_set & status_set) begin
@@ -299,12 +252,17 @@ always@(posedge clk_sys) begin
status_req <= status_in;
end
+ old_info <= info_req;
+ if(~old_info & info_req) info_n <= info;
+
sd_buff_wr <= b_wr[0];
if(b_wr[2] && (~&sd_buff_addr)) sd_buff_addr <= sd_buff_addr + 1'b1;
b_wr <= (b_wr<<1);
if(PS2DIV) {kbd_rd,kbd_we,mouse_rd,mouse_we} <= 0;
+ gamma_wr <= 0;
+
if(~io_enable) begin
if(cmd == 4 && !ps2skip) ps2_mouse[24] <= ~ps2_mouse[24];
if(cmd == 5 && !ps2skip) begin
@@ -321,53 +279,55 @@ always@(posedge clk_sys) begin
sd_ack_conf <= 0;
io_dout <= 0;
ps2skip <= 0;
- end else begin
- if(io_strobe) begin
+ end
+ else if(io_strobe) begin
- io_dout <= 0;
- if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1;
+ io_dout <= 0;
+ if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1;
- if(byte_cnt == 0) begin
- cmd <= io_din;
+ if(byte_cnt == 0) begin
+ cmd <= io_din;
- case(io_din)
- 'h19: sd_ack_conf <= 1;
- 'h17,
- 'h18: sd_ack <= 1;
- 'h29: io_dout <= {4'hA, stflg};
- 'h2B: io_dout <= 1;
- 'h2F: io_dout <= 1;
- endcase
+ case(io_din)
+ 'h19: sd_ack_conf <= 1;
+ 'h17,
+ 'h18: sd_ack <= 1;
+ 'h29: io_dout <= {4'hA, stflg};
+ 'h2B: io_dout <= 1;
+ 'h2F: io_dout <= 1;
+ 'h32: io_dout <= gamma_bus[21];
+ 'h36: begin io_dout <= info_n; info_n <= 0; end
+ endcase
- sd_buff_addr <= 0;
- img_mounted <= 0;
- if(io_din == 5) ps2_key_raw <= 0;
- end else begin
+ sd_buff_addr <= 0;
+ img_mounted <= 0;
+ if(io_din == 5) ps2_key_raw <= 0;
+ end else begin
- case(cmd)
- // buttons and switches
- 'h01: cfg <= io_din[7:0];
- '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;
- 'h11: if(byte_cnt==1) joystick_3[15:0] <= io_din; else joystick_3[31:16] <= io_din;
- 'h12: if(byte_cnt==1) joystick_4[15:0] <= io_din; else joystick_4[31:16] <= io_din;
- 'h13: if(byte_cnt==1) joystick_5[15:0] <= io_din; else joystick_5[31:16] <= io_din;
+ case(cmd)
+ // buttons and switches
+ '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;
+ 'h11: if(byte_cnt==1) joystick_3[15:0] <= io_din; else joystick_3[31:16] <= io_din;
+ 'h12: if(byte_cnt==1) joystick_4[15:0] <= io_din; else joystick_4[31:16] <= io_din;
+ 'h13: if(byte_cnt==1) joystick_5[15:0] <= io_din; else joystick_5[31:16] <= io_din;
- // store incoming ps2 mouse bytes
- 'h04: begin
+ // store incoming ps2 mouse bytes
+ 'h04: begin
if(PS2DIV) begin
mouse_data <= io_din[7:0];
mouse_we <= 1;
end
if(&io_din[15:8]) ps2skip <= 1;
- if(~&io_din[15:8] & ~ps2skip) begin
- case(byte_cnt)
+ if(~&io_din[15:8] && ~ps2skip && !byte_cnt[MAX_W:2]) begin
+ case(byte_cnt[1:0])
1: ps2_mouse[7:0] <= io_din[7:0];
2: ps2_mouse[15:8] <= io_din[7:0];
3: ps2_mouse[23:16] <= io_din[7:0];
endcase
- case(byte_cnt)
+ case(byte_cnt[1:0])
1: ps2_mouse_ext[7:0] <= {io_din[14], io_din[14:8]};
2: ps2_mouse_ext[11:8] <= io_din[11:8];
3: ps2_mouse_ext[15:12]<= io_din[11:8];
@@ -375,8 +335,8 @@ always@(posedge clk_sys) begin
end
end
- // store incoming ps2 keyboard bytes
- 'h05: begin
+ // store incoming ps2 keyboard bytes
+ 'h05: begin
if(&io_din[15:8]) ps2skip <= 1;
if(~&io_din[15:8] & ~ps2skip) ps2_key_raw[31:0] <= {ps2_key_raw[23:0], io_din[7:0]};
if(PS2DIV) begin
@@ -385,116 +345,137 @@ always@(posedge clk_sys) begin
end
end
- // reading config string, returning a byte from string
- 'h14: if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8];
+ // reading config string, returning a byte from string
+ 'h14: if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8];
- // reading sd card status
- 'h16: case(byte_cnt)
+ // reading sd card status
+ 'h16: if(!byte_cnt[MAX_W:3]) begin
+ case(byte_cnt[2:0])
1: io_dout <= sd_cmd;
2: io_dout <= sd_lba[15:0];
3: io_dout <= sd_lba[31:16];
4: io_dout <= sd_req_type;
endcase
+ end
- // send SD config IO -> FPGA
- // flag that download begins
- // sd card knows data is config if sd_dout_strobe is asserted
- // with sd_ack still being inactive (low)
- 'h19,
- // send sector IO -> FPGA
- // flag that download begins
- 'h17: begin
+ // send SD config IO -> FPGA
+ // flag that download begins
+ // sd card knows data is config if sd_dout_strobe is asserted
+ // with sd_ack still being inactive (low)
+ 'h19,
+ // send sector IO -> FPGA
+ // flag that download begins
+ 'h17: begin
sd_buff_dout <= io_din[DW:0];
b_wr <= 1;
end
- // reading sd card write data
- 'h18: begin
+ // reading sd card write data
+ 'h18: begin
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
io_dout <= sd_buff_din;
end
- // joystick analog
- 'h1a: case(byte_cnt)
- 1: stick_idx <= io_din[2:0]; // first byte is joystick index
+ // joystick analog
+ 'h1a: if(!byte_cnt[MAX_W:2]) begin
+ case(byte_cnt[1:0])
+ 1: {pdsp_idx,stick_idx} <= io_din[7:0]; // first byte is joystick index
2: case(stick_idx)
- 0: joystick_analog_0 <= io_din;
- 1: joystick_analog_1 <= io_din;
- 2: joystick_analog_2 <= io_din;
- 3: joystick_analog_3 <= io_din;
- 4: joystick_analog_4 <= io_din;
- 5: joystick_analog_5 <= io_din;
+ 0: joystick_analog_0 <= io_din;
+ 1: joystick_analog_1 <= io_din;
+ 2: joystick_analog_2 <= io_din;
+ 3: joystick_analog_3 <= io_din;
+ 4: joystick_analog_4 <= io_din;
+ 5: joystick_analog_5 <= io_din;
+ 15: case(pdsp_idx)
+ 0: paddle_0 <= io_din[7:0];
+ 1: paddle_1 <= io_din[7:0];
+ 2: paddle_2 <= io_din[7:0];
+ 3: paddle_3 <= io_din[7:0];
+ 4: paddle_4 <= io_din[7:0];
+ 5: paddle_5 <= io_din[7:0];
+ 8: spinner_0 <= {~spinner_0[8],io_din[7:0]};
+ 9: spinner_1 <= {~spinner_1[8],io_din[7:0]};
+ 10: spinner_2 <= {~spinner_2[8],io_din[7:0]};
+ 11: spinner_3 <= {~spinner_3[8],io_din[7:0]};
+ 12: spinner_4 <= {~spinner_4[8],io_din[7:0]};
+ 13: spinner_5 <= {~spinner_5[8],io_din[7:0]};
+ endcase
endcase
endcase
+ end
- // notify image selection
- 'h1c: begin
+ // notify image selection
+ 'h1c: begin
img_mounted <= io_din[VD:0] ? io_din[VD:0] : 1'b1;
img_readonly <= io_din[7];
end
- // send image info
- 'h1d: if(byte_cnt<5) img_size[{byte_cnt-1'b1, 4'b0000} +:16] <= io_din;
+ // send image info
+ 'h1d: if(byte_cnt<5) img_size[{byte_cnt-1'b1, 4'b0000} +:16] <= io_din;
- // status, 32bit version
- 'h1e: if(byte_cnt==1) status[15:0] <= io_din;
- else if(byte_cnt==2) status[31:16] <= io_din;
+ // status, 64bit version
+ 'h1e: if(!byte_cnt[MAX_W:3]) begin
+ case(byte_cnt[2:0])
+ 1: status[15:00] <= io_din;
+ 2: status[31:16] <= io_din;
+ 3: status[47:32] <= io_din;
+ 4: status[63:48] <= io_din;
+ endcase
+ end
- // reading keyboard LED status
- 'h1f: io_dout <= {|PS2WE, 2'b01, ps2_kbd_led_status[2], ps2_kbd_led_use[2], ps2_kbd_led_status[1], ps2_kbd_led_use[1], ps2_kbd_led_status[0], ps2_kbd_led_use[0]};
+ // reading keyboard LED status
+ 'h1f: io_dout <= {|PS2WE, 2'b01, ps2_kbd_led_status[2], ps2_kbd_led_use[2], ps2_kbd_led_status[1], ps2_kbd_led_use[1], ps2_kbd_led_status[0], ps2_kbd_led_use[0]};
- // reading ps2 keyboard/mouse control
- 'h21: if(PS2DIV) begin
- if(byte_cnt == 1) begin
- io_dout <= kbd_data_host;
- kbd_rd <= 1;
- end
- else
- if(byte_cnt == 2) begin
- io_dout <= mouse_data_host;
- mouse_rd <= 1;
- end
+ // reading ps2 keyboard/mouse control
+ 'h21: if(PS2DIV) begin
+ if(byte_cnt == 1) begin
+ io_dout <= kbd_data_host;
+ kbd_rd <= 1;
end
+ else
+ if(byte_cnt == 2) begin
+ io_dout <= mouse_data_host;
+ mouse_rd <= 1;
+ end
+ end
- //RTC
- 'h22: RTC[(byte_cnt-6'd1)<<4 +:16] <= io_din;
+ //RTC
+ 'h22: RTC[(byte_cnt-6'd1)<<4 +:16] <= io_din;
- //Video res.
- 'h23: case(byte_cnt)
- 1: io_dout <= {|vid_int, vid_nres};
- 2: io_dout <= vid_hcnt[15:0];
- 3: io_dout <= vid_hcnt[31:16];
- 4: io_dout <= vid_vcnt[15:0];
- 5: io_dout <= vid_vcnt[31:16];
- 6: io_dout <= vid_htime[15:0];
- 7: io_dout <= vid_htime[31:16];
- 8: io_dout <= vid_vtime[15:0];
- 9: io_dout <= vid_vtime[31:16];
- 10: io_dout <= vid_pix[15:0];
- 11: io_dout <= vid_pix[31:16];
- 12: io_dout <= vid_vtime_hdmi[15:0];
- 13: io_dout <= vid_vtime_hdmi[31:16];
- endcase
+ //Video res.
+ 'h23: if(!byte_cnt[MAX_W:4]) io_dout <= vc_dout;
- //RTC
- 'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din;
+ //RTC
+ 'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din;
- //UART flags
- 'h28: io_dout <= uart_mode;
+ //UART flags
+ 'h28: io_dout <= uart_mode;
- //status set
- 'h29: case(byte_cnt)
- 1: io_dout <= status_req[15:0];
+ //status set
+ 'h29: if(!byte_cnt[MAX_W:3]) begin
+ case(byte_cnt[2:0])
+ 1: io_dout <= status_req[15:00];
2: io_dout <= status_req[31:16];
+ 3: io_dout <= status_req[47:32];
+ 4: io_dout <= status_req[63:48];
endcase
-
- //menu mask
- 'h2E: if(byte_cnt == 1) io_dout <= status_menumask;
+ end
- //sdram size set
- 'h31: if(byte_cnt == 1) sdram_sz <= io_din;
- endcase
- end
+ //menu mask
+ 'h2E: if(byte_cnt == 1) io_dout <= status_menumask;
+
+ //sdram size set
+ 'h31: if(byte_cnt == 1) sdram_sz <= io_din;
+
+ // Gamma
+ 'h32: gamma_en <= io_din[0];
+ 'h33: begin
+ gamma_wr_addr <= {(byte_cnt[1:0]-1'b1),io_din[15:8]};
+ {gamma_wr, gamma_value} <= {1'b1,io_din[7:0]};
+ if (byte_cnt[1:0] == 3) byte_cnt <= 1;
+ end
+ endcase
end
end
end
@@ -504,7 +485,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
@@ -580,11 +561,11 @@ always@(posedge clk_sys) begin
reg has_cmd;
reg [26:0] addr;
reg wr;
-
+
ioctl_wr <= wr;
wr <= 0;
- if(~io_enable) has_cmd <= 0;
+ if(~fp_enable) has_cmd <= 0;
else begin
if(io_strobe) begin
@@ -777,89 +758,138 @@ end
endmodule
-//
-// Phase shift helper module for better 64MB/128MB modules support.
-//
-// Copyright (c) 2019 Alexey Melnikov
-//
-module phase_shift #(parameter M32MB=0, M64MB=0, M128MB=0)
+///////////////// calc video parameters //////////////////
+module video_calc
(
- input reset,
+ input clk_100,
+ input clk_vid,
+ input clk_sys,
- input clk,
- input pll_locked,
+ input ce_pix,
+ input de,
+ input hs,
+ input vs,
+ input vs_hdmi,
+ input f1,
+ input new_vmode,
- output reg phase_en,
- output reg updn,
- input phase_done,
-
- input [15:0] sdram_sz,
- output reg ready
+ input [3:0] par_num,
+ output reg [15:0] dout
);
-localparam ph32 = ($signed(M32MB ) >= 0) ? M32MB : (0 - M32MB);
-localparam ph64 = ($signed(M64MB ) >= 0) ? M64MB : (0 - M64MB);
-localparam ph128 = ($signed(M128MB) >= 0) ? M128MB : (0 - M128MB);
+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;
+ endcase
+end
-localparam up32 = ($signed(M32MB ) >= 0) ? 1'b1 : 1'b0;
-localparam up64 = ($signed(M64MB ) >= 0) ? 1'b1 : 1'b0;
-localparam up128 = ($signed(M128MB) >= 0) ? 1'b1 : 1'b0;
+reg [31:0] vid_hcnt = 0;
+reg [31:0] vid_vcnt = 0;
+reg [7:0] vid_nres = 0;
+reg [1:0] vid_int = 0;
-always @(posedge clk, posedge reset) begin
- reg [2:0] state = 0;
- reg [7:0] cnt;
- reg [8:0] ph;
-
- if(reset) begin
- state <= 0;
- ready <= 0;
+always @(posedge clk_vid) begin
+ integer hcnt;
+ integer vcnt;
+ reg old_vs= 0, old_de = 0, old_vmode = 0;
+ reg [3:0] resto = 0;
+ reg calch = 0;
+
+ if(ce_pix) begin
+ old_vs <= vs;
+ old_de <= de;
+
+ if(~vs & ~old_de & de) vcnt <= vcnt + 1;
+ if(calch & de) hcnt <= hcnt + 1;
+ if(old_de & ~de) calch <= 0;
+
+ if(old_vs & ~vs) begin
+ vid_int <= {vid_int[0],f1};
+ if(~f1) begin
+ if(hcnt && vcnt) begin
+ old_vmode <= new_vmode;
+
+ //report new resolution after timeout
+ if(resto) resto <= resto + 1'd1;
+ if(vid_hcnt != hcnt || vid_vcnt != vcnt || old_vmode != new_vmode) resto <= 1;
+ if(&resto) vid_nres <= vid_nres + 1'd1;
+ vid_hcnt <= hcnt;
+ vid_vcnt <= vcnt;
+ end
+ vcnt <= 0;
+ hcnt <= 0;
+ calch <= 1;
+ end
+ end
end
- else begin
- case(state)
- 0: begin
- ready <= 0;
- if(pll_locked) state <= state + 1'd1;
- end
- 1: if(sdram_sz[15]) begin
- cnt <= 0;
- if(sdram_sz[14]) ph <= sdram_sz[8:0];
- else begin
- case(sdram_sz[1:0])
- 0: ph <= 0;
- 1: ph <= {up32[0],ph32[7:0]};
- 2: ph <= {up64[0],ph64[7:0]};
- 3: ph <= {up128[0],ph128[7:0]};
- endcase
- end
- state <= state + 1'd1;
- end
- 2: if(ph[7:0]) begin
- ph[7:0] <= ph[7:0] - 1'd1;
- updn <= ph[8];
- state <= state + 1'd1;
- end
- else begin
- state <= 6;
- end
- 3: begin
- phase_en <= 1;
- state <= state + 1'd1;
- end
- 4: if(~phase_done) begin
- phase_en <= 0;
- state <= state + 1'd1;
- end
- 5: if(phase_done) begin
- cnt <= cnt + 1'd1;
- if(cnt == ph[7:0]) state <= state + 1'd1;
- else state <= 3;
- end
- 6: begin
- ready <= 1;
- if(!sdram_sz[15]) state <= 0;
- end
- endcase
+end
+
+reg [31:0] vid_htime = 0;
+reg [31:0] vid_vtime = 0;
+reg [31:0] vid_pix = 0;
+
+always @(posedge clk_100) begin
+ integer vtime, htime, hcnt;
+ reg old_vs, old_hs, old_vs2, old_hs2, old_de, old_de2;
+ reg calch = 0;
+
+ old_vs <= vs;
+ old_hs <= hs;
+
+ old_vs2 <= old_vs;
+ old_hs2 <= old_hs;
+
+ vtime <= vtime + 1'd1;
+ htime <= htime + 1'd1;
+
+ if(~old_vs2 & old_vs) begin
+ vid_pix <= hcnt;
+ vid_vtime <= vtime;
+ vtime <= 0;
+ hcnt <= 0;
+ end
+
+ if(old_vs2 & ~old_vs) calch <= 1;
+
+ if(~old_hs2 & old_hs) begin
+ vid_htime <= htime;
+ htime <= 0;
+ end
+
+ old_de <= de;
+ old_de2 <= old_de;
+
+ if(calch & old_de) hcnt <= hcnt + 1;
+ if(old_de2 & ~old_de) calch <= 0;
+end
+
+reg [31:0] vid_vtime_hdmi;
+always @(posedge clk_100) begin
+ integer vtime;
+ reg old_vs, old_vs2;
+
+ old_vs <= vs_hdmi;
+ old_vs2 <= old_vs;
+
+ vtime <= vtime + 1'd1;
+
+ if(~old_vs2 & old_vs) begin
+ vid_vtime_hdmi <= vtime;
+ vtime <= 0;
end
end
diff --git a/sys/hq2x.sv b/sys/hq2x.sv
index d7c58f9..f5fcc71 100644
--- a/sys/hq2x.sv
+++ b/sys/hq2x.sv
@@ -8,9 +8,7 @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
-// synopsys translate_off
-`timescale 1 ps / 1 ps
-// synopsys translate_on
+// altera message_off 10030
module Hq2x #(parameter LENGTH, parameter HALF_DEPTH)
(
@@ -34,24 +32,29 @@ localparam AWIDTH = $clog2(LENGTH)-1;
localparam DWIDTH = HALF_DEPTH ? 11 : 23;
localparam DWIDTH1 = DWIDTH+1;
-wire [5:0] hqTable[256] = '{
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
- 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
- 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
- 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
- 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
-};
+(* romstyle = "MLAB" *) reg [5:0] hqTable[256];
+initial begin
+ hqTable = '{
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
+ 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
+ 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
+ 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
+ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
+ };
+end
+
+wire [5:0] hqrule = hqTable[nextpatt];
reg [23:0] Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2;
reg [23:0] A, B, D, F, G, H;
@@ -70,7 +73,7 @@ wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]};
wire [23:0] X = (cyc == 0) ? A : (cyc == 1) ? Prev1 : (cyc == 2) ? Next1 : G;
wire [23:0] blend_result_pre;
-Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result_pre);
+Blend blender(clk, ce_in, disable_hq2x ? 6'd0 : hqrule, Curr0, X, B, D, F, H, blend_result_pre);
wire [DWIDTH:0] Curr20tmp;
wire [23:0] Curr20 = HALF_DEPTH ? h2rgb(Curr20tmp) : Curr20tmp;
@@ -146,12 +149,28 @@ reg [AWIDTH:0] offs;
always @(posedge clk) begin
reg old_reset_line;
reg old_reset_frame;
+ reg [3:0] wrdata_finished;
+ reg [AWIDTH+1:0] waddr;
wrout_en <= 0;
wrin_en <= 0;
if(ce_in) begin
+ // blend_result has been delayed by 4 cycles
+ case(cyc)
+ 0: wrdata[DWIDTH:0] <= blend_result;
+ 1: wrdata[DWIDTH1+DWIDTH:DWIDTH1] <= blend_result;
+ 2: wrdata[DWIDTH1*3+DWIDTH:DWIDTH1*3] <= blend_result;
+ 3: wrdata[DWIDTH1*2+DWIDTH:DWIDTH1*2] <= blend_result;
+ endcase
+
+ wrdata_finished <= wrdata_finished << 1;
+ if(wrdata_finished[3]) begin
+ wrout_en <= 1;
+ wrout_addr <= waddr;
+ end
+
if(~&offs) begin
if (cyc == 1) begin
Prev2 <= Curr20;
@@ -162,17 +181,10 @@ always @(posedge clk) begin
wrin_en <= 1;
end
- case({cyc[1],^cyc})
- 0: wrdata[DWIDTH:0] <= blend_result;
- 1: wrdata[DWIDTH1+DWIDTH:DWIDTH1] <= blend_result;
- 2: wrdata[DWIDTH1*2+DWIDTH:DWIDTH1*2] <= blend_result;
- 3: wrdata[DWIDTH1*3+DWIDTH:DWIDTH1*3] <= blend_result;
- endcase
-
if(cyc==3) begin
offs <= offs + 1'd1;
- wrout_addr <= {offs, curbuf};
- wrout_en <= 1;
+ waddr <= {offs, curbuf};
+ wrdata_finished[0] <= 1;
end
end
@@ -225,26 +237,27 @@ module hq2x_in #(parameter LENGTH, parameter DWIDTH)
input wren
);
- localparam AWIDTH = $clog2(LENGTH)-1;
- wire [DWIDTH:0] out[2];
- assign q0 = out[rdbuf0];
- assign q1 = out[rdbuf1];
+localparam AWIDTH = $clog2(LENGTH)-1;
+wire [DWIDTH:0] out[2];
+assign q0 = out[rdbuf0];
+assign q1 = out[rdbuf1];
+
+hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
+hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
- hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
- hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
endmodule
module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH)
(
- input clock,
- input [DWIDTH:0] data,
- input [AWIDTH:0] rdaddress,
- input [AWIDTH:0] wraddress,
- input wren,
- output logic [DWIDTH:0] q
+ input clock,
+ input [DWIDTH:0] data,
+ input [AWIDTH:0] rdaddress,
+ input [AWIDTH:0] wraddress,
+ input wren,
+ output reg [DWIDTH:0] q
);
-logic [DWIDTH:0] ram[0:NUMWORDS-1];
+reg [DWIDTH:0] ram[0:NUMWORDS-1];
always_ff@(posedge clock) begin
if(wren) ram[wraddress] <= data;
@@ -259,15 +272,14 @@ module DiffCheck
(
input [23:0] rgb1,
input [23:0] rgb2,
- output result
+ output result
);
wire [7:0] r = rgb1[7:1] - rgb2[7:1];
wire [7:0] g = rgb1[15:9] - rgb2[15:9];
wire [7:0] b = rgb1[23:17] - rgb2[23:17];
wire [8:0] t = $signed(r) + $signed(b);
- wire [8:0] gx = {g[7], g};
- wire [9:0] y = $signed(t) + $signed(gx);
+ wire [9:0] y = $signed(t) + $signed({g[7], g});
wire [8:0] u = $signed(r) - $signed(b);
wire [9:0] v = $signed({g, 1'b0}) - $signed(t);
@@ -275,48 +287,19 @@ module DiffCheck
wire y_inside = (y < 10'h60 || y >= 10'h3a0);
// if u is inside (-16, 16)
- wire u_inside = (u < 9'h10 || u >= 9'h1f0);
+ wire u_inside = (!u[8:4] || &u[8:4]); //(u < 9'h10 || u >= 9'h1f0);
// if v is inside (-24, 24)
wire v_inside = (v < 10'h18 || v >= 10'h3e8);
assign result = !(y_inside && u_inside && v_inside);
-endmodule
-module InnerBlend
-(
- input [8:0] Op,
- input [7:0] A,
- input [7:0] B,
- input [7:0] C,
- output [7:0] O
-);
-
- function [10:0] mul8x3;
- input [7:0] op1;
- input [2:0] op2;
- begin
- mul8x3 = 11'd0;
- if(op2[0]) mul8x3 = mul8x3 + op1;
- if(op2[1]) mul8x3 = mul8x3 + {op1, 1'b0};
- if(op2[2]) mul8x3 = mul8x3 + {op1, 2'b00};
- end
- endfunction
-
- wire OpOnes = Op[4];
- wire [10:0] Amul = mul8x3(A, Op[7:5]);
- wire [10:0] Bmul = mul8x3(B, {Op[3:2], 1'b0});
- wire [10:0] Cmul = mul8x3(C, {Op[1:0], 1'b0});
- wire [10:0] At = Amul;
- wire [10:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B};
- wire [10:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C};
- wire [11:0] Res = {At, 1'b0} + Bt + Ct;
- assign O = Op[8] ? A : Res[11:4];
endmodule
module Blend
(
+ input clk,
+ input clk_en,
input [5:0] rule,
- input disable_hq2x,
input [23:0] E,
input [23:0] A,
input [23:0] B,
@@ -326,66 +309,63 @@ module Blend
output [23:0] Result
);
- reg [1:0] input_ctrl;
- reg [8:0] op;
- localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A
- localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4
- localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4
- localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4
- localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4
- localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4
- localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4
- localparam AB = 2'b00;
- localparam AD = 2'b01;
- localparam DB = 2'b10;
- localparam BD = 2'b11;
- wire is_diff;
- DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff);
+ localparam BLEND1 = 7'b110_10_00; // (A * 12 + B * 4 ) >> 4
+ localparam BLEND2 = 7'b100_10_10; // (A * 8 + B * 4 + C * 4) >> 4
+ localparam BLEND3 = 7'b101_10_01; // (A * 10 + B * 4 + C * 2) >> 4
+ localparam BLEND4 = 7'b110_01_01; // (A * 12 + B * 2 + C * 2) >> 4
+ localparam BLEND5 = 7'b010_11_11; // (A * 4 + B * 6 + C * 6) >> 4
+ localparam BLEND6 = 7'b111_00_00; // (A * 14 + B * 1 + C * 1) >> 4
- always @* begin
- case({!is_diff, rule[5:2]})
- 1,17: {op, input_ctrl} = {BLEND1, AB};
- 2,18: {op, input_ctrl} = {BLEND1, DB};
- 3,19: {op, input_ctrl} = {BLEND1, BD};
- 4,20: {op, input_ctrl} = {BLEND2, DB};
- 5,21: {op, input_ctrl} = {BLEND2, AB};
- 6,22: {op, input_ctrl} = {BLEND2, AD};
-
- 8: {op, input_ctrl} = {BLEND0, 2'bxx};
- 9: {op, input_ctrl} = {BLEND0, 2'bxx};
- 10: {op, input_ctrl} = {BLEND0, 2'bxx};
- 11: {op, input_ctrl} = {BLEND1, AB};
- 12: {op, input_ctrl} = {BLEND1, AB};
- 13: {op, input_ctrl} = {BLEND1, AB};
- 14: {op, input_ctrl} = {BLEND1, DB};
- 15: {op, input_ctrl} = {BLEND1, BD};
-
- 24: {op, input_ctrl} = {BLEND2, DB};
- 25: {op, input_ctrl} = {BLEND5, DB};
- 26: {op, input_ctrl} = {BLEND6, DB};
- 27: {op, input_ctrl} = {BLEND2, DB};
- 28: {op, input_ctrl} = {BLEND4, DB};
- 29: {op, input_ctrl} = {BLEND5, DB};
- 30: {op, input_ctrl} = {BLEND3, BD};
- 31: {op, input_ctrl} = {BLEND3, DB};
- default: {op, input_ctrl} = {11{1'bx}};
- endcase
-
- // Setting op[8] effectively disables HQ2X because blend will always return E.
- if (disable_hq2x) op[8] = 1;
+ reg [23:0] a,b,d,e,h,f;
+ reg [3:0] bl_rule;
+ reg [1:0] df_rule;
+ always @(posedge clk) if (clk_en) begin
+ {bl_rule,df_rule} <= rule;
+ a <= A; b <= B; d <= D; e <= E; f <= F; h <= H;
end
- // Generate inputs to the inner blender. Valid combinations.
- // 00: E A B
- // 01: E A D
- // 10: E D B
- // 11: E B D
- wire [23:0] Input1 = E;
- wire [23:0] Input2 = !input_ctrl[1] ? A :
- !input_ctrl[0] ? D : B;
+ wire is_diff;
+ DiffCheck diff_checker(df_rule[1] ? b : h, df_rule[0] ? d : f, is_diff);
+
+ reg [23:0] i10,i20,i30;
+ reg [6:0] op0;
+ always @(posedge clk) if (clk_en) begin
+ i10 <= e;
+ case({!is_diff, bl_rule})
+ 1,11,12,13,17: {op0, i20, i30} <= {BLEND1, a, 24'd0};
+ 2,14,18: {op0, i20, i30} <= {BLEND1, d, 24'd0};
+ 3,15,19: {op0, i20, i30} <= {BLEND1, b, 24'd0};
+ 4,20,24,27: {op0, i20, i30} <= {BLEND2, d, b};
+ 5,21: {op0, i20, i30} <= {BLEND2, a, b};
+ 6,22: {op0, i20, i30} <= {BLEND2, a, d};
+ 25,29: {op0, i20, i30} <= {BLEND5, d, b};
+ 26: {op0, i20, i30} <= {BLEND6, d, b};
+ 28: {op0, i20, i30} <= {BLEND4, d, b};
+ 30: {op0, i20, i30} <= {BLEND3, b, d};
+ 31: {op0, i20, i30} <= {BLEND3, d, b};
+ default: {op0, i20, i30} <= {BLEND1, e, 24'd0};
+ endcase
+ end
+
+ reg [23:0] i1,i2,i3;
+ reg [6:0] op;
+ always @(posedge clk) if (clk_en) begin
+ op <= op0; i1 <= i10; i2 <= i20; i3 <= i30;
+ end
+
+ function [34:0] mul24x3;
+ input [23:0] op1;
+ input [2:0] op2;
+ begin
+ mul24x3 = 0;
+ if(op2[0]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0]};
+ if(op2[1]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0], 1'b0};
+ if(op2[2]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0], 2'b00};
+ end
+ endfunction
+
+ wire [35:0] res = {mul24x3(i1, op[6:4]), 1'b0} + mul24x3(i2, {op[3:2], !op[3:2]}) + mul24x3(i3, {op[1:0], !op[3:2]});
+
+ always @(posedge clk) if (clk_en) Result <= {res[35:28],res[23:16],res[11:4]};
- wire [23:0] Input3 = !input_ctrl[0] ? B : D;
- InnerBlend inner_blend1(op, Input1[7:0], Input2[7:0], Input3[7:0], Result[7:0]);
- InnerBlend inner_blend2(op, Input1[15:8], Input2[15:8], Input3[15:8], Result[15:8]);
- InnerBlend inner_blend3(op, Input1[23:16], Input2[23:16], Input3[23:16], Result[23:16]);
endmodule
diff --git a/sys/osd.v b/sys/osd.v
index b564a26..a4fbdde 100644
--- a/sys/osd.v
+++ b/sys/osd.v
@@ -22,27 +22,29 @@ module osd
);
parameter OSD_COLOR = 3'd4;
-parameter OSD_X_OFFSET = 12'd0;
-parameter OSD_Y_OFFSET = 12'd0;
localparam OSD_WIDTH = 12'd256;
localparam OSD_HEIGHT = 12'd64;
`ifdef OSD_HEADER
-localparam OSD_HDR = 12'd32;
+localparam OSD_HDR = 12'd24;
`else
localparam OSD_HDR = 12'd0;
`endif
reg osd_enable;
-reg [7:0] osd_buffer[OSD_HDR ? (4096+1024) : 4096];
+(* ramstyle="no_rw_check" *) reg [7:0] osd_buffer[OSD_HDR ? (4096+1024) : 4096];
reg info = 0;
reg [8:0] infoh;
reg [8:0] infow;
-reg [11:0] infox;
+reg [21:0] infox;
reg [21:0] infoy;
-reg [21:0] hrheight;
+reg [21:0] osd_h;
+reg [21:0] osd_t;
+reg [21:0] osd_w;
+
+reg [1:0] rot = 0;
always@(posedge clk_sys) begin
reg [12:0] bcnt;
@@ -51,7 +53,9 @@ always@(posedge clk_sys) begin
reg old_strobe;
reg highres = 0;
- hrheight <= info ? infoh : ((OSD_HEIGHT<> 9) > 1) ? (((cnt+1'b1) >> 9) - 1) : 0;
+ pixsz <= (((cnt+1'b1) >> (9-rot[0])) > 1) ? (((cnt+1'b1) >> (9-rot[0])) - 1'd1) : 22'd0;
pixcnt <= 0;
end
end
@@ -118,26 +123,39 @@ end
reg [2:0] osd_de;
reg osd_pixel;
reg [21:0] v_cnt;
+reg v_cnt_h, v_cnt_1, v_cnt_2, v_cnt_3, v_cnt_4;
+reg [21:0] v_osd_start_h, v_osd_start_1, v_osd_start_2, v_osd_start_3, v_osd_start_4, v_osd_start_5;
+reg [21:0] v_info_start_h, v_info_start_1, v_info_start_2, v_info_start_3, v_info_start_4, v_info_start_5;
-reg v_cnt_below320, v_cnt_below640, v_cnt_below960;
-
-reg [21:0] v_osd_start_320, v_osd_start_640, v_osd_start_960, v_osd_start_other;
+wire [21:0] osd_h_hdr = (info || rot) ? osd_h : (osd_h + OSD_HDR);
// pipeline the comparisons a bit
always @(posedge clk_video) if(ce_pix) begin
- v_cnt_below320 <= v_cnt < 320;
- v_cnt_below640 <= v_cnt < 640;
- v_cnt_below960 <= v_cnt < 960;
- v_osd_start_320 <= ((v_cnt-hrheight)>>1) + OSD_Y_OFFSET;
- v_osd_start_640 <= ((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET;
- v_osd_start_960 <= ((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET;
- v_osd_start_other <= ((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET;
+ v_cnt_h <= v_cnt < osd_t;
+ v_cnt_1 <= v_cnt < 320;
+ v_cnt_2 <= v_cnt < 640;
+ v_cnt_3 <= v_cnt < 960;
+ v_cnt_4 <= v_cnt < 1280;
+
+ v_osd_start_h <= (v_cnt-(osd_h_hdr>>1))>>1;
+ v_osd_start_1 <= (v_cnt-osd_h_hdr)>>1;
+ v_osd_start_2 <= (v_cnt-(osd_h_hdr<<1))>>1;
+ v_osd_start_3 <= (v_cnt-(osd_h_hdr + (osd_h_hdr<<1)))>>1;
+ v_osd_start_4 <= (v_cnt-(osd_h_hdr<<2))>>1;
+ v_osd_start_5 <= (v_cnt-(osd_h_hdr + (osd_h_hdr<<2)))>>1;
+
+ v_info_start_h <= rot[0] ? infox : infoy;
+ v_info_start_1 <= rot[0] ? infox : infoy;
+ v_info_start_2 <= rot[0] ? (infox<<1) : (infoy<<1);
+ v_info_start_3 <= rot[0] ? (infox + (infox << 1)) : (infoy + (infoy << 1));
+ v_info_start_4 <= rot[0] ? (infox << 2) : (infoy << 2);
+ v_info_start_5 <= rot[0] ? (infox + (infox << 2)) : (infoy + (infoy << 2));
end
always @(posedge clk_video) begin
reg deD;
- reg [1:0] osd_div;
- reg [1:0] multiscan;
+ reg [2:0] osd_div;
+ reg [2:0] multiscan;
reg [7:0] osd_byte;
reg [23:0] h_cnt;
reg [21:0] dsp_width;
@@ -145,22 +163,31 @@ always @(posedge clk_video) begin
reg [21:0] h_osd_start;
reg [21:0] v_osd_start;
reg [21:0] osd_hcnt;
+ reg [21:0] osd_hcnt2;
reg osd_de1,osd_de2;
reg [1:0] osd_en;
reg f1;
+ reg half;
if(ce_pix) begin
deD <= de_in;
if(~&h_cnt) h_cnt <= h_cnt + 1'd1;
- if(~&osd_hcnt) osd_hcnt <= osd_hcnt + 1'd1;
+ if(~&osd_hcnt) osd_hcnt <= osd_hcnt + 1'd1;
+ if(~&osd_hcnt2) osd_hcnt2 <= osd_hcnt2 + 1'd1;
+
if (h_cnt == h_osd_start) begin
- osd_de[0] <= osd_en[1] && hrheight && (info ? (osd_vcnt < hrheight) :
- (!osd_vcnt[11:7] || (osd_vcnt[11] && osd_vcnt[7] && (osd_vcnt[6:0] >= 4) && (osd_vcnt[6:0] < 19))));
+ osd_de[0] <= osd_en[1] && osd_h && (
+ osd_vcnt[11] ? (osd_vcnt[7] && (osd_vcnt[6:0] >= 4) && (osd_vcnt[6:0] < 19)) :
+ (info && (rot == 3)) ? !osd_vcnt[21:8] :
+ (osd_vcnt < osd_h)
+ );
osd_hcnt <= 0;
+ osd_hcnt2 <= 0;
+ if(info && rot == 1) osd_hcnt2 <= 22'd128-infoh;
end
- if (osd_hcnt+1 == (info ? infow : OSD_WIDTH)) osd_de[0] <= 0;
+ if (osd_hcnt+1 == osd_w) osd_de[0] <= 0;
// falling edge of de
if(!de_in && deD) dsp_width <= h_cnt[21:0];
@@ -169,7 +196,7 @@ always @(posedge clk_video) begin
if(de_in && !deD) begin
h_cnt <= 0;
v_cnt <= v_cnt + 1'd1;
- h_osd_start <= info ? infox : (((dsp_width - OSD_WIDTH)>>1) + OSD_X_OFFSET - 2'd2);
+ h_osd_start <= info ? (rot[0] ? infoy : infox) : (((dsp_width - osd_w)>>1) - 2'd2);
if(h_cnt > {dsp_width, 2'b00}) begin
v_cnt <= 1;
@@ -179,21 +206,31 @@ always @(posedge clk_video) begin
osd_en <= (osd_en << 1) | osd_enable;
if(~osd_enable) osd_en <= 0;
- if(v_cnt_below320) begin
+ half <= 0;
+ if(v_cnt_h) begin
multiscan <= 0;
- v_osd_start <= info ? infoy : v_osd_start_320;
+ v_osd_start <= info ? v_info_start_h : v_osd_start_h;
+ half <= 1;
end
- else if(v_cnt_below640) begin
+ else if(v_cnt_1 | (rot[0] & v_cnt_2)) begin
+ multiscan <= 0;
+ v_osd_start <= info ? v_info_start_1 : v_osd_start_1;
+ end
+ else if(rot[0] ? v_cnt_3 : v_cnt_2) begin
multiscan <= 1;
- v_osd_start <= info ? (infoy<<1) : v_osd_start_640;
+ v_osd_start <= info ? v_info_start_2 : v_osd_start_2;
end
- else if(v_cnt_below960) begin
+ else if(rot[0] ? v_cnt_4 : v_cnt_3) begin
multiscan <= 2;
- v_osd_start <= info ? (infoy + (infoy << 1)) : v_osd_start_960;
+ v_osd_start <= info ? v_info_start_3 : v_osd_start_3;
+ end
+ else if(rot[0] | v_cnt_4) begin
+ multiscan <= 3;
+ v_osd_start <= info ? v_info_start_4 : v_osd_start_4;
end
else begin
- multiscan <= 3;
- v_osd_start <= info ? (infoy<<2) : v_osd_start_other;
+ multiscan <= 4;
+ v_osd_start <= info ? v_info_start_5 : v_osd_start_5;
end
end
end
@@ -201,14 +238,18 @@ always @(posedge clk_video) begin
osd_div <= osd_div + 1'd1;
if(osd_div == multiscan) begin
osd_div <= 0;
- if(~osd_vcnt[10]) osd_vcnt <= osd_vcnt + 1'd1;
+ if(~osd_vcnt[10]) osd_vcnt <= osd_vcnt + 1'd1 + half;
if(osd_vcnt == 'b100010011111 && ~info) osd_vcnt <= 0;
end
- if(v_osd_start == v_cnt) {osd_div, osd_vcnt} <= OSD_HDR ? {~info, 3'b000, ~info, 7'b0000000} : 22'd0;
+ if(v_osd_start == v_cnt) begin
+ {osd_div,osd_vcnt} <= 0;
+ if(info && rot == 3) osd_vcnt <= 22'd256-infow;
+ else if(OSD_HDR && !rot) osd_vcnt <= {~info, 3'b000, ~info, 7'b0000000};
+ end
end
- osd_byte <= osd_buffer[{osd_vcnt[7:3], osd_hcnt[7:0]}];
- osd_pixel <= osd_byte[osd_vcnt[2:0]];
+ osd_byte <= osd_buffer[rot[0] ? ({osd_hcnt2[6:3], osd_vcnt[7:0]} ^ { {4{~rot[1]}}, {8{rot[1]}} }) : {osd_vcnt[7:3], osd_hcnt[7:0]}];
+ osd_pixel <= osd_byte[rot[0] ? ((osd_hcnt2[2:0]-1'd1) ^ {3{~rot[1]}}) : osd_vcnt[2:0]];
osd_de[2:1] <= osd_de[1:0];
end
end
diff --git a/sys/pll.13.qip b/sys/pll.13.qip
index a5cd7dc..a6a1dca 100644
--- a/sys/pll.13.qip
+++ b/sys/pll.13.qip
@@ -4,9 +4,13 @@ set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_ENV "mwpim"
set_global_assignment -library "pll" -name MISC_FILE [file join $::quartus(qip_path) "pll.cmp"]
set_global_assignment -name SYNTHESIS_ONLY_QIP ON
-set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
-set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll/pll_0002.v"]
-set_global_assignment -library "pll" -name QIP_FILE [file join $::quartus(qip_path) "pll/pll_0002_q13.qip"]
+set_global_assignment -library "pll" -name VERILOG_FILE rtl/pll.v
+set_global_assignment -library "pll" -name VERILOG_FILE rtl/pll/pll_0002.v
+
+set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_NAME "altera_pll"
set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_VERSION "13.1"
diff --git a/sys/pll/pll_0002_q13.qip b/sys/pll/pll_0002_q13.qip
deleted file mode 100644
index 9f8ded1..0000000
--- a/sys/pll/pll_0002_q13.qip
+++ /dev/null
@@ -1,4 +0,0 @@
-set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*"
diff --git a/sys/pll_hdmi.13.qip b/sys/pll_hdmi.13.qip
index 705d514..76def89 100644
--- a/sys/pll_hdmi.13.qip
+++ b/sys/pll_hdmi.13.qip
@@ -6,7 +6,11 @@ set_global_assignment -name SYNTHESIS_ONLY_QIP ON
set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi.v"]
set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002.v"]
-set_global_assignment -library "pll_hdmi" -name QIP_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002_q13.qip"]
+
+set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
+set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll"
set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1"
diff --git a/sys/pll_hdmi/pll_hdmi_0002_q13.qip b/sys/pll_hdmi/pll_hdmi_0002_q13.qip
deleted file mode 100644
index fb8053d..0000000
--- a/sys/pll_hdmi/pll_hdmi_0002_q13.qip
+++ /dev/null
@@ -1,4 +0,0 @@
-set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
-set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
diff --git a/sys/pll_q17.qip b/sys/pll_q17.qip
index 9c69934..5bc92e0 100644
--- a/sys/pll_q17.qip
+++ b/sys/pll_q17.qip
@@ -1,3 +1,3 @@
-set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.qip ]
+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_cfg.qip ]
diff --git a/sys/scandoubler.v b/sys/scandoubler.v
index 1a39247..a1d5a44 100644
--- a/sys/scandoubler.v
+++ b/sys/scandoubler.v
@@ -22,7 +22,7 @@
module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
(
// system interface
- input clk_sys,
+ input clk_vid,
input ce_pix,
output ce_pix_out,
@@ -59,7 +59,7 @@ wire [7:0] pc_in = pix_in_cnt + 1'b1;
reg [7:0] pixsz, pixsz2, pixsz4 = 0;
reg ce_x4i, ce_x1i;
-always @(negedge clk_sys) begin
+always @(posedge clk_vid) begin
reg old_ce, valid, hs;
if(~&pix_len) pix_len <= pl;
@@ -94,7 +94,7 @@ end
reg req_line_reset;
reg [DWIDTH:0] r_d, g_d, b_d;
-always @(posedge clk_sys) begin
+always @(posedge clk_vid) begin
if(ce_x1i) begin
req_line_reset <= hb_in;
r_d <= r_in;
@@ -105,7 +105,7 @@ end
Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
(
- .clk(clk_sys),
+ .clk(clk_vid),
.ce_in(ce_x4i),
.inputpixel({b_d,g_d,r_d}),
@@ -124,7 +124,7 @@ reg [7:0] pix_out_cnt = 0;
wire [7:0] pc_out = pix_out_cnt + 1'b1;
reg ce_x4o, ce_x2o;
-always @(negedge clk_sys) begin
+always @(posedge clk_vid) begin
reg hs;
if(~&pix_out_cnt) pix_out_cnt <= pc_out;
@@ -148,7 +148,7 @@ reg [1:0] sd_line;
reg [3:0] vbo;
reg [3:0] vso;
reg [8:0] hbo;
-always @(posedge clk_sys) begin
+always @(posedge clk_vid) begin
reg [31:0] hcnt;
reg [30:0] sd_hcnt;
diff --git a/sys/sys.qip b/sys/sys.qip
index 6a5d6b6..3a594df 100644
--- a/sys/sys.qip
+++ b/sys/sys.qip
@@ -3,12 +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 ]
@@ -20,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 0be58d1..c12cfee 100644
--- a/sys/sys.tcl
+++ b/sys/sys.tcl
@@ -99,12 +99,9 @@ set_location_assignment PIN_W14 -to SDRAM_nRAS
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_*
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*]
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQM*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_n*
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_*
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*]
+set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*]
set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM_*
#============================================================
@@ -132,41 +129,17 @@ set_location_assignment PIN_E11 -to FPGA_CLK3_50
#============================================================
# HDMI
#============================================================
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SCL
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SDA
+set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_*
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2S
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_LRCLK
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_MCLK
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_SCLK
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_CLK
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_DE
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[0]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[1]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[2]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[3]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[4]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[5]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[6]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[7]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[8]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[9]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[10]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[11]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[12]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[13]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[14]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[15]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[16]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[17]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[18]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[19]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[20]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[21]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[22]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[23]
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_HS
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_INT
-set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_VS
+set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_*
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_D[*]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_DE
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_HS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_VS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_CLK
set_location_assignment PIN_U10 -to HDMI_I2C_SCL
set_location_assignment PIN_AA4 -to HDMI_I2C_SDA
set_location_assignment PIN_T13 -to HDMI_I2S
@@ -245,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_dual_sdram.tcl b/sys/sys_dual_sdram.tcl
index de9fd29..bffcdf4 100644
--- a/sys/sys_dual_sdram.tcl
+++ b/sys/sys_dual_sdram.tcl
@@ -42,12 +42,9 @@ set_location_assignment PIN_AE17 -to SDRAM2_A[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM2_*
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM2_*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_A*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_BA*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_DQ[*]
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_DQM*
-set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_n*
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_*
set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM2_DQ[*]
+set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM2_DQ[*]
set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM2_*
set_global_assignment -name VERILOG_MACRO "DUAL_SDRAM=1"
diff --git a/sys/sys_top.sdc b/sys/sys_top.sdc
index 90d943d..67619ac 100644
--- a/sys/sys_top.sdc
+++ b/sys/sys_top.sdc
@@ -6,11 +6,6 @@ create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk]
create_clock -period "100.0 MHz" [get_pins -compatibility_mode spi|sclk_out] -name spi_sck
derive_pll_clocks
-
-create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \
- -name HDMI_CLK [get_ports HDMI_TX_CLK]
-
-
derive_clock_uncertainty
# Decouple different clock groups (to simplify routing)
@@ -22,9 +17,6 @@ set_clock_groups -exclusive \
-group [get_clocks { FPGA_CLK2_50 }] \
-group [get_clocks { FPGA_CLK3_50 }]
-set_output_delay -max -clock HDMI_CLK 4.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
-set_output_delay -min -clock HDMI_CLK 3.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
-
set_false_path -from [get_ports {KEY*}]
set_false_path -from [get_ports {BTN_*}]
set_false_path -to [get_ports {LED_*}]
@@ -34,4 +26,26 @@ set_false_path -to [get_ports {AUDIO_L}]
set_false_path -to [get_ports {AUDIO_R}]
set_false_path -to {cfg[*]}
set_false_path -from {cfg[*]}
+set_false_path -from {VSET[*]}
set_false_path -to {wcalc[*] hcalc[*]}
+set_false_path -to {width[*] height[*]}
+
+set_multicycle_path -to {*_osd|osd_vcnt*} -setup 2
+set_multicycle_path -to {*_osd|osd_vcnt*} -hold 1
+set_false_path -to {*_osd|v_cnt*}
+set_false_path -to {*_osd|v_osd_start*}
+set_false_path -to {*_osd|v_info_start*}
+set_false_path -to {*_osd|h_osd_start*}
+set_false_path -from {*_osd|v_osd_start*}
+set_false_path -from {*_osd|v_info_start*}
+set_false_path -from {*_osd|h_osd_start*}
+set_false_path -from {*_osd|rot*}
+set_false_path -from {*_osd|dsp_width*}
+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 {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
+set_false_path -from {vol_att[*] scaler_flt[*] led_overtake[*] led_state[*]}
diff --git a/sys/sys_top.v b/sys/sys_top.v
index d1572ed..c8ef6f7 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 ///////////////////////////////////
@@ -222,7 +235,6 @@ wire io_clk = gp_outr[17];
wire io_ss0 = gp_outr[18];
wire io_ss1 = gp_outr[19];
wire io_ss2 = gp_outr[20];
-//wire io_sdd = gp_outr[21]; // used only in ST core
wire io_osd_hdmi = io_ss1 & ~io_ss0;
wire io_fpga = ~io_ss1 & io_ss0;
@@ -266,6 +278,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];
@@ -289,13 +302,16 @@ reg [8:0] coef_data;
reg coef_wr = 0;
wire [7:0] ARX, ARY;
-reg [11:0] VSET = 0;
+reg [11:0] VSET = 0, HSET = 0;
+reg FREESCALE = 0;
reg [2:0] scaler_flt;
reg lowlat = 0;
reg cfg_dis = 0;
reg vs_wait = 0;
+reg [11:0] vs_line = 0;
+reg scaler_out = 0;
always@(posedge clk_sys) begin
reg [7:0] cmd;
reg has_cmd;
@@ -322,6 +338,7 @@ always@(posedge clk_sys) begin
if(cmd == 1) begin
cfg <= io_din;
cfg_set <= 1;
+ scaler_out <= 1;
end
if(cmd == 'h20) begin
cfg_set <= 0;
@@ -370,12 +387,14 @@ always@(posedge clk_sys) begin
end
if(cmd == 'h25) {led_overtake, led_state} <= io_din;
if(cmd == 'h26) vol_att <= io_din[4:0];
- if(cmd == 'h27) VSET <= io_din[11:0];
+ if(cmd == 'h27) VSET <= io_din[11:0];
if(cmd == 'h2A) {coef_wr,coef_addr,coef_data} <= {1'b1,io_din};
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];
end
end
-
+
vs_d0 <= HDMI_TX_VS;
if(vs_d0 == HDMI_TX_VS) vs_d1 <= vs_d0;
@@ -395,7 +414,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,20 +425,21 @@ 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)
);
-wire [63:0] f2h_irq = {HDMI_TX_VS};
+wire [63:0] f2h_irq = {video_sync,HDMI_TX_VS};
cyclonev_hps_interface_interrupts interrupts
(
.irq(f2h_irq)
@@ -444,7 +466,7 @@ always @(posedge FPGA_CLK2_50) begin
end
wire clk_100m;
-wire clk_hdmi = ~hdmi_clk_out; // Internal HDMI clock, inverted in relation to external clock
+wire clk_hdmi = hdmi_clk_out;
wire clk_audio = FPGA_CLK3_50;
wire clk_pal = FPGA_CLK3_50;
@@ -461,6 +483,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 +495,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 +523,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 +588,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),
@@ -540,7 +604,7 @@ ascal
.vimax (0),
.o_clk (clk_hdmi),
- .o_ce (1),
+ .o_ce (scaler_out),
.o_r (hdmi_data[23:16]),
.o_g (hdmi_data[15:8]),
.o_b (hdmi_data[7:0]),
@@ -612,7 +676,12 @@ always @(posedge clk_vid) begin
reg [2:0] state;
reg [11:0] videow;
reg [11:0] videoh;
-
+ reg [11:0] height;
+ reg [11:0] width;
+
+ height <= (VSET && (VSET < HEIGHT)) ? VSET : HEIGHT;
+ width <= (HSET && (HSET < WIDTH)) ? HSET : WIDTH;
+
state <= state + 1'd1;
case(state)
0: if(FB_EN) begin
@@ -622,22 +691,17 @@ always @(posedge clk_vid) begin
vmax <= FB_VMAX;
state<= 0;
end
- else if(ARX && ARY) begin
- wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY;
- hcalc <= (WIDTH*ARY)/ARX;
+ else if(ARX && ARY && !FREESCALE) begin
+ wcalc <= (height*ARX)/ARY;
+ hcalc <= (width*ARY)/ARX;
end
else begin
- hmin <= 0;
- hmax <= WIDTH - 1'd1;
- vmin <= 0;
- vmax <= HEIGHT - 1'd1;
- wcalc<= WIDTH;
- hcalc<= HEIGHT;
- state<= 0;
+ wcalc <= width;
+ hcalc <= height;
end
6: begin
- videow <= (!VSET && (wcalc > WIDTH)) ? WIDTH : wcalc[11:0];
- videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0];
+ videow <= (wcalc > width) ? width : wcalc[11:0];
+ videoh <= (hcalc > height) ? height : hcalc[11:0];
end
7: begin
hmin <= ((WIDTH - videow)>>1);
@@ -668,37 +732,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,14 +878,19 @@ 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 @(negedge clk_vid) begin
+always @(posedge clk_vid) begin
reg [23:0] dv_d1, dv_d2;
reg dv_de1, dv_de2, dv_hs1, dv_hs2, dv_vs1, dv_vs2;
reg [12:0] vsz, vcnt;
@@ -876,11 +929,63 @@ always @(negedge clk_vid) begin
dv_vs <= dv_vs2;
end
-assign HDMI_TX_CLK = direct_video ? clk_vid : hdmi_clk_out;
-assign HDMI_TX_HS = direct_video ? dv_hs : hdmi_hs_osd;
-assign HDMI_TX_VS = direct_video ? dv_vs : hdmi_vs_osd;
-assign HDMI_TX_DE = direct_video ? dv_de : hdmi_de_osd;
-assign HDMI_TX_D = direct_video ? dv_data : hdmi_data_osd;
+wire hdmi_tx_clk;
+cyclonev_clkselect hdmi_clk_sw
+(
+ .clkselect({1'b1, ~vga_fb & direct_video}),
+ .inclk({clk_vid, hdmi_clk_out, 2'b00}),
+ .outclk(hdmi_tx_clk)
+);
+
+altddio_out
+#(
+ .extend_oe_disable("OFF"),
+ .intended_device_family("Cyclone V"),
+ .invert_output("OFF"),
+ .lpm_hint("UNUSED"),
+ .lpm_type("altddio_out"),
+ .oe_reg("UNREGISTERED"),
+ .power_up_high("OFF"),
+ .width(1)
+)
+hdmiclk_ddr
+(
+ .datain_h(1'b0),
+ .datain_l(1'b1),
+ .outclock(hdmi_tx_clk),
+ .dataout(HDMI_TX_CLK),
+ .aclr(1'b0),
+ .aset(1'b0),
+ .oe(1'b1),
+ .outclocken(1'b1),
+ .sclr(1'b0),
+ .sset(1'b0)
+);
+
+reg hdmi_out_hs;
+reg hdmi_out_vs;
+reg hdmi_out_de;
+reg [23:0] hdmi_out_d;
+
+always @(posedge hdmi_tx_clk) begin
+ reg hs,vs,de;
+ reg [23:0] d;
+
+ 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;
+ hdmi_out_de <= de;
+ hdmi_out_d <= d;
+end
+
+assign HDMI_TX_HS = hdmi_out_hs;
+assign HDMI_TX_VS = hdmi_out_vs;
+assign HDMI_TX_DE = hdmi_out_de;
+assign HDMI_TX_D = hdmi_out_d;
///////////////////////// VGA output //////////////////////////////////
@@ -933,15 +1038,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;
@@ -950,6 +1052,31 @@ csync csync_vga(clk_vid, vga_hs_osd, vga_vs_osd, vga_cs_osd);
assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[7:2];
`endif
+reg video_sync = 0;
+always @(posedge clk_vid) begin
+ reg [11:0] line_cnt = 0;
+ reg [11:0] sync_line = 0;
+ reg [1:0] hs_cnt = 0;
+ reg old_hs;
+
+ old_hs <= hs_fix;
+ if(~old_hs & hs_fix) begin
+
+ video_sync <= (sync_line == line_cnt);
+
+ line_cnt <= line_cnt + 1'd1;
+ if(~hs_cnt[1]) begin
+ hs_cnt <= hs_cnt + 1'd1;
+ if(hs_cnt[0]) begin
+ sync_line <= (line_cnt - vs_line);
+ line_cnt <= 0;
+ end
+ end
+ end
+
+ if(de_emu) hs_cnt <= 0;
+end
+
///////////////////////// Audio output ////////////////////////////////
assign SDCD_SPDIF =(SW[3] & ~spdif) ? 1'b0 : 1'bZ;
@@ -1014,32 +1141,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)
@@ -1067,52 +1190,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),
@@ -1121,23 +1268,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),
@@ -1148,7 +1313,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),
@@ -1160,6 +1327,7 @@ emu emu
.SDRAM_nCAS(SDRAM_nCAS),
.SDRAM_CLK(SDRAM_CLK),
.SDRAM_CKE(SDRAM_CKE),
+`endif
`ifdef DUAL_SDRAM
.SDRAM2_DQ(SDRAM2_DQ),
@@ -1173,6 +1341,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),
@@ -1189,11 +1360,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
diff --git a/sys/video_mixer.sv b/sys/video_mixer.sv
index 8f48f11..8f204ee 100644
--- a/sys/video_mixer.sv
+++ b/sys/video_mixer.sv
@@ -17,17 +17,21 @@
// HALF_DEPTH: If =1 then color dept is 4 bits per component
// For half depth 8 bits monochrome is available with
// mono signal enabled and color = {G, R}
+//
+// altera message_off 10720
+// altera message_off 12161
module video_mixer
#(
parameter LINE_LENGTH = 768,
- parameter HALF_DEPTH = 0
+ parameter HALF_DEPTH = 0,
+ parameter GAMMA = 0
)
(
- // master clock
+ // video clock
// it should be multiple by (ce_pix*4).
- input clk_sys,
-
+ input clk_vid,
+
// Pixel clock or clock_enable (both are accepted).
input ce_pix,
output ce_pix_out,
@@ -48,6 +52,8 @@ module video_mixer
// Monochrome mode (for HALF_DEPTH only)
input mono,
+ inout [21:0] gamma_bus,
+
// Positive pulses.
input HSync,
input VSync,
@@ -64,22 +70,74 @@ module video_mixer
);
localparam DWIDTH = HALF_DEPTH ? 3 : 7;
+localparam DWIDTH_SD = GAMMA ? 7 : DWIDTH;
+localparam HALF_DEPTH_SD = GAMMA ? 0 : HALF_DEPTH;
-wire [DWIDTH:0] R_sd;
-wire [DWIDTH:0] G_sd;
-wire [DWIDTH:0] B_sd;
+generate
+ if(GAMMA && HALF_DEPTH) begin
+ wire [7:0] R_in = mono ? {G,R} : {R,R};
+ wire [7:0] G_in = mono ? {G,R} : {G,G};
+ wire [7:0] B_in = mono ? {G,R} : {B,B};
+ end else begin
+ wire [DWIDTH:0] R_in = R;
+ wire [DWIDTH:0] G_in = G;
+ wire [DWIDTH:0] B_in = B;
+ end
+endgenerate
+
+
+wire hs_g, vs_g;
+wire hb_g, vb_g;
+wire [DWIDTH_SD:0] R_gamma, G_gamma, B_gamma;
+
+generate
+ if(GAMMA) begin
+ assign gamma_bus[21] = 1;
+ gamma_corr gamma(
+ .clk_sys(gamma_bus[20]),
+ .clk_vid(clk_vid),
+ .ce_pix(ce_pix),
+
+ .gamma_en(gamma_bus[19]),
+ .gamma_wr(gamma_bus[18]),
+ .gamma_wr_addr(gamma_bus[17:8]),
+ .gamma_value(gamma_bus[7:0]),
+
+ .HSync(HSync),
+ .VSync(VSync),
+ .HBlank(HBlank),
+ .VBlank(VBlank),
+ .RGB_in({R_in,G_in,B_in}),
+
+ .HSync_out(hs_g),
+ .VSync_out(vs_g),
+ .HBlank_out(hb_g),
+ .VBlank_out(vb_g),
+ .RGB_out({R_gamma,G_gamma,B_gamma})
+ );
+ end else begin
+ assign gamma_bus[21] = 0;
+ assign {R_gamma,G_gamma,B_gamma} = {R_in,G_in,B_in};
+ assign {hs_g, vs_g, hb_g, vb_g} = {HSync, VSync, HBlank, VBlank};
+ end
+endgenerate
+
+
+wire [DWIDTH_SD:0] R_sd;
+wire [DWIDTH_SD:0] G_sd;
+wire [DWIDTH_SD:0] B_sd;
wire hs_sd, vs_sd, hb_sd, vb_sd, ce_pix_sd;
-scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) sd
+scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH_SD)) sd
(
.*,
- .hs_in(HSync),
- .vs_in(VSync),
- .hb_in(HBlank),
- .vb_in(VBlank),
- .r_in(R),
- .g_in(G),
- .b_in(B),
+ .hs_in(hs_g),
+ .vs_in(vs_g),
+ .hb_in(hb_g),
+ .vb_in(vb_g),
+ .r_in(R_gamma),
+ .g_in(G_gamma),
+ .b_in(B_gamma),
.ce_pix_out(ce_pix_sd),
.hs_out(hs_sd),
@@ -91,12 +149,12 @@ scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) sd
.b_out(B_sd)
);
-wire [DWIDTH:0] rt = (scandoubler ? R_sd : R);
-wire [DWIDTH:0] gt = (scandoubler ? G_sd : G);
-wire [DWIDTH:0] bt = (scandoubler ? B_sd : B);
+wire [DWIDTH_SD:0] rt = (scandoubler ? R_sd : R_gamma);
+wire [DWIDTH_SD:0] gt = (scandoubler ? G_sd : G_gamma);
+wire [DWIDTH_SD:0] bt = (scandoubler ? B_sd : B_gamma);
generate
- if(HALF_DEPTH) begin
+ if(!GAMMA && HALF_DEPTH) begin
wire [7:0] r = mono ? {gt,rt} : {rt,rt};
wire [7:0] g = mono ? {gt,rt} : {gt,gt};
wire [7:0] b = mono ? {gt,rt} : {bt,bt};
@@ -107,14 +165,14 @@ generate
end
endgenerate
-wire hs = (scandoubler ? hs_sd : HSync);
-wire vs = (scandoubler ? vs_sd : VSync);
+wire hs = (scandoubler ? hs_sd : hs_g);
+wire vs = (scandoubler ? vs_sd : vs_g);
assign ce_pix_out = scandoubler ? ce_pix_sd : ce_pix;
reg scanline = 0;
-always @(posedge clk_sys) begin
+always @(posedge clk_vid) begin
reg old_hs, old_vs;
old_hs <= hs;
@@ -124,44 +182,57 @@ always @(posedge clk_sys) begin
if(old_vs && ~vs) scanline <= 0;
end
-wire hde = scandoubler ? ~hb_sd : ~HBlank;
-wire vde = scandoubler ? ~vb_sd : ~VBlank;
+wire hde = scandoubler ? ~hb_sd : ~hb_g;
+wire vde = scandoubler ? ~vb_sd : ~vb_g;
-always @(posedge clk_sys) begin
+reg [7:0] v_r,v_g,v_b;
+reg v_vs,v_hs,v_de;
+always @(posedge clk_vid) begin
reg old_hde;
- case(scanlines & {scanline, scanline})
- 1: begin // reduce 25% = 1/2 + 1/4
- VGA_R <= {1'b0, r[7:1]} + {2'b00, r[7:2]};
- VGA_G <= {1'b0, g[7:1]} + {2'b00, g[7:2]};
- VGA_B <= {1'b0, b[7:1]} + {2'b00, b[7:2]};
- end
+ if(ce_pix_out) begin
+ case(scanlines & {scanline, scanline})
+ 1: begin // reduce 25% = 1/2 + 1/4
+ v_r <= {1'b0, r[7:1]} + {2'b00, r[7:2]};
+ v_g <= {1'b0, g[7:1]} + {2'b00, g[7:2]};
+ v_b <= {1'b0, b[7:1]} + {2'b00, b[7:2]};
+ end
- 2: begin // reduce 50% = 1/2
- VGA_R <= {1'b0, r[7:1]};
- VGA_G <= {1'b0, g[7:1]};
- VGA_B <= {1'b0, b[7:1]};
- end
+ 2: begin // reduce 50% = 1/2
+ v_r <= {1'b0, r[7:1]};
+ v_g <= {1'b0, g[7:1]};
+ v_b <= {1'b0, b[7:1]};
+ end
- 3: begin // reduce 75% = 1/4
- VGA_R <= {2'b00, r[7:2]};
- VGA_G <= {2'b00, g[7:2]};
- VGA_B <= {2'b00, b[7:2]};
- end
+ 3: begin // reduce 75% = 1/4
+ v_r <= {2'b00, r[7:2]};
+ v_g <= {2'b00, g[7:2]};
+ v_b <= {2'b00, b[7:2]};
+ end
- default: begin
- VGA_R <= r;
- VGA_G <= g;
- VGA_B <= b;
- end
- endcase
+ default: begin
+ v_r <= r;
+ v_g <= g;
+ v_b <= b;
+ end
+ endcase
- VGA_VS <= vs;
- VGA_HS <= hs;
+ v_vs <= vs;
+ v_hs <= hs;
- old_hde <= hde;
- if(~old_hde && hde) VGA_DE <= vde;
- if(old_hde && ~hde) VGA_DE <= 0;
+ old_hde <= hde;
+ if(~old_hde && hde) v_de <= vde;
+ if(old_hde && ~hde) v_de <= 0;
+ end
+end
+
+always @(posedge clk_vid) if(ce_pix_out) begin
+ VGA_R <= v_r;
+ VGA_G <= v_g;
+ VGA_B <= v_b;
+ VGA_HS <= v_hs;
+ VGA_VS <= v_vs;
+ VGA_DE <= v_de;
end
endmodule