├── README.md
├── audio.json
├── core.json
├── data.json
├── dist
├── .gitkeep
├── assets
│ └── .keep
├── icon.bin
└── platforms
│ ├── _images
│ └── ex_platform.bin
│ └── ex_platform.json
├── info.txt
├── input.json
├── interact.json
├── output
├── .gitkeep
└── bitstream.rbf_r
├── src
└── fpga
│ ├── .gitignore
│ ├── ap_core.qpf
│ ├── ap_core.qsf
│ ├── 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.qip
│ └── mf_ddio_bidir_12.v
│ ├── core
│ ├── core_bridge_cmd.v
│ ├── core_constraints.sdc
│ ├── core_top.v
│ ├── 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
│ └── stp1.stp
│ └── output_files
│ ├── .gitignore
│ ├── ap_core.jdi
│ ├── ap_core.rbf
│ └── ap_core.sof
├── variants.json
└── video.json
/README.md:
--------------------------------------------------------------------------------
1 | # Core Template
2 | This is a template repository for a core which contains all of the core definition JSON files and FPGA starter code.
3 |
4 | ## Legal
5 | Analogue’s Development program was created to further video game hardware preservation with FPGA technology. Analogue Developers have access to Analogue Pocket I/O’s so Developers can utilize cartridge adapters or interface with other pieces of original or bespoke hardware to support legacy media. Analogue does not support or endorse the unauthorized use or distribution of material protected by copyright or other intellectual property rights.
6 |
--------------------------------------------------------------------------------
/audio.json:
--------------------------------------------------------------------------------
1 | {
2 | "audio": {
3 | "magic": "APF_VER_1"
4 | }
5 | }
--------------------------------------------------------------------------------
/core.json:
--------------------------------------------------------------------------------
1 | {
2 | "core": {
3 | "magic": "APF_VER_1",
4 | "metadata": {
5 | "platform_ids": ["ex_platform"],
6 | "shortname": "Core Template",
7 | "description": "APF core template. Displays gray test screen.",
8 | "author": "Developer",
9 | "url": "https://github.com/open-fpga/core-template",
10 | "version": "1.3.0",
11 | "date_release": "2023-03-08"
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 |
--------------------------------------------------------------------------------
/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "data": {
3 | "magic": "APF_VER_1",
4 | "data_slots": []
5 | }
6 | }
--------------------------------------------------------------------------------
/dist/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/dist/.gitkeep
--------------------------------------------------------------------------------
/dist/assets/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/dist/assets/.keep
--------------------------------------------------------------------------------
/dist/icon.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/dist/icon.bin
--------------------------------------------------------------------------------
/dist/platforms/_images/ex_platform.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/dist/platforms/_images/ex_platform.bin
--------------------------------------------------------------------------------
/dist/platforms/ex_platform.json:
--------------------------------------------------------------------------------
1 | {
2 | "platform": {
3 | "category": "Example Cores",
4 | "name": "Example Platform",
5 | "year": 2022,
6 | "manufacturer": "Example Manufacturer"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/info.txt:
--------------------------------------------------------------------------------
1 | Example Core - Core Template
2 |
3 | This is a template for a core containing all of the core definition JSON files and FPGA starter code.
4 |
--------------------------------------------------------------------------------
/input.json:
--------------------------------------------------------------------------------
1 | {
2 | "input": {
3 | "magic": "APF_VER_1",
4 | "controllers": []
5 | }
6 | }
--------------------------------------------------------------------------------
/interact.json:
--------------------------------------------------------------------------------
1 | {
2 | "interact": {
3 | "magic": "APF_VER_1",
4 | "variables": [],
5 | "messages": []
6 | }
7 | }
--------------------------------------------------------------------------------
/output/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/output/.gitkeep
--------------------------------------------------------------------------------
/output/bitstream.rbf_r:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-fpga/core-template/da3a021b1eaf742604d86d8dc9b33a6666263e6a/output/bitstream.rbf_r
--------------------------------------------------------------------------------
/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/apf_top.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 | // 6515C - Analogue Pocket main unit
38 | // SOCRATES FPGA
39 | //
40 | // 2022-08-17 Analogue
41 |
42 | `default_nettype none
43 |
44 | module apf_top (
45 | ///////////////////////////////////////////////////
46 | // clock inputs 74.25mhz. not phase aligned, so treat these domains as asynchronous
47 |
48 | input wire clk_74a, // mainclk1
49 | input wire clk_74b, // mainclk1
50 |
51 | ///////////////////////////////////////////////////
52 | // cartridge interface
53 | // switches between 3.3v and 5v mechanically
54 | // output enable for multibit translators controlled by PIC32
55 |
56 | // GBA AD[15:8]
57 | inout wire [7:0] cart_tran_bank2,
58 | output wire cart_tran_bank2_dir,
59 |
60 | // GBA AD[7:0]
61 | inout wire [7:0] cart_tran_bank3,
62 | output wire cart_tran_bank3_dir,
63 |
64 | // GBA A[23:16]
65 | inout wire [7:0] cart_tran_bank1,
66 | output wire cart_tran_bank1_dir,
67 |
68 | // GBA [7] PHI#
69 | // GBA [6] WR#
70 | // GBA [5] RD#
71 | // GBA [4] CS1#/CS#
72 | // [3:0] unwired
73 | inout wire [7:4] cart_tran_bank0,
74 | output wire cart_tran_bank0_dir,
75 |
76 | // GBA CS2#/RES#
77 | inout wire cart_tran_pin30,
78 | output wire cart_tran_pin30_dir,
79 | // when GBC cart is inserted, this signal when low or weak will pull GBC /RES low with a special circuit
80 | // the goal is that when unconfigured, the FPGA weak pullups won't interfere.
81 | // thus, if GBC cart is inserted, FPGA must drive this high in order to let the level translators
82 | // and general IO drive this pin.
83 | output wire cart_pin30_pwroff_reset,
84 |
85 | // GBA IRQ/DRQ
86 | inout wire cart_tran_pin31,
87 | output wire cart_tran_pin31_dir,
88 |
89 | // infrared
90 | // avoid driving the TX LED with DC or leaving it stuck on. pulsed usage is fine
91 | input wire port_ir_rx,
92 | output wire port_ir_tx,
93 | output wire port_ir_rx_disable,
94 |
95 | // GBA link port
96 | inout wire port_tran_si,
97 | output wire port_tran_si_dir,
98 | inout wire port_tran_so,
99 | output wire port_tran_so_dir,
100 | inout wire port_tran_sck,
101 | output wire port_tran_sck_dir,
102 | inout wire port_tran_sd,
103 | output wire port_tran_sd_dir,
104 |
105 | ///////////////////////////////////////////////////
106 | // video output to the scaler
107 |
108 | inout wire [11:0] scal_vid,
109 | inout wire scal_clk,
110 | inout wire scal_de,
111 | inout wire scal_skip,
112 | inout wire scal_vs,
113 | inout wire scal_hs,
114 |
115 | output wire scal_audmclk,
116 | input wire scal_audadc,
117 | output wire scal_auddac,
118 | output wire scal_audlrck,
119 |
120 | ///////////////////////////////////////////////////
121 | // communication between main and scaler (aristotle) fpga.
122 | // spi bus with aristotle as controller.
123 |
124 | inout wire bridge_spimosi,
125 | inout wire bridge_spimiso,
126 | inout wire bridge_spiclk,
127 | input wire bridge_spiss,
128 | inout wire bridge_1wire,
129 |
130 | ///////////////////////////////////////////////////
131 | // cellular psram 0 and 1, two chips (64mbit x2 dual die per chip)
132 |
133 | output wire [21:16] cram0_a,
134 | inout wire [15:0] cram0_dq,
135 | input wire cram0_wait,
136 | output wire cram0_clk,
137 | output wire cram0_adv_n,
138 | output wire cram0_cre,
139 | output wire cram0_ce0_n,
140 | output wire cram0_ce1_n,
141 | output wire cram0_oe_n,
142 | output wire cram0_we_n,
143 | output wire cram0_ub_n,
144 | output wire cram0_lb_n,
145 |
146 | output wire [21:16] cram1_a,
147 | inout wire [15:0] cram1_dq,
148 | input wire cram1_wait,
149 | output wire cram1_clk,
150 | output wire cram1_adv_n,
151 | output wire cram1_cre,
152 | output wire cram1_ce0_n,
153 | output wire cram1_ce1_n,
154 | output wire cram1_oe_n,
155 | output wire cram1_we_n,
156 | output wire cram1_ub_n,
157 | output wire cram1_lb_n,
158 |
159 | ///////////////////////////////////////////////////
160 | // sdram, 512mbit x16
161 |
162 | output wire [12:0] dram_a,
163 | output wire [1:0] dram_ba,
164 | inout wire [15:0] dram_dq,
165 | output wire [1:0] dram_dqm,
166 | output wire dram_clk,
167 | output wire dram_cke,
168 | output wire dram_ras_n,
169 | output wire dram_cas_n,
170 | output wire dram_we_n,
171 |
172 | ///////////////////////////////////////////////////
173 | // sram, 1mbit x16
174 |
175 | output wire [16:0] sram_a,
176 | inout wire [15:0] sram_dq,
177 | output wire sram_oe_n,
178 | output wire sram_we_n,
179 | output wire sram_ub_n,
180 | output wire sram_lb_n,
181 |
182 | ///////////////////////////////////////////////////
183 | // vblank output to scaler
184 |
185 | input wire vblank,
186 |
187 | ///////////////////////////////////////////////////
188 | // i/o to 6515D breakout usb uart
189 |
190 | output wire dbg_tx,
191 | input wire dbg_rx,
192 |
193 | ///////////////////////////////////////////////////
194 | // i/o pads near jtag connector user can solder to
195 |
196 | output wire user1,
197 | input wire user2,
198 |
199 | ///////////////////////////////////////////////////
200 | // powerup self test, do not use
201 |
202 | inout wire bist,
203 | output wire vpll_feed,
204 |
205 | ///////////////////////////////////////////////////
206 | // RFU internal i2c bus (DNU)
207 |
208 | inout wire aux_sda,
209 | output wire aux_scl
210 |
211 | );
212 |
213 | assign bist = 1'bZ;
214 |
215 | // reset generation
216 |
217 | reg [24:0] count;
218 | reg reset_n;
219 |
220 | initial begin
221 | count <= 0;
222 | reset_n <= 0;
223 | end
224 | always @(posedge clk_74a) begin
225 | count <= count + 1'b1;
226 |
227 | if(count[15]) begin
228 | // exit reset
229 | reset_n <= 1;
230 | end
231 |
232 | end
233 |
234 |
235 |
236 |
237 | // convert 24-bit rgb data to 12-bit DDR for ARISTOTLE
238 |
239 | wire [23:0] video_rgb;
240 | wire video_rgb_clock;
241 | wire video_rgb_clock_90;
242 | wire video_de;
243 | wire video_skip;
244 | wire video_vs;
245 | wire video_hs;
246 |
247 | mf_ddio_bidir_12 isco (
248 | .oe ( 1'b1 ),
249 | .datain_h ( video_rgb[23:12] ),
250 | .datain_l ( video_rgb[11: 0] ),
251 | .outclock ( video_rgb_clock ),
252 | .padio ( scal_ddio_12 )
253 | );
254 |
255 | wire [11:0] scal_ddio_12;
256 | assign scal_vid = scal_ddio_12;
257 |
258 | mf_ddio_bidir_12 iscc (
259 | .oe ( 1'b1 ),
260 | .datain_h ( {video_vs, video_hs, video_de, video_skip} ),
261 | .datain_l ( {video_vs, video_hs, video_de, video_skip} ),
262 | .outclock ( video_rgb_clock ),
263 | .padio ( scal_ddio_ctrl )
264 | );
265 |
266 | wire [3:0] scal_ddio_ctrl;
267 | assign scal_vs = scal_ddio_ctrl[3];
268 | assign scal_hs = scal_ddio_ctrl[2];
269 | assign scal_de = scal_ddio_ctrl[1];
270 | assign scal_skip = scal_ddio_ctrl[0];
271 |
272 | mf_ddio_bidir_12 isclk(
273 | .oe ( 1'b1 ),
274 | .datain_h ( 1'b1 ),
275 | .datain_l ( 1'b0 ),
276 | .outclock ( video_rgb_clock_90 ),
277 | .padio ( scal_clk )
278 | );
279 |
280 |
281 |
282 | // controller data (pad) controller.
283 | wire [31:0] cont1_key;
284 | wire [31:0] cont2_key;
285 | wire [31:0] cont3_key;
286 | wire [31:0] cont4_key;
287 | wire [31:0] cont1_joy;
288 | wire [31:0] cont2_joy;
289 | wire [31:0] cont3_joy;
290 | wire [31:0] cont4_joy;
291 | wire [15:0] cont1_trig;
292 | wire [15:0] cont2_trig;
293 | wire [15:0] cont3_trig;
294 | wire [15:0] cont4_trig;
295 |
296 | io_pad_controller ipm (
297 | .clk ( clk_74a ),
298 | .reset_n ( reset_n ),
299 |
300 | .pad_1wire ( bridge_1wire ),
301 |
302 | .cont1_key ( cont1_key ),
303 | .cont2_key ( cont2_key ),
304 | .cont3_key ( cont3_key ),
305 | .cont4_key ( cont4_key ),
306 | .cont1_joy ( cont1_joy ),
307 | .cont2_joy ( cont2_joy ),
308 | .cont3_joy ( cont3_joy ),
309 | .cont4_joy ( cont4_joy ),
310 | .cont1_trig ( cont1_trig ),
311 | .cont2_trig ( cont2_trig ),
312 | .cont3_trig ( cont3_trig ),
313 | .cont4_trig ( cont4_trig )
314 | );
315 |
316 |
317 | // virtual pmp bridge
318 | wire bridge_endian_little;
319 | wire [31:0] bridge_addr;
320 | wire bridge_rd;
321 | wire [31:0] bridge_rd_data;
322 | wire bridge_wr;
323 | wire [31:0] bridge_wr_data;
324 |
325 | io_bridge_peripheral ibs (
326 |
327 | .clk ( clk_74a ),
328 | .reset_n ( reset_n ),
329 |
330 | .endian_little ( bridge_endian_little ),
331 |
332 | .pmp_addr ( bridge_addr ),
333 | .pmp_rd ( bridge_rd ),
334 | .pmp_rd_data ( bridge_rd_data ),
335 | .pmp_wr ( bridge_wr ),
336 | .pmp_wr_data ( bridge_wr_data ),
337 |
338 | .phy_spimosi ( bridge_spimosi ),
339 | .phy_spimiso ( bridge_spimiso ),
340 | .phy_spiclk ( bridge_spiclk ),
341 | .phy_spiss ( bridge_spiss )
342 |
343 | );
344 |
345 |
346 | ///////////////////////////////////////////////////
347 | // instantiate the user core top-level
348 |
349 | core_top ic (
350 |
351 | // physical connections
352 | //
353 | .clk_74a ( clk_74a ),
354 | .clk_74b ( clk_74b ),
355 |
356 | .cart_tran_bank2 ( cart_tran_bank2 ),
357 | .cart_tran_bank2_dir ( cart_tran_bank2_dir ),
358 | .cart_tran_bank3 ( cart_tran_bank3 ),
359 | .cart_tran_bank3_dir ( cart_tran_bank3_dir ),
360 | .cart_tran_bank1 ( cart_tran_bank1 ),
361 | .cart_tran_bank1_dir ( cart_tran_bank1_dir ),
362 | .cart_tran_bank0 ( cart_tran_bank0 ),
363 | .cart_tran_bank0_dir ( cart_tran_bank0_dir ),
364 | .cart_tran_pin30 ( cart_tran_pin30 ),
365 | .cart_tran_pin30_dir ( cart_tran_pin30_dir ),
366 | .cart_pin30_pwroff_reset ( cart_pin30_pwroff_reset ),
367 | .cart_tran_pin31 ( cart_tran_pin31 ),
368 | .cart_tran_pin31_dir ( cart_tran_pin31_dir ),
369 |
370 | .port_ir_rx ( port_ir_rx ),
371 | .port_ir_tx ( port_ir_tx ),
372 | .port_ir_rx_disable ( port_ir_rx_disable ),
373 |
374 | .port_tran_si ( port_tran_si ),
375 | .port_tran_si_dir ( port_tran_si_dir ),
376 | .port_tran_so ( port_tran_so ),
377 | .port_tran_so_dir ( port_tran_so_dir ),
378 | .port_tran_sck ( port_tran_sck ),
379 | .port_tran_sck_dir ( port_tran_sck_dir ),
380 | .port_tran_sd ( port_tran_sd ),
381 | .port_tran_sd_dir ( port_tran_sd_dir ),
382 |
383 | .cram0_a ( cram0_a ),
384 | .cram0_dq ( cram0_dq ),
385 | .cram0_wait ( cram0_wait ),
386 | .cram0_clk ( cram0_clk ),
387 | .cram0_adv_n ( cram0_adv_n ),
388 | .cram0_cre ( cram0_cre ),
389 | .cram0_ce0_n ( cram0_ce0_n ),
390 | .cram0_ce1_n ( cram0_ce1_n ),
391 | .cram0_oe_n ( cram0_oe_n ),
392 | .cram0_we_n ( cram0_we_n ),
393 | .cram0_ub_n ( cram0_ub_n ),
394 | .cram0_lb_n ( cram0_lb_n ),
395 | .cram1_a ( cram1_a ),
396 | .cram1_dq ( cram1_dq ),
397 | .cram1_wait ( cram1_wait ),
398 | .cram1_clk ( cram1_clk ),
399 | .cram1_adv_n ( cram1_adv_n ),
400 | .cram1_cre ( cram1_cre ),
401 | .cram1_ce0_n ( cram1_ce0_n ),
402 | .cram1_ce1_n ( cram1_ce1_n ),
403 | .cram1_oe_n ( cram1_oe_n ),
404 | .cram1_we_n ( cram1_we_n ),
405 | .cram1_ub_n ( cram1_ub_n ),
406 | .cram1_lb_n ( cram1_lb_n ),
407 |
408 | .dram_a ( dram_a ),
409 | .dram_ba ( dram_ba ),
410 | .dram_dq ( dram_dq ),
411 | .dram_dqm ( dram_dqm ),
412 | .dram_clk ( dram_clk ),
413 | .dram_cke ( dram_cke ),
414 | .dram_ras_n ( dram_ras_n ),
415 | .dram_cas_n ( dram_cas_n ),
416 | .dram_we_n ( dram_we_n ),
417 |
418 | .sram_a ( sram_a ),
419 | .sram_dq ( sram_dq ),
420 | .sram_oe_n ( sram_oe_n ),
421 | .sram_we_n ( sram_we_n ),
422 | .sram_ub_n ( sram_ub_n ),
423 | .sram_lb_n ( sram_lb_n ),
424 |
425 | .vblank ( vblank ),
426 | .vpll_feed ( vpll_feed ),
427 |
428 | .dbg_tx ( dbg_tx ),
429 | .dbg_rx ( dbg_rx ),
430 | .user1 ( user1 ),
431 | .user2 ( user2 ),
432 |
433 | .aux_sda ( aux_sda ),
434 | .aux_scl ( aux_scl ),
435 |
436 |
437 | // logical connections with user core
438 | //
439 | .video_rgb ( video_rgb ),
440 | .video_rgb_clock ( video_rgb_clock ),
441 | .video_rgb_clock_90 ( video_rgb_clock_90 ),
442 | .video_de ( video_de ),
443 | .video_skip ( video_skip ),
444 | .video_vs ( video_vs ),
445 | .video_hs ( video_hs ),
446 |
447 | .audio_mclk ( scal_audmclk ),
448 | .audio_adc ( scal_audadc ),
449 | .audio_dac ( scal_auddac ),
450 | .audio_lrck ( scal_audlrck ),
451 |
452 | .bridge_endian_little ( bridge_endian_little ),
453 | .bridge_addr ( bridge_addr ),
454 | .bridge_rd ( bridge_rd ),
455 | .bridge_rd_data ( bridge_rd_data ),
456 | .bridge_wr ( bridge_wr ),
457 | .bridge_wr_data ( bridge_wr_data ),
458 |
459 | .cont1_key ( cont1_key ),
460 | .cont2_key ( cont2_key ),
461 | .cont3_key ( cont3_key ),
462 | .cont4_key ( cont4_key ),
463 | .cont1_joy ( cont1_joy ),
464 | .cont2_joy ( cont2_joy ),
465 | .cont3_joy ( cont3_joy ),
466 | .cont4_joy ( cont4_joy ),
467 | .cont1_trig ( cont1_trig ),
468 | .cont2_trig ( cont2_trig ),
469 | .cont3_trig ( cont3_trig ),
470 | .cont4_trig ( cont4_trig )
471 |
472 | );
473 |
474 | endmodule
475 |
476 |
--------------------------------------------------------------------------------
/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 : 20230308;
13 | 0E1 : 00210243;
14 | 0E2 : 35e2f538;
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 [31:0] cont1_key,
49 | output reg [31:0] cont2_key,
50 | output reg [31:0] cont3_key,
51 | output reg [31: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;
144 | 1: cont1_joy <= rx_word;
145 | 2: cont1_trig <= rx_word[15:0];
146 |
147 | 3: cont2_key <= rx_word;
148 | 4: cont2_joy <= rx_word;
149 | 5: cont2_trig <= rx_word[15:0];
150 |
151 | 6: cont3_key <= rx_word;
152 | 7: cont3_joy <= rx_word;
153 | 8: cont3_trig <= rx_word[15:0];
154 |
155 | 9: cont4_key <= rx_word;
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 "18.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 | // 18.1.1 Build 646 04/11/2019 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2019 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.qip:
--------------------------------------------------------------------------------
1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR"
2 | set_global_assignment -name IP_TOOL_VERSION "18.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 | // altera_mf
13 | // ============================================================
14 | // ************************************************************
15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
16 | //
17 | // 18.1.1 Build 646 04/11/2019 SJ Lite Edition
18 | // ************************************************************
19 |
20 |
21 | //Copyright (C) 2019 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 | // Retrieval info: LIB_FILE: altera_mf
135 |
--------------------------------------------------------------------------------
/src/fpga/core/core_bridge_cmd.v:
--------------------------------------------------------------------------------
1 | //
2 | // bridge host/target command handler
3 | // 2022 Analogue
4 | //
5 |
6 | // mapped to 0xF8xxxxxx on bridge
7 | // the spec is loose enough to allow implementation with either
8 | // block rams and a soft CPU, or simply hard logic with some case statements.
9 | //
10 | // the implementation spec is documented, and depending on your application you
11 | // may want to completely replace this module. this is only one of many
12 | // possible ways to accomplish the host/target command system and data table.
13 | //
14 | // this module should always be clocked by a direct clock input and never a PLL,
15 | // because it should report PLL lock status
16 | //
17 |
18 | module core_bridge_cmd (
19 |
20 | input wire clk,
21 | output reg reset_n,
22 |
23 | input wire bridge_endian_little,
24 | input wire [31:0] bridge_addr,
25 | input wire bridge_rd,
26 | output reg [31:0] bridge_rd_data,
27 | input wire bridge_wr,
28 | input wire [31:0] bridge_wr_data,
29 |
30 | // all these signals should be synchronous to clk
31 | // add synchronizers if these need to be used in other clock domains
32 | input wire status_boot_done, // assert when PLLs lock and logic is ready
33 | input wire status_setup_done, // assert when core is happy with what's been loaded into it
34 | input wire status_running, // assert when pocket's taken core out of reset and is running
35 |
36 | output reg dataslot_requestread,
37 | output reg [15:0] dataslot_requestread_id,
38 | input wire dataslot_requestread_ack,
39 | input wire dataslot_requestread_ok,
40 |
41 | output reg dataslot_requestwrite,
42 | output reg [15:0] dataslot_requestwrite_id,
43 | output reg [31:0] dataslot_requestwrite_size,
44 | input wire dataslot_requestwrite_ack,
45 | input wire dataslot_requestwrite_ok,
46 |
47 | output reg dataslot_update,
48 | output reg [15:0] dataslot_update_id,
49 | output reg [31:0] dataslot_update_size,
50 |
51 | output reg dataslot_allcomplete,
52 |
53 | output reg [31:0] rtc_epoch_seconds,
54 | output reg [31:0] rtc_date_bcd,
55 | output reg [31:0] rtc_time_bcd,
56 | output reg rtc_valid,
57 |
58 | input wire savestate_supported,
59 | input wire [31:0] savestate_addr,
60 | input wire [31:0] savestate_size,
61 | input wire [31:0] savestate_maxloadsize,
62 |
63 | output reg osnotify_inmenu,
64 |
65 | output reg savestate_start, // core should detect rising edge on this,
66 | input wire savestate_start_ack, // and then assert ack for at least 1 cycle
67 | input wire savestate_start_busy, // assert constantly while in progress after ack
68 | input wire savestate_start_ok, // assert continuously when done, and clear when new process is started
69 | input wire savestate_start_err, // assert continuously on error, and clear when new process is started
70 |
71 | output reg savestate_load,
72 | input wire savestate_load_ack,
73 | input wire savestate_load_busy,
74 | input wire savestate_load_ok,
75 | input wire savestate_load_err,
76 |
77 | input wire target_dataslot_read, // rising edge triggered
78 | input wire target_dataslot_write,
79 | input wire target_dataslot_getfile,
80 | input wire target_dataslot_openfile,
81 |
82 | output reg target_dataslot_ack, // asserted upon command start until completion
83 | output reg target_dataslot_done, // asserted upon command finish until next command is issued
84 | output reg [2:0] target_dataslot_err, // contains result of command execution. zero is OK
85 |
86 | input wire [15:0] target_dataslot_id, // parameters for each of the read/reload/write commands
87 | input wire [31:0] target_dataslot_slotoffset,
88 | input wire [31:0] target_dataslot_bridgeaddr,
89 | input wire [31:0] target_dataslot_length,
90 |
91 | input wire [31:0] target_buffer_param_struct, // bus address of the memory region APF will fetch additional parameter struct from
92 | input wire [31:0] target_buffer_resp_struct, // bus address of the memory region APF will write its response struct to
93 | // this should be mapped by the developer, the buffer is not implemented in this file
94 |
95 | input wire [9:0] datatable_addr,
96 | input wire datatable_wren,
97 | input wire [31:0] datatable_data,
98 | output wire [31:0] datatable_q
99 |
100 | );
101 |
102 | // handle endianness
103 | reg [31:0] bridge_wr_data_in;
104 | reg [31:0] bridge_rd_data_out;
105 |
106 | wire endian_little_s;
107 | synch_3 s01(bridge_endian_little, endian_little_s, clk);
108 |
109 | always @(*) begin
110 | bridge_rd_data <= endian_little_s ? {
111 | bridge_rd_data_out[7:0],
112 | bridge_rd_data_out[15:8],
113 | bridge_rd_data_out[23:16],
114 | bridge_rd_data_out[31:24]
115 | } : bridge_rd_data_out;
116 |
117 | bridge_wr_data_in <= endian_little_s ? {
118 | bridge_wr_data[7:0],
119 | bridge_wr_data[15:8],
120 | bridge_wr_data[23:16],
121 | bridge_wr_data[31:24]
122 | } : bridge_wr_data;
123 | end
124 |
125 |
126 | // minimalistic approach here -
127 | // keep the commonly used registers in logic, but data table in BRAM.
128 | // implementation could be changed quite a bit for a more advanced use case
129 |
130 | // host
131 |
132 | reg [31:0] host_0;
133 | reg [31:0] host_4 = 'h20; // host cmd parameter data at 0x20
134 | reg [31:0] host_8 = 'h40; // host cmd response data at 0x40
135 |
136 | reg [31:0] host_20; // parameter data
137 | reg [31:0] host_24;
138 | reg [31:0] host_28;
139 | reg [31:0] host_2C;
140 |
141 | reg [31:0] host_40; // response data
142 | reg [31:0] host_44;
143 | reg [31:0] host_48;
144 | reg [31:0] host_4C;
145 |
146 | reg host_cmd_start;
147 | reg [15:0] host_cmd_startval;
148 | reg [15:0] host_cmd;
149 | reg [15:0] host_resultcode;
150 |
151 | localparam [3:0] ST_IDLE = 'd0;
152 | localparam [3:0] ST_PARSE = 'd1;
153 | localparam [3:0] ST_WORK = 'd2;
154 | localparam [3:0] ST_DONE_OK = 'd13;
155 | localparam [3:0] ST_DONE_CODE = 'd14;
156 | localparam [3:0] ST_DONE_ERR = 'd15;
157 | reg [3:0] hstate;
158 |
159 | // target
160 |
161 | reg [31:0] target_0;
162 | reg [31:0] target_4 = 'h20; // target cmd parameter data at 0x20
163 | reg [31:0] target_8 = 'h40; // target cmd response data at 0x40
164 |
165 | reg [31:0] target_20; // parameter data
166 | reg [31:0] target_24;
167 | reg [31:0] target_28;
168 | reg [31:0] target_2C;
169 |
170 | reg [31:0] target_40; // response data
171 | reg [31:0] target_44;
172 | reg [31:0] target_48;
173 | reg [31:0] target_4C;
174 |
175 | localparam [3:0] TARG_ST_IDLE = 'd0;
176 | localparam [3:0] TARG_ST_READYTORUN = 'd1;
177 | localparam [3:0] TARG_ST_DATASLOTOP = 'd2;
178 | localparam [3:0] TARG_ST_WAITRESULT_RTR = 'd14;
179 | localparam [3:0] TARG_ST_WAITRESULT_DSO = 'd15;
180 | reg [3:0] tstate;
181 |
182 | reg status_setup_done_1, status_setup_done_queue;
183 | reg target_dataslot_read_1, target_dataslot_read_queue;
184 | reg target_dataslot_write_1, target_dataslot_write_queue;
185 | reg target_dataslot_getfile_1, target_dataslot_getfile_queue;
186 | reg target_dataslot_openfile_1, target_dataslot_openfile_queue;
187 |
188 |
189 | initial begin
190 | reset_n <= 0;
191 | dataslot_requestread <= 0;
192 | dataslot_requestwrite <= 0;
193 | dataslot_update <= 0;
194 | dataslot_allcomplete <= 0;
195 | rtc_valid <= 0;
196 | savestate_start <= 0;
197 | savestate_load <= 0;
198 | osnotify_inmenu <= 0;
199 |
200 | status_setup_done_queue <= 0;
201 | target_dataslot_read_queue <= 0;
202 | target_dataslot_write_queue <= 0;
203 | target_dataslot_getfile_queue <= 0;
204 | target_dataslot_openfile_queue <= 0;
205 | target_dataslot_ack <= 0;
206 | target_dataslot_done <= 0;
207 | target_dataslot_err <= 0;
208 | end
209 |
210 | always @(posedge clk) begin
211 |
212 | // detect a rising edge on the input signal
213 | // and flag a queue that will be cleared later
214 | status_setup_done_1 <= status_setup_done;
215 | target_dataslot_read_1 <= target_dataslot_read;
216 | target_dataslot_write_1 <= target_dataslot_write;
217 | target_dataslot_getfile_1 <= target_dataslot_getfile;
218 | target_dataslot_openfile_1 <= target_dataslot_openfile;
219 |
220 | if(status_setup_done & ~status_setup_done_1) begin
221 | status_setup_done_queue <= 1;
222 | end
223 | if(target_dataslot_read & ~target_dataslot_read_1) begin
224 | target_dataslot_read_queue <= 1;
225 | end
226 | if(target_dataslot_write & ~target_dataslot_write_1) begin
227 | target_dataslot_write_queue <= 1;
228 | end
229 | if(target_dataslot_getfile & ~target_dataslot_getfile_1) begin
230 | target_dataslot_getfile_queue <= 1;
231 | end
232 | if(target_dataslot_openfile & ~target_dataslot_openfile_1) begin
233 | target_dataslot_openfile_queue <= 1;
234 | end
235 |
236 |
237 | b_datatable_wren <= 0;
238 | b_datatable_addr <= bridge_addr >> 2;
239 |
240 | if(bridge_wr) begin
241 | casex(bridge_addr)
242 | 32'hF8xx00xx: begin
243 | case(bridge_addr[7:0])
244 | 8'h0: begin
245 | host_0 <= bridge_wr_data_in; // command/status
246 | // check for command
247 | if(bridge_wr_data_in[31:16] == 16'h434D) begin
248 | // host wants us to do a command
249 | host_cmd_startval <= bridge_wr_data_in[15:0];
250 | host_cmd_start <= 1;
251 | end
252 | end
253 | 8'h20: host_20 <= bridge_wr_data_in; // parameter data regs
254 | 8'h24: host_24 <= bridge_wr_data_in;
255 | 8'h28: host_28 <= bridge_wr_data_in;
256 | 8'h2C: host_2C <= bridge_wr_data_in;
257 | endcase
258 | end
259 | 32'hF8xx10xx: begin
260 | case(bridge_addr[7:0])
261 | 8'h0: target_0 <= bridge_wr_data_in; // command/status
262 | 8'h4: target_4 <= bridge_wr_data_in; // parameter data pointer
263 | 8'h8: target_8 <= bridge_wr_data_in; // response data pointer
264 | 8'h40: target_40 <= bridge_wr_data_in; // response data regs
265 | 8'h44: target_44 <= bridge_wr_data_in;
266 | 8'h48: target_48 <= bridge_wr_data_in;
267 | 8'h4C: target_4C <= bridge_wr_data_in;
268 | endcase
269 | end
270 | 32'hF8xx2xxx: begin
271 | b_datatable_wren <= 1;
272 | end
273 | endcase
274 | end
275 | if(bridge_rd) begin
276 | casex(bridge_addr)
277 | 32'hF8xx00xx: begin
278 | case(bridge_addr[7:0])
279 | 8'h0: bridge_rd_data_out <= host_0; // command/status
280 | 8'h4: bridge_rd_data_out <= host_4; // parameter data pointer
281 | 8'h8: bridge_rd_data_out <= host_8; // response data pointer
282 | 8'h40: bridge_rd_data_out <= host_40; // response data regs
283 | 8'h44: bridge_rd_data_out <= host_44;
284 | 8'h48: bridge_rd_data_out <= host_48;
285 | 8'h4C: bridge_rd_data_out <= host_4C;
286 | endcase
287 | end
288 | 32'hF8xx10xx: begin
289 | case(bridge_addr[7:0])
290 | 8'h0: bridge_rd_data_out <= target_0;
291 | 8'h4: bridge_rd_data_out <= target_4;
292 | 8'h8: bridge_rd_data_out <= target_8;
293 | 8'h20: bridge_rd_data_out <= target_20; // parameter data regs
294 | 8'h24: bridge_rd_data_out <= target_24;
295 | 8'h28: bridge_rd_data_out <= target_28;
296 | 8'h2C: bridge_rd_data_out <= target_2C;
297 | endcase
298 | end
299 | 32'hF8xx2xxx: begin
300 | bridge_rd_data_out <= b_datatable_q;
301 |
302 | end
303 | endcase
304 | end
305 |
306 |
307 |
308 |
309 |
310 | // host > target command executer
311 | case(hstate)
312 | ST_IDLE: begin
313 |
314 | dataslot_requestread <= 0;
315 | dataslot_requestwrite <= 0;
316 | dataslot_update <= 0;
317 | savestate_start <= 0;
318 | savestate_load <= 0;
319 |
320 | // there is no queueing. pocket will always make sure any outstanding host
321 | // commands are finished before starting another
322 | if(host_cmd_start) begin
323 | host_cmd_start <= 0;
324 | // save the command in case it gets clobbered later
325 | host_cmd <= host_cmd_startval;
326 | hstate <= ST_PARSE;
327 | end
328 |
329 | end
330 | ST_PARSE: begin
331 | // overwrite command semaphore with busy flag
332 | host_0 <= {16'h4255, host_cmd};
333 |
334 | case(host_cmd)
335 | 16'h0000: begin
336 | // Request Status
337 | host_resultcode <= 1; // default: booting
338 | if(status_boot_done) begin
339 | host_resultcode <= 2; // setup
340 | if(status_setup_done) begin
341 | host_resultcode <= 3; // idle
342 | end else if(status_running) begin
343 | host_resultcode <= 4; // running
344 | end
345 | end
346 | hstate <= ST_DONE_CODE;
347 | end
348 | 16'h0010: begin
349 | // Reset Enter
350 | reset_n <= 0;
351 | hstate <= ST_DONE_OK;
352 | end
353 | 16'h0011: begin
354 | // Reset Exit
355 | reset_n <= 1;
356 | hstate <= ST_DONE_OK;
357 | end
358 | 16'h0080: begin
359 | // Data slot request read
360 | dataslot_allcomplete <= 0;
361 | dataslot_requestread <= 1;
362 | dataslot_requestread_id <= host_20[15:0];
363 | if(dataslot_requestread_ack) begin
364 | host_resultcode <= 0;
365 | if(!dataslot_requestread_ok) host_resultcode <= 2;
366 | hstate <= ST_DONE_CODE;
367 | end
368 | end
369 | 16'h0082: begin
370 | // Data slot request write
371 | dataslot_allcomplete <= 0;
372 | dataslot_requestwrite <= 1;
373 | dataslot_requestwrite_id <= host_20[15:0];
374 | dataslot_requestwrite_size <= host_24;
375 | if(dataslot_requestwrite_ack) begin
376 | host_resultcode <= 0;
377 | if(!dataslot_requestwrite_ok) host_resultcode <= 2;
378 | hstate <= ST_DONE_CODE;
379 | end
380 | end
381 | 16'h008A: begin
382 | // Data slot update (sent on deferload marked slots only)
383 | dataslot_update <= 1;
384 | dataslot_update_id <= host_20[15:0];
385 | dataslot_update_size <= host_24;
386 | hstate <= ST_DONE_OK;
387 | end
388 | 16'h008F: begin
389 | // Data slot access all complete
390 | dataslot_allcomplete <= 1;
391 | hstate <= ST_DONE_OK;
392 | end
393 | 16'h0090: begin
394 | // Real-time Clock Data
395 | // user logic should detect rising edge, it is not continuously updated
396 | rtc_valid <= 1;
397 | rtc_epoch_seconds <= host_20;
398 | rtc_date_bcd <= host_24;
399 | rtc_time_bcd <= host_28;
400 | hstate <= ST_DONE_OK;
401 | end
402 | 16'h00A0: begin
403 | // Savestate: Start/Query
404 | host_40 <= savestate_supported;
405 | host_44 <= savestate_addr;
406 | host_48 <= savestate_size;
407 |
408 | host_resultcode <= 0;
409 | if(savestate_start_busy) host_resultcode <= 1;
410 | if(savestate_start_ok) host_resultcode <= 2;
411 | if(savestate_start_err) host_resultcode <= 3;
412 |
413 | if(host_20[0]) begin
414 | // Request Start!
415 | savestate_start <= 1;
416 | // stay in this state until ack'd
417 | if(savestate_start_ack) begin
418 | hstate <= ST_DONE_CODE;
419 | end
420 | end else begin
421 | hstate <= ST_DONE_CODE;
422 | end
423 | end
424 | 16'h00A4: begin
425 | // Savestate: Load/Query
426 | host_40 <= savestate_supported;
427 | host_44 <= savestate_addr;
428 | host_48 <= savestate_maxloadsize;
429 |
430 | host_resultcode <= 0;
431 | if(savestate_load_busy) host_resultcode <= 1;
432 | if(savestate_load_ok) host_resultcode <= 2;
433 | if(savestate_load_err) host_resultcode <= 3;
434 |
435 | if(host_20[0]) begin
436 | // Request Load!
437 | savestate_load <= 1;
438 | // stay in this state until ack'd
439 | if(savestate_load_ack) begin
440 | hstate <= ST_DONE_CODE;
441 | end
442 | end else begin
443 | hstate <= ST_DONE_CODE;
444 | end
445 | end
446 | 16'h00B0: begin
447 | // OS Notify: Menu State
448 | osnotify_inmenu <= host_20[0];
449 | hstate <= ST_DONE_OK;
450 | end
451 | default: begin
452 | hstate <= ST_DONE_ERR;
453 | end
454 | endcase
455 | end
456 | ST_WORK: begin
457 | hstate <= ST_IDLE;
458 | end
459 | ST_DONE_OK: begin
460 | host_0 <= 32'h4F4B0000; // result code 0
461 | hstate <= ST_IDLE;
462 | end
463 | ST_DONE_CODE: begin
464 | host_0 <= {16'h4F4B, host_resultcode};
465 | hstate <= ST_IDLE;
466 | end
467 | ST_DONE_ERR: begin
468 | host_0 <= 32'h4F4BFFFF; // result code FFFF = unknown command
469 | hstate <= ST_IDLE;
470 | end
471 | endcase
472 |
473 |
474 | // target > host command executer
475 | case(tstate)
476 | TARG_ST_IDLE: begin
477 |
478 | target_dataslot_ack <= 0;
479 |
480 | if(status_setup_done_queue) begin
481 | status_setup_done_queue <= 0;
482 | tstate <= TARG_ST_READYTORUN;
483 |
484 | end else if(target_dataslot_read_queue) begin
485 | target_dataslot_read_queue <= 0;
486 | target_0[15:0] <= 16'h0180;
487 |
488 | target_20 <= target_dataslot_id;
489 | target_24 <= target_dataslot_slotoffset;
490 | target_28 <= target_dataslot_bridgeaddr;
491 | target_2C <= target_dataslot_length;
492 |
493 | tstate <= TARG_ST_DATASLOTOP;
494 |
495 | end else if(target_dataslot_write_queue) begin
496 | target_dataslot_write_queue <= 0;
497 | target_0[15:0] <= 16'h0184;
498 |
499 | target_20 <= target_dataslot_id;
500 | target_24 <= target_dataslot_slotoffset;
501 | target_28 <= target_dataslot_bridgeaddr;
502 | target_2C <= target_dataslot_length;
503 |
504 | tstate <= TARG_ST_DATASLOTOP;
505 |
506 | end else if(target_dataslot_getfile_queue) begin
507 | target_dataslot_getfile_queue <= 0;
508 | target_0[15:0] <= 16'h0190;
509 |
510 | target_20 <= target_dataslot_id;
511 | target_24 <= target_buffer_resp_struct; // pointer to the bram that will hold the response struct
512 | // which will contain the requested filename before command completion
513 | tstate <= TARG_ST_DATASLOTOP;
514 |
515 | end else if(target_dataslot_openfile_queue) begin
516 | target_dataslot_openfile_queue <= 0;
517 | target_0[15:0] <= 16'h0192;
518 |
519 | target_20 <= target_dataslot_id;
520 | target_24 <= target_buffer_param_struct; // pointer to the bram that will hold the parameter struct
521 | // which must contain the desired filename and flag/size before command execution
522 | tstate <= TARG_ST_DATASLOTOP;
523 | end
524 | end
525 | TARG_ST_READYTORUN: begin
526 | target_0 <= 32'h636D_0140;
527 | tstate <= TARG_ST_WAITRESULT_RTR;
528 | end
529 | TARG_ST_DATASLOTOP: begin
530 | target_0[31:16] <= 16'h636D;
531 |
532 | target_dataslot_done <= 0;
533 | target_dataslot_err <= 0;
534 | tstate <= TARG_ST_WAITRESULT_DSO;
535 | end
536 | TARG_ST_WAITRESULT_DSO: begin
537 | if(target_0[31:16] == 16'h6275) begin
538 | target_dataslot_ack <= 1;
539 | end
540 | if(target_0[31:16] == 16'h6F6B) begin
541 | // done
542 | // save result code
543 | target_dataslot_err <= target_0[2:0];
544 | // assert done
545 | target_dataslot_done <= 1;
546 | tstate <= TARG_ST_IDLE;
547 | end
548 | end
549 | TARG_ST_WAITRESULT_RTR: begin
550 | if(target_0[31:16] == 16'h6F6B) begin
551 | // done
552 | tstate <= TARG_ST_IDLE;
553 | end
554 |
555 | end
556 | endcase
557 |
558 |
559 | end
560 |
561 | wire [31:0] b_datatable_q;
562 | reg [9:0] b_datatable_addr;
563 | reg b_datatable_wren;
564 |
565 | mf_datatable idt (
566 | .address_a ( datatable_addr ),
567 | .address_b ( b_datatable_addr ),
568 | .clock_a ( clk ),
569 | .clock_b ( clk ),
570 | .data_a ( datatable_data ),
571 | .data_b ( bridge_wr_data_in ),
572 | .wren_a ( datatable_wren ),
573 | .wren_b ( b_datatable_wren ),
574 | .q_a ( datatable_q ),
575 | .q_b ( b_datatable_q )
576 | );
577 |
578 |
579 | endmodule
580 |
--------------------------------------------------------------------------------
/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 } \
13 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \
14 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk }
15 |
--------------------------------------------------------------------------------
/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) 2019 Intel Corporation. All rights reserved.
8 | Your use of Intel Corporation's design tools, logic functions
9 | and other software and tools, and any 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, at
20 | https://fpgasoftware.intel.com/eula.
21 | */
22 | (header "symbol" (version "1.1"))
23 | (symbol
24 | (rect 0 0 160 304)
25 | (text "mf_pllbase" (rect 48 -1 91 11)(font "Arial" (font_size 10)))
26 | (text "inst" (rect 8 288 20 300)(font "Arial" ))
27 | (port
28 | (pt 0 72)
29 | (input)
30 | (text "refclk" (rect 0 0 22 12)(font "Arial" (font_size 8)))
31 | (text "refclk" (rect 4 61 40 72)(font "Arial" (font_size 8)))
32 | (line (pt 0 72)(pt 48 72)(line_width 1))
33 | )
34 | (port
35 | (pt 0 112)
36 | (input)
37 | (text "rst" (rect 0 0 10 12)(font "Arial" (font_size 8)))
38 | (text "rst" (rect 4 101 22 112)(font "Arial" (font_size 8)))
39 | (line (pt 0 112)(pt 48 112)(line_width 1))
40 | )
41 | (port
42 | (pt 160 72)
43 | (output)
44 | (text "outclk_0" (rect 0 0 33 12)(font "Arial" (font_size 8)))
45 | (text "outclk_0" (rect 117 61 165 72)(font "Arial" (font_size 8)))
46 | (line (pt 160 72)(pt 112 72)(line_width 1))
47 | )
48 | (port
49 | (pt 160 112)
50 | (output)
51 | (text "outclk_1" (rect 0 0 31 12)(font "Arial" (font_size 8)))
52 | (text "outclk_1" (rect 119 101 167 112)(font "Arial" (font_size 8)))
53 | (line (pt 160 112)(pt 112 112)(line_width 1))
54 | )
55 | (port
56 | (pt 160 152)
57 | (output)
58 | (text "outclk_2" (rect 0 0 33 12)(font "Arial" (font_size 8)))
59 | (text "outclk_2" (rect 117 141 165 152)(font "Arial" (font_size 8)))
60 | (line (pt 160 152)(pt 112 152)(line_width 1))
61 | )
62 | (port
63 | (pt 160 192)
64 | (output)
65 | (text "outclk_3" (rect 0 0 33 12)(font "Arial" (font_size 8)))
66 | (text "outclk_3" (rect 117 181 165 192)(font "Arial" (font_size 8)))
67 | (line (pt 160 192)(pt 112 192)(line_width 1))
68 | )
69 | (port
70 | (pt 160 232)
71 | (output)
72 | (text "outclk_4" (rect 0 0 34 12)(font "Arial" (font_size 8)))
73 | (text "outclk_4" (rect 117 221 165 232)(font "Arial" (font_size 8)))
74 | (line (pt 160 232)(pt 112 232)(line_width 1))
75 | )
76 | (port
77 | (pt 160 272)
78 | (output)
79 | (text "locked" (rect 0 0 24 12)(font "Arial" (font_size 8)))
80 | (text "locked" (rect 127 261 163 272)(font "Arial" (font_size 8)))
81 | (line (pt 160 272)(pt 112 272)(line_width 1))
82 | )
83 | (drawing
84 | (text "refclk" (rect 16 43 68 99)(font "Arial" (color 128 0 0)(font_size 9)))
85 | (text "clk" (rect 53 67 124 144)(font "Arial" (color 0 0 0)))
86 | (text "reset" (rect 19 83 68 179)(font "Arial" (color 128 0 0)(font_size 9)))
87 | (text "reset" (rect 53 107 136 224)(font "Arial" (color 0 0 0)))
88 | (text "outclk0" (rect 113 43 268 99)(font "Arial" (color 128 0 0)(font_size 9)))
89 | (text "clk" (rect 97 67 212 144)(font "Arial" (color 0 0 0)))
90 | (text "outclk1" (rect 113 83 268 179)(font "Arial" (color 128 0 0)(font_size 9)))
91 | (text "clk" (rect 97 107 212 224)(font "Arial" (color 0 0 0)))
92 | (text "outclk2" (rect 113 123 268 259)(font "Arial" (color 128 0 0)(font_size 9)))
93 | (text "clk" (rect 97 147 212 304)(font "Arial" (color 0 0 0)))
94 | (text "outclk3" (rect 113 163 268 339)(font "Arial" (color 128 0 0)(font_size 9)))
95 | (text "clk" (rect 97 187 212 384)(font "Arial" (color 0 0 0)))
96 | (text "outclk4" (rect 113 203 268 419)(font "Arial" (color 128 0 0)(font_size 9)))
97 | (text "clk" (rect 97 227 212 464)(font "Arial" (color 0 0 0)))
98 | (text "locked" (rect 113 243 262 499)(font "Arial" (color 128 0 0)(font_size 9)))
99 | (text "export" (rect 82 267 200 544)(font "Arial" (color 0 0 0)))
100 | (text " altera_pll " (rect 118 288 308 586)(font "Arial" ))
101 | (line (pt 48 32)(pt 112 32)(line_width 1))
102 | (line (pt 112 32)(pt 112 288)(line_width 1))
103 | (line (pt 48 288)(pt 112 288)(line_width 1))
104 | (line (pt 48 32)(pt 48 288)(line_width 1))
105 | (line (pt 49 52)(pt 49 76)(line_width 1))
106 | (line (pt 50 52)(pt 50 76)(line_width 1))
107 | (line (pt 49 92)(pt 49 116)(line_width 1))
108 | (line (pt 50 92)(pt 50 116)(line_width 1))
109 | (line (pt 111 52)(pt 111 76)(line_width 1))
110 | (line (pt 110 52)(pt 110 76)(line_width 1))
111 | (line (pt 111 92)(pt 111 116)(line_width 1))
112 | (line (pt 110 92)(pt 110 116)(line_width 1))
113 | (line (pt 111 132)(pt 111 156)(line_width 1))
114 | (line (pt 110 132)(pt 110 156)(line_width 1))
115 | (line (pt 111 172)(pt 111 196)(line_width 1))
116 | (line (pt 110 172)(pt 110 196)(line_width 1))
117 | (line (pt 111 212)(pt 111 236)(line_width 1))
118 | (line (pt 110 212)(pt 110 236)(line_width 1))
119 | (line (pt 111 252)(pt 111 276)(line_width 1))
120 | (line (pt 110 252)(pt 110 276)(line_width 1))
121 | (line (pt 0 0)(pt 160 0)(line_width 1))
122 | (line (pt 160 0)(pt 160 304)(line_width 1))
123 | (line (pt 0 304)(pt 160 304)(line_width 1))
124 | (line (pt 0 0)(pt 0 304)(line_width 1))
125 | )
126 | )
127 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase.ppf:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/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.1"
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.v:
--------------------------------------------------------------------------------
1 | // megafunction wizard: %PLL Intel FPGA IP v18.1%
2 | // GENERATION: XML
3 | // mf_pllbase.v
4 |
5 | // Generated using ACDS version 18.1 646
6 |
7 | `timescale 1 ps / 1 ps
8 | module mf_pllbase (
9 | input wire refclk, // refclk.clk
10 | input wire rst, // reset.reset
11 | output wire outclk_0, // outclk0.clk
12 | output wire outclk_1, // outclk1.clk
13 | output wire outclk_2, // outclk2.clk
14 | output wire outclk_3, // outclk3.clk
15 | output wire outclk_4, // outclk4.clk
16 | output wire locked // locked.export
17 | );
18 |
19 | mf_pllbase_0002 mf_pllbase_inst (
20 | .refclk (refclk), // refclk.clk
21 | .rst (rst), // reset.reset
22 | .outclk_0 (outclk_0), // outclk0.clk
23 | .outclk_1 (outclk_1), // outclk1.clk
24 | .outclk_2 (outclk_2), // outclk2.clk
25 | .outclk_3 (outclk_3), // outclk3.clk
26 | .outclk_4 (outclk_4), // outclk4.clk
27 | .locked (locked) // locked.export
28 | );
29 |
30 | endmodule
31 | // Retrieval info:
32 | //
57 | // Retrieval info:
58 | // Retrieval info:
59 | // Retrieval info:
60 | // Retrieval info:
61 | // Retrieval info:
62 | // Retrieval info:
63 | // Retrieval info:
64 | // Retrieval info:
65 | // Retrieval info:
66 | // Retrieval info:
67 | // Retrieval info:
68 | // Retrieval info:
69 | // Retrieval info:
70 | // Retrieval info:
71 | // Retrieval info:
72 | // Retrieval info:
73 | // Retrieval info:
74 | // Retrieval info:
75 | // Retrieval info:
76 | // Retrieval info:
77 | // Retrieval info:
78 | // Retrieval info:
79 | // Retrieval info:
80 | // Retrieval info:
81 | // Retrieval info:
82 | // Retrieval info:
83 | // Retrieval info:
84 | // Retrieval info:
85 | // Retrieval info:
86 | // Retrieval info:
87 | // Retrieval info:
88 | // Retrieval info:
89 | // Retrieval info:
90 | // Retrieval info:
91 | // Retrieval info:
92 | // Retrieval info:
93 | // Retrieval info:
94 | // Retrieval info:
95 | // Retrieval info:
96 | // Retrieval info:
97 | // Retrieval info:
98 | // Retrieval info:
99 | // Retrieval info:
100 | // Retrieval info:
101 | // Retrieval info:
102 | // Retrieval info:
103 | // Retrieval info:
104 | // Retrieval info:
105 | // Retrieval info:
106 | // Retrieval info:
107 | // Retrieval info:
108 | // Retrieval info:
109 | // Retrieval info:
110 | // Retrieval info:
111 | // Retrieval info:
112 | // Retrieval info:
113 | // Retrieval info:
114 | // Retrieval info:
115 | // Retrieval info:
116 | // Retrieval info:
117 | // Retrieval info:
118 | // Retrieval info:
119 | // Retrieval info:
120 | // Retrieval info:
121 | // Retrieval info:
122 | // Retrieval info:
123 | // Retrieval info:
124 | // Retrieval info:
125 | // Retrieval info:
126 | // Retrieval info:
127 | // Retrieval info:
128 | // Retrieval info:
129 | // Retrieval info:
130 | // Retrieval info:
131 | // Retrieval info:
132 | // Retrieval info:
133 | // Retrieval info:
134 | // Retrieval info:
135 | // Retrieval info:
136 | // Retrieval info:
137 | // Retrieval info:
138 | // Retrieval info:
139 | // Retrieval info:
140 | // Retrieval info:
141 | // Retrieval info:
142 | // Retrieval info:
143 | // Retrieval info:
144 | // Retrieval info:
145 | // Retrieval info:
146 | // Retrieval info:
147 | // Retrieval info:
148 | // Retrieval info:
149 | // Retrieval info:
150 | // Retrieval info:
151 | // Retrieval info:
152 | // Retrieval info:
153 | // Retrieval info:
154 | // Retrieval info:
155 | // Retrieval info:
156 | // Retrieval info:
157 | // Retrieval info:
158 | // Retrieval info:
159 | // Retrieval info:
160 | // Retrieval info:
161 | // Retrieval info:
162 | // Retrieval info:
163 | // Retrieval info:
164 | // Retrieval info:
165 | // Retrieval info:
166 | // Retrieval info:
167 | // Retrieval info:
168 | // Retrieval info:
169 | // Retrieval info:
170 | // Retrieval info:
171 | // Retrieval info:
172 | // Retrieval info:
173 | // Retrieval info:
174 | // Retrieval info:
175 | // Retrieval info:
176 | // Retrieval info:
177 | // Retrieval info:
178 | // Retrieval info:
179 | // Retrieval info:
180 | // Retrieval info:
181 | // Retrieval info:
182 | // Retrieval info:
183 | // Retrieval info:
184 | // Retrieval info:
185 | // Retrieval info:
186 | // Retrieval info:
187 | // Retrieval info:
188 | // Retrieval info:
189 | // Retrieval info:
190 | // Retrieval info:
191 | // Retrieval info:
192 | // Retrieval info:
193 | // Retrieval info:
194 | // Retrieval info:
195 | // Retrieval info:
196 | // Retrieval info:
197 | // Retrieval info:
198 | // Retrieval info:
199 | // Retrieval info:
200 | // Retrieval info:
201 | // Retrieval info:
202 | // Retrieval info:
203 | // Retrieval info:
204 | // Retrieval info:
205 | // Retrieval info:
206 | // Retrieval info:
207 | // Retrieval info:
208 | // Retrieval info:
209 | // Retrieval info:
210 | // Retrieval info:
211 | // Retrieval info:
212 | // Retrieval info:
213 | // Retrieval info:
214 | // Retrieval info:
215 | // Retrieval info:
216 | // Retrieval info:
217 | // Retrieval info:
218 | // Retrieval info:
219 | // Retrieval info:
220 | // Retrieval info:
221 | // Retrieval info:
222 | // Retrieval info:
223 | // Retrieval info:
224 | // Retrieval info:
225 | // Retrieval info:
226 | // Retrieval info:
227 | // Retrieval info:
228 | // Retrieval info:
229 | // Retrieval info:
230 | // Retrieval info:
231 | // Retrieval info:
232 | // Retrieval info:
233 | // Retrieval info:
234 | // Retrieval info:
235 | // Retrieval info:
236 | // Retrieval info:
237 | // Retrieval info:
238 | // Retrieval info:
239 | // Retrieval info:
240 | // Retrieval info:
241 | // Retrieval info:
242 | // Retrieval info:
243 | // Retrieval info:
244 | // Retrieval info:
245 | // Retrieval info:
246 | // Retrieval info:
247 | // Retrieval info:
248 | // Retrieval info:
249 | // Retrieval info:
250 | // Retrieval info:
251 | // Retrieval info:
252 | // Retrieval info:
253 | // Retrieval info:
254 | // Retrieval info:
255 | // Retrieval info:
256 | // Retrieval info:
257 | // Retrieval info:
258 | // Retrieval info:
259 | // Retrieval info:
260 | // IPFS_FILES : mf_pllbase.vo
261 | // RELATED_FILES: mf_pllbase.v, mf_pllbase_0002.v
262 |
--------------------------------------------------------------------------------
/src/fpga/core/mf_pllbase/mf_pllbase_0002.qip:
--------------------------------------------------------------------------------
1 | set_instance_assignment -name PLL_COMPENSATION_MODE NORMAL -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*"
2 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*"
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 'outclk3'
20 | output wire outclk_3,
21 |
22 | // interface 'outclk4'
23 | output wire outclk_4,
24 |
25 | // interface 'locked'
26 | output wire locked
27 | );
28 |
29 | altera_pll #(
30 | .fractional_vco_multiplier("true"),
31 | .reference_clock_frequency("74.25 MHz"),
32 | .operation_mode("normal"),
33 | .number_of_clocks(5),
34 | .output_clock_frequency0("12.287999 MHz"),
35 | .phase_shift0("0 ps"),
36 | .duty_cycle0(50),
37 | .output_clock_frequency1("12.287999 MHz"),
38 | .phase_shift1("20345 ps"),
39 | .duty_cycle1(50),
40 | .output_clock_frequency2("133.119993 MHz"),
41 | .phase_shift2("0 ps"),
42 | .duty_cycle2(50),
43 | .output_clock_frequency3("133.119992 MHz"),
44 | .phase_shift3("6573 ps"),
45 | .duty_cycle3(50),
46 | .output_clock_frequency4("133.119990 MHz"),
47 | .phase_shift4("5634 ps"),
48 | .duty_cycle4(50),
49 | .output_clock_frequency5("0 MHz"),
50 | .phase_shift5("0 ps"),
51 | .duty_cycle5(50),
52 | .output_clock_frequency6("0 MHz"),
53 | .phase_shift6("0 ps"),
54 | .duty_cycle6(50),
55 | .output_clock_frequency7("0 MHz"),
56 | .phase_shift7("0 ps"),
57 | .duty_cycle7(50),
58 | .output_clock_frequency8("0 MHz"),
59 | .phase_shift8("0 ps"),
60 | .duty_cycle8(50),
61 | .output_clock_frequency9("0 MHz"),
62 | .phase_shift9("0 ps"),
63 | .duty_cycle9(50),
64 | .output_clock_frequency10("0 MHz"),
65 | .phase_shift10("0 ps"),
66 | .duty_cycle10(50),
67 | .output_clock_frequency11("0 MHz"),
68 | .phase_shift11("0 ps"),
69 | .duty_cycle11(50),
70 | .output_clock_frequency12("0 MHz"),
71 | .phase_shift12("0 ps"),
72 | .duty_cycle12(50),
73 | .output_clock_frequency13("0 MHz"),
74 | .phase_shift13("0 ps"),
75 | .duty_cycle13(50),
76 | .output_clock_frequency14("0 MHz"),
77 | .phase_shift14("0 ps"),
78 | .duty_cycle14(50),
79 | .output_clock_frequency15("0 MHz"),
80 | .phase_shift15("0 ps"),
81 | .duty_cycle15(50),
82 | .output_clock_frequency16("0 MHz"),
83 | .phase_shift16("0 ps"),
84 | .duty_cycle16(50),
85 | .output_clock_frequency17("0 MHz"),
86 | .phase_shift17("0 ps"),
87 | .duty_cycle17(50),
88 | .pll_type("General"),
89 | .pll_subtype("General")
90 | ) altera_pll_i (
91 | .rst (rst),
92 | .outclk ({outclk_4, outclk_3, outclk_2, outclk_1, outclk_0}),
93 | .locked (locked),
94 | .fboutclk ( ),
95 | .fbclk (1'b0),
96 | .refclk (refclk)
97 | );
98 | endmodule
99 |
100 |
--------------------------------------------------------------------------------
/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.1 646 win32 2022.06.28.14:59:52
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