├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── fpga ├── Makefile ├── axi4_axi4lite_conv.v ├── core_soc.v ├── eth_axi4lite.v ├── eth_defs.v ├── firmware.bmm ├── fpga.ut ├── fpga.xst ├── fpga_top.v ├── gpio.v ├── gpio_defs.v ├── mak.sh ├── ram_wb.v ├── reset_gen.v ├── top.v └── top_g2.ucf ├── fw ├── include │ ├── eth_io.h │ ├── gpio_defs.h │ ├── pano_io.h │ ├── spiffs_config_g2.h │ └── spiffs_config_g2_revc.h └── pano_ldr │ ├── Makefile │ ├── arch │ └── cc.h │ ├── lwipopts.h │ ├── main.c │ ├── rand.c │ ├── tftp_ldr.c │ └── tftp_ldr.h ├── install_pano_ldr.sh ├── patches ├── cores │ ├── cpu │ │ └── riscv │ │ │ ├── 0001-Increase-on-chip-RAM-to-128k.patch │ │ │ └── 0010-Enable-SUPPORT_REGFILE_XILINX.patch │ └── ethernet_mac │ │ └── 0001-BUFGMUX-routing-fix.patch └── fw │ └── lwip │ └── 0001-Fix-build-for-NO_SYS-1.patch ├── prebuilt ├── install_rev_b ├── install_rev_c ├── mak_install_progs.sh ├── pano-g2-c.bit └── pano-g2.bit └── project.mk /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.log 3 | *.vcd 4 | *.a 5 | *_bd.bmm 6 | *.lst 7 | build/ 8 | lib/ 9 | obj/ 10 | obj_verilated/ 11 | verilated/ 12 | ise/work/ 13 | fpga/firmware.mem 14 | fpga/build/ 15 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cores/core_soc"] 2 | path = cores/core_soc 3 | url = https://github.com/ultraembedded/core_soc.git 4 | [submodule "cores/dbg_bridge"] 5 | path = cores/dbg_bridge 6 | url = https://github.com/ultraembedded/core_dbg_bridge.git 7 | [submodule "pano"] 8 | path = pano 9 | url = https://github.com/skiphansen/pano_blocks 10 | [submodule "cores/ethernet_mac"] 11 | path = cores/ethernet_mac 12 | url = https://github.com/yol/ethernet_mac.git 13 | [submodule "cores/cpu/riscv"] 14 | path = cores/cpu/riscv 15 | url = https://github.com/ultraembedded/riscv 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help build_all prog_fpga clean_all start_console run 2 | 3 | INIT_APP := fw/pano_ldr 4 | 5 | help: 6 | @echo "Usage:" 7 | @echo " REV A or B Pano (xc6slx150):" 8 | @echo " make load - load bit stream directly into FPGA" 9 | @echo " make prog_fpga - program SPI flash" 10 | @echo " make build_all - rebuild bitstream from sources (optional)" 11 | @echo 12 | @echo " REV C Pano (xc6slx100):" 13 | @echo " make PLATFORM=pano-g2-c load" 14 | @echo " ..." 15 | @echo 16 | @echo " make start_console (bit stream must be loaded)" 17 | @echo 18 | @echo " other make targets: build_all, clean_all, run" 19 | 20 | build_all: 21 | make -C $(INIT_APP) init_image 22 | make -C fpga 23 | 24 | prog_fpga: 25 | make -C fpga prog_fpga 26 | 27 | clean_all: 28 | make -C $(INIT_APP) clean 29 | make -C fpga clean 30 | 31 | start_console: 32 | make -C $(INIT_APP) start_console 33 | 34 | run: 35 | make -C $(INIT_APP) run 36 | 37 | load: 38 | make -C $(INIT_APP) load 39 | 40 | reset: 41 | make -C fpga reset 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pano_ldr 2 | 3 | [https://github.com/skiphansen/panog2_ldr](https://github.com/skiphansen/panog2_ldr) 4 | 5 | The purpose of this project is to allow a user to flash and run their own 6 | projects on [Pano G2](https://github.com/tomverbeure/panologic-g2/wiki/Identifying-different-Pano-generations-and-revisions#second-generation-rev-b-g2_b) 7 | and [Fujitsu DZ22-2](https://github.com/tomverbeure/panologic-g2/wiki/Identifying-different-Pano-generations-and-revisions#fujitsu-zero-client-dz22-2) 8 | thin clients without a JTAG programer. 9 | 10 | Unlike my [pano_progfpga](https://github.com/skiphansen/pano_progfpga) project 11 | pano_ldr is a bitstream for the Pano which can be co-resident with the user's 12 | bitstream. This means that pano_ldr may be used to update the Pano over and 13 | over as many times as desired. 14 | 15 | It is possible to install pano_ldr on a factory stock Pano G2 using [pano_progfpga](https://github.com/skiphansen/pano_progfpga) 16 | without opening the case. This is particularly important for owners of the 17 | DZ22-2 since it's almost impossible to open the case without damage to the 18 | case, the user or both. 19 | 20 | Once pano_ldr has been installed the user can telnet into the Pano and issue 21 | commands to update the flash and run applications. 22 | 23 | Unlike Pano's original progfpga utility pano_ldr is fast, limited only by the 24 | speed of the flash chip itself. Flashing with pano_ldr over the network is just 25 | as fast or faster than as using a JTAG programmer. 26 | 27 | # Usage 28 | 29 | Pano_ldr provides the user with a command line interface (CLI) via a 30 | [telnet](https://en.wikipedia.org/wiki/Telnet) connection. Commands are 31 | provided for reading and writing flash as well as configuring Pano_ldr to 32 | automatically boot the user's application on power on or reset. 33 | 34 | Files are transferred to and from a specified TFTP server on your network. 35 | 36 | ``` 37 | skip@Dell-7040:~/pano/working/panog2_ldr$ telnet pano_ldr 38 | Trying 192.168.123.196... 39 | Connected to pano_ldr.lan. 40 | Escape character is '^]'. 41 | Pano LDR v0.02 compiled May 28 2022 10:49:09 42 | ldr> help 43 | Commands: 44 | autoboot - [ on | off | delayed ] 45 | autoerase - [ on | off] 46 | bootadr - 47 | dump - 48 | erase - 49 | flash - 50 | map - Display blank regions in flash 51 | reboot - 52 | save - 53 | tftp - 54 | verify - 55 | ldr> flash my_project.bin 0x40000 56 | .............................. 57 | flashed 1974219 bytes 58 | ldr> 59 | 60 | ``` 61 | # TFTP server 62 | 63 | There are MANY choices for a TFTP servers, personally I use tftpd-hpa on 64 | Ubuntu 20.04. 65 | 66 | Please refer to the Internet for instructions on how to install and configure 67 | a TFTP server of your choice. 68 | 69 | # Auto boot 70 | 71 | Once pano_ldr has been installed it is the default bitstream that is loaded 72 | following power on or reset. With the default configuration pano_ldr will 73 | initialize the network and then wait for a telnet connection. 74 | 75 | Once an application has been installed pano_ldr can be configured to start 76 | the application automatically (autoboot) if desired. 77 | 78 | When autoboot is enabled instead of initializing the network and waiting for a 79 | telnet connection pano_ldr checks if the Pano button is pressed. If the button 80 | is pressed pano_ldr will enter normal operation, otherwise it will load the 81 | application bitstream. 82 | 83 | A delayed autoboot mode is provided for the DZ22-2 which lacks a dedicated Pano 84 | button. When the delayed mode is enabled pano_ldr will wait for 3 seconds for 85 | a "button" press before autobooting the application. 86 | 87 | This allows pano_ldr to be entered on a DZ22-2 from power off by slowly 88 | clicking the power button twice. The first click turns on the DZ22-2, the 89 | second click causes the LCD controller to send a Pano Button press to the 90 | Pano which causes pano_ldr to abort the autoboot and begin normal operation. 91 | 92 | The autoboot and bootadr commands are used to configure the auto bootmode. 93 | 94 | # Pano_ldr Commands 95 | 96 | All arguments can be specified in either decimal or hex. For hex prefix the hex value 97 | with '0x'. To save typing commands may be abbreviated. 98 | 99 | The "help" command lists available commands for reference. 100 | 101 | ## Autoboot [on | off | delayed] 102 | 103 | The autoboot command displays or sets the autoboot mode. 104 | 105 | | Mode | Action | 106 | | - | - | 107 | | Off | Pano_ldr initializes the network and waits for a connection. | 108 | | On | If the Pano button is not pressed pano_ldr initializes the network and waits for a connection. | 109 | | Delayed | Pano_ldr waits for the Pano button to be pressed for 3 seconds. If the Pano button is pressed then it will initialize the network and wait for a connection. | 110 | 111 | For example: 112 | ``` 113 | ldr> autoboot 114 | Autoboot off 115 | ldr> autoboot on 116 | Autoboot on 117 | ldr> autoboot delayed 118 | Autoboot delayed 119 | ldr> autoboot off 120 | Autoboot off 121 | ldr> 122 | ``` 123 | 124 | ## Autoerase [on | off] 125 | 126 | The autoerase command displays or turns the autoerase feature ON and OFF. 127 | 128 | By default autoerase is ON allowing the flash command to erase flash as needed. 129 | 130 | By turning autoerase OFF it is possible to flash multiple data blocks into the 131 | one erase block. For example firmware for a project might be stored past 132 | the end of a bitimage but before the end of the erase block to save some space. 133 | 134 | Another usage would be to flash a multiboot header along with pano_ldr at 135 | the beginning of flash to save almost 256K of flash on a Rev B or almost 136 | 64k on a Rev C. 137 | 138 | **NB:** It is strongly advised that the verify command be used after 139 | flashing with autoerase turned OFF to ensure that flash is in the desired state. 140 | Flash write operations can only turn '1' bits into '0' so programming the 141 | same byte with conflicting value **WILL** result in errors. 142 | 143 | **NB:** Even if flash is completely corrupted it is always possible to fix it 144 | as long as you have backups of the data and you have not power cycled the Pano. 145 | If you power cycle the Pano while flash is corrupted enough to prevent both 146 | pano_ldr and the "Golden" from starting you will need to use a JTAG programmer 147 | to recover. 148 | 149 | For example: 150 | ``` 151 | ldr> autoerase 152 | AutoErase on 153 | ldr> autoerase off 154 | AutoErase off 155 | ldr> 156 | ``` 157 | 158 | ## Bootadr [\] 159 | 160 | The bootadr command displays or sets the address of the auto boot bitstream. 161 | By default bootadr is set to 0x40000 which is the location of the "golden" 162 | image on a stock Pano. 163 | 164 | For example: 165 | ``` 166 | ldr> bootadr 167 | Autoboot @0x40000 168 | ldr> bootadr 0x380000 169 | ldr> bootadr 170 | Autoboot @0x380000 171 | ldr> 172 | ``` 173 | 174 | ## Dump \ \ 175 | 176 | The dump command displays the specified range of flash in hex. 177 | 178 | For example: 179 | ``` 180 | ldr> dump 0x40000 128 181 | 00040000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 182 | 00040010 aa 99 55 66 30 a1 00 07 20 00 31 a1 09 60 31 41 183 | 00040020 3d 00 31 61 09 ee 31 c2 04 01 d0 93 30 e1 00 cf 184 | 00040030 30 c1 00 81 20 00 20 00 20 00 20 00 20 00 20 00 185 | 00040040 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 186 | 00040050 20 00 20 00 20 00 33 81 3c 18 31 81 08 81 34 21 187 | 00040060 00 00 32 01 00 1f 31 e1 ff ff 33 21 00 05 33 41 188 | 00040070 00 04 33 01 01 00 32 61 00 00 32 81 00 00 32 a1 189 | ldr> 190 | ``` 191 | 192 | ## Erase \ \ 193 | 194 | The erase command erases the specified range of flash. This command does not 195 | need be used before using the flash command unless autoerase is turned OFF. 196 | 197 | The start address must be on an [erase boundary](https://github.com/skiphansen/panog2_ldr#erase-boundaries) 198 | and the end address must be one byte less than the next erase boundary. 199 | 200 | For a rev B the erase size is 201 | 256k or 0x40000, for a rev C it is 64K or 0x10000. 202 | 203 | For example on a rev b: 204 | ``` 205 | ldr> map 206 | M25P128: 16 MB, 256 KB sectors 207 | 0x000000 -> 0x8fffff 9216 K not empty 208 | 0x900000 -> 0xffffff 7168 K empty 209 | ldr> erase 0x480000 0x4bffff 210 | . 211 | Erased 256K 212 | ldr> map 213 | M25P128: 16 MB, 256 KB sectors 214 | 0x000000 -> 0x47ffff 4608 K not empty 215 | 0x480000 -> 0x4bffff 256 K empty 216 | 0x4c0000 -> 0x8fffff 4352 K not empty 217 | 0x900000 -> 0xffffff 7168 K empty 218 | ldr> 219 | ``` 220 | 221 | ## Flash \ \ 222 | 223 | The flash command programs flash with the specified file from the TFTP server. 224 | The start address should be on an [erase boundary](https://github.com/skiphansen/panog2_ldr#erase-boundaries) 225 | unless autoerase is turned OFF. 226 | 227 | If autoerase is on flash is erased automatically as needed. 228 | 229 | For compatibility with the stock Pano flash partitioning it is suggested that 230 | user applications be flashed at address 0x900000 for rev B and at address 0x40000 for rev C. 231 | 232 | Please see [SPI-Flash-memory-maps](https://github.com/tomverbeure/panologic-g2/wiki/SPI-Flash-memory-maps) 233 | for details. 234 | 235 | For example: 236 | ``` 237 | ldr> flash pano-g2-c.bin 0x40000 238 | .............................. 239 | 240 | flashed 1974219 bytes 241 | ldr> 242 | ``` 243 | 244 | ## Map 245 | 246 | The map command scans flash displaying the regions of flash which are 247 | empty and not empty. 248 | 249 | For example on a Rev C Pano with stock partitioning: 250 | 251 | ``` 252 | ldr> map 253 | M25P64: 8 MB, 64 KB sectors 254 | 0x000000 -> 0x00ffff 64 K not empty 255 | 0x010000 -> 0x03ffff 192 K empty 256 | 0x040000 -> 0x36ffff 3264 K not empty 257 | 0x370000 -> 0x37ffff 64 K empty 258 | 0x380000 -> 0x6affff 3264 K not empty 259 | 0x6b0000 -> 0x6bffff 64 K empty 260 | 0x6c0000 -> 0x6cffff 64 K not empty 261 | 0x6d0000 -> 0x7fffff 1216 K empty 262 | ``` 263 | 264 | ## Reboot \ 265 | 266 | The reboot command initiates a FPGA reconfiguration using the bitstream at the 267 | specified address. 268 | 269 | For example: 270 | ``` 271 | ldr> reboot 0x380000 272 | Booting bitstream @ 0x380000 273 | ``` 274 | 275 | ## save \ \ \ 276 | 277 | The save command saves a region of flash as a file on the TFTP sever. 278 | 279 | For example: 280 | ``` 281 | ldr> save pano-g2-c.bin 0x40000 1974219 282 | .............................. 283 | Saved 1974219 bytes 284 | ldr> 285 | ``` 286 | 287 | ## tftp [\] 288 | 289 | The tftp command is used display or set the IP address of the TFTP server. 290 | The TFTP server MUST be on the same subnet as the Pano. The TFTP server address 291 | is saved in flash. 292 | 293 | Note: TFTP server address is set to the IP address of the telnet connection 294 | unless it has been set previously. 295 | 296 | For example: 297 | ``` 298 | ldr> tftp 299 | 192.168.123.170 300 | ldr> tftp 1.2.3.4 301 | ldr> tftp 302 | 1.2.3.4 303 | ldr> 304 | ``` 305 | 306 | ## verify \ \ 307 | 308 | The verify command compares flash with the specified file from the TFTP server. 309 | 310 | For example: 311 | ``` 312 | ldr> verify pano-g2-c.bit 0x40000 313 | .............................. 314 | 1974219 bytes verified 315 | ldr> 316 | ``` 317 | 318 | ## Persistant Data storage 319 | 320 | Pano_ldr saves its configuration in the flash's last erase block. To prevent 321 | clobbering user data Pano_ldr will not save its data unless valid 322 | pano_ldr data is is detected in the block or the block is empty. 323 | 324 | ## HW Requirements 325 | 326 | * A Pano Logic G2 (the one with a DVI port) or a DZ22-2 327 | * A suitable 5 volt power supply 328 | 329 | ## Software Requirements 330 | 331 | * Host (or VM) capable of running 32 bit Linux programs 332 | * DHCP server somewhere on the LAN 333 | * TFTP server somewhere on the LAN 334 | 335 | ## Installation 336 | 337 | There are two way to install the loader, using a JTAG programmer or over the 338 | network. 339 | 340 | Using a JTAG programmer is the fastest way for a developer who already has 341 | a JTAG programmer connected. 342 | 343 | ## Installation without a JTAG programmer 344 | 345 | A script that uses patched Pano update utilities is provide to install pano_ldr 346 | over the network. 347 | 348 | The Pano update utilities are 32 bit Linux x86 programs that can be run on 349 | ny OS that can run 32 bit Linux binaries. 350 | 351 | You should be able to run these programs on a modern X86 Linux by installing 352 | [32 bit libraries](https://linuxconfig.org/unable-to-find-a-suitable-destination-to-install-32-bit-compatibility-libraries-on-ubuntu-18-04-bionic-beaver-linux). 353 | Alternately they can be run in a VM running a 32 bit version of Linux. 354 | If you want to go the VM route start [here](https://www.youtube.com/watch?v=DPkF5EisGDQ), 355 | or create a 32 bit Linux VM of your choice. 356 | 357 | The pano_ldr is installed as the "multiboot bitstream" so unexpected power 358 | failures during the update should **NOT** brick the Pano. 359 | 360 | The installation procedure is: 361 | 362 | * Plug the Pano into your local LAN. 363 | * Turn it on. 364 | * Wait for it to obtain an IP address via DHCP 365 | * Run install_pano_ldr.sh 366 | * Verify that you want to proceed 367 | * Cross your fingers and wait as the Pano is updated. (Go get coffee, you have time) 368 | * Power cycle the Pano 369 | 370 | Connect the Pano to your LAN then power it on. 371 | 372 | When installing on Pano G2 Wait for the Pano button to turn amber and stop 373 | flashing before running the install script. 374 | 375 | When installing on a DZ22-2 Wait until the power switch blinks amber slowly. 376 | 377 | It takes about 6 minutes to install pano_ldr on a G2 Rev B and about 4 minutes 378 | on a Rev C. 379 | 380 | **NB:** If installation is takes considerably longer than expected there could firewall issues **EVEN** on 381 | a local network. See [ticket #5](https://github.com/skiphansen/panog2_ldr/issues/5) for details. 382 | 383 | ``` 384 | skip@Dell-7040:~/pano/working/panog2_ldr$ ./install_pano_ldr.sh 385 | Pano IP: 192.168.123.118 386 | 387 | Install pano_ldr on Rev B Pano G2 (y/n) ?y 388 | answer: 'y' 389 | Running Test = flashFPGA_Series2_Multiboot 390 | Client connected : IP Addr = 192.168.123.118:8321 391 | READ CFG reg 0: 0x08010000 392 | TESTING with board Type = SERIES_II 393 | FPGA Major Rev = 0801, Minor Rev = 0014 394 | SPI ERASE SECTOR 00120000 395 | Flash type : LX150look for lx150/multiboot.9nimgSPI ERASE SECTOR 00124000 396 | SPI ERASE SECTOR 00128000 397 | SPI ERASE SECTOR 0012c000 398 | ... 399 | SPI ERASE SECTOR 0022c000 400 | Erase took 204.816864 seconds 401 | finish writing addr=0x00123fc0, 0x00004000 words and 1 sectors 402 | finish writing addr=0x00127fc0, 0x00008000 words and 2 sectors 403 | ... 404 | finish writing addr=0x0021ffc0, 0x00100000 words and 64 sectors 405 | Writing the Start writing multiboot image! consumed 89.843155 seconds 406 | reading flash & verifing 407 | Test has PASSED 408 | Disconnecting audio... 409 | Start writing multiboot image! Image Verified, validation consumed 154.612976 seconds 410 | Disconnected 411 | Pano_ldr installed, power cycle the Pano to start it 412 | skip@Dell-7040:~/pano/working/panog2_ldr$ 413 | ``` 414 | 415 | 416 | After power cycling the Pano, pano_ldr should run and initialize the network. 417 | 418 | The Pano button's LEDs are used to show pano_ldr's network state. 419 | 420 | | State | LED | 421 | | - | - | 422 | | Ethernet link down | Flashing red | 423 | | Ethernet link up, IP address not assigned | Flashing blue | 424 | | IP address assigned by DHCP, not connected | Flashing green | 425 | | User connected | Solid green | 426 | 427 | Once the Pano button begins blinking green you should be able to telnet into 428 | pano_ldr. 429 | 430 | DZ22-2 note: The LED on the DZ22-2 is not directly controlled by the Pano so no 431 | useful status will be displayed. 432 | 433 | ## Determine the Pano's IP address 434 | 435 | Pano_ldr's MAC address is 00:1c:02:70:1d:5d. Since this MAC address is 436 | different that the MAC address used by the stock bitstream a new IP address 437 | should be assigned to the Pano after it reboots. 438 | 439 | The DHCP client provides a host name of "pano_ldr" to the DHCP server 440 | when an IP address is requested. IF your router provides DNS service for 441 | local clients you should be able to telnet into your pano by host name. 442 | I use an OpenWRT based router and it provides this service. 443 | 444 | If your router doesn't provide DNS for local clients you will need to use 445 | determine the Pano's IP address manually. All routers should have some way 446 | of viewing active DHCP leases. 447 | 448 | ## Installation using a JTAG programmer 449 | 450 | If you already know how to flash .bit files you can find them in the prebuilt 451 | subdirectory, otherwise read on. 452 | 453 | Install xc3sprog for your system. If a binary install isn't available for your 454 | system the original project can be found here: https://sourceforge.net/projects/xc3sprog/. 455 | Sources can be checked out using subversion from https://svn.code.sf.net/p/xc3sprog/code/trunk. 456 | 457 | As an alternate if you don't have subversion a fork of the original project 458 | can be found here: https://github.com/Ole2mail/xc3sprog.git . 459 | 460 | If your JTAG cable is not a Digilent JTAG-HS2 then you will need to set the 461 | "CABLE" environment variable to your cable type before loading the bit file. 462 | 463 | Refer to the supported hardware [web page](http://xc3sprog.sourceforge.net/hardware.php) page or run xc3sprog -c 464 | to find the correct cable option for your device. 465 | 466 | **IMPORTANT: There are 2 versions of the Pano Logic G2: some use a Spartan 6 467 | LX150 while others use an LX100. You should be able to distinguish between the 468 | two by the revision code: LX150 is rev B and LX100 is rev C. 469 | 470 | The bit file and the embedded firmware must be generated for the correct device, 471 | the binary images are NOT compatible. The build system uses the PLATFORM 472 | environment variable to determine the target device. If the PLATFORM environment 473 | variable is not set a revision A or B device is assumed. 474 | 475 | Set the PLATFORM environment variable to "pano-g2-c" if your device is a 476 | revision C before running make or specify it on the make command line. 477 | 478 | Once xc3sprog has been in installed the bit file can be programmed into the 479 | Pano's SPI flash by running "make prog_fpga". 480 | 481 | ## Erase Boundaries 482 | 483 | Flash chips can be read and written in single byte increments, however they 484 | can only be erased in blocks. 485 | 486 | As a consequence of this the flash commands and erase commands must start 487 | on an erase boundary 488 | 489 | | Pano | flash size | erase block size | number of blocks | 490 | | - | - | - | - | 491 | | rev B | 16 MBytes | 256k | 64 | 492 | | rev C | 8 MBytes | 64k | 128 | 493 | 494 | ## Rev B erase blocks 495 | 496 | | Block number | Address range | 497 | | - | - | 498 | | 0 | 0x000000 -> 0x03ffff | 499 | | 1 | 0x040000 -> 0x07ffff | 500 | | 2 | 0x080000 -> 0x0bffff | 501 | | ... | 502 | | 62 | 0xf80000 -> 0xfbffff | 503 | | 63 | 0xfc0000 -> 0xffffff | 504 | 505 | ## Rev C erase blocks 506 | 507 | | Block number | Address range | 508 | | - | - | 509 | | 0 | 0x000000 -> 0x00ffff | 510 | | 1 | 0x010000 -> 0x01ffff | 511 | | 2 | 0x020000 -> 0x02ffff | 512 | | ... | 513 | | 126 | 0x7e0000 -> 0x7effff | 514 | | 127 | 0x7f0000 -> 0x7fffff | 515 | 516 | # Flash Partitioning 517 | 518 | Once pano_mon has been installed it is possible to repartition flash to make 519 | it more efficient and convenient. 520 | 521 | Using bit stream compression is an easy way to save flash space and all it 522 | takes setting a bitgen configuration varaible. 523 | 524 | For example a compressed bit stream of pano_ldr for rev B occupies ten flash 525 | sectors rather than 17. On the rev C it occupies 526 | 527 | # Building everything from sources 528 | 529 | **NB:** While it may be possible to use Windows for development I haven't 530 | tried it and don't recommend it. 531 | 532 | 1. Clone the https://github.com/skiphansen/panog2_ldr repository 533 | 2. cd into .../panog2_ldr 534 | 3. Make sure the RISC-V GCC (built for RV32IM) is in the PATH. 535 | 4. Run "make build_all" or "make PLATFORM=pano-g2-c build_all". 536 | 537 | The output from the build will be in the prebuilt subdirectory name 538 | pano-g2.bit or pano-g2-c.bit. 539 | 540 | ## Serial port (Optional) 541 | 542 | Pano_ldr is based on Ultraembedded's SOC platform which includes the ability to 543 | load firmware over a serial port which is VERY HANDY for code development. I 544 | strongly suggest building a serial cable to allow the capability to be used if 545 | you are interested in modifying the firmware. 546 | 547 | Please see the [fpga_test_soc](https://github.com/skiphansen/fpga_test_soc/tree/master/fpga/panologic_g2#serial-port) for more information. 548 | 549 | # Acknowledgement and Thanks 550 | This project uses code from several other projects including: 551 | - [ultraembedded's fpga_test_soc](https://github.com/ultraembedded/fpga_test_soc.git) 552 | - [Yol's Ethernet MAC](https://github.com/yol/ethernet_mac.git) 553 | - [The Light Weight IP project](https://savannah.nongnu.org/projects/lwip) 554 | 555 | # Pano Links 556 | 557 | Links to other Pano logic information can be found on the 558 | [Pano Logic Hackers wiki](https://github.com/tomverbeure/panologic-g2/wiki) 559 | 560 | # LEGAL 561 | 562 | My original work (the Pano ethernet_mac glue code and pano_ldr firmware) is 563 | released under the GNU General Public License, version 2. 564 | -------------------------------------------------------------------------------- /fpga/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## Makefile 3 | ############################################################################### 4 | include ../project.mk 5 | 6 | INCLUDE_ETHERNET ?= y 7 | 8 | SRC_DIR = . 9 | SRC_DIR += $(CORES_DIR)/core_soc/src_v 10 | SRC_DIR += $(CORES_DIR)/dbg_bridge/src_v 11 | SRC_DIR += $(CORES_DIR)/cpu/riscv/core/riscv 12 | SRC_DIR += $(CORES_DIR)/cpu/riscv/top_tcm_wrapper 13 | 14 | ifeq ($(INCLUDE_ETHERNET),y) 15 | SRC_DIR += $(CORES_DIR)/ethernet_mac 16 | SRC_DIR += $(CORES_DIR)/ethernet_mac/xilinx 17 | SRC_DIR += $(CORES_DIR)/ethernet_mac/xilinx/ipcore_dir 18 | SRC_DIR += $(PANO_CORES_DIR)/g2/ethernet_mac 19 | SRC_DIR += $(PANO_CORES_DIR)/g2/multiboot 20 | EXCLUDE_SRC += $(CORES_DIR)/ethernet_mac/ethernet_mac_tb.vhd 21 | EXTRA_VFLAGS += INCLUDE_ETHERNET=1 22 | else 23 | EXCLUDE_SRC += $(abspath ./eth_axi4lite.v) 24 | endif 25 | 26 | EXCLUDE_SRC += $(CORES_DIR)/core_soc/src_v/core_soc.v 27 | EXCLUDE_SRC += $(CORES_DIR)/core_soc/src_v/gpio.v 28 | EXCLUDE_SRC += $(CORES_DIR)/core_soc/src_v/gpio_defs.v 29 | 30 | BSCAN_SPI_DIR = $(PANO_CORES_DIR)/xc3sprog 31 | 32 | #COMPRESS_BITFILE = yes 33 | COMPRESS_BITFILE = no 34 | INIT_IMAGE = ./firmware.mem 35 | 36 | #MAP_CMDS = -w -intstyle ise -detail -ir off -ignore_keep_hierarchy -ol high 37 | 38 | # NB: the -pr b option was removed from the default options, otherwise there 39 | # are timing errors 40 | MAP_CMDS = -w -intstyle ise -detail -ir off -ignore_keep_hierarchy -timing -ol high -mt 2 41 | 42 | # use 4 cores 43 | PAR_CMDS = -w -intstyle ise -ol high -mt 4 44 | 45 | PATCHED_ETH_MAC = $(CORES_DIR)/ethernet_mac/.patched 46 | PATCHED_CPU = $(CORES_DIR)/cpu/riscv/.patched 47 | 48 | .PHONY: init_and_build 49 | init_and_build: $(PATCHED_ETH_MAC) $(PATCHED_CPU) all 50 | 51 | TOPDIR = .. 52 | include $(TOPDIR)/pano/make/ise.mk 53 | 54 | ETHERNET_MAC_PATCH := $(PATCHES_DIR)/cores/ethernet_mac/0001-BUFGMUX-routing-fix.patch 55 | 56 | $(PATCHED_ETH_MAC): $(ETHERNET_MAC_PATCH) 57 | (cd $(CORES_DIR)/ethernet_mac; git reset HEAD --hard) 58 | (cd $(CORES_DIR)/ethernet_mac; patch -p1 < $(ETHERNET_MAC_PATCH)) 59 | touch $@ 60 | 61 | CPU_PATCH_DIR := $(PATCHES_DIR)/cores/cpu/riscv 62 | CPU_PATCHES := $(wildcard $(CPU_PATCH_DIR)/*.patch) 63 | 64 | $(PATCHED_CPU): $(CPU_PATCHES) 65 | (cd $(CORES_DIR)/cpu/riscv; git reset HEAD --hard; \ 66 | $(foreach _patch,$(CPU_PATCHES), patch -p1 < $(_patch);)) 67 | touch $@ 68 | 69 | firmware.mem: 70 | make -C $(TOPDIR)/fw/blinky init_image 71 | 72 | debug: 73 | echo "INCLUDE_ETHERNET: $(INCLUDE_ETHERNET)" 74 | echo "SRC_DIR: $(SRC_DIR)" 75 | -------------------------------------------------------------------------------- /fpga/axi4_axi4lite_conv.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // FPGA Test Soc 3 | // V0.1 4 | // Ultra-Embedded.com 5 | // Copyright 2019 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | //----------------------------------------------------------------- 32 | // Generated File 33 | //----------------------------------------------------------------- 34 | 35 | module axi4_axi4lite_conv 36 | ( 37 | // Inputs 38 | input clk_i 39 | ,input rst_i 40 | ,input inport_awvalid_i 41 | ,input [ 31:0] inport_awaddr_i 42 | ,input [ 3:0] inport_awid_i 43 | ,input [ 7:0] inport_awlen_i 44 | ,input [ 1:0] inport_awburst_i 45 | ,input inport_wvalid_i 46 | ,input [ 31:0] inport_wdata_i 47 | ,input [ 3:0] inport_wstrb_i 48 | ,input inport_wlast_i 49 | ,input inport_bready_i 50 | ,input inport_arvalid_i 51 | ,input [ 31:0] inport_araddr_i 52 | ,input [ 3:0] inport_arid_i 53 | ,input [ 7:0] inport_arlen_i 54 | ,input [ 1:0] inport_arburst_i 55 | ,input inport_rready_i 56 | ,input outport_awready_i 57 | ,input outport_wready_i 58 | ,input outport_bvalid_i 59 | ,input [ 1:0] outport_bresp_i 60 | ,input outport_arready_i 61 | ,input outport_rvalid_i 62 | ,input [ 31:0] outport_rdata_i 63 | ,input [ 1:0] outport_rresp_i 64 | 65 | // Outputs 66 | ,output inport_awready_o 67 | ,output inport_wready_o 68 | ,output inport_bvalid_o 69 | ,output [ 1:0] inport_bresp_o 70 | ,output [ 3:0] inport_bid_o 71 | ,output inport_arready_o 72 | ,output inport_rvalid_o 73 | ,output [ 31:0] inport_rdata_o 74 | ,output [ 1:0] inport_rresp_o 75 | ,output [ 3:0] inport_rid_o 76 | ,output inport_rlast_o 77 | ,output outport_awvalid_o 78 | ,output [ 31:0] outport_awaddr_o 79 | ,output outport_wvalid_o 80 | ,output [ 31:0] outport_wdata_o 81 | ,output [ 3:0] outport_wstrb_o 82 | ,output outport_bready_o 83 | ,output outport_arvalid_o 84 | ,output [ 31:0] outport_araddr_o 85 | ,output outport_rready_o 86 | ); 87 | 88 | 89 | 90 | //----------------------------------------------------------------- 91 | // calculate_addr_next: AXI address calculation logic 92 | //----------------------------------------------------------------- 93 | function [31:0] calculate_addr_next; 94 | input [31:0] addr; 95 | input [1:0] axtype; 96 | input [7:0] axlen; 97 | reg [31:0] mask; 98 | begin 99 | 100 | case (axtype) 101 | 2'd0: // AXI4_BURST_FIXED 102 | begin 103 | calculate_addr_next = addr; 104 | end 105 | 2'd2: // AXI4_BURST_WRAP 106 | begin 107 | case (axlen) 108 | 8'd0: mask = 32'h03; 109 | 8'd1: mask = 32'h07; 110 | 8'd3: mask = 32'h0F; 111 | 8'd7: mask = 32'h1F; 112 | 8'd15: mask = 32'h3F; 113 | default: mask = 32'h3F; 114 | endcase 115 | 116 | calculate_addr_next = (addr & ~mask) | ((addr + 32'd4) & mask); 117 | end 118 | default: // AXI4_BURST_INCR 119 | calculate_addr_next = addr + 32'd4; 120 | endcase 121 | end 122 | endfunction 123 | 124 | //----------------------------------------------------------------- 125 | // AXI logic 126 | //----------------------------------------------------------------- 127 | reg awvalid_mask_q; 128 | reg wvalid_mask_q; 129 | reg arvalid_mask_q; 130 | 131 | reg awvalid_mask_r; 132 | reg wvalid_mask_r; 133 | reg arvalid_mask_r; 134 | always @ * 135 | begin 136 | awvalid_mask_r = awvalid_mask_q; 137 | wvalid_mask_r = wvalid_mask_q; 138 | arvalid_mask_r = arvalid_mask_q; 139 | 140 | // (last) Write response provided to input port 141 | if (inport_bvalid_o && inport_bready_i) 142 | begin 143 | awvalid_mask_r = 1'b0; 144 | wvalid_mask_r = 1'b0; 145 | end 146 | 147 | // Write address accept 148 | if (inport_awvalid_i && inport_awready_o) 149 | awvalid_mask_r = 1'b1; 150 | 151 | // Write data accept 152 | if (inport_wvalid_i && inport_wready_o) 153 | wvalid_mask_r = 1'b1; 154 | 155 | // (last) Read response provided to input port 156 | if (inport_rvalid_o && inport_rlast_o && inport_rready_i) 157 | arvalid_mask_r = 1'b0; 158 | 159 | // Read address accept 160 | if (inport_arvalid_i && inport_arready_o) 161 | arvalid_mask_r = 1'b1; 162 | end 163 | 164 | always @ (posedge clk_i ) 165 | if (rst_i) 166 | begin 167 | awvalid_mask_q <= 1'b0; 168 | wvalid_mask_q <= 1'b0; 169 | arvalid_mask_q <= 1'b0; 170 | end 171 | else 172 | begin 173 | awvalid_mask_q <= awvalid_mask_r; 174 | wvalid_mask_q <= wvalid_mask_r; 175 | arvalid_mask_q <= arvalid_mask_r; 176 | end 177 | 178 | reg arvalid_q; 179 | reg [31:0] araddr_q; 180 | reg [7:0] arcnt_q; 181 | reg [3:0] arid_q; 182 | reg [7:0] arlen_q; 183 | reg [1:0] arburst_q; 184 | 185 | always @ (posedge clk_i ) 186 | if (rst_i) 187 | begin 188 | arcnt_q <= 8'b0; 189 | araddr_q <= 32'd0; 190 | arvalid_q <= 1'b0; 191 | arid_q <= 4'b0; 192 | arlen_q <= 8'b0; 193 | arburst_q <= 2'b0; 194 | end 195 | else 196 | begin 197 | // AXI4-L request accept (or burst continuation) 198 | if (arvalid_q && outport_arvalid_o && outport_arready_i) 199 | begin 200 | araddr_q <= calculate_addr_next(araddr_q, arburst_q, arlen_q); 201 | 202 | // Last tick in the burst 203 | if (arcnt_q == 8'd1) 204 | arvalid_q <= 1'b0; 205 | 206 | arcnt_q <= arcnt_q - 8'd1; 207 | end 208 | // Read command accepted 209 | else if (inport_arvalid_i && inport_arready_o) 210 | begin 211 | arvalid_q <= (inport_arlen_i != 8'b0); 212 | arcnt_q <= inport_arlen_i; 213 | arlen_q <= inport_arlen_i; 214 | arburst_q <= inport_arburst_i; 215 | araddr_q <= calculate_addr_next(inport_araddr_i, inport_arburst_i, inport_arlen_i); 216 | arid_q <= inport_arid_i; 217 | end 218 | end 219 | 220 | reg awvalid_q; 221 | reg [31:0] awaddr_q; 222 | reg [7:0] awcnt_q; 223 | reg [3:0] awid_q; 224 | reg [7:0] awlen_q; 225 | reg [1:0] awburst_q; 226 | reg blast_q; 227 | 228 | always @ (posedge clk_i ) 229 | if (rst_i) 230 | begin 231 | awcnt_q <= 8'b0; 232 | awaddr_q <= 32'd0; 233 | awvalid_q <= 1'b0; 234 | awid_q <= 4'b0; 235 | awlen_q <= 8'b0; 236 | awburst_q <= 2'b0; 237 | blast_q <= 1'b0; 238 | end 239 | else 240 | begin 241 | // AXI4-L request accept (or burst continuation) 242 | // NOTE: This won't be presented until write data ready... 243 | if (awvalid_q && outport_awvalid_o && outport_awready_i) 244 | begin 245 | awaddr_q <= calculate_addr_next(awaddr_q, awburst_q, awlen_q); 246 | 247 | // Last tick in the burst 248 | if (awcnt_q == 8'd1) 249 | begin 250 | awvalid_q <= 1'b0; 251 | blast_q <= 1'b1; 252 | end 253 | 254 | awcnt_q <= awcnt_q - 8'd1; 255 | end 256 | // Write command accepted 257 | else if (inport_awvalid_i && inport_awready_o) 258 | begin 259 | awid_q <= inport_awid_i; 260 | 261 | // Data ready? 262 | if (inport_wvalid_i && inport_wready_o) 263 | begin 264 | awvalid_q <= !inport_wlast_i; 265 | awcnt_q <= inport_awlen_i; 266 | awaddr_q <= calculate_addr_next(inport_awaddr_i, inport_awburst_i, inport_awlen_i); 267 | awlen_q <= inport_awlen_i; 268 | awburst_q <= inport_awburst_i; 269 | blast_q <= inport_wlast_i; 270 | end 271 | // Data not ready 272 | else 273 | begin 274 | awvalid_q <= 1'b1; 275 | awcnt_q <= inport_awlen_i + 8'd1; 276 | awaddr_q <= inport_awaddr_i; 277 | awlen_q <= inport_awlen_i; 278 | awburst_q <= inport_awburst_i; 279 | blast_q <= 1'b0; 280 | end 281 | end 282 | // Reset last write response when accepted by input 283 | else if (inport_bvalid_o && inport_bready_i) 284 | blast_q <= 1'b0; 285 | end 286 | 287 | // NOTE: This IP expects AWREADY and WREADY to follow each other.... 288 | always @ (posedge clk_i ) 289 | if (rst_i) 290 | begin 291 | end 292 | else if (outport_awvalid_o || outport_wvalid_o) 293 | begin 294 | if (outport_awready_i != outport_wready_i) 295 | begin 296 | $display("ERROR: Unexpected flow control signals..."); 297 | end 298 | end 299 | 300 | // Output port 301 | assign outport_awvalid_o = (inport_awvalid_i & inport_wvalid_i & !awvalid_mask_q) | (awvalid_q & inport_wvalid_i); 302 | assign outport_awaddr_o = awvalid_q ? awaddr_q : inport_awaddr_i; 303 | assign outport_wvalid_o = inport_wvalid_i; 304 | assign outport_wdata_o = inport_wdata_i; 305 | assign outport_wstrb_o = inport_wstrb_i; 306 | 307 | assign outport_arvalid_o = (inport_arvalid_i & !arvalid_mask_q) | arvalid_q; 308 | assign outport_araddr_o = arvalid_q ? araddr_q : inport_araddr_i; 309 | assign outport_rready_o = inport_rready_i; 310 | 311 | assign inport_rvalid_o = outport_rvalid_i; 312 | assign inport_rdata_o = outport_rdata_i; 313 | assign inport_rid_o = arid_q; 314 | assign inport_rlast_o = (arcnt_q == 8'd0); 315 | assign inport_rresp_o = outport_rresp_i; 316 | 317 | assign inport_bvalid_o = outport_bvalid_i & blast_q; 318 | assign inport_bresp_o = outport_bresp_i; 319 | assign inport_bid_o = awid_q; 320 | 321 | assign outport_rready_o = inport_rready_i; 322 | assign outport_bready_o = !blast_q || inport_bready_i; 323 | 324 | // Handshaking 325 | assign inport_awready_o = (outport_awready_i & !awvalid_mask_q); 326 | assign inport_wready_o = outport_wready_i; 327 | assign inport_arready_o = (outport_arready_i & !arvalid_mask_q); 328 | 329 | 330 | 331 | endmodule 332 | -------------------------------------------------------------------------------- /fpga/core_soc.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // Basic Peripheral SoC 3 | // V1.1 4 | // Ultra-Embedded.com 5 | // Copyright 2014-2020 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | //----------------------------------------------------------------- 32 | // Generated File 33 | //----------------------------------------------------------------- 34 | 35 | module core_soc 36 | //----------------------------------------------------------------- 37 | // Params 38 | //----------------------------------------------------------------- 39 | #( 40 | parameter CLK_FREQ = 50000000 41 | ,parameter BAUDRATE = 1000000 42 | ,parameter C_SCK_RATIO = 50 43 | ) 44 | //----------------------------------------------------------------- 45 | // Ports 46 | //----------------------------------------------------------------- 47 | ( 48 | // Inputs 49 | input clk_i 50 | ,input rst_i 51 | ,input inport_awvalid_i 52 | ,input [ 31:0] inport_awaddr_i 53 | ,input inport_wvalid_i 54 | ,input [ 31:0] inport_wdata_i 55 | ,input [ 3:0] inport_wstrb_i 56 | ,input inport_bready_i 57 | ,input inport_arvalid_i 58 | ,input [ 31:0] inport_araddr_i 59 | ,input inport_rready_i 60 | ,input spi_miso_i 61 | ,input uart_rx_i 62 | ,input [ 31:0] gpio_input_i 63 | ,input ext1_cfg_awready_i 64 | ,input ext1_cfg_wready_i 65 | ,input ext1_cfg_bvalid_i 66 | ,input [ 1:0] ext1_cfg_bresp_i 67 | ,input ext1_cfg_arready_i 68 | ,input ext1_cfg_rvalid_i 69 | ,input [ 31:0] ext1_cfg_rdata_i 70 | ,input [ 1:0] ext1_cfg_rresp_i 71 | ,input ext1_irq_i 72 | ,input ext2_cfg_awready_i 73 | ,input ext2_cfg_wready_i 74 | ,input ext2_cfg_bvalid_i 75 | ,input [ 1:0] ext2_cfg_bresp_i 76 | ,input ext2_cfg_arready_i 77 | ,input ext2_cfg_rvalid_i 78 | ,input [ 31:0] ext2_cfg_rdata_i 79 | ,input [ 1:0] ext2_cfg_rresp_i 80 | ,input ext2_irq_i 81 | ,input ext3_cfg_awready_i 82 | ,input ext3_cfg_wready_i 83 | ,input ext3_cfg_bvalid_i 84 | ,input [ 1:0] ext3_cfg_bresp_i 85 | ,input ext3_cfg_arready_i 86 | ,input ext3_cfg_rvalid_i 87 | ,input [ 31:0] ext3_cfg_rdata_i 88 | ,input [ 1:0] ext3_cfg_rresp_i 89 | ,input ext3_irq_i 90 | 91 | // Outputs 92 | ,output intr_o 93 | ,output inport_awready_o 94 | ,output inport_wready_o 95 | ,output inport_bvalid_o 96 | ,output [ 1:0] inport_bresp_o 97 | ,output inport_arready_o 98 | ,output inport_rvalid_o 99 | ,output [ 31:0] inport_rdata_o 100 | ,output [ 1:0] inport_rresp_o 101 | ,output spi_clk_o 102 | ,output spi_mosi_o 103 | ,output [ 7:0] spi_cs_o 104 | ,output uart_tx_o 105 | ,output [ 31:0] gpio_output_o 106 | ,output [ 31:0] gpio_output_enable_o 107 | ,output ext1_cfg_awvalid_o 108 | ,output [ 31:0] ext1_cfg_awaddr_o 109 | ,output ext1_cfg_wvalid_o 110 | ,output [ 31:0] ext1_cfg_wdata_o 111 | ,output [ 3:0] ext1_cfg_wstrb_o 112 | ,output ext1_cfg_bready_o 113 | ,output ext1_cfg_arvalid_o 114 | ,output [ 31:0] ext1_cfg_araddr_o 115 | ,output ext1_cfg_rready_o 116 | ,output ext2_cfg_awvalid_o 117 | ,output [ 31:0] ext2_cfg_awaddr_o 118 | ,output ext2_cfg_wvalid_o 119 | ,output [ 31:0] ext2_cfg_wdata_o 120 | ,output [ 3:0] ext2_cfg_wstrb_o 121 | ,output ext2_cfg_bready_o 122 | ,output ext2_cfg_arvalid_o 123 | ,output [ 31:0] ext2_cfg_araddr_o 124 | ,output ext2_cfg_rready_o 125 | ,output ext3_cfg_awvalid_o 126 | ,output [ 31:0] ext3_cfg_awaddr_o 127 | ,output ext3_cfg_wvalid_o 128 | ,output [ 31:0] ext3_cfg_wdata_o 129 | ,output [ 3:0] ext3_cfg_wstrb_o 130 | ,output ext3_cfg_bready_o 131 | ,output ext3_cfg_arvalid_o 132 | ,output [ 31:0] ext3_cfg_araddr_o 133 | ,output ext3_cfg_rready_o 134 | ,output [ 23:0] boot_spi_adr_o 135 | ,output reboot_o 136 | ); 137 | 138 | wire [ 31:0] periph1_rdata_w; 139 | wire [ 1:0] periph0_bresp_w; 140 | wire periph2_awvalid_w; 141 | wire [ 1:0] periph3_rresp_w; 142 | wire periph4_arready_w; 143 | wire periph1_bready_w; 144 | wire periph2_arready_w; 145 | wire periph3_arvalid_w; 146 | wire [ 31:0] periph4_rdata_w; 147 | wire periph3_bready_w; 148 | wire periph3_rvalid_w; 149 | wire periph4_bvalid_w; 150 | wire periph1_bvalid_w; 151 | wire periph4_arvalid_w; 152 | wire periph2_bready_w; 153 | wire periph0_rvalid_w; 154 | wire periph2_awready_w; 155 | wire periph2_arvalid_w; 156 | wire periph1_arvalid_w; 157 | wire [ 31:0] periph2_rdata_w; 158 | wire periph0_awvalid_w; 159 | wire [ 31:0] periph3_araddr_w; 160 | wire [ 1:0] periph1_rresp_w; 161 | wire [ 31:0] periph0_rdata_w; 162 | wire [ 3:0] periph4_wstrb_w; 163 | wire [ 31:0] periph2_awaddr_w; 164 | wire [ 1:0] periph4_bresp_w; 165 | wire periph1_arready_w; 166 | wire [ 31:0] periph3_rdata_w; 167 | wire periph4_rready_w; 168 | wire periph1_wvalid_w; 169 | wire [ 31:0] periph4_araddr_w; 170 | wire periph0_bvalid_w; 171 | wire periph0_rready_w; 172 | wire periph1_rready_w; 173 | wire periph4_rvalid_w; 174 | wire periph3_arready_w; 175 | wire [ 1:0] periph2_bresp_w; 176 | wire periph3_awvalid_w; 177 | wire periph4_wready_w; 178 | wire [ 31:0] periph3_awaddr_w; 179 | wire [ 3:0] periph1_wstrb_w; 180 | wire [ 1:0] periph0_rresp_w; 181 | wire [ 3:0] periph0_wstrb_w; 182 | wire [ 31:0] periph1_wdata_w; 183 | wire periph1_awready_w; 184 | wire interrupt1_w; 185 | wire interrupt0_w; 186 | wire interrupt3_w; 187 | wire interrupt2_w; 188 | wire [ 31:0] periph1_awaddr_w; 189 | wire periph4_awvalid_w; 190 | wire periph3_awready_w; 191 | wire periph1_awvalid_w; 192 | wire periph3_wready_w; 193 | wire periph0_wready_w; 194 | wire [ 31:0] periph0_awaddr_w; 195 | wire [ 1:0] periph3_bresp_w; 196 | wire periph0_arvalid_w; 197 | wire periph3_bvalid_w; 198 | wire periph0_bready_w; 199 | wire [ 31:0] periph2_wdata_w; 200 | wire periph4_wvalid_w; 201 | wire periph0_wvalid_w; 202 | wire [ 3:0] periph2_wstrb_w; 203 | wire periph2_rvalid_w; 204 | wire [ 31:0] periph4_awaddr_w; 205 | wire [ 1:0] periph4_rresp_w; 206 | wire [ 1:0] periph1_bresp_w; 207 | wire periph1_wready_w; 208 | wire periph2_rready_w; 209 | wire periph2_bvalid_w; 210 | wire periph2_wready_w; 211 | wire [ 31:0] periph0_wdata_w; 212 | wire [ 3:0] periph3_wstrb_w; 213 | wire [ 31:0] periph4_wdata_w; 214 | wire periph0_awready_w; 215 | wire periph1_rvalid_w; 216 | wire [ 31:0] periph1_araddr_w; 217 | wire periph4_awready_w; 218 | wire periph0_arready_w; 219 | wire [ 31:0] periph2_araddr_w; 220 | wire periph3_wvalid_w; 221 | wire [ 1:0] periph2_rresp_w; 222 | wire [ 31:0] periph0_araddr_w; 223 | wire periph4_bready_w; 224 | wire [ 31:0] periph3_wdata_w; 225 | wire periph3_rready_w; 226 | wire periph2_wvalid_w; 227 | 228 | 229 | irq_ctrl 230 | u_intc 231 | ( 232 | // Inputs 233 | .clk_i(clk_i) 234 | ,.rst_i(rst_i) 235 | ,.cfg_awvalid_i(periph0_awvalid_w) 236 | ,.cfg_awaddr_i(periph0_awaddr_w) 237 | ,.cfg_wvalid_i(periph0_wvalid_w) 238 | ,.cfg_wdata_i(periph0_wdata_w) 239 | ,.cfg_wstrb_i(periph0_wstrb_w) 240 | ,.cfg_bready_i(periph0_bready_w) 241 | ,.cfg_arvalid_i(periph0_arvalid_w) 242 | ,.cfg_araddr_i(periph0_araddr_w) 243 | ,.cfg_rready_i(periph0_rready_w) 244 | ,.interrupt0_i(interrupt0_w) 245 | ,.interrupt1_i(interrupt1_w) 246 | ,.interrupt2_i(interrupt2_w) 247 | ,.interrupt3_i(interrupt3_w) 248 | ,.interrupt4_i(ext1_irq_i) 249 | ,.interrupt5_i(ext2_irq_i) 250 | ,.interrupt6_i(ext3_irq_i) 251 | 252 | // Outputs 253 | ,.cfg_awready_o(periph0_awready_w) 254 | ,.cfg_wready_o(periph0_wready_w) 255 | ,.cfg_bvalid_o(periph0_bvalid_w) 256 | ,.cfg_bresp_o(periph0_bresp_w) 257 | ,.cfg_arready_o(periph0_arready_w) 258 | ,.cfg_rvalid_o(periph0_rvalid_w) 259 | ,.cfg_rdata_o(periph0_rdata_w) 260 | ,.cfg_rresp_o(periph0_rresp_w) 261 | ,.intr_o(intr_o) 262 | ); 263 | 264 | 265 | axi4lite_dist 266 | u_dist 267 | ( 268 | // Inputs 269 | .clk_i(clk_i) 270 | ,.rst_i(rst_i) 271 | ,.inport_awvalid_i(inport_awvalid_i) 272 | ,.inport_awaddr_i(inport_awaddr_i) 273 | ,.inport_wvalid_i(inport_wvalid_i) 274 | ,.inport_wdata_i(inport_wdata_i) 275 | ,.inport_wstrb_i(inport_wstrb_i) 276 | ,.inport_bready_i(inport_bready_i) 277 | ,.inport_arvalid_i(inport_arvalid_i) 278 | ,.inport_araddr_i(inport_araddr_i) 279 | ,.inport_rready_i(inport_rready_i) 280 | ,.outport0_awready_i(periph0_awready_w) 281 | ,.outport0_wready_i(periph0_wready_w) 282 | ,.outport0_bvalid_i(periph0_bvalid_w) 283 | ,.outport0_bresp_i(periph0_bresp_w) 284 | ,.outport0_arready_i(periph0_arready_w) 285 | ,.outport0_rvalid_i(periph0_rvalid_w) 286 | ,.outport0_rdata_i(periph0_rdata_w) 287 | ,.outport0_rresp_i(periph0_rresp_w) 288 | ,.outport1_awready_i(periph1_awready_w) 289 | ,.outport1_wready_i(periph1_wready_w) 290 | ,.outport1_bvalid_i(periph1_bvalid_w) 291 | ,.outport1_bresp_i(periph1_bresp_w) 292 | ,.outport1_arready_i(periph1_arready_w) 293 | ,.outport1_rvalid_i(periph1_rvalid_w) 294 | ,.outport1_rdata_i(periph1_rdata_w) 295 | ,.outport1_rresp_i(periph1_rresp_w) 296 | ,.outport2_awready_i(periph2_awready_w) 297 | ,.outport2_wready_i(periph2_wready_w) 298 | ,.outport2_bvalid_i(periph2_bvalid_w) 299 | ,.outport2_bresp_i(periph2_bresp_w) 300 | ,.outport2_arready_i(periph2_arready_w) 301 | ,.outport2_rvalid_i(periph2_rvalid_w) 302 | ,.outport2_rdata_i(periph2_rdata_w) 303 | ,.outport2_rresp_i(periph2_rresp_w) 304 | ,.outport3_awready_i(periph3_awready_w) 305 | ,.outport3_wready_i(periph3_wready_w) 306 | ,.outport3_bvalid_i(periph3_bvalid_w) 307 | ,.outport3_bresp_i(periph3_bresp_w) 308 | ,.outport3_arready_i(periph3_arready_w) 309 | ,.outport3_rvalid_i(periph3_rvalid_w) 310 | ,.outport3_rdata_i(periph3_rdata_w) 311 | ,.outport3_rresp_i(periph3_rresp_w) 312 | ,.outport4_awready_i(periph4_awready_w) 313 | ,.outport4_wready_i(periph4_wready_w) 314 | ,.outport4_bvalid_i(periph4_bvalid_w) 315 | ,.outport4_bresp_i(periph4_bresp_w) 316 | ,.outport4_arready_i(periph4_arready_w) 317 | ,.outport4_rvalid_i(periph4_rvalid_w) 318 | ,.outport4_rdata_i(periph4_rdata_w) 319 | ,.outport4_rresp_i(periph4_rresp_w) 320 | ,.outport5_awready_i(ext1_cfg_awready_i) 321 | ,.outport5_wready_i(ext1_cfg_wready_i) 322 | ,.outport5_bvalid_i(ext1_cfg_bvalid_i) 323 | ,.outport5_bresp_i(ext1_cfg_bresp_i) 324 | ,.outport5_arready_i(ext1_cfg_arready_i) 325 | ,.outport5_rvalid_i(ext1_cfg_rvalid_i) 326 | ,.outport5_rdata_i(ext1_cfg_rdata_i) 327 | ,.outport5_rresp_i(ext1_cfg_rresp_i) 328 | ,.outport6_awready_i(ext2_cfg_awready_i) 329 | ,.outport6_wready_i(ext2_cfg_wready_i) 330 | ,.outport6_bvalid_i(ext2_cfg_bvalid_i) 331 | ,.outport6_bresp_i(ext2_cfg_bresp_i) 332 | ,.outport6_arready_i(ext2_cfg_arready_i) 333 | ,.outport6_rvalid_i(ext2_cfg_rvalid_i) 334 | ,.outport6_rdata_i(ext2_cfg_rdata_i) 335 | ,.outport6_rresp_i(ext2_cfg_rresp_i) 336 | ,.outport7_awready_i(ext3_cfg_awready_i) 337 | ,.outport7_wready_i(ext3_cfg_wready_i) 338 | ,.outport7_bvalid_i(ext3_cfg_bvalid_i) 339 | ,.outport7_bresp_i(ext3_cfg_bresp_i) 340 | ,.outport7_arready_i(ext3_cfg_arready_i) 341 | ,.outport7_rvalid_i(ext3_cfg_rvalid_i) 342 | ,.outport7_rdata_i(ext3_cfg_rdata_i) 343 | ,.outport7_rresp_i(ext3_cfg_rresp_i) 344 | 345 | // Outputs 346 | ,.inport_awready_o(inport_awready_o) 347 | ,.inport_wready_o(inport_wready_o) 348 | ,.inport_bvalid_o(inport_bvalid_o) 349 | ,.inport_bresp_o(inport_bresp_o) 350 | ,.inport_arready_o(inport_arready_o) 351 | ,.inport_rvalid_o(inport_rvalid_o) 352 | ,.inport_rdata_o(inport_rdata_o) 353 | ,.inport_rresp_o(inport_rresp_o) 354 | ,.outport0_awvalid_o(periph0_awvalid_w) 355 | ,.outport0_awaddr_o(periph0_awaddr_w) 356 | ,.outport0_wvalid_o(periph0_wvalid_w) 357 | ,.outport0_wdata_o(periph0_wdata_w) 358 | ,.outport0_wstrb_o(periph0_wstrb_w) 359 | ,.outport0_bready_o(periph0_bready_w) 360 | ,.outport0_arvalid_o(periph0_arvalid_w) 361 | ,.outport0_araddr_o(periph0_araddr_w) 362 | ,.outport0_rready_o(periph0_rready_w) 363 | ,.outport1_awvalid_o(periph1_awvalid_w) 364 | ,.outport1_awaddr_o(periph1_awaddr_w) 365 | ,.outport1_wvalid_o(periph1_wvalid_w) 366 | ,.outport1_wdata_o(periph1_wdata_w) 367 | ,.outport1_wstrb_o(periph1_wstrb_w) 368 | ,.outport1_bready_o(periph1_bready_w) 369 | ,.outport1_arvalid_o(periph1_arvalid_w) 370 | ,.outport1_araddr_o(periph1_araddr_w) 371 | ,.outport1_rready_o(periph1_rready_w) 372 | ,.outport2_awvalid_o(periph2_awvalid_w) 373 | ,.outport2_awaddr_o(periph2_awaddr_w) 374 | ,.outport2_wvalid_o(periph2_wvalid_w) 375 | ,.outport2_wdata_o(periph2_wdata_w) 376 | ,.outport2_wstrb_o(periph2_wstrb_w) 377 | ,.outport2_bready_o(periph2_bready_w) 378 | ,.outport2_arvalid_o(periph2_arvalid_w) 379 | ,.outport2_araddr_o(periph2_araddr_w) 380 | ,.outport2_rready_o(periph2_rready_w) 381 | ,.outport3_awvalid_o(periph3_awvalid_w) 382 | ,.outport3_awaddr_o(periph3_awaddr_w) 383 | ,.outport3_wvalid_o(periph3_wvalid_w) 384 | ,.outport3_wdata_o(periph3_wdata_w) 385 | ,.outport3_wstrb_o(periph3_wstrb_w) 386 | ,.outport3_bready_o(periph3_bready_w) 387 | ,.outport3_arvalid_o(periph3_arvalid_w) 388 | ,.outport3_araddr_o(periph3_araddr_w) 389 | ,.outport3_rready_o(periph3_rready_w) 390 | ,.outport4_awvalid_o(periph4_awvalid_w) 391 | ,.outport4_awaddr_o(periph4_awaddr_w) 392 | ,.outport4_wvalid_o(periph4_wvalid_w) 393 | ,.outport4_wdata_o(periph4_wdata_w) 394 | ,.outport4_wstrb_o(periph4_wstrb_w) 395 | ,.outport4_bready_o(periph4_bready_w) 396 | ,.outport4_arvalid_o(periph4_arvalid_w) 397 | ,.outport4_araddr_o(periph4_araddr_w) 398 | ,.outport4_rready_o(periph4_rready_w) 399 | ,.outport5_awvalid_o(ext1_cfg_awvalid_o) 400 | ,.outport5_awaddr_o(ext1_cfg_awaddr_o) 401 | ,.outport5_wvalid_o(ext1_cfg_wvalid_o) 402 | ,.outport5_wdata_o(ext1_cfg_wdata_o) 403 | ,.outport5_wstrb_o(ext1_cfg_wstrb_o) 404 | ,.outport5_bready_o(ext1_cfg_bready_o) 405 | ,.outport5_arvalid_o(ext1_cfg_arvalid_o) 406 | ,.outport5_araddr_o(ext1_cfg_araddr_o) 407 | ,.outport5_rready_o(ext1_cfg_rready_o) 408 | ,.outport6_awvalid_o(ext2_cfg_awvalid_o) 409 | ,.outport6_awaddr_o(ext2_cfg_awaddr_o) 410 | ,.outport6_wvalid_o(ext2_cfg_wvalid_o) 411 | ,.outport6_wdata_o(ext2_cfg_wdata_o) 412 | ,.outport6_wstrb_o(ext2_cfg_wstrb_o) 413 | ,.outport6_bready_o(ext2_cfg_bready_o) 414 | ,.outport6_arvalid_o(ext2_cfg_arvalid_o) 415 | ,.outport6_araddr_o(ext2_cfg_araddr_o) 416 | ,.outport6_rready_o(ext2_cfg_rready_o) 417 | ,.outport7_awvalid_o(ext3_cfg_awvalid_o) 418 | ,.outport7_awaddr_o(ext3_cfg_awaddr_o) 419 | ,.outport7_wvalid_o(ext3_cfg_wvalid_o) 420 | ,.outport7_wdata_o(ext3_cfg_wdata_o) 421 | ,.outport7_wstrb_o(ext3_cfg_wstrb_o) 422 | ,.outport7_bready_o(ext3_cfg_bready_o) 423 | ,.outport7_arvalid_o(ext3_cfg_arvalid_o) 424 | ,.outport7_araddr_o(ext3_cfg_araddr_o) 425 | ,.outport7_rready_o(ext3_cfg_rready_o) 426 | ); 427 | 428 | 429 | uart_lite 430 | #( 431 | .CLK_FREQ(CLK_FREQ) 432 | ,.BAUDRATE(BAUDRATE) 433 | ) 434 | u_uart 435 | ( 436 | // Inputs 437 | .clk_i(clk_i) 438 | ,.rst_i(rst_i) 439 | ,.cfg_awvalid_i(periph2_awvalid_w) 440 | ,.cfg_awaddr_i(periph2_awaddr_w) 441 | ,.cfg_wvalid_i(periph2_wvalid_w) 442 | ,.cfg_wdata_i(periph2_wdata_w) 443 | ,.cfg_wstrb_i(periph2_wstrb_w) 444 | ,.cfg_bready_i(periph2_bready_w) 445 | ,.cfg_arvalid_i(periph2_arvalid_w) 446 | ,.cfg_araddr_i(periph2_araddr_w) 447 | ,.cfg_rready_i(periph2_rready_w) 448 | ,.rx_i(uart_rx_i) 449 | 450 | // Outputs 451 | ,.cfg_awready_o(periph2_awready_w) 452 | ,.cfg_wready_o(periph2_wready_w) 453 | ,.cfg_bvalid_o(periph2_bvalid_w) 454 | ,.cfg_bresp_o(periph2_bresp_w) 455 | ,.cfg_arready_o(periph2_arready_w) 456 | ,.cfg_rvalid_o(periph2_rvalid_w) 457 | ,.cfg_rdata_o(periph2_rdata_w) 458 | ,.cfg_rresp_o(periph2_rresp_w) 459 | ,.tx_o(uart_tx_o) 460 | ,.intr_o(interrupt1_w) 461 | ); 462 | 463 | 464 | timer 465 | u_timer 466 | ( 467 | // Inputs 468 | .clk_i(clk_i) 469 | ,.rst_i(rst_i) 470 | ,.cfg_awvalid_i(periph1_awvalid_w) 471 | ,.cfg_awaddr_i(periph1_awaddr_w) 472 | ,.cfg_wvalid_i(periph1_wvalid_w) 473 | ,.cfg_wdata_i(periph1_wdata_w) 474 | ,.cfg_wstrb_i(periph1_wstrb_w) 475 | ,.cfg_bready_i(periph1_bready_w) 476 | ,.cfg_arvalid_i(periph1_arvalid_w) 477 | ,.cfg_araddr_i(periph1_araddr_w) 478 | ,.cfg_rready_i(periph1_rready_w) 479 | 480 | // Outputs 481 | ,.cfg_awready_o(periph1_awready_w) 482 | ,.cfg_wready_o(periph1_wready_w) 483 | ,.cfg_bvalid_o(periph1_bvalid_w) 484 | ,.cfg_bresp_o(periph1_bresp_w) 485 | ,.cfg_arready_o(periph1_arready_w) 486 | ,.cfg_rvalid_o(periph1_rvalid_w) 487 | ,.cfg_rdata_o(periph1_rdata_w) 488 | ,.cfg_rresp_o(periph1_rresp_w) 489 | ,.intr_o(interrupt0_w) 490 | ); 491 | 492 | 493 | spi_lite 494 | #( 495 | .C_SCK_RATIO(C_SCK_RATIO) 496 | ) 497 | u_spi 498 | ( 499 | // Inputs 500 | .clk_i(clk_i) 501 | ,.rst_i(rst_i) 502 | ,.cfg_awvalid_i(periph3_awvalid_w) 503 | ,.cfg_awaddr_i(periph3_awaddr_w) 504 | ,.cfg_wvalid_i(periph3_wvalid_w) 505 | ,.cfg_wdata_i(periph3_wdata_w) 506 | ,.cfg_wstrb_i(periph3_wstrb_w) 507 | ,.cfg_bready_i(periph3_bready_w) 508 | ,.cfg_arvalid_i(periph3_arvalid_w) 509 | ,.cfg_araddr_i(periph3_araddr_w) 510 | ,.cfg_rready_i(periph3_rready_w) 511 | ,.spi_miso_i(spi_miso_i) 512 | 513 | // Outputs 514 | ,.cfg_awready_o(periph3_awready_w) 515 | ,.cfg_wready_o(periph3_wready_w) 516 | ,.cfg_bvalid_o(periph3_bvalid_w) 517 | ,.cfg_bresp_o(periph3_bresp_w) 518 | ,.cfg_arready_o(periph3_arready_w) 519 | ,.cfg_rvalid_o(periph3_rvalid_w) 520 | ,.cfg_rdata_o(periph3_rdata_w) 521 | ,.cfg_rresp_o(periph3_rresp_w) 522 | ,.spi_clk_o(spi_clk_o) 523 | ,.spi_mosi_o(spi_mosi_o) 524 | ,.spi_cs_o(spi_cs_o) 525 | ,.intr_o(interrupt2_w) 526 | ); 527 | 528 | 529 | gpio 530 | u_gpio 531 | ( 532 | // Inputs 533 | .clk_i(clk_i) 534 | ,.rst_i(rst_i) 535 | ,.cfg_awvalid_i(periph4_awvalid_w) 536 | ,.cfg_awaddr_i(periph4_awaddr_w) 537 | ,.cfg_wvalid_i(periph4_wvalid_w) 538 | ,.cfg_wdata_i(periph4_wdata_w) 539 | ,.cfg_wstrb_i(periph4_wstrb_w) 540 | ,.cfg_bready_i(periph4_bready_w) 541 | ,.cfg_arvalid_i(periph4_arvalid_w) 542 | ,.cfg_araddr_i(periph4_araddr_w) 543 | ,.cfg_rready_i(periph4_rready_w) 544 | ,.gpio_input_i(gpio_input_i) 545 | 546 | // Outputs 547 | ,.cfg_awready_o(periph4_awready_w) 548 | ,.cfg_wready_o(periph4_wready_w) 549 | ,.cfg_bvalid_o(periph4_bvalid_w) 550 | ,.cfg_bresp_o(periph4_bresp_w) 551 | ,.cfg_arready_o(periph4_arready_w) 552 | ,.cfg_rvalid_o(periph4_rvalid_w) 553 | ,.cfg_rdata_o(periph4_rdata_w) 554 | ,.cfg_rresp_o(periph4_rresp_w) 555 | ,.gpio_output_o(gpio_output_o) 556 | ,.gpio_output_enable_o(gpio_output_enable_o) 557 | ,.intr_o(interrupt3_w) 558 | ,.boot_spi_adr_o(boot_spi_adr_o) 559 | ,.reboot_o(reboot_o) 560 | ); 561 | 562 | endmodule 563 | -------------------------------------------------------------------------------- /fpga/eth_axi4lite.v: -------------------------------------------------------------------------------- 1 | // License: GPL 2 | // If you would like a version with a more permissive license for 3 | // use in closed source commercial applications please contact me 4 | // for details. 5 | //----------------------------------------------------------------- 6 | // 7 | // This file is open source HDL; you can redistribute it and/or 8 | // modify it under the terms of the GNU General Public License as 9 | // published by the Free Software Foundation; either version 2 of 10 | // the License, or (at your option) any later version. 11 | // 12 | // This file is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | // 17 | // You should have received a copy of the GNU General Public 18 | // License along with this file; if not, write to the Free Software 19 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 | // USA 21 | //----------------------------------------------------------------- 22 | 23 | //----------------------------------------------------------------- 24 | // Generated File 25 | //----------------------------------------------------------------- 26 | 27 | `include "eth_defs.v" 28 | 29 | module eth_axi4lite 30 | //----------------------------------------------------------------- 31 | // Params 32 | //----------------------------------------------------------------- 33 | #( 34 | // Change this if you like, this was copied from the label on one of Skip's G2s 35 | parameter MAC_ADDRESS = 48'h5d1d70021c00 36 | ) 37 | //----------------------------------------------------------------- 38 | // Ports 39 | //----------------------------------------------------------------- 40 | ( 41 | // axi4 Inputs 42 | input clk_i // 32 Mhz 43 | ,input rst_i 44 | ,input cfg_awvalid_i 45 | ,input [31:0] cfg_awaddr_i 46 | ,input cfg_wvalid_i 47 | ,input [31:0] cfg_wdata_i 48 | ,input [3:0] cfg_wstrb_i 49 | ,input cfg_bready_i 50 | ,input cfg_arvalid_i 51 | ,input [31:0] cfg_araddr_i 52 | ,input cfg_rready_i 53 | 54 | // axi4 Outputs 55 | ,output cfg_awready_o 56 | ,output cfg_wready_o 57 | ,output cfg_bvalid_o 58 | ,output [1:0] cfg_bresp_o 59 | ,output cfg_arready_o 60 | ,output cfg_rvalid_o 61 | ,output [31:0] cfg_rdata_o 62 | ,output [1:0] cfg_rresp_o 63 | 64 | // peripheral inputs 65 | // Unbuffered 125 MHz clock input 66 | ,input clock_125_i 67 | 68 | // MII (Media-independent interface) 69 | ,input mii_tx_clk_i 70 | ,output mii_tx_er_o 71 | ,output mii_tx_en_o 72 | ,output [7:0] mii_txd_o 73 | ,input mii_rx_clk_i 74 | ,input mii_rx_er_i 75 | ,input mii_rx_dv_i 76 | ,input [7:0] mii_rxd_i 77 | 78 | // GMII (Gigabit media-independent interface) 79 | ,output gmii_gtx_clk_o 80 | 81 | // RGMII (Reduced pin count gigabit media-independent interface) 82 | ,output rgmii_tx_ctl_o 83 | ,input rgmii_rx_ctl_i 84 | 85 | // MII Management Interface 86 | ,output mdc_o 87 | ,inout mdio_io 88 | ); 89 | 90 | //----------------------------------------------------------------- 91 | // Write address / data split 92 | //----------------------------------------------------------------- 93 | // Address but no data ready 94 | reg awvalid_q; 95 | 96 | // Data but no data ready 97 | reg wvalid_q; 98 | 99 | wire wr_cmd_accepted_w = (cfg_awvalid_i && cfg_awready_o) || awvalid_q; 100 | wire wr_data_accepted_w = (cfg_wvalid_i && cfg_wready_o) || wvalid_q; 101 | 102 | always @ (posedge clk_i or posedge rst_i) 103 | if (rst_i) 104 | awvalid_q <= 1'b0; 105 | else if (cfg_awvalid_i && cfg_awready_o && !wr_data_accepted_w) 106 | awvalid_q <= 1'b1; 107 | else if (wr_data_accepted_w) 108 | awvalid_q <= 1'b0; 109 | 110 | always @ (posedge clk_i or posedge rst_i) 111 | if (rst_i) 112 | wvalid_q <= 1'b0; 113 | else if (cfg_wvalid_i && cfg_wready_o && !wr_cmd_accepted_w) 114 | wvalid_q <= 1'b1; 115 | else if (wr_cmd_accepted_w) 116 | wvalid_q <= 1'b0; 117 | 118 | //----------------------------------------------------------------- 119 | // Capture address (for delayed data) 120 | //----------------------------------------------------------------- 121 | reg [7:0] wr_addr_q; 122 | 123 | always @ (posedge clk_i or posedge rst_i) 124 | if (rst_i) 125 | wr_addr_q <= 8'b0; 126 | else if (cfg_awvalid_i && cfg_awready_o) 127 | wr_addr_q <= cfg_awaddr_i[7:0]; 128 | 129 | wire [7:0] wr_addr_w = awvalid_q ? wr_addr_q : cfg_awaddr_i[7:0]; 130 | wire [47:0] mac_address = MAC_ADDRESS; 131 | wire rx_reset; 132 | wire rx_empty; 133 | reg rx_rd_en; 134 | wire [7:0] rx_data; 135 | wire [7:0] tx_data; 136 | reg tx_wr_en; 137 | wire tx_full; 138 | wire tx_reset; 139 | wire link_up; 140 | wire [1:0] link_speed; 141 | 142 | 143 | //----------------------------------------------------------------- 144 | // Retime write data 145 | //----------------------------------------------------------------- 146 | reg [31:0] wr_data_q; 147 | 148 | always @ (posedge clk_i or posedge rst_i) 149 | if (rst_i) 150 | wr_data_q <= 32'b0; 151 | else if (cfg_wvalid_i && cfg_wready_o) 152 | wr_data_q <= cfg_wdata_i; 153 | 154 | //----------------------------------------------------------------- 155 | // Request Logic 156 | //----------------------------------------------------------------- 157 | wire read_en_w = cfg_arvalid_i & cfg_arready_o; 158 | wire write_en_w = wr_cmd_accepted_w && wr_data_accepted_w; 159 | 160 | //----------------------------------------------------------------- 161 | // Accept Logic 162 | //----------------------------------------------------------------- 163 | assign cfg_arready_o = ~cfg_rvalid_o; 164 | assign cfg_awready_o = ~cfg_bvalid_o && ~cfg_arvalid_i && ~awvalid_q; 165 | assign cfg_wready_o = ~cfg_bvalid_o && ~cfg_arvalid_i && ~wvalid_q; 166 | 167 | 168 | //----------------------------------------------------------------- 169 | // Register ETH_tx 170 | //----------------------------------------------------------------- 171 | 172 | always @ (posedge clk_i or posedge rst_i) 173 | if (rst_i) 174 | tx_wr_en <= 1'b0; 175 | else if (write_en_w && (wr_addr_w[7:0] == `ETH_TX)) 176 | tx_wr_en <= 1'b1; 177 | else 178 | tx_wr_en <= 1'b0; 179 | 180 | assign tx_data = wr_data_q[`ETH_TX_DATA_R]; 181 | 182 | 183 | //----------------------------------------------------------------- 184 | // Register ETH_status 185 | //----------------------------------------------------------------- 186 | reg eth_status_wr_q; 187 | 188 | always @ (posedge clk_i or posedge rst_i) 189 | if (rst_i) 190 | eth_status_wr_q <= 1'b0; 191 | else if (write_en_w && (wr_addr_w[7:0] == `ETH_STATUS)) 192 | eth_status_wr_q <= 1'b1; 193 | else 194 | eth_status_wr_q <= 1'b0; 195 | 196 | 197 | //----------------------------------------------------------------- 198 | // Read mux 199 | //----------------------------------------------------------------- 200 | reg [31:0] data_r; 201 | 202 | always @ * 203 | begin 204 | data_r = 32'b0; 205 | 206 | case (cfg_araddr_i[7:0]) 207 | 208 | `ETH_RX: 209 | begin 210 | data_r[`ETH_RX_DATA_R] = rx_data; 211 | end 212 | `ETH_STATUS: 213 | begin 214 | data_r[`ETH_STATUS_IE_R] = 1'b0; 215 | data_r[`ETH_STATUS_TXFULL_R] = tx_full; 216 | data_r[`ETH_STATUS_RXEMPTY_R] = rx_empty; 217 | data_r[`ETH_STATUS_RXRESET_R] = rx_reset; 218 | data_r[`ETH_STATUS_TXRESET_R] = tx_reset; 219 | data_r[`ETH_STATUS_LINK_UP_R] = link_up; 220 | data_r[`ETH_STATUS_LINK_SPEED_R] = link_speed; 221 | end 222 | default : 223 | data_r = 32'b0; 224 | endcase 225 | end 226 | 227 | //----------------------------------------------------------------- 228 | // RVALID 229 | //----------------------------------------------------------------- 230 | reg rvalid_q; 231 | 232 | always @ (posedge clk_i or posedge rst_i) 233 | if (rst_i) 234 | rvalid_q <= 1'b0; 235 | else if (read_en_w) 236 | rvalid_q <= 1'b1; 237 | else if (cfg_rready_i) 238 | rvalid_q <= 1'b0; 239 | 240 | assign cfg_rvalid_o = rvalid_q; 241 | 242 | //----------------------------------------------------------------- 243 | // Retime read response 244 | //----------------------------------------------------------------- 245 | reg [31:0] rd_data_q; 246 | 247 | always @ (posedge clk_i or posedge rst_i) 248 | if (rst_i) 249 | rd_data_q <= 32'b0; 250 | else if (!cfg_rvalid_o || cfg_rready_i) 251 | rd_data_q <= data_r; 252 | 253 | assign cfg_rdata_o = rd_data_q; 254 | assign cfg_rresp_o = 2'b0; 255 | 256 | //----------------------------------------------------------------- 257 | // BVALID 258 | //----------------------------------------------------------------- 259 | reg bvalid_q; 260 | 261 | always @ (posedge clk_i or posedge rst_i) 262 | if (rst_i) 263 | bvalid_q <= 1'b0; 264 | else if (write_en_w) 265 | bvalid_q <= 1'b1; 266 | else if (cfg_bready_i) 267 | bvalid_q <= 1'b0; 268 | 269 | assign cfg_bvalid_o = bvalid_q; 270 | assign cfg_bresp_o = 2'b0; 271 | 272 | ethernet_with_fifos 273 | #( 274 | .MIIM_CLOCK_DIVIDER(13) // 32Mhz / 13 = about 2.5 Mhz 275 | ) 276 | eth_u ( 277 | // Unbuffered 125 MHz clock input 278 | .clock_125_i(clock_125_i) 279 | // Asynchronous reset 280 | ,.reset_i(rst_i) 281 | // MAC address of this station 282 | // Must not change after reset is deasserted 283 | ,.mac_address_i(mac_address) 284 | 285 | // MII (Media-independent interface) 286 | ,.mii_tx_clk_i(mii_tx_clk_i) 287 | ,.mii_tx_er_o(mii_tx_er_o) 288 | ,.mii_tx_en_o(mii_tx_en_o) 289 | ,.mii_txd_o(mii_txd_o) 290 | ,.mii_rx_clk_i(mii_rx_clk_i) 291 | ,.mii_rx_er_i(mii_rx_er_i) 292 | ,.mii_rx_dv_i(mii_rx_dv_i) 293 | ,.mii_rxd_i(mii_rxd_i) 294 | 295 | // GMII (Gigabit media-independent interface) 296 | ,.gmii_gtx_clk_o(gmii_gtx_clk_o) 297 | // RGMII (Reduced pin count gigabit media-independent interface) 298 | ,.rgmii_tx_ctl_o(rgmii_tx_ctl_o) 299 | ,.rgmii_rx_ctl_i(rgmii_rx_ctl_i) 300 | 301 | // MII Management Interface 302 | ,.mdc_o(mdc_o) 303 | ,.mdio_io(mdio_io) 304 | // Status, synchronous to clk_i 305 | ,.link_up_o(link_up) 306 | ,.speed_o(link_speed) 307 | 308 | // MII Management Interface 309 | // Clock, can be identical to clock_125_i 310 | // If not, adjust MIIM_CLOCK_DIVIDER accordingly 311 | ,.miim_clock_i(clk_i) 312 | 313 | // Also synchronous to miim_clock_i if used! 314 | ,.speed_override_i(`SPEED_UNSPECIFIED) 315 | 316 | // RX FIFO 317 | ,.rx_clock_i(clk_i) 318 | // Synchronous reset 319 | // When asserted, the content of the buffer was lost. 320 | // When empty is deasserted the next time, a packet size must be read out. 321 | // The data of the packet previously being read out is not available anymore then. 322 | ,.rx_reset_o(rx_reset) 323 | ,.rx_empty_o(rx_empty) 324 | ,.rx_rd_en_i(rx_rd_en) 325 | ,.rx_data_o(rx_data) 326 | // TX FIFO 327 | ,.tx_clock_i(clk_i) 328 | // Synchronous reset 329 | // When asserted, the content of the buffer was lost. 330 | // When full is deasserted the next time, a packet size must be written. 331 | // The data of the packet previously being written is not available anymore then. 332 | ,.tx_reset_o(tx_reset) 333 | ,.tx_data_i(tx_data) 334 | ,.tx_wr_en_i(tx_wr_en) 335 | ,.tx_full_o(tx_full) 336 | ); 337 | 338 | 339 | always @ (posedge clk_i) 340 | if (read_en_w) begin 341 | if(cfg_araddr_i[7:0] == `ETH_RX) begin 342 | // Read fifo 343 | rx_rd_en <= 1'b1; 344 | end 345 | end 346 | else begin 347 | rx_rd_en <= 1'b0; 348 | end 349 | 350 | 351 | endmodule 352 | -------------------------------------------------------------------------------- /fpga/eth_defs.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // This file is open source HDL; you can redistribute it and/or 3 | // modify it under the terms of the GNU General Public License as 4 | // published by the Free Software Foundation; either version 2 of 5 | // the License, or (at your option) any later version. 6 | // 7 | // This file is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | // GNU General Public License for more details. 11 | // 12 | // You should have received a copy of the GNU General Public 13 | // License along with this file; if not, write to the Free Software 14 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 15 | // USA 16 | //----------------------------------------------------------------- 17 | 18 | `define ETH_RX 8'h0 19 | 20 | `define ETH_RX_DATA_DEFAULT 0 21 | `define ETH_RX_DATA_B 0 22 | `define ETH_RX_DATA_T 7 23 | `define ETH_RX_DATA_W 8 24 | `define ETH_RX_DATA_R 7:0 25 | 26 | `define ETH_TX 8'h4 27 | 28 | `define ETH_TX_DATA_DEFAULT 0 29 | `define ETH_TX_DATA_B 0 30 | `define ETH_TX_DATA_T 7 31 | `define ETH_TX_DATA_W 8 32 | `define ETH_TX_DATA_R 7:0 33 | 34 | `define ETH_STATUS 8'h8 35 | 36 | `define ETH_STATUS_LINK_SPEED_R 7:6 37 | `define ETH_STATUS_LINK_UP_R 5:5 38 | 39 | `define ETH_STATUS_IE 4 40 | `define ETH_STATUS_IE_DEFAULT 0 41 | `define ETH_STATUS_IE_B 4 42 | `define ETH_STATUS_IE_T 4 43 | `define ETH_STATUS_IE_W 1 44 | `define ETH_STATUS_IE_R 4:4 45 | 46 | `define ETH_STATUS_TXFULL 3 47 | `define ETH_STATUS_TXFULL_DEFAULT 0 48 | `define ETH_STATUS_TXFULL_B 3 49 | `define ETH_STATUS_TXFULL_T 3 50 | `define ETH_STATUS_TXFULL_W 1 51 | `define ETH_STATUS_TXFULL_R 3:3 52 | 53 | `define ETH_STATUS_RXEMPTY 2 54 | `define ETH_STATUS_RXEMPTY_DEFAULT 0 55 | `define ETH_STATUS_RXEMPTY_B 2 56 | `define ETH_STATUS_RXEMPTY_T 2 57 | `define ETH_STATUS_RXEMPTY_W 1 58 | `define ETH_STATUS_RXEMPTY_R 2:2 59 | 60 | `define ETH_STATUS_RXRESET 1 61 | `define ETH_STATUS_RXRESET_DEFAULT 0 62 | `define ETH_STATUS_RXRESET_B 1 63 | `define ETH_STATUS_RXRESET_T 1 64 | `define ETH_STATUS_RXRESET_W 1 65 | `define ETH_STATUS_RXRESET_R 1:1 66 | 67 | `define ETH_STATUS_TXRESET 0 68 | `define ETH_STATUS_TXRESET_DEFAULT 0 69 | `define ETH_STATUS_TXRESET_B 0 70 | `define ETH_STATUS_TXRESET_T 0 71 | `define ETH_STATUS_TXRESET_W 1 72 | `define ETH_STATUS_TXRESET_R 0:0 73 | 74 | 75 | 76 | // Speed constants 77 | `define SPEED_1000MBPS 2'b10 78 | `define SPEED_100MBPS 2'b01 79 | `define SPEED_10MBPS 2'b00 80 | `define SPEED_UNSPECIFIED 2'b11 81 | 82 | -------------------------------------------------------------------------------- /fpga/firmware.bmm: -------------------------------------------------------------------------------- 1 | ADDRESS_SPACE progmem RAMB16 WORD_ADDRESSING [0x00000000:0x00003FFF] 2 | BUS_BLOCK 3 | u_top/u_cpu/u_tcm/u_ram/Mram_ram1 [31:0]; 4 | END_BUS_BLOCK; 5 | BUS_BLOCK 6 | u_top/u_cpu/u_tcm/u_ram/Mram_ram2 [31:0]; 7 | END_BUS_BLOCK; 8 | BUS_BLOCK 9 | u_top/u_cpu/u_tcm/u_ram/Mram_ram3 [31:0]; 10 | END_BUS_BLOCK; 11 | BUS_BLOCK 12 | u_top/u_cpu/u_tcm/u_ram/Mram_ram4 [31:0]; 13 | END_BUS_BLOCK; 14 | BUS_BLOCK 15 | u_top/u_cpu/u_tcm/u_ram/Mram_ram5 [31:0]; 16 | END_BUS_BLOCK; 17 | BUS_BLOCK 18 | u_top/u_cpu/u_tcm/u_ram/Mram_ram6 [31:0]; 19 | END_BUS_BLOCK; 20 | BUS_BLOCK 21 | u_top/u_cpu/u_tcm/u_ram/Mram_ram7 [31:0]; 22 | END_BUS_BLOCK; 23 | BUS_BLOCK 24 | u_top/u_cpu/u_tcm/u_ram/Mram_ram8 [31:0]; 25 | END_BUS_BLOCK; 26 | BUS_BLOCK 27 | u_top/u_cpu/u_tcm/u_ram/Mram_ram9 [31:0]; 28 | END_BUS_BLOCK; 29 | BUS_BLOCK 30 | u_top/u_cpu/u_tcm/u_ram/Mram_ram10 [31:0]; 31 | END_BUS_BLOCK; 32 | BUS_BLOCK 33 | u_top/u_cpu/u_tcm/u_ram/Mram_ram11 [31:0]; 34 | END_BUS_BLOCK; 35 | BUS_BLOCK 36 | u_top/u_cpu/u_tcm/u_ram/Mram_ram12 [31:0]; 37 | END_BUS_BLOCK; 38 | BUS_BLOCK 39 | u_top/u_cpu/u_tcm/u_ram/Mram_ram13 [31:0]; 40 | END_BUS_BLOCK; 41 | BUS_BLOCK 42 | u_top/u_cpu/u_tcm/u_ram/Mram_ram14 [31:0]; 43 | END_BUS_BLOCK; 44 | BUS_BLOCK 45 | u_top/u_cpu/u_tcm/u_ram/Mram_ram15 [31:0]; 46 | END_BUS_BLOCK; 47 | BUS_BLOCK 48 | u_top/u_cpu/u_tcm/u_ram/Mram_ram16 [31:0]; 49 | END_BUS_BLOCK; 50 | BUS_BLOCK 51 | u_top/u_cpu/u_tcm/u_ram/Mram_ram17 [31:0]; 52 | END_BUS_BLOCK; 53 | BUS_BLOCK 54 | u_top/u_cpu/u_tcm/u_ram/Mram_ram18 [31:0]; 55 | END_BUS_BLOCK; 56 | BUS_BLOCK 57 | u_top/u_cpu/u_tcm/u_ram/Mram_ram19 [31:0]; 58 | END_BUS_BLOCK; 59 | BUS_BLOCK 60 | u_top/u_cpu/u_tcm/u_ram/Mram_ram20 [31:0]; 61 | END_BUS_BLOCK; 62 | BUS_BLOCK 63 | u_top/u_cpu/u_tcm/u_ram/Mram_ram21 [31:0]; 64 | END_BUS_BLOCK; 65 | BUS_BLOCK 66 | u_top/u_cpu/u_tcm/u_ram/Mram_ram22 [31:0]; 67 | END_BUS_BLOCK; 68 | BUS_BLOCK 69 | u_top/u_cpu/u_tcm/u_ram/Mram_ram23 [31:0]; 70 | END_BUS_BLOCK; 71 | BUS_BLOCK 72 | u_top/u_cpu/u_tcm/u_ram/Mram_ram24 [31:0]; 73 | END_BUS_BLOCK; 74 | BUS_BLOCK 75 | u_top/u_cpu/u_tcm/u_ram/Mram_ram25 [31:0]; 76 | END_BUS_BLOCK; 77 | BUS_BLOCK 78 | u_top/u_cpu/u_tcm/u_ram/Mram_ram26 [31:0]; 79 | END_BUS_BLOCK; 80 | BUS_BLOCK 81 | u_top/u_cpu/u_tcm/u_ram/Mram_ram27 [31:0]; 82 | END_BUS_BLOCK; 83 | BUS_BLOCK 84 | u_top/u_cpu/u_tcm/u_ram/Mram_ram28 [31:0]; 85 | END_BUS_BLOCK; 86 | BUS_BLOCK 87 | u_top/u_cpu/u_tcm/u_ram/Mram_ram29 [31:0]; 88 | END_BUS_BLOCK; 89 | BUS_BLOCK 90 | u_top/u_cpu/u_tcm/u_ram/Mram_ram30 [31:0]; 91 | END_BUS_BLOCK; 92 | BUS_BLOCK 93 | u_top/u_cpu/u_tcm/u_ram/Mram_ram31 [31:0]; 94 | END_BUS_BLOCK; 95 | BUS_BLOCK 96 | u_top/u_cpu/u_tcm/u_ram/Mram_ram32 [31:0]; 97 | END_BUS_BLOCK; 98 | END_ADDRESS_SPACE; 99 | 100 | 101 | -------------------------------------------------------------------------------- /fpga/fpga.ut: -------------------------------------------------------------------------------- 1 | -w 2 | -g DebugBitstream:No 3 | -g Binary:no 4 | -g CRC:Enable 5 | -g ConfigRate:26 6 | -g ProgPin:PullUp 7 | -g DonePin:PullUp 8 | -g TckPin:PullUp 9 | -g TdiPin:PullUp 10 | -g TdoPin:PullUp 11 | -g TmsPin:PullUp 12 | -g UnusedPin:PullDown 13 | -g UserID:0xFFFFFFFF 14 | -g StartUpClk:CClk 15 | -g DONE_cycle:4 16 | -g GTS_cycle:5 17 | -g GWE_cycle:6 18 | -g LCK_cycle:NoWait 19 | -g Security:None 20 | -g DonePipe:No 21 | -g DriveDone:No 22 | -g Compress 23 | -------------------------------------------------------------------------------- /fpga/fpga.xst: -------------------------------------------------------------------------------- 1 | set -tmpdir "xst/projnav.tmp" 2 | set -xsthdpdir "xst" 3 | run 4 | -ifn fpga.prj 5 | -ofn fpga 6 | -ofmt NGC 7 | -top top 8 | -opt_mode Speed 9 | -opt_level 1 10 | -power NO 11 | -iuc NO 12 | -keep_hierarchy No 13 | -netlist_hierarchy As_Optimized 14 | -rtlview Yes 15 | -glob_opt AllClockNets 16 | -read_cores YES 17 | -write_timing_constraints NO 18 | -cross_clock_analysis NO 19 | -hierarchy_separator / 20 | -bus_delimiter <> 21 | -case Maintain 22 | -slice_utilization_ratio 100 23 | -bram_utilization_ratio 100 24 | -dsp_utilization_ratio 100 25 | -lc Auto 26 | -reduce_control_sets Auto 27 | -fsm_extract YES -fsm_encoding Auto 28 | -safe_implementation No 29 | -fsm_style LUT 30 | -ram_extract Yes 31 | -ram_style Auto 32 | -rom_extract Yes 33 | -shreg_extract YES 34 | -rom_style Auto 35 | -auto_bram_packing NO 36 | -resource_sharing YES 37 | -async_to_sync NO 38 | -shreg_min_size 2 39 | -use_dsp48 Auto 40 | -iobuf YES 41 | -max_fanout 100000 42 | -bufg 16 43 | -register_duplication YES 44 | -register_balancing No 45 | -optimize_primitives NO 46 | -use_clock_enable Auto 47 | -use_sync_set Auto 48 | -use_sync_reset Auto 49 | -iob Auto 50 | -equivalent_register_removal YES 51 | -slice_utilization_ratio_maxmargin 5 52 | -------------------------------------------------------------------------------- /fpga/fpga_top.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // FPGA Test Soc 3 | // V0.1 4 | // Ultra-Embedded.com 5 | // Copyright 2019 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | module fpga_top 32 | //----------------------------------------------------------------- 33 | // Params 34 | //----------------------------------------------------------------- 35 | #( 36 | parameter CLK_FREQ = 50000000 37 | ,parameter BAUDRATE = 1000000 38 | ,parameter UART_SPEED = 1000000 39 | ,parameter C_SCK_RATIO = 50 40 | ,parameter CPU = "riscv" // riscv or armv6m 41 | ) 42 | //----------------------------------------------------------------- 43 | // Ports 44 | //----------------------------------------------------------------- 45 | ( 46 | // Inputs 47 | input clk_i 48 | ,input rst_i 49 | ,input dbg_txd_i 50 | ,input spi_miso_i 51 | ,input uart_rx_i 52 | ,input [ 31:0] gpio_input_i 53 | ,input clock_125_i 54 | 55 | // Outputs 56 | ,output dbg_rxd_o 57 | ,output spi_clk_o 58 | ,output spi_mosi_o 59 | ,output [ 7:0] spi_cs_o 60 | ,output uart_tx_o 61 | ,output [ 31:0] gpio_output_o 62 | ,output [ 31:0] gpio_output_enable_o 63 | ,output [ 23:0] boot_spi_adr_o 64 | ,output reboot_o 65 | 66 | `ifdef INCLUDE_ETHERNET 67 | // MII (Media-independent interface) 68 | ,input mii_tx_clk_i 69 | ,output mii_tx_er_o 70 | ,output mii_tx_en_o 71 | ,output [7:0] mii_txd_o 72 | ,input mii_rx_clk_i 73 | ,input mii_rx_er_i 74 | ,input mii_rx_dv_i 75 | ,input [7:0] mii_rxd_i 76 | 77 | // GMII (Gigabit media-independent interface) 78 | ,output gmii_gtx_clk_o 79 | 80 | // RGMII (Reduced pin count gigabit media-independent interface) 81 | ,output rgmii_tx_ctl_o 82 | ,input rgmii_rx_ctl_i 83 | 84 | // MII Management Interface 85 | ,output mdc_o 86 | ,inout mdio_io 87 | `endif 88 | 89 | // UTMI Interface 90 | ,input [ 7:0] utmi_data_out_i 91 | ,input [ 7:0] utmi_data_in_i 92 | ,input utmi_txvalid_i 93 | ,input utmi_txready_i 94 | ,input utmi_rxvalid_i 95 | ,input utmi_rxactive_i 96 | ,input utmi_rxerror_i 97 | ,input [ 1:0] utmi_linestate_i 98 | 99 | ,output [ 1:0] utmi_op_mode_o 100 | ,output [ 1:0] utmi_xcvrselect_o 101 | ,output utmi_termselect_o 102 | ,output utmi_dppulldown_o 103 | ,output utmi_dmpulldown_o 104 | ); 105 | 106 | wire [ 3:0] axi_t_awid_w; 107 | wire axi_l_awvalid_w; 108 | wire axi_l_arvalid_w; 109 | wire [ 1:0] axi_i_bresp_w; 110 | wire [ 1:0] axi_l_bresp_w; 111 | wire [ 31:0] axi_t_wdata_w; 112 | wire axi_t_rlast_w; 113 | wire [ 3:0] axi_i_wstrb_w; 114 | wire [ 31:0] axi_t_rdata_w; 115 | wire axi_t_bvalid_w; 116 | wire axi_t_awready_w; 117 | wire axi_l_wvalid_w; 118 | wire [ 3:0] axi_t_arid_w; 119 | wire [ 31:0] axi_t_awaddr_w; 120 | wire [ 1:0] axi_i_rresp_w; 121 | wire [ 7:0] axi_t_arlen_w; 122 | wire axi_l_bvalid_w; 123 | wire axi_i_wlast_w; 124 | wire axi_i_arready_w; 125 | wire axi_t_wvalid_w; 126 | wire [ 31:0] axi_t_araddr_w; 127 | wire [ 3:0] axi_i_bid_w; 128 | wire [ 1:0] axi_t_rresp_w; 129 | wire axi_l_awready_w; 130 | wire axi_t_wlast_w; 131 | wire [ 31:0] axi_l_rdata_w; 132 | wire [ 1:0] axi_i_awburst_w; 133 | wire axi_t_rvalid_w; 134 | wire axi_i_rvalid_w; 135 | wire axi_t_arvalid_w; 136 | wire axi_t_arready_w; 137 | wire [ 1:0] axi_i_arburst_w; 138 | wire axi_t_awvalid_w; 139 | wire [ 7:0] axi_i_arlen_w; 140 | wire axi_l_rready_w; 141 | wire [ 1:0] axi_l_rresp_w; 142 | wire [ 31:0] axi_i_rdata_w; 143 | wire axi_i_rlast_w; 144 | wire [ 31:0] cpu_intr_w; 145 | wire [ 3:0] axi_i_awid_w; 146 | wire [ 31:0] axi_l_awaddr_w; 147 | wire [ 7:0] axi_t_awlen_w; 148 | wire axi_i_wready_w; 149 | wire [ 31:0] axi_l_wdata_w; 150 | wire [ 31:0] enable_w; 151 | wire [ 31:0] axi_l_araddr_w; 152 | wire [ 3:0] axi_l_wstrb_w; 153 | wire soc_intr_w; 154 | wire [ 1:0] axi_t_arburst_w; 155 | wire [ 1:0] axi_t_awburst_w; 156 | wire [ 3:0] axi_i_rid_w; 157 | wire [ 7:0] axi_i_awlen_w; 158 | wire axi_l_wready_w; 159 | wire axi_i_arvalid_w; 160 | wire axi_l_bready_w; 161 | wire [ 31:0] axi_i_awaddr_w; 162 | wire axi_t_rready_w; 163 | wire axi_i_bready_w; 164 | wire [ 31:0] axi_i_wdata_w; 165 | wire axi_t_bready_w; 166 | wire [ 3:0] axi_i_arid_w; 167 | wire axi_i_bvalid_w; 168 | wire axi_l_rvalid_w; 169 | wire [ 3:0] axi_t_bid_w; 170 | wire axi_l_arready_w; 171 | wire axi_i_rready_w; 172 | wire [ 3:0] axi_t_wstrb_w; 173 | wire [ 1:0] axi_t_bresp_w; 174 | wire axi_i_wvalid_w; 175 | wire axi_i_awready_w; 176 | wire rst_cpu_w; 177 | wire axi_i_awvalid_w; 178 | wire [ 31:0] axi_i_araddr_w; 179 | wire axi_t_wready_w; 180 | wire [ 3:0] axi_t_rid_w; 181 | 182 | wire ext1_cfg_awready_w; 183 | wire ext1_cfg_wready_w; 184 | wire ext1_cfg_bvalid_w; 185 | wire [ 1:0] ext1_cfg_bresp_w; 186 | wire ext1_cfg_arready_w; 187 | wire ext1_cfg_rvalid_w; 188 | wire [ 31:0] ext1_cfg_rdata_w; 189 | wire [ 1:0] ext1_cfg_rresp_w; 190 | wire ext1_irq_w; 191 | wire ext2_cfg_awready_w; 192 | wire ext2_cfg_wready_w; 193 | wire ext2_cfg_bvalid_w; 194 | wire [ 1:0] ext2_cfg_bresp_w; 195 | wire ext2_cfg_arready_w; 196 | wire ext2_cfg_rvalid_w; 197 | wire [ 31:0] ext2_cfg_rdata_w; 198 | wire [ 1:0] ext2_cfg_rresp_w; 199 | wire ext2_irq_w; 200 | wire ext3_cfg_awready_w; 201 | wire ext3_cfg_wready_w; 202 | wire ext3_cfg_bvalid_w; 203 | wire [ 1:0] ext3_cfg_bresp_w; 204 | wire ext3_cfg_arready_w; 205 | wire ext3_cfg_rvalid_w; 206 | wire [ 31:0] ext3_cfg_rdata_w; 207 | wire [ 1:0] ext3_cfg_rresp_w; 208 | wire ext3_irq_w; 209 | wire ext1_cfg_awvalid_w; 210 | wire [ 31:0] ext1_cfg_awaddr_w; 211 | wire ext1_cfg_wvalid_w; 212 | wire [ 31:0] ext1_cfg_wdata_w; 213 | wire [ 3:0] ext1_cfg_wstrb_w; 214 | wire ext1_cfg_bready_w; 215 | wire ext1_cfg_arvalid_w; 216 | wire [ 31:0] ext1_cfg_araddr_w; 217 | wire ext1_cfg_rready_w; 218 | wire ext2_cfg_awvalid_w; 219 | wire [ 31:0] ext2_cfg_awaddr_w; 220 | wire ext2_cfg_wvalid_w; 221 | wire [ 31:0] ext2_cfg_wdata_w; 222 | wire [ 3:0] ext2_cfg_wstrb_w; 223 | wire ext2_cfg_bready_w; 224 | wire ext2_cfg_arvalid_w; 225 | wire [ 31:0] ext2_cfg_araddr_w; 226 | wire ext2_cfg_rready_w; 227 | wire ext3_cfg_awvalid_w; 228 | wire [ 31:0] ext3_cfg_awaddr_w; 229 | wire ext3_cfg_wvalid_w; 230 | wire [ 31:0] ext3_cfg_wdata_w; 231 | wire [ 3:0] ext3_cfg_wstrb_w; 232 | wire ext3_cfg_bready_w; 233 | wire ext3_cfg_arvalid_w; 234 | wire [ 31:0] ext3_cfg_araddr_w; 235 | wire ext3_cfg_rready_w; 236 | 237 | dbg_bridge 238 | #( 239 | .CLK_FREQ(CLK_FREQ) 240 | ,.UART_SPEED(UART_SPEED) 241 | ) 242 | u_dbg 243 | ( 244 | // Inputs 245 | .clk_i(clk_i) 246 | ,.rst_i(rst_i) 247 | ,.uart_rxd_i(dbg_txd_i) 248 | ,.mem_awready_i(axi_t_awready_w) 249 | ,.mem_wready_i(axi_t_wready_w) 250 | ,.mem_bvalid_i(axi_t_bvalid_w) 251 | ,.mem_bresp_i(axi_t_bresp_w) 252 | ,.mem_bid_i(axi_t_bid_w) 253 | ,.mem_arready_i(axi_t_arready_w) 254 | ,.mem_rvalid_i(axi_t_rvalid_w) 255 | ,.mem_rdata_i(axi_t_rdata_w) 256 | ,.mem_rresp_i(axi_t_rresp_w) 257 | ,.mem_rid_i(axi_t_rid_w) 258 | ,.mem_rlast_i(axi_t_rlast_w) 259 | ,.gpio_inputs_i(32'b0) 260 | 261 | // Outputs 262 | ,.uart_txd_o(dbg_rxd_o) 263 | ,.mem_awvalid_o(axi_t_awvalid_w) 264 | ,.mem_awaddr_o(axi_t_awaddr_w) 265 | ,.mem_awid_o(axi_t_awid_w) 266 | ,.mem_awlen_o(axi_t_awlen_w) 267 | ,.mem_awburst_o(axi_t_awburst_w) 268 | ,.mem_wvalid_o(axi_t_wvalid_w) 269 | ,.mem_wdata_o(axi_t_wdata_w) 270 | ,.mem_wstrb_o(axi_t_wstrb_w) 271 | ,.mem_wlast_o(axi_t_wlast_w) 272 | ,.mem_bready_o(axi_t_bready_w) 273 | ,.mem_arvalid_o(axi_t_arvalid_w) 274 | ,.mem_araddr_o(axi_t_araddr_w) 275 | ,.mem_arid_o(axi_t_arid_w) 276 | ,.mem_arlen_o(axi_t_arlen_w) 277 | ,.mem_arburst_o(axi_t_arburst_w) 278 | ,.mem_rready_o(axi_t_rready_w) 279 | ,.gpio_outputs_o(enable_w) 280 | ); 281 | 282 | 283 | axi4_axi4lite_conv 284 | u_conv 285 | ( 286 | // Inputs 287 | .clk_i(clk_i) 288 | ,.rst_i(rst_i) 289 | ,.inport_awvalid_i(axi_i_awvalid_w) 290 | ,.inport_awaddr_i(axi_i_awaddr_w) 291 | ,.inport_awid_i(axi_i_awid_w) 292 | ,.inport_awlen_i(axi_i_awlen_w) 293 | ,.inport_awburst_i(axi_i_awburst_w) 294 | ,.inport_wvalid_i(axi_i_wvalid_w) 295 | ,.inport_wdata_i(axi_i_wdata_w) 296 | ,.inport_wstrb_i(axi_i_wstrb_w) 297 | ,.inport_wlast_i(axi_i_wlast_w) 298 | ,.inport_bready_i(axi_i_bready_w) 299 | ,.inport_arvalid_i(axi_i_arvalid_w) 300 | ,.inport_araddr_i(axi_i_araddr_w) 301 | ,.inport_arid_i(axi_i_arid_w) 302 | ,.inport_arlen_i(axi_i_arlen_w) 303 | ,.inport_arburst_i(axi_i_arburst_w) 304 | ,.inport_rready_i(axi_i_rready_w) 305 | ,.outport_awready_i(axi_l_awready_w) 306 | ,.outport_wready_i(axi_l_wready_w) 307 | ,.outport_bvalid_i(axi_l_bvalid_w) 308 | ,.outport_bresp_i(axi_l_bresp_w) 309 | ,.outport_arready_i(axi_l_arready_w) 310 | ,.outport_rvalid_i(axi_l_rvalid_w) 311 | ,.outport_rdata_i(axi_l_rdata_w) 312 | ,.outport_rresp_i(axi_l_rresp_w) 313 | 314 | // Outputs 315 | ,.inport_awready_o(axi_i_awready_w) 316 | ,.inport_wready_o(axi_i_wready_w) 317 | ,.inport_bvalid_o(axi_i_bvalid_w) 318 | ,.inport_bresp_o(axi_i_bresp_w) 319 | ,.inport_bid_o(axi_i_bid_w) 320 | ,.inport_arready_o(axi_i_arready_w) 321 | ,.inport_rvalid_o(axi_i_rvalid_w) 322 | ,.inport_rdata_o(axi_i_rdata_w) 323 | ,.inport_rresp_o(axi_i_rresp_w) 324 | ,.inport_rid_o(axi_i_rid_w) 325 | ,.inport_rlast_o(axi_i_rlast_w) 326 | ,.outport_awvalid_o(axi_l_awvalid_w) 327 | ,.outport_awaddr_o(axi_l_awaddr_w) 328 | ,.outport_wvalid_o(axi_l_wvalid_w) 329 | ,.outport_wdata_o(axi_l_wdata_w) 330 | ,.outport_wstrb_o(axi_l_wstrb_w) 331 | ,.outport_bready_o(axi_l_bready_w) 332 | ,.outport_arvalid_o(axi_l_arvalid_w) 333 | ,.outport_araddr_o(axi_l_araddr_w) 334 | ,.outport_rready_o(axi_l_rready_w) 335 | ); 336 | 337 | riscv_tcm_wrapper 338 | u_cpu 339 | ( 340 | // Inputs 341 | .clk_i(clk_i) 342 | ,.rst_i(rst_i) 343 | ,.rst_cpu_i(rst_cpu_w) 344 | ,.axi_i_awready_i(axi_i_awready_w) 345 | ,.axi_i_wready_i(axi_i_wready_w) 346 | ,.axi_i_bvalid_i(axi_i_bvalid_w) 347 | ,.axi_i_bresp_i(axi_i_bresp_w) 348 | ,.axi_i_bid_i(axi_i_bid_w) 349 | ,.axi_i_arready_i(axi_i_arready_w) 350 | ,.axi_i_rvalid_i(axi_i_rvalid_w) 351 | ,.axi_i_rdata_i(axi_i_rdata_w) 352 | ,.axi_i_rresp_i(axi_i_rresp_w) 353 | ,.axi_i_rid_i(axi_i_rid_w) 354 | ,.axi_i_rlast_i(axi_i_rlast_w) 355 | ,.axi_t_awvalid_i(axi_t_awvalid_w) 356 | ,.axi_t_awaddr_i(axi_t_awaddr_w) 357 | ,.axi_t_awid_i(axi_t_awid_w) 358 | ,.axi_t_awlen_i(axi_t_awlen_w) 359 | ,.axi_t_awburst_i(axi_t_awburst_w) 360 | ,.axi_t_wvalid_i(axi_t_wvalid_w) 361 | ,.axi_t_wdata_i(axi_t_wdata_w) 362 | ,.axi_t_wstrb_i(axi_t_wstrb_w) 363 | ,.axi_t_wlast_i(axi_t_wlast_w) 364 | ,.axi_t_bready_i(axi_t_bready_w) 365 | ,.axi_t_arvalid_i(axi_t_arvalid_w) 366 | ,.axi_t_araddr_i(axi_t_araddr_w) 367 | ,.axi_t_arid_i(axi_t_arid_w) 368 | ,.axi_t_arlen_i(axi_t_arlen_w) 369 | ,.axi_t_arburst_i(axi_t_arburst_w) 370 | ,.axi_t_rready_i(axi_t_rready_w) 371 | ,.intr_i(cpu_intr_w) 372 | 373 | // Outputs 374 | ,.axi_i_awvalid_o(axi_i_awvalid_w) 375 | ,.axi_i_awaddr_o(axi_i_awaddr_w) 376 | ,.axi_i_awid_o(axi_i_awid_w) 377 | ,.axi_i_awlen_o(axi_i_awlen_w) 378 | ,.axi_i_awburst_o(axi_i_awburst_w) 379 | ,.axi_i_wvalid_o(axi_i_wvalid_w) 380 | ,.axi_i_wdata_o(axi_i_wdata_w) 381 | ,.axi_i_wstrb_o(axi_i_wstrb_w) 382 | ,.axi_i_wlast_o(axi_i_wlast_w) 383 | ,.axi_i_bready_o(axi_i_bready_w) 384 | ,.axi_i_arvalid_o(axi_i_arvalid_w) 385 | ,.axi_i_araddr_o(axi_i_araddr_w) 386 | ,.axi_i_arid_o(axi_i_arid_w) 387 | ,.axi_i_arlen_o(axi_i_arlen_w) 388 | ,.axi_i_arburst_o(axi_i_arburst_w) 389 | ,.axi_i_rready_o(axi_i_rready_w) 390 | ,.axi_t_awready_o(axi_t_awready_w) 391 | ,.axi_t_wready_o(axi_t_wready_w) 392 | ,.axi_t_bvalid_o(axi_t_bvalid_w) 393 | ,.axi_t_bresp_o(axi_t_bresp_w) 394 | ,.axi_t_bid_o(axi_t_bid_w) 395 | ,.axi_t_arready_o(axi_t_arready_w) 396 | ,.axi_t_rvalid_o(axi_t_rvalid_w) 397 | ,.axi_t_rdata_o(axi_t_rdata_w) 398 | ,.axi_t_rresp_o(axi_t_rresp_w) 399 | ,.axi_t_rid_o(axi_t_rid_w) 400 | ,.axi_t_rlast_o(axi_t_rlast_w) 401 | ); 402 | 403 | core_soc 404 | #( 405 | .CLK_FREQ(CLK_FREQ) 406 | ,.BAUDRATE(BAUDRATE) 407 | ,.C_SCK_RATIO(C_SCK_RATIO) 408 | ) 409 | u_soc 410 | ( 411 | // Inputs 412 | .clk_i(clk_i) 413 | ,.rst_i(rst_i) 414 | ,.inport_awvalid_i(axi_l_awvalid_w) 415 | ,.inport_awaddr_i(axi_l_awaddr_w) 416 | ,.inport_wvalid_i(axi_l_wvalid_w) 417 | ,.inport_wdata_i(axi_l_wdata_w) 418 | ,.inport_wstrb_i(axi_l_wstrb_w) 419 | ,.inport_bready_i(axi_l_bready_w) 420 | ,.inport_arvalid_i(axi_l_arvalid_w) 421 | ,.inport_araddr_i(axi_l_araddr_w) 422 | ,.inport_rready_i(axi_l_rready_w) 423 | ,.spi_miso_i(spi_miso_i) 424 | ,.uart_rx_i(uart_rx_i) 425 | ,.gpio_input_i(gpio_input_i) 426 | ,.ext1_cfg_awready_i(ext1_cfg_awready_w) 427 | ,.ext1_cfg_wready_i(ext1_cfg_wready_w) 428 | ,.ext1_cfg_bvalid_i(ext1_cfg_bvalid_w) 429 | ,.ext1_cfg_bresp_i(ext1_cfg_bresp_w) 430 | ,.ext1_cfg_arready_i(ext1_cfg_arready_w) 431 | ,.ext1_cfg_rvalid_i(ext1_cfg_rvalid_w) 432 | ,.ext1_cfg_rdata_i(ext1_cfg_rdata_w) 433 | ,.ext1_cfg_rresp_i(ext1_cfg_rresp_w) 434 | ,.ext1_irq_i(ext1_irq_w) 435 | ,.ext2_cfg_awready_i(ext2_cfg_awready_w) 436 | ,.ext2_cfg_wready_i(ext2_cfg_wready_w) 437 | ,.ext2_cfg_bvalid_i(ext2_cfg_bvalid_w) 438 | ,.ext2_cfg_bresp_i(ext2_cfg_bresp_w) 439 | ,.ext2_cfg_arready_i(ext2_cfg_arready_w) 440 | ,.ext2_cfg_rvalid_i(ext2_cfg_rvalid_w) 441 | ,.ext2_cfg_rdata_i(ext2_cfg_rdata_w) 442 | ,.ext2_cfg_rresp_i(ext2_cfg_rresp_w) 443 | ,.ext2_irq_i(ext2_irq_w) 444 | ,.ext3_cfg_awready_i(ext3_cfg_awready_w) 445 | ,.ext3_cfg_wready_i(ext3_cfg_wready_w) 446 | ,.ext3_cfg_bvalid_i(ext3_cfg_bvalid_w) 447 | ,.ext3_cfg_bresp_i(ext3_cfg_bresp_w) 448 | ,.ext3_cfg_arready_i(ext3_cfg_arready_w) 449 | ,.ext3_cfg_rvalid_i(ext3_cfg_rvalid_w) 450 | ,.ext3_cfg_rdata_i(ext3_cfg_rdata_w) 451 | ,.ext3_cfg_rresp_i(ext3_cfg_rresp_w) 452 | ,.ext3_irq_i(ext3_irq_w) 453 | 454 | // Outputs 455 | ,.intr_o(soc_intr_w) 456 | ,.inport_awready_o(axi_l_awready_w) 457 | ,.inport_wready_o(axi_l_wready_w) 458 | ,.inport_bvalid_o(axi_l_bvalid_w) 459 | ,.inport_bresp_o(axi_l_bresp_w) 460 | ,.inport_arready_o(axi_l_arready_w) 461 | ,.inport_rvalid_o(axi_l_rvalid_w) 462 | ,.inport_rdata_o(axi_l_rdata_w) 463 | ,.inport_rresp_o(axi_l_rresp_w) 464 | ,.spi_clk_o(spi_clk_o) 465 | ,.spi_mosi_o(spi_mosi_o) 466 | ,.spi_cs_o(spi_cs_o) 467 | ,.uart_tx_o(uart_tx_o) 468 | ,.gpio_output_o(gpio_output_o) 469 | ,.gpio_output_enable_o(gpio_output_enable_o) 470 | ,.boot_spi_adr_o(boot_spi_adr_o) 471 | ,.reboot_o(reboot_o) 472 | 473 | ,.ext1_cfg_awvalid_o(ext1_cfg_awvalid_w) 474 | ,.ext1_cfg_awaddr_o(ext1_cfg_awaddr_w) 475 | ,.ext1_cfg_wvalid_o(ext1_cfg_wvalid_w) 476 | ,.ext1_cfg_wdata_o(ext1_cfg_wdata_w) 477 | ,.ext1_cfg_wstrb_o(ext1_cfg_wstrb_w) 478 | ,.ext1_cfg_bready_o(ext1_cfg_bready_w) 479 | ,.ext1_cfg_arvalid_o(ext1_cfg_arvalid_w) 480 | ,.ext1_cfg_araddr_o(ext1_cfg_araddr_w) 481 | ,.ext1_cfg_rready_o(ext1_cfg_rready_w) 482 | ,.ext2_cfg_awvalid_o(ext2_cfg_awvalid_w) 483 | ,.ext2_cfg_awaddr_o(ext2_cfg_awaddr_w) 484 | ,.ext2_cfg_wvalid_o(ext2_cfg_wvalid_w) 485 | ,.ext2_cfg_wdata_o(ext2_cfg_wdata_w) 486 | ,.ext2_cfg_wstrb_o(ext2_cfg_wstrb_w) 487 | ,.ext2_cfg_bready_o(ext2_cfg_bready_w) 488 | ,.ext2_cfg_arvalid_o(ext2_cfg_arvalid_w) 489 | ,.ext2_cfg_araddr_o(ext2_cfg_araddr_w) 490 | ,.ext2_cfg_rready_o(ext2_cfg_rready_w) 491 | ,.ext3_cfg_awvalid_o(ext3_cfg_awvalid_w) 492 | ,.ext3_cfg_awaddr_o(ext3_cfg_awaddr_w) 493 | ,.ext3_cfg_wvalid_o(ext3_cfg_wvalid_w) 494 | ,.ext3_cfg_wdata_o(ext3_cfg_wdata_w) 495 | ,.ext3_cfg_wstrb_o(ext3_cfg_wstrb_w) 496 | ,.ext3_cfg_bready_o(ext3_cfg_bready_w) 497 | ,.ext3_cfg_arvalid_o(ext3_cfg_arvalid_w) 498 | ,.ext3_cfg_araddr_o(ext3_cfg_araddr_w) 499 | ,.ext3_cfg_rready_o(ext3_cfg_rready_w) 500 | ); 501 | 502 | // enable_w[0] from the dbg_bridge is used for a reset, but we want to 503 | // come up running so ignore it until it has been asserted and released once 504 | reg bridge_rst_enable; 505 | reg rst_cpu_r; 506 | 507 | always @(posedge clk_i or posedge rst_i) 508 | if (rst_i) begin 509 | bridge_rst_enable <= 0; 510 | rst_cpu_r <= 1; 511 | end 512 | else begin 513 | if(!bridge_rst_enable) 514 | bridge_rst_enable <= enable_w[0]; 515 | 516 | if(bridge_rst_enable) 517 | rst_cpu_r <= ~enable_w[0]; 518 | else 519 | rst_cpu_r <= 0; 520 | end 521 | 522 | 523 | assign rst_cpu_w = rst_cpu_r; 524 | assign cpu_intr_w = {31'b0, soc_intr_w}; 525 | 526 | `ifdef INCLUDE_ETHERNET 527 | eth_axi4lite u_eth ( 528 | // axi4lite Inputs 529 | .clk_i(clk_i) 530 | ,.rst_i(rst_i) 531 | ,.cfg_awvalid_i(ext1_cfg_awvalid_w) 532 | ,.cfg_awaddr_i(ext1_cfg_awaddr_w) 533 | ,.cfg_wvalid_i(ext1_cfg_wvalid_w) 534 | ,.cfg_wdata_i(ext1_cfg_wdata_w) 535 | ,.cfg_wstrb_i(ext1_cfg_wstrb_w) 536 | ,.cfg_bready_i(ext1_cfg_bready_w) 537 | ,.cfg_arvalid_i(ext1_cfg_arvalid_w) 538 | ,.cfg_araddr_i(ext1_cfg_araddr_w) 539 | ,.cfg_rready_i(ext1_cfg_rready_w) 540 | 541 | // axi4lite Outputs 542 | ,.cfg_awready_o(ext1_cfg_awready_w) 543 | ,.cfg_wready_o(ext1_cfg_wready_w) 544 | ,.cfg_bvalid_o(ext1_cfg_bvalid_w) 545 | ,.cfg_bresp_o(ext1_cfg_bresp_w) 546 | ,.cfg_arready_o(ext1_cfg_arready_w) 547 | ,.cfg_rvalid_o(ext1_cfg_rvalid_w) 548 | ,.cfg_rdata_o(ext1_cfg_rdata_w) 549 | ,.cfg_rresp_o(ext1_cfg_rresp_w) 550 | 551 | 552 | // peripheral inputs 553 | ,.clock_125_i(clock_125_i) 554 | 555 | // MII (Media-independent interface) 556 | ,.mii_tx_clk_i(mii_tx_clk_i) 557 | ,.mii_tx_er_o(mii_tx_er_o) 558 | ,.mii_tx_en_o(mii_tx_en_o) 559 | ,.mii_txd_o(mii_txd_o) 560 | ,.mii_rx_clk_i(mii_rx_clk_i) 561 | ,.mii_rx_er_i(mii_rx_er_i) 562 | ,.mii_rx_dv_i(mii_rx_dv_i) 563 | ,.mii_rxd_i(mii_rxd_i) 564 | 565 | // GMII (Gigabit media-independent interface) 566 | ,.gmii_gtx_clk_o(gmii_gtx_clk_o) 567 | 568 | // RGMII (Reduced pin count gigabit media-independent interface) 569 | ,.rgmii_tx_ctl_o(rgmii_tx_ctl_o) 570 | ,.rgmii_rx_ctl_i(rgmii_rx_ctl_i) 571 | 572 | // MII Management Interface 573 | ,.mdc_o(mdc_o) 574 | ,.mdio_io(mdio_io) 575 | ); 576 | `endif 577 | 578 | endmodule 579 | 580 | 581 | -------------------------------------------------------------------------------- /fpga/gpio.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // Basic Peripheral SoC 3 | // V1.1 4 | // Ultra-Embedded.com 5 | // Copyright 2014-2020 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | //----------------------------------------------------------------- 32 | // Generated File 33 | //----------------------------------------------------------------- 34 | 35 | `include "gpio_defs.v" 36 | 37 | //----------------------------------------------------------------- 38 | // Module: General Purpose IO Peripheral 39 | //----------------------------------------------------------------- 40 | module gpio 41 | ( 42 | // Inputs 43 | input clk_i 44 | ,input rst_i 45 | ,input cfg_awvalid_i 46 | ,input [31:0] cfg_awaddr_i 47 | ,input cfg_wvalid_i 48 | ,input [31:0] cfg_wdata_i 49 | ,input [3:0] cfg_wstrb_i 50 | ,input cfg_bready_i 51 | ,input cfg_arvalid_i 52 | ,input [31:0] cfg_araddr_i 53 | ,input cfg_rready_i 54 | ,input [31:0] gpio_input_i 55 | 56 | // Outputs 57 | ,output cfg_awready_o 58 | ,output cfg_wready_o 59 | ,output cfg_bvalid_o 60 | ,output [1:0] cfg_bresp_o 61 | ,output cfg_arready_o 62 | ,output cfg_rvalid_o 63 | ,output [31:0] cfg_rdata_o 64 | ,output [1:0] cfg_rresp_o 65 | ,output [31:0] gpio_output_o 66 | ,output [31:0] gpio_output_enable_o 67 | ,output intr_o 68 | ,output [23:0] boot_spi_adr_o 69 | ,output reboot_o 70 | ); 71 | 72 | //----------------------------------------------------------------- 73 | // Write address / data split 74 | //----------------------------------------------------------------- 75 | // Address but no data ready 76 | reg awvalid_q; 77 | 78 | // Data but no data ready 79 | reg wvalid_q; 80 | 81 | wire wr_cmd_accepted_w = (cfg_awvalid_i && cfg_awready_o) || awvalid_q; 82 | wire wr_data_accepted_w = (cfg_wvalid_i && cfg_wready_o) || wvalid_q; 83 | 84 | always @ (posedge clk_i or posedge rst_i) 85 | if (rst_i) 86 | awvalid_q <= 1'b0; 87 | else if (cfg_awvalid_i && cfg_awready_o && !wr_data_accepted_w) 88 | awvalid_q <= 1'b1; 89 | else if (wr_data_accepted_w) 90 | awvalid_q <= 1'b0; 91 | 92 | always @ (posedge clk_i or posedge rst_i) 93 | if (rst_i) 94 | wvalid_q <= 1'b0; 95 | else if (cfg_wvalid_i && cfg_wready_o && !wr_cmd_accepted_w) 96 | wvalid_q <= 1'b1; 97 | else if (wr_cmd_accepted_w) 98 | wvalid_q <= 1'b0; 99 | 100 | //----------------------------------------------------------------- 101 | // Capture address (for delayed data) 102 | //----------------------------------------------------------------- 103 | reg [7:0] wr_addr_q; 104 | 105 | always @ (posedge clk_i or posedge rst_i) 106 | if (rst_i) 107 | wr_addr_q <= 8'b0; 108 | else if (cfg_awvalid_i && cfg_awready_o) 109 | wr_addr_q <= cfg_awaddr_i[7:0]; 110 | 111 | wire [7:0] wr_addr_w = awvalid_q ? wr_addr_q : cfg_awaddr_i[7:0]; 112 | 113 | //----------------------------------------------------------------- 114 | // Retime write data 115 | //----------------------------------------------------------------- 116 | reg [31:0] wr_data_q; 117 | 118 | always @ (posedge clk_i or posedge rst_i) 119 | if (rst_i) 120 | wr_data_q <= 32'b0; 121 | else if (cfg_wvalid_i && cfg_wready_o) 122 | wr_data_q <= cfg_wdata_i; 123 | 124 | //----------------------------------------------------------------- 125 | // Request Logic 126 | //----------------------------------------------------------------- 127 | wire read_en_w = cfg_arvalid_i & cfg_arready_o; 128 | wire write_en_w = wr_cmd_accepted_w && wr_data_accepted_w; 129 | 130 | //----------------------------------------------------------------- 131 | // Accept Logic 132 | //----------------------------------------------------------------- 133 | assign cfg_arready_o = ~cfg_rvalid_o; 134 | assign cfg_awready_o = ~cfg_bvalid_o && ~cfg_arvalid_i && ~awvalid_q; 135 | assign cfg_wready_o = ~cfg_bvalid_o && ~cfg_arvalid_i && ~wvalid_q; 136 | 137 | 138 | //----------------------------------------------------------------- 139 | // Register gpio_direction 140 | //----------------------------------------------------------------- 141 | reg gpio_direction_wr_q; 142 | 143 | always @ (posedge clk_i or posedge rst_i) 144 | if (rst_i) 145 | gpio_direction_wr_q <= 1'b0; 146 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_DIRECTION)) 147 | gpio_direction_wr_q <= 1'b1; 148 | else 149 | gpio_direction_wr_q <= 1'b0; 150 | 151 | // gpio_direction_output [internal] 152 | reg [31:0] gpio_direction_output_q; 153 | 154 | always @ (posedge clk_i or posedge rst_i) 155 | if (rst_i) 156 | gpio_direction_output_q <= 32'd`GPIO_DIRECTION_OUTPUT_DEFAULT; 157 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_DIRECTION)) 158 | gpio_direction_output_q <= cfg_wdata_i[`GPIO_DIRECTION_OUTPUT_R]; 159 | 160 | wire [31:0] gpio_direction_output_out_w = gpio_direction_output_q; 161 | 162 | 163 | //----------------------------------------------------------------- 164 | // Register gpio_input 165 | //----------------------------------------------------------------- 166 | reg gpio_input_wr_q; 167 | 168 | always @ (posedge clk_i or posedge rst_i) 169 | if (rst_i) 170 | gpio_input_wr_q <= 1'b0; 171 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INPUT)) 172 | gpio_input_wr_q <= 1'b1; 173 | else 174 | gpio_input_wr_q <= 1'b0; 175 | 176 | 177 | //----------------------------------------------------------------- 178 | // Register gpio_output 179 | //----------------------------------------------------------------- 180 | reg gpio_output_wr_q; 181 | 182 | always @ (posedge clk_i or posedge rst_i) 183 | if (rst_i) 184 | gpio_output_wr_q <= 1'b0; 185 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_OUTPUT)) 186 | gpio_output_wr_q <= 1'b1; 187 | else 188 | gpio_output_wr_q <= 1'b0; 189 | 190 | // gpio_output_data [external] 191 | wire [31:0] gpio_output_data_out_w = wr_data_q[`GPIO_OUTPUT_DATA_R]; 192 | 193 | //----------------------------------------------------------------- 194 | // Register gpio1_output 195 | //----------------------------------------------------------------- 196 | 197 | reg [23:0] boot_spi_adr_q; 198 | 199 | always @ (posedge clk_i or posedge rst_i) 200 | if (rst_i) 201 | begin 202 | boot_spi_adr_q <= 24'b0; 203 | end 204 | else if (write_en_w && (wr_addr_w[7:0] == `BOOT_SPI_ADR)) 205 | begin 206 | boot_spi_adr_q <= cfg_wdata_i[23:0]; 207 | end 208 | 209 | assign boot_spi_adr_o = boot_spi_adr_q; 210 | 211 | reg reboot_q; 212 | 213 | always @ (posedge clk_i or posedge rst_i) 214 | if (rst_i) 215 | begin 216 | reboot_q <= 1'b0; 217 | end 218 | else if (write_en_w && (wr_addr_w[7:0] == `REBOOT_ADR)) 219 | begin 220 | reboot_q <= cfg_wdata_i[0]; 221 | end 222 | assign reboot_o = reboot_q; 223 | 224 | //----------------------------------------------------------------- 225 | // Register gpio_output_set 226 | //----------------------------------------------------------------- 227 | reg gpio_output_set_wr_q; 228 | 229 | always @ (posedge clk_i or posedge rst_i) 230 | if (rst_i) 231 | gpio_output_set_wr_q <= 1'b0; 232 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_OUTPUT_SET)) 233 | gpio_output_set_wr_q <= 1'b1; 234 | else 235 | gpio_output_set_wr_q <= 1'b0; 236 | 237 | // gpio_output_set_data [external] 238 | wire [31:0] gpio_output_set_data_out_w = wr_data_q[`GPIO_OUTPUT_SET_DATA_R]; 239 | 240 | 241 | //----------------------------------------------------------------- 242 | // Register gpio_output_clr 243 | //----------------------------------------------------------------- 244 | reg gpio_output_clr_wr_q; 245 | 246 | always @ (posedge clk_i or posedge rst_i) 247 | if (rst_i) 248 | gpio_output_clr_wr_q <= 1'b0; 249 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_OUTPUT_CLR)) 250 | gpio_output_clr_wr_q <= 1'b1; 251 | else 252 | gpio_output_clr_wr_q <= 1'b0; 253 | 254 | // gpio_output_clr_data [external] 255 | wire [31:0] gpio_output_clr_data_out_w = wr_data_q[`GPIO_OUTPUT_CLR_DATA_R]; 256 | 257 | 258 | //----------------------------------------------------------------- 259 | // Register gpio_int_mask 260 | //----------------------------------------------------------------- 261 | reg gpio_int_mask_wr_q; 262 | 263 | always @ (posedge clk_i or posedge rst_i) 264 | if (rst_i) 265 | gpio_int_mask_wr_q <= 1'b0; 266 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_MASK)) 267 | gpio_int_mask_wr_q <= 1'b1; 268 | else 269 | gpio_int_mask_wr_q <= 1'b0; 270 | 271 | // gpio_int_mask_enable [internal] 272 | reg [31:0] gpio_int_mask_enable_q; 273 | 274 | always @ (posedge clk_i or posedge rst_i) 275 | if (rst_i) 276 | gpio_int_mask_enable_q <= 32'd`GPIO_INT_MASK_ENABLE_DEFAULT; 277 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_MASK)) 278 | gpio_int_mask_enable_q <= cfg_wdata_i[`GPIO_INT_MASK_ENABLE_R]; 279 | 280 | wire [31:0] gpio_int_mask_enable_out_w = gpio_int_mask_enable_q; 281 | 282 | 283 | //----------------------------------------------------------------- 284 | // Register gpio_int_set 285 | //----------------------------------------------------------------- 286 | reg gpio_int_set_wr_q; 287 | 288 | always @ (posedge clk_i or posedge rst_i) 289 | if (rst_i) 290 | gpio_int_set_wr_q <= 1'b0; 291 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_SET)) 292 | gpio_int_set_wr_q <= 1'b1; 293 | else 294 | gpio_int_set_wr_q <= 1'b0; 295 | 296 | // gpio_int_set_sw_irq [external] 297 | wire [31:0] gpio_int_set_sw_irq_out_w = wr_data_q[`GPIO_INT_SET_SW_IRQ_R]; 298 | 299 | 300 | //----------------------------------------------------------------- 301 | // Register gpio_int_clr 302 | //----------------------------------------------------------------- 303 | reg gpio_int_clr_wr_q; 304 | 305 | always @ (posedge clk_i or posedge rst_i) 306 | if (rst_i) 307 | gpio_int_clr_wr_q <= 1'b0; 308 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_CLR)) 309 | gpio_int_clr_wr_q <= 1'b1; 310 | else 311 | gpio_int_clr_wr_q <= 1'b0; 312 | 313 | // gpio_int_clr_ack [external] 314 | wire [31:0] gpio_int_clr_ack_out_w = wr_data_q[`GPIO_INT_CLR_ACK_R]; 315 | 316 | 317 | //----------------------------------------------------------------- 318 | // Register gpio_int_status 319 | //----------------------------------------------------------------- 320 | reg gpio_int_status_wr_q; 321 | 322 | always @ (posedge clk_i or posedge rst_i) 323 | if (rst_i) 324 | gpio_int_status_wr_q <= 1'b0; 325 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_STATUS)) 326 | gpio_int_status_wr_q <= 1'b1; 327 | else 328 | gpio_int_status_wr_q <= 1'b0; 329 | 330 | 331 | //----------------------------------------------------------------- 332 | // Register gpio_int_level 333 | //----------------------------------------------------------------- 334 | reg gpio_int_level_wr_q; 335 | 336 | always @ (posedge clk_i or posedge rst_i) 337 | if (rst_i) 338 | gpio_int_level_wr_q <= 1'b0; 339 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_LEVEL)) 340 | gpio_int_level_wr_q <= 1'b1; 341 | else 342 | gpio_int_level_wr_q <= 1'b0; 343 | 344 | // gpio_int_level_active_high [internal] 345 | reg [31:0] gpio_int_level_active_high_q; 346 | 347 | always @ (posedge clk_i or posedge rst_i) 348 | if (rst_i) 349 | gpio_int_level_active_high_q <= 32'd`GPIO_INT_LEVEL_ACTIVE_HIGH_DEFAULT; 350 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_LEVEL)) 351 | gpio_int_level_active_high_q <= cfg_wdata_i[`GPIO_INT_LEVEL_ACTIVE_HIGH_R]; 352 | 353 | wire [31:0] gpio_int_level_active_high_out_w = gpio_int_level_active_high_q; 354 | 355 | 356 | //----------------------------------------------------------------- 357 | // Register gpio_int_mode 358 | //----------------------------------------------------------------- 359 | reg gpio_int_mode_wr_q; 360 | 361 | always @ (posedge clk_i or posedge rst_i) 362 | if (rst_i) 363 | gpio_int_mode_wr_q <= 1'b0; 364 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_MODE)) 365 | gpio_int_mode_wr_q <= 1'b1; 366 | else 367 | gpio_int_mode_wr_q <= 1'b0; 368 | 369 | // gpio_int_mode_edge [internal] 370 | reg [31:0] gpio_int_mode_edge_q; 371 | 372 | always @ (posedge clk_i or posedge rst_i) 373 | if (rst_i) 374 | gpio_int_mode_edge_q <= 32'd`GPIO_INT_MODE_EDGE_DEFAULT; 375 | else if (write_en_w && (wr_addr_w[7:0] == `GPIO_INT_MODE)) 376 | gpio_int_mode_edge_q <= cfg_wdata_i[`GPIO_INT_MODE_EDGE_R]; 377 | 378 | wire [31:0] gpio_int_mode_edge_out_w = gpio_int_mode_edge_q; 379 | 380 | 381 | wire [31:0] gpio_input_value_in_w; 382 | wire [31:0] gpio_output_data_in_w; 383 | wire [31:0] gpio_int_status_raw_in_w; 384 | 385 | 386 | //----------------------------------------------------------------- 387 | // Read mux 388 | //----------------------------------------------------------------- 389 | reg [31:0] data_r; 390 | 391 | always @ * 392 | begin 393 | data_r = 32'b0; 394 | 395 | case (cfg_araddr_i[7:0]) 396 | 397 | `GPIO_DIRECTION: 398 | begin 399 | data_r[`GPIO_DIRECTION_OUTPUT_R] = gpio_direction_output_q; 400 | end 401 | `GPIO_INPUT: 402 | begin 403 | data_r[`GPIO_INPUT_VALUE_R] = gpio_input_value_in_w; 404 | end 405 | `GPIO_OUTPUT: 406 | begin 407 | data_r[`GPIO_OUTPUT_DATA_R] = gpio_output_data_in_w; 408 | end 409 | `GPIO_INT_MASK: 410 | begin 411 | data_r[`GPIO_INT_MASK_ENABLE_R] = gpio_int_mask_enable_q; 412 | end 413 | `GPIO_INT_STATUS: 414 | begin 415 | data_r[`GPIO_INT_STATUS_RAW_R] = gpio_int_status_raw_in_w; 416 | end 417 | `GPIO_INT_LEVEL: 418 | begin 419 | data_r[`GPIO_INT_LEVEL_ACTIVE_HIGH_R] = gpio_int_level_active_high_q; 420 | end 421 | `GPIO_INT_MODE: 422 | begin 423 | data_r[`GPIO_INT_MODE_EDGE_R] = gpio_int_mode_edge_q; 424 | end 425 | `BOOT_SPI_ADR: 426 | begin 427 | data_r[23:0] = boot_spi_adr_q; 428 | end 429 | default : 430 | data_r = 32'b0; 431 | endcase 432 | end 433 | 434 | //----------------------------------------------------------------- 435 | // RVALID 436 | //----------------------------------------------------------------- 437 | reg rvalid_q; 438 | 439 | always @ (posedge clk_i or posedge rst_i) 440 | if (rst_i) 441 | rvalid_q <= 1'b0; 442 | else if (read_en_w) 443 | rvalid_q <= 1'b1; 444 | else if (cfg_rready_i) 445 | rvalid_q <= 1'b0; 446 | 447 | assign cfg_rvalid_o = rvalid_q; 448 | 449 | //----------------------------------------------------------------- 450 | // Retime read response 451 | //----------------------------------------------------------------- 452 | reg [31:0] rd_data_q; 453 | 454 | always @ (posedge clk_i or posedge rst_i) 455 | if (rst_i) 456 | rd_data_q <= 32'b0; 457 | else if (!cfg_rvalid_o || cfg_rready_i) 458 | rd_data_q <= data_r; 459 | 460 | assign cfg_rdata_o = rd_data_q; 461 | assign cfg_rresp_o = 2'b0; 462 | 463 | //----------------------------------------------------------------- 464 | // BVALID 465 | //----------------------------------------------------------------- 466 | reg bvalid_q; 467 | 468 | always @ (posedge clk_i or posedge rst_i) 469 | if (rst_i) 470 | bvalid_q <= 1'b0; 471 | else if (write_en_w) 472 | bvalid_q <= 1'b1; 473 | else if (cfg_bready_i) 474 | bvalid_q <= 1'b0; 475 | 476 | assign cfg_bvalid_o = bvalid_q; 477 | assign cfg_bresp_o = 2'b0; 478 | 479 | wire gpio_output_rd_req_w = read_en_w & (cfg_araddr_i[7:0] == `GPIO_OUTPUT); 480 | 481 | wire gpio_output_wr_req_w = gpio_output_wr_q; 482 | wire gpio_output_set_wr_req_w = gpio_output_set_wr_q; 483 | wire gpio_output_clr_wr_req_w = gpio_output_clr_wr_q; 484 | wire gpio_int_set_wr_req_w = gpio_int_set_wr_q; 485 | wire gpio_int_clr_wr_req_w = gpio_int_clr_wr_q; 486 | 487 | 488 | //----------------------------------------------------------------- 489 | // Inputs 490 | //----------------------------------------------------------------- 491 | // Resync inputs 492 | reg [31:0] input_ms; 493 | reg [31:0] input_q; 494 | 495 | always @ (posedge clk_i or posedge rst_i) 496 | if (rst_i) 497 | begin 498 | input_ms <= 32'b0; 499 | input_q <= 32'b0; 500 | end 501 | else 502 | begin 503 | input_q <= input_ms; 504 | input_ms <= gpio_input_i; 505 | end 506 | 507 | assign gpio_input_value_in_w = input_q; 508 | 509 | //----------------------------------------------------------------- 510 | // Outputs 511 | //----------------------------------------------------------------- 512 | reg [31:0] output_q; 513 | reg [31:0] output_next_r; 514 | 515 | always @ * 516 | begin 517 | output_next_r = output_q; 518 | 519 | if (gpio_output_set_wr_req_w) 520 | output_next_r = output_q | gpio_output_set_data_out_w; 521 | else if (gpio_output_clr_wr_req_w) 522 | output_next_r = output_q & ~gpio_output_clr_data_out_w; 523 | else if (gpio_output_wr_req_w) 524 | output_next_r = gpio_output_data_out_w; 525 | end 526 | 527 | always @ (posedge clk_i or posedge rst_i) 528 | if (rst_i) 529 | output_q <= 32'b0; 530 | else 531 | output_q <= output_next_r; 532 | 533 | assign gpio_output_data_in_w = output_q; 534 | assign gpio_output_o = output_q; 535 | 536 | //----------------------------------------------------------------- 537 | // Interrupts 538 | //----------------------------------------------------------------- 539 | reg intr_q; 540 | 541 | reg [31:0] interrupt_raw_q; 542 | reg [31:0] interrupt_raw_r; 543 | 544 | reg [31:0] input_last_q; 545 | 546 | always @ (posedge clk_i or posedge rst_i) 547 | if (rst_i) 548 | input_last_q <= 32'b0; 549 | else 550 | input_last_q <= gpio_input_value_in_w; 551 | 552 | wire [31:0] active_low_w = (~gpio_int_level_active_high_out_w); 553 | wire [31:0] falling_edge_w = (~gpio_int_level_active_high_out_w); 554 | wire [31:0] level_mask_w = (~gpio_int_mode_edge_out_w); 555 | wire [31:0] edge_mask_w = gpio_int_mode_edge_out_w; 556 | 557 | wire [31:0] level_active_w = (gpio_input_value_in_w ^ active_low_w) & level_mask_w; 558 | 559 | wire [31:0] edge_detect_w = (input_last_q ^ gpio_input_value_in_w); 560 | wire [31:0] edge_active_w = (edge_detect_w & (gpio_input_value_in_w ^ falling_edge_w)) & edge_mask_w; 561 | 562 | reg [31:0] interrupt_level_r; 563 | always @ * 564 | begin 565 | interrupt_raw_r = interrupt_raw_q; 566 | 567 | // Clear (ACK) 568 | if (gpio_int_clr_wr_req_w) 569 | interrupt_raw_r = interrupt_raw_r & ~gpio_int_clr_ack_out_w; 570 | 571 | // New interrupts 572 | interrupt_raw_r = interrupt_raw_r | level_active_w | edge_active_w; 573 | 574 | // Set (SW IRQ) 575 | if (gpio_int_set_wr_req_w) 576 | interrupt_raw_r = interrupt_raw_r | gpio_int_set_sw_irq_out_w; 577 | end 578 | 579 | always @ (posedge clk_i or posedge rst_i) 580 | if (rst_i) 581 | begin 582 | intr_q <= 1'b0; 583 | interrupt_raw_q <= 32'b0; 584 | end 585 | else 586 | begin 587 | intr_q <= |(interrupt_raw_q & gpio_int_mask_enable_out_w); 588 | interrupt_raw_q <= interrupt_raw_r; 589 | end 590 | 591 | assign gpio_int_status_raw_in_w = interrupt_raw_q; 592 | assign intr_o = intr_q; 593 | 594 | //----------------------------------------------------------------- 595 | // Assignments 596 | //----------------------------------------------------------------- 597 | assign gpio_output_enable_o = gpio_direction_output_out_w; 598 | 599 | 600 | endmodule 601 | -------------------------------------------------------------------------------- /fpga/gpio_defs.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // Basic Peripheral SoC 3 | // V1.1 4 | // Ultra-Embedded.com 5 | // Copyright 2014-2020 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | //----------------------------------------------------------------- 32 | // Generated File 33 | //----------------------------------------------------------------- 34 | 35 | `define GPIO_DIRECTION 8'h0 36 | 37 | `define GPIO_DIRECTION_OUTPUT_DEFAULT 0 38 | `define GPIO_DIRECTION_OUTPUT_B 0 39 | `define GPIO_DIRECTION_OUTPUT_T 31 40 | `define GPIO_DIRECTION_OUTPUT_W 32 41 | `define GPIO_DIRECTION_OUTPUT_R 31:0 42 | 43 | `define GPIO_INPUT 8'h4 44 | 45 | `define GPIO_INPUT_VALUE_DEFAULT 0 46 | `define GPIO_INPUT_VALUE_B 0 47 | `define GPIO_INPUT_VALUE_T 31 48 | `define GPIO_INPUT_VALUE_W 32 49 | `define GPIO_INPUT_VALUE_R 31:0 50 | 51 | `define GPIO_OUTPUT 8'h8 52 | 53 | `define GPIO_OUTPUT_DATA_DEFAULT 0 54 | `define GPIO_OUTPUT_DATA_B 0 55 | `define GPIO_OUTPUT_DATA_T 31 56 | `define GPIO_OUTPUT_DATA_W 32 57 | `define GPIO_OUTPUT_DATA_R 31:0 58 | 59 | `define GPIO_OUTPUT_SET 8'hc 60 | 61 | `define GPIO_OUTPUT_SET_DATA_DEFAULT 0 62 | `define GPIO_OUTPUT_SET_DATA_B 0 63 | `define GPIO_OUTPUT_SET_DATA_T 31 64 | `define GPIO_OUTPUT_SET_DATA_W 32 65 | `define GPIO_OUTPUT_SET_DATA_R 31:0 66 | 67 | `define GPIO_OUTPUT_CLR 8'h10 68 | 69 | `define GPIO_OUTPUT_CLR_DATA_DEFAULT 0 70 | `define GPIO_OUTPUT_CLR_DATA_B 0 71 | `define GPIO_OUTPUT_CLR_DATA_T 31 72 | `define GPIO_OUTPUT_CLR_DATA_W 32 73 | `define GPIO_OUTPUT_CLR_DATA_R 31:0 74 | 75 | `define GPIO_INT_MASK 8'h14 76 | 77 | `define GPIO_INT_MASK_ENABLE_DEFAULT 0 78 | `define GPIO_INT_MASK_ENABLE_B 0 79 | `define GPIO_INT_MASK_ENABLE_T 31 80 | `define GPIO_INT_MASK_ENABLE_W 32 81 | `define GPIO_INT_MASK_ENABLE_R 31:0 82 | 83 | `define GPIO_INT_SET 8'h18 84 | 85 | `define GPIO_INT_SET_SW_IRQ_DEFAULT 0 86 | `define GPIO_INT_SET_SW_IRQ_B 0 87 | `define GPIO_INT_SET_SW_IRQ_T 31 88 | `define GPIO_INT_SET_SW_IRQ_W 32 89 | `define GPIO_INT_SET_SW_IRQ_R 31:0 90 | 91 | `define GPIO_INT_CLR 8'h1c 92 | 93 | `define GPIO_INT_CLR_ACK_DEFAULT 0 94 | `define GPIO_INT_CLR_ACK_B 0 95 | `define GPIO_INT_CLR_ACK_T 31 96 | `define GPIO_INT_CLR_ACK_W 32 97 | `define GPIO_INT_CLR_ACK_R 31:0 98 | 99 | `define GPIO_INT_STATUS 8'h20 100 | 101 | `define GPIO_INT_STATUS_RAW_DEFAULT 0 102 | `define GPIO_INT_STATUS_RAW_B 0 103 | `define GPIO_INT_STATUS_RAW_T 31 104 | `define GPIO_INT_STATUS_RAW_W 32 105 | `define GPIO_INT_STATUS_RAW_R 31:0 106 | 107 | `define GPIO_INT_LEVEL 8'h24 108 | 109 | `define GPIO_INT_LEVEL_ACTIVE_HIGH_DEFAULT 0 110 | `define GPIO_INT_LEVEL_ACTIVE_HIGH_B 0 111 | `define GPIO_INT_LEVEL_ACTIVE_HIGH_T 31 112 | `define GPIO_INT_LEVEL_ACTIVE_HIGH_W 32 113 | `define GPIO_INT_LEVEL_ACTIVE_HIGH_R 31:0 114 | 115 | `define GPIO_INT_MODE 8'h28 116 | 117 | `define GPIO_INT_MODE_EDGE_DEFAULT 0 118 | `define GPIO_INT_MODE_EDGE_B 0 119 | `define GPIO_INT_MODE_EDGE_T 31 120 | `define GPIO_INT_MODE_EDGE_W 32 121 | `define GPIO_INT_MODE_EDGE_R 31:0 122 | 123 | `define BOOT_SPI_ADR 8'h2c 124 | 125 | `define REBOOT_ADR 8'h30 126 | 127 | -------------------------------------------------------------------------------- /fpga/mak.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -e build ]; then mkdir build; fi 4 | (time make) 2>&1 | tee build/build.log 5 | -------------------------------------------------------------------------------- /fpga/reset_gen.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // FPGA Test Soc 3 | // V0.1 4 | // Ultra-Embedded.com 5 | // Copyright 2019 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | module reset_gen 31 | ( 32 | input clk_i, 33 | output rst_o 34 | ); 35 | 36 | reg [3:0] count_q = 4'b0; 37 | reg rst_q = 1'b1; 38 | 39 | always @(posedge clk_i) 40 | if (count_q != 4'hF) 41 | count_q <= count_q + 4'd1; 42 | else 43 | rst_q <= 1'b0; 44 | 45 | assign rst_o = rst_q; 46 | 47 | endmodule -------------------------------------------------------------------------------- /fpga/top.v: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // TOP 3 | //----------------------------------------------------------------- 4 | module top 5 | ( 6 | input SYSCLK 7 | ,inout pano_button 8 | ,output GMII_RST_N 9 | ,output led_red 10 | ,inout led_green 11 | ,inout led_blue 12 | 13 | // UART 14 | ,input uart_txd_i 15 | ,output uart_rxd_o 16 | // SPI-Flash 17 | ,output flash_sck_o 18 | ,output flash_cs_o 19 | ,output flash_si_o 20 | ,input flash_so_i 21 | 22 | `ifdef INCLUDE_ETHERNET 23 | // MII (Media-independent interface) 24 | ,input mii_tx_clk_i 25 | ,output mii_tx_er_o 26 | ,output mii_tx_en_o 27 | ,output [7:0] mii_txd_o 28 | ,input mii_rx_clk_i 29 | ,input mii_rx_er_i 30 | ,input mii_rx_dv_i 31 | ,input [7:0] mii_rxd_i 32 | 33 | // GMII (Gigabit media-independent interface) 34 | ,output gmii_gtx_clk_o 35 | 36 | // RGMII (Reduced pin count gigabit media-independent interface) 37 | ,output rgmii_tx_ctl_o 38 | ,input rgmii_rx_ctl_i 39 | 40 | // MII Management Interface 41 | ,output mdc_o 42 | ,inout mdio_io 43 | `endif 44 | ); 45 | 46 | // Generate 50 Mhz system clock and 24 Mhz USB clock from 125 Mhz input clock 47 | wire clk50; 48 | 49 | IBUFG clk125_buf 50 | ( .O (clk125), 51 | .I (SYSCLK) 52 | ); 53 | 54 | 55 | PLL_BASE 56 | #(.BANDWIDTH ("OPTIMIZED"), 57 | .CLKFBOUT_MULT (24), 58 | .CLKFBOUT_PHASE (0.000), 59 | .CLK_FEEDBACK ("CLKFBOUT"), 60 | .CLKIN_PERIOD (8.000), 61 | .COMPENSATION ("SYSTEM_SYNCHRONOUS"), 62 | .DIVCLK_DIVIDE (5), 63 | .REF_JITTER (0.010), 64 | .CLKOUT0_DIVIDE (15), 65 | .CLKOUT0_DUTY_CYCLE (0.500), 66 | .CLKOUT0_PHASE (0.000), 67 | .CLKOUT1_DIVIDE (30), 68 | .CLKOUT1_DUTY_CYCLE (0.500), 69 | .CLKOUT1_PHASE (0.000) 70 | ) 71 | pll_base_inst 72 | // Output clocks 73 | (.CLKFBOUT (clkfbout), 74 | .CLKOUT0 (clkout50), 75 | .CLKOUT1 (clkout20), 76 | .CLKOUT2 (), 77 | .CLKOUT3 (), 78 | .CLKOUT4 (), 79 | .CLKOUT5 (), 80 | // Status and control signals 81 | .LOCKED (), 82 | .RST (RESET), 83 | // Input clock control 84 | .CLKFBIN (clkfbout_buf), 85 | .CLKIN (clk125) 86 | ); 87 | 88 | // Output buffering 89 | //----------------------------------- 90 | BUFG clkf_buf 91 | (.O (clkfbout_buf), 92 | .I (clkfbout)); 93 | 94 | BUFG clk50_buf 95 | (.O (clk50), 96 | .I (clkout50)); 97 | 98 | BUFG clk20_buf 99 | (.O (clk20), 100 | .I (clkout20)); 101 | 102 | //----------------------------------------------------------------- 103 | // Reset 104 | //----------------------------------------------------------------- 105 | wire rst; 106 | 107 | reset_gen 108 | u_rst 109 | ( 110 | .clk_i(clk50), 111 | .rst_o(rst) 112 | ); 113 | 114 | //----------------------------------------------------------------- 115 | // Core 116 | //----------------------------------------------------------------- 117 | wire dbg_txd_w; 118 | wire uart_txd_w; 119 | 120 | wire spi_clk_w; 121 | wire spi_so_w; 122 | wire spi_si_w; 123 | wire [7:0] spi_cs_w; 124 | 125 | wire [31:0] gpio_in_w; 126 | wire [31:0] gpio_out_w; 127 | wire [31:0] gpio_out_en_w; 128 | wire [23:0] boot_spi_adr_w; 129 | 130 | fpga_top 131 | #( 132 | .CLK_FREQ(40000000) 133 | ,.BAUDRATE(1000000) // SoC UART baud rate 134 | ,.UART_SPEED(1000000) // Debug bridge UART baud (should match BAUDRATE) 135 | ,.C_SCK_RATIO(1) // SPI clock divider (M25P128 maxclock = 54 Mhz) 136 | ,.CPU("riscv") // riscv or armv6m 137 | ) 138 | u_top 139 | ( 140 | .clock_125_i(clk125) 141 | ,.clk_i(clk50) 142 | ,.rst_i(rst) 143 | 144 | ,.dbg_rxd_o(dbg_txd_w) 145 | ,.dbg_txd_i(uart_txd_i) 146 | 147 | ,.uart_tx_o(uart_txd_w) 148 | ,.uart_rx_i(uart_txd_i) 149 | 150 | ,.spi_clk_o(spi_clk_w) 151 | ,.spi_mosi_o(spi_si_w) 152 | ,.spi_miso_i(spi_so_w) 153 | ,.spi_cs_o(spi_cs_w) 154 | ,.gpio_input_i(gpio_in_w) 155 | ,.gpio_output_o(gpio_out_w) 156 | ,.gpio_output_enable_o(gpio_out_en_w) 157 | ,.boot_spi_adr_o(boot_spi_adr_w) 158 | ,.reboot_o(reboot_o) 159 | 160 | `ifdef INCLUDE_ETHERNET 161 | // MII (Media-independent interface) 162 | ,.mii_tx_clk_i(mii_tx_clk_i) 163 | ,.mii_tx_er_o(mii_tx_er_o) 164 | ,.mii_tx_en_o(mii_tx_en_o) 165 | ,.mii_txd_o(mii_txd_o) 166 | ,.mii_rx_clk_i(mii_rx_clk_i) 167 | ,.mii_rx_er_i(mii_rx_er_i) 168 | ,.mii_rx_dv_i(mii_rx_dv_i) 169 | ,.mii_rxd_i(mii_rxd_i) 170 | 171 | // GMII (Gigabit media-independent interface) 172 | ,.gmii_gtx_clk_o(gmii_gtx_clk_o) 173 | 174 | // RGMII (Reduced pin count gigabit media-independent interface) 175 | ,.rgmii_tx_ctl_o(rgmii_tx_ctl_o) 176 | ,.rgmii_rx_ctl_i(rgmii_rx_ctl_i) 177 | // 178 | ,.mdc_o(mdc_o) 179 | ,.mdio_io(mdio_io) 180 | `endif 181 | ); 182 | 183 | //----------------------------------------------------------------- 184 | // SPI Flash 185 | //----------------------------------------------------------------- 186 | assign flash_sck_o = spi_clk_w; 187 | assign flash_si_o = spi_si_w; 188 | assign flash_cs_o = spi_cs_w[0]; 189 | assign spi_so_w = flash_so_i; 190 | 191 | //----------------------------------------------------------------- 192 | // GPIO bits 193 | // 0: Not implmented 194 | // 1: Pano button 195 | // 2: Output only - red LED 196 | // 3: In/out - green LED 197 | // 4: In/out - blue LED 198 | // 5: Wolfson codec SDA 199 | // 6: Wolfson codec SCL 200 | // 7: GMII reset 201 | // 9...31: Not implmented 202 | //----------------------------------------------------------------- 203 | 204 | assign gpio_in_w[0] = gpio_out_w[0]; 205 | 206 | assign pano_button = gpio_out_en_w[1] ? gpio_out_w[1] : 1'bz; 207 | assign gpio_in_w[1] = pano_button; 208 | 209 | assign led_red = gpio_out_w[2]; 210 | assign gpio_in_w[2] = led_red; 211 | 212 | assign led_green = gpio_out_en_w[3] ? gpio_out_w[3] : 1'bz; 213 | assign gpio_in_w[3] = led_green; 214 | 215 | assign led_blue = gpio_out_en_w[4] ? gpio_out_w[4] : 1'bz; 216 | assign gpio_in_w[4] = led_blue; 217 | 218 | assign codec_sda = gpio_out_en_w[5] ? gpio_out_w[5] : 1'bz; 219 | assign gpio_in_w[5] = codec_sda; 220 | 221 | 222 | assign codec_scl = gpio_out_en_w[6] ? gpio_out_w[6] : 1'bz; 223 | assign gpio_in_w[6] = codec_scl; 224 | 225 | genvar i; 226 | generate 227 | for (i=7; i < 32; i=i+1) begin : gpio_in 228 | assign gpio_in_w[i] = 1'b0; 229 | end 230 | endgenerate 231 | 232 | //----------------------------------------------------------------- 233 | // UART Tx combine 234 | //----------------------------------------------------------------- 235 | // Xilinx placement pragmas: 236 | //synthesis attribute IOB of uart_rxd_o is "TRUE" 237 | reg txd_q; 238 | 239 | always @ (posedge clk50 or posedge rst) 240 | if (rst) 241 | txd_q <= 1'b1; 242 | else 243 | txd_q <= dbg_txd_w & uart_txd_w; 244 | 245 | // 'OR' two UARTs together 246 | assign uart_rxd_o = txd_q; 247 | 248 | //----------------------------------------------------------------- 249 | // Tie-offs 250 | //----------------------------------------------------------------- 251 | 252 | // Must remove reset from the Ethernet Phy for 125 Mhz input clock. 253 | // See https://github.com/tomverbeure/panologic-g2 254 | assign GMII_RST_N = !gpio_out_w[7]; 255 | 256 | //----------------------------------------------------------------- 257 | // Boot another bitstream 258 | //----------------------------------------------------------------- 259 | 260 | multiboot u_boot 261 | ( 262 | .clk(clk20) 263 | ,.rst(rst) 264 | ,.boot(reboot_o) 265 | ,.boot_spi_adr(boot_spi_adr_w) 266 | ); 267 | 268 | endmodule 269 | -------------------------------------------------------------------------------- /fpga/top_g2.ucf: -------------------------------------------------------------------------------- 1 | # Clocks 2 | NET "SYSCLK" PERIOD = 125 MHz HIGH 50% | LOC = "Y13"; 3 | 4 | # Flash 5 | NET "flash_cs_o" LOC="T5" | IOSTANDARD=LVCMOS33; 6 | NET "flash_sck_o" LOC="Y21" | IOSTANDARD=LVCMOS33; 7 | NET "flash_si_o" LOC="AB20" | IOSTANDARD=LVCMOS33; 8 | NET "flash_so_i" LOC="AA20" | IOSTANDARD=LVCMOS33; 9 | 10 | # serial cable connected to mini HDMI DDC signals 11 | NET "uart_txd_i" LOC="AA21" | IOSTANDARD=LVTTL; # AKA DDC2_SCK (PC->Pano) 12 | NET "uart_rxd_o" LOC="AB19" | IOSTANDARD=LVTTL; # AKA DDC2_SDA (Pano->PC) 13 | 14 | # Ethernet PHY 15 | NET "GMII_RST_N" LOC = R11 | IOSTANDARD = LVCMOS33; 16 | 17 | # Pano Button LED Output, Active High 18 | NET "led_red" LOC = E12 | IOSTANDARD = LVCMOS33; 19 | NET "led_blue" LOC = H13 | IOSTANDARD = LVCMOS33; 20 | NET "led_green" LOC = F13 | IOSTANDARD = LVCMOS33; 21 | 22 | # Pano Button Input, Active Low 23 | NET "pano_button" LOC = H12 | IOSTANDARD = LVCMOS33 | PULLUP; 24 | 25 | # Wolfson codec audio interface 26 | #NET "codec_scl" LOC = U17 | IOSTANDARD = LVCMOS33; 27 | #NET "codec_sda" LOC = AB17 | IOSTANDARD = LVCMOS33; 28 | 29 | -------------------------------------------------------------------------------- /fw/include/eth_io.h: -------------------------------------------------------------------------------- 1 | #ifndef _ETH_IO_H_ 2 | #define _ETH_IO_H_ 3 | 4 | #define ETH_RX_OFFSET 0x0 5 | #define ETH_TX_OFFSET 0x4 6 | #define ETH_STATUS_OFFSET 0x8 7 | 8 | #define ETH_STATUS_TXRESET (1 << 0) 9 | #define ETH_STATUS_RXRESET (1 << 1) 10 | #define ETH_STATUS_RXEMPTY (1 << 2) 11 | #define ETH_STATUS_TXFULL (1 << 3) 12 | #define ETH_STATUS_IE (1 << 4) 13 | #define ETH_STATUS_LINK_UP (1 << 5) 14 | 15 | #define ETH_LINK_SPEED_SHIFT 6 16 | #define ETH_STATUS_LINK_SPEED (3 << ETH_LINK_SPEED_SHIFT) 17 | 18 | #define ETH_RX() (*((volatile uint8_t *)(ETH_BASE + ETH_RX_OFFSET))) 19 | #define ETH_TX *((volatile uint8_t *)(ETH_BASE + ETH_TX_OFFSET)) 20 | #define ETH_STATUS *((volatile uint32_t *)(ETH_BASE + ETH_STATUS_OFFSET)) 21 | 22 | // Speed constants 23 | #define SPEED_1000MBPS (2 << ETH_LINK_SPEED_SHIFT) 24 | #define SPEED_100MBPS (1 << ETH_LINK_SPEED_SHIFT) 25 | #define SPEED_10MBPS (0 << ETH_LINK_SPEED_SHIFT) 26 | #define SPEED_UNSPECIFIED (3 << ETH_LINK_SPEED_SHIFT) 27 | 28 | // Change this if you like, this was copied from the label on one of Skip's G2s 29 | #define MAC_ADR 0x00,0x1c,0x02,0x70,0x1d,0x5d 30 | 31 | #endif // _ETH_IO_H_ 32 | 33 | -------------------------------------------------------------------------------- /fw/include/gpio_defs.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------- 2 | // Basic Peripheral SoC 3 | // V1.1 4 | // Ultra-Embedded.com 5 | // Copyright 2014-2020 6 | // 7 | // Email: admin@ultra-embedded.com 8 | // 9 | // License: GPL 10 | // If you would like a version with a more permissive license for 11 | // use in closed source commercial applications please contact me 12 | // for details. 13 | //----------------------------------------------------------------- 14 | // 15 | // This file is open source HDL; you can redistribute it and/or 16 | // modify it under the terms of the GNU General Public License as 17 | // published by the Free Software Foundation; either version 2 of 18 | // the License, or (at your option) any later version. 19 | // 20 | // This file is distributed in the hope that it will be useful, 21 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | // GNU General Public License for more details. 24 | // 25 | // You should have received a copy of the GNU General Public 26 | // License along with this file; if not, write to the Free Software 27 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 28 | // USA 29 | //----------------------------------------------------------------- 30 | 31 | //----------------------------------------------------------------- 32 | // Generated File 33 | //----------------------------------------------------------------- 34 | 35 | #ifndef __GPIO_DEFS_H__ 36 | #define __GPIO_DEFS_H__ 37 | 38 | #define GPIO_DIRECTION 0x0 39 | #define GPIO_DIRECTION_OUTPUT_SHIFT 0 40 | #define GPIO_DIRECTION_OUTPUT_MASK 0xffffffff 41 | 42 | #define GPIO_INPUT 0x4 43 | #define GPIO_INPUT_VALUE_SHIFT 0 44 | #define GPIO_INPUT_VALUE_MASK 0xffffffff 45 | 46 | #define GPIO_OUTPUT 0x8 47 | #define GPIO_OUTPUT_DATA_SHIFT 0 48 | #define GPIO_OUTPUT_DATA_MASK 0xffffffff 49 | 50 | #define GPIO_OUTPUT_SET 0xc 51 | #define GPIO_OUTPUT_SET_DATA_SHIFT 0 52 | #define GPIO_OUTPUT_SET_DATA_MASK 0xffffffff 53 | 54 | #define GPIO_OUTPUT_CLR 0x10 55 | #define GPIO_OUTPUT_CLR_DATA_SHIFT 0 56 | #define GPIO_OUTPUT_CLR_DATA_MASK 0xffffffff 57 | 58 | #define GPIO_INT_MASK 0x14 59 | #define GPIO_INT_MASK_ENABLE_SHIFT 0 60 | #define GPIO_INT_MASK_ENABLE_MASK 0xffffffff 61 | 62 | #define GPIO_INT_SET 0x18 63 | #define GPIO_INT_SET_SW_IRQ_SHIFT 0 64 | #define GPIO_INT_SET_SW_IRQ_MASK 0xffffffff 65 | 66 | #define GPIO_INT_CLR 0x1c 67 | #define GPIO_INT_CLR_ACK_SHIFT 0 68 | #define GPIO_INT_CLR_ACK_MASK 0xffffffff 69 | 70 | #define GPIO_INT_STATUS 0x20 71 | #define GPIO_INT_STATUS_RAW_SHIFT 0 72 | #define GPIO_INT_STATUS_RAW_MASK 0xffffffff 73 | 74 | #define GPIO_INT_LEVEL 0x24 75 | #define GPIO_INT_LEVEL_ACTIVE_HIGH_SHIFT 0 76 | #define GPIO_INT_LEVEL_ACTIVE_HIGH_MASK 0xffffffff 77 | 78 | #define GPIO_INT_MODE 0x28 79 | #define GPIO_INT_MODE_EDGE_SHIFT 0 80 | #define GPIO_INT_MODE_EDGE_MASK 0xffffffff 81 | 82 | #define BOOT_SPI_ADR 0x2c 83 | 84 | #define REBOOT_ADR 0x30 85 | 86 | 87 | #endif -------------------------------------------------------------------------------- /fw/include/pano_io.h: -------------------------------------------------------------------------------- 1 | #ifndef _PANIO_IO_H_ 2 | #define _PANIO_IO_H_ 3 | 4 | #define GPIO_BASE 0x94000000 5 | #define ETH_BASE 0x95000000 6 | 7 | #define GPIO_BIT_PANO_BUTTON 0x02 8 | #define GPIO_BIT_RED_LED 0x04 9 | #define GPIO_BIT_GREEN_LED 0x08 10 | #define GPIO_BIT_BLUE_LED 0x10 11 | #define GPIO_BIT_CODEC_SDA 0x20 12 | #define GPIO_BIT_CODEC_SCL 0x40 13 | 14 | #define GPIO_LED_BITS (GPIO_BIT_RED_LED | \ 15 | GPIO_BIT_GREEN_LED | \ 16 | GPIO_BIT_BLUE_LED) 17 | 18 | 19 | #endif // _PANIO_IO_H_ 20 | 21 | -------------------------------------------------------------------------------- /fw/include/spiffs_config_g2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spiffs_config.h 3 | * 4 | * Created on: Jul 3, 2013 5 | * Author: petera 6 | */ 7 | 8 | #ifndef SPIFFS_CONFIG_H_ 9 | #define SPIFFS_CONFIG_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef int32_t s32_t; 18 | typedef uint32_t u32_t; 19 | typedef int16_t s16_t; 20 | typedef uint16_t u16_t; 21 | typedef int8_t s8_t; 22 | typedef uint8_t u8_t; 23 | 24 | // compile time switches 25 | 26 | // Set generic spiffs debug output call. 27 | #ifndef SPIFFS_DBG 28 | #define SPIFFS_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 29 | #endif 30 | // Set spiffs debug output call for garbage collecting. 31 | #ifndef SPIFFS_GC_DBG 32 | #define SPIFFS_GC_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 33 | #endif 34 | // Set spiffs debug output call for caching. 35 | #ifndef SPIFFS_CACHE_DBG 36 | #define SPIFFS_CACHE_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 37 | #endif 38 | // Set spiffs debug output call for system consistency checks. 39 | #ifndef SPIFFS_CHECK_DBG 40 | #define SPIFFS_CHECK_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 41 | #endif 42 | // Set spiffs debug output call for all api invocations. 43 | #ifndef SPIFFS_API_DBG 44 | #define SPIFFS_API_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 45 | #endif 46 | 47 | 48 | 49 | // Defines spiffs debug print formatters 50 | // some general signed number 51 | #ifndef _SPIPRIi 52 | #define _SPIPRIi "%d" 53 | #endif 54 | // address 55 | #ifndef _SPIPRIad 56 | #define _SPIPRIad "%08x" 57 | #endif 58 | // block 59 | #ifndef _SPIPRIbl 60 | #define _SPIPRIbl "%04x" 61 | #endif 62 | // page 63 | #ifndef _SPIPRIpg 64 | #define _SPIPRIpg "%04x" 65 | #endif 66 | // span index 67 | #ifndef _SPIPRIsp 68 | #define _SPIPRIsp "%04x" 69 | #endif 70 | // file descriptor 71 | #ifndef _SPIPRIfd 72 | #define _SPIPRIfd "%d" 73 | #endif 74 | // file object id 75 | #ifndef _SPIPRIid 76 | #define _SPIPRIid "%04x" 77 | #endif 78 | // file flags 79 | #ifndef _SPIPRIfl 80 | #define _SPIPRIfl "%02x" 81 | #endif 82 | 83 | 84 | // Enable/disable API functions to determine exact number of bytes 85 | // for filedescriptor and cache buffers. Once decided for a configuration, 86 | // this can be disabled to reduce flash. 87 | #ifndef SPIFFS_BUFFER_HELP 88 | #define SPIFFS_BUFFER_HELP 0 89 | #endif 90 | 91 | // Enables/disable memory read caching of nucleus file system operations. 92 | // If enabled, memory area must be provided for cache in SPIFFS_mount. 93 | #ifndef SPIFFS_CACHE 94 | #define SPIFFS_CACHE 0 95 | #endif 96 | #if SPIFFS_CACHE 97 | // Enables memory write caching for file descriptors in hydrogen 98 | #ifndef SPIFFS_CACHE_WR 99 | #define SPIFFS_CACHE_WR 1 100 | #endif 101 | 102 | // Enable/disable statistics on caching. Debug/test purpose only. 103 | #ifndef SPIFFS_CACHE_STATS 104 | #define SPIFFS_CACHE_STATS 1 105 | #endif 106 | #endif 107 | 108 | // Always check header of each accessed page to ensure consistent state. 109 | // If enabled it will increase number of reads, will increase flash. 110 | #ifndef SPIFFS_PAGE_CHECK 111 | #define SPIFFS_PAGE_CHECK 1 112 | #endif 113 | 114 | // Define maximum number of gc runs to perform to reach desired free pages. 115 | #ifndef SPIFFS_GC_MAX_RUNS 116 | #define SPIFFS_GC_MAX_RUNS 5 117 | #endif 118 | 119 | // Enable/disable statistics on gc. Debug/test purpose only. 120 | #ifndef SPIFFS_GC_STATS 121 | #define SPIFFS_GC_STATS 1 122 | #endif 123 | 124 | // Garbage collecting examines all pages in a block which and sums up 125 | // to a block score. Deleted pages normally gives positive score and 126 | // used pages normally gives a negative score (as these must be moved). 127 | // To have a fair wear-leveling, the erase age is also included in score, 128 | // whose factor normally is the most positive. 129 | // The larger the score, the more likely it is that the block will 130 | // picked for garbage collection. 131 | 132 | // Garbage collecting heuristics - weight used for deleted pages. 133 | #ifndef SPIFFS_GC_HEUR_W_DELET 134 | #define SPIFFS_GC_HEUR_W_DELET (5) 135 | #endif 136 | // Garbage collecting heuristics - weight used for used pages. 137 | #ifndef SPIFFS_GC_HEUR_W_USED 138 | #define SPIFFS_GC_HEUR_W_USED (-1) 139 | #endif 140 | // Garbage collecting heuristics - weight used for time between 141 | // last erased and erase of this block. 142 | #ifndef SPIFFS_GC_HEUR_W_ERASE_AGE 143 | #define SPIFFS_GC_HEUR_W_ERASE_AGE (50) 144 | #endif 145 | 146 | // Object name maximum length. Note that this length include the 147 | // zero-termination character, meaning maximum string of characters 148 | // can at most be SPIFFS_OBJ_NAME_LEN - 1. 149 | #ifndef SPIFFS_OBJ_NAME_LEN 150 | #define SPIFFS_OBJ_NAME_LEN (32) 151 | #endif 152 | 153 | // Maximum length of the metadata associated with an object. 154 | // Setting to non-zero value enables metadata-related API but also 155 | // changes the on-disk format, so the change is not backward-compatible. 156 | // 157 | // Do note: the meta length must never exceed 158 | // logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64) 159 | // 160 | // This is derived from following: 161 | // logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) + 162 | // spiffs_object_ix_header fields + at least some LUT entries) 163 | #ifndef SPIFFS_OBJ_META_LEN 164 | #define SPIFFS_OBJ_META_LEN (0) 165 | #endif 166 | 167 | // Size of buffer allocated on stack used when copying data. 168 | // Lower value generates more read/writes. No meaning having it bigger 169 | // than logical page size. 170 | #ifndef SPIFFS_COPY_BUFFER_STACK 171 | #define SPIFFS_COPY_BUFFER_STACK (64) 172 | #endif 173 | 174 | // Enable this to have an identifiable spiffs filesystem. This will look for 175 | // a magic in all sectors to determine if this is a valid spiffs system or 176 | // not on mount point. If not, SPIFFS_format must be called prior to mounting 177 | // again. 178 | #ifndef SPIFFS_USE_MAGIC 179 | #define SPIFFS_USE_MAGIC (0) 180 | #endif 181 | 182 | #if SPIFFS_USE_MAGIC 183 | // Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is 184 | // enabled, the magic will also be dependent on the length of the filesystem. 185 | // For example, a filesystem configured and formatted for 4 megabytes will not 186 | // be accepted for mounting with a configuration defining the filesystem as 2 187 | // megabytes. 188 | #ifndef SPIFFS_USE_MAGIC_LENGTH 189 | #define SPIFFS_USE_MAGIC_LENGTH (1) 190 | #endif 191 | #endif 192 | 193 | // SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level 194 | // These should be defined on a multithreaded system 195 | 196 | // define this to enter a mutex if you're running on a multithreaded system 197 | #ifndef SPIFFS_LOCK 198 | #define SPIFFS_LOCK(fs) 199 | #endif 200 | // define this to exit a mutex if you're running on a multithreaded system 201 | #ifndef SPIFFS_UNLOCK 202 | #define SPIFFS_UNLOCK(fs) 203 | #endif 204 | 205 | // Enable if only one spiffs instance with constant configuration will exist 206 | // on the target. This will reduce calculations, flash and memory accesses. 207 | // Parts of configuration must be defined below instead of at time of mount. 208 | #ifndef SPIFFS_SINGLETON 209 | #define SPIFFS_SINGLETON 1 210 | #endif 211 | 212 | #if SPIFFS_SINGLETON 213 | // Instead of giving parameters in config struct, singleton build must 214 | // give parameters in defines below. 215 | #ifndef SPIFFS_CFG_PHYS_SZ 216 | #define SPIFFS_CFG_PHYS_SZ(ignore) (0x760000) 217 | #endif 218 | #ifndef SPIFFS_CFG_PHYS_ERASE_SZ 219 | #define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (131072) 220 | #endif 221 | #ifndef SPIFFS_CFG_PHYS_ADDR 222 | #define SPIFFS_CFG_PHYS_ADDR(ignore) (0x8a0000) 223 | #endif 224 | #ifndef SPIFFS_CFG_LOG_PAGE_SZ 225 | #define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) 226 | #endif 227 | #ifndef SPIFFS_CFG_LOG_BLOCK_SZ 228 | #define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (131072) 229 | #endif 230 | #endif 231 | 232 | // Enable this if your target needs aligned data for index tables 233 | #ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 234 | #define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 235 | #endif 236 | 237 | // Enable this if you want the HAL callbacks to be called with the spiffs struct 238 | #ifndef SPIFFS_HAL_CALLBACK_EXTRA 239 | #define SPIFFS_HAL_CALLBACK_EXTRA 0 240 | #endif 241 | 242 | // Enable this if you want to add an integer offset to all file handles 243 | // (spiffs_file). This is useful if running multiple instances of spiffs on 244 | // same target, in order to recognise to what spiffs instance a file handle 245 | // belongs. 246 | // NB: This adds config field fh_ix_offset in the configuration struct when 247 | // mounting, which must be defined. 248 | #ifndef SPIFFS_FILEHDL_OFFSET 249 | #define SPIFFS_FILEHDL_OFFSET 0 250 | #endif 251 | 252 | // Enable this to compile a read only version of spiffs. 253 | // This will reduce binary size of spiffs. All code comprising modification 254 | // of the file system will not be compiled. Some config will be ignored. 255 | // HAL functions for erasing and writing to spi-flash may be null. Cache 256 | // can be disabled for even further binary size reduction (and ram savings). 257 | // Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL. 258 | // If the file system cannot be mounted due to aborted erase operation and 259 | // SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be 260 | // returned. 261 | // Might be useful for e.g. bootloaders and such. 262 | #ifndef SPIFFS_READ_ONLY 263 | #define SPIFFS_READ_ONLY 0 264 | #endif 265 | 266 | // Enable this to add a temporal file cache using the fd buffer. 267 | // The effects of the cache is that SPIFFS_open will find the file faster in 268 | // certain cases. It will make it a lot easier for spiffs to find files 269 | // opened frequently, reducing number of readings from the spi flash for 270 | // finding those files. 271 | // This will grow each fd by 6 bytes. If your files are opened in patterns 272 | // with a degree of temporal locality, the system is optimized. 273 | // Examples can be letting spiffs serve web content, where one file is the css. 274 | // The css is accessed for each html file that is opened, meaning it is 275 | // accessed almost every second time a file is opened. Another example could be 276 | // a log file that is often opened, written, and closed. 277 | // The size of the cache is number of given file descriptors, as it piggybacks 278 | // on the fd update mechanism. The cache lives in the closed file descriptors. 279 | // When closed, the fd know the whereabouts of the file. Instead of forgetting 280 | // this, the temporal cache will keep handling updates to that file even if the 281 | // fd is closed. If the file is opened again, the location of the file is found 282 | // directly. If all available descriptors become opened, all cache memory is 283 | // lost. 284 | #ifndef SPIFFS_TEMPORAL_FD_CACHE 285 | #define SPIFFS_TEMPORAL_FD_CACHE 1 286 | #endif 287 | 288 | // Temporal file cache hit score. Each time a file is opened, all cached files 289 | // will lose one point. If the opened file is found in cache, that entry will 290 | // gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this 291 | // value for the specific access patterns of the application. However, it must 292 | // be between 1 (no gain for hitting a cached entry often) and 255. 293 | #ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE 294 | #define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4 295 | #endif 296 | 297 | // Enable to be able to map object indices to memory. 298 | // This allows for faster and more deterministic reading if cases of reading 299 | // large files and when changing file offset by seeking around a lot. 300 | // When mapping a file's index, the file system will be scanned for index pages 301 | // and the info will be put in memory provided by user. When reading, the 302 | // memory map can be looked up instead of searching for index pages on the 303 | // medium. This way, user can trade memory against performance. 304 | // Whole, parts of, or future parts not being written yet can be mapped. The 305 | // memory array will be owned by spiffs and updated accordingly during garbage 306 | // collecting or when modifying the indices. The latter is invoked by when the 307 | // file is modified in some way. The index buffer is tied to the file 308 | // descriptor. 309 | #ifndef SPIFFS_IX_MAP 310 | #define SPIFFS_IX_MAP 1 311 | #endif 312 | 313 | // By default SPIFFS in some cases relies on the property of NOR flash that bits 314 | // cannot be set from 0 to 1 by writing and that controllers will ignore such 315 | // bit changes. This results in fewer reads as SPIFFS can in some cases perform 316 | // blind writes, with all bits set to 1 and only those it needs reset set to 0. 317 | // Most of the chips and controllers allow this behavior, so the default is to 318 | // use this technique. If your controller is one of the rare ones that don't, 319 | // turn this option on and SPIFFS will perform a read-modify-write instead. 320 | #ifndef SPIFFS_NO_BLIND_WRITES 321 | #define SPIFFS_NO_BLIND_WRITES 0 322 | #endif 323 | 324 | // Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function 325 | // in the api. This function will visualize all filesystem using given printf 326 | // function. 327 | #ifndef SPIFFS_TEST_VISUALISATION 328 | #define SPIFFS_TEST_VISUALISATION 1 329 | #endif 330 | #if SPIFFS_TEST_VISUALISATION 331 | #ifndef spiffs_printf 332 | #define spiffs_printf(...) printf(__VA_ARGS__) 333 | #endif 334 | // spiffs_printf argument for a free page 335 | #ifndef SPIFFS_TEST_VIS_FREE_STR 336 | #define SPIFFS_TEST_VIS_FREE_STR "_" 337 | #endif 338 | // spiffs_printf argument for a deleted page 339 | #ifndef SPIFFS_TEST_VIS_DELE_STR 340 | #define SPIFFS_TEST_VIS_DELE_STR "/" 341 | #endif 342 | // spiffs_printf argument for an index page for given object id 343 | #ifndef SPIFFS_TEST_VIS_INDX_STR 344 | #define SPIFFS_TEST_VIS_INDX_STR(id) "i" 345 | #endif 346 | // spiffs_printf argument for a data page for given object id 347 | #ifndef SPIFFS_TEST_VIS_DATA_STR 348 | #define SPIFFS_TEST_VIS_DATA_STR(id) "d" 349 | #endif 350 | #endif 351 | 352 | #ifndef SPIFFS_SECURE_ERASE 353 | #define SPIFFS_SECURE_ERASE 0 354 | #endif 355 | 356 | // Types depending on configuration such as the amount of flash bytes 357 | // given to spiffs file system in total (spiffs_file_system_size), 358 | // the logical block size (log_block_size), and the logical page size 359 | // (log_page_size) 360 | 361 | // Block index type. Make sure the size of this type can hold 362 | // the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size 363 | typedef u16_t spiffs_block_ix; 364 | // Page index type. Make sure the size of this type can hold 365 | // the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size 366 | typedef u16_t spiffs_page_ix; 367 | // Object id type - most significant bit is reserved for index flag. Make sure the 368 | // size of this type can hold the highest object id on a full system, 369 | // i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2 370 | typedef u16_t spiffs_obj_id; 371 | // Object span index type. Make sure the size of this type can 372 | // hold the largest possible span index on the system - 373 | // i.e. (spiffs_file_system_size / log_page_size) - 1 374 | typedef u16_t spiffs_span_ix; 375 | 376 | #endif /* SPIFFS_CONFIG_H_ */ 377 | -------------------------------------------------------------------------------- /fw/include/spiffs_config_g2_revc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * spiffs_config.h 3 | * 4 | * Created on: Jul 3, 2013 5 | * Author: petera 6 | */ 7 | 8 | #ifndef SPIFFS_CONFIG_H_ 9 | #define SPIFFS_CONFIG_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef int32_t s32_t; 18 | typedef uint32_t u32_t; 19 | typedef int16_t s16_t; 20 | typedef uint16_t u16_t; 21 | typedef int8_t s8_t; 22 | typedef uint8_t u8_t; 23 | 24 | // compile time switches 25 | 26 | // Set generic spiffs debug output call. 27 | #ifndef SPIFFS_DBG 28 | #define SPIFFS_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 29 | #endif 30 | // Set spiffs debug output call for garbage collecting. 31 | #ifndef SPIFFS_GC_DBG 32 | #define SPIFFS_GC_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 33 | #endif 34 | // Set spiffs debug output call for caching. 35 | #ifndef SPIFFS_CACHE_DBG 36 | #define SPIFFS_CACHE_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 37 | #endif 38 | // Set spiffs debug output call for system consistency checks. 39 | #ifndef SPIFFS_CHECK_DBG 40 | #define SPIFFS_CHECK_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 41 | #endif 42 | // Set spiffs debug output call for all api invocations. 43 | #ifndef SPIFFS_API_DBG 44 | #define SPIFFS_API_DBG(_f, ...) //printf(_f, ## __VA_ARGS__) 45 | #endif 46 | 47 | 48 | 49 | // Defines spiffs debug print formatters 50 | // some general signed number 51 | #ifndef _SPIPRIi 52 | #define _SPIPRIi "%d" 53 | #endif 54 | // address 55 | #ifndef _SPIPRIad 56 | #define _SPIPRIad "%08x" 57 | #endif 58 | // block 59 | #ifndef _SPIPRIbl 60 | #define _SPIPRIbl "%04x" 61 | #endif 62 | // page 63 | #ifndef _SPIPRIpg 64 | #define _SPIPRIpg "%04x" 65 | #endif 66 | // span index 67 | #ifndef _SPIPRIsp 68 | #define _SPIPRIsp "%04x" 69 | #endif 70 | // file descriptor 71 | #ifndef _SPIPRIfd 72 | #define _SPIPRIfd "%d" 73 | #endif 74 | // file object id 75 | #ifndef _SPIPRIid 76 | #define _SPIPRIid "%04x" 77 | #endif 78 | // file flags 79 | #ifndef _SPIPRIfl 80 | #define _SPIPRIfl "%02x" 81 | #endif 82 | 83 | 84 | // Enable/disable API functions to determine exact number of bytes 85 | // for filedescriptor and cache buffers. Once decided for a configuration, 86 | // this can be disabled to reduce flash. 87 | #ifndef SPIFFS_BUFFER_HELP 88 | #define SPIFFS_BUFFER_HELP 0 89 | #endif 90 | 91 | // Enables/disable memory read caching of nucleus file system operations. 92 | // If enabled, memory area must be provided for cache in SPIFFS_mount. 93 | #ifndef SPIFFS_CACHE 94 | #define SPIFFS_CACHE 0 95 | #endif 96 | #if SPIFFS_CACHE 97 | // Enables memory write caching for file descriptors in hydrogen 98 | #ifndef SPIFFS_CACHE_WR 99 | #define SPIFFS_CACHE_WR 1 100 | #endif 101 | 102 | // Enable/disable statistics on caching. Debug/test purpose only. 103 | #ifndef SPIFFS_CACHE_STATS 104 | #define SPIFFS_CACHE_STATS 1 105 | #endif 106 | #endif 107 | 108 | // Always check header of each accessed page to ensure consistent state. 109 | // If enabled it will increase number of reads, will increase flash. 110 | #ifndef SPIFFS_PAGE_CHECK 111 | #define SPIFFS_PAGE_CHECK 1 112 | #endif 113 | 114 | // Define maximum number of gc runs to perform to reach desired free pages. 115 | #ifndef SPIFFS_GC_MAX_RUNS 116 | #define SPIFFS_GC_MAX_RUNS 5 117 | #endif 118 | 119 | // Enable/disable statistics on gc. Debug/test purpose only. 120 | #ifndef SPIFFS_GC_STATS 121 | #define SPIFFS_GC_STATS 1 122 | #endif 123 | 124 | // Garbage collecting examines all pages in a block which and sums up 125 | // to a block score. Deleted pages normally gives positive score and 126 | // used pages normally gives a negative score (as these must be moved). 127 | // To have a fair wear-leveling, the erase age is also included in score, 128 | // whose factor normally is the most positive. 129 | // The larger the score, the more likely it is that the block will 130 | // picked for garbage collection. 131 | 132 | // Garbage collecting heuristics - weight used for deleted pages. 133 | #ifndef SPIFFS_GC_HEUR_W_DELET 134 | #define SPIFFS_GC_HEUR_W_DELET (5) 135 | #endif 136 | // Garbage collecting heuristics - weight used for used pages. 137 | #ifndef SPIFFS_GC_HEUR_W_USED 138 | #define SPIFFS_GC_HEUR_W_USED (-1) 139 | #endif 140 | // Garbage collecting heuristics - weight used for time between 141 | // last erased and erase of this block. 142 | #ifndef SPIFFS_GC_HEUR_W_ERASE_AGE 143 | #define SPIFFS_GC_HEUR_W_ERASE_AGE (50) 144 | #endif 145 | 146 | // Object name maximum length. Note that this length include the 147 | // zero-termination character, meaning maximum string of characters 148 | // can at most be SPIFFS_OBJ_NAME_LEN - 1. 149 | #ifndef SPIFFS_OBJ_NAME_LEN 150 | #define SPIFFS_OBJ_NAME_LEN (32) 151 | #endif 152 | 153 | // Maximum length of the metadata associated with an object. 154 | // Setting to non-zero value enables metadata-related API but also 155 | // changes the on-disk format, so the change is not backward-compatible. 156 | // 157 | // Do note: the meta length must never exceed 158 | // logical_page_size - (SPIFFS_OBJ_NAME_LEN + 64) 159 | // 160 | // This is derived from following: 161 | // logical_page_size - (SPIFFS_OBJ_NAME_LEN + sizeof(spiffs_page_header) + 162 | // spiffs_object_ix_header fields + at least some LUT entries) 163 | #ifndef SPIFFS_OBJ_META_LEN 164 | #define SPIFFS_OBJ_META_LEN (0) 165 | #endif 166 | 167 | // Size of buffer allocated on stack used when copying data. 168 | // Lower value generates more read/writes. No meaning having it bigger 169 | // than logical page size. 170 | #ifndef SPIFFS_COPY_BUFFER_STACK 171 | #define SPIFFS_COPY_BUFFER_STACK (64) 172 | #endif 173 | 174 | // Enable this to have an identifiable spiffs filesystem. This will look for 175 | // a magic in all sectors to determine if this is a valid spiffs system or 176 | // not on mount point. If not, SPIFFS_format must be called prior to mounting 177 | // again. 178 | #ifndef SPIFFS_USE_MAGIC 179 | #define SPIFFS_USE_MAGIC (0) 180 | #endif 181 | 182 | #if SPIFFS_USE_MAGIC 183 | // Only valid when SPIFFS_USE_MAGIC is enabled. If SPIFFS_USE_MAGIC_LENGTH is 184 | // enabled, the magic will also be dependent on the length of the filesystem. 185 | // For example, a filesystem configured and formatted for 4 megabytes will not 186 | // be accepted for mounting with a configuration defining the filesystem as 2 187 | // megabytes. 188 | #ifndef SPIFFS_USE_MAGIC_LENGTH 189 | #define SPIFFS_USE_MAGIC_LENGTH (1) 190 | #endif 191 | #endif 192 | 193 | // SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level 194 | // These should be defined on a multithreaded system 195 | 196 | // define this to enter a mutex if you're running on a multithreaded system 197 | #ifndef SPIFFS_LOCK 198 | #define SPIFFS_LOCK(fs) 199 | #endif 200 | // define this to exit a mutex if you're running on a multithreaded system 201 | #ifndef SPIFFS_UNLOCK 202 | #define SPIFFS_UNLOCK(fs) 203 | #endif 204 | 205 | // Enable if only one spiffs instance with constant configuration will exist 206 | // on the target. This will reduce calculations, flash and memory accesses. 207 | // Parts of configuration must be defined below instead of at time of mount. 208 | #ifndef SPIFFS_SINGLETON 209 | #define SPIFFS_SINGLETON 1 210 | #endif 211 | 212 | #if SPIFFS_SINGLETON 213 | // Instead of giving parameters in config struct, singleton build must 214 | // give parameters in defines below. 215 | #ifndef SPIFFS_CFG_PHYS_SZ 216 | #define SPIFFS_CFG_PHYS_SZ(ignore) (0x320000) 217 | #endif 218 | #ifndef SPIFFS_CFG_PHYS_ERASE_SZ 219 | #define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) 220 | #endif 221 | #ifndef SPIFFS_CFG_PHYS_ADDR 222 | #define SPIFFS_CFG_PHYS_ADDR(ignore) (0x4e0000) 223 | #endif 224 | #ifndef SPIFFS_CFG_LOG_PAGE_SZ 225 | #define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) 226 | #endif 227 | #ifndef SPIFFS_CFG_LOG_BLOCK_SZ 228 | #define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536) 229 | #endif 230 | #endif 231 | 232 | // Enable this if your target needs aligned data for index tables 233 | #ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 234 | #define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 235 | #endif 236 | 237 | // Enable this if you want the HAL callbacks to be called with the spiffs struct 238 | #ifndef SPIFFS_HAL_CALLBACK_EXTRA 239 | #define SPIFFS_HAL_CALLBACK_EXTRA 0 240 | #endif 241 | 242 | // Enable this if you want to add an integer offset to all file handles 243 | // (spiffs_file). This is useful if running multiple instances of spiffs on 244 | // same target, in order to recognise to what spiffs instance a file handle 245 | // belongs. 246 | // NB: This adds config field fh_ix_offset in the configuration struct when 247 | // mounting, which must be defined. 248 | #ifndef SPIFFS_FILEHDL_OFFSET 249 | #define SPIFFS_FILEHDL_OFFSET 0 250 | #endif 251 | 252 | // Enable this to compile a read only version of spiffs. 253 | // This will reduce binary size of spiffs. All code comprising modification 254 | // of the file system will not be compiled. Some config will be ignored. 255 | // HAL functions for erasing and writing to spi-flash may be null. Cache 256 | // can be disabled for even further binary size reduction (and ram savings). 257 | // Functions modifying the fs will return SPIFFS_ERR_RO_NOT_IMPL. 258 | // If the file system cannot be mounted due to aborted erase operation and 259 | // SPIFFS_USE_MAGIC is enabled, SPIFFS_ERR_RO_ABORTED_OPERATION will be 260 | // returned. 261 | // Might be useful for e.g. bootloaders and such. 262 | #ifndef SPIFFS_READ_ONLY 263 | #define SPIFFS_READ_ONLY 0 264 | #endif 265 | 266 | // Enable this to add a temporal file cache using the fd buffer. 267 | // The effects of the cache is that SPIFFS_open will find the file faster in 268 | // certain cases. It will make it a lot easier for spiffs to find files 269 | // opened frequently, reducing number of readings from the spi flash for 270 | // finding those files. 271 | // This will grow each fd by 6 bytes. If your files are opened in patterns 272 | // with a degree of temporal locality, the system is optimized. 273 | // Examples can be letting spiffs serve web content, where one file is the css. 274 | // The css is accessed for each html file that is opened, meaning it is 275 | // accessed almost every second time a file is opened. Another example could be 276 | // a log file that is often opened, written, and closed. 277 | // The size of the cache is number of given file descriptors, as it piggybacks 278 | // on the fd update mechanism. The cache lives in the closed file descriptors. 279 | // When closed, the fd know the whereabouts of the file. Instead of forgetting 280 | // this, the temporal cache will keep handling updates to that file even if the 281 | // fd is closed. If the file is opened again, the location of the file is found 282 | // directly. If all available descriptors become opened, all cache memory is 283 | // lost. 284 | #ifndef SPIFFS_TEMPORAL_FD_CACHE 285 | #define SPIFFS_TEMPORAL_FD_CACHE 1 286 | #endif 287 | 288 | // Temporal file cache hit score. Each time a file is opened, all cached files 289 | // will lose one point. If the opened file is found in cache, that entry will 290 | // gain SPIFFS_TEMPORAL_CACHE_HIT_SCORE points. One can experiment with this 291 | // value for the specific access patterns of the application. However, it must 292 | // be between 1 (no gain for hitting a cached entry often) and 255. 293 | #ifndef SPIFFS_TEMPORAL_CACHE_HIT_SCORE 294 | #define SPIFFS_TEMPORAL_CACHE_HIT_SCORE 4 295 | #endif 296 | 297 | // Enable to be able to map object indices to memory. 298 | // This allows for faster and more deterministic reading if cases of reading 299 | // large files and when changing file offset by seeking around a lot. 300 | // When mapping a file's index, the file system will be scanned for index pages 301 | // and the info will be put in memory provided by user. When reading, the 302 | // memory map can be looked up instead of searching for index pages on the 303 | // medium. This way, user can trade memory against performance. 304 | // Whole, parts of, or future parts not being written yet can be mapped. The 305 | // memory array will be owned by spiffs and updated accordingly during garbage 306 | // collecting or when modifying the indices. The latter is invoked by when the 307 | // file is modified in some way. The index buffer is tied to the file 308 | // descriptor. 309 | #ifndef SPIFFS_IX_MAP 310 | #define SPIFFS_IX_MAP 1 311 | #endif 312 | 313 | // By default SPIFFS in some cases relies on the property of NOR flash that bits 314 | // cannot be set from 0 to 1 by writing and that controllers will ignore such 315 | // bit changes. This results in fewer reads as SPIFFS can in some cases perform 316 | // blind writes, with all bits set to 1 and only those it needs reset set to 0. 317 | // Most of the chips and controllers allow this behavior, so the default is to 318 | // use this technique. If your controller is one of the rare ones that don't, 319 | // turn this option on and SPIFFS will perform a read-modify-write instead. 320 | #ifndef SPIFFS_NO_BLIND_WRITES 321 | #define SPIFFS_NO_BLIND_WRITES 0 322 | #endif 323 | 324 | // Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function 325 | // in the api. This function will visualize all filesystem using given printf 326 | // function. 327 | #ifndef SPIFFS_TEST_VISUALISATION 328 | #define SPIFFS_TEST_VISUALISATION 1 329 | #endif 330 | #if SPIFFS_TEST_VISUALISATION 331 | #ifndef spiffs_printf 332 | #define spiffs_printf(...) printf(__VA_ARGS__) 333 | #endif 334 | // spiffs_printf argument for a free page 335 | #ifndef SPIFFS_TEST_VIS_FREE_STR 336 | #define SPIFFS_TEST_VIS_FREE_STR "_" 337 | #endif 338 | // spiffs_printf argument for a deleted page 339 | #ifndef SPIFFS_TEST_VIS_DELE_STR 340 | #define SPIFFS_TEST_VIS_DELE_STR "/" 341 | #endif 342 | // spiffs_printf argument for an index page for given object id 343 | #ifndef SPIFFS_TEST_VIS_INDX_STR 344 | #define SPIFFS_TEST_VIS_INDX_STR(id) "i" 345 | #endif 346 | // spiffs_printf argument for a data page for given object id 347 | #ifndef SPIFFS_TEST_VIS_DATA_STR 348 | #define SPIFFS_TEST_VIS_DATA_STR(id) "d" 349 | #endif 350 | #endif 351 | 352 | #ifndef SPIFFS_SECURE_ERASE 353 | #define SPIFFS_SECURE_ERASE 0 354 | #endif 355 | 356 | // Types depending on configuration such as the amount of flash bytes 357 | // given to spiffs file system in total (spiffs_file_system_size), 358 | // the logical block size (log_block_size), and the logical page size 359 | // (log_page_size) 360 | 361 | // Block index type. Make sure the size of this type can hold 362 | // the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size 363 | typedef u16_t spiffs_block_ix; 364 | // Page index type. Make sure the size of this type can hold 365 | // the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size 366 | typedef u16_t spiffs_page_ix; 367 | // Object id type - most significant bit is reserved for index flag. Make sure the 368 | // size of this type can hold the highest object id on a full system, 369 | // i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2 370 | typedef u16_t spiffs_obj_id; 371 | // Object span index type. Make sure the size of this type can 372 | // hold the largest possible span index on the system - 373 | // i.e. (spiffs_file_system_size / log_page_size) - 1 374 | typedef u16_t spiffs_span_ix; 375 | 376 | #endif /* SPIFFS_CONFIG_H_ */ 377 | -------------------------------------------------------------------------------- /fw/pano_ldr/Makefile: -------------------------------------------------------------------------------- 1 | include ../../project.mk 2 | 3 | TARGET = pano_ldr 4 | 5 | # source to include 6 | SRC_DIR = . 7 | SRC_DIR += $(CORES_DIR)/core_soc/src_c 8 | SRC_DIR += $(PANO_FW_DIR)/lib/libstd 9 | EXTRA_SRC += $(PANO_FW_DIR)/common/log.c 10 | EXTRA_SRC += $(PANO_FW_DIR)/common/spi_drv.c 11 | EXTRA_SRC += $(PANO_FW_DIR)/common/cmd_parser.c 12 | # tftp 13 | TFTP_DIR = $(abspath $(LWIP_SRC_DIR)/src/apps/tftp) 14 | EXTRA_SRC += $(TFTP_DIR)/tftp.c 15 | INCLUDE_PATH += $(TFTP_DIR) 16 | 17 | PROJECT_DIR := $(abspath .) 18 | INCLUDE_PATH += ../include 19 | INCLUDE_PATH += $(PROJECT_INC) 20 | INCLUDE_PATH += $(PANO_FW_DIR)/common 21 | 22 | 23 | # build optons 24 | OPT = 2 25 | ENABLE_LST = yes 26 | 27 | BUILD_TARGETS += $(LWIP_LIB) 28 | 29 | include $(PANO_FW_DIR)/lwip/include.mk 30 | include $(MAKE_DIR)/c_prog.mk 31 | 32 | .PHONY: distclean 33 | 34 | distclean: clean 35 | make -C $(LWIP_LIB_DIR) distclean 36 | 37 | debug: 38 | @echo "SRC_DIR: $(SRC_DIR)" 39 | @echo "SRC: $(SRC)" 40 | @echo "OBJ: $(OBJ)" 41 | @echo "EXTRA_LIBS: $(EXTRA_LIBS)" 42 | @echo "CFLAGS: $(CFLAGS)" 43 | @echo "INCLUDE_PATH: $(INCLUDE_PATH)" 44 | -------------------------------------------------------------------------------- /fw/pano_ldr/arch/cc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2001-2003 Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 21 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 25 | * OF SUCH DAMAGE. 26 | * 27 | * This file is part of the lwIP TCP/IP stack. 28 | * 29 | * Author: Adam Dunkels 30 | * 31 | */ 32 | #ifndef LWIP_ARCH_CC_H 33 | #define LWIP_ARCH_CC_H 34 | 35 | /* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */ 36 | #if defined __ANDROID__ 37 | #define LWIP_UNIX_ANDROID 38 | #elif defined __linux__ 39 | #define LWIP_UNIX_LINUX 40 | #elif defined __APPLE__ 41 | #define LWIP_UNIX_MACH 42 | #elif defined __OpenBSD__ 43 | #define LWIP_UNIX_OPENBSD 44 | #elif defined __FreeBSD_kernel__ && __GLIBC__ 45 | #define LWIP_UNIX_KFREEBSD 46 | #elif defined __CYGWIN__ 47 | #define LWIP_UNIX_CYGWIN 48 | #elif defined __GNU__ 49 | #define LWIP_UNIX_HURD 50 | #endif 51 | 52 | #define LWIP_TIMEVAL_PRIVATE 0 53 | #include 54 | 55 | #define LWIP_ERRNO_INCLUDE 56 | 57 | #if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) || defined(LWIP_UNIX_KFREEBSD) 58 | #define LWIP_ERRNO_STDINCLUDE 1 59 | #endif 60 | 61 | extern unsigned int lwip_port_rand(void); 62 | #define LWIP_RAND() (lwip_port_rand()) 63 | 64 | /* different handling for unit test, normally not needed */ 65 | #ifdef LWIP_NOASSERT_ON_ERROR 66 | #define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ 67 | handler;}} while(0) 68 | #endif 69 | 70 | #if defined(LWIP_UNIX_ANDROID) && defined(FD_SET) 71 | typedef __kernel_fd_set fd_set; 72 | #endif 73 | 74 | #if defined(LWIP_UNIX_MACH) 75 | /* sys/types.h and signal.h bring in Darwin byte order macros. pull the 76 | header here and disable LwIP's version so that apps still can get 77 | the macros via LwIP headers and use system headers */ 78 | #include 79 | #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 80 | #endif 81 | 82 | struct sio_status_s; 83 | typedef struct sio_status_s sio_status_t; 84 | #define sio_fd_t sio_status_t* 85 | #define __sio_fd_t_defined 86 | 87 | /** Define this to 1 in arch/cc.h of your port if your compiler does not provide 88 | * the inttypes.h header. You need to define the format strings listed in 89 | * lwip/arch.h yourself in this case (X8_F, U16_F...). 90 | */ 91 | #define LWIP_NO_INTTYPES_H 1 92 | 93 | /* The following are needed beause we're using a simplified (small) printf */ 94 | #define X8_F "x" 95 | #define U16_F "d" 96 | #define S16_F "d" 97 | #define X16_F "x" 98 | #define U32_F "d" 99 | #define S32_F "d" 100 | #define X32_F "x" 101 | #define SZT_F "p" 102 | 103 | 104 | #endif /* LWIP_ARCH_CC_H */ 105 | -------------------------------------------------------------------------------- /fw/pano_ldr/lwipopts.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2001-2003 Swedish Institute of Computer Science. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * 1. Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, 11 | * this list of conditions and the following disclaimer in the documentation 12 | * and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 21 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 25 | * OF SUCH DAMAGE. 26 | * 27 | * This file is part of the lwIP TCP/IP stack. 28 | * 29 | * Author: Adam Dunkels 30 | * 31 | */ 32 | #ifndef LWIP_LWIPOPTS_H 33 | #define LWIP_LWIPOPTS_H 34 | 35 | #define LWIP_DEBUG 1 36 | 37 | #define NO_SYS 1 38 | #define NO_SYS_NO_TIMERS 0 39 | #define LWIP_TIMERS 1 40 | #define LWIP_TIMERS_CUSTOM 0 41 | #define LWIP_MPU_COMPATIBLE 0 42 | #define LWIP_TCPIP_CORE_LOCKING 0 43 | #define LWIP_TCPIP_CORE_LOCKING_INPUT 0 44 | #define SYS_LIGHTWEIGHT_PROT 0 45 | #define MEM_LIBC_MALLOC 0 46 | #define MEMP_MEM_MALLOC 0 47 | #define MEMP_MEM_INIT 0 48 | #define MEM_ALIGNMENT 4 49 | #define MEM_SIZE 1600 50 | #define MEMP_OVERFLOW_CHECK 0 51 | #define MEMP_SANITY_CHECK 0 52 | #define MEM_OVERFLOW_CHECK 0 53 | #define MEM_SANITY_CHECK 0 54 | #define MEM_USE_POOLS 0 55 | #define MEM_USE_POOLS_TRY_BIGGER_POOL 0 56 | #define MEMP_USE_CUSTOM_POOLS 0 57 | #define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 58 | #define MEMP_NUM_PBUF 16 59 | #define MEMP_NUM_RAW_PCB 4 60 | #define MEMP_NUM_UDP_PCB 4 61 | #define MEMP_NUM_TCP_PCB 5 62 | #define MEMP_NUM_TCP_PCB_LISTEN 8 63 | #define MEMP_NUM_TCP_SEG 16 64 | #define MEMP_NUM_ALTCP_PCB MEMP_NUM_TCP_PCB 65 | #define MEMP_NUM_REASSDATA 5 66 | #define MEMP_NUM_FRAG_PBUF 15 67 | #define MEMP_NUM_ARP_QUEUE 30 68 | #define MEMP_NUM_IGMP_GROUP 8 69 | #define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 2) 70 | #define MEMP_NUM_NETBUF 2 71 | #define MEMP_NUM_NETCONN 4 72 | #define MEMP_NUM_SELECT_CB 4 73 | #define MEMP_NUM_TCPIP_MSG_API 8 74 | #define MEMP_NUM_TCPIP_MSG_INPKT 8 75 | #define MEMP_NUM_NETDB 1 76 | #define MEMP_NUM_LOCALHOSTLIST 1 77 | #define PBUF_POOL_SIZE 16 78 | #define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API 79 | #define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API 80 | #define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API 81 | #define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API 82 | #define LWIP_ARP 1 83 | #define ARP_TABLE_SIZE 10 84 | #define ARP_MAXAGE 300 85 | #define ARP_QUEUEING 0 86 | #define ARP_QUEUE_LEN 3 87 | #define ETHARP_SUPPORT_VLAN 0 88 | #define LWIP_ETHERNET LWIP_ARP 89 | #define ETH_PAD_SIZE 0 90 | #define ETHARP_SUPPORT_STATIC_ENTRIES 0 91 | #define ETHARP_TABLE_MATCH_NETIF !LWIP_SINGLE_NETIF 92 | #define LWIP_IPV4 1 93 | #define IP_FORWARD 0 94 | #define IP_REASSEMBLY 1 95 | #define IP_FRAG 1 96 | #define IP_OPTIONS_ALLOWED 1 97 | #define IP_REASS_MAXAGE 15 98 | #define IP_REASS_MAX_PBUFS 10 99 | #define IP_DEFAULT_TTL 255 100 | #define IP_SOF_BROADCAST 0 101 | #define IP_SOF_BROADCAST_RECV 0 102 | #define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 103 | #define LWIP_ICMP 1 104 | #define ICMP_TTL (IP_DEFAULT_TTL) 105 | #define LWIP_BROADCAST_PING 0 106 | #define LWIP_MULTICAST_PING 0 107 | #define LWIP_RAW 0 108 | #define RAW_TTL (IP_DEFAULT_TTL) 109 | #define LWIP_DHCP LWIP_UDP 110 | #define LWIP_DHCP_CHECK_LINK_UP 0 111 | #define LWIP_DHCP_BOOTP_FILE 0 112 | #define LWIP_DHCP_GET_NTP_SRV 0 113 | #define LWIP_DHCP_MAX_NTP_SERVERS 1 114 | #define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS 115 | #define LWIP_AUTOIP 0 116 | #define LWIP_DHCP_AUTOIP_COOP 0 117 | #define LWIP_DHCP_AUTOIP_COOP_TRIES 9 118 | #define LWIP_MIB2_CALLBACKS 0 119 | #define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW)) 120 | #define LWIP_IGMP 0 121 | #define LWIP_DNS 0 122 | #define DNS_TABLE_SIZE 4 123 | #define DNS_MAX_NAME_LENGTH 256 124 | #define DNS_MAX_SERVERS 2 125 | #define DNS_MAX_RETRIES 4 126 | #define DNS_DOES_NAME_CHECK 1 127 | #define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) 128 | #define DNS_LOCAL_HOSTLIST 0 129 | #define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 130 | #define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 131 | #define LWIP_UDP 1 132 | #define LWIP_UDPLITE 0 133 | #define UDP_TTL (IP_DEFAULT_TTL) 134 | #define LWIP_NETBUF_RECVINFO 0 135 | #define LWIP_TCP 1 136 | #define TCP_TTL (IP_DEFAULT_TTL) 137 | #define TCP_WND (4 * TCP_MSS) 138 | #define TCP_MAXRTX 12 139 | #define TCP_SYNMAXRTX 6 140 | #define TCP_QUEUE_OOSEQ (LWIP_TCP) 141 | #define LWIP_TCP_SACK_OUT 0 142 | #define LWIP_TCP_MAX_SACK_NUM 4 143 | #define TCP_MSS 536 144 | #define TCP_CALCULATE_EFF_SEND_MSS 1 145 | #define TCP_SND_BUF (2 * TCP_MSS) 146 | #define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) 147 | #define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) 148 | #define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) 149 | #define TCP_OOSEQ_MAX_BYTES 0 150 | #define TCP_OOSEQ_BYTES_LIMIT(pcb) TCP_OOSEQ_MAX_BYTES 151 | #define TCP_OOSEQ_MAX_PBUFS 0 152 | #define TCP_OOSEQ_PBUFS_LIMIT(pcb) TCP_OOSEQ_MAX_PBUFS 153 | #define TCP_LISTEN_BACKLOG 0 154 | #define TCP_DEFAULT_LISTEN_BACKLOG 0xff 155 | #define TCP_OVERSIZE TCP_MSS 156 | #define LWIP_TCP_TIMESTAMPS 0 157 | #define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) 158 | #define LWIP_EVENT_API 0 159 | #define LWIP_CALLBACK_API 1 160 | #define LWIP_WND_SCALE 0 161 | #define TCP_RCV_SCALE 0 162 | #define LWIP_TCP_PCB_NUM_EXT_ARGS 0 163 | #define LWIP_ALTCP 0 164 | #define LWIP_ALTCP_TLS 0 165 | #define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) 166 | #define PBUF_LINK_ENCAPSULATION_HLEN 0 167 | #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) 168 | #define LWIP_PBUF_REF_T u8_t 169 | #define LWIP_SINGLE_NETIF 0 170 | #define LWIP_NETIF_HOSTNAME 1 171 | #define LWIP_NETIF_API 0 172 | #define LWIP_NETIF_STATUS_CALLBACK 0 173 | #define LWIP_NETIF_EXT_STATUS_CALLBACK 0 174 | #define LWIP_NETIF_LINK_CALLBACK 0 175 | #define LWIP_NETIF_REMOVE_CALLBACK 0 176 | #define LWIP_NETIF_HWADDRHINT 0 177 | #define LWIP_NETIF_TX_SINGLE_PBUF 0 178 | #define LWIP_NUM_NETIF_CLIENT_DATA 0 179 | #define LWIP_HAVE_LOOPIF (LWIP_NETIF_LOOPBACK && !LWIP_SINGLE_NETIF) 180 | #define LWIP_LOOPIF_MULTICAST 0 181 | #define LWIP_NETIF_LOOPBACK 0 182 | #define LWIP_LOOPBACK_MAX_PBUFS 0 183 | #define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) 184 | /*#define TCPIP_THREAD_NAME "tcpip_thread" 185 | #define TCPIP_THREAD_STACKSIZE 0 186 | #define TCPIP_THREAD_PRIO 1 187 | #define TCPIP_MBOX_SIZE 0 188 | #define LWIP_TCPIP_THREAD_ALIVE() 189 | #define SLIPIF_THREAD_NAME "slipif_loop" 190 | #define SLIPIF_THREAD_STACKSIZE 0 191 | #define SLIPIF_THREAD_PRIO 1 192 | #define DEFAULT_THREAD_NAME "lwIP" 193 | #define DEFAULT_THREAD_STACKSIZE 0 194 | #define DEFAULT_THREAD_PRIO 1 195 | #define DEFAULT_RAW_RECVMBOX_SIZE 0 196 | #define DEFAULT_UDP_RECVMBOX_SIZE 0 197 | #define DEFAULT_TCP_RECVMBOX_SIZE 0 198 | #define DEFAULT_ACCEPTMBOX_SIZE 0*/ 199 | #define LWIP_NETCONN 0 200 | #define LWIP_TCPIP_TIMEOUT 0 201 | #define LWIP_NETCONN_SEM_PER_THREAD 0 202 | #define LWIP_NETCONN_FULLDUPLEX 0 203 | #define LWIP_SOCKET 0 204 | #define LWIP_COMPAT_SOCKETS 1 /* 0..2 */ 205 | #define LWIP_POSIX_SOCKETS_IO_NAMES 1 206 | #define LWIP_SOCKET_OFFSET 0 207 | #define LWIP_TCP_KEEPALIVE 0 208 | #define LWIP_SO_SNDTIMEO 0 209 | #define LWIP_SO_RCVTIMEO 0 210 | #define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 211 | #define LWIP_SO_RCVBUF 0 212 | #define LWIP_SO_LINGER 0 213 | #define RECV_BUFSIZE_DEFAULT INT_MAX 214 | #define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 215 | #define SO_REUSE 0 216 | #define SO_REUSE_RXTOALL 0 217 | #define LWIP_FIONREAD_LINUXMODE 0 218 | #define LWIP_SOCKET_SELECT 1 219 | #define LWIP_SOCKET_POLL 1 220 | #define LWIP_STATS 1 221 | #define LWIP_STATS_DISPLAY 0 222 | #define LINK_STATS 1 223 | #define ETHARP_STATS (LWIP_ARP) 224 | #define IP_STATS 1 225 | #define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) 226 | #define ICMP_STATS 1 227 | #define IGMP_STATS (LWIP_IGMP) 228 | #define UDP_STATS (LWIP_UDP) 229 | #define TCP_STATS (LWIP_TCP) 230 | #define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) 231 | #define MEMP_STATS (MEMP_MEM_MALLOC == 0) 232 | #define SYS_STATS (NO_SYS == 0) 233 | #define IP6_STATS (LWIP_IPV6) 234 | #define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) 235 | #define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) 236 | #define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) 237 | #define ND6_STATS (LWIP_IPV6) 238 | #define MIB2_STATS 0 239 | #define LWIP_CHECKSUM_CTRL_PER_NETIF 0 240 | #define CHECKSUM_GEN_IP 1 241 | #define CHECKSUM_GEN_UDP 1 242 | #define CHECKSUM_GEN_TCP 1 243 | #define CHECKSUM_GEN_ICMP 1 244 | #define CHECKSUM_GEN_ICMP6 1 245 | #define CHECKSUM_CHECK_IP 1 246 | #define CHECKSUM_CHECK_UDP 1 247 | #define CHECKSUM_CHECK_TCP 1 248 | #define CHECKSUM_CHECK_ICMP 1 249 | #define CHECKSUM_CHECK_ICMP6 1 250 | #define LWIP_CHECKSUM_ON_COPY 0 251 | #define LWIP_IPV6 0 252 | #define IPV6_REASS_MAXAGE 60 253 | #define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF) 254 | #define LWIP_IPV6_SCOPES_DEBUG 0 255 | #define LWIP_IPV6_NUM_ADDRESSES 3 256 | #define LWIP_IPV6_FORWARD 0 257 | #define LWIP_IPV6_FRAG 1 258 | #define LWIP_IPV6_REASS (LWIP_IPV6) 259 | #define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 260 | #define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6) 261 | #define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG) 262 | #define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 263 | #define LWIP_ICMP6 (LWIP_IPV6) 264 | #define LWIP_ICMP6_DATASIZE 8 265 | #define LWIP_ICMP6_HL 255 266 | #define LWIP_IPV6_MLD (LWIP_IPV6) 267 | #define MEMP_NUM_MLD6_GROUP 4 268 | #define LWIP_ND6_QUEUEING (LWIP_IPV6) 269 | #define MEMP_NUM_ND6_QUEUE 20 270 | #define LWIP_ND6_NUM_NEIGHBORS 10 271 | #define LWIP_ND6_NUM_DESTINATIONS 10 272 | #define LWIP_ND6_NUM_PREFIXES 5 273 | #define LWIP_ND6_NUM_ROUTERS 3 274 | #define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 275 | #define LWIP_ND6_MAX_UNICAST_SOLICIT 3 276 | #define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 277 | #define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 278 | #define LWIP_ND6_REACHABLE_TIME 30000 279 | #define LWIP_ND6_RETRANS_TIMER 1000 280 | #define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 281 | #define LWIP_ND6_ALLOW_RA_UPDATES 1 282 | #define LWIP_ND6_TCP_REACHABILITY_HINTS 1 283 | #define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 284 | #define LWIP_IPV6_DHCP6 0 285 | #define LWIP_IPV6_DHCP6_STATEFUL 0 286 | #define LWIP_IPV6_DHCP6_STATELESS LWIP_IPV6_DHCP6 287 | #define LWIP_DHCP6_GET_NTP_SRV 0 288 | #define LWIP_DHCP6_MAX_NTP_SERVERS 1 289 | #define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS 290 | 291 | /* TODO: check hooks */ 292 | 293 | #define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL 294 | #define LWIP_DBG_TYPES_ON LWIP_DBG_ON 295 | #define ETHARP_DEBUG LWIP_DBG_OFF 296 | #define NETIF_DEBUG LWIP_DBG_OFF 297 | #define PBUF_DEBUG LWIP_DBG_OFF 298 | #define API_LIB_DEBUG LWIP_DBG_OFF 299 | #define API_MSG_DEBUG LWIP_DBG_OFF 300 | #define SOCKETS_DEBUG LWIP_DBG_OFF 301 | #define ICMP_DEBUG LWIP_DBG_OFF 302 | #define IGMP_DEBUG LWIP_DBG_OFF 303 | #define INET_DEBUG LWIP_DBG_OFF 304 | #define IP_DEBUG LWIP_DBG_OFF 305 | #define IP_REASS_DEBUG LWIP_DBG_OFF 306 | #define RAW_DEBUG LWIP_DBG_OFF 307 | #define MEM_DEBUG LWIP_DBG_OFF 308 | #define MEMP_DEBUG LWIP_DBG_OFF 309 | #define SYS_DEBUG LWIP_DBG_OFF 310 | #define TIMERS_DEBUG LWIP_DBG_OFF 311 | #define TCP_DEBUG LWIP_DBG_OFF 312 | #define TCP_INPUT_DEBUG LWIP_DBG_OFF 313 | #define TCP_FR_DEBUG LWIP_DBG_OFF 314 | #define TCP_RTO_DEBUG LWIP_DBG_OFF 315 | #define TCP_CWND_DEBUG LWIP_DBG_OFF 316 | #define TCP_WND_DEBUG LWIP_DBG_OFF 317 | #define TCP_OUTPUT_DEBUG LWIP_DBG_OFF 318 | #define TCP_RST_DEBUG LWIP_DBG_OFF 319 | #define TCP_QLEN_DEBUG LWIP_DBG_OFF 320 | #define UDP_DEBUG LWIP_DBG_OFF 321 | #define TCPIP_DEBUG LWIP_DBG_OFF 322 | #define SLIP_DEBUG LWIP_DBG_OFF 323 | #define DHCP_DEBUG LWIP_DBG_OFF 324 | #define AUTOIP_DEBUG LWIP_DBG_OFF 325 | #define DNS_DEBUG LWIP_DBG_OFF 326 | #define IP6_DEBUG LWIP_DBG_OFF 327 | #define DHCP6_DEBUG LWIP_DBG_OFF 328 | #define LWIP_TESTMODE 0 329 | #define LWIP_PERF 0 330 | 331 | #define LWIP_NO_CTYPE_H 1 332 | #define LWIP_DHCP_DOES_ACD_CHECK 0 333 | 334 | 335 | /* The following defines must be done even in OPTTEST mode: */ 336 | 337 | #if !defined(NO_SYS) || !NO_SYS /* default is 0 */ 338 | void sys_check_core_locking(void); 339 | #define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking() 340 | #endif 341 | 342 | void lwip_pano_assert(const char *msg, int line, const char *file); 343 | #define LWIP_PLATFORM_ASSERT(x) lwip_pano_assert(x, __LINE__, __FILE__) 344 | 345 | #endif /* LWIP_LWIPOPTS_H */ 346 | -------------------------------------------------------------------------------- /fw/pano_ldr/rand.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple xorshift PRNG 3 | * see http://www.jstatsoft.org/v08/i14/paper 4 | * 5 | * Copyright (c) 2012 Michael Walle 6 | * Michael Walle 7 | * 8 | * SPDX-License-Identifier: GPL-2.0+ 9 | */ 10 | 11 | // #include 12 | 13 | static unsigned int y = 1U; 14 | 15 | unsigned int rand_r(unsigned int *seedp) 16 | { 17 | *seedp ^= (*seedp << 13); 18 | *seedp ^= (*seedp >> 17); 19 | *seedp ^= (*seedp << 5); 20 | 21 | return *seedp; 22 | } 23 | 24 | unsigned int rand(void) 25 | { 26 | return rand_r(&y); 27 | } 28 | 29 | void srand(unsigned int seed) 30 | { 31 | y = seed; 32 | } 33 | -------------------------------------------------------------------------------- /fw/pano_ldr/tftp_ldr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Skip Hansen 3 | * 4 | * This program is free software; you can redistribute it and/or modify it 5 | * under the terms and conditions of the GNU General Public License, 6 | * version 2, as published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 | * more details. 12 | * 13 | * You should have received a copy of the GNU General Public License along 14 | * with this program; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 | * 17 | */ 18 | 19 | /* 20 | * Redistribution and use in source and binary forms, with or without modification, 21 | * are permitted provided that the following conditions are met: 22 | * 23 | * 1. Redistributions of source code must retain the above copyright notice, 24 | * this list of conditions and the following disclaimer. 25 | * 2. Redistributions in binary form must reproduce the above copyright notice, 26 | * this list of conditions and the following disclaimer in the documentation 27 | * and/or other materials provided with the distribution. 28 | * 3. The name of the author may not be used to endorse or promote products 29 | * derived from this software without specific prior written permission. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 32 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 33 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 34 | * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 35 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 36 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 37 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 38 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 39 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 40 | * OF SUCH DAMAGE. 41 | * 42 | * This file is part of the lwIP TCP/IP stack. 43 | * 44 | * Author: Dirk Ziegelmeier 45 | * 46 | */ 47 | 48 | #include 49 | #include 50 | #include 51 | 52 | #include "lwip/apps/tftp_client.h" 53 | // #include "lwip/apps/tftp_server.h" 54 | #include "tftp_ldr.h" 55 | #include "spi_drv.h" 56 | 57 | // #define DEBUG_LOGGING 1 58 | // #define VERBOSE_DEBUG_LOGGING 1 59 | #include "log.h" 60 | 61 | #define INVALID_FLASH_ADR 0xffffffff 62 | 63 | static void *tftp_open(const char *p,const char *Mode,u8_t bWrite) 64 | { 65 | LWIP_UNUSED_ARG(Mode); 66 | return NULL; 67 | } 68 | 69 | static void tftp_close(void* handle) 70 | { 71 | tftp_ldr_internal *p = (tftp_ldr_internal *) handle; 72 | LOG("%d bytes transfered\n",p->BytesTransfered); 73 | if(p->Error == TFTP_IN_PROGRESS) { 74 | p->Error = TFTP_OK; 75 | } 76 | } 77 | 78 | // tftp put 79 | static int tftp_read(void *handle,void *Buf, int Len) 80 | { 81 | tftp_ldr_internal *p = (tftp_ldr_internal *) handle; 82 | int Ret; 83 | LOG("Called, Len %d\n",Len); 84 | 85 | if(p->TransferType == TFTP_TYPE_SAVE) { 86 | uint32_t Adr = p->FlashAdr + p->BytesTransfered; 87 | uint32_t Bytes2Read = Len; 88 | 89 | if(p->BytesTransfered + Len > p->SendLen) { 90 | Len = p->SendLen - p->BytesTransfered; 91 | } 92 | 93 | spi_read(p->FlashAdr + p->BytesTransfered,(uint8_t *) Buf,Len); 94 | p->BytesTransfered += Len; 95 | Ret = Len; 96 | } 97 | else { 98 | ELOG("Internal err\n"); 99 | Ret = -1; 100 | } 101 | 102 | LOG("Returning %d\n",Ret); 103 | return Ret; 104 | } 105 | 106 | static int tftp_write(void *handle, struct pbuf *pBuf) 107 | { 108 | tftp_ldr_internal *p = (tftp_ldr_internal *) handle; 109 | uint32_t Adr = p->FlashAdr + p->BytesTransfered; 110 | 111 | int Ret = 0; // assume the best 112 | u16_t TotalLen = pBuf->tot_len; 113 | u16_t Len = 0; 114 | u16_t BufLen; 115 | 116 | while(Ret == 0 && Len < TotalLen) { 117 | BufLen = pBuf->len; 118 | switch(p->TransferType) { 119 | case TFTP_TYPE_RAM: 120 | if((p->BytesTransfered + TotalLen) > p->MaxBytes ) { 121 | p->Error = TFTP_ERR_BUF_TOO_SMALL; 122 | break; 123 | } 124 | memcpy(&p->Ram[p->BytesTransfered],pBuf->payload,BufLen); 125 | break; 126 | 127 | case TFTP_TYPE_FLASH: { 128 | const FlashInfo_t *pInfo = spi_get_flashinfo(); 129 | uint32_t EraseSize = pInfo->EraseSize; 130 | uint32_t LastAdr = Adr + BufLen - 1; 131 | uint32_t EraseAdr; 132 | uint32_t EraseEnd = LastAdr - (LastAdr % EraseSize); 133 | 134 | if(p->bAutoErase && p->LastEraseAdr != EraseEnd) { 135 | if(p->LastEraseAdr == INVALID_FLASH_ADR) { 136 | p->LastEraseAdr = Adr - (Adr % EraseSize); 137 | } 138 | else { 139 | p->LastEraseAdr += EraseSize; 140 | } 141 | LOG("erase 0x%x\n",p->LastEraseAdr); 142 | spi_erase(p->LastEraseAdr,pInfo->EraseSize); 143 | } 144 | 145 | LOG("flash %d @ 0x%x\n",BufLen,Adr); 146 | spi_write(Adr,pBuf->payload,BufLen); 147 | break; 148 | } 149 | 150 | case TFTP_TYPE_COMPARE: 151 | LOG("comparing %d bytes\n",BufLen); 152 | if(BufLen > p->MaxBytes) { 153 | p->Error = TFTP_ERR_BUF_TOO_SMALL; 154 | break; 155 | } 156 | spi_read(Adr,p->Ram,BufLen); 157 | if(memcmp(p->Ram,pBuf->payload,BufLen) != 0) { 158 | int i; 159 | char *cp = pBuf->payload; 160 | // Find the exact point of failure 161 | for(i = 0; i < BufLen; i++) { 162 | if(p->Ram[i] != *cp++) { 163 | break; 164 | } 165 | p->BytesTransfered++; 166 | } 167 | 168 | LOG("Compare failed\n"); 169 | p->Error = TFTP_ERR_COMPARE_FAIL; 170 | } 171 | break; 172 | 173 | default: 174 | p->Error = TFTP_ERR_INTERNAL; 175 | break; 176 | } 177 | 178 | if(p->Error != TFTP_IN_PROGRESS) { 179 | Ret = -1; 180 | } 181 | else { 182 | pBuf = pBuf->next; 183 | p->BytesTransfered += BufLen; 184 | Len += BufLen; 185 | } 186 | } 187 | 188 | LOG("Returning %d\n",Ret); 189 | 190 | return Ret; 191 | } 192 | 193 | /* For TFTP client only */ 194 | static void tftp_error(void *handle,int err,const char *Msg,int size) 195 | { 196 | tftp_ldr_internal *p = (tftp_ldr_internal *) handle; 197 | 198 | ELOG("err %d: %s\n",err,Msg); 199 | if(size > MAX_ERR_MSG_LEN) { 200 | size = MAX_ERR_MSG_LEN; 201 | } 202 | memcpy(p->ErrMsg,Msg,size); 203 | p->ErrMsg[MAX_ERR_MSG_LEN] = 0; 204 | p->Error = TFTP_ERR_FAILED; 205 | } 206 | 207 | static const struct tftp_context tftp = { 208 | tftp_open, 209 | tftp_close, 210 | tftp_read, 211 | tftp_write, 212 | tftp_error 213 | }; 214 | 215 | err_t ldr_tftp_init(tftp_ldr_internal *p) 216 | { 217 | err_t Err; 218 | const char *Filename; 219 | const char *TransferTypes[] = { "read", "flash","compar","sav" }; 220 | 221 | do { 222 | if(p == NULL || p->ServerIP.addr == 0 || p->Filename == NULL || 223 | p->TransferType < 0 || p->TransferType > TFTP_TYPE_LAST) 224 | { 225 | Err = ERR_VAL; 226 | break; 227 | } 228 | p->Error = TFTP_OK; 229 | p->LastEraseAdr = INVALID_FLASH_ADR; 230 | p->BytesTransfered = 0; 231 | p->LastProgress = 0; 232 | p->ErrMsg[0] = 0; 233 | 234 | if((Err = tftp_init_client(&tftp)) != ERR_OK) { 235 | ELOG("tftp_init_client failed %d\n",Err); 236 | break; 237 | } 238 | Filename = (const char *) p->Filename; 239 | LOG("%sing %s @ 0x%x\n", 240 | TransferTypes[p->TransferType - 1],Filename,p->FlashAdr); 241 | 242 | if(p->TransferType == TFTP_TYPE_SAVE) { 243 | Err = tftp_put(p,&p->ServerIP,TFTP_PORT,Filename,TFTP_MODE_OCTET); 244 | } 245 | else { 246 | Err = tftp_get(p,&p->ServerIP,TFTP_PORT,Filename,TFTP_MODE_OCTET); 247 | } 248 | if(Err != ERR_OK) { 249 | ELOG("failed %d\n",Err); 250 | break; 251 | } 252 | p->Error = TFTP_IN_PROGRESS; 253 | } while(false); 254 | 255 | return Err; 256 | } 257 | 258 | -------------------------------------------------------------------------------- /fw/pano_ldr/tftp_ldr.h: -------------------------------------------------------------------------------- 1 | #ifndef _TFTP_LDR_H_ 2 | #define _TFTP_LDR_H_ 3 | 4 | 5 | // How often to show progress during flash command 6 | #define PROGRESS_SIZE (64*1024) 7 | 8 | typedef enum { 9 | TFTP_TYPE_RAM = 1, 10 | TFTP_TYPE_FLASH, 11 | TFTP_TYPE_COMPARE, 12 | TFTP_TYPE_SAVE 13 | } TransferType_t; 14 | #define TFTP_TYPE_LAST TFTP_TYPE_SAVE 15 | 16 | 17 | typedef enum { 18 | TFTP_OK = 0, 19 | TFTP_ERR_BUF_TOO_SMALL, 20 | TFTP_ERR_COMPARE_FAIL, 21 | TFTP_IN_PROGRESS, 22 | TFTP_ERR_FAILED, 23 | TFTP_ERR_INTERNAL 24 | } TransferResult_t; 25 | 26 | #define MAX_FILENAME_LEN 32 27 | #define MAX_ERR_MSG_LEN 32 28 | typedef struct { 29 | ip_addr_t ServerIP; 30 | char Filename[MAX_FILENAME_LEN + 1]; 31 | char ErrMsg[MAX_ERR_MSG_LEN + 1]; 32 | int BytesTransfered; 33 | int MaxBytes; 34 | uint32_t SendLen; 35 | TransferType_t TransferType; 36 | char *Ram; 37 | uint32_t FlashAdr; 38 | uint32_t LastEraseAdr; 39 | uint32_t LastProgress; 40 | TransferResult_t Error; 41 | bool bAutoErase; 42 | } tftp_ldr_internal; 43 | 44 | err_t ldr_tftp_init(tftp_ldr_internal *p); 45 | int NetPrintf(const char *Format, ...); 46 | 47 | #endif // _TFTP_LDR_H_ 48 | -------------------------------------------------------------------------------- /install_pano_ldr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # set -x 4 | pano_ip=`./prebuilt/install_rev_b --discover pano | head -n3 | tail -n1 | cut -d' ' -f1` 5 | if [ "x$pano_ip" = "xTest" ]; then 6 | echo "Error: no Panos were found" 7 | exit 1 8 | fi 9 | echo "Pano IP: $pano_ip" 10 | boardid=`./prebuilt/install_rev_b $pano_ip chipIdRd | grep CFG | cut -d' ' -f 5` 11 | 12 | if [ "x$boardid" = "x0x00050000" ]; then 13 | echo "The detected Pano is a first generation device which is not supported" 14 | exit 1 15 | elif [ "x$boardid" = "x0x10010001" ]; then 16 | device="Pano G1+" 17 | rev=c 18 | elif [ "x$boardid" = "x0x08010000" ]; then 19 | device="Rev B Pano G2" 20 | rev=b 21 | elif [ "x$boardid" = "x0x08010002" ]; then 22 | device="Rev C Pano G2" 23 | rev=c 24 | elif [ "x$boardid" = "x0x08011000" ]; then 25 | device="Fujitsu DZ22-2" 26 | rev=b 27 | else 28 | echo 29 | echo "Unknown Pano boardId '$boardid'" 30 | echo "Please open an issue and report this to https://github.com/skiphansen/panog2_ldr/issues with the following" 31 | echo "with the following:" 32 | echo "----" 33 | ./prebuilt/install_rev_b $pano_ip chipIdRd 34 | echo "----" 35 | echo 36 | echo "You might also post to https://gitter.im/panologic/community for help" 37 | exit 1 38 | fi 39 | 40 | echo "" 41 | echo -n "Install pano_ldr on $device (y/n) ?" 42 | read answer 43 | if [ x$answer = "xy" -o x$answer = "xyes" ]; then 44 | rm BurninLowLevel${pano_ip}.log > /dev/null 45 | ./prebuilt/install_rev_${rev} $pano_ip flashFPGA_Series2_Multiboot & 46 | installer_pid=$! 47 | sleep 1 48 | tail -f BurninLowLevel${pano_ip}.log & 49 | wait $installer_pid 50 | rm BurninLowLevel${pano_ip}.log 51 | echo "Pano_ldr installed, power cycle the Pano to start it" 52 | fi 53 | 54 | -------------------------------------------------------------------------------- /patches/cores/cpu/riscv/0001-Increase-on-chip-RAM-to-128k.patch: -------------------------------------------------------------------------------- 1 | From de820f078c075250303ea85b730e9b3df9a7c2f4 Mon Sep 17 00:00:00 2001 2 | From: Skip Hansen 3 | Date: Wed, 8 Apr 2020 09:49:11 -0700 4 | Subject: [PATCH] Increase on chip RAM to 128k. 5 | 6 | --- 7 | top_tcm_wrapper/dport_mux.v | 2 +- 8 | top_tcm_wrapper/tcm_mem.v | 4 ++-- 9 | top_tcm_wrapper/tcm_mem_ram.v | 10 +++++++--- 10 | 3 files changed, 10 insertions(+), 6 deletions(-) 11 | mode change 100644 => 100755 top_tcm_wrapper/dport_mux.v 12 | mode change 100644 => 100755 top_tcm_wrapper/tcm_mem.v 13 | 14 | diff --git a/top_tcm_wrapper/dport_mux.v b/top_tcm_wrapper/dport_mux.v 15 | old mode 100644 16 | new mode 100755 17 | index 0a0ecbb..cea3caa 18 | --- a/top_tcm_wrapper/dport_mux.v 19 | +++ b/top_tcm_wrapper/dport_mux.v 20 | @@ -110,7 +110,7 @@ module dport_mux 21 | wire hold_w; 22 | 23 | /* verilator lint_off UNSIGNED */ 24 | -wire tcm_access_w = (mem_addr_i >= TCM_MEM_BASE && mem_addr_i < (TCM_MEM_BASE + 32'd65536)); 25 | +wire tcm_access_w = (mem_addr_i >= TCM_MEM_BASE && mem_addr_i < (TCM_MEM_BASE + 32'd131072)); 26 | /* verilator lint_on UNSIGNED */ 27 | 28 | reg tcm_access_q; 29 | diff --git a/top_tcm_wrapper/tcm_mem.v b/top_tcm_wrapper/tcm_mem.v 30 | old mode 100644 31 | new mode 100755 32 | index f2eb6ae..59170ee 33 | --- a/top_tcm_wrapper/tcm_mem.v 34 | +++ b/top_tcm_wrapper/tcm_mem.v 35 | @@ -165,7 +165,7 @@ u_conv 36 | //------------------------------------------------------------- 37 | 38 | // Mux access to the 2nd port between external access and CPU data access 39 | -wire [13:0] muxed_addr_w = ext_accept_w ? ext_addr_w[15:2] : mem_d_addr_i[15:2]; 40 | +wire [14:0] muxed_addr_w = ext_accept_w ? ext_addr_w[16:2] : mem_d_addr_i[16:2]; 41 | wire [31:0] muxed_data_w = ext_accept_w ? ext_write_data_w : mem_d_data_wr_i; 42 | wire [3:0] muxed_wr_w = ext_accept_w ? ext_wr_w : mem_d_wr_i; 43 | wire [31:0] data_r_w; 44 | @@ -176,7 +176,7 @@ u_ram 45 | // Instruction fetch 46 | .clk0_i(clk_i) 47 | ,.rst0_i(rst_i) 48 | - ,.addr0_i(mem_i_pc_i[15:2]) 49 | + ,.addr0_i(mem_i_pc_i[16:2]) 50 | ,.data0_i(32'b0) 51 | ,.wr0_i(4'b0) 52 | 53 | diff --git a/top_tcm_wrapper/tcm_mem_ram.v b/top_tcm_wrapper/tcm_mem_ram.v 54 | index c641bf2..6c72a55 100644 55 | --- a/top_tcm_wrapper/tcm_mem_ram.v 56 | +++ b/top_tcm_wrapper/tcm_mem_ram.v 57 | @@ -47,12 +47,12 @@ module tcm_mem_ram 58 | // Inputs 59 | input clk0_i 60 | ,input rst0_i 61 | - ,input [ 13:0] addr0_i 62 | + ,input [ 14:0] addr0_i 63 | ,input [ 31:0] data0_i 64 | ,input [ 3:0] wr0_i 65 | ,input clk1_i 66 | ,input rst1_i 67 | - ,input [ 13:0] addr1_i 68 | + ,input [ 14:0] addr1_i 69 | ,input [ 31:0] data1_i 70 | ,input [ 3:0] wr1_i 71 | 72 | @@ -68,9 +68,13 @@ module tcm_mem_ram 73 | // Mode: Read First 74 | //----------------------------------------------------------------- 75 | /* verilator lint_off MULTIDRIVEN */ 76 | -reg [31:0] ram [16383:0] /*verilator public*/; 77 | +reg [31:0] ram [32767:0] /*verilator public*/; 78 | /* verilator lint_on MULTIDRIVEN */ 79 | 80 | +initial begin 81 | + $readmemh("firmware.mem", ram, 0, 32767); 82 | +end 83 | + 84 | reg [31:0] ram_read0_q; 85 | reg [31:0] ram_read1_q; 86 | 87 | -- 88 | 2.17.1 89 | 90 | -------------------------------------------------------------------------------- /patches/cores/cpu/riscv/0010-Enable-SUPPORT_REGFILE_XILINX.patch: -------------------------------------------------------------------------------- 1 | From 56690b8790ef8b1488d506a1b024f9573493cb30 Mon Sep 17 00:00:00 2001 2 | From: Skip Hansen 3 | Date: Wed, 3 Jun 2020 07:34:30 -0700 4 | Subject: [PATCH] Enable SUPPORT_REGFILE_XILINX. 5 | 6 | --- 7 | core/riscv/riscv_core.v | 2 +- 8 | 1 file changed, 1 insertion(+), 1 deletion(-) 9 | mode change 100644 => 100755 core/riscv/riscv_core.v 10 | 11 | diff --git a/core/riscv/riscv_core.v b/core/riscv/riscv_core.v 12 | old mode 100644 13 | new mode 100755 14 | index 4efc244..11575f1 15 | --- a/core/riscv/riscv_core.v 16 | +++ b/core/riscv/riscv_core.v 17 | @@ -49,7 +49,7 @@ module riscv_core 18 | ,parameter SUPPORT_MMU = 0 19 | ,parameter SUPPORT_LOAD_BYPASS = 1 20 | ,parameter SUPPORT_MUL_BYPASS = 1 21 | - ,parameter SUPPORT_REGFILE_XILINX = 0 22 | + ,parameter SUPPORT_REGFILE_XILINX = 1 23 | ,parameter EXTRA_DECODE_STAGE = 0 24 | ,parameter MEM_CACHE_ADDR_MIN = 32'h80000000 25 | ,parameter MEM_CACHE_ADDR_MAX = 32'h8fffffff 26 | -- 27 | 2.17.1 28 | 29 | -------------------------------------------------------------------------------- /patches/cores/ethernet_mac/0001-BUFGMUX-routing-fix.patch: -------------------------------------------------------------------------------- 1 | Index: e/xilinx/mii_gmii_io_spartan6.vhd 2 | =================================================================== 3 | --- e.orig/xilinx/mii_gmii_io_spartan6.vhd 4 | +++ e/xilinx/mii_gmii_io_spartan6.vhd 5 | @@ -17,6 +17,7 @@ architecture spartan_6 of mii_gmii_io is 6 | signal clock_tx_inv : std_ulogic := '1'; 7 | signal clock_mii_rx_io : std_ulogic := '0'; 8 | signal clock_mii_rx_div : std_ulogic; 9 | + signal clock_tx_int : std_ulogic; 10 | 11 | -- IDELAY_VALUE applied to the inputs using IODELAY2 12 | -- This will need fine-tuning depending on the exact device and the location of the IO pins 13 | @@ -40,16 +41,29 @@ begin 14 | -- Asynchronous clock switch-over is required: the MII TX_CLK might not be running any more when 15 | -- switching to GMII. This means that glitches can occur on the clock and the complete MAC has to 16 | -- be reset after a speed change. 17 | - clock_tx_BUFGMUX_inst : BUFGMUX 18 | - generic map( 19 | - CLK_SEL_TYPE => "ASYNC" -- Glitchles ("SYNC") or fast ("ASYNC") clock switch-over 20 | - ) 21 | - port map( 22 | - O => clock_tx, -- 1-bit output: Clock buffer output 23 | - I0 => mii_tx_clk_i, -- 1-bit input: Clock buffer input (S=0) 24 | - I1 => clock_125_i, -- 1-bit input: Clock buffer input (S=1) 25 | - S => gmii_active -- 1-bit input: Clock buffer select 26 | - ); 27 | +-- clock_tx_BUFGMUX_inst : BUFGMUX 28 | +-- generic map( 29 | +-- CLK_SEL_TYPE => "ASYNC" -- Glitchles ("SYNC") or fast ("ASYNC") clock switch-over 30 | +-- ) 31 | +-- port map( 32 | +-- O => clock_tx, -- 1-bit output: Clock buffer output 33 | +-- I0 => mii_tx_clk_i, -- 1-bit input: Clock buffer input (S=0) 34 | +-- I1 => clock_125_i, -- 1-bit input: Clock buffer input (S=1) 35 | +-- S => gmii_active -- 1-bit input: Clock buffer select 36 | +-- ); 37 | + 38 | + -- Can't use a BUFGMUX on a Panologic G2 because of routing contraints. 39 | + -- We need access to the 125 Mhz clock for other purposes as well, 40 | + -- as soon as we add an input buffer for SYCCLK/Y13 the design becomes 41 | + -- unroutable if we also try to use a BUFGMUX. 42 | + 43 | + clock_tx_int <= clock_125_i when gmii_active = '1' else mii_tx_clk_i; 44 | + 45 | + mii_tx_clk_BUFG_inst : BUFG 46 | + port map( 47 | + O => clock_tx, -- 1-bit output: Clock buffer output 48 | + I => clock_tx_int -- 1-bit input: Clock buffer input 49 | + ); 50 | 51 | -- Output clock only when running GMII to reduce switching noise 52 | -- and avoid outputting a useless 25 MHz clock in MII mode. 53 | -------------------------------------------------------------------------------- /patches/fw/lwip/0001-Fix-build-for-NO_SYS-1.patch: -------------------------------------------------------------------------------- 1 | From 33b61656e9789455bb97fd81b7b22b3a3ae1e65d Mon Sep 17 00:00:00 2001 2 | From: Skip Hansen 3 | Date: Wed, 8 Apr 2020 10:24:13 -0700 4 | Subject: [PATCH] Fix build for NO_SYS=1. 5 | 6 | --- 7 | src/core/{init.c => lwip_init.c} | 0 8 | src/include/lwip/priv/api_msg.h | 4 +++- 9 | src/include/lwip/priv/tcpip_priv.h | 4 ++-- 10 | src/include/lwip/tcpip.h | 4 ++-- 11 | 4 files changed, 7 insertions(+), 5 deletions(-) 12 | rename src/core/{init.c => lwip_init.c} (100%) 13 | mode change 100644 => 100755 src/include/lwip/priv/api_msg.h 14 | mode change 100644 => 100755 src/include/lwip/priv/tcpip_priv.h 15 | mode change 100644 => 100755 src/include/lwip/tcpip.h 16 | 17 | diff --git a/src/core/init.c b/src/core/lwip_init.c 18 | similarity index 100% 19 | rename from src/core/init.c 20 | rename to src/core/lwip_init.c 21 | diff --git a/src/include/lwip/priv/api_msg.h b/src/include/lwip/priv/api_msg.h 22 | old mode 100644 23 | new mode 100755 24 | index 9e8ffc9e..3c330784 25 | --- a/src/include/lwip/priv/api_msg.h 26 | +++ b/src/include/lwip/priv/api_msg.h 27 | @@ -92,7 +92,9 @@ struct api_msg { 28 | } n; 29 | /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ 30 | struct { 31 | - API_MSG_M_DEF_C(ip_addr_t, ipaddr); 32 | + const ip_addr_t *ipaddr1; 33 | + ip_addr_t ipaddr2; 34 | + API_MSG_M_DEF_C(ip_addr_t, ipaddr); 35 | u16_t port; 36 | u8_t if_idx; 37 | } bc; 38 | diff --git a/src/include/lwip/priv/tcpip_priv.h b/src/include/lwip/priv/tcpip_priv.h 39 | old mode 100644 40 | new mode 100755 41 | index bfa88ff6..f79948c3 42 | --- a/src/include/lwip/priv/tcpip_priv.h 43 | +++ b/src/include/lwip/priv/tcpip_priv.h 44 | @@ -39,7 +39,7 @@ 45 | 46 | #include "lwip/opt.h" 47 | 48 | -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ 49 | +// #if !NO_SYS /* don't build if not configured for use in lwipopts.h */ 50 | 51 | #include "lwip/tcpip.h" 52 | #include "lwip/sys.h" 53 | @@ -171,6 +171,6 @@ struct tcpip_msg { 54 | } 55 | #endif 56 | 57 | -#endif /* !NO_SYS */ 58 | +// #endif /* !NO_SYS */ 59 | 60 | #endif /* LWIP_HDR_TCPIP_PRIV_H */ 61 | diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h 62 | old mode 100644 63 | new mode 100755 64 | index 30ce4fef..1a092e88 65 | --- a/src/include/lwip/tcpip.h 66 | +++ b/src/include/lwip/tcpip.h 67 | @@ -39,7 +39,7 @@ 68 | 69 | #include "lwip/opt.h" 70 | 71 | -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ 72 | +// #if !NO_SYS /* don't build if not configured for use in lwipopts.h */ 73 | 74 | #include "lwip/err.h" 75 | #include "lwip/timeouts.h" 76 | @@ -109,6 +109,6 @@ int tcpip_thread_poll_one(void); 77 | } 78 | #endif 79 | 80 | -#endif /* !NO_SYS */ 81 | +// #endif /* !NO_SYS */ 82 | 83 | #endif /* LWIP_HDR_TCPIP_H */ 84 | -- 85 | 2.17.1 86 | 87 | -------------------------------------------------------------------------------- /prebuilt/install_rev_b: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skiphansen/panog2_ldr/423c163879f91229ede8b5923352b0b4bb3ae196/prebuilt/install_rev_b -------------------------------------------------------------------------------- /prebuilt/install_rev_c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skiphansen/panog2_ldr/423c163879f91229ede8b5923352b0b4bb3ae196/prebuilt/install_rev_c -------------------------------------------------------------------------------- /prebuilt/mak_install_progs.sh: -------------------------------------------------------------------------------- 1 | #set -x 2 | 3 | PROG_FPGA_DIR=../../pano_progfpga 4 | PREBUILT_DIR=`pwd` 5 | 6 | make_install() { 7 | if [ ${1} == "c" ];then 8 | PATCH_OPTION=c 9 | FILE=pano-g2-c 10 | FPGA_TYPE=lx100 11 | elif [ ${1} == "b" ];then 12 | PATCH_OPTION=2 13 | FILE=pano-g2 14 | FPGA_TYPE=lx150 15 | else 16 | exit 17 | fi 18 | bitparse -i BIT -o BIN -O ${FILE}.bin ${FILE}.bit 19 | (cd ${PROG_FPGA_DIR};./patch_progfpga -$PATCH_OPTION -m ${PREBUILT_DIR}/${FILE}.bin) 20 | rm ${FILE}.bin 21 | cp ${PROG_FPGA_DIR}/patched/series2/${FPGA_TYPE}/progfpga_multiboot install_rev_${1} 22 | } 23 | 24 | make_install b 25 | make_install c 26 | 27 | -------------------------------------------------------------------------------- /prebuilt/pano-g2-c.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skiphansen/panog2_ldr/423c163879f91229ede8b5923352b0b4bb3ae196/prebuilt/pano-g2-c.bit -------------------------------------------------------------------------------- /prebuilt/pano-g2.bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skiphansen/panog2_ldr/423c163879f91229ede8b5923352b0b4bb3ae196/prebuilt/pano-g2.bit -------------------------------------------------------------------------------- /project.mk: -------------------------------------------------------------------------------- 1 | TEMP = $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 2 | TOPDIR := $(TEMP:/=) 3 | 4 | GIT_INIT := $(shell if [ ! -e $(TOPDIR)/pano/.git ]; then echo "updating submodules"> /dev/stderr;git submodule init; git submodule update; fi) 5 | 6 | ARCH = riscv 7 | BASE_ADDRESS = 0x0 8 | MEM_SIZE = 131072 9 | 10 | # hardware defines 11 | CPU_KHZ = 50000 12 | EXTRA_CFLAGS += -DCPU_KHZ=$(CPU_KHZ) 13 | 14 | # UART driver 15 | EXTRA_CFLAGS += -DCONFIG_UARTLITE_BASE=0x92000000 16 | 17 | # SPI driver 18 | EXTRA_CFLAGS += -DCONFIG_SPILITE_BASE=0x93000000 19 | 20 | # Create .d dependency files 21 | EXTRA_CFLAGS += -DMD 22 | 23 | ifeq ($(PLATFORM),pano-g2-c) 24 | PROG_FPGA_OFFSET = 3670016 25 | else 26 | PROG_FPGA_OFFSET = 4718592 27 | endif 28 | 29 | include $(TOPDIR)/pano/make/common.mk 30 | 31 | 32 | --------------------------------------------------------------------------------