├── 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