├── README.md
├── dist
├── Assets
│ └── superbreakout
│ │ └── common
│ │ └── .keep
├── Cores
│ └── ericlewis.SuperBreakout
│ │ ├── audio.json
│ │ ├── bitstream.rbf_r
│ │ ├── core.json
│ │ ├── data.json
│ │ ├── icon.bin
│ │ ├── input.json
│ │ ├── interact.json
│ │ ├── variants.json
│ │ └── video.json
└── Platforms
│ ├── _images
│ └── superbreakout.bin
│ └── superbreakout.json
├── mra
└── Super Breakout (Rev 04).mra
└── src
└── fpga
├── .gitignore
├── ap_core.qpf
├── ap_core.qsf
├── ap_core_assignment_defaults.qdf
├── apf
├── apf.qip
├── apf_constraints.sdc
├── apf_top.v
├── build_id.mif
├── build_id_gen.tcl
├── common.v
├── io_bridge_peripheral.v
├── io_pad_controller.v
├── mf_datatable.qip
├── mf_datatable.v
├── mf_ddio_bidir_12.ppf
├── mf_ddio_bidir_12.qip
└── mf_ddio_bidir_12.v
├── core
├── core_bridge_cmd.v
├── core_constraints.sdc
├── core_top.v
├── data_loader.sv
├── mf_pllbase.bsf
├── mf_pllbase.ppf
├── mf_pllbase.qip
├── mf_pllbase.sip
├── mf_pllbase.spd
├── mf_pllbase.v
├── mf_pllbase
│ ├── mf_pllbase_0002.qip
│ └── mf_pllbase_0002.v
├── mf_pllbase_sim.f
├── mf_pllbase_sim
│ ├── aldec
│ │ └── rivierapro_setup.tcl
│ ├── cadence
│ │ ├── cds.lib
│ │ ├── hdl.var
│ │ └── ncsim_setup.sh
│ ├── mentor
│ │ └── msim_setup.tcl
│ ├── mf_pllbase.vo
│ └── synopsys
│ │ ├── vcs
│ │ └── vcs_setup.sh
│ │ └── vcsmx
│ │ ├── synopsys_sim.setup
│ │ └── vcsmx_setup.sh
├── pin_ddio_clk.ppf
├── pin_ddio_clk.qip
├── pin_ddio_clk.v
├── rtl
│ ├── IO.vhd
│ ├── K6_PROM.vhd
│ ├── T65
│ │ ├── T65.vhd
│ │ ├── T65_ALU.vhd
│ │ ├── T65_MCode.vhd
│ │ ├── T65_Pack.vhd
│ │ └── t65.qip
│ ├── audio.vhd
│ ├── cpu_mem.vhd
│ ├── deltasigma.vhd
│ ├── dpram.vhd
│ ├── joy2quad.sv
│ ├── motion.vhd
│ ├── paddle.vhd
│ ├── paddle_analog.vhd
│ ├── playfield.vhd
│ ├── quadrature_decoder.vhd
│ ├── super_breakout.vhd
│ └── sync.vhd
└── stp1.stp
└── output_files
├── .gitignore
├── ap_core.jdi
├── ap_core.rbf
├── ap_core.sof
├── bitstream.rbf_r
├── reverse_bits.exe
└── run.bat
/README.md:
--------------------------------------------------------------------------------
1 | # Super Breakout for Analogue Pocket
2 |
3 | + FPGA implementation by james10952001 of Arcade _Super Breakout_ (Atari, 1978) for Analogue Pocket.
4 | + Ported from [MiSTer.](https://github.com/MiSTer-devel/Arcade-SuperBreakout_MiSTer/)
5 | + Multiplayer support via dock.
6 |
7 | ## Known Issues
8 |
9 | + Double / Progressive modes not implemented.
10 | + Audio is probably not quite right.
11 |
12 | ## ROM Instructions
13 |
14 | ROM files are not included, you must use [mra-tools-c](https://github.com/sebdel/mra-tools-c/) to convert to a singular `sbrkout.rom` file, then place the ROM file in `/Assets/superbreakout/common`.
--------------------------------------------------------------------------------
/dist/Assets/superbreakout/common/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericlewis/openfpga-superbreakout/d4e70e5cc7748c2e1db8ed39aba373d97f7b33e7/dist/Assets/superbreakout/common/.keep
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/audio.json:
--------------------------------------------------------------------------------
1 | {
2 | "audio": {
3 | "magic": "APF_VER_1"
4 | }
5 | }
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/bitstream.rbf_r:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericlewis/openfpga-superbreakout/d4e70e5cc7748c2e1db8ed39aba373d97f7b33e7/dist/Cores/ericlewis.SuperBreakout/bitstream.rbf_r
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/core.json:
--------------------------------------------------------------------------------
1 | {
2 | "core": {
3 | "magic": "APF_VER_1",
4 | "metadata": {
5 | "platform_ids": ["superbreakout"],
6 | "shortname": "SuperBreakout",
7 | "description": "Atari's Super Breakout released in 1978.",
8 | "author": "ericlewis",
9 | "url": "https://github.com/ericlewis/openfpga-superbreakout",
10 | "version": "0.0.1",
11 | "date_release": "2022-09-14"
12 | },
13 | "framework": {
14 | "target_product": "Analogue Pocket",
15 | "version_required": "1.1",
16 | "sleep_supported": false,
17 | "dock": {
18 | "supported": true,
19 | "analog_output": false
20 | },
21 | "hardware": {
22 | "link_port": false,
23 | "cartridge_adapter": -1
24 | }
25 | },
26 | "cores": [
27 | {
28 | "name": "default",
29 | "id": 0,
30 | "filename": "bitstream.rbf_r"
31 | }
32 | ]
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "magic": "APF_VER_1",
4 | "data_slots": [
5 | {
6 | "name": "ROM",
7 | "required": true,
8 | "parameters": 8,
9 | "filename": "sbrkout.rom",
10 | "address": "0x00000000"
11 | }
12 | ]
13 | }
14 | }
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/icon.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericlewis/openfpga-superbreakout/d4e70e5cc7748c2e1db8ed39aba373d97f7b33e7/dist/Cores/ericlewis.SuperBreakout/icon.bin
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/input.json:
--------------------------------------------------------------------------------
1 | {
2 | "input": {
3 | "magic": "APF_VER_1",
4 | "controllers": [
5 | {
6 | "type": "default",
7 | "mappings": [
8 | {
9 | "id": 0,
10 | "name": "Serve",
11 | "key": "pad_btn_a"
12 | },
13 | {
14 | "id": 1,
15 | "name": "Insert Coin",
16 | "key": "pad_trig_r"
17 | },
18 | {
19 | "id": 2,
20 | "name": "Start",
21 | "key": "pad_btn_start"
22 | }
23 | ]
24 | }
25 | ]
26 | }
27 | }
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/interact.json:
--------------------------------------------------------------------------------
1 | {
2 | "interact": {
3 | "magic": "APF_VER_1",
4 | "variables": [],
5 | "messages": []
6 | }
7 | }
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/variants.json:
--------------------------------------------------------------------------------
1 | {
2 | "variants": {
3 | "magic": "APF_VER_1",
4 | "variant_list": []
5 | }
6 | }
--------------------------------------------------------------------------------
/dist/Cores/ericlewis.SuperBreakout/video.json:
--------------------------------------------------------------------------------
1 | {
2 | "video": {
3 | "magic": "APF_VER_1",
4 | "scaler_modes": [
5 | {
6 | "width": 256,
7 | "height": 224,
8 | "aspect_w": 8,
9 | "aspect_h": 7,
10 | "rotation": 270,
11 | "mirror": 0
12 | }
13 | ]
14 | }
15 | }
--------------------------------------------------------------------------------
/dist/Platforms/_images/superbreakout.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ericlewis/openfpga-superbreakout/d4e70e5cc7748c2e1db8ed39aba373d97f7b33e7/dist/Platforms/_images/superbreakout.bin
--------------------------------------------------------------------------------
/dist/Platforms/superbreakout.json:
--------------------------------------------------------------------------------
1 | {
2 | "platform": {
3 | "category": "Arcade",
4 | "name": "Super Breakout",
5 | "year": 1978,
6 | "manufacturer": "Atari"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/mra/Super Breakout (Rev 04).mra:
--------------------------------------------------------------------------------
1 |
2 | Super Breakout
3 |
4 | no
5 | no
6 | Rev 04
7 |
8 |
9 | Breakout
10 | 1978
11 | Atari
12 | Ball and Paddle
13 |
14 | sbrkout
15 | sbrkout
16 | 0220
17 | superbreakout
18 |
19 |
20 | 15kHz
21 | vertical (ccw)
22 | no
23 |
24 | 1
25 |
26 | spinner
27 | 1
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 20210430005030
52 |
53 |
--------------------------------------------------------------------------------
/src/fpga/.gitignore:
--------------------------------------------------------------------------------
1 | */db/
2 | */incremental_db/
3 | */simulation/
4 | */greybox_tmp/
5 | incremental_db/
6 | db/
7 | PLLJ_PLLSPE_INFO.txt
8 | c5_pin_model_dump.txt
9 | cr_ie_info.json
10 | *.pin
11 | *.pof
12 | *.ptf.*
13 | *.qar
14 | *.qarlog
15 | *.qws
16 | *.rpt
17 | *.smsg
18 | *.sof
19 | *.sopc_builder
20 | *.summary
21 | *.txt
22 | *.bak
23 | *.cmp
24 | *.done
25 | *.xml
26 | *.sld
27 | *.cdf
28 |
29 |
--------------------------------------------------------------------------------
/src/fpga/ap_core.qpf:
--------------------------------------------------------------------------------
1 | # -------------------------------------------------------------------------- #
2 | #
3 | # Copyright (C) 2019 Intel Corporation. All rights reserved.
4 | # Your use of Intel Corporation's design tools, logic functions
5 | # and other software and tools, and any 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, at
16 | # https://fpgasoftware.intel.com/eula.
17 | #
18 | # -------------------------------------------------------------------------- #
19 | #
20 | # Quartus Prime
21 | # Version 18.1.1 Build 646 04/11/2019 SJ Lite Edition
22 | # Date created = 21:31:36 January 22, 2020
23 | #
24 | # -------------------------------------------------------------------------- #
25 |
26 | QUARTUS_VERSION = "18.1"
27 | DATE = "21:31:36 January 22, 2020"
28 |
29 | # Revisions
30 |
31 | PROJECT_REVISION = "ap_core"
32 |
--------------------------------------------------------------------------------
/src/fpga/apf/apf.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "apf_top.v"]
2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "common.v"]
3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_bridge_peripheral.v"]
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_pad_controller.v"]
5 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) "apf_constraints.sdc"]
6 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.qip"]
7 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_datatable.qip"]
8 |
--------------------------------------------------------------------------------
/src/fpga/apf/apf_constraints.sdc:
--------------------------------------------------------------------------------
1 | #
2 | # APF constraints
3 | # Do not edit this file.
4 | #
5 | # Add your own constraints in the \core_constraints.sdc in the core directory, which will also be loaded.
6 |
7 | create_clock -name clk_74a -period 13.468 [get_ports clk_74a]
8 | create_clock -name clk_74b -period 13.468 [get_ports clk_74b]
9 | create_clock -name bridge_spiclk -period 13.468 [get_ports bridge_spiclk]
10 |
11 | # autogenerate PLL clock names for use down below
12 | derive_pll_clocks
13 |
14 |
15 | # io constraints go here
16 | #
17 |
18 |
19 | # load in user constraints
20 | read_sdc "core/core_constraints.sdc"
--------------------------------------------------------------------------------
/src/fpga/apf/build_id.mif:
--------------------------------------------------------------------------------
1 | -- Build ID Memory Initialization File
2 | --
3 |
4 | DEPTH = 256;
5 | WIDTH = 32;
6 | ADDRESS_RADIX = HEX;
7 | DATA_RADIX = HEX;
8 |
9 | CONTENT
10 | BEGIN
11 |
12 | 0E0 : 20220916;
13 | 0E1 : 00140352;
14 | 0E2 : 50a677ea;
15 |
16 | END;
17 |
--------------------------------------------------------------------------------
/src/fpga/apf/build_id_gen.tcl:
--------------------------------------------------------------------------------
1 | # ================================================================================
2 | # (c) 2011 Altera Corporation. All rights reserved.
3 | # Altera products are protected under numerous U.S. and foreign patents, maskwork
4 | # rights, copyrights and other intellectual property laws.
5 | #
6 | # This reference design file, and your use thereof, is subject to and governed
7 | # by the terms and conditions of the applicable Altera Reference Design License
8 | # Agreement (either as signed by you, agreed by you upon download or as a
9 | # "click-through" agreement upon installation andor found at www.altera.com).
10 | # By using this reference design file, you indicate your acceptance of such terms
11 | # and conditions between you and Altera Corporation. In the event that you do
12 | # not agree with such terms and conditions, you may not use the reference design
13 | # file and please promptly destroy any copies you have made.
14 | #
15 | # This reference design file is being provided on an "as-is" basis and as an
16 | # accommodation and therefore all warranties, representations or guarantees of
17 | # any kind (whether express, implied or statutory) including, without limitation,
18 | # warranties of merchantability, non-infringement, or fitness for a particular
19 | # purpose, are specifically disclaimed. By making this reference design file
20 | # available, Altera expressly does not recommend, suggest or require that this
21 | # reference design file be used in combination with any other product not
22 | # provided by Altera.
23 | # ================================================================================
24 | #
25 | # Build ID Verilog Module Script
26 | # Jeff Wiencrot - 8/1/2011
27 | #
28 | # Generates a Verilog module that contains a timestamp, physical address, and host name
29 | # from the current build. These values are available from the build_date, build_time,
30 | # physical_address, and host_name output ports of the build_id module in the build_id.v
31 | # Verilog source file.
32 | #
33 | # The format for each value is as follows:
34 | # Date - 32-bit decimal number of the format mmddyyyy
35 | # Time - 32-bit decimal number of the format hhmmss
36 | # Phyiscal Address - 48-bit hexadecimal number
37 | # Host name - 120-bit hexadecimal number with pairs of digits equal to the
38 | # hexadecimal code for the first 15 ASCII characters of the host
39 | # name. For added clarity, host names that have fewer than 30
40 | # hexadecimal digits (15 characters) are padded on the left with
41 | # zeros.
42 | #
43 | # Usage:
44 | #
45 | # To manually execute this script, source this file using the following Tcl commands:
46 | # source build_id_verilog.tcl
47 | #
48 | # To have this script automatically execute each time your project is built, use the
49 | # following command (see: http://www.altera.com/support/examples/tcl/auto_processing.html):
50 | # set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:build_id_verilog.tcl
51 | #
52 | # Comment out the last line to prevent the process from automatically executing when
53 | # the file is sourced. The process can then be executed with the following command:
54 | # generateBuildID_Verilog
55 | #
56 | #
57 | # For more information, see "build_identification.pdf"
58 | #
59 | # ================================================================================
60 | #
61 | # 2021-01-21 Analogue
62 | #
63 | # Only care about generating build date/time, so the rest was removed.
64 | # The original can be downloaded from the Intel resource page
65 | #
66 |
67 | proc generateBuildID_Verilog {} {
68 |
69 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
70 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ]
71 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
72 |
73 | # Create a Verilog file for output
74 | set outputFileName "apf/build_id.v"
75 | set outputFile [open $outputFileName "w"]
76 |
77 | # Output the Verilog source
78 | puts $outputFile "// Build ID Verilog Module"
79 | puts $outputFile "//"
80 | puts $outputFile "// Note - these are stored as binary coded decimal"
81 | puts $outputFile "// Date: $buildDate"
82 | puts $outputFile "// Time: $buildTime"
83 | puts $outputFile ""
84 | puts $outputFile "module build_id"
85 | puts $outputFile "("
86 | puts $outputFile " output \[31:0\] build_date,"
87 | puts $outputFile " output \[31:0\] build_time"
88 | puts $outputFile ");"
89 | puts $outputFile ""
90 | puts $outputFile " assign build_date = 32'h$buildDate;"
91 | puts $outputFile " assign build_time = 32'h$buildTime;"
92 | puts $outputFile ""
93 | puts $outputFile "endmodule"
94 | close $outputFile
95 |
96 |
97 |
98 | # Send confirmation message to the Messages window
99 | #post_message "APF core build date/time generated: [pwd]/$outputFileName"
100 | #post_message "Date: $buildDate"
101 | #post_message "Time: $buildTime"
102 | }
103 |
104 |
105 | proc generateBuildID_MIF {} {
106 |
107 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
108 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ]
109 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
110 | set buildUnique [expr {int(rand()*(4294967295))}]
111 |
112 | set buildDateNoLeadingZeros [string trimleft $buildDate "0"]
113 | set buildTimeNoLeadingZeros [string trimleft $buildTime "0"]
114 | set buildDate4Byte [format "%08d" $buildDateNoLeadingZeros]
115 | set buildTime4Byte [format "%08d" $buildTimeNoLeadingZeros]
116 | set buildUnique4Byte [format "%08x" $buildUnique]
117 |
118 | #set buildDate4Byte \
119 | [concat [string range $buildDate 0 1] \
120 | [string range $buildDate 2 3] \
121 | [string range $buildDate 4 5] \
122 | [string range $buildDate 6 7] ]
123 |
124 |
125 | set buildDateNumBytes 4
126 | set buildTimeNumBytes 4
127 |
128 | # Calculate depth of the memory (8-bit) words
129 | set memoryDepth [expr $buildDateNumBytes + $buildTimeNumBytes]
130 |
131 | # Create a Memory Initialization File for output
132 | set outputFileName "apf/build_id.mif"
133 | set outputFile [open $outputFileName "w"]
134 |
135 | # Output the MIF header (see: http://quartushelp.altera.com/current/mergedProjects/reference/glossary/def_mif.htm)
136 | puts $outputFile "-- Build ID Memory Initialization File"
137 | puts $outputFile "--"
138 | puts $outputFile ""
139 | puts $outputFile "DEPTH = 256;"
140 | puts $outputFile "WIDTH = 32;"
141 | puts $outputFile "ADDRESS_RADIX = HEX;"
142 | puts $outputFile "DATA_RADIX = HEX;"
143 | puts $outputFile ""
144 | puts $outputFile "CONTENT"
145 | puts $outputFile "BEGIN"
146 | puts $outputFile ""
147 | puts $outputFile " 0E0 : $buildDate4Byte;"
148 | puts $outputFile " 0E1 : $buildTime4Byte;"
149 | puts $outputFile " 0E2 : $buildUnique4Byte;"
150 | puts $outputFile ""
151 | puts $outputFile "END;"
152 |
153 | # Close file to complete write
154 | close $outputFile
155 |
156 | # Send confirmation message to the Messages window
157 | post_message "APF core build date/time generated: [pwd]/$outputFileName"
158 | }
159 |
160 | generateBuildID_MIF
161 |
162 | # 2021-01-21 Analogue
163 | #
164 | # There are some circumstances where you want all parts of a FPGA flow to be deterministic, especially
165 | # when trying to hash out timing issues.
166 | # You should comment this line out and temporarily bypass buildid generation so that synthesis/par
167 | # have consistent working input. MIF bram contents like above won't affect the random seed or trigger
168 | # recompilation.
169 | # Don't forget to re-enable before you release.
170 | #
171 | # generateBuildID_Verilog
172 |
--------------------------------------------------------------------------------
/src/fpga/apf/common.v:
--------------------------------------------------------------------------------
1 | // Software License Agreement
2 |
3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”),
4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the
5 | // Company's customer, solely for use in designing, testing and creating
6 | // applications for use with Company's Products or Services. The software is
7 | // owned by the Company and/or its licensors, and is protected under applicable
8 | // laws, including, but not limited to, U.S. copyright law. All rights are
9 | // reserved. By using the APF code you are agreeing to the terms of the End User
10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula]
11 | // and incorporated herein by reference. To the extent any use of the APF requires
12 | // application of the MIT License or the GNU General Public License and terms of
13 | // this APF Software License Agreement and EULA are inconsistent with such license,
14 | // the applicable terms of the MIT License or the GNU General Public License, as
15 | // applicable, will prevail.
16 |
17 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED
18 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO,
19 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR
20 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM
21 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE
22 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED,
23 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND
24 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING
25 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR
26 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
27 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES,
28 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR
29 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY
30 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY
31 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION,
32 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU
33 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH
34 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE
35 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW.
36 | //
37 | // 2-stage synchronizer
38 | //
39 | module synch_2 #(parameter WIDTH = 1) (
40 | input wire [WIDTH-1:0] i, // input signal
41 | output reg [WIDTH-1:0] o, // synchronized output
42 | input wire clk, // clock to synchronize on
43 | output wire rise, // one-cycle rising edge pulse
44 | output wire fall // one-cycle falling edge pulse
45 | );
46 |
47 | reg [WIDTH-1:0] stage_1;
48 | reg [WIDTH-1:0] stage_2;
49 | reg [WIDTH-1:0] stage_3;
50 |
51 | assign rise = (WIDTH == 1) ? (o & ~stage_2) : 1'b0;
52 | assign fall = (WIDTH == 1) ? (~o & stage_2) : 1'b0;
53 | always @(posedge clk)
54 | {stage_2, o, stage_1} <= {o, stage_1, i};
55 |
56 | endmodule
57 |
58 |
59 | //
60 | // 3-stage synchronizer
61 | //
62 | module synch_3 #(parameter WIDTH = 1) (
63 | input wire [WIDTH-1:0] i, // input signal
64 | output reg [WIDTH-1:0] o, // synchronized output
65 | input wire clk, // clock to synchronize on
66 | output wire rise, // one-cycle rising edge pulse
67 | output wire fall // one-cycle falling edge pulse
68 | );
69 |
70 | reg [WIDTH-1:0] stage_1;
71 | reg [WIDTH-1:0] stage_2;
72 | reg [WIDTH-1:0] stage_3;
73 |
74 | assign rise = (WIDTH == 1) ? (o & ~stage_3) : 1'b0;
75 | assign fall = (WIDTH == 1) ? (~o & stage_3) : 1'b0;
76 | always @(posedge clk)
77 | {stage_3, o, stage_2, stage_1} <= {o, stage_2, stage_1, i};
78 |
79 | endmodule
80 |
81 |
82 | module bram_block_dp #(
83 | parameter DATA = 32,
84 | parameter ADDR = 7
85 | ) (
86 | input wire a_clk,
87 | input wire a_wr,
88 | input wire [ADDR-1:0] a_addr,
89 | input wire [DATA-1:0] a_din,
90 | output reg [DATA-1:0] a_dout,
91 |
92 | input wire b_clk,
93 | input wire b_wr,
94 | input wire [ADDR-1:0] b_addr,
95 | input wire [DATA-1:0] b_din,
96 | output reg [DATA-1:0] b_dout
97 | );
98 |
99 | reg [DATA-1:0] mem [(2**ADDR)-1:0];
100 |
101 | always @(posedge a_clk) begin
102 | if(a_wr) begin
103 | a_dout <= a_din;
104 | mem[a_addr] <= a_din;
105 | end else
106 | a_dout <= mem[a_addr];
107 | end
108 |
109 | always @(posedge b_clk) begin
110 | if(b_wr) begin
111 | b_dout <= b_din;
112 | mem[b_addr] <= b_din;
113 | end else
114 | b_dout <= mem[b_addr];
115 | end
116 |
117 | endmodule
118 |
119 |
120 | module bram_block_dp_nonstd #(
121 | parameter DATA = 32,
122 | parameter ADDR = 7,
123 | parameter DEPTH = 128
124 | ) (
125 | input wire a_clk,
126 | input wire a_wr,
127 | input wire [ADDR-1:0] a_addr,
128 | input wire [DATA-1:0] a_din,
129 | output reg [DATA-1:0] a_dout,
130 |
131 | input wire b_clk,
132 | input wire b_wr,
133 | input wire [ADDR-1:0] b_addr,
134 | input wire [DATA-1:0] b_din,
135 | output reg [DATA-1:0] b_dout
136 | );
137 |
138 | reg [DATA-1:0] mem [DEPTH-1:0];
139 |
140 | always @(posedge a_clk) begin
141 | if(a_wr) begin
142 | a_dout <= a_din;
143 | mem[a_addr] <= a_din;
144 | end else
145 | a_dout <= mem[a_addr];
146 | end
147 |
148 | always @(posedge b_clk) begin
149 | if(b_wr) begin
150 | b_dout <= b_din;
151 | mem[b_addr] <= b_din;
152 | end else
153 | b_dout <= mem[b_addr];
154 | end
155 |
156 | endmodule
157 |
--------------------------------------------------------------------------------
/src/fpga/apf/io_bridge_peripheral.v:
--------------------------------------------------------------------------------
1 | // Software License Agreement
2 |
3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”),
4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the
5 | // Company's customer, solely for use in designing, testing and creating
6 | // applications for use with Company's Products or Services. The software is
7 | // owned by the Company and/or its licensors, and is protected under applicable
8 | // laws, including, but not limited to, U.S. copyright law. All rights are
9 | // reserved. By using the APF code you are agreeing to the terms of the End User
10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula]
11 | // and incorporated herein by reference. To the extent any use of the APF requires
12 | // application of the MIT License or the GNU General Public License and terms of
13 | // this APF Software License Agreement and EULA are inconsistent with such license,
14 | // the applicable terms of the MIT License or the GNU General Public License, as
15 | // applicable, will prevail.
16 |
17 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED
18 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO,
19 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR
20 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM
21 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE
22 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED,
23 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND
24 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING
25 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR
26 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
27 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES,
28 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR
29 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY
30 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY
31 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION,
32 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU
33 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH
34 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE
35 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW.
36 | //
37 | // bridge peripheral for socrates PMP bridge to heraclitus+aristotle
38 | // 2020-2022 Analogue
39 | //
40 | // please note that while writes are immediate,
41 | // reads are buffered by 1 word. this is necessary to maintain
42 | // data throughput while reading from slower data sources like
43 | // sdram.
44 | // reads should always return the current bus value, and kickstart
45 | // into the next read immediately. this way, you have the entire
46 | // next word time to retrieve the data, instead of just a few
47 | // cycles.
48 | //
49 | // the worst-case read/write timing is every 88 cycles @ 74.25mhz
50 | // which is about 1180ns.
51 |
52 | module io_bridge_peripheral (
53 |
54 | input wire clk,
55 | input wire reset_n,
56 |
57 | input wire endian_little,
58 |
59 | output reg [31:0] pmp_addr,
60 | output reg pmp_addr_valid,
61 | output reg pmp_rd,
62 | input wire [31:0] pmp_rd_data,
63 | output reg pmp_wr,
64 | output reg [31:0] pmp_wr_data,
65 |
66 | inout reg phy_spimosi,
67 | inout reg phy_spimiso,
68 | inout reg phy_spiclk,
69 | input wire phy_spiss
70 |
71 | );
72 |
73 | //
74 | // clock domain: clk (74.25mhz) rising edge
75 | //
76 | wire reset_n_s;
77 | synch_3 s00(reset_n, reset_n_s, clk);
78 |
79 | wire endian_little_s;
80 | synch_3 s01(endian_little, endian_little_s, clk);
81 |
82 | wire phy_spiss_s, phy_spiss_r, phy_spiss_f;
83 | synch_3 s02(phy_spiss, phy_spiss_s, clk, phy_spiss_r, phy_spiss_f);
84 |
85 |
86 | reg [4:0] state;
87 | localparam ST_RESET = 'd0;
88 | localparam ST_IDLE = 'd1;
89 | localparam ST_READ_0 = 'd2;
90 | localparam ST_READ_1 = 'd3;
91 | localparam ST_READ_2 = 'd4;
92 | localparam ST_READ_3 = 'd5;
93 | localparam ST_WRITE_0 = 'd6;
94 | localparam ST_WRITE_1 = 'd7;
95 | localparam ST_WRITE_2 = 'd8;
96 | localparam ST_ADDR_0 = 'd9;
97 |
98 | reg [1:0] addr_cnt;
99 | reg [1:0] data_cnt;
100 | reg [6:0] read_cnt;
101 |
102 | // synchronize rd byte flag's rising edge into clk
103 | wire rx_byte_done_s, rx_byte_done_r;
104 | synch_3 s03(rx_byte_done, rx_byte_done_s, clk, rx_byte_done_r);
105 |
106 | reg [4:0] spis;
107 | localparam ST_SIDLE = 'd1;
108 | localparam ST_SEND_N = 'd6;
109 | localparam ST_SEND_0 = 'd2;
110 | localparam ST_SEND_1 = 'd3;
111 | localparam ST_SEND_2 = 'd4;
112 | localparam ST_SEND_3 = 'd5;
113 | reg spis_tx;
114 | reg [31:0] spis_word_tx;
115 | reg [31:0] spis_word;
116 | reg [4:0] spis_count;
117 | reg spis_done;
118 |
119 | reg rx_byte_done_r_1, rx_byte_done_r_2;
120 | reg [7:0] rx_byte_1, rx_byte_2;
121 |
122 | // handle reversing endianness on both ports
123 | reg [31:0] pmp_wr_data_latch;
124 | reg [31:0] pmp_rd_data_e; // asynchronous
125 | reg [31:0] pmp_rd_data_buf; // buffer the last word for immediate response
126 | always @(*) begin
127 | pmp_wr_data <= endian_little_s ? { pmp_wr_data_latch[7:0],
128 | pmp_wr_data_latch[15:8],
129 | pmp_wr_data_latch[23:16],
130 | pmp_wr_data_latch[31:24]
131 | } : pmp_wr_data_latch;
132 |
133 | pmp_rd_data_e <= endian_little_s ? {pmp_rd_data[7:0],
134 | pmp_rd_data[15:8],
135 | pmp_rd_data[23:16],
136 | pmp_rd_data[31:24]
137 | } : pmp_rd_data;
138 | end
139 |
140 | always @(posedge clk) begin
141 |
142 | rx_byte_2 <= rx_byte_1;
143 | rx_byte_1 <= rx_byte;
144 |
145 | rx_byte_done_r_1 <= rx_byte_done_r;
146 | rx_byte_done_r_2 <= rx_byte_done_r_1;
147 |
148 | case(state)
149 | ST_RESET: begin
150 | addr_cnt <= 0;
151 | data_cnt <= 0;
152 | pmp_wr <= 0;
153 | pmp_rd <= 0;
154 | pmp_addr_valid <= 0;
155 | spis_tx <= 0;
156 |
157 | state <= ST_ADDR_0;
158 | end
159 | ST_ADDR_0: begin
160 | // transaction has started
161 |
162 | if(rx_byte_done_r_2) begin
163 | case(addr_cnt)
164 | 0: pmp_addr[31:24] <= rx_byte_2;
165 | 1: pmp_addr[23:16] <= rx_byte_2;
166 | 2: pmp_addr[15: 8] <= rx_byte_2;
167 | 3: begin
168 | pmp_addr[ 7: 0] <= {rx_byte_2[7:2], 2'b00};
169 | // address is latched
170 | if( rx_byte_2[0] ) begin
171 | data_cnt <= 0;
172 | state <= ST_WRITE_0;
173 | end else begin
174 | data_cnt <= 0;
175 | read_cnt <= 0;
176 | state <= ST_READ_0;
177 | end
178 | end
179 | endcase
180 |
181 | addr_cnt <= addr_cnt + 1'b1;
182 | end
183 | end
184 | ST_WRITE_0: begin
185 | // give notice, address has become valid
186 | pmp_addr_valid <= 1;
187 |
188 | if(rx_byte_done_r_2) begin
189 | case(data_cnt)
190 | 0: pmp_wr_data_latch[31:24] <= rx_byte_2;
191 | 1: pmp_wr_data_latch[23:16] <= rx_byte_2;
192 | 2: pmp_wr_data_latch[15: 8] <= rx_byte_2;
193 | 3: begin
194 | pmp_wr_data_latch[ 7: 0] <= rx_byte_2;
195 | state <= ST_WRITE_1;
196 | end
197 | endcase
198 | data_cnt <= data_cnt + 1'b1;
199 | end
200 | end
201 | ST_WRITE_1: begin
202 | pmp_wr <= 1;
203 | state <= ST_WRITE_2;
204 | end
205 | ST_WRITE_2: begin
206 | // exited upon new transaction
207 | pmp_wr <= 0;
208 | end
209 | ST_READ_0: begin
210 | pmp_addr_valid <= 1;
211 |
212 | // delay a few cycles
213 | read_cnt <= read_cnt + 1'b1;
214 | if(read_cnt == 4-1) begin
215 | // load the buffer with the current data
216 | // and give the current buffer contents to bridge
217 | spis_word_tx <= pmp_rd_data_e;
218 | spis_tx <= 1;
219 |
220 | state <= ST_READ_1;
221 | end
222 | end
223 | ST_READ_1: begin
224 | pmp_rd <= 1;
225 | state <= ST_READ_2;
226 | end
227 | ST_READ_2: begin
228 | pmp_rd <= 0;
229 | if(spis_done) begin
230 | spis_tx <= 0;
231 | state <= ST_READ_3;
232 | end
233 | end
234 | ST_READ_3: begin
235 | // exited upon new transaction
236 | end
237 | endcase
238 |
239 |
240 |
241 |
242 | //
243 | // word transmit
244 | //
245 | spis_done <= 0;
246 | case(spis)
247 | ST_SIDLE: begin
248 | spis_count <= 0;
249 |
250 | phy_spiclk <= 1'bZ;
251 | phy_spimosi <= 1'bZ;
252 | phy_spimiso <= 1'bZ;
253 |
254 | if(spis_tx) begin
255 | spis_word <= spis_word_tx;
256 | spis <= ST_SEND_N;
257 | end
258 | end
259 | // drive high first
260 | ST_SEND_N: begin
261 | phy_spiclk <= 1'b1;
262 | phy_spimosi <= 1'b1;
263 | phy_spimiso <= 1'b1;
264 | spis <= ST_SEND_0;
265 | end
266 | // tx, shift out bits
267 | ST_SEND_0: begin
268 | phy_spiclk <= 0;
269 | spis <= ST_SEND_1;
270 | phy_spimosi <= spis_word[31];
271 | phy_spimiso <= spis_word[30];
272 | spis_word <= {spis_word[29:0], 2'b00};
273 | end
274 | ST_SEND_1: begin
275 | phy_spiclk <= 1;
276 | spis <= ST_SEND_0;
277 | spis_count <= spis_count + 1'b1;
278 | if(spis_count == 15) spis <= ST_SEND_2;
279 | end
280 | ST_SEND_2: begin
281 | phy_spiclk <= 1'b1;
282 | phy_spimosi <= 1'b1;
283 | phy_spimiso <= 1'b1;
284 | spis <= ST_SEND_3;
285 | spis_done <= 1;
286 | end
287 | ST_SEND_3: begin
288 | spis <= ST_SIDLE;
289 | end
290 | endcase
291 |
292 | if(phy_spiss_s) begin
293 | // select is high, go back to reset
294 | state <= ST_RESET;
295 | spis <= ST_SIDLE;
296 | end
297 |
298 | end
299 |
300 |
301 | //
302 | // clock domain: phy_spiclk rising edge
303 | //
304 | reg [1:0] rx_latch_idx;
305 | reg [7:0] rx_dat;
306 | reg [7:0] rx_byte; // latched by clk, but upon a synchronized trigger
307 | reg rx_byte_done;
308 |
309 | always @(posedge phy_spiclk or posedge phy_spiss) begin
310 |
311 | if(phy_spiss) begin
312 | // reset
313 | rx_byte_done <= 0;
314 | rx_latch_idx <= 0;
315 |
316 | end else begin
317 | // spiclk rising edge, latch data
318 | rx_byte_done <= 0;
319 |
320 | case(rx_latch_idx)
321 | 0: begin rx_dat[7:6] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 1; end
322 | 1: begin rx_dat[5:4] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 2; end
323 | 2: begin rx_dat[3:2] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 3; end
324 | 3: begin
325 | // final 2 bits
326 | rx_byte <= {rx_dat[7:2], phy_spimosi, phy_spimiso};
327 | rx_latch_idx <= 0;
328 | rx_byte_done <= 1;
329 | end
330 | endcase
331 | end
332 | end
333 |
334 | endmodule
335 |
--------------------------------------------------------------------------------
/src/fpga/apf/io_pad_controller.v:
--------------------------------------------------------------------------------
1 | // Software License Agreement
2 |
3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”),
4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the
5 | // Company's customer, solely for use in designing, testing and creating
6 | // applications for use with Company's Products or Services. The software is
7 | // owned by the Company and/or its licensors, and is protected under applicable
8 | // laws, including, but not limited to, U.S. copyright law. All rights are
9 | // reserved. By using the APF code you are agreeing to the terms of the End User
10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula]
11 | // and incorporated herein by reference. To the extent any use of the APF requires
12 | // application of the MIT License or the GNU General Public License and terms of
13 | // this APF Software License Agreement and EULA are inconsistent with such license,
14 | // the applicable terms of the MIT License or the GNU General Public License, as
15 | // applicable, will prevail.
16 |
17 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED
18 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO,
19 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR
20 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM
21 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE
22 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED,
23 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND
24 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING
25 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR
26 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
27 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES,
28 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR
29 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY
30 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY
31 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION,
32 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU
33 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH
34 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE
35 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW.
36 | //
37 | // pad controller
38 | // 2020-08-17 Analogue
39 | //
40 |
41 | module io_pad_controller (
42 |
43 | input wire clk,
44 | input wire reset_n,
45 |
46 | inout reg pad_1wire,
47 |
48 | output reg [15:0] cont1_key,
49 | output reg [15:0] cont2_key,
50 | output reg [15:0] cont3_key,
51 | output reg [15:0] cont4_key,
52 | output reg [31:0] cont1_joy,
53 | output reg [31:0] cont2_joy,
54 | output reg [31:0] cont3_joy,
55 | output reg [31:0] cont4_joy,
56 | output reg [15:0] cont1_trig,
57 | output reg [15:0] cont2_trig,
58 | output reg [15:0] cont3_trig,
59 | output reg [15:0] cont4_trig,
60 |
61 | output reg rx_timed_out
62 | );
63 |
64 | wire reset_n_s;
65 | synch_3 s00(reset_n, reset_n_s, clk);
66 |
67 | wire pad_1wire_s, pad_1wire_r, pad_1wire_f;
68 | synch_3 s01(pad_1wire, pad_1wire_s, clk, pad_1wire_r, pad_1wire_f);
69 |
70 |
71 | //
72 | // protocol fsm
73 | //
74 |
75 | reg [20:0] rx_timeout; // ~28ms
76 |
77 | reg [15:0] auto_poll_cnt; // 882us
78 | reg auto_poll_queue;
79 |
80 | reg [18:0] heartbeat_cnt; // 7ms
81 | reg heartbeat_queue;
82 |
83 |
84 | localparam ST_RESET = 'd0;
85 | localparam ST_IDLE = 'd1;
86 | localparam ST_RX_BUTTON_1 = 'd2;
87 | localparam ST_RX_BUTTON_2 = 'd3;
88 | localparam ST_TX_SCALER = 'd4;
89 | localparam ST_END_TX = 'd5;
90 |
91 | reg [3:0] state;
92 | reg [3:0] cnt;
93 |
94 | always @(posedge clk) begin
95 | tx_word_start <= 0;
96 |
97 | auto_poll_cnt <= auto_poll_cnt + 1'b1;
98 | heartbeat_cnt <= heartbeat_cnt + 1'b1;
99 |
100 | // increment rx timeout, override and reset when idle below
101 | rx_timeout <= rx_timeout + 1'b1;
102 |
103 | case(state)
104 | ST_RESET: begin
105 | reset_tr_n <= 0;
106 | rx_timed_out <= 0;
107 |
108 | if(&rx_timeout[19:0]) begin
109 | state <= ST_IDLE;
110 | end
111 | end
112 | ST_IDLE: begin
113 | // idle state
114 | reset_tr_n <= 1;
115 | rx_timeout <= 0;
116 | cnt <= 0;
117 | if(auto_poll_queue) begin
118 | auto_poll_queue <= 0;
119 |
120 | tx_word_start <= 1;
121 | tx_word <= 32'h4A10000C;
122 |
123 | state <= ST_RX_BUTTON_1;
124 | end else if(heartbeat_queue) begin
125 | heartbeat_queue <= 0;
126 |
127 | tx_word_start <= 1;
128 | tx_word <= 32'h4AFE0000;
129 |
130 | state <= ST_END_TX;
131 | end
132 | end
133 | // receive button words
134 | ST_RX_BUTTON_1: begin
135 | if(tx_word_done) begin
136 | state <= ST_RX_BUTTON_2;
137 | end
138 | end
139 | ST_RX_BUTTON_2: begin
140 | if(rx_word_done) begin
141 | cnt <= cnt + 1'b1;
142 | case(cnt)
143 | 0: cont1_key <= rx_word[15:0];
144 | 1: cont1_joy <= rx_word;
145 | 2: cont1_trig <= rx_word[15:0];
146 |
147 | 3: cont2_key <= rx_word[15:0];
148 | 4: cont2_joy <= rx_word;
149 | 5: cont2_trig <= rx_word[15:0];
150 |
151 | 6: cont3_key <= rx_word[15:0];
152 | 7: cont3_joy <= rx_word;
153 | 8: cont3_trig <= rx_word[15:0];
154 |
155 | 9: cont4_key <= rx_word[15:0];
156 | 10: cont4_joy <= rx_word;
157 | 11: begin
158 | cont4_trig <= rx_word[15:0];
159 | state <= ST_IDLE;
160 | end
161 | endcase
162 | end
163 | end
164 | // do nothing
165 | ST_END_TX: begin
166 | // done sending, idle again
167 | if(tx_word_done) begin
168 | state <= ST_IDLE;
169 | end
170 | end
171 | endcase
172 |
173 |
174 | if(&auto_poll_cnt) begin
175 | auto_poll_queue <= 1;
176 | end
177 | if(&heartbeat_cnt) begin
178 | heartbeat_queue <= 1;
179 | end
180 |
181 | if(&rx_timeout) begin
182 | // reset protocol FSM which will also reset t/r engine
183 | rx_timed_out <= 1;
184 | rx_timeout <= 0;
185 | state <= ST_RESET;
186 | end
187 |
188 | if(~reset_n_s) begin
189 | state <= ST_RESET;
190 | end
191 | end
192 |
193 |
194 |
195 |
196 |
197 | //
198 | // word receive/transmit engine
199 | //
200 | reg reset_tr_n;
201 | localparam BITLEN = 60;
202 |
203 | reg rx_word_done;
204 | reg [31:0] rx_word_shift;
205 | reg [31:0] rx_word;
206 |
207 | reg tx_word_start, tx_word_start_1;
208 | reg tx_word_done;
209 | reg [31:0] tx_word;
210 | reg [31:0] tx_word_shift;
211 |
212 | reg [7:0] tr_cnt;
213 | reg [5:0] tr_bit;
214 |
215 | localparam TR_IDLE = 'd1;
216 | localparam TR_TX_START = 'd2;
217 | localparam TR_TX_CONTINUE = 'd3;
218 | localparam TR_TX_DONE = 'd4;
219 | localparam TR_RX_START = 'd5;
220 | localparam TR_RX_WAITEDGE = 'd6;
221 | localparam TR_RX_DONE = 'd7;
222 |
223 | reg [3:0] tr_state;
224 |
225 | always @(posedge clk) begin
226 |
227 | rx_word_done <= 0;
228 | tx_word_done <= 0;
229 |
230 | tx_word_start_1 <= tx_word_start;
231 |
232 | case(tr_state)
233 | TR_IDLE: begin
234 | tr_bit <= 0;
235 | tr_cnt <= 0;
236 |
237 | pad_1wire <= 1'bZ;
238 |
239 | if(tx_word_start & ~tx_word_start_1) begin
240 | // transmit word
241 | tx_word_shift <= tx_word;
242 | tr_state <= TR_TX_START;
243 | end
244 |
245 | if(pad_1wire_f) begin
246 | // receive word
247 | tr_state <= TR_RX_START;
248 | end
249 | end
250 |
251 | // transmit 32bit
252 | TR_TX_START: begin
253 | // insert delay
254 | tr_cnt <= tr_cnt + 1'b1;
255 | if(&tr_cnt) begin
256 | // drive from tristate(high) to explicitly high to prevent glitching
257 | pad_1wire <= 1'b1;
258 | tr_state <= TR_TX_CONTINUE;
259 | end
260 | end
261 | TR_TX_CONTINUE: begin
262 | tr_cnt <= tr_cnt + 1'b1;
263 | case(tr_cnt)
264 | 0: begin
265 | pad_1wire <= 1'b0;
266 | end
267 | (BITLEN/3): begin
268 | pad_1wire <= tx_word_shift[31];
269 | end
270 | (BITLEN*2/3): begin
271 | pad_1wire <= 1'b1;
272 | end
273 | (BITLEN-1): begin
274 | tr_cnt <= 0;
275 | tx_word_shift <= {tx_word_shift[30:0], 1'b1};
276 |
277 | tr_bit <= tr_bit + 1'b1;
278 | if(tr_bit == 31) begin
279 | tr_state <= TR_TX_DONE;
280 | end
281 | end
282 | endcase
283 | end
284 | TR_TX_DONE: begin
285 | tx_word_done <= 1;
286 | tr_state <= TR_IDLE;
287 | end
288 |
289 | // receive 32bit
290 | TR_RX_START: begin
291 | tr_cnt <= tr_cnt + 1'b1;
292 | case(tr_cnt)
293 | (BITLEN/2-4): begin
294 | rx_word_shift <= {rx_word_shift[30:0], pad_1wire_s};
295 | end
296 | (BITLEN*5/6): begin
297 | tr_cnt <= 0;
298 |
299 | // wait for next falling edge
300 | tr_state <= TR_RX_WAITEDGE;
301 | tr_bit <= tr_bit + 1'b1;
302 | if(tr_bit == 31) begin
303 | // if this is bit32, don't wait and finish
304 | tr_state <= TR_RX_DONE;
305 | end
306 | end
307 | endcase
308 | end
309 | TR_RX_WAITEDGE: begin
310 | if(pad_1wire_f) begin
311 | tr_state <= TR_RX_START;
312 | end
313 | end
314 | TR_RX_DONE: begin
315 | rx_word <= rx_word_shift;
316 | rx_word_done <= 1;
317 | tr_state <= TR_IDLE;
318 | end
319 |
320 | default: begin
321 | tr_state <= TR_IDLE;
322 | end
323 | endcase
324 |
325 | if(~reset_n_s | ~reset_tr_n) tr_state <= TR_IDLE;
326 | end
327 |
328 | endmodule
329 |
--------------------------------------------------------------------------------
/src/fpga/apf/mf_datatable.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
2 | set_global_assignment -name IP_TOOL_VERSION "21.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_datatable.v"]
5 |
--------------------------------------------------------------------------------
/src/fpga/apf/mf_datatable.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %RAM: 2-PORT%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: altsyncram
5 |
6 | // ============================================================
7 | // File Name: mf_datatable.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 | // 21.1.1 Build 850 06/23/2022 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2022 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and any 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, at
34 | //https://fpgasoftware.intel.com/eula.
35 |
36 |
37 | // synopsys translate_off
38 | `timescale 1 ps / 1 ps
39 | // synopsys translate_on
40 | module mf_datatable (
41 | address_a,
42 | address_b,
43 | clock_a,
44 | clock_b,
45 | data_a,
46 | data_b,
47 | wren_a,
48 | wren_b,
49 | q_a,
50 | q_b);
51 |
52 | input [7:0] address_a;
53 | input [7:0] address_b;
54 | input clock_a;
55 | input clock_b;
56 | input [31:0] data_a;
57 | input [31:0] data_b;
58 | input wren_a;
59 | input wren_b;
60 | output [31:0] q_a;
61 | output [31:0] q_b;
62 | `ifndef ALTERA_RESERVED_QIS
63 | // synopsys translate_off
64 | `endif
65 | tri1 clock_a;
66 | tri0 wren_a;
67 | tri0 wren_b;
68 | `ifndef ALTERA_RESERVED_QIS
69 | // synopsys translate_on
70 | `endif
71 |
72 | wire [31:0] sub_wire0;
73 | wire [31:0] sub_wire1;
74 | wire [31:0] q_a = sub_wire0[31:0];
75 | wire [31:0] q_b = sub_wire1[31:0];
76 |
77 | altsyncram altsyncram_component (
78 | .address_a (address_a),
79 | .address_b (address_b),
80 | .clock0 (clock_a),
81 | .clock1 (clock_b),
82 | .data_a (data_a),
83 | .data_b (data_b),
84 | .wren_a (wren_a),
85 | .wren_b (wren_b),
86 | .q_a (sub_wire0),
87 | .q_b (sub_wire1),
88 | .aclr0 (1'b0),
89 | .aclr1 (1'b0),
90 | .addressstall_a (1'b0),
91 | .addressstall_b (1'b0),
92 | .byteena_a (1'b1),
93 | .byteena_b (1'b1),
94 | .clocken0 (1'b1),
95 | .clocken1 (1'b1),
96 | .clocken2 (1'b1),
97 | .clocken3 (1'b1),
98 | .eccstatus (),
99 | .rden_a (1'b1),
100 | .rden_b (1'b1));
101 | defparam
102 | altsyncram_component.address_reg_b = "CLOCK1",
103 | altsyncram_component.clock_enable_input_a = "BYPASS",
104 | altsyncram_component.clock_enable_input_b = "BYPASS",
105 | altsyncram_component.clock_enable_output_a = "BYPASS",
106 | altsyncram_component.clock_enable_output_b = "BYPASS",
107 | altsyncram_component.indata_reg_b = "CLOCK1",
108 | altsyncram_component.init_file = "./apf/build_id.mif",
109 | altsyncram_component.intended_device_family = "Cyclone V",
110 | altsyncram_component.lpm_type = "altsyncram",
111 | altsyncram_component.numwords_a = 256,
112 | altsyncram_component.numwords_b = 256,
113 | altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
114 | altsyncram_component.outdata_aclr_a = "NONE",
115 | altsyncram_component.outdata_aclr_b = "NONE",
116 | altsyncram_component.outdata_reg_a = "CLOCK0",
117 | altsyncram_component.outdata_reg_b = "CLOCK1",
118 | altsyncram_component.power_up_uninitialized = "FALSE",
119 | altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
120 | altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
121 | altsyncram_component.widthad_a = 8,
122 | altsyncram_component.widthad_b = 8,
123 | altsyncram_component.width_a = 32,
124 | altsyncram_component.width_b = 32,
125 | altsyncram_component.width_byteena_a = 1,
126 | altsyncram_component.width_byteena_b = 1,
127 | altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1";
128 |
129 |
130 | endmodule
131 |
132 | // ============================================================
133 | // CNX file retrieval info
134 | // ============================================================
135 | // Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
136 | // Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
137 | // Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
138 | // Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
139 | // Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
140 | // Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
141 | // Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
142 | // Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
143 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
144 | // Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
145 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
146 | // Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
147 | // Retrieval info: PRIVATE: CLRdata NUMERIC "0"
148 | // Retrieval info: PRIVATE: CLRq NUMERIC "0"
149 | // Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
150 | // Retrieval info: PRIVATE: CLRrren NUMERIC "0"
151 | // Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
152 | // Retrieval info: PRIVATE: CLRwren NUMERIC "0"
153 | // Retrieval info: PRIVATE: Clock NUMERIC "5"
154 | // Retrieval info: PRIVATE: Clock_A NUMERIC "0"
155 | // Retrieval info: PRIVATE: Clock_B NUMERIC "0"
156 | // Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
157 | // Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
158 | // Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
159 | // Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
160 | // Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
161 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
162 | // Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
163 | // Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
164 | // Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
165 | // Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192"
166 | // Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
167 | // Retrieval info: PRIVATE: MIFfilename STRING "./apf/build_id.mif"
168 | // Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
169 | // Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
170 | // Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
171 | // Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
172 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
173 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
174 | // Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
175 | // Retrieval info: PRIVATE: REGdata NUMERIC "1"
176 | // Retrieval info: PRIVATE: REGq NUMERIC "1"
177 | // Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
178 | // Retrieval info: PRIVATE: REGrren NUMERIC "0"
179 | // Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
180 | // Retrieval info: PRIVATE: REGwren NUMERIC "1"
181 | // Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
182 | // Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
183 | // Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
184 | // Retrieval info: PRIVATE: VarWidth NUMERIC "0"
185 | // Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32"
186 | // Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
187 | // Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32"
188 | // Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
189 | // Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
190 | // Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
191 | // Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
192 | // Retrieval info: PRIVATE: enable NUMERIC "0"
193 | // Retrieval info: PRIVATE: rden NUMERIC "0"
194 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
195 | // Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1"
196 | // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
197 | // Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
198 | // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
199 | // Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
200 | // Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1"
201 | // Retrieval info: CONSTANT: INIT_FILE STRING "./apf/build_id.mif"
202 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
203 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
204 | // Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
205 | // Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256"
206 | // Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
207 | // Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
208 | // Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
209 | // Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
210 | // Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1"
211 | // Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
212 | // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
213 | // Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ"
214 | // Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
215 | // Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8"
216 | // Retrieval info: CONSTANT: WIDTH_A NUMERIC "32"
217 | // Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
218 | // Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
219 | // Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
220 | // Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1"
221 | // Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL "address_a[7..0]"
222 | // Retrieval info: USED_PORT: address_b 0 0 8 0 INPUT NODEFVAL "address_b[7..0]"
223 | // Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT VCC "clock_a"
224 | // Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL "clock_b"
225 | // Retrieval info: USED_PORT: data_a 0 0 32 0 INPUT NODEFVAL "data_a[31..0]"
226 | // Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]"
227 | // Retrieval info: USED_PORT: q_a 0 0 32 0 OUTPUT NODEFVAL "q_a[31..0]"
228 | // Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]"
229 | // Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
230 | // Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
231 | // Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0
232 | // Retrieval info: CONNECT: @address_b 0 0 8 0 address_b 0 0 8 0
233 | // Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0
234 | // Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0
235 | // Retrieval info: CONNECT: @data_a 0 0 32 0 data_a 0 0 32 0
236 | // Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0
237 | // Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
238 | // Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
239 | // Retrieval info: CONNECT: q_a 0 0 32 0 @q_a 0 0 32 0
240 | // Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
241 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.v TRUE
242 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.inc FALSE
243 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.cmp FALSE
244 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.bsf FALSE
245 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_inst.v FALSE
246 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_bb.v FALSE
247 | // Retrieval info: LIB_FILE: altera_mf
248 |
--------------------------------------------------------------------------------
/src/fpga/apf/mf_ddio_bidir_12.ppf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/fpga/apf/mf_ddio_bidir_12.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR"
2 | set_global_assignment -name IP_TOOL_VERSION "21.1"
3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}"
4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.v"]
5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.ppf"]
6 |
--------------------------------------------------------------------------------
/src/fpga/apf/mf_ddio_bidir_12.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %ALTDDIO_BIDIR%
2 | // GENERATION: STANDARD
3 | // VERSION: WM1.0
4 | // MODULE: ALTDDIO_BIDIR
5 |
6 | // ============================================================
7 | // File Name: mf_ddio_bidir_12.v
8 | // Megafunction Name(s):
9 | // ALTDDIO_BIDIR
10 | //
11 | // Simulation Library Files(s):
12 | //
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 21.1.1 Build 850 06/23/2022 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2022 Intel Corporation. All rights reserved.
22 | //Your use of Intel Corporation's design tools, logic functions
23 | //and other software and tools, and any 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, at
34 | //https://fpgasoftware.intel.com/eula.
35 |
36 |
37 | // synopsys translate_off
38 | `timescale 1 ps / 1 ps
39 | // synopsys translate_on
40 | module mf_ddio_bidir_12 (
41 | datain_h,
42 | datain_l,
43 | inclock,
44 | oe,
45 | outclock,
46 | dataout_h,
47 | dataout_l,
48 | padio);
49 |
50 | input [11:0] datain_h;
51 | input [11:0] datain_l;
52 | input inclock;
53 | input oe;
54 | input outclock;
55 | output [11:0] dataout_h;
56 | output [11:0] dataout_l;
57 | inout [11:0] padio;
58 |
59 | wire [11:0] sub_wire0;
60 | wire [11:0] sub_wire1;
61 | wire [11:0] dataout_h = sub_wire0[11:0];
62 | wire [11:0] dataout_l = sub_wire1[11:0];
63 |
64 | altddio_bidir ALTDDIO_BIDIR_component (
65 | .datain_h (datain_h),
66 | .datain_l (datain_l),
67 | .inclock (inclock),
68 | .oe (oe),
69 | .outclock (outclock),
70 | .padio (padio),
71 | .dataout_h (sub_wire0),
72 | .dataout_l (sub_wire1),
73 | .aclr (1'b0),
74 | .aset (1'b0),
75 | .combout (),
76 | .dqsundelayedout (),
77 | .inclocken (1'b1),
78 | .oe_out (),
79 | .outclocken (1'b1),
80 | .sclr (1'b0),
81 | .sset (1'b0));
82 | defparam
83 | ALTDDIO_BIDIR_component.extend_oe_disable = "OFF",
84 | ALTDDIO_BIDIR_component.implement_input_in_lcell = "OFF",
85 | ALTDDIO_BIDIR_component.intended_device_family = "Cyclone V",
86 | ALTDDIO_BIDIR_component.invert_output = "OFF",
87 | ALTDDIO_BIDIR_component.lpm_hint = "UNUSED",
88 | ALTDDIO_BIDIR_component.lpm_type = "altddio_bidir",
89 | ALTDDIO_BIDIR_component.oe_reg = "UNREGISTERED",
90 | ALTDDIO_BIDIR_component.power_up_high = "OFF",
91 | ALTDDIO_BIDIR_component.width = 12;
92 |
93 |
94 | endmodule
95 |
96 | // ============================================================
97 | // CNX file retrieval info
98 | // ============================================================
99 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
100 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
101 | // Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF"
102 | // Retrieval info: CONSTANT: IMPLEMENT_INPUT_IN_LCELL STRING "OFF"
103 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
104 | // Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF"
105 | // Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED"
106 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_bidir"
107 | // Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED"
108 | // Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF"
109 | // Retrieval info: CONSTANT: WIDTH NUMERIC "12"
110 | // Retrieval info: USED_PORT: datain_h 0 0 12 0 INPUT NODEFVAL "datain_h[11..0]"
111 | // Retrieval info: CONNECT: @datain_h 0 0 12 0 datain_h 0 0 12 0
112 | // Retrieval info: USED_PORT: datain_l 0 0 12 0 INPUT NODEFVAL "datain_l[11..0]"
113 | // Retrieval info: CONNECT: @datain_l 0 0 12 0 datain_l 0 0 12 0
114 | // Retrieval info: USED_PORT: dataout_h 0 0 12 0 OUTPUT NODEFVAL "dataout_h[11..0]"
115 | // Retrieval info: CONNECT: dataout_h 0 0 12 0 @dataout_h 0 0 12 0
116 | // Retrieval info: USED_PORT: dataout_l 0 0 12 0 OUTPUT NODEFVAL "dataout_l[11..0]"
117 | // Retrieval info: CONNECT: dataout_l 0 0 12 0 @dataout_l 0 0 12 0
118 | // Retrieval info: USED_PORT: inclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "inclock"
119 | // Retrieval info: CONNECT: @inclock 0 0 0 0 inclock 0 0 0 0
120 | // Retrieval info: USED_PORT: oe 0 0 0 0 INPUT NODEFVAL "oe"
121 | // Retrieval info: CONNECT: @oe 0 0 0 0 oe 0 0 0 0
122 | // Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock"
123 | // Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0
124 | // Retrieval info: USED_PORT: padio 0 0 12 0 BIDIR NODEFVAL "padio[11..0]"
125 | // Retrieval info: CONNECT: padio 0 0 12 0 @padio 0 0 12 0
126 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.v TRUE FALSE
127 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.qip TRUE FALSE
128 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.bsf FALSE TRUE
129 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_inst.v FALSE TRUE
130 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_bb.v FALSE TRUE
131 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.inc FALSE TRUE
132 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.cmp FALSE TRUE
133 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.ppf TRUE FALSE
134 |
--------------------------------------------------------------------------------
/src/fpga/core/core_constraints.sdc:
--------------------------------------------------------------------------------
1 | #
2 | # user core constraints
3 | #
4 | # put your clock groups in here as well as any net assignments
5 | #
6 |
7 | set_clock_groups -asynchronous \
8 | -group { bridge_spiclk } \
9 | -group { clk_74a } \
10 | -group { clk_74b } \
11 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \
12 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk }
--------------------------------------------------------------------------------
/src/fpga/core/data_loader.sv:
--------------------------------------------------------------------------------
1 | // MIT License
2 |
3 | // Copyright (c) 2022 Adam Gastineau
4 |
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 |
12 | // The above copyright notice and this permission notice shall be included in all
13 | // copies or substantial portions of the Software.
14 |
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 | //
23 | ////////////////////////////////////////////////////////////////////////////////
24 |
25 | // A data loader for consuming APF bridge writes and directing them to some storage medium
26 | //
27 | // This takes the 32 bit words from APF, and splits it into four / OUTPUT_WORD_SIZE words (4 separate bytes, or 2 16-bit words).
28 | // You can configure the cycle delay by setting WRITE_MEM_CLOCK_DELAY
29 | module data_loader #(
30 | // Upper 4 bits of address
31 | parameter ADDRESS_MASK_UPPER_4 = 0,
32 | parameter ADDRESS_SIZE = 14,
33 |
34 | // Number of clk_memory cycles to delay each write output
35 | // Min 4. Component will assert this value is within the valid range
36 | // Be aware that APF sends data every ~75 74MHz cycles, so you cannot send data slower than this
37 | parameter WRITE_MEM_CLOCK_DELAY = 4,
38 |
39 | // Number of clk_memory cycles to hold the write_en signal high
40 | // Min 1. Component will assert this value is within the valid range
41 | parameter WRITE_MEM_EN_CYCLE_LENGTH = 1,
42 |
43 | // Word size in number of bytes. Can either be 1 (output 8 bits), or 2 (output 16 bits)
44 | // Component will assert this value is within the valid range
45 | parameter OUTPUT_WORD_SIZE = 1
46 | ) (
47 | input wire clk_74a,
48 | input wire clk_memory,
49 |
50 | input wire bridge_wr,
51 | input wire bridge_endian_little,
52 | input wire [31:0] bridge_addr,
53 | input wire [31:0] bridge_wr_data,
54 |
55 | // These outputs are synced to the memory clock
56 | output reg write_en = 0,
57 | output reg [ADDRESS_SIZE:0] write_addr = 0,
58 | output reg [8 * OUTPUT_WORD_SIZE - 1:0] write_data = 0
59 | );
60 |
61 | `define MAX(x, y) ((x > y) ? x : y)
62 |
63 | localparam WORD_SIZE = 8 * OUTPUT_WORD_SIZE;
64 |
65 | // Only use the lower 28 bits of the address
66 | localparam FIFO_SIZE = WORD_SIZE + 28;
67 |
68 | wire mem_empty;
69 |
70 | wire [FIFO_SIZE - 1:0] fifo_out;
71 |
72 | reg read_req = 0;
73 | reg write_req = 0;
74 | reg [31:0] shift_data;
75 | reg [27:0] buff_bridge_addr;
76 |
77 | wire [FIFO_SIZE - 1:0] fifo_in = {shift_data[WORD_SIZE-1:0], buff_bridge_addr[27:0]};
78 |
79 | dcfifo dcfifo_component (
80 | .data(fifo_in),
81 | .rdclk(clk_memory),
82 | .rdreq(read_req),
83 | .wrclk(clk_74a),
84 | .wrreq(write_req),
85 | .q(fifo_out),
86 | .rdempty(mem_empty)
87 | // .wrempty(),
88 | // .aclr(),
89 | // .eccstatus(),
90 | // .rdfull(),
91 | // .rdusedw(),
92 | // .wrfull(),
93 | // .wrusedw()
94 | );
95 | defparam dcfifo_component.clocks_are_synchronized = "FALSE",
96 | dcfifo_component.intended_device_family = "Cyclone V", dcfifo_component.lpm_numwords = 4,
97 | dcfifo_component.lpm_showahead = "OFF", dcfifo_component.lpm_type = "dcfifo",
98 | dcfifo_component.lpm_width = FIFO_SIZE, dcfifo_component.lpm_widthu = 2,
99 | dcfifo_component.overflow_checking = "OFF", dcfifo_component.rdsync_delaypipe = 5,
100 | dcfifo_component.underflow_checking = "OFF", dcfifo_component.use_eab = "OFF",
101 | dcfifo_component.wrsync_delaypipe = 5;
102 |
103 | /// APF to Mem clock
104 |
105 | reg prev_bridge_wr = 0;
106 | reg [2:0] write_count = 0;
107 | reg [2:0] write_state = 0;
108 |
109 | localparam WRITE_START = 1;
110 | localparam WRITE_REQ_SHIFT = 2;
111 |
112 | // Receive APF writes and buffer them into the memory clock domain
113 | always @(posedge clk_74a) begin
114 | prev_bridge_wr <= bridge_wr;
115 |
116 | if (~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin
117 | // Beginning APF write to core
118 | write_state <= WRITE_REQ_SHIFT;
119 | write_req <= 1;
120 | write_count <= 0;
121 |
122 | shift_data <= bridge_endian_little ? bridge_wr_data : {
123 | bridge_wr_data[7:0], bridge_wr_data[15:8], bridge_wr_data[23:16], bridge_wr_data[31:24]
124 | };
125 |
126 | buff_bridge_addr <= bridge_addr[27:0];
127 | end
128 |
129 | case (write_state)
130 | WRITE_START: begin
131 | write_req <= 1;
132 |
133 | write_state <= WRITE_REQ_SHIFT;
134 | end
135 | WRITE_REQ_SHIFT: begin
136 | write_req <= 0;
137 |
138 | // We will be writing again in the next cycle
139 | shift_data <= {8'h0, shift_data[31:WORD_SIZE]};
140 | buff_bridge_addr <= buff_bridge_addr + OUTPUT_WORD_SIZE;
141 |
142 | write_count <= write_count + 1;
143 |
144 | if (write_count == (4 / OUTPUT_WORD_SIZE) - 1) begin
145 | // Finished write
146 | write_state <= 0;
147 | end else begin
148 | write_state <= WRITE_START;
149 | end
150 | end
151 | endcase
152 | end
153 |
154 | /// Mem clock to core
155 |
156 | reg [5:0] read_state = 0;
157 |
158 | localparam READ_DELAY = 1;
159 | localparam READ_WRITE = 2;
160 | localparam READ_WRITE_EN_CYCLE_OFF = READ_WRITE + WRITE_MEM_EN_CYCLE_LENGTH;
161 | localparam READ_WRITE_END_DEFAULT = WRITE_MEM_CLOCK_DELAY - 1;
162 | // Must use max to prevent READ_WRITE_END from being the same as READ_WRITE_EN_CYCLE_OFF
163 | localparam READ_WRITE_END =
164 | `MAX(READ_WRITE_END_DEFAULT, READ_WRITE_EN_CYCLE_OFF + 1);
165 | localparam HAS_DELAY = READ_WRITE_END_DEFAULT > READ_WRITE_EN_CYCLE_OFF;
166 |
167 | always @(posedge clk_memory) begin
168 | if (read_state != 0) begin
169 | read_state <= read_state + 1;
170 | end else if (~mem_empty) begin
171 | // Start read
172 | read_state <= READ_DELAY;
173 | read_req <= 1;
174 | end
175 |
176 | case (read_state)
177 | READ_DELAY: begin
178 | read_req <= 0;
179 | write_en <= 0;
180 | end
181 | READ_WRITE: begin
182 | // Read data is available
183 | write_en <= 1;
184 |
185 | // Lowest 28 bits are the address
186 | write_addr <= fifo_out[27:0];
187 |
188 | write_data <= fifo_out[WORD_SIZE+27:28];
189 |
190 | read_req <= 0;
191 | end
192 | READ_WRITE_EN_CYCLE_OFF: begin
193 | write_en <= 0;
194 |
195 | if (!HAS_DELAY) begin
196 | // No extra delay, immediately go back to start
197 | read_state <= 0;
198 | end
199 | end
200 | READ_WRITE_END: begin
201 | read_state <= 0;
202 | end
203 | endcase
204 | end
205 |
206 | initial begin
207 | // Verify parameters
208 | if (WRITE_MEM_CLOCK_DELAY < 4) begin
209 | $error("WRITE_MEM_CLOCK_DELAY has a minimum value of 4. Received %d", WRITE_MEM_CLOCK_DELAY);
210 | end
211 |
212 | if (WRITE_MEM_EN_CYCLE_LENGTH < 1 || WRITE_MEM_EN_CYCLE_LENGTH >= WRITE_MEM_CLOCK_DELAY - 2) begin
213 | $error(
214 | "WRITE_MEM_EN_CYCLE_LENGTH must be between 1 and %d (inclusive, based off of WRITE_MEM_CLOCK_DELAY). Received %d",
215 | WRITE_MEM_CLOCK_DELAY - 2 - 1, WRITE_MEM_EN_CYCLE_LENGTH);
216 | end
217 |
218 | if (OUTPUT_WORD_SIZE < 1 || OUTPUT_WORD_SIZE > 2) begin
219 | $error("OUTPUT_WORD_SIZE must be 1 or 2. Received %d", OUTPUT_WORD_SIZE);
220 | end
221 | end
222 |
223 | endmodule
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase.bsf:
--------------------------------------------------------------------------------
1 | /*
2 | WARNING: Do NOT edit the input and output ports in this file in a text
3 | editor if you plan to continue editing the block that represents it in
4 | the Block Editor! File corruption is VERY likely to occur.
5 | */
6 | /*
7 | Copyright (C) 2018 Intel Corporation. All rights reserved.
8 | Your use of Intel Corporation's design tools, logic functions
9 | and other software and tools, and its AMPP partner logic
10 | functions, and any output files from any of the foregoing
11 | (including device programming or simulation files), and any
12 | associated documentation or information are expressly subject
13 | to the terms and conditions of the Intel Program License
14 | Subscription Agreement, the Intel Quartus Prime License Agreement,
15 | the Intel FPGA IP License Agreement, or other applicable license
16 | agreement, including, without limitation, that your use is for
17 | the sole purpose of programming logic devices manufactured by
18 | Intel and sold by Intel or its authorized distributors. Please
19 | refer to the applicable agreement for further details.
20 | */
21 | (header "symbol" (version "1.1"))
22 | (symbol
23 | (rect 0 0 160 224)
24 | (text "mf_pllbase" (rect 48 -1 91 11)(font "Arial" (font_size 10)))
25 | (text "inst" (rect 8 208 20 220)(font "Arial" ))
26 | (port
27 | (pt 0 72)
28 | (input)
29 | (text "refclk" (rect 0 0 22 12)(font "Arial" (font_size 8)))
30 | (text "refclk" (rect 4 61 40 72)(font "Arial" (font_size 8)))
31 | (line (pt 0 72)(pt 48 72)(line_width 1))
32 | )
33 | (port
34 | (pt 0 112)
35 | (input)
36 | (text "rst" (rect 0 0 10 12)(font "Arial" (font_size 8)))
37 | (text "rst" (rect 4 101 22 112)(font "Arial" (font_size 8)))
38 | (line (pt 0 112)(pt 48 112)(line_width 1))
39 | )
40 | (port
41 | (pt 160 72)
42 | (output)
43 | (text "outclk_0" (rect 0 0 33 12)(font "Arial" (font_size 8)))
44 | (text "outclk_0" (rect 117 61 165 72)(font "Arial" (font_size 8)))
45 | (line (pt 160 72)(pt 112 72)(line_width 1))
46 | )
47 | (port
48 | (pt 160 112)
49 | (output)
50 | (text "outclk_1" (rect 0 0 31 12)(font "Arial" (font_size 8)))
51 | (text "outclk_1" (rect 119 101 167 112)(font "Arial" (font_size 8)))
52 | (line (pt 160 112)(pt 112 112)(line_width 1))
53 | )
54 | (port
55 | (pt 160 152)
56 | (output)
57 | (text "outclk_2" (rect 0 0 33 12)(font "Arial" (font_size 8)))
58 | (text "outclk_2" (rect 117 141 165 152)(font "Arial" (font_size 8)))
59 | (line (pt 160 152)(pt 112 152)(line_width 1))
60 | )
61 | (port
62 | (pt 160 192)
63 | (output)
64 | (text "locked" (rect 0 0 24 12)(font "Arial" (font_size 8)))
65 | (text "locked" (rect 127 181 163 192)(font "Arial" (font_size 8)))
66 | (line (pt 160 192)(pt 112 192)(line_width 1))
67 | )
68 | (drawing
69 | (text "refclk" (rect 16 43 68 99)(font "Arial" (color 128 0 0)(font_size 9)))
70 | (text "clk" (rect 53 67 124 144)(font "Arial" (color 0 0 0)))
71 | (text "reset" (rect 19 83 68 179)(font "Arial" (color 128 0 0)(font_size 9)))
72 | (text "reset" (rect 53 107 136 224)(font "Arial" (color 0 0 0)))
73 | (text "outclk0" (rect 113 43 268 99)(font "Arial" (color 128 0 0)(font_size 9)))
74 | (text "clk" (rect 97 67 212 144)(font "Arial" (color 0 0 0)))
75 | (text "outclk1" (rect 113 83 268 179)(font "Arial" (color 128 0 0)(font_size 9)))
76 | (text "clk" (rect 97 107 212 224)(font "Arial" (color 0 0 0)))
77 | (text "outclk2" (rect 113 123 268 259)(font "Arial" (color 128 0 0)(font_size 9)))
78 | (text "clk" (rect 97 147 212 304)(font "Arial" (color 0 0 0)))
79 | (text "locked" (rect 113 163 262 339)(font "Arial" (color 128 0 0)(font_size 9)))
80 | (text "export" (rect 82 187 200 384)(font "Arial" (color 0 0 0)))
81 | (text " altera_pll " (rect 118 208 308 426)(font "Arial" ))
82 | (line (pt 48 32)(pt 112 32)(line_width 1))
83 | (line (pt 112 32)(pt 112 208)(line_width 1))
84 | (line (pt 48 208)(pt 112 208)(line_width 1))
85 | (line (pt 48 32)(pt 48 208)(line_width 1))
86 | (line (pt 49 52)(pt 49 76)(line_width 1))
87 | (line (pt 50 52)(pt 50 76)(line_width 1))
88 | (line (pt 49 92)(pt 49 116)(line_width 1))
89 | (line (pt 50 92)(pt 50 116)(line_width 1))
90 | (line (pt 111 52)(pt 111 76)(line_width 1))
91 | (line (pt 110 52)(pt 110 76)(line_width 1))
92 | (line (pt 111 92)(pt 111 116)(line_width 1))
93 | (line (pt 110 92)(pt 110 116)(line_width 1))
94 | (line (pt 111 132)(pt 111 156)(line_width 1))
95 | (line (pt 110 132)(pt 110 156)(line_width 1))
96 | (line (pt 111 172)(pt 111 196)(line_width 1))
97 | (line (pt 110 172)(pt 110 196)(line_width 1))
98 | (line (pt 0 0)(pt 160 0)(line_width 1))
99 | (line (pt 160 0)(pt 160 224)(line_width 1))
100 | (line (pt 0 224)(pt 160 224)(line_width 1))
101 | (line (pt 0 0)(pt 0 224)(line_width 1))
102 | )
103 | )
104 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase.ppf:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase.sip:
--------------------------------------------------------------------------------
1 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_NAME "altera_pll"
2 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_VERSION "18.0"
3 | set_global_assignment -entity "mf_pllbase" -library "lib_mf_pllbase" -name IP_TOOL_ENV "mwpim"
4 | set_global_assignment -library "lib_mf_pllbase" -name SPD_FILE [file join $::quartus(sip_path) "mf_pllbase.spd"]
5 |
6 | set_global_assignment -library "lib_mf_pllbase" -name MISC_FILE [file join $::quartus(sip_path) "mf_pllbase_sim/mf_pllbase.vo"]
7 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase.spd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase/mf_pllbase_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*"
2 |
3 | set_instance_assignment -name PLL_AUTO_RESET OFF -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*"
4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*"
5 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase/mf_pllbase_0002.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | module mf_pllbase_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 'outclk2'
17 | output wire outclk_2,
18 |
19 | // interface 'locked'
20 | output wire locked
21 | );
22 |
23 | altera_pll #(
24 | .fractional_vco_multiplier("false"),
25 | .reference_clock_frequency("74.25 MHz"),
26 | .operation_mode("direct"),
27 | .number_of_clocks(3),
28 | .output_clock_frequency0("12.000000 MHz"),
29 | .phase_shift0("0 ps"),
30 | .duty_cycle0(50),
31 | .output_clock_frequency1("6.000000 MHz"),
32 | .phase_shift1("0 ps"),
33 | .duty_cycle1(50),
34 | .output_clock_frequency2("6.000000 MHz"),
35 | .phase_shift2("41667 ps"),
36 | .duty_cycle2(50),
37 | .output_clock_frequency3("0 MHz"),
38 | .phase_shift3("0 ps"),
39 | .duty_cycle3(50),
40 | .output_clock_frequency4("0 MHz"),
41 | .phase_shift4("0 ps"),
42 | .duty_cycle4(50),
43 | .output_clock_frequency5("0 MHz"),
44 | .phase_shift5("0 ps"),
45 | .duty_cycle5(50),
46 | .output_clock_frequency6("0 MHz"),
47 | .phase_shift6("0 ps"),
48 | .duty_cycle6(50),
49 | .output_clock_frequency7("0 MHz"),
50 | .phase_shift7("0 ps"),
51 | .duty_cycle7(50),
52 | .output_clock_frequency8("0 MHz"),
53 | .phase_shift8("0 ps"),
54 | .duty_cycle8(50),
55 | .output_clock_frequency9("0 MHz"),
56 | .phase_shift9("0 ps"),
57 | .duty_cycle9(50),
58 | .output_clock_frequency10("0 MHz"),
59 | .phase_shift10("0 ps"),
60 | .duty_cycle10(50),
61 | .output_clock_frequency11("0 MHz"),
62 | .phase_shift11("0 ps"),
63 | .duty_cycle11(50),
64 | .output_clock_frequency12("0 MHz"),
65 | .phase_shift12("0 ps"),
66 | .duty_cycle12(50),
67 | .output_clock_frequency13("0 MHz"),
68 | .phase_shift13("0 ps"),
69 | .duty_cycle13(50),
70 | .output_clock_frequency14("0 MHz"),
71 | .phase_shift14("0 ps"),
72 | .duty_cycle14(50),
73 | .output_clock_frequency15("0 MHz"),
74 | .phase_shift15("0 ps"),
75 | .duty_cycle15(50),
76 | .output_clock_frequency16("0 MHz"),
77 | .phase_shift16("0 ps"),
78 | .duty_cycle16(50),
79 | .output_clock_frequency17("0 MHz"),
80 | .phase_shift17("0 ps"),
81 | .duty_cycle17(50),
82 | .pll_type("General"),
83 | .pll_subtype("General")
84 | ) altera_pll_i (
85 | .rst (rst),
86 | .outclk ({outclk_2, outclk_1, outclk_0}),
87 | .locked (locked),
88 | .fboutclk ( ),
89 | .fbclk (1'b0),
90 | .refclk (refclk)
91 | );
92 | endmodule
93 |
94 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase_sim.f:
--------------------------------------------------------------------------------
1 | mf_pllbase_sim/mf_pllbase.vo
2 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase_sim/aldec/rivierapro_setup.tcl:
--------------------------------------------------------------------------------
1 |
2 | # (C) 2001-2022 Altera Corporation. All rights reserved.
3 | # Your use of Altera Corporation's design tools, logic functions and
4 | # other software and tools, and its AMPP partner logic functions, and
5 | # any output files any of the foregoing (including device programming
6 | # or simulation files), and any associated documentation or information
7 | # are expressly subject to the terms and conditions of the Altera
8 | # Program License Subscription Agreement, Altera MegaCore Function
9 | # License Agreement, or other applicable license agreement, including,
10 | # without limitation, that your use is for the sole purpose of
11 | # programming logic devices manufactured by Altera and sold by Altera
12 | # or its authorized distributors. Please refer to the applicable
13 | # agreement for further details.
14 |
15 | # ACDS 18.0 614 win32 2022.09.16.12:00:45
16 | # ----------------------------------------
17 | # Auto-generated simulation script rivierapro_setup.tcl
18 | # ----------------------------------------
19 | # This script provides commands to simulate the following IP detected in
20 | # your Quartus project:
21 | # mf_pllbase
22 | #
23 | # Altera recommends that you source this Quartus-generated IP simulation
24 | # script from your own customized top-level script, and avoid editing this
25 | # generated script.
26 | #
27 | # To write a top-level script that compiles Altera simulation libraries and
28 | # the Quartus-generated IP in your project, along with your design and
29 | # testbench files, copy the text from the TOP-LEVEL TEMPLATE section below
30 | # into a new file, e.g. named "aldec.do", and modify the text as directed.
31 | #
32 | # ----------------------------------------
33 | # # TOP-LEVEL TEMPLATE - BEGIN
34 | # #
35 | # # QSYS_SIMDIR is used in the Quartus-generated IP simulation script to
36 | # # construct paths to the files required to simulate the IP in your Quartus
37 | # # project. By default, the IP script assumes that you are launching the
38 | # # simulator from the IP script location. If launching from another
39 | # # location, set QSYS_SIMDIR to the output directory you specified when you
40 | # # generated the IP script, relative to the directory from which you launch
41 | # # the simulator.
42 | # #
43 | # set QSYS_SIMDIR