├── releases
├── Arcade-DigDug_20190921.rbf
├── Arcade-DigDug_20191022.rbf
├── rommap.txt
└── Dig Dug.mra
├── .gitignore
├── sys
├── pll_hdmi
│ ├── pll_hdmi_0002.qip
│ ├── pll_hdmi_0002_q13.qip
│ └── pll_hdmi_0002.v
├── pll
│ ├── pll_0002.qip
│ └── pll_0002.v
├── sigma_delta_dac.v
├── pll_hdmi_q13.qip
├── scanlines.v
├── i2c.v
├── sys_top.sdc
├── video_cleaner.sv
├── sys.qip
├── build_id.tcl
├── sys_q13.qip
├── i2s.v
├── vga_out.sv
├── alsa.sv
├── video_mixer.sv
├── pll_hdmi_cfg.v
├── scandoubler.v
├── osd.v
├── pll_hdmi_cfg.qip
├── pll_hdmi_cfg
│ └── altera_std_synchronizer.v
├── hdmi_config.sv
├── pll_hdmi_adj.vhd
├── sysmem.sv
├── hq2x.sv
└── spdif.v
├── src
├── LINEBUF.qip
├── cpucore.v
├── dprams.v
├── cpu
│ ├── tv80_reg.v
│ ├── tv80s.v
│ └── tv80_alu.v
├── DIGDUG_SPRITE.v
├── FPGA_DIGDUG.v
├── DIGDUG_VIDEO.v
├── wsg.v
├── DIGDUG_CORES.v
├── DIGDUG_IODEV.v
├── DIGDUG_CUSIO.v
└── LINEBUF.v
├── clean.bat
├── Arcade-DigDug.qpf
├── readme.txt
├── Arcade-DigDug.srf
└── Arcade-DigDug.sv
/releases/Arcade-DigDug_20190921.rbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrX-8B/MiSTer-Arcade-DigDug/HEAD/releases/Arcade-DigDug_20190921.rbf
--------------------------------------------------------------------------------
/releases/Arcade-DigDug_20191022.rbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrX-8B/MiSTer-Arcade-DigDug/HEAD/releases/Arcade-DigDug_20191022.rbf
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | *.bak
3 | db/*
4 | incremental_db/*
5 | output_files/*
6 | build_id.v
7 | jtag.cdf
8 | c5_pin_model_dump.txt
9 | *.qws
10 |
--------------------------------------------------------------------------------
/sys/pll_hdmi/pll_hdmi_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
2 | set_instance_assignment -name UNFORCE_MERGE_PLL_OUTPUT_COUNTER ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
3 |
--------------------------------------------------------------------------------
/src/LINEBUF.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
2 | set_global_assignment -name IP_TOOL_VERSION "17.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "LINEBUF.v"]
5 |
--------------------------------------------------------------------------------
/releases/rommap.txt:
--------------------------------------------------------------------------------
1 |
2 | 0000-3FFF cpu0
3 | 4000-7FFF spchip
4 | 8000-9FFF cpu1
5 | A000-AFFF cpu2
6 | B000-BFFF bgscrn
7 | C000-CFFF bgchip
8 | D000-D7FF fgchip
9 | D800-D8FF wave
10 | D900-D9FF spclut
11 | DA00-DAFF bgclut
12 | DB00-DB1F palet
13 |
14 | [EOF]
15 |
--------------------------------------------------------------------------------
/sys/pll/pll_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*"
2 |
3 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*"
4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*"
5 |
--------------------------------------------------------------------------------
/sys/pll_hdmi/pll_hdmi_0002_q13.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
2 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
3 | set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*"
5 |
--------------------------------------------------------------------------------
/clean.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | del /s *.bak
3 | del /s *.orig
4 | del /s *.rej
5 | del /s *~
6 | rmdir /s /q db
7 | rmdir /s /q incremental_db
8 | rmdir /s /q output_files
9 | rmdir /s /q simulation
10 | rmdir /s /q greybox_tmp
11 | rmdir /s /q hc_output
12 | rmdir /s /q .qsys_edit
13 | rmdir /s /q hps_isw_handoff
14 | rmdir /s /q sys\.qsys_edit
15 | rmdir /s /q sys\vip
16 | cd sys
17 | for /d %%i in (*_sim) do rmdir /s /q "%%~nxi"
18 | cd ..
19 | for /d %%i in (*_sim) do rmdir /s /q "%%~nxi"
20 | del build_id.v
21 | del c5_pin_model_dump.txt
22 | del PLLJ_PLLSPE_INFO.txt
23 | del /s *.qws
24 | del /s *.ppf
25 | del /s *.ddb
26 | del /s *.csv
27 | del /s *.cmp
28 | del /s *.sip
29 | del /s *.spd
30 | del /s *.bsf
31 | del /s *.f
32 | del /s *.sopcinfo
33 | del /s *.xml
34 | del *.cdf
35 | del /s new_rtl_netlist
36 | del /s old_rtl_netlist
37 | del sys\vip.qip
38 | del sys\sysmem.qip
39 | del sys\sdram.sv
40 | del sys\ddram.sv
41 | pause
42 |
--------------------------------------------------------------------------------
/sys/sigma_delta_dac.v:
--------------------------------------------------------------------------------
1 | //
2 | // PWM DAC
3 | //
4 | // MSBI is the highest bit number. NOT amount of bits!
5 | //
6 | module sigma_delta_dac #(parameter MSBI=7, parameter INV=1'b1)
7 | (
8 | output reg DACout, //Average Output feeding analog lowpass
9 | input [MSBI:0] DACin, //DAC input (excess 2**MSBI)
10 | input CLK,
11 | input RESET
12 | );
13 |
14 | reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder
15 | reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder
16 | reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder
17 | reg [MSBI+2:0] DeltaB; //B input of Delta Adder
18 |
19 | always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1);
20 | always @(*) DeltaAdder = DACin + DeltaB;
21 | always @(*) SigmaAdder = DeltaAdder + SigmaLatch;
22 |
23 | always @(posedge CLK or posedge RESET) begin
24 | if(RESET) begin
25 | SigmaLatch <= 1'b1 << (MSBI+1);
26 | DACout <= INV;
27 | end else begin
28 | SigmaLatch <= SigmaAdder;
29 | DACout <= SigmaLatch[MSBI+2] ^ INV;
30 | end
31 | end
32 |
33 | endmodule
34 |
--------------------------------------------------------------------------------
/sys/pll_hdmi_q13.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll"
2 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1"
3 | set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim"
4 | set_global_assignment -library "pll_hdmi" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi.cmp"]
5 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON
6 |
7 | set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi.v"]
8 | set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002.v"]
9 | set_global_assignment -library "pll_hdmi" -name QIP_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002_q13.qip"]
10 |
11 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll"
12 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1"
13 | set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim"
14 |
--------------------------------------------------------------------------------
/sys/scanlines.v:
--------------------------------------------------------------------------------
1 | module scanlines #(parameter v2=0)
2 | (
3 | input clk,
4 |
5 | input [1:0] scanlines,
6 | input [23:0] din,
7 | output reg [23:0] dout,
8 | input hs,vs
9 | );
10 |
11 | reg [1:0] scanline;
12 | always @(posedge clk) begin
13 | reg old_hs, old_vs;
14 |
15 | old_hs <= hs;
16 | old_vs <= vs;
17 |
18 | if(old_hs && ~hs) begin
19 | if(v2) begin
20 | scanline <= scanline + 1'd1;
21 | if (scanline == scanlines) scanline <= 0;
22 | end
23 | else scanline <= scanline ^ scanlines;
24 | end
25 | if(old_vs && ~vs) scanline <= 0;
26 | end
27 |
28 | wire [7:0] r,g,b;
29 | assign {r,g,b} = din;
30 |
31 | always @(*) begin
32 | case(scanline)
33 | 1: // reduce 25% = 1/2 + 1/4
34 | dout = {{1'b0, r[7:1]} + {2'b00, r[7:2]},
35 | {1'b0, g[7:1]} + {2'b00, g[7:2]},
36 | {1'b0, b[7:1]} + {2'b00, b[7:2]}};
37 |
38 | 2: // reduce 50% = 1/2
39 | dout = {{1'b0, r[7:1]},
40 | {1'b0, g[7:1]},
41 | {1'b0, b[7:1]}};
42 |
43 | 3: // reduce 75% = 1/4
44 | dout = {{2'b00, r[7:2]},
45 | {2'b00, g[7:2]},
46 | {2'b00, b[7:2]}};
47 |
48 | default: dout = {r,g,b};
49 | endcase
50 | end
51 |
52 | endmodule
53 |
--------------------------------------------------------------------------------
/releases/Dig Dug.mra:
--------------------------------------------------------------------------------
1 |
2 | Dig Dug (rev 2)
3 | 0220
4 | digdug
5 | 20200427161917
6 | 1982
7 | Namco
8 | Maze / Digging
9 | digdug
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Arcade-DigDug.qpf:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------- #
2 | #
3 | # Copyright (C) 2017 Intel Corporation. All rights reserved.
4 | # Your use of Intel Corporation's design tools, logic functions
5 | # and other software and tools, and its AMPP partner logic
6 | # functions, and any output files from any of the foregoing
7 | # (including device programming or simulation files), and any
8 | # associated documentation or information are expressly subject
9 | # to the terms and conditions of the Intel Program License
10 | # Subscription Agreement, the Intel Quartus Prime License Agreement,
11 | # the Intel FPGA IP License Agreement, or other applicable license
12 | # agreement, including, without limitation, that your use is for
13 | # the sole purpose of programming logic devices manufactured by
14 | # Intel and sold by Intel or its authorized distributors. Please
15 | # refer to the applicable agreement for further details.
16 | #
17 | # -------------------------------------------------------------------------- #
18 | #
19 | # Quartus Prime
20 | # Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition
21 | # Date created = 11:35:41 April 26, 2019
22 | #
23 | # -------------------------------------------------------------------------- #
24 |
25 | QUARTUS_VERSION = "17.1"
26 | DATE = "11:35:41 April 26, 2019"
27 |
28 | # Revisions
29 |
30 | PROJECT_REVISION = "Arcade-DigDug"
31 |
--------------------------------------------------------------------------------
/sys/i2c.v:
--------------------------------------------------------------------------------
1 |
2 | module i2c
3 | (
4 | input CLK,
5 |
6 | input START,
7 | input [23:0] I2C_DATA,
8 | output reg END = 1,
9 | output reg ACK = 0,
10 |
11 | //I2C bus
12 | output I2C_SCL,
13 | inout I2C_SDA
14 | );
15 |
16 |
17 | // Clock Setting
18 | parameter CLK_Freq = 50_000_000; // 50 MHz
19 | parameter I2C_Freq = 400_000; // 400 KHz
20 |
21 | reg I2C_CLOCK;
22 | always@(negedge CLK) begin
23 | integer mI2C_CLK_DIV = 0;
24 | if(mI2C_CLK_DIV < (CLK_Freq/I2C_Freq)) begin
25 | mI2C_CLK_DIV <= mI2C_CLK_DIV + 1;
26 | end else begin
27 | mI2C_CLK_DIV <= 0;
28 | I2C_CLOCK <= ~I2C_CLOCK;
29 | end
30 | end
31 |
32 | assign I2C_SCL = SCLK | I2C_CLOCK;
33 | assign I2C_SDA = SDO ? 1'bz : 1'b0;
34 |
35 | reg SCLK = 1, SDO = 1;
36 |
37 | always @(posedge CLK) begin
38 | reg old_clk;
39 | reg old_st;
40 |
41 | reg [5:0] SD_COUNTER = 'b111111;
42 | reg [0:31] SD;
43 |
44 | old_clk <= I2C_CLOCK;
45 | old_st <= START;
46 |
47 | if(~old_st && START) begin
48 | SCLK <= 1;
49 | SDO <= 1;
50 | ACK <= 0;
51 | END <= 0;
52 | SD <= {2'b10, I2C_DATA[23:16], 1'b1, I2C_DATA[15:8], 1'b1, I2C_DATA[7:0], 4'b1011};
53 | SD_COUNTER <= 0;
54 | end else begin
55 | if(~old_clk && I2C_CLOCK && ~&SD_COUNTER) begin
56 | SD_COUNTER <= SD_COUNTER + 6'd1;
57 | case(SD_COUNTER)
58 | 01: SCLK <= 0;
59 | 10,19,28: ACK <= ACK | I2C_SDA;
60 | 29: SCLK <= 1;
61 | 32: END <= 1;
62 | endcase
63 | end
64 |
65 | if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[5]) SDO <= SD[SD_COUNTER[4:0]];
66 | end
67 | end
68 |
69 | endmodule
70 |
--------------------------------------------------------------------------------
/src/cpucore.v:
--------------------------------------------------------------------------------
1 | module CPUCORE
2 | (
3 | input RESET,
4 | input CLK,
5 | input IRQ,
6 | input NMI,
7 | output RD,
8 | output WR,
9 | output [15:0] AD,
10 | input DV,
11 | input [7:0] DI,
12 | input [7:0] IR,
13 | output [7:0] DO
14 | );
15 |
16 | wire [7:0] m_do;
17 | wire [15:0] m_ad;
18 | wire m_irq, m_nmi, m_me, m_ie, m_rd, m_wr;
19 |
20 | wire m_mx = (~m_me);
21 | wire m_mr = (~m_rd) & m_mx;
22 | wire m_mw = (~m_wr) & m_mx;
23 |
24 | wire cs_mrom = ( m_ad[15:14] == 2'b00 );
25 | wire cs_nodv = cs_mrom;
26 |
27 | wire [7:0] m_di = cs_mrom ? IR : DV ? DI : 8'hFF;
28 |
29 | assign m_irq = ~IRQ;
30 | assign m_nmi = ~NMI;
31 |
32 | tv80s core(
33 | .mreq_n(m_me),
34 | .iorq_n(m_ie),
35 | .rd_n(m_rd),
36 | .wr_n(m_wr),
37 | .A(m_ad),
38 | .do(m_do),
39 |
40 | .reset_n(~RESET),
41 | .clk(CLK),
42 | .wait_n(1'b1),
43 | .int_n(m_irq),
44 | .nmi_n(m_nmi),
45 | .busrq_n(1'b1),
46 | .di(m_di)
47 | );
48 |
49 | assign RD = m_mr & ~cs_nodv;
50 | assign WR = m_mw & ~cs_nodv;
51 | assign AD = m_ad;
52 | assign DO = m_do;
53 |
54 | endmodule
55 |
56 |
57 | //-----------------------------------------------
58 | // NMI Ack Control
59 | //-----------------------------------------------
60 | module CPUNMIACK
61 | (
62 | input RST,
63 | input CL,
64 | input [15:0] AD,
65 | input NMI,
66 | output reg NMIo
67 | );
68 |
69 | reg pNMI = 1'b0;
70 | wire NMIACK = ( AD == 16'h0066 );
71 | always @( negedge CL or posedge RST ) begin
72 | if (RST) begin
73 | pNMI <= 1'b0;
74 | NMIo <= 1'b0;
75 | end
76 | else begin
77 | if (NMIACK) NMIo <= 0;
78 | else if ((pNMI^NMI) & NMI) NMIo <= 1'b1;
79 | pNMI <= NMI;
80 | end
81 | end
82 |
83 | endmodule
84 |
85 |
--------------------------------------------------------------------------------
/sys/sys_top.sdc:
--------------------------------------------------------------------------------
1 | # Specify root clocks
2 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK1_50]
3 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK2_50]
4 | create_clock -period "50.0 MHz" [get_ports FPGA_CLK3_50]
5 | create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk]
6 | create_clock -period 10.0 [get_pins -compatibility_mode spi|sclk_out] -name spi_sck
7 |
8 | derive_pll_clocks
9 |
10 | # Specify PLL-generated clock(s)
11 | create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \
12 | -name HDMI_CLK [get_ports HDMI_TX_CLK]
13 |
14 | derive_clock_uncertainty
15 |
16 | # Decouple different clock groups (to simplify routing)
17 | set_clock_groups -asynchronous \
18 | -group [get_clocks { *|pll|pll_inst|altera_pll_i|general[*].gpll~PLL_OUTPUT_COUNTER|divclk}] \
19 | -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \
20 | -group [get_clocks { *|h2f_user0_clk}] \
21 | -group [get_clocks { FPGA_CLK1_50 FPGA_CLK2_50 FPGA_CLK3_50}]
22 |
23 | set_output_delay -max -clock HDMI_CLK 2.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
24 | set_output_delay -min -clock HDMI_CLK -1.5ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}]
25 |
26 | set_false_path -from {*} -to [get_registers {wcalc[*] hcalc[*]}]
27 |
28 |
29 | # Put constraints on input ports
30 | set_false_path -from [get_ports {KEY*}] -to *
31 | set_false_path -from [get_ports {BTN_*}] -to *
32 |
33 | # Put constraints on output ports
34 | set_false_path -from * -to [get_ports {LED_*}]
35 | set_false_path -from * -to [get_ports {VGA_*}]
36 | set_false_path -from * -to [get_ports {AUDIO_SPDIF}]
37 | set_false_path -from * -to [get_ports {AUDIO_L}]
38 | set_false_path -from * -to [get_ports {AUDIO_R}]
39 |
--------------------------------------------------------------------------------
/sys/video_cleaner.sv:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2018 Sorgelig
4 | //
5 | // This program is GPL Licensed. See COPYING for the full license.
6 | //
7 | //
8 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
9 |
10 | `timescale 1ns / 1ps
11 |
12 | module video_cleaner
13 | (
14 | input clk_vid,
15 | input ce_pix,
16 |
17 | input [7:0] R,
18 | input [7:0] G,
19 | input [7:0] B,
20 |
21 | input HSync,
22 | input VSync,
23 | input HBlank,
24 | input VBlank,
25 |
26 | // video output signals
27 | output reg [7:0] VGA_R,
28 | output reg [7:0] VGA_G,
29 | output reg [7:0] VGA_B,
30 | output reg VGA_VS,
31 | output reg VGA_HS,
32 | output VGA_DE,
33 |
34 | // optional aligned blank
35 | output reg HBlank_out,
36 | output reg VBlank_out
37 | );
38 |
39 | wire hs, vs;
40 | s_fix sync_v(clk_vid, HSync, hs);
41 | s_fix sync_h(clk_vid, VSync, vs);
42 |
43 | wire hbl = hs | HBlank;
44 | wire vbl = vs | VBlank;
45 |
46 | assign VGA_DE = ~(HBlank_out | VBlank_out);
47 |
48 | always @(posedge clk_vid) begin
49 | if(ce_pix) begin
50 | HBlank_out <= hbl;
51 |
52 | VGA_VS <= vs;
53 | VGA_HS <= hs;
54 | VGA_R <= R;
55 | VGA_G <= G;
56 | VGA_B <= B;
57 |
58 | if(HBlank_out & ~hbl) VBlank_out <= vbl;
59 | end
60 | end
61 |
62 | endmodule
63 |
64 | module s_fix
65 | (
66 | input clk,
67 |
68 | input sync_in,
69 | output sync_out
70 | );
71 |
72 | assign sync_out = sync_in ^ pol;
73 |
74 | reg pol;
75 | always @(posedge clk) begin
76 | integer pos = 0, neg = 0, cnt = 0;
77 | reg s1,s2;
78 |
79 | s1 <= sync_in;
80 | s2 <= s1;
81 |
82 | if(~s2 & s1) neg <= cnt;
83 | if(s2 & ~s1) pos <= cnt;
84 |
85 | cnt <= cnt + 1;
86 | if(s2 != s1) cnt <= 0;
87 |
88 | pol <= pos > neg;
89 | end
90 |
91 | endmodule
92 |
--------------------------------------------------------------------------------
/sys/sys.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ]
2 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ]
3 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.qip ]
4 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ]
5 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.qip ]
6 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ]
7 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ]
8 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ]
9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ]
10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ]
11 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ]
12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ]
13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ]
14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ]
15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ]
16 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ]
17 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ]
18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ]
19 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ]
20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ]
21 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ]
22 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ]
23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ]
24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ]
25 | set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi
26 |
--------------------------------------------------------------------------------
/sys/build_id.tcl:
--------------------------------------------------------------------------------
1 |
2 | # Build TimeStamp Verilog Module
3 | # Jeff Wiencrot - 8/1/2011
4 | proc generateBuildID_Verilog {} {
5 |
6 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
7 | set buildDate [ clock format [ clock seconds ] -format %y%m%d ]
8 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
9 |
10 | # Create a Verilog file for output
11 | set outputFileName "build_id.v"
12 | set outputFile [open $outputFileName "w"]
13 |
14 | # Output the Verilog source
15 | puts $outputFile "`define BUILD_DATE \"$buildDate\""
16 | puts $outputFile "`define BUILD_TIME \"$buildTime\""
17 | close $outputFile
18 |
19 | # Send confirmation message to the Messages window
20 | post_message "Generated build identification Verilog module: [pwd]/$outputFileName"
21 | post_message "Date: $buildDate"
22 | post_message "Time: $buildTime"
23 | }
24 |
25 | # Build CDF file
26 | # Sorgelig - 17/2/2018
27 | proc generateCDF {revision device outpath} {
28 |
29 | set outputFileName "jtag.cdf"
30 | set outputFile [open $outputFileName "w"]
31 |
32 | puts $outputFile "JedecChain;"
33 | puts $outputFile " FileRevision(JESD32A);"
34 | puts $outputFile " DefaultMfr(6E);"
35 | puts $outputFile ""
36 | puts $outputFile " P ActionCode(Ign)"
37 | puts $outputFile " Device PartName(SOCVHPS) MfrSpec(OpMask(0));"
38 | puts $outputFile " P ActionCode(Cfg)"
39 | puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));"
40 | puts $outputFile "ChainEnd;"
41 | puts $outputFile ""
42 | puts $outputFile "AlteraBegin;"
43 | puts $outputFile " ChainType(JTAG);"
44 | puts $outputFile "AlteraEnd;"
45 | }
46 |
47 | set project_name [lindex $quartus(args) 1]
48 | set revision [lindex $quartus(args) 2]
49 |
50 | if {[project_exists $project_name]} {
51 | if {[string equal "" $revision]} {
52 | project_open $project_name -revision [get_current_revision $project_name]
53 | } else {
54 | project_open $project_name -revision $revision
55 | }
56 | } else {
57 | post_message -type error "Project $project_name does not exist"
58 | exit
59 | }
60 |
61 | set device [get_global_assignment -name DEVICE]
62 | set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY]
63 |
64 | if [is_project_open] {
65 | project_close
66 | }
67 |
68 | generateBuildID_Verilog
69 | generateCDF $revision $device $outpath
70 |
--------------------------------------------------------------------------------
/sys/pll/pll_0002.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | module pll_0002(
3 |
4 | // interface 'refclk'
5 | input wire refclk,
6 |
7 | // interface 'reset'
8 | input wire rst,
9 |
10 | // interface 'outclk0'
11 | output wire outclk_0,
12 |
13 | // interface 'outclk1'
14 | output wire outclk_1,
15 |
16 | // interface 'locked'
17 | output wire locked
18 | );
19 |
20 | altera_pll #(
21 | .fractional_vco_multiplier("false"),
22 | .reference_clock_frequency("50.0 MHz"),
23 | .operation_mode("direct"),
24 | .number_of_clocks(2),
25 | .output_clock_frequency0("49.147727 MHz"),
26 | .phase_shift0("0 ps"),
27 | .duty_cycle0(50),
28 | .output_clock_frequency1("24.573863 MHz"),
29 | .phase_shift1("0 ps"),
30 | .duty_cycle1(50),
31 | .output_clock_frequency2("0 MHz"),
32 | .phase_shift2("0 ps"),
33 | .duty_cycle2(50),
34 | .output_clock_frequency3("0 MHz"),
35 | .phase_shift3("0 ps"),
36 | .duty_cycle3(50),
37 | .output_clock_frequency4("0 MHz"),
38 | .phase_shift4("0 ps"),
39 | .duty_cycle4(50),
40 | .output_clock_frequency5("0 MHz"),
41 | .phase_shift5("0 ps"),
42 | .duty_cycle5(50),
43 | .output_clock_frequency6("0 MHz"),
44 | .phase_shift6("0 ps"),
45 | .duty_cycle6(50),
46 | .output_clock_frequency7("0 MHz"),
47 | .phase_shift7("0 ps"),
48 | .duty_cycle7(50),
49 | .output_clock_frequency8("0 MHz"),
50 | .phase_shift8("0 ps"),
51 | .duty_cycle8(50),
52 | .output_clock_frequency9("0 MHz"),
53 | .phase_shift9("0 ps"),
54 | .duty_cycle9(50),
55 | .output_clock_frequency10("0 MHz"),
56 | .phase_shift10("0 ps"),
57 | .duty_cycle10(50),
58 | .output_clock_frequency11("0 MHz"),
59 | .phase_shift11("0 ps"),
60 | .duty_cycle11(50),
61 | .output_clock_frequency12("0 MHz"),
62 | .phase_shift12("0 ps"),
63 | .duty_cycle12(50),
64 | .output_clock_frequency13("0 MHz"),
65 | .phase_shift13("0 ps"),
66 | .duty_cycle13(50),
67 | .output_clock_frequency14("0 MHz"),
68 | .phase_shift14("0 ps"),
69 | .duty_cycle14(50),
70 | .output_clock_frequency15("0 MHz"),
71 | .phase_shift15("0 ps"),
72 | .duty_cycle15(50),
73 | .output_clock_frequency16("0 MHz"),
74 | .phase_shift16("0 ps"),
75 | .duty_cycle16(50),
76 | .output_clock_frequency17("0 MHz"),
77 | .phase_shift17("0 ps"),
78 | .duty_cycle17(50),
79 | .pll_type("General"),
80 | .pll_subtype("General")
81 | ) altera_pll_i (
82 | .rst (rst),
83 | .outclk ({outclk_1, outclk_0}),
84 | .locked (locked),
85 | .fboutclk ( ),
86 | .fbclk (1'b0),
87 | .refclk (refclk)
88 | );
89 | endmodule
90 |
91 |
--------------------------------------------------------------------------------
/src/dprams.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // Dualport RAM modules for FPGA DigDug
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module DPR2KV
7 | (
8 | input CL0,
9 | input [10:0] AD0,
10 | input EN0,
11 | input WR0,
12 | input [7:0] DI0,
13 | output [7:0] DO0,
14 |
15 | input CL1,
16 | input [10:0] AD1,
17 | output [7:0] DO1
18 | );
19 |
20 | DPR2K ram(
21 | CL0, AD0, EN0, WR0, DI0, DO0,
22 | CL1, AD1, 1'b1, 1'b0, 8'h0, DO1
23 | );
24 |
25 | endmodule
26 |
27 |
28 | module DPR2K
29 | (
30 | input CL0,
31 | input [10:0] AD0,
32 | input EN0,
33 | input WR0,
34 | input [7:0] DI0,
35 | output reg [7:0] DO0,
36 |
37 | input CL1,
38 | input [10:0] AD1,
39 | input EN1,
40 | input WR1,
41 | input [7:0] DI1,
42 | output reg [7:0] DO1
43 | );
44 |
45 | reg [7:0] core[0:2047];
46 |
47 | always @( posedge CL0 ) begin
48 | if (EN0) begin
49 | DO0 <= core[AD0];
50 | if (WR0) core[AD0] <= DI0;
51 | end
52 | end
53 |
54 | always @( posedge CL1 ) begin
55 | if (EN1) begin
56 | DO1 <= core[AD1];
57 | if (WR1) core[AD1] <= DI1;
58 | end
59 | end
60 |
61 | endmodule
62 |
63 |
64 | module LBUF1K
65 | (
66 | input CL0,
67 | input [9:0] AD0,
68 | input WR0,
69 | input [7:0] DI0,
70 |
71 | input CL1,
72 | input [9:0] AD1,
73 | input WR1,
74 | input [7:0] DI1,
75 | output [7:0] DO1
76 | );
77 |
78 | wire [7:0] non;
79 |
80 | LINEBUF lbuf(
81 | AD0,AD1,
82 | CL0,CL1,
83 | DI0,DI1,
84 | WR0,WR1,
85 | non,DO1
86 | );
87 |
88 | endmodule
89 |
90 |
91 | module DLROM #(parameter AW,parameter DW)
92 | (
93 | input CL0,
94 | input [(AW-1):0] AD0,
95 | output reg [(DW-1):0] DO0,
96 |
97 | input CL1,
98 | input [(AW-1):0] AD1,
99 | input [(DW-1):0] DI1,
100 | input WE1
101 | );
102 |
103 | reg [DW:0] core[0:((2**AW)-1)];
104 |
105 | always @(posedge CL0) DO0 <= core[AD0];
106 | always @(posedge CL1) if (WE1) core[AD1] <= DI1;
107 |
108 | endmodule
109 |
110 |
111 | module DLROMe #(parameter AW,parameter DW)
112 | (
113 | input RE0,
114 | input CL0,
115 | input [(AW-1):0] AD0,
116 | output reg [(DW-1):0] DO0,
117 |
118 | input CL1,
119 | input [(AW-1):0] AD1,
120 | input [(DW-1):0] DI1,
121 | input WE1
122 | );
123 |
124 | reg [DW:0] core[0:((2**AW)-1)];
125 |
126 | always @(posedge CL0) if (RE0) DO0 <= core[AD0];
127 | always @(posedge CL1) if (WE1) core[AD1] <= DI1;
128 |
129 | endmodule
130 |
131 |
--------------------------------------------------------------------------------
/src/cpu/tv80_reg.v:
--------------------------------------------------------------------------------
1 | //
2 | // TV80 8-Bit Microprocessor Core
3 | // Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
4 | //
5 | // Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a
8 | // copy of this software and associated documentation files (the "Software"),
9 | // to deal in the Software without restriction, including without limitation
10 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | // and/or sell copies of the Software, and to permit persons to whom the
12 | // Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included
15 | // in all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | module tv80_reg (/*AUTOARG*/
26 | // Outputs
27 | DOBH, DOAL, DOCL, DOBL, DOCH, DOAH,
28 | // Inputs
29 | AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL
30 | );
31 | input [2:0] AddrC;
32 | output [7:0] DOBH;
33 | input [2:0] AddrA;
34 | input [2:0] AddrB;
35 | input [7:0] DIH;
36 | output [7:0] DOAL;
37 | output [7:0] DOCL;
38 | input [7:0] DIL;
39 | output [7:0] DOBL;
40 | output [7:0] DOCH;
41 | output [7:0] DOAH;
42 | input clk, CEN, WEH, WEL;
43 |
44 | reg [7:0] RegsH [0:7];
45 | reg [7:0] RegsL [0:7];
46 |
47 | always @(posedge clk)
48 | begin
49 | if (CEN)
50 | begin
51 | if (WEH) RegsH[AddrA] <= DIH;
52 | if (WEL) RegsL[AddrA] <= DIL;
53 | end
54 | end
55 |
56 | assign DOAH = RegsH[AddrA];
57 | assign DOAL = RegsL[AddrA];
58 | assign DOBH = RegsH[AddrB];
59 | assign DOBL = RegsL[AddrB];
60 | assign DOCH = RegsH[AddrC];
61 | assign DOCL = RegsL[AddrC];
62 |
63 | // break out ram bits for waveform debug
64 | wire [7:0] H = RegsH[2];
65 | wire [7:0] L = RegsL[2];
66 |
67 | // synopsys dc_script_begin
68 | // set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004/05/16 17:39:57 ghutchis Exp $" -type string -quiet
69 | // synopsys dc_script_end
70 | endmodule
71 |
72 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | ---------------------------------------------------------------------------------
2 | --
3 | -- Arcade: DigDug port to MiSTer by MiSTer-X
4 | -- 21 September 2019
5 | --
6 | ---------------------------------------------------------------------------------
7 | -- FPGA DigDug for XILINX Spartan-6
8 | ------------------------------------------------
9 | -- Copyright (c) 2017 MiSTer-X
10 | ---------------------------------------------------------------------------------
11 | -- T80/T80s - Version : 0242
12 | -----------------------------
13 | -- TV80 8-Bit Microprocessor Core
14 | -- Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
15 | --
16 | -- Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
17 | ---------------------------------------------------------------------------------
18 | --
19 | --
20 | -- Keyboard inputs :
21 | --
22 | -- F2 : Coin + Start 2 players
23 | -- F1 : Coin + Start 1 player
24 | -- UP,DOWN,LEFT,RIGHT arrows : Movements
25 | -- SPACE/CTRL : Pump
26 | --
27 | -- MAME/IPAC/JPAC Style Keyboard inputs:
28 | -- 5 : Coin 1
29 | -- 6 : Coin 2
30 | -- 1 : Start 1 Player
31 | -- 2 : Start 2 Players
32 | -- R,F,D,G : Player 2 Movements
33 | -- A/S : Player 2 Pump
34 | --
35 | --
36 | -- Joystick support.
37 | --
38 | --
39 | ---------------------------------------------------------------------------------
40 | -- 21 September 2019
41 | ---------------------------------------------------------------------------------
42 | -- FIXED: wrong aspect ratio in "Vert" mode.
43 | ---------------------------------------------------------------------------------
44 | -- 22 October 2019
45 | ---------------------------------------------------------------------------------
46 | -- FIXED: Little problem with CRT and HDMI.
47 | -- CHANGED: Keyboard inputs.
48 | -- Abolished rotation of control direction in Horz mode.
49 | ---------------------------------------------------------------------------------
50 |
51 | *** Attention ***
52 |
53 | ROMs are not included. In order to use this arcade, you need to provide the
54 | correct ROMs.
55 |
56 | To simplify the process .mra files are provided in the releases folder, that
57 | specifies the required ROMs with checksums. The ROMs .zip filename refers to the
58 | corresponding file of the M.A.M.E. project.
59 |
60 | Please refer to https://github.com/MiSTer-devel/Main_MiSTer/wiki/Arcade-Roms for
61 | information on how to setup and use the environment.
62 |
63 | Quickreference for folders and file placement:
64 |
65 | /_Arcade/.mra
66 | /_Arcade/cores/.rbf
67 | /_Arcade/mame/.zip
68 | /_Arcade/hbmame/.zip
69 |
70 |
--------------------------------------------------------------------------------
/sys/sys_q13.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ]
2 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ]
3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll.v ]
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll/pll_0002.v ]
5 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll/pll_0002.qip ]
6 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_q13.qip ]
7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.v ]
8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_core.v ]
9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_top.v ]
10 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ]
11 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ]
12 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ]
13 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ]
14 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ]
15 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ]
16 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ]
17 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) arcade_video.v ]
18 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ]
19 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ]
20 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ]
21 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ]
22 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ]
23 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ]
24 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ]
25 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ]
26 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ]
27 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ]
28 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ]
29 | set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi
30 |
--------------------------------------------------------------------------------
/sys/i2s.v:
--------------------------------------------------------------------------------
1 |
2 | module i2s
3 | #(
4 | parameter CLK_RATE = 50000000,
5 | parameter AUDIO_DW = 16,
6 | parameter AUDIO_RATE = 96000
7 | )
8 | (
9 | input reset,
10 | input clk_sys,
11 | input half_rate,
12 |
13 | output reg sclk,
14 | output reg lrclk,
15 | output reg sdata,
16 |
17 | input [AUDIO_DW-1:0] left_chan,
18 | input [AUDIO_DW-1:0] right_chan
19 | );
20 |
21 | localparam WHOLE_CYCLES = (CLK_RATE) / (AUDIO_RATE*AUDIO_DW*4);
22 | localparam ERROR_BASE = 10000;
23 | localparam [63:0] ERRORS_PER_BIT = ((CLK_RATE * ERROR_BASE) / (AUDIO_RATE*AUDIO_DW*4)) - (WHOLE_CYCLES * ERROR_BASE);
24 |
25 | reg lpf_ce;
26 | wire [AUDIO_DW-1:0] al, ar;
27 |
28 | lpf_i2s lpf_l
29 | (
30 | .CLK(clk_sys),
31 | .CE(lpf_ce),
32 | .IDATA(left_chan),
33 | .ODATA(al)
34 | );
35 |
36 | lpf_i2s lpf_r
37 | (
38 | .CLK(clk_sys),
39 | .CE(lpf_ce),
40 |
41 | .IDATA(right_chan),
42 | .ODATA(ar)
43 | );
44 |
45 | always @(posedge clk_sys) begin
46 | reg [31:0] count_q;
47 | reg [31:0] error_q;
48 | reg [7:0] bit_cnt;
49 | reg skip = 0;
50 |
51 | reg [AUDIO_DW-1:0] left;
52 | reg [AUDIO_DW-1:0] right;
53 |
54 | reg msclk;
55 | reg ce;
56 |
57 | lpf_ce <= 0;
58 |
59 | if (reset) begin
60 | count_q <= 0;
61 | error_q <= 0;
62 | ce <= 0;
63 | bit_cnt <= 1;
64 | lrclk <= 1;
65 | sclk <= 1;
66 | msclk <= 1;
67 | end
68 | else
69 | begin
70 | if(count_q == WHOLE_CYCLES-1) begin
71 | if (error_q < (ERROR_BASE - ERRORS_PER_BIT)) begin
72 | error_q <= error_q + ERRORS_PER_BIT[31:0];
73 | count_q <= 0;
74 | end else begin
75 | error_q <= error_q + ERRORS_PER_BIT[31:0] - ERROR_BASE;
76 | count_q <= count_q + 1;
77 | end
78 | end else if(count_q == WHOLE_CYCLES) begin
79 | count_q <= 0;
80 | end else begin
81 | count_q <= count_q + 1;
82 | end
83 |
84 | sclk <= msclk;
85 | if(!count_q) begin
86 | ce <= ~ce;
87 | if(~half_rate || ce) begin
88 | msclk <= ~msclk;
89 | if(msclk) begin
90 | skip <= ~skip;
91 | if(skip) lpf_ce <= 1;
92 | if(bit_cnt >= AUDIO_DW) begin
93 | bit_cnt <= 1;
94 | lrclk <= ~lrclk;
95 | if(lrclk) begin
96 | left <= al;
97 | right <= ar;
98 | end
99 | end
100 | else begin
101 | bit_cnt <= bit_cnt + 1'd1;
102 | end
103 | sdata <= lrclk ? right[AUDIO_DW - bit_cnt] : left[AUDIO_DW - bit_cnt];
104 | end
105 | end
106 | end
107 | end
108 | end
109 |
110 | endmodule
111 |
112 | module lpf_i2s
113 | (
114 | input CLK,
115 | input CE,
116 | input [15:0] IDATA,
117 | output reg [15:0] ODATA
118 | );
119 |
120 | reg [511:0] acc;
121 | reg [20:0] sum;
122 |
123 | always @(*) begin
124 | integer i;
125 | sum = 0;
126 | for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]};
127 | end
128 |
129 | always @(posedge CLK) begin
130 | if(CE) begin
131 | acc <= {acc[495:0], IDATA};
132 | ODATA <= sum[20:5];
133 | end
134 | end
135 |
136 | endmodule
137 |
--------------------------------------------------------------------------------
/sys/vga_out.sv:
--------------------------------------------------------------------------------
1 |
2 | module vga_out
3 | (
4 | input ypbpr_full,
5 | input ypbpr_en,
6 |
7 | input [23:0] din,
8 | output [23:0] dout
9 | );
10 |
11 | wire [5:0] yuv_full[225] = '{
12 | 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
13 | 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
14 | 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
15 | 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
16 | 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
17 | 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
18 | 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
19 | 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
20 | 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
21 | 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
22 | 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
23 | 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
24 | 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
25 | 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
26 | 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
27 | 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
28 | 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
29 | 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
30 | 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
31 | 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
32 | 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
33 | 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
34 | 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
35 | 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
36 | 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
37 | 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
38 | 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
39 | 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
40 | 6'd63
41 | };
42 |
43 | wire [5:0] red = din[23:18];
44 | wire [5:0] green = din[15:10];
45 | wire [5:0] blue = din[7:2];
46 |
47 | // http://marsee101.blog19.fc2.com/blog-entry-2311.html
48 | // Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B)
49 | // Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
50 | // Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
51 |
52 | wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
53 | wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
54 | wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
55 |
56 | wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
57 | wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
58 | wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
59 |
60 | assign dout[23:16] = ypbpr_en ? {(ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]), 2'b00} : din[23:16];
61 | assign dout[15:8] = ypbpr_en ? {(ypbpr_full ? yuv_full[y -8'd16] : y[7:2]), 2'b00} : din[15:8];
62 | assign dout[7:0] = ypbpr_en ? {(ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]), 2'b00} : din[7:0];
63 |
64 |
65 | endmodule
66 |
--------------------------------------------------------------------------------
/src/DIGDUG_SPRITE.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // FPGA DigDug (Sprite part)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module DIGDUG_SPRITE
7 | (
8 | input RCLK, // Rendering Clock
9 | input VCLK, // Video Dot Clock
10 | input VCLKx2, // Video Dot Clockx2
11 |
12 | input [8:0] POSH,
13 | input [8:0] POSV,
14 |
15 | output SPATCL,
16 | output [6:0] SPATAD,
17 | input [23:0] SPATDT,
18 |
19 | output reg [4:0] SPCOL,
20 |
21 |
22 | input ROMCL, // Downloaded ROM image
23 | input [15:0] ROMAD,
24 | input [7:0] ROMDT,
25 | input ROMEN
26 | );
27 |
28 | wire [8:0] PH = POSH+1;
29 | wire [8:0] PV = POSV+2;
30 | wire [8:0] TY;
31 |
32 |
33 | reg [3:0] PHASE;
34 | reg SIDE;
35 |
36 | reg [7:0] ADR;
37 | reg [23:0] ATR0, ATR1;
38 |
39 | reg [8:0] WXP;
40 | reg [8:0] WCN;
41 |
42 |
43 | wire SZ = ATR0[7]; // Size
44 | wire [8:0] SS = SZ ? 32 : 16; // Size (Pixels)
45 | wire [5:0] SC = ATR1[5:0]; // Color
46 | wire [8:0] SX = {1'b0,ATR1[15:8]}-9'd39; // Position X
47 | wire [8:0] SY = (9'd256-TY); // Position Y
48 | wire [8:0] SU = (SS-WCN)^{9{ATR0[16]}}; // Position U
49 | wire [8:0] SV = (PV-SY )^{9{ATR0[17]}}; // Position V
50 | wire [7:0] SM = ATR0[7:0]; // Code (for Normal)
51 | wire [7:0] SL = {SM[7]|SM[5],SM[6]|SM[4],SM[3:0],SV[4],SU[4]}; // Code (for Size)
52 | wire [7:0] SN = SZ ? SL : SM; // Code
53 | wire SD = ATR1[17]|((PV=(SY+SS)); // Visiblity (False:Visible)
54 |
55 | assign TY = ((({1'b0,ATR0[15:8]}+1)+(SZ ? 9'd16 : 9'd0)) & 9'd255) + 9'd30;
56 |
57 | wire ABORT = (PH==288);
58 | wire STANDBY = (PH!=289);
59 | wire ATRTAIL = (ADR[7]);
60 | wire DRAWING = (WCN!=1);
61 |
62 |
63 | assign SPATCL = ~RCLK;
64 | assign SPATAD = ADR[6:0];
65 |
66 | wire [8:0] WSX = {1'b0,SX[7:0]} + ((SX[7:0]<8'd16) ? 9'd256 : 9'd0);
67 |
68 | always @( posedge RCLK ) begin
69 | if (ABORT) begin PHASE <= 0; WCN <= 0; end
70 | else case (PHASE)
71 | `define LOOP (PHASE)
72 | `define NEXT (PHASE+1)
73 | `define NXTA (1)
74 | 0: begin SIDE <= PV[0]; ADR <= 0; WCN <= 0; PHASE <= STANDBY ? `LOOP : `NEXT; end
75 | 1: begin PHASE <= ATRTAIL ? `NXTA : `NEXT; end
76 | 2: begin ATR0 <= SPATDT; ADR <= ADR+1; PHASE <= `NEXT; end
77 | 3: begin ATR1 <= SPATDT; ADR <= ADR+1; PHASE <= `NEXT; end
78 | 4: begin WXP <= WSX; WCN <= SS; PHASE <= SD ? `NXTA : `NEXT; end
79 | // CHIP Read
80 | 5: begin /* CLUT Read */ PHASE <= `NEXT; end
81 | // LBUF Write
82 | 6: begin WXP <= WXP+1; WCN <= WCN-1; PHASE <= DRAWING ? 5 : `NXTA; end
83 | default:;
84 | endcase
85 | end
86 |
87 | wire [7:0] CHRD;
88 | DLROMe #(14,8) spchip((PHASE==5),~RCLK,{SN,SV[3],SU[3:2],SV[2:0]},CHRD, ROMCL,ROMAD[14:0],ROMDT,ROMEN & (ROMAD[15:14]==2'b01));
89 | wire [7:0] PIX = CHRD << (SU[1:0]);
90 |
91 | wire [7:0] WDT;
92 | DLROMe #(8,8) spclut((PHASE==5), RCLK,{SC,PIX[7],PIX[3]},WDT, ROMCL,ROMAD[7:0],ROMDT,ROMEN & (ROMAD[15:8]==8'hD9));
93 |
94 | wire [4:0] LBOUT;
95 | LBUF1K lbuf (
96 | ~RCLK, {SIDE,WXP}, (PHASE==6) & (PIX[7]|PIX[3]), {4'h1,WDT[3:0]},
97 | VCLKx2, {~SIDE,PH}, (radr0==radr1), 8'h0, LBOUT
98 | );
99 |
100 | reg [9:0] radr0=0,radr1=1;
101 | always @(posedge VCLK) radr0 <= {~SIDE,PH};
102 | always @(negedge VCLK) begin
103 | if (radr0!=radr1) SPCOL <= LBOUT;
104 | radr1 <= radr0;
105 | end
106 |
107 | endmodule
108 |
109 |
--------------------------------------------------------------------------------
/sys/alsa.sv:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | //
3 | // ALSA sound support for MiSTer
4 | // (c)2019 Sorgelig
5 | //
6 | // This program is free software; you can redistribute it and/or modify it
7 | // under the terms of the GNU General Public License as published by the Free
8 | // Software Foundation; either version 2 of the License, or (at your option)
9 | // any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful, but WITHOUT
12 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 | // more details.
15 | //
16 | // You should have received a copy of the GNU General Public License along
17 | // with this program; if not, write to the Free Software Foundation, Inc.,
18 | // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 | //
20 | //============================================================================
21 |
22 | module alsa
23 | (
24 | input reset,
25 |
26 | input ram_clk,
27 | output reg [28:0] ram_address,
28 | output reg [7:0] ram_burstcount,
29 | input ram_waitrequest,
30 | input [63:0] ram_readdata,
31 | input ram_readdatavalid,
32 | output reg ram_read,
33 |
34 | input spi_ss,
35 | input spi_sck,
36 | input spi_mosi,
37 |
38 | output reg [15:0] pcm_l,
39 | output reg [15:0] pcm_r
40 | );
41 |
42 | reg spi_new = 0;
43 | reg [127:0] spi_data;
44 | always @(posedge spi_sck, posedge spi_ss) begin
45 | reg [7:0] mosi;
46 | reg [6:0] spicnt = 0;
47 |
48 | if(spi_ss) spicnt <= 0;
49 | else begin
50 | mosi <= {mosi[6:0],spi_mosi};
51 |
52 | spicnt <= spicnt + 1'd1;
53 | if(&spicnt[2:0]) begin
54 | spi_data[{spicnt[6:3],3'b000} +:8] <= {mosi[6:0],spi_mosi};
55 | spi_new <= &spicnt;
56 | end
57 | end
58 | end
59 |
60 | reg [31:0] buf_addr;
61 | reg [31:0] buf_len;
62 | reg [31:0] buf_wptr = 0;
63 |
64 | always @(posedge ram_clk) begin
65 | reg n1,n2,n3;
66 | reg [127:0] data1,data2;
67 |
68 | n1 <= spi_new;
69 | n2 <= n1;
70 | n3 <= n2;
71 |
72 | data1 <= spi_data;
73 | data2 <= data1;
74 |
75 | if(~n3 & n2) {buf_wptr,buf_len,buf_addr} <= data2[95:0];
76 | end
77 |
78 | reg [31:0] buf_rptr = 0;
79 | always @(posedge ram_clk) begin
80 | reg got_first = 0;
81 | reg ready = 0;
82 | reg ud;
83 | reg [31:0] readdata;
84 |
85 | if(~ram_waitrequest) ram_read <= 0;
86 | if(ram_readdatavalid && ram_burstcount) begin
87 | ram_burstcount <= 0;
88 | ready <= 1;
89 | readdata <= ud ? ram_readdata[63:32] : ram_readdata[31:0];
90 | if(buf_rptr[31:2] >= buf_len[31:2]) buf_rptr <= 0;
91 | end
92 |
93 | if(reset) {ready, got_first} <= 0;
94 | else
95 | if(buf_rptr[31:2] != buf_wptr[31:2]) begin
96 | if(~got_first) begin
97 | buf_rptr <= buf_wptr;
98 | got_first <= 1;
99 | end
100 | else
101 | if(!ram_burstcount && ~ram_waitrequest && ~ready) begin
102 | ram_address <= buf_addr[31:3] + buf_rptr[31:3];
103 | ud <= buf_rptr[2];
104 | ram_burstcount <= 1;
105 | ram_read <= 1;
106 | buf_rptr <= buf_rptr + 4;
107 | end
108 | end
109 |
110 | if(ready & ce_48k) begin
111 | {pcm_r,pcm_l} <= readdata;
112 | ready <= 0;
113 | end
114 | end
115 |
116 | reg ce_48k;
117 | always @(posedge ram_clk) begin
118 | reg [15:0] acc = 0;
119 |
120 | ce_48k <= 0;
121 | acc <= acc + 16'd48;
122 | if(acc >= 50000) begin
123 | acc <= acc - 16'd50000;
124 | ce_48k <= 1;
125 | end
126 | end
127 |
128 | endmodule
129 |
--------------------------------------------------------------------------------
/src/FPGA_DIGDUG.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // FPGA DigDug (Top module)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module FPGA_DIGDUG
7 | (
8 | input RESET, // RESET
9 | input MCLK, // Master Clock (48.0MHz) = VCLKx8
10 |
11 | input [7:0] INP0, // Control Panel
12 | input [7:0] INP1,
13 | input [7:0] DSW0,
14 | input [7:0] DSW1,
15 |
16 | input [8:0] PH, // PIXEL H
17 | input [8:0] PV, // PIXEL V
18 | output PCLK, // PIXEL CLOCK
19 | output [7:0] POUT, // PIXEL OUT
20 |
21 | output reg [7:0] SOUT, // SOUND OUT
22 |
23 | output [7:0] LED, // LEDs (for Debug)
24 |
25 |
26 | input ROMCL, // Downloaded ROM image
27 | input [15:0] ROMAD,
28 | input [7:0] ROMDT,
29 | input ROMEN
30 | );
31 |
32 | // Common I/O Device Bus
33 | wire DEV_CL;
34 | wire [15:0] DEV_AD;
35 | wire DEV_RD;
36 | wire DEV_DV;
37 | wire [7:0] DEV_DO;
38 | wire DEV_WR;
39 | wire [7:0] DEV_DI;
40 |
41 |
42 | //-----------------------------------------------
43 | // CPUs
44 | //-----------------------------------------------
45 | wire [2:0] RSTS,IRQS,NMIS;
46 |
47 | DIGDUG_CORES cores
48 | (
49 | .MCLK(MCLK),
50 | .RSTS(RSTS),.IRQS(IRQS),.NMIS(NMIS),
51 |
52 | .DEV_CL(DEV_CL),.DEV_AD(DEV_AD),
53 | .DEV_RD(DEV_RD),.DEV_DV(DEV_DV),.DEV_DO(DEV_DO),
54 | .DEV_WR(DEV_WR),.DEV_DI(DEV_DI),
55 |
56 | .ROMCL(ROMCL),.ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN)
57 | );
58 |
59 | assign LED = { RSTS, IRQS[1:0], 1'b0, NMIS[2],NMIS[0] };
60 |
61 |
62 | //-----------------------------------------------
63 | // Sound wave ROM
64 | //-----------------------------------------------
65 | wire WAVECL;
66 | wire [7:0] WAVEAD;
67 | wire [3:0] WAVEDT;
68 |
69 | DLROM #(8,4) wave(WAVECL,WAVEAD,WAVEDT, ROMCL,ROMAD[7:0],ROMDT,ROMEN & (ROMAD[15:8]==8'hD8));
70 |
71 |
72 | //-----------------------------------------------
73 | // Common I/O Device Module
74 | //-----------------------------------------------
75 | wire PCMCLK;
76 | wire [7:0] PCMOUT;
77 | always @(posedge PCMCLK) SOUT <= PCMOUT;
78 |
79 | wire FGSCCL;
80 | wire [9:0] FGSCAD;
81 | wire [7:0] FGSCDT;
82 |
83 | wire SPATCL;
84 | wire [6:0] SPATAD;
85 | wire [23:0] SPATDT;
86 |
87 | wire [1:0] BG_SELECT;
88 | wire [1:0] BG_COLBNK;
89 | wire BG_CUTOFF;
90 | wire FG_CLMODE;
91 |
92 | wire VBLK;
93 |
94 | DIGDUG_IODEV iodev
95 | (
96 | .RESET(RESET),
97 | .VBLK(VBLK),
98 |
99 | .INP0(INP0),
100 | .INP1(INP1),
101 | .DSW0(DSW0),
102 | .DSW1(DSW1),
103 |
104 | .CL(DEV_CL), // Access Clock: 24.0MHz
105 | .AD(DEV_AD),.WR(DEV_WR),.DI(DEV_DI),
106 | .RD(DEV_RD),.DV(DEV_DV),.DO(DEV_DO),
107 |
108 | .RSTS(RSTS),.IRQS(IRQS),.NMIS(NMIS),
109 |
110 | .CLK48M(MCLK),.PCMCLK(PCMCLK),.PCMOUT(PCMOUT),
111 |
112 | .WAVECL(WAVECL),.WAVEAD(WAVEAD),.WAVEDT(WAVEDT),
113 |
114 | .FGSCCL(FGSCCL),.FGSCAD(FGSCAD),.FGSCDT(FGSCDT),
115 | .SPATCL(SPATCL),.SPATAD(SPATAD),.SPATDT(SPATDT),
116 |
117 | .BG_SELECT(BG_SELECT),.BG_COLBNK(BG_COLBNK),.BG_CUTOFF(BG_CUTOFF),
118 | .FG_CLMODE(FG_CLMODE)
119 | );
120 |
121 |
122 | //-----------------------------------------------
123 | // Video Module
124 | //-----------------------------------------------
125 | DIGDUG_VIDEO video
126 | (
127 | .CLK48M(MCLK),
128 | .POSH(PH),.POSV(PV),
129 |
130 | .BG_SELECT(BG_SELECT),.BG_COLBNK(BG_COLBNK),.BG_CUTOFF(BG_CUTOFF),
131 | .FG_CLMODE(FG_CLMODE),
132 |
133 | .FGSCCL(FGSCCL),.FGSCAD(FGSCAD),.FGSCDT(FGSCDT),
134 | .SPATCL(SPATCL),.SPATAD(SPATAD),.SPATDT(SPATDT),
135 |
136 | .VBLK(VBLK),.PCLK(PCLK),.POUT(POUT),
137 |
138 | .ROMCL(ROMCL),.ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN)
139 | );
140 |
141 |
142 | endmodule
143 |
144 |
--------------------------------------------------------------------------------
/src/DIGDUG_VIDEO.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // FPGA DigDug (Video part)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module DIGDUG_VIDEO
7 | (
8 | input CLK48M,
9 | input [8:0] POSH,
10 | input [8:0] POSV,
11 |
12 | input [1:0] BG_SELECT,
13 | input [1:0] BG_COLBNK,
14 | input BG_CUTOFF,
15 | input FG_CLMODE,
16 |
17 | output FGSCCL,
18 | output [9:0] FGSCAD,
19 | input [7:0] FGSCDT,
20 |
21 | output SPATCL,
22 | output [6:0] SPATAD,
23 | input [23:0] SPATDT,
24 |
25 | output VBLK,
26 | output PCLK,
27 | output [7:0] POUT,
28 |
29 |
30 | input ROMCL, // Downloaded ROM image
31 | input [15:0] ROMAD,
32 | input [7:0] ROMDT,
33 | input ROMEN
34 | );
35 |
36 | //---------------------------------------
37 | // Clock Generator
38 | //---------------------------------------
39 | reg [2:0] clkdiv;
40 | always @( posedge CLK48M ) clkdiv <= clkdiv+1;
41 | wire VCLKx8 = CLK48M;
42 | wire VCLKx4 = clkdiv[0];
43 | wire VCLKx2 = clkdiv[1];
44 | wire VCLK = clkdiv[2];
45 |
46 |
47 | //---------------------------------------
48 | // Local Offset
49 | //---------------------------------------
50 | reg [8:0] PH, PV;
51 | always@( posedge VCLK ) begin
52 | PH <= POSH+1;
53 | PV <= POSV+(POSH>=504);
54 | end
55 |
56 |
57 | //---------------------------------------
58 | // VRAM Scan Address Generator
59 | //---------------------------------------
60 | wire [5:0] SCOL = PH[8:3]-2;
61 | wire [5:0] SROW = PV[8:3]+2;
62 | wire [9:0] VSAD = SCOL[5] ? {SCOL[4:0],SROW[4:0]} : {SROW[4:0],SCOL[4:0]};
63 |
64 |
65 | //---------------------------------------
66 | // Sprite ScanLine Generator
67 | //---------------------------------------
68 | wire [4:0] SPCOL;
69 |
70 | DIGDUG_SPRITE sprite
71 | (
72 | .RCLK(VCLKx8),.VCLK(VCLK),.VCLKx2(VCLKx2),
73 | .POSH(PH-1),.POSV(PV),
74 | .SPATCL(SPATCL),.SPATAD(SPATAD),.SPATDT(SPATDT),
75 |
76 | .SPCOL(SPCOL),
77 |
78 | .ROMCL(ROMCL),.ROMAD(ROMAD),.ROMDT(ROMDT),.ROMEN(ROMEN)
79 | );
80 |
81 |
82 | //---------------------------------------
83 | // FG ScanLine Generator
84 | //---------------------------------------
85 | reg [4:0] FGCOL;
86 |
87 | assign FGSCCL = VCLKx2;
88 | assign FGSCAD = VSAD;
89 |
90 | wire [10:0] FGCHAD = {1'b0,FGSCDT[6:0],PV[2:0]};
91 | wire [7:0] FGCHDT;
92 | DLROM #(11,8) fgchip(~VCLKx2,FGCHAD,FGCHDT, ROMCL,ROMAD[10:0],ROMDT,ROMEN & (ROMAD[15:11]=={4'hD,1'b0}));
93 | wire [7:0] FGCHPX = FGCHDT >> (PH[2:0]);
94 |
95 | wire [3:0] FGCLUT = FG_CLMODE ? FGSCDT[3:0] : ({FGSCDT[7:5],1'b0}|{2'b00,FGSCDT[4],1'b0});
96 |
97 | always @( posedge VCLKx2 ) FGCOL <= {FGCHPX[0],FGCLUT};
98 |
99 |
100 | //---------------------------------------
101 | // BG ScanLine Generator
102 | //---------------------------------------
103 | wire [3:0] BGCOL;
104 |
105 | wire [11:0] BGSCAD = {BG_SELECT,VSAD};
106 | wire [7:0] BGSCDT;
107 | DLROM #(12,8) bgscrn(VCLKx2,BGSCAD,BGSCDT, ROMCL,ROMAD[11:0],ROMDT,ROMEN & (ROMAD[15:12]==4'hB));
108 |
109 | wire [11:0] BGCHAD = {BGSCDT,~PH[2],PV[2:0]};
110 | wire [7:0] BGCHDT;
111 | DLROM #(12,8) bgchip(~VCLKx2,BGCHAD,BGCHDT, ROMCL,ROMAD[11:0],ROMDT,ROMEN & (ROMAD[15:12]==4'hC));
112 | wire [7:0] BGCHPI = BGCHDT << (PH[1:0]);
113 | wire [1:0] BGCHPX = {BGCHPI[7],BGCHPI[3]};
114 |
115 | wire [7:0] BGCLAD = BG_CUTOFF ? {6'h0F,BGCHPX} : {BG_COLBNK,BGSCDT[7:4],BGCHPX};
116 | DLROM #(8,4) bgclut(VCLKx2,BGCLAD,BGCOL, ROMCL,ROMAD[7:0],ROMDT,ROMEN & (ROMAD[15:8]==8'hDA));
117 |
118 |
119 | //---------------------------------------
120 | // Color Mixer & Pixel Output
121 | //---------------------------------------
122 | wire [4:0] CMIX = SPCOL[4] ? {1'b1,SPCOL[3:0]} : FGCOL[4] ? {1'b0,FGCOL[3:0]} : {1'b0,BGCOL};
123 |
124 | DLROM #(5,8) palet( VCLK, CMIX, POUT, ROMCL,ROMAD[4:0],ROMDT,ROMEN & (ROMAD[15:5]=={8'hDB,3'b000}) );
125 | assign PCLK = ~VCLK;
126 | assign VBLK = (PH<64)&(PV==224);
127 |
128 | endmodule
129 |
130 |
--------------------------------------------------------------------------------
/Arcade-DigDug.srf:
--------------------------------------------------------------------------------
1 | { "" "" "" "Vip.Mixer: The MixerII register map changed in ACDS v16.0. Please refer to the VIP User Guide for details." { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
2 | { "" "" "" "Vip.Reset_Source.reset_sys: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
3 | { "" "" "" "Vip.Reset_Source.reset_warm: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
4 | { "" "" "" "Vip.Reset_Source.reset_cold: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
5 | { "" "" "" "Vip.Video_Output.control: Interrupt sender control.av_mm_control_interrupt is not connected to an interrupt receiver" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
6 | { "" "" "" "Vip.Video_Output: Interrupt sender Video_Output.status_update_irq is not connected to an interrupt receiver" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
7 | { "" "" "" "Vip.: You have exported the interface HPS.f2h_sdram1_data but not its associated reset interface. Export the driver(s) of HPS.h2f_reset" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
8 | { "" "" "" "Vip.: You have exported the interface HPS.f2h_sdram2_data but not its associated reset interface. Export the driver(s) of HPS.h2f_reset" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""}
9 | { "" "" "" "Variable or input pin \"data_b\" is defined but never used." { } { } 0 287013 "" 0 0 "Design Software" 0 -1 0 ""}
10 | { "" "" "" "Variable or input pin \"data_a\" is defined but never used." { } { } 0 287013 "" 0 0 "Design Software" 0 -1 0 ""}
11 | { "" "" "" "Port \"extclk\" on the entity instantiation of \"cyclonev_pll\" is connected to a signal of width 1. The formal width of the signal in the module is 2. The extra bits will be left dangling without any fan-out logic." { } { } 0 12030 "" 0 0 "Design Software" 0 -1 0 ""}
12 | { "" "" "" "Port \"trs\" on the entity instantiation of \"statemachine\" is connected to a signal of width 2. The formal width of the signal in the module is 1. The extra bits will be ignored." { } { } 0 12020 "" 0 0 "Design Software" 0 -1 0 ""}
13 | { "" "" "" "Port \"reset_value\" on the entity instantiation of \"h_counter\" is connected to a signal of width 32. The formal width of the signal in the module is 16. The extra bits will be ignored." { } { } 0 12020 "" 0 0 "Design Software" 0 -1 0 ""}
14 | { "" "" "" "Overwriting existing clock: vip\|hps\|fpga_interfaces\|clocks_resets\|h2f_user0_clk" { } { } 0 332043 "" 0 0 "Design Software" 0 -1 0 ""}
15 | { "" "" "" "LOCKED port on the PLL is not properly connected on instance \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""}
16 | { "" "" "" "Vip.vip: Module dependency loop involving: \"HPS\"" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
17 | { "" "" "" "alt_vip_common_frame_counter.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
18 | { "" "" "" "alt_vip_cvo_mode_banks.sv" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
19 | { "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
20 | { "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
21 | { "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
22 | { "" "" "" "genlock_enable_sync" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
23 | { "" "" "" "u_calculate_mode" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
24 | { "" "" "" "mode_banks" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
25 | { "" "" "" "RST port on the PLL is not properly connected" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
26 | { "" "" "" "alt_vip_cvo_core.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
27 | { "" "" "" "alt_vip_packet_transfer.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
28 | { "" "" "" "alt_vip_common_dc_mixed_widths_fifo.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
29 | { "" "" "" "vip_HPS_fpga_interfaces.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""}
30 |
--------------------------------------------------------------------------------
/sys/video_mixer.sv:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2017 Sorgelig
4 | //
5 | // This program is GPL Licensed. See COPYING for the full license.
6 | //
7 | //
8 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
9 |
10 | `timescale 1ns / 1ps
11 |
12 | //
13 | // LINE_LENGTH: Length of display line in pixels
14 | // Usually it's length from HSync to HSync.
15 | // May be less if line_start is used.
16 | //
17 | // HALF_DEPTH: If =1 then color dept is 4 bits per component
18 | // For half depth 8 bits monochrome is available with
19 | // mono signal enabled and color = {G, R}
20 |
21 | module video_mixer
22 | #(
23 | parameter LINE_LENGTH = 768,
24 | parameter HALF_DEPTH = 0
25 | )
26 | (
27 | // master clock
28 | // it should be multiple by (ce_pix*4).
29 | input clk_sys,
30 |
31 | // Pixel clock or clock_enable (both are accepted).
32 | input ce_pix,
33 | output ce_pix_out,
34 |
35 | input scandoubler,
36 |
37 | // scanlines (00-none 01-25% 10-50% 11-75%)
38 | input [1:0] scanlines,
39 |
40 | // High quality 2x scaling
41 | input hq2x,
42 |
43 | // color
44 | input [DWIDTH:0] R,
45 | input [DWIDTH:0] G,
46 | input [DWIDTH:0] B,
47 |
48 | // Monochrome mode (for HALF_DEPTH only)
49 | input mono,
50 |
51 | // Positive pulses.
52 | input HSync,
53 | input VSync,
54 | input HBlank,
55 | input VBlank,
56 |
57 | // video output signals
58 | output reg [7:0] VGA_R,
59 | output reg [7:0] VGA_G,
60 | output reg [7:0] VGA_B,
61 | output reg VGA_VS,
62 | output reg VGA_HS,
63 | output reg VGA_DE
64 | );
65 |
66 | localparam DWIDTH = HALF_DEPTH ? 3 : 7;
67 |
68 | wire [DWIDTH:0] R_sd;
69 | wire [DWIDTH:0] G_sd;
70 | wire [DWIDTH:0] B_sd;
71 | wire hs_sd, vs_sd, hb_sd, vb_sd, ce_pix_sd;
72 |
73 | scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) sd
74 | (
75 | .*,
76 | .hs_in(HSync),
77 | .vs_in(VSync),
78 | .hb_in(HBlank),
79 | .vb_in(VBlank),
80 | .r_in(R),
81 | .g_in(G),
82 | .b_in(B),
83 |
84 | .ce_pix_out(ce_pix_sd),
85 | .hs_out(hs_sd),
86 | .vs_out(vs_sd),
87 | .hb_out(hb_sd),
88 | .vb_out(vb_sd),
89 | .r_out(R_sd),
90 | .g_out(G_sd),
91 | .b_out(B_sd)
92 | );
93 |
94 | wire [DWIDTH:0] rt = (scandoubler ? R_sd : R);
95 | wire [DWIDTH:0] gt = (scandoubler ? G_sd : G);
96 | wire [DWIDTH:0] bt = (scandoubler ? B_sd : B);
97 |
98 | generate
99 | if(HALF_DEPTH) begin
100 | wire [7:0] r = mono ? {gt,rt} : {rt,rt};
101 | wire [7:0] g = mono ? {gt,rt} : {gt,gt};
102 | wire [7:0] b = mono ? {gt,rt} : {bt,bt};
103 | end else begin
104 | wire [7:0] r = rt;
105 | wire [7:0] g = gt;
106 | wire [7:0] b = bt;
107 | end
108 | endgenerate
109 |
110 | wire hs = (scandoubler ? hs_sd : HSync);
111 | wire vs = (scandoubler ? vs_sd : VSync);
112 |
113 | assign ce_pix_out = scandoubler ? ce_pix_sd : ce_pix;
114 |
115 |
116 | reg scanline = 0;
117 | always @(posedge clk_sys) begin
118 | reg old_hs, old_vs;
119 |
120 | old_hs <= hs;
121 | old_vs <= vs;
122 |
123 | if(old_hs && ~hs) scanline <= ~scanline;
124 | if(old_vs && ~vs) scanline <= 0;
125 | end
126 |
127 | wire hde = scandoubler ? ~hb_sd : ~HBlank;
128 | wire vde = scandoubler ? ~vb_sd : ~VBlank;
129 |
130 | always @(posedge clk_sys) begin
131 | reg old_hde;
132 |
133 | case(scanlines & {scanline, scanline})
134 | 1: begin // reduce 25% = 1/2 + 1/4
135 | VGA_R <= {1'b0, r[7:1]} + {2'b00, r[7:2]};
136 | VGA_G <= {1'b0, g[7:1]} + {2'b00, g[7:2]};
137 | VGA_B <= {1'b0, b[7:1]} + {2'b00, b[7:2]};
138 | end
139 |
140 | 2: begin // reduce 50% = 1/2
141 | VGA_R <= {1'b0, r[7:1]};
142 | VGA_G <= {1'b0, g[7:1]};
143 | VGA_B <= {1'b0, b[7:1]};
144 | end
145 |
146 | 3: begin // reduce 75% = 1/4
147 | VGA_R <= {2'b00, r[7:2]};
148 | VGA_G <= {2'b00, g[7:2]};
149 | VGA_B <= {2'b00, b[7:2]};
150 | end
151 |
152 | default: begin
153 | VGA_R <= r;
154 | VGA_G <= g;
155 | VGA_B <= b;
156 | end
157 | endcase
158 |
159 | VGA_VS <= vs;
160 | VGA_HS <= hs;
161 |
162 | old_hde <= hde;
163 | if(~old_hde && hde) VGA_DE <= vde;
164 | if(old_hde && ~hde) VGA_DE <= 0;
165 | end
166 |
167 | endmodule
168 |
--------------------------------------------------------------------------------
/sys/pll_hdmi_cfg.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %Altera PLL Reconfig v17.1%
2 | // GENERATION: XML
3 | // pll_hdmi_cfg.v
4 |
5 | // Generated using ACDS version 17.1 590
6 |
7 | `timescale 1 ps / 1 ps
8 | module pll_hdmi_cfg #(
9 | parameter ENABLE_BYTEENABLE = 0,
10 | parameter BYTEENABLE_WIDTH = 4,
11 | parameter RECONFIG_ADDR_WIDTH = 6,
12 | parameter RECONFIG_DATA_WIDTH = 32,
13 | parameter reconf_width = 64,
14 | parameter WAIT_FOR_LOCK = 1
15 | ) (
16 | input wire mgmt_clk, // mgmt_clk.clk
17 | input wire mgmt_reset, // mgmt_reset.reset
18 | output wire mgmt_waitrequest, // mgmt_avalon_slave.waitrequest
19 | input wire mgmt_read, // .read
20 | input wire mgmt_write, // .write
21 | output wire [31:0] mgmt_readdata, // .readdata
22 | input wire [5:0] mgmt_address, // .address
23 | input wire [31:0] mgmt_writedata, // .writedata
24 | output wire [63:0] reconfig_to_pll, // reconfig_to_pll.reconfig_to_pll
25 | input wire [63:0] reconfig_from_pll // reconfig_from_pll.reconfig_from_pll
26 | );
27 |
28 | altera_pll_reconfig_top #(
29 | .device_family ("Cyclone V"),
30 | .ENABLE_MIF (0),
31 | .MIF_FILE_NAME ("sys/pll_hdmi_cfg.mif"),
32 | .ENABLE_BYTEENABLE (ENABLE_BYTEENABLE),
33 | .BYTEENABLE_WIDTH (BYTEENABLE_WIDTH),
34 | .RECONFIG_ADDR_WIDTH (RECONFIG_ADDR_WIDTH),
35 | .RECONFIG_DATA_WIDTH (RECONFIG_DATA_WIDTH),
36 | .reconf_width (reconf_width),
37 | .WAIT_FOR_LOCK (WAIT_FOR_LOCK)
38 | ) pll_hdmi_cfg_inst (
39 | .mgmt_clk (mgmt_clk), // mgmt_clk.clk
40 | .mgmt_reset (mgmt_reset), // mgmt_reset.reset
41 | .mgmt_waitrequest (mgmt_waitrequest), // mgmt_avalon_slave.waitrequest
42 | .mgmt_read (mgmt_read), // .read
43 | .mgmt_write (mgmt_write), // .write
44 | .mgmt_readdata (mgmt_readdata), // .readdata
45 | .mgmt_address (mgmt_address), // .address
46 | .mgmt_writedata (mgmt_writedata), // .writedata
47 | .reconfig_to_pll (reconfig_to_pll), // reconfig_to_pll.reconfig_to_pll
48 | .reconfig_from_pll (reconfig_from_pll), // reconfig_from_pll.reconfig_from_pll
49 | .mgmt_byteenable (4'b0000) // (terminated)
50 | );
51 |
52 | endmodule
53 | // Retrieval info:
54 | //
79 | // Retrieval info:
80 | // Retrieval info:
81 | // Retrieval info:
82 | // Retrieval info:
83 | // Retrieval info:
84 | // Retrieval info:
85 | // IPFS_FILES : pll_hdmi_cfg.vo
86 | // RELATED_FILES: pll_hdmi_cfg.v, altera_pll_reconfig_top.v, altera_pll_reconfig_core.v, altera_std_synchronizer.v
87 |
--------------------------------------------------------------------------------
/sys/scandoubler.v:
--------------------------------------------------------------------------------
1 | //
2 | // scandoubler.v
3 | //
4 | // Copyright (c) 2015 Till Harbaum
5 | // Copyright (c) 2017-2019 Sorgelig
6 | //
7 | // This source file is free software: you can redistribute it and/or modify
8 | // it under the terms of the GNU General Public License as published
9 | // by the Free Software Foundation, either version 3 of the License, or
10 | // (at your option) any later version.
11 | //
12 | // This source file is distributed in the hope that it will be useful,
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | // GNU General Public License for more details.
16 | //
17 | // You should have received a copy of the GNU General Public License
18 | // along with this program. If not, see .
19 |
20 | // TODO: Delay vsync one line
21 |
22 | module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
23 | (
24 | // system interface
25 | input clk_sys,
26 | input ce_pix,
27 | output ce_pix_out,
28 |
29 | input hq2x,
30 |
31 | // shifter video interface
32 | input hs_in,
33 | input vs_in,
34 | input hb_in,
35 | input vb_in,
36 |
37 | input [DWIDTH:0] r_in,
38 | input [DWIDTH:0] g_in,
39 | input [DWIDTH:0] b_in,
40 | input mono,
41 |
42 | // output interface
43 | output reg hs_out,
44 | output vs_out,
45 | output hb_out,
46 | output vb_out,
47 | output [DWIDTH:0] r_out,
48 | output [DWIDTH:0] g_out,
49 | output [DWIDTH:0] b_out
50 | );
51 |
52 |
53 | localparam DWIDTH = HALF_DEPTH ? 3 : 7;
54 |
55 | assign vs_out = vso[3];
56 | assign ce_pix_out = hq2x ? ce_x4 : ce_x2;
57 |
58 | //Compensate picture shift after HQ2x
59 | assign vb_out = vbo[3];
60 | assign hb_out = hbo[6];
61 |
62 | reg [7:0] pix_len = 0;
63 | reg [7:0] pix_cnt = 0;
64 | wire [7:0] pl = pix_len + 1'b1;
65 | wire [7:0] pc = pix_cnt + 1'b1;
66 |
67 | reg ce_x4, ce_x2, ce_x1;
68 | always @(negedge clk_sys) begin
69 | reg old_ce, valid, hs;
70 | reg [2:0] ce_cnt;
71 |
72 | reg [7:0] pixsz, pixsz2, pixsz4 = 0;
73 |
74 | if(~&pix_len) pix_len <= pl;
75 | if(~&pix_cnt) pix_cnt <= pc;
76 |
77 | ce_x4 <= 0;
78 | ce_x2 <= 0;
79 | ce_x1 <= 0;
80 |
81 | // use such odd comparison to place ce_x4 evenly if master clock isn't multiple of 4.
82 | if((pc == pixsz4) || (pc == pixsz2) || (pc == (pixsz2+pixsz4))) ce_x4 <= 1;
83 | if( pc == pixsz2) ce_x2 <= 1;
84 |
85 | old_ce <= ce_pix;
86 | if(~old_ce & ce_pix) begin
87 | if(valid & ~hb_in & ~vb_in) begin
88 | pixsz <= pl;
89 | pixsz2 <= {1'b0, pl[7:1]};
90 | pixsz4 <= {2'b00, pl[7:2]};
91 | end
92 | pix_len <= 0;
93 | valid <= 1;
94 | end
95 |
96 | if(hb_in | vb_in) valid <= 0;
97 |
98 | hs <= hs_out;
99 | if((~hs & hs_out) || (pc >= pixsz)) begin
100 | ce_x2 <= 1;
101 | ce_x4 <= 1;
102 | ce_x1 <= 1;
103 | pix_cnt <= 0;
104 | end
105 | end
106 |
107 | Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
108 | (
109 | .clk(clk_sys),
110 | .ce_x4(ce_x4),
111 | .inputpixel({b_d,g_d,r_d}),
112 | .mono(mono),
113 | .disable_hq2x(~hq2x),
114 | .reset_frame(vb_in),
115 | .reset_line(req_line_reset),
116 | .read_y(sd_line),
117 | .hblank(hbo[0]&hbo[8]),
118 | .outpixel({b_out,g_out,r_out})
119 | );
120 |
121 | reg [DWIDTH:0] r_d;
122 | reg [DWIDTH:0] g_d;
123 | reg [DWIDTH:0] b_d;
124 |
125 | reg [1:0] sd_line;
126 | reg [3:0] vbo;
127 | reg [3:0] vso;
128 | reg [8:0] hbo;
129 |
130 | reg req_line_reset;
131 | always @(posedge clk_sys) begin
132 |
133 | reg [31:0] hcnt;
134 | reg [30:0] sd_hcnt;
135 | reg [30:0] hs_start, hs_end;
136 | reg [30:0] hde_start, hde_end;
137 |
138 | reg hs, hb;
139 |
140 | if(ce_x4) begin
141 | hbo[8:1] <= hbo[7:0];
142 | end
143 |
144 | // output counter synchronous to input and at twice the rate
145 | sd_hcnt <= sd_hcnt + 1'd1;
146 | if(sd_hcnt == hde_start) begin
147 | sd_hcnt <= 0;
148 | vbo[3:1] <= vbo[2:0];
149 | end
150 |
151 | if(sd_hcnt == hs_end) begin
152 | sd_line <= sd_line + 1'd1;
153 | if(&vbo[3:2]) sd_line <= 1;
154 | vso[3:1] <= vso[2:0];
155 | end
156 |
157 | if(sd_hcnt == hde_start)hbo[0] <= 0;
158 | if(sd_hcnt == hde_end) hbo[0] <= 1;
159 |
160 | // replicate horizontal sync at twice the speed
161 | if(sd_hcnt == hs_end) hs_out <= 0;
162 | if(sd_hcnt == hs_start) hs_out <= 1;
163 |
164 | hs <= hs_in;
165 | hb <= hb_in;
166 |
167 | if(ce_x1) begin
168 | req_line_reset <= hb_in;
169 | r_d <= r_in;
170 | g_d <= g_in;
171 | b_d <= b_in;
172 | end
173 |
174 | hcnt <= hcnt + 1'd1;
175 | if(hb && !hb_in) begin
176 | hde_start <= hcnt[31:1];
177 | hbo[0] <= 0;
178 | hcnt <= 0;
179 | sd_hcnt <= 0;
180 | vbo <= {vbo[2:0],vb_in};
181 | end
182 |
183 | if(!hb && hb_in) hde_end <= hcnt[31:1];
184 |
185 | // falling edge of hsync indicates start of line
186 | if(hs && !hs_in) begin
187 | hs_end <= hcnt[31:1];
188 | vso[0] <= vs_in;
189 | end
190 |
191 | // save position of rising edge
192 | if(!hs && hs_in) hs_start <= hcnt[31:1];
193 | end
194 |
195 | endmodule
196 |
--------------------------------------------------------------------------------
/src/wsg.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // Wave-base Sound Generator (3ch)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module WSG_3CH
7 | (
8 | input CLK48M,
9 | input RESET,
10 |
11 | input CPUCLK,
12 | input [4:0] ADRS,
13 | input [3:0] DATA,
14 | input WR,
15 |
16 | output WROMCLK,
17 | output [7:0] WROMADR,
18 | input [3:0] WROMDAT,
19 |
20 | output PCMCLK,
21 | output [7:0] PCMOUT
22 | );
23 |
24 | wire WSGCLKx4;
25 | WSGCLKGEN cgen( CLK48M, WSGCLKx4 );
26 |
27 | wire [2:0] W0, W1, W2;
28 | wire [3:0] V0, V1, V2;
29 | wire [19:0] F0;
30 | wire [15:0] F1, F2;
31 |
32 | WSGREGS regs
33 | (
34 | RESET,
35 | CPUCLK, ADRS, WR, DATA,
36 |
37 | W0, W1, W2,
38 | V0, V1, V2,
39 | F0, F1, F2
40 | );
41 |
42 | WSGCORE core
43 | (
44 | RESET, WSGCLKx4,
45 | WROMCLK, WROMADR, WROMDAT,
46 |
47 | W0, W1, W2,
48 | V0, V1, V2,
49 | F0, F1, F2,
50 |
51 | PCMCLK, PCMOUT
52 | );
53 |
54 | endmodule
55 |
56 |
57 | module WSGREGS
58 | (
59 | input RESET,
60 | input CPUCLK,
61 | input [4:0] ADRS,
62 | input WR,
63 | input [3:0] DATA,
64 |
65 | output reg [2:0] W0,
66 | output reg [2:0] W1,
67 | output reg [2:0] W2,
68 |
69 | output reg [3:0] V0,
70 | output reg [3:0] V1,
71 | output reg [3:0] V2,
72 |
73 | output reg [19:0] F0,
74 | output reg [15:0] F1,
75 | output reg [15:0] F2
76 | );
77 |
78 | always @ ( posedge CPUCLK or posedge RESET ) begin
79 |
80 | if ( RESET ) begin
81 |
82 | W0 <= 0;
83 | W1 <= 0;
84 | W2 <= 0;
85 |
86 | F0 <= 0;
87 | F1 <= 0;
88 | F2 <= 0;
89 |
90 | V0 <= 0;
91 | V1 <= 0;
92 | V2 <= 0;
93 |
94 | end
95 | else begin
96 |
97 | if ( WR ) case ( ADRS )
98 |
99 | 5'h05: W0 <= DATA[2:0];
100 | 5'h0A: W1 <= DATA[2:0];
101 | 5'h0F: W2 <= DATA[2:0];
102 |
103 | 5'h15: V0 <= DATA;
104 | 5'h1A: V1 <= DATA;
105 | 5'h1F: V2 <= DATA;
106 |
107 | 5'h10: F0[3:0] <= DATA;
108 | 5'h11: F0[7:4] <= DATA;
109 | 5'h12: F0[11:8] <= DATA;
110 | 5'h13: F0[15:12] <= DATA;
111 | 5'h14: F0[19:16] <= DATA;
112 |
113 | 5'h16: F1[3:0] <= DATA;
114 | 5'h17: F1[7:4] <= DATA;
115 | 5'h18: F1[11:8] <= DATA;
116 | 5'h19: F1[15:12] <= DATA;
117 |
118 | 5'h1B: F2[3:0] <= DATA;
119 | 5'h1C: F2[7:4] <= DATA;
120 | 5'h1D: F2[11:8] <= DATA;
121 | 5'h1E: F2[15:12] <= DATA;
122 |
123 | default:;
124 |
125 | endcase
126 |
127 | end
128 |
129 | end
130 |
131 | endmodule
132 |
133 |
134 | module WSGCORE
135 | (
136 | input RESET,
137 | input WSGCLKx4,
138 |
139 | output WROMCLK,
140 | output [7:0] WROMADR,
141 | input [3:0] WROMDAT,
142 |
143 | input [2:0] W0,
144 | input [2:0] W1,
145 | input [2:0] W2,
146 |
147 | input [3:0] V0,
148 | input [3:0] V1,
149 | input [3:0] V2,
150 |
151 | input [19:0] F0,
152 | input [15:0] F1,
153 | input [15:0] F2,
154 |
155 | output reg outclk,
156 | output reg [7:0] sndout
157 | );
158 |
159 | reg [7:0] waveadr, cc1, cc2;
160 |
161 | reg [19:0] c0;
162 | reg [15:0] c1, c2;
163 |
164 | reg [3:0] wavevol;
165 | wire [7:0] waveout = wavevol * WROMDAT;
166 |
167 | reg [9:0] sndmix;
168 | wire [10:0] sndmixdown = { 1'b0, sndmix };
169 |
170 | reg [1:0] phase;
171 | always @ ( posedge WSGCLKx4 or posedge RESET ) begin
172 |
173 | if ( RESET ) begin
174 | phase <= 0;
175 | sndout <= 0;
176 | outclk <= 0;
177 | cc1 <= 0;
178 | cc2 <= 0;
179 | end
180 | else begin
181 |
182 | case ( phase )
183 |
184 | 0: begin
185 | sndout <= ( sndmixdown[9:2] | {8{sndmixdown[10]}} );
186 |
187 | cc1 <= {W1,c1[15:11]};
188 | cc2 <= {W2,c2[15:11]};
189 |
190 | sndmix <= 0;
191 | waveadr <= {W0,c0[19:15]};
192 | wavevol <= (F0!=0) ? V0 : 0;
193 | end
194 |
195 | 1: begin
196 | outclk <= 1'b1;
197 | sndmix <= sndmix + waveout;
198 |
199 | waveadr <= cc1;
200 | wavevol <= (F1!=0) ? V1 : 0;
201 | end
202 |
203 | 2: begin
204 | sndmix <= sndmix + waveout;
205 |
206 | waveadr <= cc2;
207 | wavevol <= (F2!=0) ? V2 : 0;
208 | end
209 |
210 | 3: begin
211 | outclk <= 0;
212 | sndmix <= sndmix + waveout;
213 | end
214 |
215 | default:;
216 |
217 | endcase
218 |
219 | phase <= phase+1;
220 |
221 | c0 <= c0 + F0;
222 | c1 <= c1 + F1;
223 | c2 <= c2 + F2;
224 |
225 | end
226 |
227 | end
228 |
229 | assign WROMCLK = ~WSGCLKx4;
230 | assign WROMADR = waveadr;
231 |
232 | endmodule
233 |
234 |
235 | /*
236 | Clock Generator
237 | in: 48000000Hz -> out: 96000Hz
238 | */
239 | module WSGCLKGEN( input in, output reg out );
240 | reg [7:0] count;
241 | always @( posedge in ) begin
242 | if (count > 8'd249) begin
243 | count <= count - 8'd249;
244 | out <= ~out;
245 | end
246 | else count <= count + 8'd1;
247 | end
248 | endmodule
249 |
250 |
--------------------------------------------------------------------------------
/src/DIGDUG_CORES.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // FPGA DigDug (CPU part)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module DIGDUG_CORES
7 | (
8 | input MCLK, // Clock (48.0MHz)
9 |
10 | input [2:0] RSTS, // RESET [2:0]
11 | input [2:0] IRQS, // IRQ [2:0]
12 | input [2:0] NMIS, // NMI [2:0]
13 |
14 | output DEV_CL, // I/O device Interface
15 | output [15:0] DEV_AD,
16 | output DEV_RD,
17 | input DEV_DV,
18 | input [7:0] DEV_DO,
19 | output DEV_WR,
20 | output [7:0] DEV_DI,
21 |
22 |
23 | input ROMCL, // Downloaded ROM image
24 | input [15:0] ROMAD,
25 | input [7:0] ROMDT,
26 | input ROMEN
27 | );
28 |
29 | //-----------------------------------------------
30 | // CPU0
31 | //-----------------------------------------------
32 | wire CPU0CL;
33 | wire [15:0] CPU0AD;
34 | wire CPU0RD;
35 | wire CPU0DV;
36 | wire [7:0] CPU0DI;
37 | wire CPU0WR;
38 | wire [7:0] CPU0DO;
39 |
40 | wire [7:0] CPU0IR;
41 | DLROM #(14,8) rom0( DEV_CL, CPU0AD[13:0], CPU0IR, ROMCL,ROMAD[13:0],ROMDT,ROMEN & (ROMAD[15:14]==2'b00) );
42 |
43 | wire NMI0;
44 | CPUNMIACK n0( RSTS[0], CPU0CL, CPU0AD, NMIS[0], NMI0 );
45 |
46 | CPUCORE cpu0 (
47 | .RESET(RSTS[0]),.CLK(CPU0CL),
48 | .IRQ(IRQS[0]),.NMI(NMI0),
49 | .AD(CPU0AD),.IR(CPU0IR),
50 | .RD(CPU0RD),.DV(CPU0DV),.DI(CPU0DI),
51 | .WR(CPU0WR),.DO(CPU0DO)
52 | );
53 |
54 |
55 | //-----------------------------------------------
56 | // CPU1
57 | //-----------------------------------------------
58 | wire CPU1CL;
59 | wire [15:0] CPU1AD;
60 | wire CPU1RD;
61 | wire CPU1DV;
62 | wire [7:0] CPU1DI;
63 | wire CPU1WR;
64 | wire [7:0] CPU1DO;
65 |
66 | wire [7:0] CPU1IR;
67 | DLROM #(13,8) rom1( DEV_CL, CPU1AD[12:0], CPU1IR, ROMCL,ROMAD[12:0],ROMDT,ROMEN & (ROMAD[15:13]==3'b100) );
68 |
69 | CPUCORE cpu1 (
70 | .RESET(RSTS[1]),.CLK(CPU1CL),
71 | .IRQ(IRQS[1]),.NMI(NMIS[1]),
72 | .AD(CPU1AD),.IR(CPU1IR),
73 | .RD(CPU1RD),.DV(CPU1DV),.DI(CPU1DI),
74 | .WR(CPU1WR),.DO(CPU1DO)
75 | );
76 |
77 |
78 | //-----------------------------------------------
79 | // CPU2
80 | //-----------------------------------------------
81 | wire CPU2CL;
82 | wire [15:0] CPU2AD;
83 | wire CPU2RD;
84 | wire CPU2DV;
85 | wire [7:0] CPU2DI;
86 | wire CPU2WR;
87 | wire [7:0] CPU2DO;
88 |
89 | wire [7:0] CPU2IR;
90 | DLROM #(12,8) rom2( DEV_CL, CPU2AD[11:0], CPU2IR, ROMCL,ROMAD[11:0],ROMDT,ROMEN & (ROMAD[15:12]==4'hA) );
91 |
92 | wire NMI2;
93 | CPUNMIACK n2( RSTS[2], CPU2CL, CPU2AD, NMIS[2], NMI2 );
94 |
95 | CPUCORE cpu2 (
96 | .RESET(RSTS[2]),.CLK(CPU2CL),
97 | .IRQ(IRQS[2]),.NMI(NMI2),
98 | .AD(CPU2AD),.IR(CPU2IR),
99 | .RD(CPU2RD),.DV(CPU2DV),.DI(CPU2DI),
100 | .WR(CPU2WR),.DO(CPU2DO)
101 | );
102 |
103 |
104 | //-----------------------------------------------
105 | // CPU Access Arbiter
106 | //-----------------------------------------------
107 | CPUARB arb
108 | (
109 | MCLK,
110 | DEV_CL, DEV_AD, DEV_RD, DEV_DV, DEV_DO, DEV_WR, DEV_DI,
111 | CPU0CL, CPU0AD, CPU0RD, CPU0DV, CPU0DI, CPU0WR, CPU0DO,
112 | CPU1CL, CPU1AD, CPU1RD, CPU1DV, CPU1DI, CPU1WR, CPU1DO,
113 | CPU2CL, CPU2AD, CPU2RD, CPU2DV, CPU2DI, CPU2WR, CPU2DO
114 | );
115 |
116 | endmodule
117 |
118 |
119 | module CPUARB
120 | (
121 | input CLK48M,
122 |
123 | output DEV_CL,
124 | output [15:0] DEV_AD,
125 | output DEV_RD,
126 | input DEV_DV,
127 | input [7:0] DEV_DO,
128 | output DEV_WR,
129 | output [7:0] DEV_DI,
130 |
131 | output CPU0CL,
132 | input [15:0] CPU0AD,
133 | input CPU0RD,
134 | output CPU0DV,
135 | output [7:0] CPU0DI,
136 | input CPU0WR,
137 | input [7:0] CPU0DO,
138 |
139 | output CPU1CL,
140 | input [15:0] CPU1AD,
141 | input CPU1RD,
142 | output CPU1DV,
143 | output [7:0] CPU1DI,
144 | input CPU1WR,
145 | input [7:0] CPU1DO,
146 |
147 | output CPU2CL,
148 | input [15:0] CPU2AD,
149 | input CPU2RD,
150 | output CPU2DV,
151 | output [7:0] CPU2DI,
152 | input CPU2WR,
153 | input [7:0] CPU2DO
154 | );
155 |
156 | reg [1:0] clkdiv;
157 | always @( posedge CLK48M ) clkdiv <= clkdiv+1;
158 | wire CLK24M = clkdiv[0];
159 | wire CLK12M = clkdiv[1];
160 |
161 | reg [3:0] CLKS = 4'b1000;
162 | reg [3:0] BUSS = 4'b0001;
163 | always @( posedge CLK12M ) CLKS <= {CLKS[2:0],CLKS[3]};
164 | always @( negedge CLK12M ) BUSS <= {BUSS[2:0],BUSS[3]};
165 |
166 | assign CPU0CL = CLKS[0];
167 | assign CPU1CL = CLKS[1];
168 | assign CPU2CL = CLKS[2];
169 |
170 | assign DEV_CL = CLK24M;
171 |
172 | assign DEV_AD = BUSS[0] ? CPU0AD :
173 | BUSS[1] ? CPU1AD :
174 | BUSS[2] ? CPU2AD : 0;
175 |
176 | assign DEV_RD = BUSS[0] ? CPU0RD :
177 | BUSS[1] ? CPU1RD :
178 | BUSS[2] ? CPU2RD : 0;
179 |
180 | assign CPU0DV = BUSS[0] ? DEV_DV : 0;
181 | assign CPU1DV = BUSS[1] ? DEV_DV : 0;
182 | assign CPU2DV = BUSS[2] ? DEV_DV : 0;
183 |
184 | assign CPU0DI = BUSS[0] ? DEV_DO : 0;
185 | assign CPU1DI = BUSS[1] ? DEV_DO : 0;
186 | assign CPU2DI = BUSS[2] ? DEV_DO : 0;
187 |
188 | assign DEV_WR = BUSS[0] ? CPU0WR :
189 | BUSS[1] ? CPU1WR :
190 | BUSS[2] ? CPU2WR : 0;
191 |
192 | assign DEV_DI = BUSS[0] ? CPU0DO :
193 | BUSS[1] ? CPU1DO :
194 | BUSS[2] ? CPU2DO : 0;
195 |
196 | endmodule
197 |
198 |
--------------------------------------------------------------------------------
/sys/osd.v:
--------------------------------------------------------------------------------
1 | // A simple OSD implementation. Can be hooked up between a cores
2 | // VGA output and the physical VGA pins
3 |
4 | module osd
5 | (
6 | input clk_sys,
7 |
8 | input io_osd,
9 | input io_strobe,
10 | input [15:0] io_din,
11 |
12 | input clk_video,
13 | input [23:0] din,
14 | output [23:0] dout,
15 | input de_in,
16 | output reg de_out,
17 | output reg osd_status
18 | );
19 |
20 | parameter OSD_COLOR = 3'd4;
21 | parameter OSD_X_OFFSET = 12'd0;
22 | parameter OSD_Y_OFFSET = 12'd0;
23 |
24 | localparam OSD_WIDTH = 12'd256;
25 | localparam OSD_HEIGHT = 12'd64;
26 |
27 | reg osd_enable;
28 | reg [7:0] osd_buffer[4096];
29 |
30 | reg info = 0;
31 | reg [8:0] infoh;
32 | reg [8:0] infow;
33 | reg [11:0] infox;
34 | reg [21:0] infoy;
35 | reg [21:0] hrheight;
36 |
37 | always@(posedge clk_sys) begin
38 | reg [11:0] bcnt;
39 | reg [7:0] cmd;
40 | reg has_cmd;
41 | reg old_strobe;
42 | reg highres = 0;
43 |
44 | hrheight <= info ? infoh : (OSD_HEIGHT<> 9) > 1) ? (((cnt+1'b1) >> 9) - 1) : 0;
104 | pixcnt <= 0;
105 | end
106 | end
107 |
108 | reg [2:0] osd_de;
109 | reg osd_pixel;
110 |
111 | always @(posedge clk_video) begin
112 | reg deD;
113 | reg [1:0] osd_div;
114 | reg [1:0] multiscan;
115 | reg [7:0] osd_byte;
116 | reg [23:0] h_cnt;
117 | reg [21:0] v_cnt;
118 | reg [21:0] dsp_width;
119 | reg [21:0] osd_vcnt;
120 | reg [21:0] h_osd_start;
121 | reg [21:0] v_osd_start;
122 | reg [21:0] osd_hcnt;
123 | reg osd_de1,osd_de2;
124 | reg [1:0] osd_en;
125 |
126 | if(ce_pix) begin
127 |
128 | deD <= de_in;
129 | if(~&h_cnt) h_cnt <= h_cnt + 1'd1;
130 |
131 | if(~&osd_hcnt) osd_hcnt <= osd_hcnt + 1'd1;
132 | if (h_cnt == h_osd_start) begin
133 | osd_de[0] <= osd_en[1] && hrheight && (osd_vcnt < hrheight);
134 | osd_hcnt <= 0;
135 | end
136 | if (osd_hcnt+1 == (info ? infow : OSD_WIDTH)) osd_de[0] <= 0;
137 |
138 | // falling edge of de
139 | if(!de_in && deD) dsp_width <= h_cnt[21:0];
140 |
141 | // rising edge of de
142 | if(de_in && !deD) begin
143 | h_cnt <= 0;
144 | v_cnt <= v_cnt + 1'd1;
145 | h_osd_start <= info ? infox : (((dsp_width - OSD_WIDTH)>>1) + OSD_X_OFFSET - 2'd2);
146 |
147 | if(h_cnt > {dsp_width, 2'b00}) begin
148 | v_cnt <= 0;
149 |
150 | osd_en <= (osd_en << 1) | osd_enable;
151 | if(~osd_enable) osd_en <= 0;
152 |
153 | if(v_cnt<320) begin
154 | multiscan <= 0;
155 | v_osd_start <= info ? infoy : (((v_cnt-hrheight)>>1) + OSD_Y_OFFSET);
156 | end
157 | else if(v_cnt<640) begin
158 | multiscan <= 1;
159 | v_osd_start <= info ? (infoy<<1) : (((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET);
160 | end
161 | else if(v_cnt<960) begin
162 | multiscan <= 2;
163 | v_osd_start <= info ? (infoy + (infoy << 1)) : (((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET);
164 | end
165 | else begin
166 | multiscan <= 3;
167 | v_osd_start <= info ? (infoy<<2) : (((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET);
168 | end
169 | end
170 |
171 | osd_div <= osd_div + 1'd1;
172 | if(osd_div == multiscan) begin
173 | osd_div <= 0;
174 | if(~&osd_vcnt) osd_vcnt <= osd_vcnt + 1'd1;
175 | end
176 | if(v_osd_start == (v_cnt+1'b1)) {osd_div, osd_vcnt} <= 0;
177 | end
178 |
179 | osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}];
180 | osd_pixel <= osd_byte[osd_vcnt[2:0]];
181 | osd_de[2:1] <= osd_de[1:0];
182 | end
183 | end
184 |
185 | reg [23:0] rdout;
186 | assign dout = rdout;
187 |
188 | always @(posedge clk_video) begin
189 | rdout <= ~osd_de[2] ? din : {{osd_pixel, osd_pixel, OSD_COLOR[2], din[23:19]},
190 | {osd_pixel, osd_pixel, OSD_COLOR[1], din[15:11]},
191 | {osd_pixel, osd_pixel, OSD_COLOR[0], din[7:3]}};
192 | de_out <= de_in;
193 | end
194 |
195 | endmodule
196 |
--------------------------------------------------------------------------------
/src/cpu/tv80s.v:
--------------------------------------------------------------------------------
1 | //
2 | // TV80 8-Bit Microprocessor Core
3 | // Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
4 | //
5 | // Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a
8 | // copy of this software and associated documentation files (the "Software"),
9 | // to deal in the Software without restriction, including without limitation
10 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | // and/or sell copies of the Software, and to permit persons to whom the
12 | // Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included
15 | // in all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | //`define TV80_REFRESH
26 |
27 | module tv80s (/*AUTOARG*/
28 | // Outputs
29 | m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do,
30 | // Inputs
31 | reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
32 | );
33 |
34 | parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
35 | parameter T2Write = 1; // 0 => wr_n active in T3, /=0 => wr_n active in T2
36 | parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
37 |
38 |
39 | input reset_n;
40 | input clk;
41 | input wait_n;
42 | input int_n;
43 | input nmi_n;
44 | input busrq_n;
45 | output m1_n;
46 | output mreq_n;
47 | output iorq_n;
48 | output rd_n;
49 | output wr_n;
50 | output rfsh_n;
51 | output halt_n;
52 | output busak_n;
53 | output [15:0] A;
54 | input [7:0] di;
55 | output [7:0] do;
56 |
57 | reg mreq_n;
58 | reg iorq_n;
59 | reg rd_n;
60 | reg wr_n;
61 |
62 | wire cen;
63 | wire intcycle_n;
64 | wire no_read;
65 | wire write;
66 | wire iorq;
67 | reg [7:0] di_reg;
68 | wire [6:0] mcycle;
69 | wire [6:0] tstate;
70 |
71 | assign cen = 1;
72 |
73 | tv80_core #(Mode, IOWait) i_tv80_core
74 | (
75 | .cen (cen),
76 | .m1_n (m1_n),
77 | .iorq (iorq),
78 | .no_read (no_read),
79 | .write (write),
80 | .rfsh_n (rfsh_n),
81 | .halt_n (halt_n),
82 | .wait_n (wait_n),
83 | .int_n (int_n),
84 | .nmi_n (nmi_n),
85 | .reset_n (reset_n),
86 | .busrq_n (busrq_n),
87 | .busak_n (busak_n),
88 | .clk (clk),
89 | .IntE (),
90 | .stop (),
91 | .A (A),
92 | .dinst (di),
93 | .di (di_reg),
94 | .do (do),
95 | .mc (mcycle),
96 | .ts (tstate),
97 | .intcycle_n (intcycle_n)
98 | );
99 |
100 | always @(posedge clk)
101 | begin
102 | if (!reset_n)
103 | begin
104 | rd_n <= #1 1'b1;
105 | wr_n <= #1 1'b1;
106 | iorq_n <= #1 1'b1;
107 | mreq_n <= #1 1'b1;
108 | di_reg <= #1 0;
109 | end
110 | else
111 | begin
112 | rd_n <= #1 1'b1;
113 | wr_n <= #1 1'b1;
114 | iorq_n <= #1 1'b1;
115 | mreq_n <= #1 1'b1;
116 | if (mcycle[0])
117 | begin
118 | if (tstate[1] || (tstate[2] && wait_n == 1'b0))
119 | begin
120 | rd_n <= #1 ~ intcycle_n;
121 | mreq_n <= #1 ~ intcycle_n;
122 | iorq_n <= #1 intcycle_n;
123 | end
124 | `ifdef TV80_REFRESH
125 | if (tstate[3])
126 | mreq_n <= #1 1'b0;
127 | `endif
128 | end // if (mcycle[0])
129 | else
130 | begin
131 | if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0)
132 | begin
133 | rd_n <= #1 1'b0;
134 | iorq_n <= #1 ~ iorq;
135 | mreq_n <= #1 iorq;
136 | end
137 | if (T2Write == 0)
138 | begin
139 | if (tstate[2] && write == 1'b1)
140 | begin
141 | wr_n <= #1 1'b0;
142 | iorq_n <= #1 ~ iorq;
143 | mreq_n <= #1 iorq;
144 | end
145 | end
146 | else
147 | begin
148 | if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1)
149 | begin
150 | wr_n <= #1 1'b0;
151 | iorq_n <= #1 ~ iorq;
152 | mreq_n <= #1 iorq;
153 | end
154 | end // else: !if(T2write == 0)
155 |
156 | end // else: !if(mcycle[0])
157 |
158 | if (tstate[2] && wait_n == 1'b1)
159 | di_reg <= #1 di;
160 | end // else: !if(!reset_n)
161 | end // always @ (posedge clk or negedge reset_n)
162 |
163 | endmodule // t80s
164 |
165 |
--------------------------------------------------------------------------------
/src/DIGDUG_IODEV.v:
--------------------------------------------------------------------------------
1 | //--------------------------------------------
2 | // FPGA DigDug (I/O device part)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //--------------------------------------------
6 | module DIGDUG_IODEV
7 | (
8 | input RESET,
9 |
10 | input [7:0] INP0,
11 | input [7:0] INP1,
12 | input [7:0] DSW0,
13 | input [7:0] DSW1,
14 |
15 | input VBLK, // V-BLANK
16 |
17 | input CL, // CPU Interface
18 | input [15:0] AD,
19 | input WR,
20 | input [7:0] DI,
21 | input RD,
22 | output DV,
23 | output [7:0] DO,
24 |
25 | output [2:0] RSTS, // CPU Reset Ctrl & Interrupt
26 | output [2:0] IRQS,
27 | output [2:0] NMIS,
28 |
29 | input CLK48M,
30 | output PCMCLK,
31 | output [7:0] PCMOUT,
32 |
33 | output WAVECL, // Wave ROM
34 | output [7:0] WAVEAD,
35 | input [3:0] WAVEDT,
36 |
37 | input FGSCCL, // FG VRAM
38 | input [9:0] FGSCAD,
39 | output [7:0] FGSCDT,
40 |
41 | input SPATCL, // SP ARAM
42 | input [6:0] SPATAD,
43 | output [23:0] SPATDT,
44 |
45 | output [1:0] BG_SELECT, // Video Ctrl.
46 | output [1:0] BG_COLBNK,
47 | output BG_CUTOFF,
48 | output FG_CLMODE
49 |
50 | );
51 |
52 | // Work & Video Memory
53 | wire CSM0 = (AD[15:11] == 5'b1000_0); // $8000-$87FF
54 | wire CSM1 = (AD[15:11] == 5'b1000_1); // $8800-$8FFF
55 | wire CSM2 = (AD[15:11] == 5'b1001_0); // $9000-$97FF
56 | wire CSM3 = (AD[15:11] == 5'b1001_1); // $9800-$9FFF
57 |
58 | wire [10:0] MAD = AD[10:0];
59 | wire [7:0] DOM0, DOM1, DOM2, DOM3;
60 | DPR2KV ram0( CL, MAD, CSM0, WR, DI, DOM0, FGSCCL, {1'b0,FGSCAD}, FGSCDT ); // (FGTX) $8000-$8300
61 | DPR2KV ram1( CL, MAD, CSM1, WR, DI, DOM1, SPATCL, {4'h7,SPATAD}, SPATDT[ 7: 0] ); // (SPA0) $8B80-$8BFF
62 | DPR2KV ram2( CL, MAD, CSM2, WR, DI, DOM2, SPATCL, {4'h7,SPATAD}, SPATDT[15: 8] ); // (SPA1) $9380-$93FF
63 | DPR2KV ram3( CL, MAD, CSM3, WR, DI, DOM3, SPATCL, {4'h7,SPATAD}, SPATDT[23:16] ); // (SPA2) $9B80-$9BFF
64 |
65 |
66 | // NAMCO WSG
67 | wire WSGWR =( AD[15:5] == 11'b0110_1000_000 ) & WR; // $6800-$681F
68 | WSG_3CH wsg( CLK48M, RESET, CL, AD[4:0], DI[3:0], WSGWR, WAVECL, WAVEAD, WAVEDT, PCMCLK, PCMOUT );
69 |
70 |
71 | // NAMCO Custom I/O Chip
72 | wire CSCUSIO = (AD[15:9] == 7'b0111_000); // $70xx-$71xx
73 | wire [7:0] DOCUSIO;
74 | wire NMI0;
75 | DIGDUG_CUSIO cusio( RESET, VBLK, INP0, INP1, DSW0, DSW1, CL, CSCUSIO, WR, {AD[8],AD[3:0]}, DI, DOCUSIO, NMI0 );
76 |
77 |
78 | // Video Ctrl Latches
79 | wire VLWR = (AD[15:3] == 13'b1010_0000_0000_0) & WR; // $A000-$A007
80 | DIGDUG_VLATCH vlats( RESET, CL, AD[2:0], VLWR, DI[0], BG_SELECT, BG_COLBNK, BG_CUTOFF, FG_CLMODE );
81 |
82 |
83 | // CPU Ctrl Latches
84 | wire CLWR = (AD[15:3] == 13'b0110_1000_0010_0) & WR; // $6820-$6827
85 | wire NMI2;
86 | DIGDUG_CLATCH clats( RESET, CL, AD[2:0], CLWR, DI[0], VBLK, RSTS, IRQS, NMI2 );
87 |
88 |
89 | // To CPU
90 | assign DV = CSM0|CSM1|CSM2|CSM3|CSCUSIO;
91 | assign DO = CSM0 ? DOM0 : CSM1 ? DOM1 : CSM2 ? DOM2 : CSM3 ? DOM3 : CSCUSIO ? DOCUSIO : 8'hFF;
92 | assign NMIS = {NMI2,1'b0,NMI0};
93 |
94 | endmodule
95 |
96 |
97 | module DIGDUG_VLATCH
98 | (
99 | input RESET,
100 | input CL,
101 | input [2:0] AD,
102 | input WR,
103 | input DI,
104 |
105 | output reg [1:0] BG_SELECT,
106 | output reg [1:0] BG_COLBNK,
107 | output reg BG_CUTOFF,
108 | output reg FG_CLMODE
109 | );
110 |
111 | always @( posedge CL or posedge RESET ) begin
112 | if (RESET) begin
113 | BG_SELECT <= 2'b00;
114 | BG_COLBNK <= 2'b00;
115 | BG_CUTOFF <= 1'b0;
116 | FG_CLMODE <= 1'b0;
117 | end
118 | else begin
119 | if (WR) case(AD)
120 | 3'h0: BG_SELECT[0] <= DI;
121 | 3'h1: BG_SELECT[1] <= DI;
122 | 3'h2: FG_CLMODE <= DI;
123 | 3'h3: BG_CUTOFF <= DI;
124 | 3'h4: BG_COLBNK[0] <= DI;
125 | 3'h5: BG_COLBNK[1] <= DI;
126 | default:;
127 | endcase
128 | end
129 | end
130 |
131 | endmodule
132 |
133 |
134 | module DIGDUG_CLATCH
135 | (
136 | input RESET,
137 | input CL, // 24MHz
138 | input [2:0] AD,
139 | input WR,
140 | input DI,
141 |
142 | input VBLK,
143 | output [2:0] RSTS,
144 | output [2:0] IRQS,
145 | output NMI2
146 | );
147 |
148 | // OSC 120Hz
149 | `define H120FLOW (12500)
150 | reg [3:0] clkdiv;
151 | always @( posedge CL ) clkdiv <= clkdiv+1;
152 | reg [13:0] H120CNT;
153 | always @( posedge clkdiv[3] or posedge RESET ) begin
154 | if (RESET) H120CNT <= 0;
155 | else H120CNT <= (H120CNT==`H120FLOW) ? 0 : (H120CNT+1);
156 | end
157 | wire H120 = ( H120CNT >= (`H120FLOW-200) ) ? 1'b1 : 0;
158 |
159 |
160 | reg IRQ0EN, IRQ0LC;
161 | reg IRQ1EN, IRQ1LC;
162 | reg NMI2EN, NMI2LC;
163 | reg NMI0LC;
164 |
165 | reg C12RST = 1'b1;
166 | reg pH120;
167 |
168 | always @( posedge CL or posedge RESET ) begin
169 | if (RESET) begin
170 | IRQ0EN <= 1'b0; IRQ0LC <= 1'b0;
171 | IRQ1EN <= 1'b0; IRQ1LC <= 1'b0;
172 | NMI2EN <= 1'b0; NMI2LC <= 1'b0;
173 | C12RST <= 1'b1; NMI0LC <= 1'b0;
174 | pH120 <= 1'b0;
175 | end
176 | else begin
177 | if (WR) begin
178 | case(AD)
179 | 3'h0: begin IRQ0EN <= DI; if (~DI) IRQ0LC <= 1'b0; end
180 | 3'h1: begin IRQ1EN <= DI; if (~DI) IRQ1LC <= 1'b0; end
181 | 3'h2: begin NMI2EN <=~DI; if ( DI) NMI2LC <= 1'b0; end
182 | 3'h3: C12RST <= ~DI;
183 | default:;
184 | endcase
185 | end
186 | if (VBLK) begin IRQ0LC <= 1'b1; IRQ1LC <= 1'b1; end
187 | if ((pH120^H120)&H120) NMI2LC <= 1'b1;
188 | pH120 <= H120;
189 | end
190 | end
191 |
192 | assign RSTS = {{2{C12RST}},RESET};
193 | assign IRQS = {1'b0,(IRQ1EN & IRQ1LC),(IRQ0EN & IRQ0LC)};
194 | assign NMI2 = (NMI2EN & NMI2LC);
195 |
196 | endmodule
197 |
198 |
--------------------------------------------------------------------------------
/sys/pll_hdmi_cfg.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig"
2 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.1"
3 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim"
4 | set_global_assignment -library "pll_hdmi_cfg" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.cmp"]
5 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V"
6 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}"
7 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_QSYS_MODE "UNKNOWN"
8 | set_global_assignment -name SYNTHESIS_ONLY_QIP ON
9 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "cGxsX2hkbWlfY2Zn"
10 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw=="
11 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
12 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off"
13 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u"
14 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMQ=="
15 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ=="
16 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA=="
17 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA=="
18 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA=="
19 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA=="
20 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo"
21 | set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw=="
22 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "YWx0ZXJhX3BsbF9yZWNvbmZpZ190b3A="
23 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw=="
24 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off"
25 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off"
26 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u"
27 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMQ=="
28 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ=="
29 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "ZGV2aWNlX2ZhbWlseQ==::Q3ljbG9uZSBW::ZGV2aWNlX2ZhbWlseQ=="
30 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX01JRg==::ZmFsc2U=::RW5hYmxlIE1JRiBTdHJlYW1pbmc="
31 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA=="
32 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA=="
33 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA=="
34 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA=="
35 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo"
36 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw=="
37 |
38 | set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.v"]
39 | set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_top.v"]
40 | set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_core.v"]
41 | set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_std_synchronizer.v"]
42 |
43 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig"
44 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.1"
45 | set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim"
46 |
--------------------------------------------------------------------------------
/sys/pll_hdmi_cfg/altera_std_synchronizer.v:
--------------------------------------------------------------------------------
1 | // (C) 2001-2017 Intel Corporation. All rights reserved.
2 | // Your use of Intel Corporation's design tools, logic functions and other
3 | // software and tools, and its AMPP partner logic functions, and any output
4 | // files from any of the foregoing (including device programming or simulation
5 | // files), and any associated documentation or information are expressly subject
6 | // to the terms and conditions of the Intel Program License Subscription
7 | // Agreement, Intel FPGA IP License Agreement, or other applicable
8 | // license agreement, including, without limitation, that your use is for the
9 | // sole purpose of programming logic devices manufactured by Intel and sold by
10 | // Intel or its authorized distributors. Please refer to the applicable
11 | // agreement for further details.
12 |
13 |
14 | // $Id: //acds/rel/17.1std/ip/sopc/components/primitives/altera_std_synchronizer/altera_std_synchronizer.v#1 $
15 | // $Revision: #1 $
16 | // $Date: 2017/07/30 $
17 | // $Author: swbranch $
18 | //-----------------------------------------------------------------------------
19 | //
20 | // File: altera_std_synchronizer.v
21 | //
22 | // Abstract: Single bit clock domain crossing synchronizer.
23 | // Composed of two or more flip flops connected in series.
24 | // Random metastable condition is simulated when the
25 | // __ALTERA_STD__METASTABLE_SIM macro is defined.
26 | // Use +define+__ALTERA_STD__METASTABLE_SIM argument
27 | // on the Verilog simulator compiler command line to
28 | // enable this mode. In addition, dfine the macro
29 | // __ALTERA_STD__METASTABLE_SIM_VERBOSE to get console output
30 | // with every metastable event generated in the synchronizer.
31 | //
32 | // Copyright (C) Altera Corporation 2009, All Rights Reserved
33 | //-----------------------------------------------------------------------------
34 |
35 | `timescale 1ns / 1ns
36 |
37 | module altera_std_synchronizer (
38 | clk,
39 | reset_n,
40 | din,
41 | dout
42 | );
43 |
44 | parameter depth = 3; // This value must be >= 2 !
45 |
46 | input clk;
47 | input reset_n;
48 | input din;
49 | output dout;
50 |
51 | // QuartusII synthesis directives:
52 | // 1. Preserve all registers ie. do not touch them.
53 | // 2. Do not merge other flip-flops with synchronizer flip-flops.
54 | // QuartusII TimeQuest directives:
55 | // 1. Identify all flip-flops in this module as members of the synchronizer
56 | // to enable automatic metastability MTBF analysis.
57 | // 2. Cut all timing paths terminating on data input pin of the first flop din_s1.
58 |
59 | (* altera_attribute = {"-name ADV_NETLIST_OPT_ALLOWED NEVER_ALLOW; -name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON; -name SDC_STATEMENT \"set_false_path -to [get_keepers {*altera_std_synchronizer:*|din_s1}]\" "} *) reg din_s1;
60 |
61 | (* altera_attribute = {"-name ADV_NETLIST_OPT_ALLOWED NEVER_ALLOW; -name SYNCHRONIZER_IDENTIFICATION FORCED_IF_ASYNCHRONOUS; -name DONT_MERGE_REGISTER ON; -name PRESERVE_REGISTER ON"} *) reg [depth-2:0] dreg;
62 |
63 | //synthesis translate_off
64 | initial begin
65 | if (depth <2) begin
66 | $display("%m: Error: synchronizer length: %0d less than 2.", depth);
67 | end
68 | end
69 |
70 | // the first synchronizer register is either a simple D flop for synthesis
71 | // and non-metastable simulation or a D flop with a method to inject random
72 | // metastable events resulting in random delay of [0,1] cycles
73 |
74 | `ifdef __ALTERA_STD__METASTABLE_SIM
75 |
76 | reg[31:0] RANDOM_SEED = 123456;
77 | wire next_din_s1;
78 | wire dout;
79 | reg din_last;
80 | reg random;
81 | event metastable_event; // hook for debug monitoring
82 |
83 | initial begin
84 | $display("%m: Info: Metastable event injection simulation mode enabled");
85 | end
86 |
87 | always @(posedge clk) begin
88 | if (reset_n == 0)
89 | random <= $random(RANDOM_SEED);
90 | else
91 | random <= $random;
92 | end
93 |
94 | assign next_din_s1 = (din_last ^ din) ? random : din;
95 |
96 | always @(posedge clk or negedge reset_n) begin
97 | if (reset_n == 0)
98 | din_last <= 1'b0;
99 | else
100 | din_last <= din;
101 | end
102 |
103 | always @(posedge clk or negedge reset_n) begin
104 | if (reset_n == 0)
105 | din_s1 <= 1'b0;
106 | else
107 | din_s1 <= next_din_s1;
108 | end
109 |
110 | `else
111 |
112 | //synthesis translate_on
113 | always @(posedge clk or negedge reset_n) begin
114 | if (reset_n == 0)
115 | din_s1 <= 1'b0;
116 | else
117 | din_s1 <= din;
118 | end
119 | //synthesis translate_off
120 |
121 | `endif
122 |
123 | `ifdef __ALTERA_STD__METASTABLE_SIM_VERBOSE
124 | always @(*) begin
125 | if (reset_n && (din_last != din) && (random != din)) begin
126 | $display("%m: Verbose Info: metastable event @ time %t", $time);
127 | ->metastable_event;
128 | end
129 | end
130 | `endif
131 |
132 | //synthesis translate_on
133 |
134 | // the remaining synchronizer registers form a simple shift register
135 | // of length depth-1
136 | generate
137 | if (depth < 3) begin
138 | always @(posedge clk or negedge reset_n) begin
139 | if (reset_n == 0)
140 | dreg <= {depth-1{1'b0}};
141 | else
142 | dreg <= din_s1;
143 | end
144 | end else begin
145 | always @(posedge clk or negedge reset_n) begin
146 | if (reset_n == 0)
147 | dreg <= {depth-1{1'b0}};
148 | else
149 | dreg <= {dreg[depth-3:0], din_s1};
150 | end
151 | end
152 | endgenerate
153 |
154 | assign dout = dreg[depth-2];
155 |
156 | endmodule
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/src/DIGDUG_CUSIO.v:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------
2 | // FPGA DigDug (Custom I/O chip emulation part)
3 | //
4 | // Copyright (c) 2017 MiSTer-X
5 | //-----------------------------------------------
6 | module DIGDUG_CUSIO
7 | (
8 | input RESET,
9 | input VBLK,
10 |
11 | input [7:0] INP0,
12 | input [7:0] INP1,
13 | input [7:0] DSW0,
14 | input [7:0] DSW1,
15 |
16 | input CL,
17 | input CS,
18 | input WR,
19 | input [4:0] AD,
20 | input [7:0] DI,
21 | output [7:0] DO,
22 | output NMI0
23 | );
24 |
25 | reg MODE;
26 | reg [7:0] COMMAND;
27 |
28 | reg [3:0] r2, r3, r4, r5;
29 | reg [3:0] LCINPCRE, LCREPCIN, LCOINS;
30 | reg [3:0] RCINPCRE, RCREPCIN, RCOINS;
31 | reg CREDITAT;
32 | reg [7:0] CREDITS;
33 |
34 | reg [11:0] CLK50uc;
35 | reg CLK50u;
36 |
37 | always @( posedge CL ) begin
38 | if (RESET) begin
39 | CLK50u <= 0;
40 | CLK50uc <= 0;
41 | end
42 | else begin
43 | if ( CLK50uc == 2200 ) CLK50u <= 1'b1;
44 | if ( CLK50uc == 2400 ) begin
45 | CLK50u <= 1'b0;
46 | CLK50uc <= 0;
47 | end
48 | else CLK50uc <= CLK50uc + 1;
49 | end
50 | end
51 |
52 | reg NMI0EN = 1'b0;
53 | assign NMI0 = NMI0EN & CLK50u;
54 |
55 | always @( posedge CL or posedge RESET ) begin
56 | if (RESET) begin
57 | NMI0EN <= 0;
58 | MODE <= 0;
59 | COMMAND <= 0;
60 |
61 | LCINPCRE <= 0;
62 | LCREPCIN <= 0;
63 | RCINPCRE <= 0;
64 | RCREPCIN <= 0;
65 | CREDITAT <= 0;
66 | end
67 | else begin
68 | if (CS&WR) begin
69 | if (AD[4]) begin
70 | // command write
71 | COMMAND <= DI;
72 | MODE <= (DI==8'hA1) ? 1'b1 : ((DI==8'hC1)|(DI==8'hE1)) ? 0 : MODE;
73 | NMI0EN <= (DI!=8'h10);
74 | end
75 | else begin
76 | // data write
77 | if (COMMAND == 8'hC1) case (AD[3:0])
78 | 4'h2: r2 <= DI[3:0];
79 | 4'h3: r3 <= DI[3:0];
80 | 4'h4: r4 <= DI[3:0];
81 | 4'h5: r5 <= DI[3:0];
82 | 4'h8: begin
83 | LCINPCRE <= r2;
84 | LCREPCIN <= r3;
85 | RCINPCRE <= r4;
86 | RCREPCIN <= r5;
87 | CREDITAT <= 1'b1;
88 | end
89 | default:;
90 | endcase
91 | end
92 | end
93 | end
94 | end
95 |
96 |
97 | // data read
98 | wire [3:0] ADR = AD[3:0];
99 | wire [7:0] NONE = 8'hFF;
100 |
101 | reg [7:0] SW_CC;
102 | reg [7:0] SW_P1;
103 | reg [7:0] SW_P2;
104 |
105 | wire [7:0] ST_CC;
106 | BCDCONV bcd( CREDITS, ST_CC[3:0], ST_CC[7:4] );
107 |
108 | reg [7:0] ST_P1 = 8'hF8;
109 | reg [7:0] ST_P2 = 8'hF8;
110 |
111 | wire [7:0] SWMODE = (ADR==0) ? (~SW_CC) :
112 | (ADR==1) ? (~SW_P1) :
113 | (ADR==2) ? (~SW_P2) : NONE;
114 |
115 | wire [7:0] STMODE = (ADR==0) ? ST_CC :
116 | (ADR==1) ? ST_P1 :
117 | (ADR==2) ? ST_P2 : NONE;
118 |
119 | wire [7:0] READh71 = MODE ? SWMODE : STMODE;
120 |
121 | wire [7:0] READhB1 = {8{~(ADR<=2)}};
122 |
123 | wire [7:0] READhD2 = (ADR==0) ? DSW0 :
124 | (ADR==1) ? DSW1 : NONE;
125 |
126 | wire [7:0] READDAT = (COMMAND == 8'h71) ? READh71 :
127 | (COMMAND == 8'hB1) ? READhB1 :
128 | (COMMAND == 8'hD2) ? READhD2 : NONE;
129 |
130 | assign DO = AD[4] ? COMMAND : READDAT;
131 |
132 | //------------------------------------------------------------
133 |
134 | // INP0 = { SERVICE, 1'b0, m_coin2, m_coin1, m_start2, m_start1, m_pump2, m_pump1 };
135 | // INP1 = { m_left2, m_down2, m_right2, m_up2, m_left1, m_down1, m_right1, m_up1 };
136 |
137 | reg [15:0] pINP,piINP,piINP0,piINP1,piINP2;
138 | wire [15:0] nINP = {INP0,INP1};
139 | wire [15:0] iINP = (pINP^nINP) & nINP;
140 |
141 | function [3:0] stick;
142 | input [3:0] stk;
143 | stick = stk[0] ? 0 :
144 | stk[1] ? 2 :
145 | stk[2] ? 4 :
146 | stk[3] ? 6 : 8;
147 | endfunction
148 |
149 | always @( posedge VBLK or posedge RESET ) begin
150 | if (RESET) begin
151 | LCOINS = 0;
152 | RCOINS = 0;
153 | CREDITS = 0;
154 |
155 | SW_CC <= 0;
156 | SW_P1 <= 0;
157 | SW_P2 <= 0;
158 | ST_P1 <= 8'hF8;
159 | ST_P2 <= 8'hF8;
160 |
161 | pINP <= 0;
162 | piINP <= 0;
163 | piINP0 <= 0;
164 | piINP1 <= 0;
165 | piINP2 <= 0;
166 | end
167 | else begin
168 |
169 | SW_CC <= {nINP[15],1'b0,piINP[11],piINP[10],2'b00,iINP[13],iINP[12]};
170 | SW_P1 <= {2'b00, pINP[8], iINP[8],nINP[3:0]};
171 | SW_P2 <= {2'b00, pINP[9], iINP[9],nINP[7:4]};
172 | ST_P1 <= {2'b11,~pINP[8],~iINP[8],stick(nINP[3:0])};
173 | ST_P2 <= {2'b11,~pINP[9],~iINP[9],stick(nINP[7:4])};
174 |
175 | if (CREDITAT) begin
176 | if ( LCINPCRE > 0 ) begin
177 | if ( iINP[12] & ( CREDITS < 99 ) ) begin
178 | LCOINS = LCOINS+1;
179 | if ( LCOINS >= LCINPCRE ) begin
180 | CREDITS = CREDITS + LCREPCIN;
181 | LCOINS = 0;
182 | end
183 | end
184 | if ( iINP[13] & ( CREDITS < 99 ) ) begin
185 | RCOINS = RCOINS+1;
186 | if ( RCOINS >= RCINPCRE ) begin
187 | CREDITS = CREDITS + RCREPCIN;
188 | RCOINS = 0;
189 | end
190 | end
191 | end
192 | else CREDITS = 2;
193 | if ( CREDITS > 99 ) CREDITS = 99;
194 |
195 | if ( piINP[10] & (CREDITS >= 1) ) CREDITS = CREDITS-1;
196 | if ( piINP[11] & (CREDITS >= 2) ) CREDITS = CREDITS-2;
197 | end
198 |
199 | pINP <= nINP;
200 | piINP0 <= iINP;
201 | piINP1 <= piINP0;
202 | piINP2 <= piINP1;
203 | piINP <= piINP2; // delay start buttons
204 |
205 | end
206 | end
207 |
208 | endmodule
209 |
210 |
211 |
212 | //----------------------------------------
213 | // BCD Converter
214 | //----------------------------------------
215 | module add3(in,out);
216 |
217 | input [3:0] in;
218 | output [3:0] out;
219 | reg [3:0] out;
220 |
221 | always @ (in)
222 | case (in)
223 | 4'b0000: out <= 4'b0000;
224 | 4'b0001: out <= 4'b0001;
225 | 4'b0010: out <= 4'b0010;
226 | 4'b0011: out <= 4'b0011;
227 | 4'b0100: out <= 4'b0100;
228 | 4'b0101: out <= 4'b1000;
229 | 4'b0110: out <= 4'b1001;
230 | 4'b0111: out <= 4'b1010;
231 | 4'b1000: out <= 4'b1011;
232 | 4'b1001: out <= 4'b1100;
233 | default: out <= 4'b0000;
234 | endcase
235 |
236 | endmodule
237 |
238 |
239 | module BCDCONV(A,ONES,TENS);
240 |
241 | input [7:0] A;
242 | output [3:0] ONES, TENS;
243 | wire [3:0] c1,c2,c3,c4,c5,c6,c7;
244 | wire [3:0] d1,d2,d3,d4,d5,d6,d7;
245 |
246 | assign d1 = {1'b0,A[7:5]};
247 | assign d2 = {c1[2:0],A[4]};
248 | assign d3 = {c2[2:0],A[3]};
249 | assign d4 = {c3[2:0],A[2]};
250 | assign d5 = {c4[2:0],A[1]};
251 | assign d6 = {1'b0,c1[3],c2[3],c3[3]};
252 | assign d7 = {c6[2:0],c4[3]};
253 |
254 | add3 m1(d1,c1);
255 | add3 m2(d2,c2);
256 | add3 m3(d3,c3);
257 | add3 m4(d4,c4);
258 | add3 m5(d5,c5);
259 | add3 m6(d6,c6);
260 | add3 m7(d7,c7);
261 |
262 | assign ONES = {c5[2:0],A[0]};
263 | assign TENS = {c7[2:0],c5[3]};
264 |
265 | endmodule
266 |
267 |
--------------------------------------------------------------------------------
/sys/hdmi_config.sv:
--------------------------------------------------------------------------------
1 |
2 | module hdmi_config
3 | (
4 | // Host Side
5 | input iCLK,
6 | input iRST_N,
7 |
8 | input dvi_mode,
9 | input audio_96k,
10 |
11 | // I2C Side
12 | output I2C_SCL,
13 | inout I2C_SDA
14 | );
15 |
16 | // Internal Registers/Wires
17 | reg mI2C_GO = 0;
18 | wire mI2C_END;
19 | wire mI2C_ACK;
20 | reg [15:0] LUT_DATA;
21 | reg [7:0] LUT_INDEX = 0;
22 |
23 | i2c #(50_000_000, 20_000) i2c_av
24 | (
25 | .CLK(iCLK),
26 |
27 | .I2C_SCL(I2C_SCL), // I2C CLOCK
28 | .I2C_SDA(I2C_SDA), // I2C DATA
29 |
30 | .I2C_DATA({8'h72,init_data[LUT_INDEX]}), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]. 0x72 is the Slave Address of the ADV7513 chip!
31 | .START(mI2C_GO), // START transfer
32 | .END(mI2C_END), // END transfer
33 | .ACK(mI2C_ACK) // ACK
34 | );
35 |
36 | ////////////////////// Config Control ////////////////////////////
37 | always@(posedge iCLK or negedge iRST_N) begin
38 | reg [1:0] mSetup_ST = 0;
39 |
40 | if(!iRST_N) begin
41 | LUT_INDEX <= 0;
42 | mSetup_ST <= 0;
43 | mI2C_GO <= 0;
44 | end else begin
45 | if(init_data[LUT_INDEX] != 16'hFFFF) begin
46 | case(mSetup_ST)
47 | 0: begin
48 | mI2C_GO <= 1;
49 | mSetup_ST <= 1;
50 | end
51 | 1: if(~mI2C_END) mSetup_ST <= 2;
52 | 2: begin
53 | mI2C_GO <= 0;
54 | if(mI2C_END) begin
55 | mSetup_ST <= 0;
56 | if(!mI2C_ACK) LUT_INDEX <= LUT_INDEX + 8'd1;
57 | end
58 | end
59 | endcase
60 | end
61 | end
62 | end
63 |
64 | ////////////////////////////////////////////////////////////////////
65 | ///////////////////// Config Data LUT //////////////////////////
66 |
67 | wire [15:0] init_data[58] =
68 | '{
69 | 16'h9803, // ADI required Write.
70 |
71 | {8'hD6, 8'b1100_0000}, // [7:6] HPD Control...
72 | // 00 = HPD is from both HPD pin or CDC HPD
73 | // 01 = HPD is from CDC HPD
74 | // 10 = HPD is from HPD pin
75 | // 11 = HPD is always high
76 |
77 | 16'h4110, // Power Down control
78 | 16'h9A70, // ADI required Write.
79 | 16'h9C30, // ADI required Write.
80 | {8'h9D, 8'b0110_0001}, // [7:4] must be b0110!.
81 | // [3:2] b00 = Input clock not divided. b01 = Clk divided by 2. b10 = Clk divided by 4. b11 = invalid!
82 | // [1:0] must be b01!
83 | 16'hA2A4, // ADI required Write.
84 | 16'hA3A4, // ADI required Write.
85 | 16'hE0D0, // ADI required Write.
86 |
87 |
88 | 16'h35_40,
89 | 16'h36_D9,
90 | 16'h37_0A,
91 | 16'h38_00,
92 | 16'h39_2D,
93 | 16'h3A_00,
94 |
95 | {8'h16, 8'b0011_1000}, // Output Format 444 [7]=0.
96 | // [6] must be 0!
97 | // Colour Depth for Input Video data [5:4] b11 = 8-bit.
98 | // Input Style [3:2] b10 = Style 1 (ignored when using 444 input).
99 | // DDR Input Edge falling [1]=0 (not using DDR atm).
100 | // Output Colour Space RGB [0]=0.
101 |
102 | {8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0
103 |
104 | {8'h18, 8'b0100_0110}, // CSC disabled [7]=0.
105 | // CSC Scaling Factor [6:5] b10 = +/- 4.0, -16384 - 16380.
106 | // CSC Equation 3 [4:0] b00110.
107 |
108 |
109 | {8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx.
110 |
111 | 16'h4000, // General Control Packet Enable
112 |
113 | {8'h48, 8'b0000_1000}, // [6]=0 Normal bus order!
114 | // [5] DDR Alignment.
115 | // [4:3] b01 Data right justified (for YCbCr 422 input modes).
116 |
117 | 16'h49A8, // ADI required Write.
118 | 16'h4C00, // ADI required Write.
119 |
120 | {8'h55, 8'b0001_0000}, // [7] must be 0!. Set RGB444 in AVinfo Frame [6:5], Set active format [4].
121 | // AVI InfoFrame Valid [4].
122 | // Bar Info [3:2] b00 Bars invalid. b01 Bars vertical. b10 Bars horizontal. b11 Bars both.
123 | // Scan Info [1:0] b00 (No data). b01 TV. b10 PC. b11 None.
124 |
125 | 16'h7301,
126 |
127 | {8'h94, 8'b1000_0000}, // [7]=1 HPD Interrupt ENabled.
128 |
129 | 16'h9902, // ADI required Write.
130 | 16'h9B18, // ADI required Write.
131 |
132 | 16'h9F00, // ADI required Write.
133 |
134 | {8'hA1, 8'b0000_0000}, // [6]=1 Monitor Sense Power Down DISabled.
135 |
136 | 16'hA408, // ADI required Write.
137 | 16'hA504, // ADI required Write.
138 | 16'hA600, // ADI required Write.
139 | 16'hA700, // ADI required Write.
140 | 16'hA800, // ADI required Write.
141 | 16'hA900, // ADI required Write.
142 | 16'hAA00, // ADI required Write.
143 | 16'hAB40, // ADI required Write.
144 |
145 | {8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled.
146 | // [6:5] must be b00!
147 | // [4]=0 Current frame is unencrypted
148 | // [3:2] must be b01!
149 | // [1]=1 HDMI Mode.
150 | // [0] must be b0!
151 |
152 | 16'hB900, // ADI required Write.
153 |
154 | {8'hBA, 8'b0110_0000}, // [7:5] Input Clock delay...
155 | // b000 = -1.2ns.
156 | // b001 = -0.8ns.
157 | // b010 = -0.4ns.
158 | // b011 = No delay.
159 | // b100 = 0.4ns.
160 | // b101 = 0.8ns.
161 | // b110 = 1.2ns.
162 | // b111 = 1.6ns.
163 |
164 | 16'hBB00, // ADI required Write.
165 |
166 | 16'hDE9C, // ADI required Write.
167 | 16'hE460, // ADI required Write.
168 | 16'hFA7D, // Nbr of times to search for good phase
169 |
170 |
171 | // (Audio stuff on Programming Guide, Page 66)...
172 |
173 | {8'h0A, 8'b0000_0000}, // [6:4] Audio Select. b000 = I2S.
174 | // [3:2] Audio Mode. (HBR stuff, leave at 00!).
175 |
176 | {8'h0B, 8'b0000_1110}, //
177 |
178 | {8'h0C, 8'b0000_0100}, // [7] 0 = Use sampling rate from I2S stream. 1 = Use samp rate from I2C Register.
179 | // [6] 0 = Use Channel Status bits from stream. 1 = Use Channel Status bits from I2C register.
180 | // [2] 1 = I2S0 Enable.
181 | // [1:0] I2S Format: 00 = Standard. 01 = Right Justified. 10 = Left Justified. 11 = AES.
182 |
183 | {8'h0D, 8'b0001_0000}, // [4:0] I2S Bit (Word) Width for Right-Justified.
184 | {8'h14, 8'b0000_0010}, // [3:0] Audio Word Length. b0010 = 16 bits.
185 | {8'h15, audio_96k, 7'b010_0000}, // I2S Sampling Rate [7:4]. b0000 = (44.1KHz). b0010 = 48KHz.
186 | // Input ID [3:1] b000 (0) = 24-bit RGB 444 or YCrCb 444 with Separate Syncs.
187 |
188 | // Audio Clock Config
189 | 16'h0100, //
190 | audio_96k ? 16'h0230 : 16'h0218, // Set N Value 12288/6144
191 | 16'h0300, //
192 |
193 | 16'h0701, //
194 | 16'h0822, // Set CTS Value 74250
195 | 16'h090A, //
196 |
197 | 16'hFFFF // END
198 | };
199 |
200 | ////////////////////////////////////////////////////////////////////
201 |
202 | endmodule
--------------------------------------------------------------------------------
/sys/pll_hdmi/pll_hdmi_0002.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | module pll_hdmi_0002(
3 |
4 | // interface 'refclk'
5 | input wire refclk,
6 |
7 | // interface 'reset'
8 | input wire rst,
9 |
10 | // interface 'outclk0'
11 | output wire outclk_0,
12 |
13 | // interface 'locked'
14 | output wire locked,
15 |
16 | // interface 'reconfig_to_pll'
17 | input wire [63:0] reconfig_to_pll,
18 |
19 | // interface 'reconfig_from_pll'
20 | output wire [63:0] reconfig_from_pll
21 | );
22 |
23 | altera_pll #(
24 | .fractional_vco_multiplier("true"),
25 | .reference_clock_frequency("50.0 MHz"),
26 | .pll_fractional_cout(32),
27 | .pll_dsm_out_sel("1st_order"),
28 | .operation_mode("direct"),
29 | .number_of_clocks(1),
30 | .output_clock_frequency0("148.500000 MHz"),
31 | .phase_shift0("0 ps"),
32 | .duty_cycle0(50),
33 | .output_clock_frequency1("0 MHz"),
34 | .phase_shift1("0 ps"),
35 | .duty_cycle1(50),
36 | .output_clock_frequency2("0 MHz"),
37 | .phase_shift2("0 ps"),
38 | .duty_cycle2(50),
39 | .output_clock_frequency3("0 MHz"),
40 | .phase_shift3("0 ps"),
41 | .duty_cycle3(50),
42 | .output_clock_frequency4("0 MHz"),
43 | .phase_shift4("0 ps"),
44 | .duty_cycle4(50),
45 | .output_clock_frequency5("0 MHz"),
46 | .phase_shift5("0 ps"),
47 | .duty_cycle5(50),
48 | .output_clock_frequency6("0 MHz"),
49 | .phase_shift6("0 ps"),
50 | .duty_cycle6(50),
51 | .output_clock_frequency7("0 MHz"),
52 | .phase_shift7("0 ps"),
53 | .duty_cycle7(50),
54 | .output_clock_frequency8("0 MHz"),
55 | .phase_shift8("0 ps"),
56 | .duty_cycle8(50),
57 | .output_clock_frequency9("0 MHz"),
58 | .phase_shift9("0 ps"),
59 | .duty_cycle9(50),
60 | .output_clock_frequency10("0 MHz"),
61 | .phase_shift10("0 ps"),
62 | .duty_cycle10(50),
63 | .output_clock_frequency11("0 MHz"),
64 | .phase_shift11("0 ps"),
65 | .duty_cycle11(50),
66 | .output_clock_frequency12("0 MHz"),
67 | .phase_shift12("0 ps"),
68 | .duty_cycle12(50),
69 | .output_clock_frequency13("0 MHz"),
70 | .phase_shift13("0 ps"),
71 | .duty_cycle13(50),
72 | .output_clock_frequency14("0 MHz"),
73 | .phase_shift14("0 ps"),
74 | .duty_cycle14(50),
75 | .output_clock_frequency15("0 MHz"),
76 | .phase_shift15("0 ps"),
77 | .duty_cycle15(50),
78 | .output_clock_frequency16("0 MHz"),
79 | .phase_shift16("0 ps"),
80 | .duty_cycle16(50),
81 | .output_clock_frequency17("0 MHz"),
82 | .phase_shift17("0 ps"),
83 | .duty_cycle17(50),
84 | .pll_type("Cyclone V"),
85 | .pll_subtype("Reconfigurable"),
86 | .m_cnt_hi_div(4),
87 | .m_cnt_lo_div(4),
88 | .n_cnt_hi_div(256),
89 | .n_cnt_lo_div(256),
90 | .m_cnt_bypass_en("false"),
91 | .n_cnt_bypass_en("true"),
92 | .m_cnt_odd_div_duty_en("false"),
93 | .n_cnt_odd_div_duty_en("false"),
94 | .c_cnt_hi_div0(2),
95 | .c_cnt_lo_div0(1),
96 | .c_cnt_prst0(1),
97 | .c_cnt_ph_mux_prst0(0),
98 | .c_cnt_in_src0("ph_mux_clk"),
99 | .c_cnt_bypass_en0("false"),
100 | .c_cnt_odd_div_duty_en0("true"),
101 | .c_cnt_hi_div1(1),
102 | .c_cnt_lo_div1(1),
103 | .c_cnt_prst1(1),
104 | .c_cnt_ph_mux_prst1(0),
105 | .c_cnt_in_src1("ph_mux_clk"),
106 | .c_cnt_bypass_en1("true"),
107 | .c_cnt_odd_div_duty_en1("false"),
108 | .c_cnt_hi_div2(1),
109 | .c_cnt_lo_div2(1),
110 | .c_cnt_prst2(1),
111 | .c_cnt_ph_mux_prst2(0),
112 | .c_cnt_in_src2("ph_mux_clk"),
113 | .c_cnt_bypass_en2("true"),
114 | .c_cnt_odd_div_duty_en2("false"),
115 | .c_cnt_hi_div3(1),
116 | .c_cnt_lo_div3(1),
117 | .c_cnt_prst3(1),
118 | .c_cnt_ph_mux_prst3(0),
119 | .c_cnt_in_src3("ph_mux_clk"),
120 | .c_cnt_bypass_en3("true"),
121 | .c_cnt_odd_div_duty_en3("false"),
122 | .c_cnt_hi_div4(1),
123 | .c_cnt_lo_div4(1),
124 | .c_cnt_prst4(1),
125 | .c_cnt_ph_mux_prst4(0),
126 | .c_cnt_in_src4("ph_mux_clk"),
127 | .c_cnt_bypass_en4("true"),
128 | .c_cnt_odd_div_duty_en4("false"),
129 | .c_cnt_hi_div5(1),
130 | .c_cnt_lo_div5(1),
131 | .c_cnt_prst5(1),
132 | .c_cnt_ph_mux_prst5(0),
133 | .c_cnt_in_src5("ph_mux_clk"),
134 | .c_cnt_bypass_en5("true"),
135 | .c_cnt_odd_div_duty_en5("false"),
136 | .c_cnt_hi_div6(1),
137 | .c_cnt_lo_div6(1),
138 | .c_cnt_prst6(1),
139 | .c_cnt_ph_mux_prst6(0),
140 | .c_cnt_in_src6("ph_mux_clk"),
141 | .c_cnt_bypass_en6("true"),
142 | .c_cnt_odd_div_duty_en6("false"),
143 | .c_cnt_hi_div7(1),
144 | .c_cnt_lo_div7(1),
145 | .c_cnt_prst7(1),
146 | .c_cnt_ph_mux_prst7(0),
147 | .c_cnt_in_src7("ph_mux_clk"),
148 | .c_cnt_bypass_en7("true"),
149 | .c_cnt_odd_div_duty_en7("false"),
150 | .c_cnt_hi_div8(1),
151 | .c_cnt_lo_div8(1),
152 | .c_cnt_prst8(1),
153 | .c_cnt_ph_mux_prst8(0),
154 | .c_cnt_in_src8("ph_mux_clk"),
155 | .c_cnt_bypass_en8("true"),
156 | .c_cnt_odd_div_duty_en8("false"),
157 | .c_cnt_hi_div9(1),
158 | .c_cnt_lo_div9(1),
159 | .c_cnt_prst9(1),
160 | .c_cnt_ph_mux_prst9(0),
161 | .c_cnt_in_src9("ph_mux_clk"),
162 | .c_cnt_bypass_en9("true"),
163 | .c_cnt_odd_div_duty_en9("false"),
164 | .c_cnt_hi_div10(1),
165 | .c_cnt_lo_div10(1),
166 | .c_cnt_prst10(1),
167 | .c_cnt_ph_mux_prst10(0),
168 | .c_cnt_in_src10("ph_mux_clk"),
169 | .c_cnt_bypass_en10("true"),
170 | .c_cnt_odd_div_duty_en10("false"),
171 | .c_cnt_hi_div11(1),
172 | .c_cnt_lo_div11(1),
173 | .c_cnt_prst11(1),
174 | .c_cnt_ph_mux_prst11(0),
175 | .c_cnt_in_src11("ph_mux_clk"),
176 | .c_cnt_bypass_en11("true"),
177 | .c_cnt_odd_div_duty_en11("false"),
178 | .c_cnt_hi_div12(1),
179 | .c_cnt_lo_div12(1),
180 | .c_cnt_prst12(1),
181 | .c_cnt_ph_mux_prst12(0),
182 | .c_cnt_in_src12("ph_mux_clk"),
183 | .c_cnt_bypass_en12("true"),
184 | .c_cnt_odd_div_duty_en12("false"),
185 | .c_cnt_hi_div13(1),
186 | .c_cnt_lo_div13(1),
187 | .c_cnt_prst13(1),
188 | .c_cnt_ph_mux_prst13(0),
189 | .c_cnt_in_src13("ph_mux_clk"),
190 | .c_cnt_bypass_en13("true"),
191 | .c_cnt_odd_div_duty_en13("false"),
192 | .c_cnt_hi_div14(1),
193 | .c_cnt_lo_div14(1),
194 | .c_cnt_prst14(1),
195 | .c_cnt_ph_mux_prst14(0),
196 | .c_cnt_in_src14("ph_mux_clk"),
197 | .c_cnt_bypass_en14("true"),
198 | .c_cnt_odd_div_duty_en14("false"),
199 | .c_cnt_hi_div15(1),
200 | .c_cnt_lo_div15(1),
201 | .c_cnt_prst15(1),
202 | .c_cnt_ph_mux_prst15(0),
203 | .c_cnt_in_src15("ph_mux_clk"),
204 | .c_cnt_bypass_en15("true"),
205 | .c_cnt_odd_div_duty_en15("false"),
206 | .c_cnt_hi_div16(1),
207 | .c_cnt_lo_div16(1),
208 | .c_cnt_prst16(1),
209 | .c_cnt_ph_mux_prst16(0),
210 | .c_cnt_in_src16("ph_mux_clk"),
211 | .c_cnt_bypass_en16("true"),
212 | .c_cnt_odd_div_duty_en16("false"),
213 | .c_cnt_hi_div17(1),
214 | .c_cnt_lo_div17(1),
215 | .c_cnt_prst17(1),
216 | .c_cnt_ph_mux_prst17(0),
217 | .c_cnt_in_src17("ph_mux_clk"),
218 | .c_cnt_bypass_en17("true"),
219 | .c_cnt_odd_div_duty_en17("false"),
220 | .pll_vco_div(2),
221 | .pll_cp_current(20),
222 | .pll_bwctrl(4000),
223 | .pll_output_clk_frequency("445.499999 MHz"),
224 | .pll_fractional_division("3908420153"),
225 | .mimic_fbclk_type("none"),
226 | .pll_fbclk_mux_1("glb"),
227 | .pll_fbclk_mux_2("m_cnt"),
228 | .pll_m_cnt_in_src("ph_mux_clk"),
229 | .pll_slf_rst("true")
230 | ) altera_pll_i (
231 | .rst (rst),
232 | .outclk ({outclk_0}),
233 | .locked (locked),
234 | .reconfig_to_pll (reconfig_to_pll),
235 | .fboutclk ( ),
236 | .fbclk (1'b0),
237 | .refclk (refclk),
238 | .reconfig_from_pll (reconfig_from_pll)
239 | );
240 | endmodule
241 |
242 |
--------------------------------------------------------------------------------
/Arcade-DigDug.sv:
--------------------------------------------------------------------------------
1 | //============================================================================
2 | // Arcade: DigDug
3 | //
4 | // Original implimentation and port to MiSTer by MiSTer-X 2019
5 | //============================================================================
6 |
7 | module emu
8 | (
9 | //Master input clock
10 | input CLK_50M,
11 |
12 | //Async reset from top-level module.
13 | //Can be used as initial reset.
14 | input RESET,
15 |
16 | //Must be passed to hps_io module
17 | inout [44:0] HPS_BUS,
18 |
19 | //Base video clock. Usually equals to CLK_SYS.
20 | output VGA_CLK,
21 |
22 | //Multiple resolutions are supported using different VGA_CE rates.
23 | //Must be based on CLK_VIDEO
24 | output VGA_CE,
25 |
26 | output [7:0] VGA_R,
27 | output [7:0] VGA_G,
28 | output [7:0] VGA_B,
29 | output VGA_HS,
30 | output VGA_VS,
31 | output VGA_DE, // = ~(VBlank | HBlank)
32 |
33 | //Base video clock. Usually equals to CLK_SYS.
34 | output HDMI_CLK,
35 |
36 | //Multiple resolutions are supported using different HDMI_CE rates.
37 | //Must be based on CLK_VIDEO
38 | output HDMI_CE,
39 |
40 | output [7:0] HDMI_R,
41 | output [7:0] HDMI_G,
42 | output [7:0] HDMI_B,
43 | output HDMI_HS,
44 | output HDMI_VS,
45 | output HDMI_DE, // = ~(VBlank | HBlank)
46 | output [1:0] HDMI_SL, // scanlines fx
47 |
48 | //Video aspect ratio for HDMI. Most retro systems have ratio 4:3.
49 | output [7:0] HDMI_ARX,
50 | output [7:0] HDMI_ARY,
51 |
52 | output LED_USER, // 1 - ON, 0 - OFF.
53 |
54 | // b[1]: 0 - LED status is system status OR'd with b[0]
55 | // 1 - LED status is controled solely by b[0]
56 | // hint: supply 2'b00 to let the system control the LED.
57 | output [1:0] LED_POWER,
58 | output [1:0] LED_DISK,
59 |
60 | output [15:0] AUDIO_L,
61 | output [15:0] AUDIO_R,
62 | output AUDIO_S // 1 - signed audio samples, 0 - unsigned
63 | );
64 |
65 | assign LED_USER = ioctl_download;
66 | assign LED_DISK = 0;
67 | assign LED_POWER = 0;
68 |
69 | assign HDMI_ARX = status[1] ? 8'd16 : status[2] ? 8'd4 : 8'd3;
70 | assign HDMI_ARY = status[1] ? 8'd9 : status[2] ? 8'd3 : 8'd4;
71 |
72 | `include "build_id.v"
73 | localparam CONF_STR = {
74 | "A.DIGDUG;;",
75 |
76 | "O1,Aspect Ratio,Original,Wide;",
77 | "O2,Orientation,Vert,Horz;",
78 | "O35,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%;",
79 | "-;",
80 | "O89,Difficulty,Medium,Hardest,Easy,Hard;",
81 | "OAB,Life,3,5,1,2;",
82 | "OCE,Bonus Life,M3,M4,M5,M6,M7,Nothing,M1,M2;",
83 | "OF,Allow Continue,No,Yes;",
84 | "OG,Demo Sound,Off,On;",
85 | "-;",
86 | "OH,Service Mode,Off,On;",
87 | "-;",
88 | "R0,Reset;",
89 | "J1,Pump,Start 1P,Start 2P,Coin;",
90 | "V,v",`BUILD_DATE
91 | };
92 |
93 |
94 | //////////////////// CLOCKS ///////////////////
95 |
96 | wire clk_hdmi;
97 | wire clk_48M;
98 | wire clk_sys = clk_hdmi;
99 |
100 | pll pll
101 | (
102 | .rst(0),
103 | .refclk(CLK_50M),
104 | .outclk_0(clk_48M),
105 | .outclk_1(clk_hdmi)
106 | );
107 |
108 | ///////////////////////////////////////////////////
109 |
110 | wire [31:0] status;
111 | wire [1:0] buttons;
112 | wire forced_scandoubler;
113 |
114 | wire ioctl_download;
115 | wire ioctl_wr;
116 | wire [24:0] ioctl_addr;
117 | wire [7:0] ioctl_dout;
118 |
119 | wire [10:0] ps2_key;
120 | wire [15:0] joystk1, joystk2;
121 |
122 | hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io
123 | (
124 | .clk_sys(clk_sys),
125 | .HPS_BUS(HPS_BUS),
126 |
127 | .conf_str(CONF_STR),
128 |
129 | .buttons(buttons),
130 | .status(status),
131 | .forced_scandoubler(forced_scandoubler),
132 |
133 | .ioctl_download(ioctl_download),
134 | .ioctl_wr(ioctl_wr),
135 | .ioctl_addr(ioctl_addr),
136 | .ioctl_dout(ioctl_dout),
137 |
138 | .joystick_0(joystk1),
139 | .joystick_1(joystk2),
140 | .ps2_key(ps2_key)
141 | );
142 |
143 | wire pressed = ps2_key[9];
144 | wire [8:0] code = ps2_key[8:0];
145 | always @(posedge clk_sys) begin
146 | reg old_state;
147 | old_state <= ps2_key[10];
148 |
149 | if(old_state != ps2_key[10]) begin
150 | casex(code)
151 | 'hX75: btn_up <= pressed; // up
152 | 'hX72: btn_down <= pressed; // down
153 | 'hX6B: btn_left <= pressed; // left
154 | 'hX74: btn_right <= pressed; // right
155 | 'h029: btn_fire <= pressed; // space
156 | 'h014: btn_fire <= pressed; // ctrl
157 | 'h005: btn_one_player <= pressed; // F1
158 | 'h006: btn_two_players <= pressed; // F2
159 |
160 | // JPAC/IPAC/MAME Style Codes
161 | 'h016: btn_start_1 <= pressed; // 1
162 | 'h01E: btn_start_2 <= pressed; // 2
163 | 'h02E: btn_coin_1 <= pressed; // 5
164 | 'h036: btn_coin_2 <= pressed; // 6
165 | 'h02D: btn_up_2 <= pressed; // R
166 | 'h02B: btn_down_2 <= pressed; // F
167 | 'h023: btn_left_2 <= pressed; // D
168 | 'h034: btn_right_2 <= pressed; // G
169 | 'h01C: btn_fire_2 <= pressed; // A
170 | 'h01B: btn_fire_2 <= pressed; // S
171 | endcase
172 | end
173 | end
174 |
175 | reg btn_up = 0;
176 | reg btn_down = 0;
177 | reg btn_right = 0;
178 | reg btn_left = 0;
179 | reg btn_fire = 0;
180 | reg btn_one_player = 0;
181 | reg btn_two_players = 0;
182 |
183 | reg btn_start_1 = 0;
184 | reg btn_start_2 = 0;
185 | reg btn_coin_1 = 0;
186 | reg btn_coin_2 = 0;
187 | reg btn_up_2 = 0;
188 | reg btn_down_2 = 0;
189 | reg btn_left_2 = 0;
190 | reg btn_right_2 = 0;
191 | reg btn_fire_2 = 0;
192 |
193 |
194 | wire bCabinet = 1'b0; // (upright only)
195 |
196 | wire m_up2 = btn_up_2 | joystk2[3];
197 | wire m_down2 = btn_down_2 | joystk2[2];
198 | wire m_left2 = btn_left_2 | joystk2[1];
199 | wire m_right2 = btn_right_2 | joystk2[0];
200 | wire m_trig2 = btn_fire_2 | joystk2[4];
201 |
202 | wire m_start1 = btn_one_player | joystk1[5] | joystk2[5] | btn_start_1;
203 | wire m_start2 = btn_two_players | joystk1[6] | joystk2[6] | btn_start_2;
204 |
205 | wire m_up1 = btn_up | joystk1[3] | (bCabinet ? 1'b0 : m_up2);
206 | wire m_down1 = btn_down | joystk1[2] | (bCabinet ? 1'b0 : m_down2);
207 | wire m_left1 = btn_left | joystk1[1] | (bCabinet ? 1'b0 : m_left2);
208 | wire m_right1 = btn_right | joystk1[0] | (bCabinet ? 1'b0 : m_right2);
209 | wire m_trig1 = btn_fire | joystk1[4] | (bCabinet ? 1'b0 : m_trig2);
210 |
211 | wire m_coin1 = btn_one_player | btn_coin_1 | joystk1[7];
212 | wire m_coin2 = btn_two_players| btn_coin_2 | joystk2[7];
213 |
214 |
215 | ///////////////////////////////////////////////////
216 |
217 | wire hblank, vblank;
218 | wire ce_vid;
219 | wire hs, vs;
220 | wire [3:0] r,g,b;
221 |
222 | reg ce_pix;
223 | always @(posedge clk_hdmi) begin
224 | reg old_clk;
225 | old_clk <= ce_vid;
226 | ce_pix <= old_clk & ~ce_vid;
227 | end
228 |
229 | arcade_rotate_fx #(288,224,12) arcade_video
230 | (
231 | .*,
232 |
233 | .clk_video(clk_hdmi),
234 |
235 | .RGB_in({r,g,b}),
236 | .HBlank(hblank),
237 | .VBlank(vblank),
238 | .HSync(~hs),
239 | .VSync(~vs),
240 |
241 | .fx(status[5:3]),
242 | .no_rotate(status[2])
243 | );
244 |
245 | wire PCLK;
246 | wire [8:0] HPOS,VPOS;
247 | wire [11:0] POUT;
248 | HVGEN hvgen
249 | (
250 | .HPOS(HPOS),.VPOS(VPOS),.PCLK(PCLK),.iRGB(POUT),
251 | .oRGB({b,g,r}),.HBLK(hblank),.VBLK(vblank),.HSYN(hs),.VSYN(vs)
252 | );
253 | assign ce_vid = PCLK;
254 |
255 |
256 | wire [15:0] AOUT;
257 | assign AUDIO_L = AOUT;
258 | assign AUDIO_R = AUDIO_L;
259 | assign AUDIO_S = 0; // unsigned PCM
260 |
261 |
262 | ///////////////////////////////////////////////////
263 |
264 | wire iRST = RESET | status[0] | buttons[1] | ioctl_download;
265 |
266 | wire [1:0] COIA = 2'b00; // 1coin/1credit
267 | wire [2:0] COIB = 3'b001; // 1coin/1credit
268 | wire CABI = ~bCabinet;
269 | wire FRZE = 1'b1;
270 |
271 | wire [1:0] DIFC = status[9:8]+2'h2;
272 | wire [1:0] LIFE = status[11:10]+2'h2;
273 | wire [2:0] EXMD = status[14:12]+3'h3;
274 | wire CONT = ~status[15];
275 | wire DSND = ~status[16];
276 | wire SERVICE = status[17];
277 |
278 | wire [7:0] DSW0 = {LIFE,EXMD,COIB};
279 | wire [7:0] DSW1 = {COIA,FRZE,DSND,CONT,CABI,DIFC};
280 | wire [7:0] INP0 = {SERVICE, 1'b0, m_coin2, m_coin1, m_start2, m_start1, m_trig2, m_trig1 };
281 | wire [7:0] INP1 = {m_left2, m_down2, m_right2, m_up2, m_left1, m_down1, m_right1, m_up1 };
282 |
283 | wire [7:0] oPIX;
284 | wire [7:0] oSND;
285 |
286 | FPGA_DIGDUG GameCore (
287 | .RESET(iRST),.MCLK(clk_48M),
288 | .INP0(INP0),.INP1(INP1),.DSW0(DSW0),.DSW1(DSW1),
289 | .PH(HPOS),.PV(VPOS),.PCLK(PCLK),.POUT(oPIX),
290 | .SOUT(oSND),
291 |
292 | .ROMCL(clk_sys),.ROMAD(ioctl_addr),.ROMDT(ioctl_dout),.ROMEN(ioctl_wr)
293 | );
294 |
295 | assign POUT = {oPIX[7:6],2'b00,oPIX[5:3],1'b0,oPIX[2:0],1'b0};
296 | assign AOUT = {oSND,8'h0};
297 |
298 | endmodule
299 |
300 |
301 | module HVGEN
302 | (
303 | output [8:0] HPOS,
304 | output [8:0] VPOS,
305 | input PCLK,
306 | input [11:0] iRGB,
307 |
308 | output reg [11:0] oRGB,
309 | output reg HBLK = 1,
310 | output reg VBLK = 1,
311 | output reg HSYN = 1,
312 | output reg VSYN = 1
313 | );
314 |
315 | reg [8:0] hcnt = 0;
316 | reg [8:0] vcnt = 0;
317 |
318 | assign HPOS = hcnt;
319 | assign VPOS = vcnt;
320 |
321 | always @(posedge PCLK) begin
322 | case (hcnt)
323 | 288: begin HBLK <= 1; hcnt <= hcnt+1; end
324 | 311: begin HSYN <= 0; hcnt <= hcnt+1; end
325 | 342: begin HSYN <= 1; hcnt <= 471; end
326 | 511: begin HBLK <= 0; hcnt <= 0;
327 | case (vcnt)
328 | 223: begin VBLK <= 1; vcnt <= vcnt+1; end
329 | 226: begin VSYN <= 0; vcnt <= vcnt+1; end
330 | 233: begin VSYN <= 1; vcnt <= 483; end
331 | 511: begin VBLK <= 0; vcnt <= 0; end
332 | default: vcnt <= vcnt+1;
333 | endcase
334 | end
335 | default: hcnt <= hcnt+1;
336 | endcase
337 | oRGB <= (HBLK|VBLK) ? 12'h0 : iRGB;
338 | end
339 |
340 | endmodule
341 |
342 |
--------------------------------------------------------------------------------
/src/LINEBUF.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %RAM: 2-PORT%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: altsyncram
5 |
6 | // ============================================================
7 | // File Name: LINEBUF.v
8 | // Megafunction Name(s):
9 | // altsyncram
10 | //
11 | // Simulation Library Files(s):
12 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 17.1.0 Build 590 10/25/2017 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2017 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and its AMPP partner logic
24 | //functions, and any output files from any of the foregoing
25 | //(including device programming or simulation files), and any
26 | //associated documentation or information are expressly subject
27 | //to the terms and conditions of the Intel Program License
28 | //Subscription Agreement, the Intel Quartus Prime License Agreement,
29 | //the Intel FPGA IP License Agreement, or other applicable license
30 | //agreement, including, without limitation, that your use is for
31 | //the sole purpose of programming logic devices manufactured by
32 | //Intel and sold by Intel or its authorized distributors. Please
33 | //refer to the applicable agreement for further details.
34 |
35 |
36 | // synopsys translate_off
37 | `timescale 1 ps / 1 ps
38 | // synopsys translate_on
39 | module LINEBUF (
40 | address_a,
41 | address_b,
42 | clock_a,
43 | clock_b,
44 | data_a,
45 | data_b,
46 | wren_a,
47 | wren_b,
48 | q_a,
49 | q_b);
50 |
51 | input [9:0] address_a;
52 | input [9:0] address_b;
53 | input clock_a;
54 | input clock_b;
55 | input [7:0] data_a;
56 | input [7:0] data_b;
57 | input wren_a;
58 | input wren_b;
59 | output [7:0] q_a;
60 | output [7:0] q_b;
61 | `ifndef ALTERA_RESERVED_QIS
62 | // synopsys translate_off
63 | `endif
64 | tri1 clock_a;
65 | tri0 wren_a;
66 | tri0 wren_b;
67 | `ifndef ALTERA_RESERVED_QIS
68 | // synopsys translate_on
69 | `endif
70 |
71 | wire [7:0] sub_wire0;
72 | wire [7:0] sub_wire1;
73 | wire [7:0] q_a = sub_wire0[7:0];
74 | wire [7:0] q_b = sub_wire1[7:0];
75 |
76 | altsyncram altsyncram_component (
77 | .address_a (address_a),
78 | .address_b (address_b),
79 | .clock0 (clock_a),
80 | .clock1 (clock_b),
81 | .data_a (data_a),
82 | .data_b (data_b),
83 | .wren_a (wren_a),
84 | .wren_b (wren_b),
85 | .q_a (sub_wire0),
86 | .q_b (sub_wire1),
87 | .aclr0 (1'b0),
88 | .aclr1 (1'b0),
89 | .addressstall_a (1'b0),
90 | .addressstall_b (1'b0),
91 | .byteena_a (1'b1),
92 | .byteena_b (1'b1),
93 | .clocken0 (1'b1),
94 | .clocken1 (1'b1),
95 | .clocken2 (1'b1),
96 | .clocken3 (1'b1),
97 | .eccstatus (),
98 | .rden_a (1'b1),
99 | .rden_b (1'b1));
100 | defparam
101 | altsyncram_component.address_reg_b = "CLOCK1",
102 | altsyncram_component.clock_enable_input_a = "BYPASS",
103 | altsyncram_component.clock_enable_input_b = "BYPASS",
104 | altsyncram_component.clock_enable_output_a = "BYPASS",
105 | altsyncram_component.clock_enable_output_b = "BYPASS",
106 | altsyncram_component.indata_reg_b = "CLOCK1",
107 | altsyncram_component.intended_device_family = "Cyclone V",
108 | altsyncram_component.lpm_type = "altsyncram",
109 | altsyncram_component.numwords_a = 1024,
110 | altsyncram_component.numwords_b = 1024,
111 | altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
112 | altsyncram_component.outdata_aclr_a = "NONE",
113 | altsyncram_component.outdata_aclr_b = "NONE",
114 | altsyncram_component.outdata_reg_a = "UNREGISTERED",
115 | altsyncram_component.outdata_reg_b = "UNREGISTERED",
116 | altsyncram_component.power_up_uninitialized = "FALSE",
117 | altsyncram_component.ram_block_type = "M10K",
118 | altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
119 | altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
120 | altsyncram_component.widthad_a = 10,
121 | altsyncram_component.widthad_b = 10,
122 | altsyncram_component.width_a = 8,
123 | altsyncram_component.width_b = 8,
124 | altsyncram_component.width_byteena_a = 1,
125 | altsyncram_component.width_byteena_b = 1,
126 | altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1";
127 |
128 |
129 | endmodule
130 |
131 | // ============================================================
132 | // CNX file retrieval info
133 | // ============================================================
134 | // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
135 | // Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
136 | // Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
137 | // Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
138 | // Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
139 | // Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
140 | // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
141 | // Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
142 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
143 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
144 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
145 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
146 | // Retrieval info: PRIVATE: CLRdata NUMERIC "0"
147 | // Retrieval info: PRIVATE: CLRq NUMERIC "0"
148 | // Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
149 | // Retrieval info: PRIVATE: CLRrren NUMERIC "0"
150 | // Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
151 | // Retrieval info: PRIVATE: CLRwren NUMERIC "0"
152 | // Retrieval info: PRIVATE: Clock NUMERIC "5"
153 | // Retrieval info: PRIVATE: Clock_A NUMERIC "0"
154 | // Retrieval info: PRIVATE: Clock_B NUMERIC "0"
155 | // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
156 | // Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
157 | // Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
158 | // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
159 | // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
160 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
161 | // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
162 | // Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
163 | // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
164 | // Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192"
165 | // Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
166 | // Retrieval info: PRIVATE: MIFfilename STRING ""
167 | // Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
168 | // Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
169 | // Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
170 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "2"
171 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
172 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
173 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
174 | // Retrieval info: PRIVATE: REGdata NUMERIC "1"
175 | // Retrieval info: PRIVATE: REGq NUMERIC "0"
176 | // Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
177 | // Retrieval info: PRIVATE: REGrren NUMERIC "0"
178 | // Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
179 | // Retrieval info: PRIVATE: REGwren NUMERIC "1"
180 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
181 | // Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
182 | // Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
183 | // Retrieval info: PRIVATE: VarWidth NUMERIC "0"
184 | // Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
185 | // Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
186 | // Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
187 | // Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
188 | // Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
189 | // Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
190 | // Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
191 | // Retrieval info: PRIVATE: enable NUMERIC "0"
192 | // Retrieval info: PRIVATE: rden NUMERIC "0"
193 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
194 | // Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
195 | // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
196 | // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
197 | // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
198 | // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
199 | // Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1"
200 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
201 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
202 | // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024"
203 | // Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "1024"
204 | // Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
205 | // Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
206 | // Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
207 | // Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
208 | // Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
209 | // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
210 | // Retrieval info: CONSTANT: RAM_BLOCK_TYPE STRING "M10K"
211 | // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
212 | // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
213 | // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10"
214 | // Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "10"
215 | // Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
216 | // Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
217 | // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
218 | // Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
219 | // Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1"
220 | // Retrieval info: USED_PORT: address_a 0 0 10 0 INPUT NODEFVAL "address_a[9..0]"
221 | // Retrieval info: USED_PORT: address_b 0 0 10 0 INPUT NODEFVAL "address_b[9..0]"
222 | // Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT VCC "clock_a"
223 | // Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL "clock_b"
224 | // Retrieval info: USED_PORT: data_a 0 0 8 0 INPUT NODEFVAL "data_a[7..0]"
225 | // Retrieval info: USED_PORT: data_b 0 0 8 0 INPUT NODEFVAL "data_b[7..0]"
226 | // Retrieval info: USED_PORT: q_a 0 0 8 0 OUTPUT NODEFVAL "q_a[7..0]"
227 | // Retrieval info: USED_PORT: q_b 0 0 8 0 OUTPUT NODEFVAL "q_b[7..0]"
228 | // Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
229 | // Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
230 | // Retrieval info: CONNECT: @address_a 0 0 10 0 address_a 0 0 10 0
231 | // Retrieval info: CONNECT: @address_b 0 0 10 0 address_b 0 0 10 0
232 | // Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0
233 | // Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0
234 | // Retrieval info: CONNECT: @data_a 0 0 8 0 data_a 0 0 8 0
235 | // Retrieval info: CONNECT: @data_b 0 0 8 0 data_b 0 0 8 0
236 | // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
237 | // Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
238 | // Retrieval info: CONNECT: q_a 0 0 8 0 @q_a 0 0 8 0
239 | // Retrieval info: CONNECT: q_b 0 0 8 0 @q_b 0 0 8 0
240 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF.v TRUE
241 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF.inc FALSE
242 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF.cmp FALSE
243 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF.bsf FALSE
244 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF_inst.v FALSE
245 | // Retrieval info: GEN_FILE: TYPE_NORMAL LINEBUF_bb.v FALSE
246 | // Retrieval info: LIB_FILE: altera_mf
247 |
--------------------------------------------------------------------------------
/sys/pll_hdmi_adj.vhd:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------------------
2 | -- HDMI PLL Adjust
3 | --------------------------------------------------------------------------------
4 |
5 | -- Changes the HDMI PLL frequency according to the scaler suggestions.
6 | --------------------------------------------
7 | -- LLTUNE :
8 | -- 0 : Input Syncline
9 | -- 1 :
10 | -- 2 : Input Interlaced mode
11 | -- 3 : Input Interlaced field
12 | -- 4 : Output Syncline
13 | -- 5 :
14 | -- 6 : Input clock
15 | -- 7 : Output clock
16 |
17 | LIBRARY ieee;
18 | USE ieee.std_logic_1164.ALL;
19 | USE ieee.numeric_std.ALL;
20 |
21 | ENTITY pll_hdmi_adj IS
22 | PORT (
23 | -- Scaler
24 | llena : IN std_logic; -- 0=Disabled 1=Enabled
25 | lltune : IN unsigned(15 DOWNTO 0); -- Outputs from scaler
26 |
27 | locked : OUT std_logic;
28 |
29 | -- Signals from reconfig commands
30 | i_waitrequest : OUT std_logic;
31 | i_write : IN std_logic;
32 | i_address : IN unsigned(5 DOWNTO 0);
33 | i_writedata : IN unsigned(31 DOWNTO 0);
34 |
35 | -- Outputs to PLL_HDMI_CFG
36 | o_waitrequest : IN std_logic;
37 | o_write : OUT std_logic;
38 | o_address : OUT unsigned(5 DOWNTO 0);
39 | o_writedata : OUT unsigned(31 DOWNTO 0);
40 |
41 | ------------------------------------
42 | clk : IN std_logic;
43 | reset_na : IN std_logic
44 | );
45 |
46 | BEGIN
47 |
48 |
49 | END ENTITY pll_hdmi_adj;
50 |
51 | --##############################################################################
52 |
53 | ARCHITECTURE rtl OF pll_hdmi_adj IS
54 | SIGNAL pwrite : std_logic;
55 | SIGNAL paddress : unsigned(5 DOWNTO 0);
56 | SIGNAL pdata : unsigned(31 DOWNTO 0);
57 | TYPE enum_state IS (sIDLE,sW1,sW2,sW3,sW4,sW5,sW6);
58 | SIGNAL state : enum_state;
59 | SIGNAL tune_freq,tune_phase : unsigned(5 DOWNTO 0);
60 | SIGNAL lltune_sync,lltune_sync2,lltune_sync3 : unsigned(15 DOWNTO 0);
61 | SIGNAL mfrac,mfrac_mem,mfrac_ref,diff : unsigned(40 DOWNTO 0);
62 | SIGNAL mul : unsigned(15 DOWNTO 0);
63 | SIGNAL sign,sign_pre : std_logic;
64 | SIGNAL up,modo,phm,dir : std_logic;
65 | SIGNAL cpt : natural RANGE 0 TO 3;
66 | SIGNAL col : natural RANGE 0 TO 15;
67 |
68 | SIGNAL icpt,ocpt,ssh : natural RANGE 0 TO 2**24-1;
69 | SIGNAL isync,isync2,itog,ipulse : std_logic;
70 | SIGNAL osync,osync2,otog,opulse : std_logic;
71 | SIGNAL sync,pulse,los,lop : std_logic;
72 | SIGNAL osize,isize,offset,osizep : signed(23 DOWNTO 0);
73 | SIGNAL logcpt : natural RANGE 0 TO 31;
74 | SIGNAL udiff : integer RANGE -2**23 TO 2**23-1 :=0;
75 |
76 | BEGIN
77 | ----------------------------------------------------------------------------
78 | -- Sample image sizes
79 | Sampler:PROCESS(clk,reset_na) IS
80 | BEGIN
81 | IF reset_na='0' THEN
82 | --pragma synthesis_off
83 | otog<='0';
84 | itog<='0';
85 | isync<='0';
86 | isync2<='0';
87 | osync<='0';
88 | osync2<='0';
89 | --pragma synthesis_on
90 |
91 | ELSIF rising_edge(clk) THEN
92 | -- Clock domain crossing
93 | isync<=lltune(0); --
94 | isync2<=isync;
95 | osync<=lltune(4); --
96 | osync2<=osync;
97 |
98 | itog<=itog XOR (isync AND NOT isync2);
99 | otog<=otog XOR (osync AND NOT osync2);
100 |
101 | --ipulse<=isync AND NOT isync2 AND itog;
102 | --opulse<=osync AND NOT osync2 AND otog;
103 |
104 | -- Measure output image size
105 | IF osync='1' AND osync2='0' AND otog='1' THEN
106 | ocpt<=0;
107 | osizep<=to_signed(ocpt,24);
108 | ELSE
109 | ocpt<=ocpt+1;
110 | END IF;
111 |
112 | -- Measure input image size
113 | IF isync='1' AND isync2='0' AND itog='1' THEN
114 | icpt<=0;
115 | --isize<=to_signed(icpt,24);
116 | osize<=osizep;
117 | offset<=to_signed(ocpt,24);
118 | udiff<=integer(to_integer(osizep)) - integer(icpt);
119 | sync<='1';
120 | ELSE
121 | icpt<=icpt+1;
122 | sync<='0';
123 | END IF;
124 |
125 | --------------------------------------------
126 | pulse<='0';
127 | IF sync='1' THEN
128 | logcpt<=0;
129 | ssh<=to_integer(osize);
130 | los<='0';
131 | lop<='0';
132 |
133 | ELSIF logcpt<24 THEN
134 | -- Frequency difference
135 | IF udiff>0 AND ssh=osize/2 AND ssh<(osize-offset) AND lop='0' THEN
147 | tune_phase<='1' & to_unsigned(logcpt,5);
148 | lop<='1';
149 | END IF;
150 | ssh<=ssh/2;
151 | logcpt<=logcpt+1;
152 |
153 | ELSIF logcpt=24 THEN
154 | pulse<='1';
155 | ssh<=ssh/2;
156 | logcpt<=logcpt+1;
157 | END IF;
158 |
159 | END IF;
160 | END PROCESS Sampler;
161 |
162 | ----------------------------------------------------------------------------
163 | -- 000010 : Start reg "Write either 0 or 1 to start fractional PLL reconf.
164 | -- 000100 : M counter
165 | -- 000111 : M counter Fractional Value K
166 |
167 | Comb:PROCESS(i_write,i_address,
168 | i_writedata,pwrite,paddress,pdata) IS
169 | BEGIN
170 | IF i_write='1' THEN
171 | o_write <=i_write;
172 | o_address <=i_address;
173 | o_writedata <=i_writedata;
174 | ELSE
175 | o_write <=pwrite;
176 | o_address <=paddress;
177 | o_writedata<=pdata;
178 | END IF;
179 | END PROCESS Comb;
180 |
181 | i_waitrequest<=o_waitrequest WHEN state=sIDLE ELSE '0';
182 |
183 | ----------------------------------------------------------------------------
184 | Schmurtz:PROCESS(clk,reset_na) IS
185 | VARIABLE off_v,ofp_v : natural RANGE 0 TO 63;
186 | VARIABLE diff_v : unsigned(40 DOWNTO 0);
187 | VARIABLE mulco : unsigned(15 DOWNTO 0);
188 | VARIABLE up_v,sign_v : std_logic;
189 | BEGIN
190 | IF reset_na='0' THEN
191 | modo<='0';
192 | state<=sIDLE;
193 | ELSIF rising_edge(clk) THEN
194 | ------------------------------------------------------
195 | -- Snoop accesses to PLL reconfiguration
196 | IF i_address="000100" AND i_write='1' THEN
197 | mfrac (40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) +
198 | ('0' & i_writedata(7 DOWNTO 0));
199 | mfrac_ref(40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) +
200 | ('0' & i_writedata(7 DOWNTO 0));
201 | mfrac_mem(40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) +
202 | ('0' & i_writedata(7 DOWNTO 0));
203 | mul<=i_writedata(15 DOWNTO 0);
204 | modo<='1';
205 | END IF;
206 |
207 | IF i_address="000111" AND i_write='1' THEN
208 | mfrac (31 DOWNTO 0)<=i_writedata;
209 | mfrac_ref(31 DOWNTO 0)<=i_writedata;
210 | mfrac_mem(31 DOWNTO 0)<=i_writedata;
211 | modo<='1';
212 | END IF;
213 |
214 | ------------------------------------------------------
215 | -- Tuning
216 | off_v:=to_integer('0' & tune_freq(4 DOWNTO 0));
217 | ofp_v:=to_integer('0' & tune_phase(4 DOWNTO 0));
218 | --IF off_v<8 THEN off_v:=8; END IF;
219 | --IF ofp_v<7 THEN ofp_v:=7; END IF;
220 | IF off_v<4 THEN off_v:=4; END IF;
221 | IF ofp_v<4 THEN ofp_v:=4; END IF;
222 |
223 | IF off_v>=18 AND ofp_v>=18 THEN
224 | locked<=llena;
225 | ELSE
226 | locked<='0';
227 | END IF;
228 |
229 | up_v:='0';
230 | IF pulse='1' THEN
231 | cpt<=(cpt+1) MOD 4;
232 | IF llena='0' THEN
233 | -- Recover original freq when disabling low lag mode
234 | cpt<=0;
235 | col<=0;
236 | IF modo='1' THEN
237 | mfrac<=mfrac_mem;
238 | mfrac_ref<=mfrac_mem;
239 | up<='1';
240 | modo<='0';
241 | END IF;
242 |
243 | ELSIF phm='0' AND cpt=0 THEN
244 | -- Frequency adjust
245 | sign_v:=tune_freq(5);
246 | IF col<10 THEN col<=col+1; END IF;
247 | IF off_v>=16 AND col>=10 THEN
248 | phm<='1';
249 | col<=0;
250 | ELSE
251 | off_v:=off_v+1;
252 | IF off_v>17 THEN
253 | off_v:=off_v + 3;
254 | END IF;
255 | up_v:='1';
256 | up<='1';
257 | END IF;
258 |
259 | ELSIF cpt=0 THEN
260 | -- Phase adjust
261 | sign_v:=NOT tune_phase(5);
262 | col<=col+1;
263 | IF col>=10 THEN
264 | phm<='0';
265 | up_v:='1';
266 | off_v:=31;
267 | col<=0;
268 | ELSE
269 | off_v:=ofp_v + 1;
270 | IF ofp_v>7 THEN
271 | off_v:=off_v + 1;
272 | END IF;
273 | IF ofp_v>14 THEN
274 | off_v:=off_v + 2;
275 | END IF;
276 | IF ofp_v>17 THEN
277 | off_v:=off_v + 3;
278 | END IF;
279 | up_v:='1';
280 | END IF;
281 | up<='1';
282 | END IF;
283 | END IF;
284 |
285 | diff_v:=shift_right(mfrac_ref,off_v);
286 | IF sign_v='0' THEN
287 | diff_v:=mfrac_ref + diff_v;
288 | ELSE
289 | diff_v:=mfrac_ref - diff_v;
290 | END IF;
291 |
292 | IF up_v='1' THEN
293 | mfrac<=diff_v;
294 | END IF;
295 |
296 | IF up_v='1' AND phm='0' THEN
297 | mfrac_ref<=diff_v;
298 | END IF;
299 |
300 | ------------------------------------------------------
301 | -- Update PLL registers
302 | mulco:=mfrac(40 DOWNTO 33) & (mfrac(40 DOWNTO 33) + ('0' & mfrac(32)));
303 |
304 | CASE state IS
305 | WHEN sIDLE =>
306 | pwrite<='0';
307 | IF up='1' THEN
308 | up<='0';
309 | IF mulco/=mul THEN
310 | state<=sW1;
311 | ELSE
312 | state<=sW3;
313 | END IF;
314 | END IF;
315 |
316 | WHEN sW1 => -- Change M multiplier
317 | mul<=mulco;
318 | pdata<=x"0000" & mulco;
319 | paddress<="000100";
320 | pwrite<='1';
321 | state<=sW2;
322 |
323 | WHEN sW2 =>
324 | IF pwrite='1' AND o_waitrequest='0' THEN
325 | state<=sW3;
326 | pwrite<='0';
327 | END IF;
328 |
329 | WHEN sW3 => -- Change M fractional value
330 | pdata<=mfrac(31 DOWNTO 0);
331 | paddress<="000111";
332 | pwrite<='1';
333 | state<=sW4;
334 |
335 | WHEN sW4 =>
336 | IF pwrite='1' AND o_waitrequest='0' THEN
337 | state<=sW5;
338 | pwrite<='0';
339 | END IF;
340 |
341 | WHEN sW5 =>
342 | pdata<=x"0000_0001";
343 | paddress<="000010";
344 | pwrite<='1';
345 | state<=sW6;
346 |
347 | WHEN sW6 =>
348 | IF pwrite='1' AND o_waitrequest='0' THEN
349 | pwrite<='0';
350 | state<=sIDLE;
351 | END IF;
352 | END CASE;
353 |
354 | END IF;
355 | END PROCESS Schmurtz;
356 |
357 | ----------------------------------------------------------------------------
358 |
359 | END ARCHITECTURE rtl;
360 |
361 |
--------------------------------------------------------------------------------
/sys/sysmem.sv:
--------------------------------------------------------------------------------
1 | `timescale 1 ps / 1 ps
2 | module sysmem_lite
3 | (
4 | output clock,
5 | output reset_out,
6 |
7 | input reset_hps_cold_req,
8 | input reset_hps_warm_req,
9 | input reset_core_req,
10 |
11 | input ram1_clk,
12 | input [28:0] ram1_address,
13 | input [7:0] ram1_burstcount,
14 | output ram1_waitrequest,
15 | output [63:0] ram1_readdata,
16 | output ram1_readdatavalid,
17 | input ram1_read,
18 | input [63:0] ram1_writedata,
19 | input [7:0] ram1_byteenable,
20 | input ram1_write,
21 |
22 | input ram2_clk,
23 | input [28:0] ram2_address,
24 | input [7:0] ram2_burstcount,
25 | output ram2_waitrequest,
26 | output [63:0] ram2_readdata,
27 | output ram2_readdatavalid,
28 | input ram2_read,
29 | input [63:0] ram2_writedata,
30 | input [7:0] ram2_byteenable,
31 | input ram2_write,
32 |
33 | input vbuf_clk,
34 | input [27:0] vbuf_address,
35 | input [7:0] vbuf_burstcount,
36 | output vbuf_waitrequest,
37 | output [127:0] vbuf_readdata,
38 | output vbuf_readdatavalid,
39 | input vbuf_read,
40 | input [127:0] vbuf_writedata,
41 | input [15:0] vbuf_byteenable,
42 | input vbuf_write
43 | );
44 |
45 | assign reset_out = ~init_reset_n | ~hps_h2f_reset_n | reset_core_req;
46 |
47 | sysmem_HPS_fpga_interfaces fpga_interfaces (
48 | .f2h_cold_rst_req_n (~reset_hps_cold_req),
49 | .f2h_warm_rst_req_n (~reset_hps_warm_req),
50 | .h2f_user0_clk (clock),
51 | .h2f_rst_n (hps_h2f_reset_n),
52 | .f2h_sdram0_clk (vbuf_clk),
53 | .f2h_sdram0_ADDRESS (vbuf_address),
54 | .f2h_sdram0_BURSTCOUNT (vbuf_burstcount),
55 | .f2h_sdram0_WAITREQUEST (vbuf_waitrequest),
56 | .f2h_sdram0_READDATA (vbuf_readdata),
57 | .f2h_sdram0_READDATAVALID (vbuf_readdatavalid),
58 | .f2h_sdram0_READ (vbuf_read),
59 | .f2h_sdram0_WRITEDATA (vbuf_writedata),
60 | .f2h_sdram0_BYTEENABLE (vbuf_byteenable),
61 | .f2h_sdram0_WRITE (vbuf_write),
62 | .f2h_sdram1_clk (ram1_clk),
63 | .f2h_sdram1_ADDRESS (ram1_address),
64 | .f2h_sdram1_BURSTCOUNT (ram1_burstcount),
65 | .f2h_sdram1_WAITREQUEST (ram1_waitrequest),
66 | .f2h_sdram1_READDATA (ram1_readdata),
67 | .f2h_sdram1_READDATAVALID (ram1_readdatavalid),
68 | .f2h_sdram1_READ (ram1_read),
69 | .f2h_sdram1_WRITEDATA (ram1_writedata),
70 | .f2h_sdram1_BYTEENABLE (ram1_byteenable),
71 | .f2h_sdram1_WRITE (ram1_write),
72 | .f2h_sdram2_clk (ram2_clk),
73 | .f2h_sdram2_ADDRESS (ram2_address),
74 | .f2h_sdram2_BURSTCOUNT (ram2_burstcount),
75 | .f2h_sdram2_WAITREQUEST (ram2_waitrequest),
76 | .f2h_sdram2_READDATA (ram2_readdata),
77 | .f2h_sdram2_READDATAVALID (ram2_readdatavalid),
78 | .f2h_sdram2_READ (ram2_read),
79 | .f2h_sdram2_WRITEDATA (ram2_writedata),
80 | .f2h_sdram2_BYTEENABLE (ram2_byteenable),
81 | .f2h_sdram2_WRITE (ram2_write)
82 | );
83 |
84 | wire hps_h2f_reset_n;
85 |
86 | reg init_reset_n = 0;
87 | always @(posedge clock) begin
88 | integer timeout = 0;
89 |
90 | if(timeout < 2000000) begin
91 | init_reset_n <= 0;
92 | timeout <= timeout + 1;
93 | end
94 | else init_reset_n <= 1;
95 | end
96 |
97 | endmodule
98 |
99 |
100 | module sysmem_HPS_fpga_interfaces
101 | (
102 | // h2f_reset
103 | output wire [1 - 1 : 0 ] h2f_rst_n
104 |
105 | // f2h_cold_reset_req
106 | ,input wire [1 - 1 : 0 ] f2h_cold_rst_req_n
107 |
108 | // f2h_warm_reset_req
109 | ,input wire [1 - 1 : 0 ] f2h_warm_rst_req_n
110 |
111 | // h2f_user0_clock
112 | ,output wire [1 - 1 : 0 ] h2f_user0_clk
113 |
114 | // f2h_sdram0_data
115 | ,input wire [28 - 1 : 0 ] f2h_sdram0_ADDRESS
116 | ,input wire [8 - 1 : 0 ] f2h_sdram0_BURSTCOUNT
117 | ,output wire [1 - 1 : 0 ] f2h_sdram0_WAITREQUEST
118 | ,output wire [128 - 1 : 0 ] f2h_sdram0_READDATA
119 | ,output wire [1 - 1 : 0 ] f2h_sdram0_READDATAVALID
120 | ,input wire [1 - 1 : 0 ] f2h_sdram0_READ
121 | ,input wire [128 - 1 : 0 ] f2h_sdram0_WRITEDATA
122 | ,input wire [16 - 1 : 0 ] f2h_sdram0_BYTEENABLE
123 | ,input wire [1 - 1 : 0 ] f2h_sdram0_WRITE
124 |
125 | // f2h_sdram0_clock
126 | ,input wire [1 - 1 : 0 ] f2h_sdram0_clk
127 |
128 | // f2h_sdram1_data
129 | ,input wire [29 - 1 : 0 ] f2h_sdram1_ADDRESS
130 | ,input wire [8 - 1 : 0 ] f2h_sdram1_BURSTCOUNT
131 | ,output wire [1 - 1 : 0 ] f2h_sdram1_WAITREQUEST
132 | ,output wire [64 - 1 : 0 ] f2h_sdram1_READDATA
133 | ,output wire [1 - 1 : 0 ] f2h_sdram1_READDATAVALID
134 | ,input wire [1 - 1 : 0 ] f2h_sdram1_READ
135 | ,input wire [64 - 1 : 0 ] f2h_sdram1_WRITEDATA
136 | ,input wire [8 - 1 : 0 ] f2h_sdram1_BYTEENABLE
137 | ,input wire [1 - 1 : 0 ] f2h_sdram1_WRITE
138 |
139 | // f2h_sdram1_clock
140 | ,input wire [1 - 1 : 0 ] f2h_sdram1_clk
141 |
142 | // f2h_sdram2_data
143 | ,input wire [29 - 1 : 0 ] f2h_sdram2_ADDRESS
144 | ,input wire [8 - 1 : 0 ] f2h_sdram2_BURSTCOUNT
145 | ,output wire [1 - 1 : 0 ] f2h_sdram2_WAITREQUEST
146 | ,output wire [64 - 1 : 0 ] f2h_sdram2_READDATA
147 | ,output wire [1 - 1 : 0 ] f2h_sdram2_READDATAVALID
148 | ,input wire [1 - 1 : 0 ] f2h_sdram2_READ
149 | ,input wire [64 - 1 : 0 ] f2h_sdram2_WRITEDATA
150 | ,input wire [8 - 1 : 0 ] f2h_sdram2_BYTEENABLE
151 | ,input wire [1 - 1 : 0 ] f2h_sdram2_WRITE
152 |
153 | // f2h_sdram2_clock
154 | ,input wire [1 - 1 : 0 ] f2h_sdram2_clk
155 | );
156 |
157 |
158 | wire [29 - 1 : 0] intermediate;
159 | assign intermediate[0:0] = ~intermediate[1:1];
160 | assign intermediate[8:8] = intermediate[4:4]|intermediate[7:7];
161 | assign intermediate[2:2] = intermediate[9:9];
162 | assign intermediate[3:3] = intermediate[9:9];
163 | assign intermediate[5:5] = intermediate[9:9];
164 | assign intermediate[6:6] = intermediate[9:9];
165 | assign intermediate[10:10] = intermediate[9:9];
166 | assign intermediate[11:11] = ~intermediate[12:12];
167 | assign intermediate[17:17] = intermediate[14:14]|intermediate[16:16];
168 | assign intermediate[13:13] = intermediate[18:18];
169 | assign intermediate[15:15] = intermediate[18:18];
170 | assign intermediate[19:19] = intermediate[18:18];
171 | assign intermediate[20:20] = ~intermediate[21:21];
172 | assign intermediate[26:26] = intermediate[23:23]|intermediate[25:25];
173 | assign intermediate[22:22] = intermediate[27:27];
174 | assign intermediate[24:24] = intermediate[27:27];
175 | assign intermediate[28:28] = intermediate[27:27];
176 | assign f2h_sdram0_WAITREQUEST[0:0] = intermediate[0:0];
177 | assign f2h_sdram1_WAITREQUEST[0:0] = intermediate[11:11];
178 | assign f2h_sdram2_WAITREQUEST[0:0] = intermediate[20:20];
179 | assign intermediate[4:4] = f2h_sdram0_READ[0:0];
180 | assign intermediate[7:7] = f2h_sdram0_WRITE[0:0];
181 | assign intermediate[9:9] = f2h_sdram0_clk[0:0];
182 | assign intermediate[14:14] = f2h_sdram1_READ[0:0];
183 | assign intermediate[16:16] = f2h_sdram1_WRITE[0:0];
184 | assign intermediate[18:18] = f2h_sdram1_clk[0:0];
185 | assign intermediate[23:23] = f2h_sdram2_READ[0:0];
186 | assign intermediate[25:25] = f2h_sdram2_WRITE[0:0];
187 | assign intermediate[27:27] = f2h_sdram2_clk[0:0];
188 |
189 | cyclonev_hps_interface_clocks_resets clocks_resets(
190 | .f2h_warm_rst_req_n({
191 | f2h_warm_rst_req_n[0:0] // 0:0
192 | })
193 | ,.f2h_pending_rst_ack({
194 | 1'b1 // 0:0
195 | })
196 | ,.f2h_dbg_rst_req_n({
197 | 1'b1 // 0:0
198 | })
199 | ,.h2f_rst_n({
200 | h2f_rst_n[0:0] // 0:0
201 | })
202 | ,.f2h_cold_rst_req_n({
203 | f2h_cold_rst_req_n[0:0] // 0:0
204 | })
205 | ,.h2f_user0_clk({
206 | h2f_user0_clk[0:0] // 0:0
207 | })
208 | );
209 |
210 |
211 | cyclonev_hps_interface_dbg_apb debug_apb(
212 | .DBG_APB_DISABLE({
213 | 1'b0 // 0:0
214 | })
215 | ,.P_CLK_EN({
216 | 1'b0 // 0:0
217 | })
218 | );
219 |
220 |
221 | cyclonev_hps_interface_tpiu_trace tpiu(
222 | .traceclk_ctl({
223 | 1'b1 // 0:0
224 | })
225 | );
226 |
227 |
228 | cyclonev_hps_interface_boot_from_fpga boot_from_fpga(
229 | .boot_from_fpga_ready({
230 | 1'b0 // 0:0
231 | })
232 | ,.boot_from_fpga_on_failure({
233 | 1'b0 // 0:0
234 | })
235 | ,.bsel_en({
236 | 1'b0 // 0:0
237 | })
238 | ,.csel_en({
239 | 1'b0 // 0:0
240 | })
241 | ,.csel({
242 | 2'b01 // 1:0
243 | })
244 | ,.bsel({
245 | 3'b001 // 2:0
246 | })
247 | );
248 |
249 |
250 | cyclonev_hps_interface_fpga2hps fpga2hps(
251 | .port_size_config({
252 | 2'b11 // 1:0
253 | })
254 | );
255 |
256 |
257 | cyclonev_hps_interface_hps2fpga hps2fpga(
258 | .port_size_config({
259 | 2'b11 // 1:0
260 | })
261 | );
262 |
263 |
264 | cyclonev_hps_interface_fpga2sdram f2sdram(
265 | .cfg_rfifo_cport_map({
266 | 16'b0010000100000000 // 15:0
267 | })
268 | ,.cfg_wfifo_cport_map({
269 | 16'b0010000100000000 // 15:0
270 | })
271 | ,.rd_ready_3({
272 | 1'b1 // 0:0
273 | })
274 | ,.cmd_port_clk_2({
275 | intermediate[28:28] // 0:0
276 | })
277 | ,.rd_ready_2({
278 | 1'b1 // 0:0
279 | })
280 | ,.cmd_port_clk_1({
281 | intermediate[19:19] // 0:0
282 | })
283 | ,.rd_ready_1({
284 | 1'b1 // 0:0
285 | })
286 | ,.cmd_port_clk_0({
287 | intermediate[10:10] // 0:0
288 | })
289 | ,.rd_ready_0({
290 | 1'b1 // 0:0
291 | })
292 | ,.wrack_ready_2({
293 | 1'b1 // 0:0
294 | })
295 | ,.wrack_ready_1({
296 | 1'b1 // 0:0
297 | })
298 | ,.wrack_ready_0({
299 | 1'b1 // 0:0
300 | })
301 | ,.cmd_ready_2({
302 | intermediate[21:21] // 0:0
303 | })
304 | ,.cmd_ready_1({
305 | intermediate[12:12] // 0:0
306 | })
307 | ,.cmd_ready_0({
308 | intermediate[1:1] // 0:0
309 | })
310 | ,.cfg_port_width({
311 | 12'b000000010110 // 11:0
312 | })
313 | ,.rd_valid_3({
314 | f2h_sdram2_READDATAVALID[0:0] // 0:0
315 | })
316 | ,.rd_valid_2({
317 | f2h_sdram1_READDATAVALID[0:0] // 0:0
318 | })
319 | ,.rd_valid_1({
320 | f2h_sdram0_READDATAVALID[0:0] // 0:0
321 | })
322 | ,.rd_clk_3({
323 | intermediate[22:22] // 0:0
324 | })
325 | ,.rd_data_3({
326 | f2h_sdram2_READDATA[63:0] // 63:0
327 | })
328 | ,.rd_clk_2({
329 | intermediate[13:13] // 0:0
330 | })
331 | ,.rd_data_2({
332 | f2h_sdram1_READDATA[63:0] // 63:0
333 | })
334 | ,.rd_clk_1({
335 | intermediate[3:3] // 0:0
336 | })
337 | ,.rd_data_1({
338 | f2h_sdram0_READDATA[127:64] // 63:0
339 | })
340 | ,.rd_clk_0({
341 | intermediate[2:2] // 0:0
342 | })
343 | ,.rd_data_0({
344 | f2h_sdram0_READDATA[63:0] // 63:0
345 | })
346 | ,.cfg_axi_mm_select({
347 | 6'b000000 // 5:0
348 | })
349 | ,.cmd_valid_2({
350 | intermediate[26:26] // 0:0
351 | })
352 | ,.cmd_valid_1({
353 | intermediate[17:17] // 0:0
354 | })
355 | ,.cmd_valid_0({
356 | intermediate[8:8] // 0:0
357 | })
358 | ,.cfg_cport_rfifo_map({
359 | 18'b000000000011010000 // 17:0
360 | })
361 | ,.wr_data_3({
362 | 2'b00 // 89:88
363 | ,f2h_sdram2_BYTEENABLE[7:0] // 87:80
364 | ,16'b0000000000000000 // 79:64
365 | ,f2h_sdram2_WRITEDATA[63:0] // 63:0
366 | })
367 | ,.wr_data_2({
368 | 2'b00 // 89:88
369 | ,f2h_sdram1_BYTEENABLE[7:0] // 87:80
370 | ,16'b0000000000000000 // 79:64
371 | ,f2h_sdram1_WRITEDATA[63:0] // 63:0
372 | })
373 | ,.wr_data_1({
374 | 2'b00 // 89:88
375 | ,f2h_sdram0_BYTEENABLE[15:8] // 87:80
376 | ,16'b0000000000000000 // 79:64
377 | ,f2h_sdram0_WRITEDATA[127:64] // 63:0
378 | })
379 | ,.cfg_cport_type({
380 | 12'b000000111111 // 11:0
381 | })
382 | ,.wr_data_0({
383 | 2'b00 // 89:88
384 | ,f2h_sdram0_BYTEENABLE[7:0] // 87:80
385 | ,16'b0000000000000000 // 79:64
386 | ,f2h_sdram0_WRITEDATA[63:0] // 63:0
387 | })
388 | ,.cfg_cport_wfifo_map({
389 | 18'b000000000011010000 // 17:0
390 | })
391 | ,.wr_clk_3({
392 | intermediate[24:24] // 0:0
393 | })
394 | ,.wr_clk_2({
395 | intermediate[15:15] // 0:0
396 | })
397 | ,.wr_clk_1({
398 | intermediate[6:6] // 0:0
399 | })
400 | ,.wr_clk_0({
401 | intermediate[5:5] // 0:0
402 | })
403 | ,.cmd_data_2({
404 | 18'b000000000000000000 // 59:42
405 | ,f2h_sdram2_BURSTCOUNT[7:0] // 41:34
406 | ,3'b000 // 33:31
407 | ,f2h_sdram2_ADDRESS[28:0] // 30:2
408 | ,intermediate[25:25] // 1:1
409 | ,intermediate[23:23] // 0:0
410 | })
411 | ,.cmd_data_1({
412 | 18'b000000000000000000 // 59:42
413 | ,f2h_sdram1_BURSTCOUNT[7:0] // 41:34
414 | ,3'b000 // 33:31
415 | ,f2h_sdram1_ADDRESS[28:0] // 30:2
416 | ,intermediate[16:16] // 1:1
417 | ,intermediate[14:14] // 0:0
418 | })
419 | ,.cmd_data_0({
420 | 18'b000000000000000000 // 59:42
421 | ,f2h_sdram0_BURSTCOUNT[7:0] // 41:34
422 | ,4'b0000 // 33:30
423 | ,f2h_sdram0_ADDRESS[27:0] // 29:2
424 | ,intermediate[7:7] // 1:1
425 | ,intermediate[4:4] // 0:0
426 | })
427 | );
428 |
429 | endmodule
430 |
--------------------------------------------------------------------------------
/sys/hq2x.sv:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // Copyright (c) 2012-2013 Ludvig Strigeus
4 | // Copyright (c) 2017,2018 Sorgelig
5 | //
6 | // This program is GPL Licensed. See COPYING for the full license.
7 | //
8 | //
9 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
10 |
11 | // synopsys translate_off
12 | `timescale 1 ps / 1 ps
13 | // synopsys translate_on
14 |
15 | module Hq2x #(parameter LENGTH, parameter HALF_DEPTH)
16 | (
17 | input clk,
18 | input ce_x4,
19 | input [DWIDTH:0] inputpixel,
20 | input mono,
21 | input disable_hq2x,
22 | input reset_frame,
23 | input reset_line,
24 | input [1:0] read_y,
25 | input hblank,
26 | output [DWIDTH:0] outpixel
27 | );
28 |
29 |
30 | localparam AWIDTH = $clog2(LENGTH)-1;
31 | localparam DWIDTH = HALF_DEPTH ? 11 : 23;
32 | localparam DWIDTH1 = DWIDTH+1;
33 |
34 | wire [5:0] hqTable[256] = '{
35 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
36 | 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
37 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
38 | 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
39 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
40 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
41 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
42 | 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
43 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
44 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
45 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
46 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
47 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
48 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
49 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
50 | 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
51 | };
52 |
53 | reg [23:0] Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2;
54 | reg [23:0] A, B, D, F, G, H;
55 | reg [7:0] pattern, nextpatt;
56 | reg [1:0] cyc;
57 |
58 | reg curbuf;
59 | reg prevbuf = 0;
60 | wire iobuf = !curbuf;
61 |
62 | wire diff0, diff1;
63 | DiffCheck diffcheck0(Curr1, (cyc == 0) ? Prev0 : (cyc == 1) ? Curr0 : (cyc == 2) ? Prev2 : Next1, diff0);
64 | DiffCheck diffcheck1(Curr1, (cyc == 0) ? Prev1 : (cyc == 1) ? Next0 : (cyc == 2) ? Curr2 : Next2, diff1);
65 |
66 | wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]};
67 |
68 | wire [23:0] X = (cyc == 0) ? A : (cyc == 1) ? Prev1 : (cyc == 2) ? Next1 : G;
69 | wire [23:0] blend_result_pre;
70 | Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result_pre);
71 |
72 | wire [DWIDTH:0] Curr20tmp;
73 | wire [23:0] Curr20 = HALF_DEPTH ? h2rgb(Curr20tmp) : Curr20tmp;
74 | wire [DWIDTH:0] Curr21tmp;
75 | wire [23:0] Curr21 = HALF_DEPTH ? h2rgb(Curr21tmp) : Curr21tmp;
76 |
77 | reg [AWIDTH:0] wrin_addr2;
78 | reg [DWIDTH:0] wrpix;
79 | reg wrin_en;
80 |
81 | function [23:0] h2rgb;
82 | input [11:0] v;
83 | begin
84 | h2rgb = mono ? {v[7:0], v[7:0], v[7:0]} : {v[11:8],v[11:8],v[7:4],v[7:4],v[3:0],v[3:0]};
85 | end
86 | endfunction
87 |
88 | function [11:0] rgb2h;
89 | input [23:0] v;
90 | begin
91 | rgb2h = mono ? {4'b0000, v[23:20], v[19:16]} : {v[23:20], v[15:12], v[7:4]};
92 | end
93 | endfunction
94 |
95 | hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in
96 | (
97 | .clk(clk),
98 |
99 | .rdaddr(offs),
100 | .rdbuf0(prevbuf),
101 | .rdbuf1(curbuf),
102 | .q0(Curr20tmp),
103 | .q1(Curr21tmp),
104 |
105 | .wraddr(wrin_addr2),
106 | .wrbuf(iobuf),
107 | .data(wrpix),
108 | .wren(wrin_en)
109 | );
110 |
111 | reg [AWIDTH+1:0] read_x;
112 | reg [AWIDTH+1:0] wrout_addr;
113 | reg wrout_en;
114 | reg [DWIDTH1*4-1:0] wrdata, wrdata_pre;
115 | wire [DWIDTH1*4-1:0] outpixel_x4;
116 | reg [DWIDTH1*2-1:0] outpixel_x2;
117 |
118 | assign outpixel = read_x[0] ? outpixel_x2[DWIDTH1*2-1:DWIDTH1] : outpixel_x2[DWIDTH:0];
119 |
120 | hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH+1), .DWIDTH(DWIDTH1*4-1)) hq2x_out
121 | (
122 | .clock(clk),
123 |
124 | .rdaddress({read_x[AWIDTH+1:1],read_y[1]}),
125 | .q(outpixel_x4),
126 |
127 | .data(wrdata),
128 | .wraddress(wrout_addr),
129 | .wren(wrout_en)
130 | );
131 |
132 | wire [DWIDTH:0] blend_result = HALF_DEPTH ? rgb2h(blend_result_pre) : blend_result_pre[DWIDTH:0];
133 |
134 | reg [AWIDTH:0] offs;
135 | always @(posedge clk) begin
136 | reg old_reset_line;
137 | reg old_reset_frame;
138 |
139 | wrout_en <= 0;
140 | wrin_en <= 0;
141 |
142 | if(ce_x4) begin
143 |
144 | pattern <= new_pattern;
145 | if(read_x[0]) outpixel_x2 <= read_y[0] ? outpixel_x4[DWIDTH1*4-1:DWIDTH1*2] : outpixel_x4[DWIDTH1*2-1:0];
146 |
147 | if(~&offs) begin
148 | if (cyc == 1) begin
149 | Prev2 <= Curr20;
150 | Curr2 <= Curr21;
151 | Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel;
152 | wrpix <= inputpixel;
153 | wrin_addr2 <= offs;
154 | wrin_en <= 1;
155 | end
156 |
157 | case({cyc[1],^cyc})
158 | 0: wrdata[DWIDTH:0] <= blend_result;
159 | 1: wrdata[DWIDTH1+DWIDTH:DWIDTH1] <= blend_result;
160 | 2: wrdata[DWIDTH1*2+DWIDTH:DWIDTH1*2] <= blend_result;
161 | 3: wrdata[DWIDTH1*3+DWIDTH:DWIDTH1*3] <= blend_result;
162 | endcase
163 |
164 | if(cyc==3) begin
165 | offs <= offs + 1'd1;
166 | wrout_addr <= {offs, curbuf};
167 | wrout_en <= 1;
168 | end
169 | end
170 |
171 | if(cyc==3) begin
172 | nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]};
173 | {A, G} <= {Prev0, Next0};
174 | {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0};
175 | {Prev0, Prev1} <= {Prev1, Prev2};
176 | {Curr0, Curr1} <= {Curr1, Curr2};
177 | {Next0, Next1} <= {Next1, Next2};
178 | end else begin
179 | nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]};
180 | {B, F, H, D} <= {F, H, D, B};
181 | end
182 |
183 | cyc <= cyc + 1'b1;
184 | if(old_reset_line && ~reset_line) begin
185 | old_reset_frame <= reset_frame;
186 | offs <= 0;
187 | cyc <= 0;
188 | curbuf <= ~curbuf;
189 | prevbuf <= curbuf;
190 | {Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2} <= '0;
191 | if(old_reset_frame & ~reset_frame) begin
192 | curbuf <= 0;
193 | prevbuf <= 0;
194 | end
195 | end
196 |
197 | if(~hblank & ~&read_x) read_x <= read_x + 1'd1;
198 | if(hblank) read_x <= 0;
199 |
200 | old_reset_line <= reset_line;
201 | end
202 | end
203 |
204 | endmodule
205 |
206 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
207 |
208 | module hq2x_in #(parameter LENGTH, parameter DWIDTH)
209 | (
210 | input clk,
211 |
212 | input [AWIDTH:0] rdaddr,
213 | input rdbuf0, rdbuf1,
214 | output[DWIDTH:0] q0,q1,
215 |
216 | input [AWIDTH:0] wraddr,
217 | input wrbuf,
218 | input [DWIDTH:0] data,
219 | input wren
220 | );
221 |
222 | localparam AWIDTH = $clog2(LENGTH)-1;
223 | wire [DWIDTH:0] out[2];
224 | assign q0 = out[rdbuf0];
225 | assign q1 = out[rdbuf1];
226 |
227 | hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
228 | hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
229 | endmodule
230 |
231 | module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH)
232 | (
233 | input clock,
234 | input [DWIDTH:0] data,
235 | input [AWIDTH:0] rdaddress,
236 | input [AWIDTH:0] wraddress,
237 | input wren,
238 | output logic [DWIDTH:0] q
239 | );
240 |
241 | logic [DWIDTH:0] ram[0:NUMWORDS-1];
242 |
243 | always_ff@(posedge clock) begin
244 | if(wren) ram[wraddress] <= data;
245 | q <= ram[rdaddress];
246 | end
247 |
248 | endmodule
249 |
250 | ////////////////////////////////////////////////////////////////////////////////////////////////////////
251 |
252 | module DiffCheck
253 | (
254 | input [23:0] rgb1,
255 | input [23:0] rgb2,
256 | output result
257 | );
258 |
259 | wire [7:0] r = rgb1[7:1] - rgb2[7:1];
260 | wire [7:0] g = rgb1[15:9] - rgb2[15:9];
261 | wire [7:0] b = rgb1[23:17] - rgb2[23:17];
262 | wire [8:0] t = $signed(r) + $signed(b);
263 | wire [8:0] gx = {g[7], g};
264 | wire [9:0] y = $signed(t) + $signed(gx);
265 | wire [8:0] u = $signed(r) - $signed(b);
266 | wire [9:0] v = $signed({g, 1'b0}) - $signed(t);
267 |
268 | // if y is inside (-96..96)
269 | wire y_inside = (y < 10'h60 || y >= 10'h3a0);
270 |
271 | // if u is inside (-16, 16)
272 | wire u_inside = (u < 9'h10 || u >= 9'h1f0);
273 |
274 | // if v is inside (-24, 24)
275 | wire v_inside = (v < 10'h18 || v >= 10'h3e8);
276 | assign result = !(y_inside && u_inside && v_inside);
277 | endmodule
278 |
279 | module InnerBlend
280 | (
281 | input [8:0] Op,
282 | input [7:0] A,
283 | input [7:0] B,
284 | input [7:0] C,
285 | output [7:0] O
286 | );
287 |
288 | function [10:0] mul8x3;
289 | input [7:0] op1;
290 | input [2:0] op2;
291 | begin
292 | mul8x3 = 11'd0;
293 | if(op2[0]) mul8x3 = mul8x3 + op1;
294 | if(op2[1]) mul8x3 = mul8x3 + {op1, 1'b0};
295 | if(op2[2]) mul8x3 = mul8x3 + {op1, 2'b00};
296 | end
297 | endfunction
298 |
299 | wire OpOnes = Op[4];
300 | wire [10:0] Amul = mul8x3(A, Op[7:5]);
301 | wire [10:0] Bmul = mul8x3(B, {Op[3:2], 1'b0});
302 | wire [10:0] Cmul = mul8x3(C, {Op[1:0], 1'b0});
303 | wire [10:0] At = Amul;
304 | wire [10:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B};
305 | wire [10:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C};
306 | wire [11:0] Res = {At, 1'b0} + Bt + Ct;
307 | assign O = Op[8] ? A : Res[11:4];
308 | endmodule
309 |
310 | module Blend
311 | (
312 | input [5:0] rule,
313 | input disable_hq2x,
314 | input [23:0] E,
315 | input [23:0] A,
316 | input [23:0] B,
317 | input [23:0] D,
318 | input [23:0] F,
319 | input [23:0] H,
320 | output [23:0] Result
321 | );
322 |
323 | reg [1:0] input_ctrl;
324 | reg [8:0] op;
325 | localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A
326 | localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4
327 | localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4
328 | localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4
329 | localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4
330 | localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4
331 | localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4
332 | localparam AB = 2'b00;
333 | localparam AD = 2'b01;
334 | localparam DB = 2'b10;
335 | localparam BD = 2'b11;
336 | wire is_diff;
337 | DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff);
338 |
339 | always @* begin
340 | case({!is_diff, rule[5:2]})
341 | 1,17: {op, input_ctrl} = {BLEND1, AB};
342 | 2,18: {op, input_ctrl} = {BLEND1, DB};
343 | 3,19: {op, input_ctrl} = {BLEND1, BD};
344 | 4,20: {op, input_ctrl} = {BLEND2, DB};
345 | 5,21: {op, input_ctrl} = {BLEND2, AB};
346 | 6,22: {op, input_ctrl} = {BLEND2, AD};
347 |
348 | 8: {op, input_ctrl} = {BLEND0, 2'bxx};
349 | 9: {op, input_ctrl} = {BLEND0, 2'bxx};
350 | 10: {op, input_ctrl} = {BLEND0, 2'bxx};
351 | 11: {op, input_ctrl} = {BLEND1, AB};
352 | 12: {op, input_ctrl} = {BLEND1, AB};
353 | 13: {op, input_ctrl} = {BLEND1, AB};
354 | 14: {op, input_ctrl} = {BLEND1, DB};
355 | 15: {op, input_ctrl} = {BLEND1, BD};
356 |
357 | 24: {op, input_ctrl} = {BLEND2, DB};
358 | 25: {op, input_ctrl} = {BLEND5, DB};
359 | 26: {op, input_ctrl} = {BLEND6, DB};
360 | 27: {op, input_ctrl} = {BLEND2, DB};
361 | 28: {op, input_ctrl} = {BLEND4, DB};
362 | 29: {op, input_ctrl} = {BLEND5, DB};
363 | 30: {op, input_ctrl} = {BLEND3, BD};
364 | 31: {op, input_ctrl} = {BLEND3, DB};
365 | default: {op, input_ctrl} = {11{1'bx}};
366 | endcase
367 |
368 | // Setting op[8] effectively disables HQ2X because blend will always return E.
369 | if (disable_hq2x) op[8] = 1;
370 | end
371 |
372 | // Generate inputs to the inner blender. Valid combinations.
373 | // 00: E A B
374 | // 01: E A D
375 | // 10: E D B
376 | // 11: E B D
377 | wire [23:0] Input1 = E;
378 | wire [23:0] Input2 = !input_ctrl[1] ? A :
379 | !input_ctrl[0] ? D : B;
380 |
381 | wire [23:0] Input3 = !input_ctrl[0] ? B : D;
382 | InnerBlend inner_blend1(op, Input1[7:0], Input2[7:0], Input3[7:0], Result[7:0]);
383 | InnerBlend inner_blend2(op, Input1[15:8], Input2[15:8], Input3[15:8], Result[15:8]);
384 | InnerBlend inner_blend3(op, Input1[23:16], Input2[23:16], Input3[23:16], Result[23:16]);
385 | endmodule
386 |
--------------------------------------------------------------------------------
/sys/spdif.v:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------
2 | // SPDIF Transmitter
3 | // V0.1
4 | // Ultra-Embedded.com
5 | // Copyright 2012
6 | //
7 | // Email: admin@ultra-embedded.com
8 | //
9 | // License: GPL
10 | // If you would like a version with a more permissive license for
11 | // use in closed source commercial applications please contact me
12 | // for details.
13 | //-----------------------------------------------------------------
14 | //
15 | // This file is open source HDL; you can redistribute it and/or
16 | // modify it under the terms of the GNU General Public License as
17 | // published by the Free Software Foundation; either version 2 of
18 | // the License, or (at your option) any later version.
19 | //
20 | // This file is distributed in the hope that it will be useful,
21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | // GNU General Public License for more details.
24 | //
25 | // You should have received a copy of the GNU General Public
26 | // License along with this file; if not, write to the Free Software
27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 | // USA
29 | //-----------------------------------------------------------------
30 | // altera message_off 10762
31 | // altera message_off 10240
32 |
33 | module spdif
34 |
35 | //-----------------------------------------------------------------
36 | // Params
37 | //-----------------------------------------------------------------
38 | #(
39 | parameter CLK_RATE = 50000000,
40 | parameter AUDIO_RATE = 48000,
41 |
42 | // Generated params
43 | parameter WHOLE_CYCLES = (CLK_RATE) / (AUDIO_RATE*128),
44 | parameter ERROR_BASE = 10000,
45 | parameter [63:0] ERRORS_PER_BIT = ((CLK_RATE * ERROR_BASE) / (AUDIO_RATE*128)) - (WHOLE_CYCLES * ERROR_BASE)
46 | )
47 |
48 | //-----------------------------------------------------------------
49 | // Ports
50 | //-----------------------------------------------------------------
51 | (
52 | input clk_i,
53 | input rst_i,
54 | input half_rate,
55 |
56 | // Output
57 | output spdif_o,
58 |
59 | // Audio interface (16-bit x 2 = RL)
60 | input [15:0] audio_r,
61 | input [15:0] audio_l,
62 | output sample_req_o
63 | );
64 |
65 | reg lpf_ce;
66 | always @(posedge clk_i) begin
67 | reg [2:0] div;
68 |
69 | if(bit_clk_q) div <= div + 1'd1;
70 | lpf_ce <= !div;
71 | end
72 |
73 | wire [15:0] al, ar;
74 |
75 | lpf_spdif lpf_l
76 | (
77 | .CLK(clk_i),
78 | .CE(lpf_ce),
79 | .IDATA(audio_l),
80 | .ODATA(al)
81 | );
82 |
83 | lpf_spdif lpf_r
84 | (
85 | .CLK(clk_i),
86 | .CE(lpf_ce),
87 |
88 | .IDATA(audio_r),
89 | .ODATA(ar)
90 | );
91 |
92 | reg bit_clk_q;
93 |
94 | // Clock pulse generator
95 | always @ (posedge rst_i or posedge clk_i) begin
96 | reg [31:0] count_q;
97 | reg [31:0] error_q;
98 | reg ce;
99 |
100 | if (rst_i) begin
101 | count_q <= 0;
102 | error_q <= 0;
103 | bit_clk_q <= 1;
104 | ce <= 0;
105 | end
106 | else
107 | begin
108 | if(count_q == WHOLE_CYCLES-1) begin
109 | if (error_q < (ERROR_BASE - ERRORS_PER_BIT)) begin
110 | error_q <= error_q + ERRORS_PER_BIT[31:0];
111 | count_q <= 0;
112 | end else begin
113 | error_q <= error_q + ERRORS_PER_BIT[31:0] - ERROR_BASE;
114 | count_q <= count_q + 1;
115 | end
116 | end else if(count_q == WHOLE_CYCLES) begin
117 | count_q <= 0;
118 | end else begin
119 | count_q <= count_q + 1;
120 | end
121 |
122 | bit_clk_q <= 0;
123 | if(!count_q) begin
124 | ce <= ~ce;
125 | if(~half_rate || ce) bit_clk_q <= 1;
126 | end
127 | end
128 | end
129 |
130 | //-----------------------------------------------------------------
131 | // Core SPDIF
132 | //-----------------------------------------------------------------
133 |
134 | wire [31:0] sample_i = {ar, al};
135 |
136 | spdif_core
137 | u_core
138 | (
139 | .clk_i(clk_i),
140 | .rst_i(rst_i),
141 |
142 | .bit_out_en_i(bit_clk_q),
143 |
144 | .spdif_o(spdif_o),
145 |
146 | .sample_i(sample_i),
147 | .sample_req_o(sample_req_o)
148 | );
149 |
150 | endmodule
151 |
152 | module spdif_core
153 | (
154 | input clk_i,
155 | input rst_i,
156 |
157 | // SPDIF bit output enable
158 | // Single cycle pulse synchronous to clk_i which drives
159 | // the output bit rate.
160 | // For 44.1KHz, 44100×32×2×2 = 5,644,800Hz
161 | // For 48KHz, 48000×32×2×2 = 6,144,000Hz
162 | input bit_out_en_i,
163 |
164 | // Output
165 | output spdif_o,
166 |
167 | // Audio interface (16-bit x 2 = RL)
168 | input [31:0] sample_i,
169 | output reg sample_req_o
170 | );
171 |
172 | //-----------------------------------------------------------------
173 | // Registers
174 | //-----------------------------------------------------------------
175 | reg [15:0] audio_sample_q;
176 | reg [8:0] subframe_count_q;
177 |
178 | reg load_subframe_q;
179 | reg [7:0] preamble_q;
180 | wire [31:0] subframe_w;
181 |
182 | reg [5:0] bit_count_q;
183 | reg bit_toggle_q;
184 |
185 | reg spdif_out_q;
186 |
187 | reg [5:0] parity_count_q;
188 |
189 | //-----------------------------------------------------------------
190 | // Subframe Counter
191 | //-----------------------------------------------------------------
192 | always @ (posedge rst_i or posedge clk_i )
193 | begin
194 | if (rst_i == 1'b1)
195 | subframe_count_q <= 9'd0;
196 | else if (load_subframe_q)
197 | begin
198 | // 192 frames (384 subframes) in an audio block
199 | if (subframe_count_q == 9'd383)
200 | subframe_count_q <= 9'd0;
201 | else
202 | subframe_count_q <= subframe_count_q + 9'd1;
203 | end
204 | end
205 |
206 | //-----------------------------------------------------------------
207 | // Sample capture
208 | //-----------------------------------------------------------------
209 | reg [15:0] sample_buf_q;
210 |
211 | always @ (posedge rst_i or posedge clk_i )
212 | begin
213 | if (rst_i == 1'b1)
214 | begin
215 | audio_sample_q <= 16'h0000;
216 | sample_buf_q <= 16'h0000;
217 | sample_req_o <= 1'b0;
218 | end
219 | else if (load_subframe_q)
220 | begin
221 | // Start of frame (first subframe)?
222 | if (subframe_count_q[0] == 1'b0)
223 | begin
224 | // Use left sample
225 | audio_sample_q <= sample_i[15:0];
226 |
227 | // Store right sample
228 | sample_buf_q <= sample_i[31:16];
229 |
230 | // Request next sample
231 | sample_req_o <= 1'b1;
232 | end
233 | else
234 | begin
235 | // Use right sample
236 | audio_sample_q <= sample_buf_q;
237 |
238 | sample_req_o <= 1'b0;
239 | end
240 | end
241 | else
242 | sample_req_o <= 1'b0;
243 | end
244 |
245 | // Timeslots 3 - 0 = Preamble
246 | assign subframe_w[3:0] = 4'b0000;
247 |
248 | // Timeslots 7 - 4 = 24-bit audio LSB
249 | assign subframe_w[7:4] = 4'b0000;
250 |
251 | // Timeslots 11 - 8 = 20-bit audio LSB
252 | assign subframe_w[11:8] = 4'b0000;
253 |
254 | // Timeslots 27 - 12 = 16-bit audio
255 | assign subframe_w[27:12] = audio_sample_q;
256 |
257 | // Timeslots 28 = Validity
258 | assign subframe_w[28] = 1'b0; // Valid
259 |
260 | // Timeslots 29 = User bit
261 | assign subframe_w[29] = 1'b0;
262 |
263 | // Timeslots 30 = Channel status bit
264 | assign subframe_w[30] = 1'b0;
265 |
266 | // Timeslots 31 = Even Parity bit (31:4)
267 | assign subframe_w[31] = 1'b0;
268 |
269 | //-----------------------------------------------------------------
270 | // Preamble
271 | //-----------------------------------------------------------------
272 | localparam PREAMBLE_Z = 8'b00010111;
273 | localparam PREAMBLE_Y = 8'b00100111;
274 | localparam PREAMBLE_X = 8'b01000111;
275 |
276 | reg [7:0] preamble_r;
277 |
278 | always @ *
279 | begin
280 | // Start of audio block?
281 | // Z(B) - Left channel
282 | if (subframe_count_q == 9'd0)
283 | preamble_r = PREAMBLE_Z; // Z(B)
284 | // Right Channel?
285 | else if (subframe_count_q[0] == 1'b1)
286 | preamble_r = PREAMBLE_Y; // Y(W)
287 | // Left Channel (but not start of block)?
288 | else
289 | preamble_r = PREAMBLE_X; // X(M)
290 | end
291 |
292 | always @ (posedge rst_i or posedge clk_i )
293 | if (rst_i == 1'b1)
294 | preamble_q <= 8'h00;
295 | else if (load_subframe_q)
296 | preamble_q <= preamble_r;
297 |
298 | //-----------------------------------------------------------------
299 | // Parity Counter
300 | //-----------------------------------------------------------------
301 | always @ (posedge rst_i or posedge clk_i )
302 | begin
303 | if (rst_i == 1'b1)
304 | begin
305 | parity_count_q <= 6'd0;
306 | end
307 | // Time to output a bit?
308 | else if (bit_out_en_i)
309 | begin
310 | // Preamble bits?
311 | if (bit_count_q < 6'd8)
312 | begin
313 | parity_count_q <= 6'd0;
314 | end
315 | // Normal timeslots
316 | else if (bit_count_q < 6'd62)
317 | begin
318 | // On first pass through this timeslot, count number of high bits
319 | if (bit_count_q[0] == 0 && subframe_w[bit_count_q / 2] == 1'b1)
320 | parity_count_q <= parity_count_q + 6'd1;
321 | end
322 | end
323 | end
324 |
325 | //-----------------------------------------------------------------
326 | // Bit Counter
327 | //-----------------------------------------------------------------
328 | always @ (posedge rst_i or posedge clk_i)
329 | begin
330 | if (rst_i == 1'b1)
331 | begin
332 | bit_count_q <= 6'b0;
333 | load_subframe_q <= 1'b1;
334 | end
335 | // Time to output a bit?
336 | else if (bit_out_en_i)
337 | begin
338 | // 32 timeslots (x2 for double frequency)
339 | if (bit_count_q == 6'd63)
340 | begin
341 | bit_count_q <= 6'd0;
342 | load_subframe_q <= 1'b1;
343 | end
344 | else
345 | begin
346 | bit_count_q <= bit_count_q + 6'd1;
347 | load_subframe_q <= 1'b0;
348 | end
349 | end
350 | else
351 | load_subframe_q <= 1'b0;
352 | end
353 |
354 | //-----------------------------------------------------------------
355 | // Bit half toggle
356 | //-----------------------------------------------------------------
357 | always @ (posedge rst_i or posedge clk_i)
358 | if (rst_i == 1'b1)
359 | bit_toggle_q <= 1'b0;
360 | // Time to output a bit?
361 | else if (bit_out_en_i)
362 | bit_toggle_q <= ~bit_toggle_q;
363 |
364 | //-----------------------------------------------------------------
365 | // Output bit (BMC encoded)
366 | //-----------------------------------------------------------------
367 | reg bit_r;
368 |
369 | always @ *
370 | begin
371 | bit_r = spdif_out_q;
372 |
373 | // Time to output a bit?
374 | if (bit_out_en_i)
375 | begin
376 | // Preamble bits?
377 | if (bit_count_q < 6'd8)
378 | begin
379 | bit_r = preamble_q[bit_count_q[2:0]];
380 | end
381 | // Normal timeslots
382 | else if (bit_count_q < 6'd62)
383 | begin
384 | if (subframe_w[bit_count_q / 2] == 1'b0)
385 | begin
386 | if (bit_toggle_q == 1'b0)
387 | bit_r = ~spdif_out_q;
388 | else
389 | bit_r = spdif_out_q;
390 | end
391 | else
392 | bit_r = ~spdif_out_q;
393 | end
394 | // Parity timeslot
395 | else
396 | begin
397 | // Even number of high bits, make odd
398 | if (parity_count_q[0] == 1'b0)
399 | begin
400 | if (bit_toggle_q == 1'b0)
401 | bit_r = ~spdif_out_q;
402 | else
403 | bit_r = spdif_out_q;
404 | end
405 | else
406 | bit_r = ~spdif_out_q;
407 | end
408 | end
409 | end
410 |
411 | always @ (posedge rst_i or posedge clk_i )
412 | if (rst_i == 1'b1)
413 | spdif_out_q <= 1'b0;
414 | else
415 | spdif_out_q <= bit_r;
416 |
417 | assign spdif_o = spdif_out_q;
418 |
419 | endmodule
420 |
421 | module lpf_spdif
422 | (
423 | input CLK,
424 | input CE,
425 | input [15:0] IDATA,
426 | output reg [15:0] ODATA
427 | );
428 |
429 | reg [511:0] acc;
430 | reg [20:0] sum;
431 |
432 | always @(*) begin
433 | integer i;
434 | sum = 0;
435 | for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]};
436 | end
437 |
438 | always @(posedge CLK) begin
439 | if(CE) begin
440 | acc <= {acc[495:0], IDATA};
441 | ODATA <= sum[20:5];
442 | end
443 | end
444 |
445 | endmodule
446 |
--------------------------------------------------------------------------------
/src/cpu/tv80_alu.v:
--------------------------------------------------------------------------------
1 | //
2 | // TV80 8-Bit Microprocessor Core
3 | // Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
4 | //
5 | // Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a
8 | // copy of this software and associated documentation files (the "Software"),
9 | // to deal in the Software without restriction, including without limitation
10 | // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 | // and/or sell copies of the Software, and to permit persons to whom the
12 | // Software is furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included
15 | // in all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | module tv80_alu (/*AUTOARG*/
26 | // Outputs
27 | Q, F_Out,
28 | // Inputs
29 | Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In
30 | );
31 |
32 | parameter Mode = 0;
33 | parameter Flag_C = 0;
34 | parameter Flag_N = 1;
35 | parameter Flag_P = 2;
36 | parameter Flag_X = 3;
37 | parameter Flag_H = 4;
38 | parameter Flag_Y = 5;
39 | parameter Flag_Z = 6;
40 | parameter Flag_S = 7;
41 |
42 | input Arith16;
43 | input Z16;
44 | input [3:0] ALU_Op ;
45 | input [5:0] IR;
46 | input [1:0] ISet;
47 | input [7:0] BusA;
48 | input [7:0] BusB;
49 | input [7:0] F_In;
50 | output [7:0] Q;
51 | output [7:0] F_Out;
52 | reg [7:0] Q;
53 | reg [7:0] F_Out;
54 |
55 | function [4:0] AddSub4;
56 | input [3:0] A;
57 | input [3:0] B;
58 | input Sub;
59 | input Carry_In;
60 | begin
61 | AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
62 | end
63 | endfunction // AddSub4
64 |
65 | function [3:0] AddSub3;
66 | input [2:0] A;
67 | input [2:0] B;
68 | input Sub;
69 | input Carry_In;
70 | begin
71 | AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
72 | end
73 | endfunction // AddSub4
74 |
75 | function [1:0] AddSub1;
76 | input A;
77 | input B;
78 | input Sub;
79 | input Carry_In;
80 | begin
81 | AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In;
82 | end
83 | endfunction // AddSub4
84 |
85 | // AddSub variables (temporary signals)
86 | reg UseCarry;
87 | reg Carry7_v;
88 | reg OverFlow_v;
89 | reg HalfCarry_v;
90 | reg Carry_v;
91 | reg [7:0] Q_v;
92 |
93 | reg [7:0] BitMask;
94 |
95 |
96 | always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR)
97 | begin
98 | case (IR[5:3])
99 | 3'b000 : BitMask = 8'b00000001;
100 | 3'b001 : BitMask = 8'b00000010;
101 | 3'b010 : BitMask = 8'b00000100;
102 | 3'b011 : BitMask = 8'b00001000;
103 | 3'b100 : BitMask = 8'b00010000;
104 | 3'b101 : BitMask = 8'b00100000;
105 | 3'b110 : BitMask = 8'b01000000;
106 | default: BitMask = 8'b10000000;
107 | endcase // case(IR[5:3])
108 |
109 | UseCarry = ~ ALU_Op[2] && ALU_Op[0];
110 | { HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) );
111 | { Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v);
112 | { Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v);
113 | OverFlow_v = Carry_v ^ Carry7_v;
114 | end // always @ *
115 |
116 | reg [7:0] Q_t;
117 | reg [8:0] DAA_Q;
118 |
119 | always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB
120 | or Carry_v or F_In or HalfCarry_v or IR or ISet
121 | or OverFlow_v or Q_v or Z16)
122 | begin
123 | Q_t = 8'hxx;
124 | DAA_Q = {9{1'bx}};
125 |
126 | F_Out = F_In;
127 | case (ALU_Op)
128 | 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 :
129 | begin
130 | F_Out[Flag_N] = 1'b0;
131 | F_Out[Flag_C] = 1'b0;
132 |
133 | case (ALU_Op[2:0])
134 |
135 | 3'b000, 3'b001 : // ADD, ADC
136 | begin
137 | Q_t = Q_v;
138 | F_Out[Flag_C] = Carry_v;
139 | F_Out[Flag_H] = HalfCarry_v;
140 | F_Out[Flag_P] = OverFlow_v;
141 | end
142 |
143 | 3'b010, 3'b011, 3'b111 : // SUB, SBC, CP
144 | begin
145 | Q_t = Q_v;
146 | F_Out[Flag_N] = 1'b1;
147 | F_Out[Flag_C] = ~ Carry_v;
148 | F_Out[Flag_H] = ~ HalfCarry_v;
149 | F_Out[Flag_P] = OverFlow_v;
150 | end
151 |
152 | 3'b100 : // AND
153 | begin
154 | Q_t[7:0] = BusA & BusB;
155 | F_Out[Flag_H] = 1'b1;
156 | end
157 |
158 | 3'b101 : // XOR
159 | begin
160 | Q_t[7:0] = BusA ^ BusB;
161 | F_Out[Flag_H] = 1'b0;
162 | end
163 |
164 | default : // OR 3'b110
165 | begin
166 | Q_t[7:0] = BusA | BusB;
167 | F_Out[Flag_H] = 1'b0;
168 | end
169 |
170 | endcase // case(ALU_OP[2:0])
171 |
172 | if (ALU_Op[2:0] == 3'b111 )
173 | begin // CP
174 | F_Out[Flag_X] = BusB[3];
175 | F_Out[Flag_Y] = BusB[5];
176 | end
177 | else
178 | begin
179 | F_Out[Flag_X] = Q_t[3];
180 | F_Out[Flag_Y] = Q_t[5];
181 | end
182 |
183 | if (Q_t[7:0] == 8'b00000000 )
184 | begin
185 | F_Out[Flag_Z] = 1'b1;
186 | if (Z16 == 1'b1 )
187 | begin
188 | F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC
189 | end
190 | end
191 | else
192 | begin
193 | F_Out[Flag_Z] = 1'b0;
194 | end // else: !if(Q_t[7:0] == 8'b00000000 )
195 |
196 | F_Out[Flag_S] = Q_t[7];
197 | case (ALU_Op[2:0])
198 | 3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP
199 | ;
200 |
201 | default :
202 | F_Out[Flag_P] = ~(^Q_t);
203 | endcase // case(ALU_Op[2:0])
204 |
205 | if (Arith16 == 1'b1 )
206 | begin
207 | F_Out[Flag_S] = F_In[Flag_S];
208 | F_Out[Flag_Z] = F_In[Flag_Z];
209 | F_Out[Flag_P] = F_In[Flag_P];
210 | end
211 | end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111
212 |
213 | 4'b1100 :
214 | begin
215 | // DAA
216 | F_Out[Flag_H] = F_In[Flag_H];
217 | F_Out[Flag_C] = F_In[Flag_C];
218 | DAA_Q[7:0] = BusA;
219 | DAA_Q[8] = 1'b0;
220 | if (F_In[Flag_N] == 1'b0 )
221 | begin
222 | // After addition
223 | // Alow > 9 || H == 1
224 | if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
225 | begin
226 | if ((DAA_Q[3:0] > 9) )
227 | begin
228 | F_Out[Flag_H] = 1'b1;
229 | end
230 | else
231 | begin
232 | F_Out[Flag_H] = 1'b0;
233 | end
234 | DAA_Q = DAA_Q + 6;
235 | end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
236 |
237 | // new Ahigh > 9 || C == 1
238 | if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 )
239 | begin
240 | DAA_Q = DAA_Q + 96; // 0x60
241 | end
242 | end
243 | else
244 | begin
245 | // After subtraction
246 | if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
247 | begin
248 | if (DAA_Q[3:0] > 5 )
249 | begin
250 | F_Out[Flag_H] = 1'b0;
251 | end
252 | DAA_Q[7:0] = DAA_Q[7:0] - 6;
253 | end
254 | if (BusA > 153 || F_In[Flag_C] == 1'b1 )
255 | begin
256 | DAA_Q = DAA_Q - 352; // 0x160
257 | end
258 | end // else: !if(F_In[Flag_N] == 1'b0 )
259 |
260 | F_Out[Flag_X] = DAA_Q[3];
261 | F_Out[Flag_Y] = DAA_Q[5];
262 | F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8];
263 | Q_t = DAA_Q[7:0];
264 |
265 | if (DAA_Q[7:0] == 8'b00000000 )
266 | begin
267 | F_Out[Flag_Z] = 1'b1;
268 | end
269 | else
270 | begin
271 | F_Out[Flag_Z] = 1'b0;
272 | end
273 |
274 | F_Out[Flag_S] = DAA_Q[7];
275 | F_Out[Flag_P] = ~ (^DAA_Q);
276 | end // case: 4'b1100
277 |
278 | 4'b1101, 4'b1110 :
279 | begin
280 | // RLD, RRD
281 | Q_t[7:4] = BusA[7:4];
282 | if (ALU_Op[0] == 1'b1 )
283 | begin
284 | Q_t[3:0] = BusB[7:4];
285 | end
286 | else
287 | begin
288 | Q_t[3:0] = BusB[3:0];
289 | end
290 | F_Out[Flag_H] = 1'b0;
291 | F_Out[Flag_N] = 1'b0;
292 | F_Out[Flag_X] = Q_t[3];
293 | F_Out[Flag_Y] = Q_t[5];
294 | if (Q_t[7:0] == 8'b00000000 )
295 | begin
296 | F_Out[Flag_Z] = 1'b1;
297 | end
298 | else
299 | begin
300 | F_Out[Flag_Z] = 1'b0;
301 | end
302 | F_Out[Flag_S] = Q_t[7];
303 | F_Out[Flag_P] = ~(^Q_t);
304 | end // case: when 4'b1101, 4'b1110
305 |
306 | 4'b1001 :
307 | begin
308 | // BIT
309 | Q_t[7:0] = BusB & BitMask;
310 | F_Out[Flag_S] = Q_t[7];
311 | if (Q_t[7:0] == 8'b00000000 )
312 | begin
313 | F_Out[Flag_Z] = 1'b1;
314 | F_Out[Flag_P] = 1'b1;
315 | end
316 | else
317 | begin
318 | F_Out[Flag_Z] = 1'b0;
319 | F_Out[Flag_P] = 1'b0;
320 | end
321 | F_Out[Flag_H] = 1'b1;
322 | F_Out[Flag_N] = 1'b0;
323 | F_Out[Flag_X] = 1'b0;
324 | F_Out[Flag_Y] = 1'b0;
325 | if (IR[2:0] != 3'b110 )
326 | begin
327 | F_Out[Flag_X] = BusB[3];
328 | F_Out[Flag_Y] = BusB[5];
329 | end
330 | end // case: when 4'b1001
331 |
332 | 4'b1010 :
333 | // SET
334 | Q_t[7:0] = BusB | BitMask;
335 |
336 | 4'b1011 :
337 | // RES
338 | Q_t[7:0] = BusB & ~ BitMask;
339 |
340 | 4'b1000 :
341 | begin
342 | // ROT
343 | case (IR[5:3])
344 | 3'b000 : // RLC
345 | begin
346 | Q_t[7:1] = BusA[6:0];
347 | Q_t[0] = BusA[7];
348 | F_Out[Flag_C] = BusA[7];
349 | end
350 |
351 | 3'b010 : // RL
352 | begin
353 | Q_t[7:1] = BusA[6:0];
354 | Q_t[0] = F_In[Flag_C];
355 | F_Out[Flag_C] = BusA[7];
356 | end
357 |
358 | 3'b001 : // RRC
359 | begin
360 | Q_t[6:0] = BusA[7:1];
361 | Q_t[7] = BusA[0];
362 | F_Out[Flag_C] = BusA[0];
363 | end
364 |
365 | 3'b011 : // RR
366 | begin
367 | Q_t[6:0] = BusA[7:1];
368 | Q_t[7] = F_In[Flag_C];
369 | F_Out[Flag_C] = BusA[0];
370 | end
371 |
372 | 3'b100 : // SLA
373 | begin
374 | Q_t[7:1] = BusA[6:0];
375 | Q_t[0] = 1'b0;
376 | F_Out[Flag_C] = BusA[7];
377 | end
378 |
379 | 3'b110 : // SLL (Undocumented) / SWAP
380 | begin
381 | if (Mode == 3 )
382 | begin
383 | Q_t[7:4] = BusA[3:0];
384 | Q_t[3:0] = BusA[7:4];
385 | F_Out[Flag_C] = 1'b0;
386 | end
387 | else
388 | begin
389 | Q_t[7:1] = BusA[6:0];
390 | Q_t[0] = 1'b1;
391 | F_Out[Flag_C] = BusA[7];
392 | end // else: !if(Mode == 3 )
393 | end // case: 3'b110
394 |
395 | 3'b101 : // SRA
396 | begin
397 | Q_t[6:0] = BusA[7:1];
398 | Q_t[7] = BusA[7];
399 | F_Out[Flag_C] = BusA[0];
400 | end
401 |
402 | default : // SRL
403 | begin
404 | Q_t[6:0] = BusA[7:1];
405 | Q_t[7] = 1'b0;
406 | F_Out[Flag_C] = BusA[0];
407 | end
408 | endcase // case(IR[5:3])
409 |
410 | F_Out[Flag_H] = 1'b0;
411 | F_Out[Flag_N] = 1'b0;
412 | F_Out[Flag_X] = Q_t[3];
413 | F_Out[Flag_Y] = Q_t[5];
414 | F_Out[Flag_S] = Q_t[7];
415 | if (Q_t[7:0] == 8'b00000000 )
416 | begin
417 | F_Out[Flag_Z] = 1'b1;
418 | end
419 | else
420 | begin
421 | F_Out[Flag_Z] = 1'b0;
422 | end
423 | F_Out[Flag_P] = ~(^Q_t);
424 |
425 | if (ISet == 2'b00 )
426 | begin
427 | F_Out[Flag_P] = F_In[Flag_P];
428 | F_Out[Flag_S] = F_In[Flag_S];
429 | F_Out[Flag_Z] = F_In[Flag_Z];
430 | end
431 | end // case: 4'b1000
432 |
433 |
434 | default :
435 | ;
436 |
437 | endcase // case(ALU_Op)
438 |
439 | Q = Q_t;
440 | end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
441 |
442 | endmodule // T80_ALU
443 |
--------------------------------------------------------------------------------