IP verschoben

This commit is contained in:
Matthias Biermann
2025-02-19 14:10:56 +01:00
parent 6dd49381ca
commit c353892eaa
2744 changed files with 1475773 additions and 1511337 deletions
@@ -1,21 +1,21 @@
MIT License
Copyright (c) 2017 Digilent
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
MIT License
Copyright (c) 2017 Digilent
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>calib_coef</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Digilent Calibration Coefficients port</spirit:description>
</spirit:busDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>calib_coef</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Digilent Calibration Coefficients port</spirit:description>
</spirit:busDefinition>
@@ -1,86 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>calib_coef_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="Digilent" spirit:library="user" spirit:name="calib_coef" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>LgMultCoef</spirit:logicalName>
<spirit:description>Low gain multiplication coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>LgAddCoef</spirit:logicalName>
<spirit:description>Low gain Addition Coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>HgMultCoef</spirit:logicalName>
<spirit:description>High gain multiplication coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>HgAddCoef</spirit:logicalName>
<spirit:description>High gain Addition Coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:abstractionDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>calib_coef_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="Digilent" spirit:library="user" spirit:name="calib_coef" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>LgMultCoef</spirit:logicalName>
<spirit:description>Low gain multiplication coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>LgAddCoef</spirit:logicalName>
<spirit:description>Low gain Addition Coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>HgMultCoef</spirit:logicalName>
<spirit:description>High gain multiplication coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>HgAddCoef</spirit:logicalName>
<spirit:description>High gain Addition Coefficient</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>18</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:abstractionDefinition>
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>pmod</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>true</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Pmod Interface for Digilent FPGAs</spirit:description>
<spirit:vendorExtensions>
<xilinx:busDefinitionInfo>
<xilinx:displayName>Pmod Interface</xilinx:displayName>
</xilinx:busDefinitionInfo>
</spirit:vendorExtensions>
</spirit:busDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>pmod</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>true</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Pmod Interface for Digilent FPGAs</spirit:description>
<spirit:vendorExtensions>
<xilinx:busDefinitionInfo>
<xilinx:displayName>Pmod Interface</xilinx:displayName>
</xilinx:busDefinitionInfo>
</spirit:vendorExtensions>
</spirit:busDefinition>
@@ -1,255 +1,255 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>pmod_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="digilentinc.com" spirit:library="interface" spirit:name="pmod" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>PIN1_I</spirit:logicalName>
<spirit:description>Pmod Pin 1 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN1_O</spirit:logicalName>
<spirit:description>Pmod Pin 1 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN1_T</spirit:logicalName>
<spirit:description>Pmod Pin 1 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_I</spirit:logicalName>
<spirit:description>Pmod Pin 2 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_O</spirit:logicalName>
<spirit:description>Pmod Pin 2 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_T</spirit:logicalName>
<spirit:description>Pmod Pin 2 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_I</spirit:logicalName>
<spirit:description>Pmod Pin 3 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_O</spirit:logicalName>
<spirit:description>Pmod Pin 3 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_T</spirit:logicalName>
<spirit:description>Pmod Pin 3 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_I</spirit:logicalName>
<spirit:description>Pmod Pin 4 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_O</spirit:logicalName>
<spirit:description>Pmod Pin 4 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_T</spirit:logicalName>
<spirit:description>Pmod Pin 4 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_I</spirit:logicalName>
<spirit:description>Pmod Pin 7 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_O</spirit:logicalName>
<spirit:description>Pmod Pin 7 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_T</spirit:logicalName>
<spirit:description>Pmod Pin 7 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_I</spirit:logicalName>
<spirit:description>Pmod Pin 8 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_O</spirit:logicalName>
<spirit:description>Pmod Pin 8 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_T</spirit:logicalName>
<spirit:description>Pmod Pin 8 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_I</spirit:logicalName>
<spirit:description>Pmod Pin 9 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_O</spirit:logicalName>
<spirit:description>Pmod Pin 9 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_T</spirit:logicalName>
<spirit:description>Pmod Pin 9 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_I</spirit:logicalName>
<spirit:description>Pmod Pin 10 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_O</spirit:logicalName>
<spirit:description>Pmod Pin 10 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_T</spirit:logicalName>
<spirit:description>Pmod Pin 10 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
</spirit:ports>
<spirit:vendorExtensions>
<xilinx:abstractionDefinitionInfo>
<xilinx:displayName>Pmod Interface</xilinx:displayName>
</xilinx:abstractionDefinitionInfo>
</spirit:vendorExtensions>
</spirit:abstractionDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>pmod_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="digilentinc.com" spirit:library="interface" spirit:name="pmod" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>PIN1_I</spirit:logicalName>
<spirit:description>Pmod Pin 1 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN1_O</spirit:logicalName>
<spirit:description>Pmod Pin 1 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN1_T</spirit:logicalName>
<spirit:description>Pmod Pin 1 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_I</spirit:logicalName>
<spirit:description>Pmod Pin 2 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_O</spirit:logicalName>
<spirit:description>Pmod Pin 2 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN2_T</spirit:logicalName>
<spirit:description>Pmod Pin 2 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_I</spirit:logicalName>
<spirit:description>Pmod Pin 3 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_O</spirit:logicalName>
<spirit:description>Pmod Pin 3 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN3_T</spirit:logicalName>
<spirit:description>Pmod Pin 3 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_I</spirit:logicalName>
<spirit:description>Pmod Pin 4 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_O</spirit:logicalName>
<spirit:description>Pmod Pin 4 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN4_T</spirit:logicalName>
<spirit:description>Pmod Pin 4 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_I</spirit:logicalName>
<spirit:description>Pmod Pin 7 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_O</spirit:logicalName>
<spirit:description>Pmod Pin 7 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN7_T</spirit:logicalName>
<spirit:description>Pmod Pin 7 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_I</spirit:logicalName>
<spirit:description>Pmod Pin 8 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_O</spirit:logicalName>
<spirit:description>Pmod Pin 8 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN8_T</spirit:logicalName>
<spirit:description>Pmod Pin 8 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_I</spirit:logicalName>
<spirit:description>Pmod Pin 9 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_O</spirit:logicalName>
<spirit:description>Pmod Pin 9 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN9_T</spirit:logicalName>
<spirit:description>Pmod Pin 9 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_I</spirit:logicalName>
<spirit:description>Pmod Pin 10 in</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_O</spirit:logicalName>
<spirit:description>Pmod Pin 10 out</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>PIN10_T</spirit:logicalName>
<spirit:description>Pmod Pin 10 tristate</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:width>1</spirit:width>
<spirit:direction>out</spirit:direction>
</spirit:onMaster>
</spirit:wire>
</spirit:port>
</spirit:ports>
<spirit:vendorExtensions>
<xilinx:abstractionDefinitionInfo>
<xilinx:displayName>Pmod Interface</xilinx:displayName>
</xilinx:abstractionDefinitionInfo>
</spirit:vendorExtensions>
</spirit:abstractionDefinition>
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>spi_ctl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Digilent SPI custom control</spirit:description>
</spirit:busDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>spi_ctl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Digilent SPI custom control</spirit:description>
</spirit:busDefinition>
@@ -1,175 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>spi_ctl_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="Digilent" spirit:library="user" spirit:name="spi_ctl" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>EnTx</spirit:logicalName>
<spirit:description>Enable Tx</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>EnRx</spirit:logicalName>
<spirit:description>Enable Rx</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxValid</spirit:logicalName>
<spirit:description>Valid resapons on the Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxDout</spirit:logicalName>
<spirit:description>Data on the Tx path</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>24</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>24</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxRdEnRdy</spirit:logicalName>
<spirit:description>Read Enable/Ready for Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxRdEn</spirit:logicalName>
<spirit:description>Read Enable bit for the Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>RxWrEn</spirit:logicalName>
<spirit:description>Write Enable on the Rx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>RxDin</spirit:logicalName>
<spirit:description>Data for the Rx path</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>8</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>8</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>Idle</spirit:logicalName>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>CmdDone</spirit:logicalName>
<spirit:description>Command done signal</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:abstractionDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>Digilent</spirit:vendor>
<spirit:library>user</spirit:library>
<spirit:name>spi_ctl_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="Digilent" spirit:library="user" spirit:name="spi_ctl" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>EnTx</spirit:logicalName>
<spirit:description>Enable Tx</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>EnRx</spirit:logicalName>
<spirit:description>Enable Rx</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxValid</spirit:logicalName>
<spirit:description>Valid resapons on the Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxDout</spirit:logicalName>
<spirit:description>Data on the Tx path</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>24</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>24</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxRdEnRdy</spirit:logicalName>
<spirit:description>Read Enable/Ready for Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>TxRdEn</spirit:logicalName>
<spirit:description>Read Enable bit for the Tx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>RxWrEn</spirit:logicalName>
<spirit:description>Write Enable on the Rx path</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>RxDin</spirit:logicalName>
<spirit:description>Data for the Rx path</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>8</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>8</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>Idle</spirit:logicalName>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>CmdDone</spirit:logicalName>
<spirit:description>Command done signal</spirit:description>
<spirit:wire>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
</spirit:abstractionDefinition>
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>tmds</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Raw TMDS electrical interface as defined in DVI 1.0</spirit:description>
<spirit:vendorExtensions>
<xilinx:busDefinitionInfo>
<xilinx:displayName>TMDS Interface for DVI and HDMI</xilinx:displayName>
</xilinx:busDefinitionInfo>
</spirit:vendorExtensions>
</spirit:busDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:busDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>tmds</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:directConnection>false</spirit:directConnection>
<spirit:isAddressable>false</spirit:isAddressable>
<spirit:maxMasters>1</spirit:maxMasters>
<spirit:maxSlaves>1</spirit:maxSlaves>
<spirit:description>Raw TMDS electrical interface as defined in DVI 1.0</spirit:description>
<spirit:vendorExtensions>
<xilinx:busDefinitionInfo>
<xilinx:displayName>TMDS Interface for DVI and HDMI</xilinx:displayName>
</xilinx:busDefinitionInfo>
</spirit:vendorExtensions>
</spirit:busDefinition>
@@ -1,91 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>tmds_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="digilentinc.com" spirit:library="interface" spirit:name="tmds" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>CLK_P</spirit:logicalName>
<spirit:description>Clock channel positive</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isClock>true</spirit:isClock>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>CLK_N</spirit:logicalName>
<spirit:description>Clock channel negative</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isClock>true</spirit:isClock>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>DATA_P</spirit:logicalName>
<spirit:description>Data channel positive</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>DATA_N</spirit:logicalName>
<spirit:description>Data channel negative</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
<spirit:vendorExtensions>
<xilinx:abstractionDefinitionInfo>
<xilinx:displayName>TMDS Interface for DVI and HDMI</xilinx:displayName>
</xilinx:abstractionDefinitionInfo>
</spirit:vendorExtensions>
</spirit:abstractionDefinition>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:abstractionDefinition xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>digilentinc.com</spirit:vendor>
<spirit:library>interface</spirit:library>
<spirit:name>tmds_rtl</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:busType spirit:vendor="digilentinc.com" spirit:library="interface" spirit:name="tmds" spirit:version="1.0"/>
<spirit:ports>
<spirit:port>
<spirit:logicalName>CLK_P</spirit:logicalName>
<spirit:description>Clock channel positive</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isClock>true</spirit:isClock>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>CLK_N</spirit:logicalName>
<spirit:description>Clock channel negative</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isClock>true</spirit:isClock>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>1</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>DATA_P</spirit:logicalName>
<spirit:description>Data channel positive</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
<spirit:port>
<spirit:logicalName>DATA_N</spirit:logicalName>
<spirit:description>Data channel negative</spirit:description>
<spirit:wire>
<spirit:qualifier>
<spirit:isData>true</spirit:isData>
</spirit:qualifier>
<spirit:onMaster>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
</spirit:onMaster>
<spirit:onSlave>
<spirit:presence>required</spirit:presence>
<spirit:width>3</spirit:width>
<spirit:direction>in</spirit:direction>
</spirit:onSlave>
<spirit:defaultValue>0</spirit:defaultValue>
</spirit:wire>
</spirit:port>
</spirit:ports>
<spirit:vendorExtensions>
<xilinx:abstractionDefinitionInfo>
<xilinx:displayName>TMDS Interface for DVI and HDMI</xilinx:displayName>
</xilinx:abstractionDefinitionInfo>
</spirit:vendorExtensions>
</spirit:abstractionDefinition>
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "AXI_DPTI" "NUM_INSTANCES" "DEVICE_ID" "AXI4_Lite_BASEADDR" "AXI4_Lite_HIGHADDR"
}
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "AXI_DPTI" "NUM_INSTANCES" "DEVICE_ID" "AXI4_Lite_BASEADDR" "AXI4_Lite_HIGHADDR"
}
@@ -1,109 +1,109 @@
/******************************************************************************
* @file AXI_DPTI.c
* AXI DPTI driver.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI transfer request function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
* 1.10 Thomas Kappenman 2020-Apr-28 Removed blocking call
* </pre>
*
*****************************************************************************/
/***************************** Include Files *******************************/
#include "AXI_DPTI.h"
#include "xil_io.h"
/************************** Function Definitions ***************************/
XStatus DPTI_SimpleTransfer (u32 BaseAddress, u8 Direction, u32 TransferLength)
{
u32 txLengthEmptyFlag, rxLengthEmptyFlag, StsReg, timeout=0;
if (TransferLength > 8388607)
return XST_FAILURE; // length is not a valid number
else
{
StsReg = Xil_In32 (BaseAddress + DPTI_STATUS_REG_OFFSET);
txLengthEmptyFlag = (StsReg & DPTI_SR_TX_LEN_EMPTY_MASK);
rxLengthEmptyFlag = (StsReg & DPTI_SR_RX_LEN_EMPTY_MASK);
// while (rxLengthEmptyFlag == 0 || txLengthEmptyFlag == 0)
// {
// StsReg = Xil_In32 (BaseAddress + DPTI_STATUS_REG_OFFSET);
// txLengthEmptyFlag = (StsReg & DPTI_SR_TX_LEN_EMPTY_MASK);
// rxLengthEmptyFlag = (StsReg & DPTI_SR_RX_LEN_EMPTY_MASK);
// timeout ++;
// if(timeout >= 1000000)return XST_FAILURE;
// }
// if (rxLengthEmptyFlag == 1 && txLengthEmptyFlag == 1){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, 0);
if (Direction == 1){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, STREAM_TO_DPTI);
}
if (Direction == 2){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, DPTI_TO_STREAM);
}
Xil_Out32 (BaseAddress + DPTI_LENGTH_REG_OFFSET, TransferLength);
// }
// else {
// xil_printf("DPTI_SimpleTransfer: Transfer already in progress.");
// return XST_FAILURE;
// }
}
return XST_SUCCESS;
}
XStatus DPTI_Reset(u32 BaseAddress){
Xil_Out32(BaseAddress+ DPTI_CONTROL_REG_OFFSET, DPTI_CR_RESET_MASK);
Xil_Out32(BaseAddress+ DPTI_LENGTH_REG_OFFSET, 0);
Xil_Out32(BaseAddress+ DPTI_CONTROL_REG_OFFSET, 0);
return XST_SUCCESS;
}
/******************************************************************************
* @file AXI_DPTI.c
* AXI DPTI driver.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI transfer request function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
* 1.10 Thomas Kappenman 2020-Apr-28 Removed blocking call
* </pre>
*
*****************************************************************************/
/***************************** Include Files *******************************/
#include "AXI_DPTI.h"
#include "xil_io.h"
/************************** Function Definitions ***************************/
XStatus DPTI_SimpleTransfer (u32 BaseAddress, u8 Direction, u32 TransferLength)
{
u32 txLengthEmptyFlag, rxLengthEmptyFlag, StsReg, timeout=0;
if (TransferLength > 8388607)
return XST_FAILURE; // length is not a valid number
else
{
StsReg = Xil_In32 (BaseAddress + DPTI_STATUS_REG_OFFSET);
txLengthEmptyFlag = (StsReg & DPTI_SR_TX_LEN_EMPTY_MASK);
rxLengthEmptyFlag = (StsReg & DPTI_SR_RX_LEN_EMPTY_MASK);
// while (rxLengthEmptyFlag == 0 || txLengthEmptyFlag == 0)
// {
// StsReg = Xil_In32 (BaseAddress + DPTI_STATUS_REG_OFFSET);
// txLengthEmptyFlag = (StsReg & DPTI_SR_TX_LEN_EMPTY_MASK);
// rxLengthEmptyFlag = (StsReg & DPTI_SR_RX_LEN_EMPTY_MASK);
// timeout ++;
// if(timeout >= 1000000)return XST_FAILURE;
// }
// if (rxLengthEmptyFlag == 1 && txLengthEmptyFlag == 1){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, 0);
if (Direction == 1){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, STREAM_TO_DPTI);
}
if (Direction == 2){
Xil_Out32(BaseAddress + DPTI_CONTROL_REG_OFFSET, DPTI_TO_STREAM);
}
Xil_Out32 (BaseAddress + DPTI_LENGTH_REG_OFFSET, TransferLength);
// }
// else {
// xil_printf("DPTI_SimpleTransfer: Transfer already in progress.");
// return XST_FAILURE;
// }
}
return XST_SUCCESS;
}
XStatus DPTI_Reset(u32 BaseAddress){
Xil_Out32(BaseAddress+ DPTI_CONTROL_REG_OFFSET, DPTI_CR_RESET_MASK);
Xil_Out32(BaseAddress+ DPTI_LENGTH_REG_OFFSET, 0);
Xil_Out32(BaseAddress+ DPTI_CONTROL_REG_OFFSET, 0);
return XST_SUCCESS;
}
@@ -1,86 +1,86 @@
/******************************************************************************
* @file AXI_DPTI.h
* AXI DPTI header.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI definitions and prototypes function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
*
* </pre>
*
*****************************************************************************/
#ifndef AXI_DPTI_H
#define AXI_DPTI_H
#ifdef __cplusplus
extern "C" {
#endif
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define DPTI_LENGTH_REG_OFFSET 0
#define DPTI_CONTROL_REG_OFFSET 4
#define DPTI_STATUS_REG_OFFSET 8
#define DPTI_TO_STREAM 2
#define STREAM_TO_DPTI 1
#define DPTI_CR_RESET_MASK (1<<2)
#define DPTI_SR_REINIT_MASK (1<<1)
#define DPTI_SR_TX_LEN_EMPTY_MASK (1<<0)
#define DPTI_SR_RX_LEN_EMPTY_MASK (1<<16)
/************************** Function Prototypes ****************************/
XStatus DPTI_SimpleTransfer (u32 BaseAddress, u8 Direction, u32 TransferLength);
XStatus AXI_DPTI_Reg_SelfTest(u32 baseaddr);
XStatus DPTI_Reset(u32 BaseAddress);
#ifdef __cplusplus
}
#endif
#endif // AXI_DPTI_H
/******************************************************************************
* @file AXI_DPTI.h
* AXI DPTI header.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI definitions and prototypes function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
*
* </pre>
*
*****************************************************************************/
#ifndef AXI_DPTI_H
#define AXI_DPTI_H
#ifdef __cplusplus
extern "C" {
#endif
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define DPTI_LENGTH_REG_OFFSET 0
#define DPTI_CONTROL_REG_OFFSET 4
#define DPTI_STATUS_REG_OFFSET 8
#define DPTI_TO_STREAM 2
#define STREAM_TO_DPTI 1
#define DPTI_CR_RESET_MASK (1<<2)
#define DPTI_SR_REINIT_MASK (1<<1)
#define DPTI_SR_TX_LEN_EMPTY_MASK (1<<0)
#define DPTI_SR_RX_LEN_EMPTY_MASK (1<<16)
/************************** Function Prototypes ****************************/
XStatus DPTI_SimpleTransfer (u32 BaseAddress, u8 Direction, u32 TransferLength);
XStatus AXI_DPTI_Reg_SelfTest(u32 baseaddr);
XStatus DPTI_Reset(u32 BaseAddress);
#ifdef __cplusplus
}
#endif
#endif // AXI_DPTI_H
@@ -1,114 +1,114 @@
/******************************************************************************
* @file AXI_DPTI_selftest.c
* AXI DPTI selftest.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI selftest function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files *******************************/
#include "AXI_DPTI.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the AXI_DPTIinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus AXI_DPTI_Reg_SelfTest(u32 baseaddr)
{
u32 StsReg, flag_0, flag_16;
// int write_loop_index;
// int read_loop_index;
// int Index;
xil_printf("******************************\n\r");
xil_printf("* User Peripheral Self Test\n\r");
xil_printf("******************************\n\n\r");
/*
* Write to user logic slave module register(s) and read back
*/
xil_printf("User logic slave module test...\n\r");
StsReg = Xil_In32 (baseaddr + DPTI_STATUS_REG_OFFSET);
flag_0 = (StsReg & 0x01);
flag_16 = (StsReg >> 0x10 ) & 0x01;
if(flag_0 == 0 || flag_16 == 0)
{
xil_printf ("Error reading register value at address %x\n", (int)baseaddr + DPTI_STATUS_REG_OFFSET);
return XST_FAILURE;
}
xil_printf(" - slave register write/read passed\n\n\r");
return XST_SUCCESS;
}
/******************************************************************************
* @file AXI_DPTI_selftest.c
* AXI DPTI selftest.
*
* @author Sergiu Arpadi
*
* @date 2016-Sep-20
*
* @copyright
* (c) 2016 Copyright Digilent Incorporated
* All Rights Reserved
*
* This program is free software; distributed under the terms of BSD 3-clause
* license ("Revised BSD License", "New BSD License", or "Modified BSD License")
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @desciption
* Contains AXI DPTI selftest function.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------------- ------------ -----------------------------------------------
* 1.00 Sergiu Arpadi 2016-Sep-20 First release
*
* </pre>
*
*****************************************************************************/
/***************************** Include Files *******************************/
#include "AXI_DPTI.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the AXI_DPTIinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus AXI_DPTI_Reg_SelfTest(u32 baseaddr)
{
u32 StsReg, flag_0, flag_16;
// int write_loop_index;
// int read_loop_index;
// int Index;
xil_printf("******************************\n\r");
xil_printf("* User Peripheral Self Test\n\r");
xil_printf("******************************\n\n\r");
/*
* Write to user logic slave module register(s) and read back
*/
xil_printf("User logic slave module test...\n\r");
StsReg = Xil_In32 (baseaddr + DPTI_STATUS_REG_OFFSET);
flag_0 = (StsReg & 0x01);
flag_16 = (StsReg >> 0x10 ) & 0x01;
if(flag_0 == 0 || flag_16 == 0)
{
xil_printf ("Error reading register value at address %x\n", (int)baseaddr + DPTI_STATUS_REG_OFFSET);
return XST_FAILURE;
}
xil_printf(" - slave register write/read passed\n\n\r");
return XST_SUCCESS;
}
@@ -1,2 +1,2 @@
#create_clock -period 10.000 [get_ports m_axis_aclk]
#create_clock -period 10.000 [get_ports m_axis_aclk]
#create_clock -period 10.000 [get_ports s_axis_aclk]
@@ -1,191 +1,191 @@
------------------------------------------------------------------------------
--
-- File: AXI_S_to_DPTI_converter.vhd
-- Author: Sergiu Arpadi
-- Original Project: AXI DPTI
-- Date: 8 June 2016
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module reads data from the AXI STREAM interface and sends it to the DPTI
-- interface. It will require a 32 bit TDATA bus, 4 bit TKEEP, TVALID and TLAST
-- as inputs and it will output the TREADY signal. It uses the DPTI clock of 60 MHz
-- to perform all the operations and it will use the maximum bandwidth of the DPTI
-- interface which is 480 mbps as long as valid data is received from the AXI STREAM
-- interface. In order to achieve this, FOR loops have been used which will generate
-- combinational logic that allows the simultaneous verification of all of the 4 TKEEP
-- bits received. Along with the DPTI clock, the module also reads the PROG_TXEN
-- signal and it will generate the PROG_D bus and PROG_WRN signal. In order to control
-- the module, two AXI Lite registers are used, one for direction/control and one for
-- the lenght of the transfer, which are synchronized in the top module.
-- The module also uses a reset signal aResetTx which is generated in the top module.
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.std_logic_arith.all;
entity AXI_S_to_DPTI_converter is
Port (
-- clock, reset and DPTI signals
pResetnTx : in std_logic;
PROG_CLK : in std_logic;
pTxe : in std_logic;
pWr : out std_logic;
pDataOut : out std_logic_vector (7 downto 0);
-- AXI Stream signals
pOutTready : out std_logic;
pInTdata : in std_logic_vector (31 downto 0);
pInTvalid : in std_logic;
pInTlast : in std_logic;
pInTkeep : in std_logic_vector (3 downto 0);
-- AXI Lite registers
pAXI_L_Length : in std_logic_vector (31 downto 0);
pOvalidLength : in std_logic;
pAXI_L_Control : in std_logic_vector (31 downto 0);
pOvalidControl : in std_logic;
pTxLengthEmpty : out std_logic
);
end AXI_S_to_DPTI_converter;
architecture Behavioral of AXI_S_to_DPTI_converter is
--------------------------------------------------------------------------------------------------------------------------
signal pTxEnDir : std_logic := '0';
signal pLengthTxCnt : std_logic_vector (22 downto 0) := (others => '0');
signal Index : integer range 0 to 3;
signal pCtlOutTready : std_logic := '0';
signal pCtlWr : std_logic := '1';
signal pTransferInvalidFlag : std_logic := '1';
signal pAuxTdata : std_logic_vector(31 downto 0);
signal pAuxTkeep : std_logic_vector(3 downto 0) := (others => '0');
--------------------------------------------------------------------------------------------------------------------------
begin
--------------------------------------------------------------------------------------------------------------------------
pWr <= pCtlWr;
pOutTready <= pCtlOutTready;
--------------------------------------------------------------------------------------------------------------------------
pTxLengthEmpty <= '1' when pLengthTxCnt = 0 else '0'; -- we check to see if we are currently doing a tranfer. this will be a part of the AXI Lite status register
-- Generating TREADY signal which will request data from the AXI STREAM interface
pCtlOutTready <= '1' when (pAuxTkeep = "0001" or pAuxTkeep = "0010" or pAuxTkeep = "0100" or pAuxTkeep = "1000" or (pAuxTkeep = "0000" )) and pTxe = '0' and pLengthTxCnt > 0 else '0';
-- new data will be requested when we have at most one valid data byte in the current TDATA bus. other conditions are that a transfer must be in progress and the DPTI interface can accept more data
pTransferInvalidFlag <= '1' when pTxe = '1' and pCtlWr = '0' else '0'; -- detecting if a transfer has failed because the FT_TXE signal from FTDI was '1'
--------------------------------------------------------------------------------------------------------------------------
generate_WR: process (PROG_CLK, pLengthTxCnt, pResetnTx) -- PROG_WRN is generated
begin
if pResetnTx = '0' then
pCtlWr <= '1';
else if rising_edge (PROG_CLK) then
if pAuxTkeep /= 0 and pLengthTxCnt > 0 then -- check if the transfer is not finnished and there is at least one valid data byte
pCtlWr <= '0'; -- when the signal is 0 then the byte currently on the PROG_D bus is valid
else -- if valid data is not available or the transfer is completed
pCtlWr <= '1'; -- PROG_WRN is '1'
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
read_Tkeep_and_Tdata: process (PROG_CLK, pResetnTx)
variable aux_tkindex : integer;
begin
if pResetnTx = '0' then
aux_tkindex := 0;
pAuxTkeep <= (others => '0');
pAuxTdata <= (others => '0');
else if rising_edge(PROG_CLK)then
if pLengthTxCnt > 0 and pTxe = '0' and pTxEnDir = '1' then -- check to see if a transfer is in progress
if (pAuxTkeep = 0 or pAuxTkeep = 1 or pAuxTkeep = 2 or pAuxTkeep = 4 or pAuxTkeep = 8) and pInTvalid = '1' then -- check if the current set of TDATA and TKEEP contains at most one valid byte of data
pAuxTkeep <= pInTkeep; --new tkeep is read
pAuxTdata <= pInTdata; --new data is read
-- TDATA and TKEEP are used in the "generate_pDataOut" process below
else -- if more than one valid bytes exist
for Index in 3 downto 0 loop -- we use a FOR loop to check all of the bytes simultaneously
if pAuxTkeep (Index) = '1' then -- each valid byte is identified by checking TKEEP
aux_tkindex := Index;
end if;
end loop;
pAuxTkeep(aux_tkindex) <= '0'; --reset one bit at a time after sending the corresponding valid byte to the DPTI interface
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pDataOut: process (PROG_CLK, pResetnTx)
begin
if pResetnTx = '0' then
pDataOut <= (others => '0');
pLengthTxCnt <= (others=>'0');
else if rising_edge(PROG_CLK) then
if pOvalidControl = '1' and pLengthTxCnt = 0 then -- the control bit (and the direction) can only be changed when the module is idle
pTxEnDir <= pAXI_L_Control(0); -- Reading control byte from AXI LITE register. Bit (0) sets the transfer's direction.
end if;
if pOvalidLength = '1' and pTxEnDir = '1' then -- checking if the module was enabled and if valid value is present in register
pLengthTxCnt (22 downto 0) <= pAXI_L_Length(22 downto 0); -- LENGTH register is read
end if;
if pLengthTxCnt > 0 and pTxe = '0' and pTxEnDir = '1' then -- conditions for starting transfer
for Index in 3 downto 0 loop -- the FOR loop allows us to check all of the bytes simultaneously
if pAuxTkeep (Index) = '1' then -- we identify the valid byte's position
pDataOut(7 downto 0) <= pAuxTdata((8 * (Index + 1)) -1 downto (8 * (Index))); -- the valid byte is extracted and sent to the DPTI interface
pLengthTxCnt <= pLengthTxCnt - '1'; -- since one valid byte was transferred, length is decremented
end if;
end loop;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
end Behavioral;
------------------------------------------------------------------------------
--
-- File: AXI_S_to_DPTI_converter.vhd
-- Author: Sergiu Arpadi
-- Original Project: AXI DPTI
-- Date: 8 June 2016
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module reads data from the AXI STREAM interface and sends it to the DPTI
-- interface. It will require a 32 bit TDATA bus, 4 bit TKEEP, TVALID and TLAST
-- as inputs and it will output the TREADY signal. It uses the DPTI clock of 60 MHz
-- to perform all the operations and it will use the maximum bandwidth of the DPTI
-- interface which is 480 mbps as long as valid data is received from the AXI STREAM
-- interface. In order to achieve this, FOR loops have been used which will generate
-- combinational logic that allows the simultaneous verification of all of the 4 TKEEP
-- bits received. Along with the DPTI clock, the module also reads the PROG_TXEN
-- signal and it will generate the PROG_D bus and PROG_WRN signal. In order to control
-- the module, two AXI Lite registers are used, one for direction/control and one for
-- the lenght of the transfer, which are synchronized in the top module.
-- The module also uses a reset signal aResetTx which is generated in the top module.
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.std_logic_arith.all;
entity AXI_S_to_DPTI_converter is
Port (
-- clock, reset and DPTI signals
pResetnTx : in std_logic;
PROG_CLK : in std_logic;
pTxe : in std_logic;
pWr : out std_logic;
pDataOut : out std_logic_vector (7 downto 0);
-- AXI Stream signals
pOutTready : out std_logic;
pInTdata : in std_logic_vector (31 downto 0);
pInTvalid : in std_logic;
pInTlast : in std_logic;
pInTkeep : in std_logic_vector (3 downto 0);
-- AXI Lite registers
pAXI_L_Length : in std_logic_vector (31 downto 0);
pOvalidLength : in std_logic;
pAXI_L_Control : in std_logic_vector (31 downto 0);
pOvalidControl : in std_logic;
pTxLengthEmpty : out std_logic
);
end AXI_S_to_DPTI_converter;
architecture Behavioral of AXI_S_to_DPTI_converter is
--------------------------------------------------------------------------------------------------------------------------
signal pTxEnDir : std_logic := '0';
signal pLengthTxCnt : std_logic_vector (22 downto 0) := (others => '0');
signal Index : integer range 0 to 3;
signal pCtlOutTready : std_logic := '0';
signal pCtlWr : std_logic := '1';
signal pTransferInvalidFlag : std_logic := '1';
signal pAuxTdata : std_logic_vector(31 downto 0);
signal pAuxTkeep : std_logic_vector(3 downto 0) := (others => '0');
--------------------------------------------------------------------------------------------------------------------------
begin
--------------------------------------------------------------------------------------------------------------------------
pWr <= pCtlWr;
pOutTready <= pCtlOutTready;
--------------------------------------------------------------------------------------------------------------------------
pTxLengthEmpty <= '1' when pLengthTxCnt = 0 else '0'; -- we check to see if we are currently doing a tranfer. this will be a part of the AXI Lite status register
-- Generating TREADY signal which will request data from the AXI STREAM interface
pCtlOutTready <= '1' when (pAuxTkeep = "0001" or pAuxTkeep = "0010" or pAuxTkeep = "0100" or pAuxTkeep = "1000" or (pAuxTkeep = "0000" )) and pTxe = '0' and pLengthTxCnt > 0 else '0';
-- new data will be requested when we have at most one valid data byte in the current TDATA bus. other conditions are that a transfer must be in progress and the DPTI interface can accept more data
pTransferInvalidFlag <= '1' when pTxe = '1' and pCtlWr = '0' else '0'; -- detecting if a transfer has failed because the FT_TXE signal from FTDI was '1'
--------------------------------------------------------------------------------------------------------------------------
generate_WR: process (PROG_CLK, pLengthTxCnt, pResetnTx) -- PROG_WRN is generated
begin
if pResetnTx = '0' then
pCtlWr <= '1';
else if rising_edge (PROG_CLK) then
if pAuxTkeep /= 0 and pLengthTxCnt > 0 then -- check if the transfer is not finnished and there is at least one valid data byte
pCtlWr <= '0'; -- when the signal is 0 then the byte currently on the PROG_D bus is valid
else -- if valid data is not available or the transfer is completed
pCtlWr <= '1'; -- PROG_WRN is '1'
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
read_Tkeep_and_Tdata: process (PROG_CLK, pResetnTx)
variable aux_tkindex : integer;
begin
if pResetnTx = '0' then
aux_tkindex := 0;
pAuxTkeep <= (others => '0');
pAuxTdata <= (others => '0');
else if rising_edge(PROG_CLK)then
if pLengthTxCnt > 0 and pTxe = '0' and pTxEnDir = '1' then -- check to see if a transfer is in progress
if (pAuxTkeep = 0 or pAuxTkeep = 1 or pAuxTkeep = 2 or pAuxTkeep = 4 or pAuxTkeep = 8) and pInTvalid = '1' then -- check if the current set of TDATA and TKEEP contains at most one valid byte of data
pAuxTkeep <= pInTkeep; --new tkeep is read
pAuxTdata <= pInTdata; --new data is read
-- TDATA and TKEEP are used in the "generate_pDataOut" process below
else -- if more than one valid bytes exist
for Index in 3 downto 0 loop -- we use a FOR loop to check all of the bytes simultaneously
if pAuxTkeep (Index) = '1' then -- each valid byte is identified by checking TKEEP
aux_tkindex := Index;
end if;
end loop;
pAuxTkeep(aux_tkindex) <= '0'; --reset one bit at a time after sending the corresponding valid byte to the DPTI interface
end if;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pDataOut: process (PROG_CLK, pResetnTx)
begin
if pResetnTx = '0' then
pDataOut <= (others => '0');
pLengthTxCnt <= (others=>'0');
else if rising_edge(PROG_CLK) then
if pOvalidControl = '1' and pLengthTxCnt = 0 then -- the control bit (and the direction) can only be changed when the module is idle
pTxEnDir <= pAXI_L_Control(0); -- Reading control byte from AXI LITE register. Bit (0) sets the transfer's direction.
end if;
if pOvalidLength = '1' and pTxEnDir = '1' then -- checking if the module was enabled and if valid value is present in register
pLengthTxCnt (22 downto 0) <= pAXI_L_Length(22 downto 0); -- LENGTH register is read
end if;
if pLengthTxCnt > 0 and pTxe = '0' and pTxEnDir = '1' then -- conditions for starting transfer
for Index in 3 downto 0 loop -- the FOR loop allows us to check all of the bytes simultaneously
if pAuxTkeep (Index) = '1' then -- we identify the valid byte's position
pDataOut(7 downto 0) <= pAuxTdata((8 * (Index + 1)) -1 downto (8 * (Index))); -- the valid byte is extracted and sent to the DPTI interface
pLengthTxCnt <= pLengthTxCnt - '1'; -- since one valid byte was transferred, length is decremented
end if;
end loop;
end if;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
end Behavioral;
@@ -1,237 +1,237 @@
------------------------------------------------------------------------------
--
-- File: DPTI_to_AXI_S_converter.vhd
-- Author: Sergiu Arpadi
-- Original Project: AXI DPTI
-- Date: 8 June 2016
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module reads data from the DPTI interface and converts it so that it is
-- compatible with the AXI STREAM interface. Along with 32 bit TDATA, it also generates
-- the 4 bit TKEEP, TVALID and TLAST, using TREADY as an input. On the DPTI side,
-- it uses the interface clock PROG_CLK, it reads data from pDataIn and uses pRxf
-- to identify valid data and it generates the output enable pOe signal and pRd which
-- requests more data. All these ports will be connected to the DPTI ports in the top.
-- The pDataIn bus will also pass through an IOBUF controlled by pOe. The converter works
-- by reading a data byte fron the DPTI, it then determines if the data is valid,
-- and if it is, it then uses it to create the TDATA bus and the TKEEP bus. The module
-- will wait until it has 4 valid bytes in order to avoid sending incomplete transfers,
-- except for the last transfer which can be incomplete due to the nature of the length
-- which is requested (if the number is not divisible by 4). When a transfer is prepared,
-- the TVALID signal is generated which acomplishes the actual transfer along with the
-- TLAST signal when the transfer is the last one. During this time, it monitors the
-- TREADY signal as well as pRxf signal coming from the DPTI interface. In order to
-- control the module, two AXI Lite registers are used, one for direction/control and
-- one for the lenght of the transfer, which are synchronized in the top module.
-- The module also uses a reset signal aResetRx which is generated in the top module.
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.std_logic_arith.all;
entity DPTI_to_AXI_S_converter is
Port (
-- clock, reset and DPTI signals
pResetnRx : in std_logic;
PROG_CLK : in std_logic;
pRxf : in std_logic;
pRd : out std_logic;
pOe : out std_logic;
pDataIn : in std_logic_vector (7 downto 0);
-- AXI Stream signals
pInTready : in std_logic;
pOutTdata : out std_logic_vector (31 downto 0);
pOutTvalid : out std_logic;
pOutTlast : out std_logic;
pOutTkeep : out std_logic_vector (3 downto 0);
-- AXI Lite registers
pAXI_L_Length : in std_logic_vector (31 downto 0);
pOvalidLength : in std_logic;
pAXI_L_Control : in std_logic_vector (31 downto 0);
pOvalidControl : in std_logic;
pRxLengthEmpty : out std_logic
);
end DPTI_to_AXI_S_converter;
architecture Behavioral of DPTI_to_AXI_S_converter is
--------------------------------------------------------------------------------------------------------------------------
signal Index: integer range 0 to 3;
signal pCountSentBytes : std_logic_vector (1 downto 0);
signal pCountBytesIncrFlag : std_logic := '1';
signal pRxEnDir : std_logic := '0';
signal pLengthRxCnt : std_logic_vector (23 downto 0);
signal pCtlRd : std_logic := '1';
signal pCtlOutTvalid : std_logic := '0';
signal pCtlOutTlast : std_logic := '0';
signal pLengthRxCntDepletedFlag : std_logic := '0';
signal pAuxLengthRxDecrFlag : std_logic := '0';
signal pLastTransferFlag : std_logic := '0';
signal pRxfDelay : std_logic := '1';
--------------------------------------------------------------------------------------------------------------------------
begin
--------------------------------------------------------------------------------------------------------------------------
pOutTlast <= pCtlOutTlast;
pOutTvalid <= pCtlOutTvalid;
pOe <= not pRxEnDir ;
pRd <= pCtlRd;
pCtlOutTvalid <= '1' when pCountSentBytes = 0 and pCountBytesIncrFlag = '0' else '0'; -- TVALID signal is generated
-- pCountSentBytes = 0 - allows TVALID to be '1' only after 4 valid data bytes have been processed
-- pCountBytesIncrFlag = '0' - This signal will ensure that the TVALID signal is high for only one Clock period. It checks if the current byte is valid or not. The counter will only increment when the data byte is valid.
pCtlOutTlast <= '1' when pCountSentBytes = 0 and pCountBytesIncrFlag = '0' and pLengthRxCnt < 4 else '0'; -- TLAST signal is generated
-- TLAST is very similar to TVALID however it must only be asserted at the end of the last AXI STREAM transfer. In order to accomplish this, pLengthRxCnt must be less than 4 (no more than 4 bytes left to transfer) so that only one more STREAM transfer is needed.
pCtlRd <= '0' when pLastTransferFlag = '0' and pInTready = '1' and pRxfDelay = '0' else '1'; -- PROG_RDN is generated
-- the signal must be 0 only when TREADY (input) is '1' since that means that the STREAM interface is ready for at least one extra set of data since the date currently being read will be transfered in the next AXI STREAM transfer
-- pLastTransferFlag indicatges that only one more transfer will be required. Once this signal is '1' this indicates that there is no more data required for the dpti to stream transfer
-- pRxfDelay will mirror the PROG_RXEN signal received from the DPTI interface. when the FTDI empties its internal FIFO, it will drive PROG_RXEN high and even if the FPGA can still receive data, PROG_RDN must be driven high, otherwise the FTDI will provide the wrong data when PROG_RXEN becomes '0'
pLastTransferFlag <= '1' when pLengthRxCnt < 4 else '0'; -- This signal will indicate when the module has reached the last AXI Stream transfer. If there are less than 4 bytes left to be transfered
-- this signal is used to determine when there is only one STREAM transfer left
pRxLengthEmpty <= '1' when pLengthRxCnt = 0 else '0'; -- this signal (used by driver) will indicate the status of the module. when high, the module is ready to do another transfer
--------------------------------------------------------------------------------------------------------------------------
generate_pRxfDelay: process(PROG_CLK) -- the signal pRxfDelay will be identical to PROG_RXEN delayed by one clock period which will then become the PROG_RDN signal.
begin
if rising_edge (PROG_CLK) then
if pRxf = '1' then
pRxfDelay <= '1';
else
pRxfDelay <= '0';
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pCountSentBytes: process (PROG_CLK, pResetnRx) -- this counter will increment when a valid byte was read from the DPTI interface and processed
begin
if pResetnRx = '0' then
pCountSentBytes <= (others => '0');
pCountBytesIncrFlag <= '1';
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 0 and ((pRxf = '0' and pRxfDelay = '0') or pLastTransferFlag = '1') and pInTready = '1' then -- check if a transfer is in progress and all the conditions are in place to read and process a byte
pCountSentBytes <= pCountSentBytes + '1'; -- the counter is incremented
pCountBytesIncrFlag <= '0'; -- the flag which indicates a change in the counter's value
elsif pLengthRxCnt = 0 then -- if a transfer was completed
pCountSentBytes <= (others => '0'); -- counter is reset
pCountBytesIncrFlag <= '1'; -- flag is set
else
pCountSentBytes <= pCountSentBytes; -- when a transfer is in progress and conditions for a valid byte to be processed are not met
pCountBytesIncrFlag <= '1'; -- flag is set
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_Index: process (PROG_CLK, pResetnRx) -- the Index integer is used for positioning the individual bytes in the 4 byte TDATA register
begin
if pResetnRx = '0' then
Index <= 0;
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 0 and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- in order to increment Index, the data provided must be valid and the receivind FIFO must not be full
if Index < 3 then -- index will have values between 0 and 3
Index <= Index + 1; -- when conditions are met, index is incremented
else
Index <= 0;
end if;
elsif pLengthRxCnt = 0 then -- when a transfer is completed, Index becomes 0
Index <= 0;
else
Index <= Index;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pOutTdata: process (PROG_CLK, pResetnRx, Index, pLengthRxCnt) is -- TDATA is generated from data received from the DPTI interface
begin
if (pResetnRx = '0') then
pOutTdata <= (others => '0');
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 3 and pRxEnDir = '1' and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- conditions for data to be considered valid
pOutTdata(( 8 * (Index + 1)) - 1 downto ( 8 * (Index))) <= pDataIn(7 downto 0); -- TDATA bus is being built. the new byte's position is determined by the value of Index
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
gen_pOutTkeep_read_AXI_Lite_registers: process (PROG_CLK, pResetnRx, Index, pLengthRxCnt) is -- reading the AXI Lite registers, controlling the main counters, generating TKEEP
begin
if (pResetnRx = '0') then
pLengthRxCnt <= (others => '0');
elsif rising_edge(PROG_CLK) then
if pOvalidControl = '1' and pLengthRxCnt = 0 then -- the control bit (and the direction) can only be changed when the module is idle
pRxEnDir <= pAXI_L_Control (1); -- Reading control byte from AXI LITE register. Bit (1) sets the transfer's direction.
end if;
if pOvalidLength = '1' and pRxEnDir = '1' then -- checking if the module was enabled and if valid value is present in the LENGTH register
pLengthRxCnt (23 downto 0) <= pAXI_L_Length(23 downto 0) + "11"; -- The counter will be the requested transfer length + 3 so that after all of the valid bytes are received and processed, there will be 3 more clock periods where it will decrement which will allow us to generate the signals required to send the last STREAM transfer, especially TLAST.
end if;
if pLengthRxCnt > 0 and (pLastTransferFlag = '1' or (pRxf = '0' and pRxfDelay = '0' and pInTready = '1')) then -- here the module checks if the byte received is valid or if we are going to send the last STREAM package
pLengthRxCnt <= pLengthRxCnt - '1'; -- the counter is decremented.
end if;
if pLengthRxCnt > 3 and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- check when a valid byte has been read from the DPTI interface
pOutTkeep (Index) <= '1'; -- the TKEEP bit of the byte sent to AXI STREAM in the "generate_pOutTdata" process is set
else
pOutTkeep (Index) <= '0'; -- if the byte is not valid, the bit will be '0'
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
end Behavioral;
------------------------------------------------------------------------------
--
-- File: DPTI_to_AXI_S_converter.vhd
-- Author: Sergiu Arpadi
-- Original Project: AXI DPTI
-- Date: 8 June 2016
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module reads data from the DPTI interface and converts it so that it is
-- compatible with the AXI STREAM interface. Along with 32 bit TDATA, it also generates
-- the 4 bit TKEEP, TVALID and TLAST, using TREADY as an input. On the DPTI side,
-- it uses the interface clock PROG_CLK, it reads data from pDataIn and uses pRxf
-- to identify valid data and it generates the output enable pOe signal and pRd which
-- requests more data. All these ports will be connected to the DPTI ports in the top.
-- The pDataIn bus will also pass through an IOBUF controlled by pOe. The converter works
-- by reading a data byte fron the DPTI, it then determines if the data is valid,
-- and if it is, it then uses it to create the TDATA bus and the TKEEP bus. The module
-- will wait until it has 4 valid bytes in order to avoid sending incomplete transfers,
-- except for the last transfer which can be incomplete due to the nature of the length
-- which is requested (if the number is not divisible by 4). When a transfer is prepared,
-- the TVALID signal is generated which acomplishes the actual transfer along with the
-- TLAST signal when the transfer is the last one. During this time, it monitors the
-- TREADY signal as well as pRxf signal coming from the DPTI interface. In order to
-- control the module, two AXI Lite registers are used, one for direction/control and
-- one for the lenght of the transfer, which are synchronized in the top module.
-- The module also uses a reset signal aResetRx which is generated in the top module.
-------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.std_logic_arith.all;
entity DPTI_to_AXI_S_converter is
Port (
-- clock, reset and DPTI signals
pResetnRx : in std_logic;
PROG_CLK : in std_logic;
pRxf : in std_logic;
pRd : out std_logic;
pOe : out std_logic;
pDataIn : in std_logic_vector (7 downto 0);
-- AXI Stream signals
pInTready : in std_logic;
pOutTdata : out std_logic_vector (31 downto 0);
pOutTvalid : out std_logic;
pOutTlast : out std_logic;
pOutTkeep : out std_logic_vector (3 downto 0);
-- AXI Lite registers
pAXI_L_Length : in std_logic_vector (31 downto 0);
pOvalidLength : in std_logic;
pAXI_L_Control : in std_logic_vector (31 downto 0);
pOvalidControl : in std_logic;
pRxLengthEmpty : out std_logic
);
end DPTI_to_AXI_S_converter;
architecture Behavioral of DPTI_to_AXI_S_converter is
--------------------------------------------------------------------------------------------------------------------------
signal Index: integer range 0 to 3;
signal pCountSentBytes : std_logic_vector (1 downto 0);
signal pCountBytesIncrFlag : std_logic := '1';
signal pRxEnDir : std_logic := '0';
signal pLengthRxCnt : std_logic_vector (23 downto 0);
signal pCtlRd : std_logic := '1';
signal pCtlOutTvalid : std_logic := '0';
signal pCtlOutTlast : std_logic := '0';
signal pLengthRxCntDepletedFlag : std_logic := '0';
signal pAuxLengthRxDecrFlag : std_logic := '0';
signal pLastTransferFlag : std_logic := '0';
signal pRxfDelay : std_logic := '1';
--------------------------------------------------------------------------------------------------------------------------
begin
--------------------------------------------------------------------------------------------------------------------------
pOutTlast <= pCtlOutTlast;
pOutTvalid <= pCtlOutTvalid;
pOe <= not pRxEnDir ;
pRd <= pCtlRd;
pCtlOutTvalid <= '1' when pCountSentBytes = 0 and pCountBytesIncrFlag = '0' else '0'; -- TVALID signal is generated
-- pCountSentBytes = 0 - allows TVALID to be '1' only after 4 valid data bytes have been processed
-- pCountBytesIncrFlag = '0' - This signal will ensure that the TVALID signal is high for only one Clock period. It checks if the current byte is valid or not. The counter will only increment when the data byte is valid.
pCtlOutTlast <= '1' when pCountSentBytes = 0 and pCountBytesIncrFlag = '0' and pLengthRxCnt < 4 else '0'; -- TLAST signal is generated
-- TLAST is very similar to TVALID however it must only be asserted at the end of the last AXI STREAM transfer. In order to accomplish this, pLengthRxCnt must be less than 4 (no more than 4 bytes left to transfer) so that only one more STREAM transfer is needed.
pCtlRd <= '0' when pLastTransferFlag = '0' and pInTready = '1' and pRxfDelay = '0' else '1'; -- PROG_RDN is generated
-- the signal must be 0 only when TREADY (input) is '1' since that means that the STREAM interface is ready for at least one extra set of data since the date currently being read will be transfered in the next AXI STREAM transfer
-- pLastTransferFlag indicatges that only one more transfer will be required. Once this signal is '1' this indicates that there is no more data required for the dpti to stream transfer
-- pRxfDelay will mirror the PROG_RXEN signal received from the DPTI interface. when the FTDI empties its internal FIFO, it will drive PROG_RXEN high and even if the FPGA can still receive data, PROG_RDN must be driven high, otherwise the FTDI will provide the wrong data when PROG_RXEN becomes '0'
pLastTransferFlag <= '1' when pLengthRxCnt < 4 else '0'; -- This signal will indicate when the module has reached the last AXI Stream transfer. If there are less than 4 bytes left to be transfered
-- this signal is used to determine when there is only one STREAM transfer left
pRxLengthEmpty <= '1' when pLengthRxCnt = 0 else '0'; -- this signal (used by driver) will indicate the status of the module. when high, the module is ready to do another transfer
--------------------------------------------------------------------------------------------------------------------------
generate_pRxfDelay: process(PROG_CLK) -- the signal pRxfDelay will be identical to PROG_RXEN delayed by one clock period which will then become the PROG_RDN signal.
begin
if rising_edge (PROG_CLK) then
if pRxf = '1' then
pRxfDelay <= '1';
else
pRxfDelay <= '0';
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pCountSentBytes: process (PROG_CLK, pResetnRx) -- this counter will increment when a valid byte was read from the DPTI interface and processed
begin
if pResetnRx = '0' then
pCountSentBytes <= (others => '0');
pCountBytesIncrFlag <= '1';
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 0 and ((pRxf = '0' and pRxfDelay = '0') or pLastTransferFlag = '1') and pInTready = '1' then -- check if a transfer is in progress and all the conditions are in place to read and process a byte
pCountSentBytes <= pCountSentBytes + '1'; -- the counter is incremented
pCountBytesIncrFlag <= '0'; -- the flag which indicates a change in the counter's value
elsif pLengthRxCnt = 0 then -- if a transfer was completed
pCountSentBytes <= (others => '0'); -- counter is reset
pCountBytesIncrFlag <= '1'; -- flag is set
else
pCountSentBytes <= pCountSentBytes; -- when a transfer is in progress and conditions for a valid byte to be processed are not met
pCountBytesIncrFlag <= '1'; -- flag is set
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_Index: process (PROG_CLK, pResetnRx) -- the Index integer is used for positioning the individual bytes in the 4 byte TDATA register
begin
if pResetnRx = '0' then
Index <= 0;
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 0 and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- in order to increment Index, the data provided must be valid and the receivind FIFO must not be full
if Index < 3 then -- index will have values between 0 and 3
Index <= Index + 1; -- when conditions are met, index is incremented
else
Index <= 0;
end if;
elsif pLengthRxCnt = 0 then -- when a transfer is completed, Index becomes 0
Index <= 0;
else
Index <= Index;
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
generate_pOutTdata: process (PROG_CLK, pResetnRx, Index, pLengthRxCnt) is -- TDATA is generated from data received from the DPTI interface
begin
if (pResetnRx = '0') then
pOutTdata <= (others => '0');
elsif rising_edge(PROG_CLK) then
if pLengthRxCnt > 3 and pRxEnDir = '1' and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- conditions for data to be considered valid
pOutTdata(( 8 * (Index + 1)) - 1 downto ( 8 * (Index))) <= pDataIn(7 downto 0); -- TDATA bus is being built. the new byte's position is determined by the value of Index
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
gen_pOutTkeep_read_AXI_Lite_registers: process (PROG_CLK, pResetnRx, Index, pLengthRxCnt) is -- reading the AXI Lite registers, controlling the main counters, generating TKEEP
begin
if (pResetnRx = '0') then
pLengthRxCnt <= (others => '0');
elsif rising_edge(PROG_CLK) then
if pOvalidControl = '1' and pLengthRxCnt = 0 then -- the control bit (and the direction) can only be changed when the module is idle
pRxEnDir <= pAXI_L_Control (1); -- Reading control byte from AXI LITE register. Bit (1) sets the transfer's direction.
end if;
if pOvalidLength = '1' and pRxEnDir = '1' then -- checking if the module was enabled and if valid value is present in the LENGTH register
pLengthRxCnt (23 downto 0) <= pAXI_L_Length(23 downto 0) + "11"; -- The counter will be the requested transfer length + 3 so that after all of the valid bytes are received and processed, there will be 3 more clock periods where it will decrement which will allow us to generate the signals required to send the last STREAM transfer, especially TLAST.
end if;
if pLengthRxCnt > 0 and (pLastTransferFlag = '1' or (pRxf = '0' and pRxfDelay = '0' and pInTready = '1')) then -- here the module checks if the byte received is valid or if we are going to send the last STREAM package
pLengthRxCnt <= pLengthRxCnt - '1'; -- the counter is decremented.
end if;
if pLengthRxCnt > 3 and pRxf = '0' and pRxfDelay = '0' and pInTready = '1' then -- check when a valid byte has been read from the DPTI interface
pOutTkeep (Index) <= '1'; -- the TKEEP bit of the byte sent to AXI STREAM in the "generate_pOutTdata" process is set
else
pOutTkeep (Index) <= '0'; -- if the byte is not valid, the bit will be '0'
end if;
end if;
end process;
--------------------------------------------------------------------------------------------------------------------------
end Behavioral;
@@ -1,194 +1,194 @@
------------------------------------------------------------------------------
--
-- File: HandshakeData.vhd
-- Author: Elod Gyorgy
-- Original Project: Atlys2 User Demo
-- Date: 29 June 20116
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module passes parallel data from the input clock domain (InClk) to the
-- output clock domain (OutClk) by the means of handshake signals. A
-- low-to-high transition on iPush will register iData inside the module
-- and will start propagating the handshake signals towards the output domain.
-- The data will appear on oData and is valid when oValid pulses high.
-- The reception of data by the receiver on the OutClk domain is signaled
-- by a pulse on oAck. This will propagate back to the input domain and
-- assert iRdy signaling to the sender that a new data can be pushed though.
-- If oData is always read when oValid pulses, oAck may be tied permanently
-- high.
-- Only assert iPush when iRdy is high!
--
-- Changelog:
-- 2016-Jun-29: Fixed oValid not being a pulse.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity HandshakeData is
Generic (
kDataWidth : natural := 8);
Port (
InClk : in STD_LOGIC;
OutClk : in STD_LOGIC;
iData : in STD_LOGIC_VECTOR (kDataWidth-1 downto 0);
oData : out STD_LOGIC_VECTOR (kDataWidth-1 downto 0);
iPush : in STD_LOGIC;
iRdy : out STD_LOGIC;
oAck : in STD_LOGIC := '1';
oValid : out STD_LOGIC;
aReset : in std_logic);
end HandshakeData;
architecture Behavioral of HandshakeData is
signal iPush_q, iPushRising, iPushT, iPushTBack, iReset : std_logic;
signal iData_int : std_logic_vector(kDataWidth-1 downto 0);
signal oPushT, oPushT_q, oPushTBack, oPushTChanged : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of aReset: signal is "TRUE";
begin
DetectPush: process(aReset, InClk)
begin
if (aReset = '1') then
iPush_q <= '0';
elsif Rising_Edge(InClk) then
iPush_q <= iPush;
end if;
end process DetectPush;
iPushRising <= iPush and not iPush_q;
-- Register data when iPush is rising and toggle internal flag
LatchData: process(aReset, InClk)
begin
if (aReset = '1') then
iData_int <= (others => '0');
iPushT <= '0';
elsif Rising_Edge(InClk) then
if (iPushRising = '1') then
iData_int <= iData;
iPushT <= not iPushT;
end if;
end if;
end process;
-- Cross toggle flag through synchronizer
SyncAsyncPushT: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2)
port map (
aReset => aReset,
aIn => iPushT,
OutClk => OutClk,
oOut => oPushT);
-- Detect a push edge in the OutClk domain
-- If receiver acknowledges receipt, we can propagate the push signal back
-- towards the input, where it will be used to generate iRdy
DetectToggle: process(aReset, OutClk)
begin
if (aReset = '1') then
oPushT_q <= '0';
oPushTBack <= '0';
elsif Rising_Edge(OutClk) then
oPushT_q <= oPushT;
if (oAck = '1') then
oPushTBack <= oPushT_q;
end if;
end if;
end process DetectToggle;
oPushTChanged <= '1' when oPushT_q /= oPushT else '0';
-- Cross data from InClk domain reg (iData_in) to OutClk domain
-- The enable for this register is the propagated and sync'd to the OutClk domain
-- We assume here that the time it took iPush to propagate to oPushTChanged is
-- more than the time it takes iData_int to propagate to the oData register's D pin
OutputData: process (aReset, OutClk)
begin
if (aReset = '1') then
oData <= (others => '0');
oValid <= '0';
elsif Rising_Edge(OutClk) then
if (oPushTChanged = '1') then
oData <= iData_int;
end if;
oValid <= oPushTChanged;
end if;
end process OutputData;
-- Cross toggle flag back through synchronizer
SyncAsyncPushTBack: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2)
port map (
aReset => aReset,
aIn => oPushTBack,
OutClk => InClk,
oOut => iPushTBack);
-- Synchronize aReset into the InClk domain
-- We need it to keep iRdy low, when aReset de-asserts
SyncReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aReset,
OutClk => InClk,
oRst => iReset);
ReadySignal: process(aReset, InClk)
begin
if (aReset = '1') then
iRdy <= '0';
elsif Rising_Edge(InClk) then
iRdy <= not iPush and (iPushTBack xnor iPushT) and not iReset;
end if;
end process ReadySignal;
end Behavioral;
------------------------------------------------------------------------------
--
-- File: HandshakeData.vhd
-- Author: Elod Gyorgy
-- Original Project: Atlys2 User Demo
-- Date: 29 June 20116
--
-------------------------------------------------------------------------------
-- (c) 2016 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module passes parallel data from the input clock domain (InClk) to the
-- output clock domain (OutClk) by the means of handshake signals. A
-- low-to-high transition on iPush will register iData inside the module
-- and will start propagating the handshake signals towards the output domain.
-- The data will appear on oData and is valid when oValid pulses high.
-- The reception of data by the receiver on the OutClk domain is signaled
-- by a pulse on oAck. This will propagate back to the input domain and
-- assert iRdy signaling to the sender that a new data can be pushed though.
-- If oData is always read when oValid pulses, oAck may be tied permanently
-- high.
-- Only assert iPush when iRdy is high!
--
-- Changelog:
-- 2016-Jun-29: Fixed oValid not being a pulse.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity HandshakeData is
Generic (
kDataWidth : natural := 8);
Port (
InClk : in STD_LOGIC;
OutClk : in STD_LOGIC;
iData : in STD_LOGIC_VECTOR (kDataWidth-1 downto 0);
oData : out STD_LOGIC_VECTOR (kDataWidth-1 downto 0);
iPush : in STD_LOGIC;
iRdy : out STD_LOGIC;
oAck : in STD_LOGIC := '1';
oValid : out STD_LOGIC;
aReset : in std_logic);
end HandshakeData;
architecture Behavioral of HandshakeData is
signal iPush_q, iPushRising, iPushT, iPushTBack, iReset : std_logic;
signal iData_int : std_logic_vector(kDataWidth-1 downto 0);
signal oPushT, oPushT_q, oPushTBack, oPushTChanged : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of aReset: signal is "TRUE";
begin
DetectPush: process(aReset, InClk)
begin
if (aReset = '1') then
iPush_q <= '0';
elsif Rising_Edge(InClk) then
iPush_q <= iPush;
end if;
end process DetectPush;
iPushRising <= iPush and not iPush_q;
-- Register data when iPush is rising and toggle internal flag
LatchData: process(aReset, InClk)
begin
if (aReset = '1') then
iData_int <= (others => '0');
iPushT <= '0';
elsif Rising_Edge(InClk) then
if (iPushRising = '1') then
iData_int <= iData;
iPushT <= not iPushT;
end if;
end if;
end process;
-- Cross toggle flag through synchronizer
SyncAsyncPushT: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2)
port map (
aReset => aReset,
aIn => iPushT,
OutClk => OutClk,
oOut => oPushT);
-- Detect a push edge in the OutClk domain
-- If receiver acknowledges receipt, we can propagate the push signal back
-- towards the input, where it will be used to generate iRdy
DetectToggle: process(aReset, OutClk)
begin
if (aReset = '1') then
oPushT_q <= '0';
oPushTBack <= '0';
elsif Rising_Edge(OutClk) then
oPushT_q <= oPushT;
if (oAck = '1') then
oPushTBack <= oPushT_q;
end if;
end if;
end process DetectToggle;
oPushTChanged <= '1' when oPushT_q /= oPushT else '0';
-- Cross data from InClk domain reg (iData_in) to OutClk domain
-- The enable for this register is the propagated and sync'd to the OutClk domain
-- We assume here that the time it took iPush to propagate to oPushTChanged is
-- more than the time it takes iData_int to propagate to the oData register's D pin
OutputData: process (aReset, OutClk)
begin
if (aReset = '1') then
oData <= (others => '0');
oValid <= '0';
elsif Rising_Edge(OutClk) then
if (oPushTChanged = '1') then
oData <= iData_int;
end if;
oValid <= oPushTChanged;
end if;
end process OutputData;
-- Cross toggle flag back through synchronizer
SyncAsyncPushTBack: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2)
port map (
aReset => aReset,
aIn => oPushTBack,
OutClk => InClk,
oOut => iPushTBack);
-- Synchronize aReset into the InClk domain
-- We need it to keep iRdy low, when aReset de-asserts
SyncReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aReset,
OutClk => InClk,
oRst => iReset);
ReadySignal: process(aReset, InClk)
begin
if (aReset = '1') then
iRdy <= '0';
elsif Rising_Edge(InClk) then
iRdy <= not iPush and (iPushTBack xnor iPushT) and not iReset;
end if;
end process ReadySignal;
end Behavioral;
@@ -1,88 +1,88 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 20 October 2014
--
-------------------------------------------------------------------------------
-- (c) 2014 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2); --double sync by default
Port (
aReset : in STD_LOGIC; -- active-high asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = '1') then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 20 October 2014
--
-------------------------------------------------------------------------------
-- (c) 2014 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2); --double sync by default
Port (
aReset : in STD_LOGIC; -- active-high asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = '1') then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
@@ -1,90 +1,90 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 20 October 2014
--
-------------------------------------------------------------------------------
-- (c) 2014 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
signal aRst_int : std_logic;
attribute KEEP : string;
attribute KEEP of aRst_int: signal is "TRUE";
begin
aRst_int <= kPolarity xnor aRst; --SyncAsync uses active-high reset
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2) --use double FF synchronizer
port map (
aReset => aRst_int,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 20 October 2014
--
-------------------------------------------------------------------------------
-- (c) 2014 Copyright Digilent Incorporated
-- All Rights Reserved
--
-- This program is free software; distributed under the terms of BSD 3-clause
-- license ("Revised BSD License", "New BSD License", or "Modified BSD License")
--
-- Redistribution and use in source and binary forms, with or without modification,
-- are permitted provided that the following conditions are met:
--
-- 1. Redistributions of source code must retain the above copyright notice, this
-- list of conditions and the following disclaimer.
-- 2. Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
-- 3. Neither the name(s) of the above-listed copyright holder(s) nor the names
-- of its contributors may be used to endorse or promote products derived
-- from this software without specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
signal aRst_int : std_logic;
attribute KEEP : string;
attribute KEEP of aRst_int: signal is "TRUE";
begin
aRst_int <= kPolarity xnor aRst; --SyncAsync uses active-high reset
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2) --use double FF synchronizer
port map (
aReset => aRst_int,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;
@@ -1,21 +1,21 @@
create_clock -period 16.667 -name prog_clko -waveform {0.000 8.333} [get_ports -prop_thru_buffers prog_clko]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers {prog_d[*]}]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers prog_rxen]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers prog_rxen]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers prog_txen]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers prog_txen]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_oen]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_oen]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_rdn]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_rdn]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_wrn]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_wrn]
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages_reg[*]/D} -hier]
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR} -hier]
set_false_path -through [get_pins -filter {NAME =~ *in_*_sync/*/CLR} -hier]
create_clock -period 16.667 -name prog_clko -waveform {0.000 8.333} [get_ports -prop_thru_buffers prog_clko]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers {prog_d[*]}]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers prog_rxen]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers prog_rxen]
set_input_delay -clock [get_clocks prog_clko] -min -add_delay 1.000 [get_ports -prop_thru_buffers prog_txen]
set_input_delay -clock [get_clocks prog_clko] -max -add_delay 5.517 [get_ports -prop_thru_buffers prog_txen]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers {prog_d[*]}]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_oen]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_oen]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_rdn]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_rdn]
set_output_delay -clock [get_clocks prog_clko] -min -add_delay 0.000 [get_ports -prop_thru_buffers prog_wrn]
set_output_delay -clock [get_clocks prog_clko] -max -add_delay 6.000 [get_ports -prop_thru_buffers prog_wrn]
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages_reg[*]/D} -hier]
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR} -hier]
set_false_path -through [get_pins -filter {NAME =~ *in_*_sync/*/CLR} -hier]
set_false_path -from [get_cells -hier -filter {NAME =~ *in_*_sync/iData_int_reg[*]}] -to [get_cells -hier -filter {NAME=~ *in_*_sync/oData_reg[*]}]
@@ -1,60 +1,60 @@
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
ipgui::add_param $IPINST -name "AXI4_Lite_BASEADDR" -parent ${Page_0}
ipgui::add_param $IPINST -name "AXI4_Lite_HIGHADDR" -parent ${Page_0}
}
proc update_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to update AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to update AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to validate AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to update AXI4_Lite_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to validate AXI4_Lite_BASEADDR
return true
}
proc update_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to update AXI4_Lite_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to validate AXI4_Lite_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_DATA_WIDTH". Setting updated value from the model parameter.
set_property value 32 ${MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_ADDR_WIDTH". Setting updated value from the model parameter.
set_property value 4 ${MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH}
}
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
ipgui::add_param $IPINST -name "AXI4_Lite_BASEADDR" -parent ${Page_0}
ipgui::add_param $IPINST -name "AXI4_Lite_HIGHADDR" -parent ${Page_0}
}
proc update_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to update AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to update AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to validate AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to update AXI4_Lite_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to validate AXI4_Lite_BASEADDR
return true
}
proc update_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to update AXI4_Lite_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to validate AXI4_Lite_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_DATA_WIDTH". Setting updated value from the model parameter.
set_property value 32 ${MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_ADDR_WIDTH". Setting updated value from the model parameter.
set_property value 4 ${MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH}
}
@@ -1,60 +1,60 @@
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
ipgui::add_param $IPINST -name "AXI4_Lite_BASEADDR" -parent ${Page_0}
ipgui::add_param $IPINST -name "AXI4_Lite_HIGHADDR" -parent ${Page_0}
}
proc update_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to update AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to update AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to validate AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to update AXI4_Lite_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to validate AXI4_Lite_BASEADDR
return true
}
proc update_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to update AXI4_Lite_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to validate AXI4_Lite_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_DATA_WIDTH". Setting updated value from the model parameter.
set_property value 32 ${MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_ADDR_WIDTH". Setting updated value from the model parameter.
set_property value 4 ${MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH}
}
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0"]
ipgui::add_param $IPINST -name "AXI4_Lite_BASEADDR" -parent ${Page_0}
ipgui::add_param $IPINST -name "AXI4_Lite_HIGHADDR" -parent ${Page_0}
}
proc update_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to update AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_ADDR_WIDTH { PARAM_VALUE.AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to update AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI_LITE_DATA_WIDTH { PARAM_VALUE.AXI_LITE_DATA_WIDTH } {
# Procedure called to validate AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to update AXI4_Lite_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_BASEADDR { PARAM_VALUE.AXI4_Lite_BASEADDR } {
# Procedure called to validate AXI4_Lite_BASEADDR
return true
}
proc update_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to update AXI4_Lite_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.AXI4_Lite_HIGHADDR { PARAM_VALUE.AXI4_Lite_HIGHADDR } {
# Procedure called to validate AXI4_Lite_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_DATA_WIDTH". Setting updated value from the model parameter.
set_property value 32 ${MODELPARAM_VALUE.C_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
# WARNING: There is no corresponding user parameter named "C_AXI_LITE_ADDR_WIDTH". Setting updated value from the model parameter.
set_property value 4 ${MODELPARAM_VALUE.C_AXI_LITE_ADDR_WIDTH}
}
@@ -1,134 +1,134 @@
proc init { cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
set full_sbusif_list [list ]
foreach busif $all_busif {
if { [string equal -nocase [get_property MODE $busif] "slave"] == 1 } {
set busif_param_list [list]
set busif_name [get_property NAME $busif]
if { [lsearch -exact -nocase $full_sbusif_list $busif_name ] == -1 } {
continue
}
foreach tparam $axi_standard_param_list {
lappend busif_param_list "C_${busif_name}_${tparam}"
}
bd::mark_propagate_only $cell_handle $busif_param_list
}
}
}
proc pre_propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "master"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
if { $val_on_cell != "" } {
set_property CONFIG.${tparam} $val_on_cell $busif
}
}
}
}
}
proc propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "slave"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
#override property of bd_interface_net to bd_cell -- only for slaves. May check for supported values..
if { $val_on_cell_intf_pin != "" } {
set_property CONFIG.${busif_param_name} $val_on_cell_intf_pin $cell_handle
}
}
}
}
}
# Do FREQ_HZ propagation here
proc post_propagate {cellpath otherInfo } {
set ip [get_bd_cells $cellpath]
set vlnv [get_property VLNV $ip]
set ver [split [lindex [split $vlnv :] 3] .]
set ver_major [lindex $ver 0]
set ver_minor [lindex $ver 1]
set_property CONFIG.kVersionMajor [expr int($ver_major)] $ip
set_property CONFIG.kVersionMinor [expr int($ver_minor)] $ip
set byte_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RxByteClkHS]]
set byte_clk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/RxByteClkHS]]
set byte_clk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/RxByteClkHS]]
set video_aclk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/video_aclk]]
set video_aclk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/video_aclk]]
set video_aclk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/video_aclk]]
if { $byte_clk == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to RxByteClkHS" $ip
return
}
if { $video_aclk == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to video_aclk" $ip
return
}
set kLaneCount [get_property CONFIG.kLaneCount $ip]
set kMaxSamplesPerClock [get_property CONFIG.C_M_MAX_SAMPLES_PER_CLOCK $ip]
set kTargetDT [get_property CONFIG.kTargetDT $ip]
set bytes_per_px [eval {switch -nocase $kTargetDT {
RAW10 {expr {1.25}}
default {expr {0}}
}}]
if { $bytes_per_px == 0 } then {
set_property MSG.ERROR "Unknown data type: $kTargetDT" $ip
return
}
set input_rate [expr int($byte_clk)*int($kLaneCount)/$bytes_per_px]
set output_rate [expr int($video_aclk)*int($kMaxSamplesPerClock)]
if { $input_rate > $output_rate } then {
set_property MSG.ERROR [concat "video_aclk frequency is too small to handle RxByteClkHS frequency. Minimum frequency " [expr $input_rate/int($kMaxSamplesPerClock)] "Hz."] $ip
} else {
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "Verified that video_aclk frequency can handle RxByteClkHS frequency. AXI-Stream bandwidth $output_rate Pix/s >= PPI bandwidth $input_rate Pix/s"
}
}
proc init { cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
set full_sbusif_list [list ]
foreach busif $all_busif {
if { [string equal -nocase [get_property MODE $busif] "slave"] == 1 } {
set busif_param_list [list]
set busif_name [get_property NAME $busif]
if { [lsearch -exact -nocase $full_sbusif_list $busif_name ] == -1 } {
continue
}
foreach tparam $axi_standard_param_list {
lappend busif_param_list "C_${busif_name}_${tparam}"
}
bd::mark_propagate_only $cell_handle $busif_param_list
}
}
}
proc pre_propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "master"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
if { $val_on_cell != "" } {
set_property CONFIG.${tparam} $val_on_cell $busif
}
}
}
}
}
proc propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "slave"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
#override property of bd_interface_net to bd_cell -- only for slaves. May check for supported values..
if { $val_on_cell_intf_pin != "" } {
set_property CONFIG.${busif_param_name} $val_on_cell_intf_pin $cell_handle
}
}
}
}
}
# Do FREQ_HZ propagation here
proc post_propagate {cellpath otherInfo } {
set ip [get_bd_cells $cellpath]
set vlnv [get_property VLNV $ip]
set ver [split [lindex [split $vlnv :] 3] .]
set ver_major [lindex $ver 0]
set ver_minor [lindex $ver 1]
set_property CONFIG.kVersionMajor [expr int($ver_major)] $ip
set_property CONFIG.kVersionMinor [expr int($ver_minor)] $ip
set byte_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RxByteClkHS]]
set byte_clk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/RxByteClkHS]]
set byte_clk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/RxByteClkHS]]
set video_aclk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/video_aclk]]
set video_aclk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/video_aclk]]
set video_aclk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/video_aclk]]
if { $byte_clk == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to RxByteClkHS" $ip
return
}
if { $video_aclk == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to video_aclk" $ip
return
}
set kLaneCount [get_property CONFIG.kLaneCount $ip]
set kMaxSamplesPerClock [get_property CONFIG.C_M_MAX_SAMPLES_PER_CLOCK $ip]
set kTargetDT [get_property CONFIG.kTargetDT $ip]
set bytes_per_px [eval {switch -nocase $kTargetDT {
RAW10 {expr {1.25}}
default {expr {0}}
}}]
if { $bytes_per_px == 0 } then {
set_property MSG.ERROR "Unknown data type: $kTargetDT" $ip
return
}
set input_rate [expr int($byte_clk)*int($kLaneCount)/$bytes_per_px]
set output_rate [expr int($video_aclk)*int($kMaxSamplesPerClock)]
if { $input_rate > $output_rate } then {
set_property MSG.ERROR [concat "video_aclk frequency is too small to handle RxByteClkHS frequency. Minimum frequency " [expr $input_rate/int($kMaxSamplesPerClock)] "Hz."] $ip
} else {
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "Verified that video_aclk frequency can handle RxByteClkHS frequency. AXI-Stream bandwidth $output_rate Pix/s >= PPI bandwidth $input_rate Pix/s"
}
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "MIPI_CSI_2_RX" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_LITE_BASEADDR" "C_S_AXI_LITE_HIGHADDR"
}
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "MIPI_CSI_2_RX" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_LITE_BASEADDR" "C_S_AXI_LITE_HIGHADDR"
}
@@ -1,6 +1,6 @@
/***************************** Include Files *******************************/
#include "MIPI_CSI_2_RX.h"
/************************** Function Definitions ***************************/
/***************************** Include Files *******************************/
#include "MIPI_CSI_2_RX.h"
/************************** Function Definitions ***************************/
@@ -1,88 +1,88 @@
#ifndef MIPI_CSI_2_RX_H
#define MIPI_CSI_2_RX_H
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define MAJOR_VERSION (1)
#define MINOR_VERSION (0)
/****************** Register map ********************/
#define CR_OFFSET 0x0
#define VERSION_OFFSET 0xC
/****************** Bit map ********************/
#define CR_ENABLE_MASK 0x2
#define CR_RESET_MASK 0x1
#define VERSION_MAJOR_MASK 0xFFFF0000
#define VERSION_MAJOR_SHIFT 16
#define VERSION_MINOR_MASK 0x0000FFFF
#define VERSION_MINOR_SHIFT 0
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a MIPI_CSI_2_RX register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the MIPI_CSI_2_RXdevice.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MIPI_CSI_2_RX_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
*
*/
#define MIPI_CSI_2_RX_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/**
*
* Read a value from a MIPI_CSI_2_RX register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the MIPI_CSI_2_RX device.
* @param RegOffset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* u32 MIPI_CSI_2_RX_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
*/
#define MIPI_CSI_2_RX_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ****************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_CSI_2_RX instance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_CSI_2_RX_Reg_SelfTest(void * baseaddr_p);
#endif // MIPI_CSI_2_RX_H
#ifndef MIPI_CSI_2_RX_H
#define MIPI_CSI_2_RX_H
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define MAJOR_VERSION (1)
#define MINOR_VERSION (0)
/****************** Register map ********************/
#define CR_OFFSET 0x0
#define VERSION_OFFSET 0xC
/****************** Bit map ********************/
#define CR_ENABLE_MASK 0x2
#define CR_RESET_MASK 0x1
#define VERSION_MAJOR_MASK 0xFFFF0000
#define VERSION_MAJOR_SHIFT 16
#define VERSION_MINOR_MASK 0x0000FFFF
#define VERSION_MINOR_SHIFT 0
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a MIPI_CSI_2_RX register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the MIPI_CSI_2_RXdevice.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MIPI_CSI_2_RX_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
*
*/
#define MIPI_CSI_2_RX_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/**
*
* Read a value from a MIPI_CSI_2_RX register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the MIPI_CSI_2_RX device.
* @param RegOffset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* u32 MIPI_CSI_2_RX_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
*/
#define MIPI_CSI_2_RX_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ****************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_CSI_2_RX instance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_CSI_2_RX_Reg_SelfTest(void * baseaddr_p);
#endif // MIPI_CSI_2_RX_H
@@ -1,47 +1,47 @@
/***************************** Include Files *******************************/
#include "MIPI_CSI_2_RX.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_CSI_2_RXinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_CSI_2_RX_Reg_SelfTest(void * baseaddr_p)
{
u32 baseaddr;
u32 version;
baseaddr = (u32) baseaddr_p;
version = MIPI_CSI_2_RX_mReadReg(baseaddr, VERSION_OFFSET);
if (!(((version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT == MAJOR_VERSION) &&
((version & VERSION_MINOR_MASK) >> VERSION_MINOR_SHIFT == MINOR_VERSION)))
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
/***************************** Include Files *******************************/
#include "MIPI_CSI_2_RX.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_CSI_2_RXinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_CSI_2_RX_Reg_SelfTest(void * baseaddr_p)
{
u32 baseaddr;
u32 version;
baseaddr = (u32) baseaddr_p;
version = MIPI_CSI_2_RX_mReadReg(baseaddr, VERSION_OFFSET);
if (!(((version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT == MAJOR_VERSION) &&
((version & VERSION_MINOR_MASK) >> VERSION_MINOR_SHIFT == MINOR_VERSION)))
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
@@ -1,283 +1,283 @@
`timescale 1 ns / 1 ps
`include "MIPI_CSI_2_RX_v1_0_tb_include.vh"
// lite_response Type Defines
`define RESPONSE_OKAY 2'b00
`define RESPONSE_EXOKAY 2'b01
`define RESP_BUS_WIDTH 2
`define BURST_TYPE_INCR 2'b01
`define BURST_TYPE_WRAP 2'b10
// AMBA AXI4 Lite Range Constants
`define S_AXI_LITE_MAX_BURST_LENGTH 1
`define S_AXI_LITE_DATA_BUS_WIDTH 32
`define S_AXI_LITE_ADDRESS_BUS_WIDTH 32
`define S_AXI_LITE_MAX_DATA_SIZE (`S_AXI_LITE_DATA_BUS_WIDTH*`S_AXI_LITE_MAX_BURST_LENGTH)/8
// AMBA AXI4 Lite Range Constants
`define S_AXI_INTR_MAX_BURST_LENGTH 1
`define S_AXI_INTR_DATA_BUS_WIDTH 32
`define S_AXI_INTR_ADDRESS_BUS_WIDTH 32
`define S_AXI_INTR_MAX_DATA_SIZE (`S_AXI_INTR_DATA_BUS_WIDTH*`S_AXI_INTR_MAX_BURST_LENGTH)/8
module MIPI_CSI_2_RX_v1_0_tb;
reg tb_ACLK;
reg tb_ARESETn;
wire tb_irq;
// Create an instance of the example tb
`BD_WRAPPER dut (.ACLK(tb_ACLK),
.ARESETN(tb_ARESETn),
.irq(tb_irq));
// Local Variables
// AMBA S_AXI_LITE AXI4 Lite Local Reg
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_rd_data_lite;
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_test_data_lite [3:0];
reg [`RESP_BUS_WIDTH-1:0] S_AXI_LITE_lite_response;
reg [`S_AXI_LITE_ADDRESS_BUS_WIDTH-1:0] S_AXI_LITE_mtestAddress;
reg [3-1:0] S_AXI_LITE_mtestProtection_lite;
integer S_AXI_LITE_mtestvectorlite; // Master side testvector
integer S_AXI_LITE_mtestdatasizelite;
// AMBA S_AXI_INTR Interrupt AXI4 Lite Local Reg
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_globalenData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_intrenData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_pendData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_ackData;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_globalenAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_intrenAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_pendAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_ackAddress;
reg [`RESP_BUS_WIDTH-1:0] S_AXI_INTR_lite_response;
reg [3-1:0] S_AXI_INTR_mtestProtection_lite;
integer S_AXI_INTR_mtestdatasizelite;
integer result_slave_lite;
// Simple Reset Generator and test
initial begin
tb_ARESETn = 1'b0;
#500;
// Release the reset on the posedge of the clk.
@(posedge tb_ACLK);
tb_ARESETn = 1'b1;
@(posedge tb_ACLK);
end
// Simple Clock Generator
initial tb_ACLK = 1'b0;
always #10 tb_ACLK = !tb_ACLK;
//------------------------------------------------------------------------
// TEST LEVEL API: CHECK_RESPONSE_OKAY
//------------------------------------------------------------------------
// Description:
// CHECK_RESPONSE_OKAY(lite_response)
// This task checks if the return lite_response is equal to OKAY
//------------------------------------------------------------------------
task automatic CHECK_RESPONSE_OKAY;
input [`RESP_BUS_WIDTH-1:0] response;
begin
if (response !== `RESPONSE_OKAY) begin
$display("TESTBENCH ERROR! lite_response is not OKAY",
"\n expected = 0x%h",`RESPONSE_OKAY,
"\n actual = 0x%h",response);
$stop;
end
end
endtask
//------------------------------------------------------------------------
// TEST LEVEL API: COMPARE_LITE_DATA
//------------------------------------------------------------------------
// Description:
// COMPARE_LITE_DATA(expected,actual)
// This task checks if the actual data is equal to the expected data.
// X is used as don't care but it is not permitted for the full vector
// to be don't care.
//------------------------------------------------------------------------
`define S_AXI_DATA_BUS_WIDTH 32
task automatic COMPARE_LITE_DATA;
input [`S_AXI_DATA_BUS_WIDTH-1:0]expected;
input [`S_AXI_DATA_BUS_WIDTH-1:0]actual;
begin
if (expected === 'hx || actual === 'hx) begin
$display("TESTBENCH ERROR! COMPARE_LITE_DATA cannot be performed with an expected or actual vector that is all 'x'!");
result_slave_lite = 0;
$stop;
end
if (actual != expected) begin
$display("TESTBENCH ERROR! Data expected is not equal to actual.",
"\nexpected = 0x%h",expected,
"\nactual = 0x%h",actual);
result_slave_lite = 0;
$stop;
end
else
begin
$display("TESTBENCH Passed! Data expected is equal to actual.",
"\n expected = 0x%h",expected,
"\n actual = 0x%h",actual);
end
end
endtask
task automatic S_AXI_LITE_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_LITE");
$display("Simple register write and read example");
$display("---------------------------------------------------------");
S_AXI_LITE_mtestvectorlite = 0;
S_AXI_LITE_mtestAddress = `S_AXI_LITE_SLAVE_ADDRESS;
S_AXI_LITE_mtestProtection_lite = 0;
S_AXI_LITE_mtestdatasizelite = `S_AXI_LITE_MAX_DATA_SIZE;
result_slave_lite = 1;
for (S_AXI_LITE_mtestvectorlite = 0; S_AXI_LITE_mtestvectorlite <= 3; S_AXI_LITE_mtestvectorlite = S_AXI_LITE_mtestvectorlite + 1)
begin
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT( S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],
S_AXI_LITE_mtestdatasizelite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d write : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_rd_data_lite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d read : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_rd_data_lite,S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
COMPARE_LITE_DATA(S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_rd_data_lite);
$display("EXAMPLE TEST %d : Sequential write and read burst transfers complete from the master side. %d",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_mtestvectorlite);
S_AXI_LITE_mtestAddress = S_AXI_LITE_mtestAddress + 32'h00000004;
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_LITE: PTGEN_TEST_FINISHED!");
if ( result_slave_lite ) begin
$display("PTGEN_TEST: PASSED!");
end else begin
$display("PTGEN_TEST: FAILED!");
end
$display("---------------------------------------------------------");
end
endtask
task automatic S_AXI_INTR_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_INTR");
$display("Simple Interrupt generation test");
$display("---------------------------------------------------------");
//Initializing local registers
S_AXI_INTR_globalenAddress = `S_AXI_INTR_SLAVE_ADDRESS;
S_AXI_INTR_intrenAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h00000004;
S_AXI_INTR_pendAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h00000010;
S_AXI_INTR_ackAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h0000000c;
S_AXI_INTR_globalenData = 32'h00000001;
S_AXI_INTR_intrenData = 32'h00000001;
S_AXI_INTR_ackData = 32'h00000001;
S_AXI_INTR_pendData = 32'h00000000;
S_AXI_INTR_mtestProtection_lite = 0;
S_AXI_INTR_mtestdatasizelite = `S_AXI_INTR_MAX_DATA_SIZE;
//Enabling global interrupt generation
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_globalenAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_globalenData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
//Enabling Interrupt generation at bit 0
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_intrenAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_intrenData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
wait(tb_irq == `IRQ_ACTIVE_STATE) @(posedge tb_ACLK);
begin
#100;
//Reading Interrupt pending register value
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_INTR_pendAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_pendData,
S_AXI_INTR_lite_response);
if ( S_AXI_INTR_pendData[0] != 1'b1) begin
$display("ERROR: Interrupt not generated at bit0");
$display("PTGEN_TEST: FAILED!");
$stop;
end
//clearing irq_f2p through Interrupt acknowledgement register
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_ackAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_ackData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
#100;
//Reading Interrupt pending register value
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_INTR_pendAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_pendData,
S_AXI_INTR_lite_response);
if ( S_AXI_INTR_pendData[0] != 1'b0) begin
$display("ERROR: Interrupt not cleared at bit0");
$display("PTGEN_TEST: FAILED!");
$stop;
end else begin
$display ("PASS: Interrupt test successful");
$display("PTGEN_TEST: PASSED!");
end
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_INTR: PTGEN_TEST_FINISHED!");
$display("---------------------------------------------------------");
end
endtask
// Create the test vectors
initial begin
// When performing debug enable all levels of INFO messages.
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.set_channel_level_info(1);
// Create test data vectors
S_AXI_LITE_test_data_lite[0] = 32'h0101FFFF;
S_AXI_LITE_test_data_lite[1] = 32'habcd0001;
S_AXI_LITE_test_data_lite[2] = 32'hdead0011;
S_AXI_LITE_test_data_lite[3] = 32'hbeef0011;
end
// Drive the BFM
initial begin
// Wait for end of reset
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
S_AXI_LITE_TEST();
S_AXI_INTR_TEST();
end
endmodule
`timescale 1 ns / 1 ps
`include "MIPI_CSI_2_RX_v1_0_tb_include.vh"
// lite_response Type Defines
`define RESPONSE_OKAY 2'b00
`define RESPONSE_EXOKAY 2'b01
`define RESP_BUS_WIDTH 2
`define BURST_TYPE_INCR 2'b01
`define BURST_TYPE_WRAP 2'b10
// AMBA AXI4 Lite Range Constants
`define S_AXI_LITE_MAX_BURST_LENGTH 1
`define S_AXI_LITE_DATA_BUS_WIDTH 32
`define S_AXI_LITE_ADDRESS_BUS_WIDTH 32
`define S_AXI_LITE_MAX_DATA_SIZE (`S_AXI_LITE_DATA_BUS_WIDTH*`S_AXI_LITE_MAX_BURST_LENGTH)/8
// AMBA AXI4 Lite Range Constants
`define S_AXI_INTR_MAX_BURST_LENGTH 1
`define S_AXI_INTR_DATA_BUS_WIDTH 32
`define S_AXI_INTR_ADDRESS_BUS_WIDTH 32
`define S_AXI_INTR_MAX_DATA_SIZE (`S_AXI_INTR_DATA_BUS_WIDTH*`S_AXI_INTR_MAX_BURST_LENGTH)/8
module MIPI_CSI_2_RX_v1_0_tb;
reg tb_ACLK;
reg tb_ARESETn;
wire tb_irq;
// Create an instance of the example tb
`BD_WRAPPER dut (.ACLK(tb_ACLK),
.ARESETN(tb_ARESETn),
.irq(tb_irq));
// Local Variables
// AMBA S_AXI_LITE AXI4 Lite Local Reg
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_rd_data_lite;
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_test_data_lite [3:0];
reg [`RESP_BUS_WIDTH-1:0] S_AXI_LITE_lite_response;
reg [`S_AXI_LITE_ADDRESS_BUS_WIDTH-1:0] S_AXI_LITE_mtestAddress;
reg [3-1:0] S_AXI_LITE_mtestProtection_lite;
integer S_AXI_LITE_mtestvectorlite; // Master side testvector
integer S_AXI_LITE_mtestdatasizelite;
// AMBA S_AXI_INTR Interrupt AXI4 Lite Local Reg
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_globalenData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_intrenData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_pendData;
reg [`S_AXI_INTR_DATA_BUS_WIDTH-1:0] S_AXI_INTR_ackData;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_globalenAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_intrenAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_pendAddress;
reg [`S_AXI_INTR_ADDRESS_BUS_WIDTH-1:0] S_AXI_INTR_ackAddress;
reg [`RESP_BUS_WIDTH-1:0] S_AXI_INTR_lite_response;
reg [3-1:0] S_AXI_INTR_mtestProtection_lite;
integer S_AXI_INTR_mtestdatasizelite;
integer result_slave_lite;
// Simple Reset Generator and test
initial begin
tb_ARESETn = 1'b0;
#500;
// Release the reset on the posedge of the clk.
@(posedge tb_ACLK);
tb_ARESETn = 1'b1;
@(posedge tb_ACLK);
end
// Simple Clock Generator
initial tb_ACLK = 1'b0;
always #10 tb_ACLK = !tb_ACLK;
//------------------------------------------------------------------------
// TEST LEVEL API: CHECK_RESPONSE_OKAY
//------------------------------------------------------------------------
// Description:
// CHECK_RESPONSE_OKAY(lite_response)
// This task checks if the return lite_response is equal to OKAY
//------------------------------------------------------------------------
task automatic CHECK_RESPONSE_OKAY;
input [`RESP_BUS_WIDTH-1:0] response;
begin
if (response !== `RESPONSE_OKAY) begin
$display("TESTBENCH ERROR! lite_response is not OKAY",
"\n expected = 0x%h",`RESPONSE_OKAY,
"\n actual = 0x%h",response);
$stop;
end
end
endtask
//------------------------------------------------------------------------
// TEST LEVEL API: COMPARE_LITE_DATA
//------------------------------------------------------------------------
// Description:
// COMPARE_LITE_DATA(expected,actual)
// This task checks if the actual data is equal to the expected data.
// X is used as don't care but it is not permitted for the full vector
// to be don't care.
//------------------------------------------------------------------------
`define S_AXI_DATA_BUS_WIDTH 32
task automatic COMPARE_LITE_DATA;
input [`S_AXI_DATA_BUS_WIDTH-1:0]expected;
input [`S_AXI_DATA_BUS_WIDTH-1:0]actual;
begin
if (expected === 'hx || actual === 'hx) begin
$display("TESTBENCH ERROR! COMPARE_LITE_DATA cannot be performed with an expected or actual vector that is all 'x'!");
result_slave_lite = 0;
$stop;
end
if (actual != expected) begin
$display("TESTBENCH ERROR! Data expected is not equal to actual.",
"\nexpected = 0x%h",expected,
"\nactual = 0x%h",actual);
result_slave_lite = 0;
$stop;
end
else
begin
$display("TESTBENCH Passed! Data expected is equal to actual.",
"\n expected = 0x%h",expected,
"\n actual = 0x%h",actual);
end
end
endtask
task automatic S_AXI_LITE_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_LITE");
$display("Simple register write and read example");
$display("---------------------------------------------------------");
S_AXI_LITE_mtestvectorlite = 0;
S_AXI_LITE_mtestAddress = `S_AXI_LITE_SLAVE_ADDRESS;
S_AXI_LITE_mtestProtection_lite = 0;
S_AXI_LITE_mtestdatasizelite = `S_AXI_LITE_MAX_DATA_SIZE;
result_slave_lite = 1;
for (S_AXI_LITE_mtestvectorlite = 0; S_AXI_LITE_mtestvectorlite <= 3; S_AXI_LITE_mtestvectorlite = S_AXI_LITE_mtestvectorlite + 1)
begin
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT( S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],
S_AXI_LITE_mtestdatasizelite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d write : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_rd_data_lite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d read : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_rd_data_lite,S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
COMPARE_LITE_DATA(S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_rd_data_lite);
$display("EXAMPLE TEST %d : Sequential write and read burst transfers complete from the master side. %d",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_mtestvectorlite);
S_AXI_LITE_mtestAddress = S_AXI_LITE_mtestAddress + 32'h00000004;
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_LITE: PTGEN_TEST_FINISHED!");
if ( result_slave_lite ) begin
$display("PTGEN_TEST: PASSED!");
end else begin
$display("PTGEN_TEST: FAILED!");
end
$display("---------------------------------------------------------");
end
endtask
task automatic S_AXI_INTR_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_INTR");
$display("Simple Interrupt generation test");
$display("---------------------------------------------------------");
//Initializing local registers
S_AXI_INTR_globalenAddress = `S_AXI_INTR_SLAVE_ADDRESS;
S_AXI_INTR_intrenAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h00000004;
S_AXI_INTR_pendAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h00000010;
S_AXI_INTR_ackAddress = `S_AXI_INTR_SLAVE_ADDRESS + 32'h0000000c;
S_AXI_INTR_globalenData = 32'h00000001;
S_AXI_INTR_intrenData = 32'h00000001;
S_AXI_INTR_ackData = 32'h00000001;
S_AXI_INTR_pendData = 32'h00000000;
S_AXI_INTR_mtestProtection_lite = 0;
S_AXI_INTR_mtestdatasizelite = `S_AXI_INTR_MAX_DATA_SIZE;
//Enabling global interrupt generation
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_globalenAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_globalenData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
//Enabling Interrupt generation at bit 0
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_intrenAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_intrenData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
wait(tb_irq == `IRQ_ACTIVE_STATE) @(posedge tb_ACLK);
begin
#100;
//Reading Interrupt pending register value
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_INTR_pendAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_pendData,
S_AXI_INTR_lite_response);
if ( S_AXI_INTR_pendData[0] != 1'b1) begin
$display("ERROR: Interrupt not generated at bit0");
$display("PTGEN_TEST: FAILED!");
$stop;
end
//clearing irq_f2p through Interrupt acknowledgement register
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT(S_AXI_INTR_ackAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_ackData,
S_AXI_INTR_mtestdatasizelite,
S_AXI_INTR_lite_response);
#100;
//Reading Interrupt pending register value
dut.`BD_INST_NAME.master_1.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_INTR_pendAddress,
S_AXI_INTR_mtestProtection_lite,
S_AXI_INTR_pendData,
S_AXI_INTR_lite_response);
if ( S_AXI_INTR_pendData[0] != 1'b0) begin
$display("ERROR: Interrupt not cleared at bit0");
$display("PTGEN_TEST: FAILED!");
$stop;
end else begin
$display ("PASS: Interrupt test successful");
$display("PTGEN_TEST: PASSED!");
end
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_INTR: PTGEN_TEST_FINISHED!");
$display("---------------------------------------------------------");
end
endtask
// Create the test vectors
initial begin
// When performing debug enable all levels of INFO messages.
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.set_channel_level_info(1);
// Create test data vectors
S_AXI_LITE_test_data_lite[0] = 32'h0101FFFF;
S_AXI_LITE_test_data_lite[1] = 32'habcd0001;
S_AXI_LITE_test_data_lite[2] = 32'hdead0011;
S_AXI_LITE_test_data_lite[3] = 32'hbeef0011;
end
// Drive the BFM
initial begin
// Wait for end of reset
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
S_AXI_LITE_TEST();
S_AXI_INTR_TEST();
end
endmodule
@@ -1,119 +1,119 @@
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create Clock and Reset Ports
set ACLK [ create_bd_port -dir I -type clk ACLK ]
set_property -dict [ list CONFIG.FREQ_HZ {100000000} CONFIG.PHASE {0.000} CONFIG.CLK_DOMAIN "${design_name}_ACLK" ] $ACLK
set ARESETN [ create_bd_port -dir I -type rst ARESETN ]
set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $ARESETN
set_property CONFIG.ASSOCIATED_RESET ARESETN $ACLK
# Create instance: MIPI_CSI_2_RX_0, and set properties
set MIPI_CSI_2_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_CSI_2_RX:1.0 MIPI_CSI_2_RX_0]
# Create instance: master_0, and set properties
set master_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_0]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_0
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_0/M_AXI_LITE] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_LITE]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_0/M_AXI_LITE_ACLK] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_LITE_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_0/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_LITE_ARESETN]
# Create instance: master_1, and set properties
set master_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_1]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_1
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_1/M_AXI_LITE] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_INTR]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_1/M_AXI_LITE_ACLK] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_INTR_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_1/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_INTR_ARESETN]
set S_AXI_INTR_IRQ [ create_bd_port -dir O -type intr irq ]
connect_bd_net [get_bd_pins /MIPI_CSI_2_RX_0/irq] ${S_AXI_INTR_IRQ}
# Auto assign address
assign_bd_address
# Copy all address to interface_address.vh file
set bd_path [file dirname [get_property NAME [get_files ${design_name}.bd]]]
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_CSI_2_RX_v1_0_tb_include.vh"
set fp [open $offset_file "w"]
puts $fp "`ifndef MIPI_CSI_2_RX_v1_0_tb_include_vh_"
puts $fp "`define MIPI_CSI_2_RX_v1_0_tb_include_vh_\n"
puts $fp "//Configuration current bd names"
puts $fp "`define BD_INST_NAME ${design_name}_i"
puts $fp "`define BD_WRAPPER ${design_name}_wrapper\n"
puts $fp "//Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_1/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_INTR_SLAVE_ADDRESS ${offset_hex}"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_0/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_LITE_SLAVE_ADDRESS ${offset_hex}"
puts $fp "\n//Interrupt configuration parameters"
set param_irq_active_state [get_property CONFIG.C_IRQ_ACTIVE_STATE [get_bd_cells MIPI_CSI_2_RX_0]]
set param_irq_sensitivity [get_property CONFIG.C_IRQ_SENSITIVITY [get_bd_cells MIPI_CSI_2_RX_0]]
set param_intr_active_state [get_property CONFIG.C_INTR_ACTIVE_STATE [get_bd_cells MIPI_CSI_2_RX_0]]
set param_intr_sensitivity [get_property CONFIG.C_INTR_SENSITIVITY [get_bd_cells MIPI_CSI_2_RX_0]]
puts $fp "`define IRQ_ACTIVE_STATE ${param_irq_active_state}"
puts $fp "`define IRQ_SENSITIVITY ${param_irq_sensitivity}"
puts $fp "`define INTR_ACTIVE_STATE ${param_intr_active_state}"
puts $fp "`define INTR_SENSITIVITY ${param_intr_sensitivity}\n"
puts $fp "`endif"
close $fp
}
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_CSI_2_RX:1.0]]]]
set test_bench_file ${ip_path}/example_designs/bfm_design/MIPI_CSI_2_RX_v1_0_tb.v
set interface_address_vh_file ""
# Set IP Repository and Update IP Catalogue
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_CSI_2_RX_v1_0_bfm_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
create_ipi_design interface_address_vh_file ${design_name}
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
set_property SOURCE_SET sources_1 [get_filesets sim_1]
import_files -fileset sim_1 -norecurse -force $test_bench_file
remove_files -quiet -fileset sim_1 MIPI_CSI_2_RX_v1_0_tb_include.vh
import_files -fileset sim_1 -norecurse -force $interface_address_vh_file
set_property top MIPI_CSI_2_RX_v1_0_tb [get_filesets sim_1]
set_property top_lib {} [get_filesets sim_1]
set_property top_file {} [get_filesets sim_1]
launch_xsim -simset sim_1 -mode behavioral
restart
run 1000 us
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create Clock and Reset Ports
set ACLK [ create_bd_port -dir I -type clk ACLK ]
set_property -dict [ list CONFIG.FREQ_HZ {100000000} CONFIG.PHASE {0.000} CONFIG.CLK_DOMAIN "${design_name}_ACLK" ] $ACLK
set ARESETN [ create_bd_port -dir I -type rst ARESETN ]
set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $ARESETN
set_property CONFIG.ASSOCIATED_RESET ARESETN $ACLK
# Create instance: MIPI_CSI_2_RX_0, and set properties
set MIPI_CSI_2_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_CSI_2_RX:1.0 MIPI_CSI_2_RX_0]
# Create instance: master_0, and set properties
set master_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_0]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_0
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_0/M_AXI_LITE] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_LITE]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_0/M_AXI_LITE_ACLK] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_LITE_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_0/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_LITE_ARESETN]
# Create instance: master_1, and set properties
set master_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_1]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_1
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_1/M_AXI_LITE] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_INTR]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_1/M_AXI_LITE_ACLK] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_INTR_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_1/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_CSI_2_RX_0/S_AXI_INTR_ARESETN]
set S_AXI_INTR_IRQ [ create_bd_port -dir O -type intr irq ]
connect_bd_net [get_bd_pins /MIPI_CSI_2_RX_0/irq] ${S_AXI_INTR_IRQ}
# Auto assign address
assign_bd_address
# Copy all address to interface_address.vh file
set bd_path [file dirname [get_property NAME [get_files ${design_name}.bd]]]
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_CSI_2_RX_v1_0_tb_include.vh"
set fp [open $offset_file "w"]
puts $fp "`ifndef MIPI_CSI_2_RX_v1_0_tb_include_vh_"
puts $fp "`define MIPI_CSI_2_RX_v1_0_tb_include_vh_\n"
puts $fp "//Configuration current bd names"
puts $fp "`define BD_INST_NAME ${design_name}_i"
puts $fp "`define BD_WRAPPER ${design_name}_wrapper\n"
puts $fp "//Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_1/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_INTR_SLAVE_ADDRESS ${offset_hex}"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_0/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_LITE_SLAVE_ADDRESS ${offset_hex}"
puts $fp "\n//Interrupt configuration parameters"
set param_irq_active_state [get_property CONFIG.C_IRQ_ACTIVE_STATE [get_bd_cells MIPI_CSI_2_RX_0]]
set param_irq_sensitivity [get_property CONFIG.C_IRQ_SENSITIVITY [get_bd_cells MIPI_CSI_2_RX_0]]
set param_intr_active_state [get_property CONFIG.C_INTR_ACTIVE_STATE [get_bd_cells MIPI_CSI_2_RX_0]]
set param_intr_sensitivity [get_property CONFIG.C_INTR_SENSITIVITY [get_bd_cells MIPI_CSI_2_RX_0]]
puts $fp "`define IRQ_ACTIVE_STATE ${param_irq_active_state}"
puts $fp "`define IRQ_SENSITIVITY ${param_irq_sensitivity}"
puts $fp "`define INTR_ACTIVE_STATE ${param_intr_active_state}"
puts $fp "`define INTR_SENSITIVITY ${param_intr_sensitivity}\n"
puts $fp "`endif"
close $fp
}
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_CSI_2_RX:1.0]]]]
set test_bench_file ${ip_path}/example_designs/bfm_design/MIPI_CSI_2_RX_v1_0_tb.v
set interface_address_vh_file ""
# Set IP Repository and Update IP Catalogue
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_CSI_2_RX_v1_0_bfm_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
create_ipi_design interface_address_vh_file ${design_name}
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
set_property SOURCE_SET sources_1 [get_filesets sim_1]
import_files -fileset sim_1 -norecurse -force $test_bench_file
remove_files -quiet -fileset sim_1 MIPI_CSI_2_RX_v1_0_tb_include.vh
import_files -fileset sim_1 -norecurse -force $interface_address_vh_file
set_property top MIPI_CSI_2_RX_v1_0_tb [get_filesets sim_1]
set_property top_lib {} [get_filesets sim_1]
set_property top_file {} [get_filesets sim_1]
launch_xsim -simset sim_1 -mode behavioral
restart
run 1000 us
@@ -1,147 +1,147 @@
# Runtime Tcl commands to interact with - MIPI_CSI_2_RX_v1_0
# Sourcing design address info tcl
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
source ${bd_path}/MIPI_CSI_2_RX_v1_0_include.tcl
# jtag axi master interface hardware name, change as per your design.
set jtag_axi_master hw_axi_1
set ec 0
# hw test script
# Delete all previous axis transactions
if { [llength [get_hw_axi_txns -quiet]] } {
delete_hw_axi_txn [get_hw_axi_txns -quiet]
}
# Test all lite slaves.
set wdata_1 abcd1234
# Test: S_AXI_LITE
# Create a write transaction at s_axi_lite_addr address
create_hw_axi_txn w_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type write -address $s_axi_lite_addr -data $wdata_1
# Create a read transaction at s_axi_lite_addr address
create_hw_axi_txn r_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type read -address $s_axi_lite_addr
# Initiate transactions
run_hw_axi r_s_axi_lite_addr
run_hw_axi w_s_axi_lite_addr
run_hw_axi r_s_axi_lite_addr
set rdata_tmp [get_property DATA [get_hw_axi_txn r_s_axi_lite_addr]]
# Compare read data
if { $rdata_tmp == $wdata_1 } {
puts "Data comparison test pass for - S_AXI_LITE"
} else {
puts "Data comparison test fail for - S_AXI_LITE, expected-$wdata_1 actual-$rdata_tmp"
inc ec
}
# Test: S_AXI_INTR
set intr_test 0
# Global interrupt register address
set glob_intr_reg $s_axi_intr_addr
# interrupt enable register address
set intr_en_reg [format 0x%x [expr {$s_axi_intr_addr + 0x4}]]
# status register address
set sts_reg [format 0x%x [expr {$s_axi_intr_addr + 0x8}]]
# interrupt acknowledgement register address
set intr_ack_reg [format 0x%x [expr {$s_axi_intr_addr + 0xC}]]
# pending register address
set pending_reg [format 0x%x [expr {$s_axi_intr_addr + 0x10}]]
# create a write transaction at global intr en reg
create_hw_axi_txn glob_intr_w [get_hw_axis $jtag_axi_master] -type write -address $glob_intr_reg -data {00000001}
# create a read transaction at global intr en reg
create_hw_axi_txn glob_intr_r [get_hw_axis $jtag_axi_master] -type read -address $glob_intr_reg
# Enable global intr enable
run_hw_axi glob_intr_w
run_hw_axi glob_intr_r
set rdata_tmp [get_property DATA [get_hw_axi_txn glob_intr_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - global intr enable register not set, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a write transaction at intr en reg
create_hw_axi_txn intr_en_w [get_hw_axis $jtag_axi_master] -type write -address $intr_en_reg -data {00000001}
# create a read transaction at intr en reg
create_hw_axi_txn intr_en_r [get_hw_axis $jtag_axi_master] -type read -address $intr_en_reg
# Enable intr by writing to bit 0 of intr reg [0]
run_hw_axi intr_en_w
run_hw_axi intr_en_r
set rdata_tmp [get_property DATA [get_hw_axi_txn intr_en_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - intr enable register not set, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at intr sts reg
create_hw_axi_txn sts_r [get_hw_axis $jtag_axi_master] -type read -address $sts_reg
# Read intr status reg. Bit 0 being 1 marks an intr condition has occurred. (should be 0x00000001)
run_hw_axi sts_r
set rdata_tmp [get_property DATA [get_hw_axi_txn sts_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - check status register, intr condition has not occurred, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at pending reg
create_hw_axi_txn pending_r [get_hw_axis $jtag_axi_master] -type read -address $pending_reg
# Read pending reg bit 0 (should be 0x00000001)
run_hw_axi pending_r
set rdata_tmp [get_property DATA [get_hw_axi_txn pending_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - Read pending reg bit 0, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at gpio reg
create_hw_axi_txn irq_r [get_hw_axis $jtag_axi_master] -type read -address $axi_gpio_irq_addr
# read gpio reg bit 0 to see if IRQ has been captured
run_hw_axi irq_r
set rdata_tmp [get_property DATA [get_hw_axi_txn irq_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - Read pending reg bit 0 to check if IRQ has been captured, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# Once intr has been detected, disable the intr enable reg bit 0 and acknowledge the interrupt by writing 1 to bit 0
set_property DATA 00000000 [get_hw_axi_txn intr_en_w]
run_hw_axi intr_en_w
# create a write transaction at intr ack reg
create_hw_axi_txn intr_ack_w [get_hw_axis $jtag_axi_master] -type write -address $intr_ack_reg -data {00000001}
#acknowledgement
run_hw_axi intr_ack_w
# Read pending reg to see if there are no pending reg (should be 0x00000000)
run_hw_axi pending_r
set rdata_tmp [get_property DATA [get_hw_axi_txn pending_r]]
if { $rdata_tmp != 00000000 } {
puts "S_AXI_INTR - Read pending reg, expected-00000000 actual-$rdata_tmp"
inc intr_test
}
# Read gpio reg to see the IRQ has been cleared (should be 0x00000000)
run_hw_axi irq_r
set rdata_tmp [get_property DATA [get_hw_axi_txn irq_r]]
if { $rdata_tmp != 00000000 } {
puts "S_AXI_INTR - Check if IRQ has been cleared, expected-00000000 actual-$rdata_tmp"
inc intr_test
}
# Compare read data
if { $intr_test == 0 } {
puts "Test pass for - S_AXI_INTR"
} else {
puts "Test fail for - S_AXI_INTR"
inc ec
}
# Check error flag
if { $ec == 0 } {
puts "PTGEN_TEST: PASSED!"
} else {
puts "PTGEN_TEST: FAILED!"
}
# Runtime Tcl commands to interact with - MIPI_CSI_2_RX_v1_0
# Sourcing design address info tcl
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
source ${bd_path}/MIPI_CSI_2_RX_v1_0_include.tcl
# jtag axi master interface hardware name, change as per your design.
set jtag_axi_master hw_axi_1
set ec 0
# hw test script
# Delete all previous axis transactions
if { [llength [get_hw_axi_txns -quiet]] } {
delete_hw_axi_txn [get_hw_axi_txns -quiet]
}
# Test all lite slaves.
set wdata_1 abcd1234
# Test: S_AXI_LITE
# Create a write transaction at s_axi_lite_addr address
create_hw_axi_txn w_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type write -address $s_axi_lite_addr -data $wdata_1
# Create a read transaction at s_axi_lite_addr address
create_hw_axi_txn r_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type read -address $s_axi_lite_addr
# Initiate transactions
run_hw_axi r_s_axi_lite_addr
run_hw_axi w_s_axi_lite_addr
run_hw_axi r_s_axi_lite_addr
set rdata_tmp [get_property DATA [get_hw_axi_txn r_s_axi_lite_addr]]
# Compare read data
if { $rdata_tmp == $wdata_1 } {
puts "Data comparison test pass for - S_AXI_LITE"
} else {
puts "Data comparison test fail for - S_AXI_LITE, expected-$wdata_1 actual-$rdata_tmp"
inc ec
}
# Test: S_AXI_INTR
set intr_test 0
# Global interrupt register address
set glob_intr_reg $s_axi_intr_addr
# interrupt enable register address
set intr_en_reg [format 0x%x [expr {$s_axi_intr_addr + 0x4}]]
# status register address
set sts_reg [format 0x%x [expr {$s_axi_intr_addr + 0x8}]]
# interrupt acknowledgement register address
set intr_ack_reg [format 0x%x [expr {$s_axi_intr_addr + 0xC}]]
# pending register address
set pending_reg [format 0x%x [expr {$s_axi_intr_addr + 0x10}]]
# create a write transaction at global intr en reg
create_hw_axi_txn glob_intr_w [get_hw_axis $jtag_axi_master] -type write -address $glob_intr_reg -data {00000001}
# create a read transaction at global intr en reg
create_hw_axi_txn glob_intr_r [get_hw_axis $jtag_axi_master] -type read -address $glob_intr_reg
# Enable global intr enable
run_hw_axi glob_intr_w
run_hw_axi glob_intr_r
set rdata_tmp [get_property DATA [get_hw_axi_txn glob_intr_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - global intr enable register not set, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a write transaction at intr en reg
create_hw_axi_txn intr_en_w [get_hw_axis $jtag_axi_master] -type write -address $intr_en_reg -data {00000001}
# create a read transaction at intr en reg
create_hw_axi_txn intr_en_r [get_hw_axis $jtag_axi_master] -type read -address $intr_en_reg
# Enable intr by writing to bit 0 of intr reg [0]
run_hw_axi intr_en_w
run_hw_axi intr_en_r
set rdata_tmp [get_property DATA [get_hw_axi_txn intr_en_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - intr enable register not set, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at intr sts reg
create_hw_axi_txn sts_r [get_hw_axis $jtag_axi_master] -type read -address $sts_reg
# Read intr status reg. Bit 0 being 1 marks an intr condition has occurred. (should be 0x00000001)
run_hw_axi sts_r
set rdata_tmp [get_property DATA [get_hw_axi_txn sts_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - check status register, intr condition has not occurred, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at pending reg
create_hw_axi_txn pending_r [get_hw_axis $jtag_axi_master] -type read -address $pending_reg
# Read pending reg bit 0 (should be 0x00000001)
run_hw_axi pending_r
set rdata_tmp [get_property DATA [get_hw_axi_txn pending_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - Read pending reg bit 0, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# create a read transaction at gpio reg
create_hw_axi_txn irq_r [get_hw_axis $jtag_axi_master] -type read -address $axi_gpio_irq_addr
# read gpio reg bit 0 to see if IRQ has been captured
run_hw_axi irq_r
set rdata_tmp [get_property DATA [get_hw_axi_txn irq_r]]
if { $rdata_tmp != 00000001 } {
puts "S_AXI_INTR - Read pending reg bit 0 to check if IRQ has been captured, expected-00000001 actual-$rdata_tmp"
inc intr_test
}
# Once intr has been detected, disable the intr enable reg bit 0 and acknowledge the interrupt by writing 1 to bit 0
set_property DATA 00000000 [get_hw_axi_txn intr_en_w]
run_hw_axi intr_en_w
# create a write transaction at intr ack reg
create_hw_axi_txn intr_ack_w [get_hw_axis $jtag_axi_master] -type write -address $intr_ack_reg -data {00000001}
#acknowledgement
run_hw_axi intr_ack_w
# Read pending reg to see if there are no pending reg (should be 0x00000000)
run_hw_axi pending_r
set rdata_tmp [get_property DATA [get_hw_axi_txn pending_r]]
if { $rdata_tmp != 00000000 } {
puts "S_AXI_INTR - Read pending reg, expected-00000000 actual-$rdata_tmp"
inc intr_test
}
# Read gpio reg to see the IRQ has been cleared (should be 0x00000000)
run_hw_axi irq_r
set rdata_tmp [get_property DATA [get_hw_axi_txn irq_r]]
if { $rdata_tmp != 00000000 } {
puts "S_AXI_INTR - Check if IRQ has been cleared, expected-00000000 actual-$rdata_tmp"
inc intr_test
}
# Compare read data
if { $intr_test == 0 } {
puts "Test pass for - S_AXI_INTR"
} else {
puts "Test fail for - S_AXI_INTR"
inc ec
}
# Check error flag
if { $ec == 0 } {
puts "PTGEN_TEST: PASSED!"
} else {
puts "PTGEN_TEST: FAILED!"
}
@@ -1,196 +1,196 @@
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create and configure Clock/Reset
create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz sys_clk_0
create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset sys_reset_0
#check if current_board is set, if true - figure out required clocks.
set is_board_clock_found 0
set is_board_reset_found 0
set external_reset_port ""
set external_clock_port ""
if { [current_board_part -quiet] != "" } {
#check if any reset interface exists in board.
set board_reset [lindex [get_board_part_interfaces -filter { BUSDEF_NAME == reset_rtl && MODE == slave }] 0 ]
if { $board_reset ne "" } {
set is_board_reset_found 1
apply_board_connection -board_interface $board_reset -ip_intf sys_clk_0/reset -diagram [current_bd_design]
apply_board_connection -board_interface $board_reset -ip_intf sys_reset_0/ext_reset -diagram [current_bd_design]
set external_rst [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/reset]]]
if { $external_rst ne "" } {
set external_reset_port [get_property NAME $external_rst]
}
} else {
send_msg "ptgen 51-200" WARNING "No reset interface found in current_board, Users may need to specify the location constraints manually."
}
# check for differential clock, exclude any special clocks which has TYPE property.
set board_clock_busifs ""
foreach busif [get_board_part_interfaces -filter "BUSDEF_NAME == diff_clock_rtl"] {
set type [get_property PARAM.TYPE $busif]
if { $type == "" } {
set board_clock_busifs $busif
break
}
}
if { $board_clock_busifs ne "" } {
apply_board_connection -board_interface $board_clock_busifs -ip_intf sys_clk_0/CLK_IN1_D -diagram [current_bd_design]
set is_board_clock_found 1
} else {
# check for single ended clock
set board_sclock_busifs [lindex [get_board_part_interfaces -filter "BUSDEF_NAME == clock_rtl"] 0 ]
if { $board_sclock_busifs ne "" } {
apply_board_connection -board_interface $board_sclock_busifs -ip_intf sys_clk_0/clock_CLK_IN1 -diagram [current_bd_design]
set external_clk [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/clk_in1]]]
if { $external_clk ne "" } {
set external_clock_port [get_property NAME $external_clk]
}
set is_board_clock_found 1
} else {
send_msg "ptgen 51-200" WARNING "No clock interface found in current_board, Users may need to specify the location constraints manually."
}
}
} else {
send_msg "ptgen 51-201" WARNING "No board selected in current_project. Users may need to specify the location constraints manually."
}
#if there is no corresponding board interface found, assume constraints will be provided manually while pin planning.
if { $is_board_reset_found == 0 } {
create_bd_port -dir I -type rst reset_rtl
set_property CONFIG.POLARITY [get_property CONFIG.POLARITY [get_bd_pins sys_clk_0/reset]] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_pins sys_reset_0/ext_reset_in] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_ports reset_rtl] [get_bd_pins sys_clk_0/reset]
set external_reset_port reset_rtl
}
if { $is_board_clock_found == 0 } {
create_bd_port -dir I -type clk clock_rtl
connect_bd_net [get_bd_pins sys_clk_0/clk_in1] [get_bd_ports clock_rtl]
set external_clock_port clock_rtl
}
#Avoid IPI DRC, make clock port synchronous to reset
if { $external_clock_port ne "" && $external_reset_port ne "" } {
set_property CONFIG.ASSOCIATED_RESET $external_reset_port [get_bd_ports $external_clock_port]
}
# Connect other sys_reset pins
connect_bd_net [get_bd_pins sys_reset_0/slowest_sync_clk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins sys_clk_0/locked] [get_bd_pins sys_reset_0/dcm_locked]
# Create instance: MIPI_CSI_2_RX_0, and set properties
set MIPI_CSI_2_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_CSI_2_RX:1.0 MIPI_CSI_2_RX_0 ]
# Create instance: jtag_axi_0, and set properties
set jtag_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:jtag_axi jtag_axi_0 ]
set_property -dict [list CONFIG.PROTOCOL {0}] [get_bd_cells jtag_axi_0]
connect_bd_net [get_bd_pins jtag_axi_0/aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins jtag_axi_0/aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_peri_interconnect, and set properties
set axi_peri_interconnect [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect axi_peri_interconnect ]
connect_bd_net [get_bd_pins axi_peri_interconnect/ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/ARESETN] [get_bd_pins sys_reset_0/interconnect_aresetn]
set_property -dict [ list CONFIG.NUM_SI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins jtag_axi_0/M_AXI] [get_bd_intf_pins axi_peri_interconnect/S00_AXI]
set_property -dict [ list CONFIG.NUM_MI {3} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_net [get_bd_pins axi_peri_interconnect/M01_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M01_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_net [get_bd_pins axi_peri_interconnect/M02_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M02_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Connect all clock & reset of MIPI_CSI_2_RX_0 slave interfaces..
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M00_AXI] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_LITE]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_lite_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_lite_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M01_AXI] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_INTR]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_intr_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_intr_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_gpio_irq, and set properties
set axi_gpio_irq [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio axi_gpio_irq ]
set_property -dict [ list CONFIG.C_ALL_INPUTS {1} CONFIG.C_GPIO_WIDTH {1} ] $axi_gpio_irq
connect_bd_net [get_bd_pins axi_gpio_irq/s_axi_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_gpio_irq/s_axi_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins axi_gpio_irq/S_AXI] [get_bd_intf_pins axi_peri_interconnect/M02_AXI]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/irq] [get_bd_pins axi_gpio_irq/gpio_io_i]
# Auto assign address
assign_bd_address
# Copy all address to MIPI_CSI_2_RX_v1_0_include.tcl file
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_CSI_2_RX_v1_0_include.tcl"
set fp [open $offset_file "w"]
puts $fp "# Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_axi_gpio_irq_Reg ]]
puts $fp "set axi_gpio_irq_addr ${offset}"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_CSI_2_RX_0_S_AXI_INTR_* ]]
puts $fp "set s_axi_intr_addr ${offset}"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_CSI_2_RX_0_S_AXI_LITE_* ]]
puts $fp "set s_axi_lite_addr ${offset}"
close $fp
}
# Set IP Repository and Update IP Catalogue
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_CSI_2_RX:1.0]]]]
set hw_test_file ${ip_path}/example_designs/debug_hw_design/MIPI_CSI_2_RX_v1_0_hw_test.tcl
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_CSI_2_RX_v1_0_hw_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
set intf_address_include_file ""
create_ipi_design intf_address_include_file ${design_name}
save_bd_design
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
puts "-------------------------------------------------------------------------------------------------"
puts "INFO NEXT STEPS : Until this stage, debug hardware design has been created, "
puts " please perform following steps to test design in targeted board."
puts "1. Generate bitstream"
puts "2. Setup your targeted board, open hardware manager and open new(or existing) hardware target"
puts "3. Download generated bitstream"
puts "4. Run generated hardware test using below command, this invokes basic read/write operation"
puts " to every interface present in the peripheral : xilinx.com:user:myip:1.0"
puts " : source -notrace ${hw_test_file}"
puts "-------------------------------------------------------------------------------------------------"
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create and configure Clock/Reset
create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz sys_clk_0
create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset sys_reset_0
#check if current_board is set, if true - figure out required clocks.
set is_board_clock_found 0
set is_board_reset_found 0
set external_reset_port ""
set external_clock_port ""
if { [current_board_part -quiet] != "" } {
#check if any reset interface exists in board.
set board_reset [lindex [get_board_part_interfaces -filter { BUSDEF_NAME == reset_rtl && MODE == slave }] 0 ]
if { $board_reset ne "" } {
set is_board_reset_found 1
apply_board_connection -board_interface $board_reset -ip_intf sys_clk_0/reset -diagram [current_bd_design]
apply_board_connection -board_interface $board_reset -ip_intf sys_reset_0/ext_reset -diagram [current_bd_design]
set external_rst [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/reset]]]
if { $external_rst ne "" } {
set external_reset_port [get_property NAME $external_rst]
}
} else {
send_msg "ptgen 51-200" WARNING "No reset interface found in current_board, Users may need to specify the location constraints manually."
}
# check for differential clock, exclude any special clocks which has TYPE property.
set board_clock_busifs ""
foreach busif [get_board_part_interfaces -filter "BUSDEF_NAME == diff_clock_rtl"] {
set type [get_property PARAM.TYPE $busif]
if { $type == "" } {
set board_clock_busifs $busif
break
}
}
if { $board_clock_busifs ne "" } {
apply_board_connection -board_interface $board_clock_busifs -ip_intf sys_clk_0/CLK_IN1_D -diagram [current_bd_design]
set is_board_clock_found 1
} else {
# check for single ended clock
set board_sclock_busifs [lindex [get_board_part_interfaces -filter "BUSDEF_NAME == clock_rtl"] 0 ]
if { $board_sclock_busifs ne "" } {
apply_board_connection -board_interface $board_sclock_busifs -ip_intf sys_clk_0/clock_CLK_IN1 -diagram [current_bd_design]
set external_clk [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/clk_in1]]]
if { $external_clk ne "" } {
set external_clock_port [get_property NAME $external_clk]
}
set is_board_clock_found 1
} else {
send_msg "ptgen 51-200" WARNING "No clock interface found in current_board, Users may need to specify the location constraints manually."
}
}
} else {
send_msg "ptgen 51-201" WARNING "No board selected in current_project. Users may need to specify the location constraints manually."
}
#if there is no corresponding board interface found, assume constraints will be provided manually while pin planning.
if { $is_board_reset_found == 0 } {
create_bd_port -dir I -type rst reset_rtl
set_property CONFIG.POLARITY [get_property CONFIG.POLARITY [get_bd_pins sys_clk_0/reset]] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_pins sys_reset_0/ext_reset_in] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_ports reset_rtl] [get_bd_pins sys_clk_0/reset]
set external_reset_port reset_rtl
}
if { $is_board_clock_found == 0 } {
create_bd_port -dir I -type clk clock_rtl
connect_bd_net [get_bd_pins sys_clk_0/clk_in1] [get_bd_ports clock_rtl]
set external_clock_port clock_rtl
}
#Avoid IPI DRC, make clock port synchronous to reset
if { $external_clock_port ne "" && $external_reset_port ne "" } {
set_property CONFIG.ASSOCIATED_RESET $external_reset_port [get_bd_ports $external_clock_port]
}
# Connect other sys_reset pins
connect_bd_net [get_bd_pins sys_reset_0/slowest_sync_clk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins sys_clk_0/locked] [get_bd_pins sys_reset_0/dcm_locked]
# Create instance: MIPI_CSI_2_RX_0, and set properties
set MIPI_CSI_2_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_CSI_2_RX:1.0 MIPI_CSI_2_RX_0 ]
# Create instance: jtag_axi_0, and set properties
set jtag_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:jtag_axi jtag_axi_0 ]
set_property -dict [list CONFIG.PROTOCOL {0}] [get_bd_cells jtag_axi_0]
connect_bd_net [get_bd_pins jtag_axi_0/aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins jtag_axi_0/aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_peri_interconnect, and set properties
set axi_peri_interconnect [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect axi_peri_interconnect ]
connect_bd_net [get_bd_pins axi_peri_interconnect/ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/ARESETN] [get_bd_pins sys_reset_0/interconnect_aresetn]
set_property -dict [ list CONFIG.NUM_SI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins jtag_axi_0/M_AXI] [get_bd_intf_pins axi_peri_interconnect/S00_AXI]
set_property -dict [ list CONFIG.NUM_MI {3} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_net [get_bd_pins axi_peri_interconnect/M01_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M01_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_net [get_bd_pins axi_peri_interconnect/M02_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M02_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Connect all clock & reset of MIPI_CSI_2_RX_0 slave interfaces..
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M00_AXI] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_LITE]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_lite_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_lite_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M01_AXI] [get_bd_intf_pins MIPI_CSI_2_RX_0/S_AXI_INTR]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_intr_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/s_axi_intr_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_gpio_irq, and set properties
set axi_gpio_irq [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio axi_gpio_irq ]
set_property -dict [ list CONFIG.C_ALL_INPUTS {1} CONFIG.C_GPIO_WIDTH {1} ] $axi_gpio_irq
connect_bd_net [get_bd_pins axi_gpio_irq/s_axi_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_gpio_irq/s_axi_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins axi_gpio_irq/S_AXI] [get_bd_intf_pins axi_peri_interconnect/M02_AXI]
connect_bd_net [get_bd_pins MIPI_CSI_2_RX_0/irq] [get_bd_pins axi_gpio_irq/gpio_io_i]
# Auto assign address
assign_bd_address
# Copy all address to MIPI_CSI_2_RX_v1_0_include.tcl file
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_CSI_2_RX_v1_0_include.tcl"
set fp [open $offset_file "w"]
puts $fp "# Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_axi_gpio_irq_Reg ]]
puts $fp "set axi_gpio_irq_addr ${offset}"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_CSI_2_RX_0_S_AXI_INTR_* ]]
puts $fp "set s_axi_intr_addr ${offset}"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_CSI_2_RX_0_S_AXI_LITE_* ]]
puts $fp "set s_axi_lite_addr ${offset}"
close $fp
}
# Set IP Repository and Update IP Catalogue
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_CSI_2_RX:1.0]]]]
set hw_test_file ${ip_path}/example_designs/debug_hw_design/MIPI_CSI_2_RX_v1_0_hw_test.tcl
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_CSI_2_RX_v1_0_hw_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
set intf_address_include_file ""
create_ipi_design intf_address_include_file ${design_name}
save_bd_design
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
puts "-------------------------------------------------------------------------------------------------"
puts "INFO NEXT STEPS : Until this stage, debug hardware design has been created, "
puts " please perform following steps to test design in targeted board."
puts "1. Generate bitstream"
puts "2. Setup your targeted board, open hardware manager and open new(or existing) hardware target"
puts "3. Download generated bitstream"
puts "4. Run generated hardware test using below command, this invokes basic read/write operation"
puts " to every interface present in the peripheral : xilinx.com:user:myip:1.0"
puts " : source -notrace ${hw_test_file}"
puts "-------------------------------------------------------------------------------------------------"
@@ -1,111 +1,111 @@
-------------------------------------------------------------------------------
--
-- File: CRC16_behavioral.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
-- Additional Comments: Sub-optimal implementation of CRC-16, with untested
-- bByteIgnore.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CRC16 is
Generic (
kLaneCount : natural range 1 to 4 := 2
);
Port (
ByteClk : in STD_LOGIC;
bData : in STD_LOGIC_VECTOR (kLaneCount*8-1 downto 0);
bDataEnable : in std_logic;
bKeep : in STD_LOGIC_VECTOR (kLaneCount-1 downto 0);
bCRC : out STD_LOGIC_VECTOR (15 downto 0);
bRst : in STD_LOGIC);
end CRC16;
architecture Behavioral of CRC16 is
function crc16_serial ( crc : std_logic_vector;
data_in : std_logic) return std_logic_vector is
variable crc_new : std_logic_vector(15 downto 0);
begin
if ((crc(0) xor data_in) = '1') then
crc_new := ('0' & crc(15 downto 1)) xor x"8408";
else
crc_new := '0' & crc(15 downto 1);
end if;
return crc_new;
end crc16_serial;
signal crc : std_logic_vector(15 downto 0);
begin
process(ByteClk)
variable crc_temp : std_logic_vector(15 downto 0);
begin
if Rising_Edge(ByteClk) then
if (bRst = '1') then
crc <= x"FFFF";
elsif (bDataEnable = '1') then
crc_temp := crc;
if std_match(bKeep, "1111") then
for i in 0 to 32-0*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "0111") then
for i in 0 to 32-1*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "-011") then
for i in 0 to 32-2*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "--01") then
for i in 0 to 32-3*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
end if;
crc <= crc_temp;
end if;
end if;
end process;
bCRC <= crc;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: CRC16_behavioral.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
-- Additional Comments: Sub-optimal implementation of CRC-16, with untested
-- bByteIgnore.
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity CRC16 is
Generic (
kLaneCount : natural range 1 to 4 := 2
);
Port (
ByteClk : in STD_LOGIC;
bData : in STD_LOGIC_VECTOR (kLaneCount*8-1 downto 0);
bDataEnable : in std_logic;
bKeep : in STD_LOGIC_VECTOR (kLaneCount-1 downto 0);
bCRC : out STD_LOGIC_VECTOR (15 downto 0);
bRst : in STD_LOGIC);
end CRC16;
architecture Behavioral of CRC16 is
function crc16_serial ( crc : std_logic_vector;
data_in : std_logic) return std_logic_vector is
variable crc_new : std_logic_vector(15 downto 0);
begin
if ((crc(0) xor data_in) = '1') then
crc_new := ('0' & crc(15 downto 1)) xor x"8408";
else
crc_new := '0' & crc(15 downto 1);
end if;
return crc_new;
end crc16_serial;
signal crc : std_logic_vector(15 downto 0);
begin
process(ByteClk)
variable crc_temp : std_logic_vector(15 downto 0);
begin
if Rising_Edge(ByteClk) then
if (bRst = '1') then
crc <= x"FFFF";
elsif (bDataEnable = '1') then
crc_temp := crc;
if std_match(bKeep, "1111") then
for i in 0 to 32-0*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "0111") then
for i in 0 to 32-1*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "-011") then
for i in 0 to 32-2*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
elsif std_match(bKeep, "--01") then
for i in 0 to 32-3*8-1 loop
crc_temp := crc16_serial(crc_temp, bData(i));
end loop;
end if;
crc <= crc_temp;
end if;
end if;
end process;
bCRC <= crc;
end Behavioral;
@@ -1,199 +1,199 @@
-------------------------------------------------------------------------------
--
-- File: DebugLib.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DebugLib is
COMPONENT ila_rxclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe10 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe11 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe12 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe13 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_vidclk
PORT (
clk : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe10 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe11 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe12 : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
probe13 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe14 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe15 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe16 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe17 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe18 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe19 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe20 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe21 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe22 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe23 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe24 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe25 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe26 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe27 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe28 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe29 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe30 : IN STD_LOGIC_VECTOR(39 DOWNTO 0);
probe31 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe32 : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
probe33 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe34 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe35 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_rxclk_lane
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT ;
type DebugLMLane_t is record
rbSkwRdEn : std_logic;
rbSkwWrEn : std_logic;
rbSkwFull : std_logic;
rbActiveHS : std_logic;
rbSyncHS : std_logic;
rbValidHS : std_logic;
rbDataHS : std_logic_vector(7 downto 0);
end record;
constant C_M_AXIS_TDATA_WIDTH : natural := 40;
constant kMaxLaneCount : natural := 4;
type DebugLMLanes_t is array(0 to kMaxLaneCount - 1) of DebugLMLane_t;
type DebugLM_t is record
state : std_logic_vector(2 downto 0);
rbByteCnt : std_logic_vector(1 downto 0);
end record;
type DebugLLP_t is record
-- LLP CDC FIFO signals, RxByteClkHS domain
rbRst : std_logic;
rbOvf : std_logic;
rbFIFO_Rstn : std_logic;
-- LLP CDC FIFO signals, video_clk domain
mRst : std_logic;
mFIFO_Tvalid : std_logic;
mFIFO_Tready : std_logic;
mFIFO_Tlast : std_logic;
mFIFO_Tdata : std_logic_vector(kMaxLaneCount*8-1 downto 0);
mFIFO_Tkeep : std_logic_vector(kMaxLaneCount-1 downto 0);
mIsHeader : std_logic; -- '1' for CSI-2 header
mECC_En : std_logic; -- Enable signal for ECC processing
mECC_Ready : std_logic; -- ECC block ready to accept new data
mECC_Valid : std_logic; -- ECC processing done, output valid
mECC_Error : std_logic; -- ECC processing done, input had errors
mWC : std_logic_vector(15 downto 0); --Word Count from header
mDT : std_logic_vector(5 downto 0); --Data Type from header
mFlush : std_logic; -- flushes packet from CDC FIFO
mKeep : std_logic; -- passes flushed packet through
mWordCount : std_logic_vector(15 downto 0);
-- Counted, CRC- and header-stripped packet
mReg_Tvalid : std_logic;
mReg_Tready : std_logic;
mReg_Tlast : std_logic;
mReg_Tuser : std_logic;
mReg_Tdata : std_logic_vector(kMaxLaneCount*8-1 downto 0);
mReg_Tkeep : std_logic_vector(kMaxLaneCount-1 downto 0);
mCRC_Sent : std_logic_vector(15 downto 0); -- Transmitted packet CRC
mCRC_En : std_logic; -- Enable signal for CRC processing
mCRC_Rst : std_logic; -- Reset signal for CRC processing
mCRC_Out : std_logic_vector(15 downto 0); -- Receiver packet CRC
-- Video-formatted packet written to Line Buffer
mFmt_Tvalid : std_logic;
mFmt_Tready : std_logic;
mFmt_Tlast : std_logic;
mFmt_Tuser : std_logic;
mFmt_Tdata : std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
mFmt_cnt : std_logic_vector(2 downto 0);
mBufDataCnt : std_logic_vector(10 downto 0);
end record;
end package;
-------------------------------------------------------------------------------
--
-- File: DebugLib.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DebugLib is
COMPONENT ila_rxclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe10 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe11 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe12 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe13 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_vidclk
PORT (
clk : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe10 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe11 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe12 : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
probe13 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe14 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe15 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe16 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe17 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe18 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe19 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe20 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
probe21 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe22 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe23 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe24 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe25 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
probe26 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe27 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe28 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe29 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe30 : IN STD_LOGIC_VECTOR(39 DOWNTO 0);
probe31 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe32 : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
probe33 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe34 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe35 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_rxclk_lane
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT ;
type DebugLMLane_t is record
rbSkwRdEn : std_logic;
rbSkwWrEn : std_logic;
rbSkwFull : std_logic;
rbActiveHS : std_logic;
rbSyncHS : std_logic;
rbValidHS : std_logic;
rbDataHS : std_logic_vector(7 downto 0);
end record;
constant C_M_AXIS_TDATA_WIDTH : natural := 40;
constant kMaxLaneCount : natural := 4;
type DebugLMLanes_t is array(0 to kMaxLaneCount - 1) of DebugLMLane_t;
type DebugLM_t is record
state : std_logic_vector(2 downto 0);
rbByteCnt : std_logic_vector(1 downto 0);
end record;
type DebugLLP_t is record
-- LLP CDC FIFO signals, RxByteClkHS domain
rbRst : std_logic;
rbOvf : std_logic;
rbFIFO_Rstn : std_logic;
-- LLP CDC FIFO signals, video_clk domain
mRst : std_logic;
mFIFO_Tvalid : std_logic;
mFIFO_Tready : std_logic;
mFIFO_Tlast : std_logic;
mFIFO_Tdata : std_logic_vector(kMaxLaneCount*8-1 downto 0);
mFIFO_Tkeep : std_logic_vector(kMaxLaneCount-1 downto 0);
mIsHeader : std_logic; -- '1' for CSI-2 header
mECC_En : std_logic; -- Enable signal for ECC processing
mECC_Ready : std_logic; -- ECC block ready to accept new data
mECC_Valid : std_logic; -- ECC processing done, output valid
mECC_Error : std_logic; -- ECC processing done, input had errors
mWC : std_logic_vector(15 downto 0); --Word Count from header
mDT : std_logic_vector(5 downto 0); --Data Type from header
mFlush : std_logic; -- flushes packet from CDC FIFO
mKeep : std_logic; -- passes flushed packet through
mWordCount : std_logic_vector(15 downto 0);
-- Counted, CRC- and header-stripped packet
mReg_Tvalid : std_logic;
mReg_Tready : std_logic;
mReg_Tlast : std_logic;
mReg_Tuser : std_logic;
mReg_Tdata : std_logic_vector(kMaxLaneCount*8-1 downto 0);
mReg_Tkeep : std_logic_vector(kMaxLaneCount-1 downto 0);
mCRC_Sent : std_logic_vector(15 downto 0); -- Transmitted packet CRC
mCRC_En : std_logic; -- Enable signal for CRC processing
mCRC_Rst : std_logic; -- Reset signal for CRC processing
mCRC_Out : std_logic_vector(15 downto 0); -- Receiver packet CRC
-- Video-formatted packet written to Line Buffer
mFmt_Tvalid : std_logic;
mFmt_Tready : std_logic;
mFmt_Tlast : std_logic;
mFmt_Tuser : std_logic;
mFmt_Tdata : std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
mFmt_cnt : std_logic_vector(2 downto 0);
mBufDataCnt : std_logic_vector(10 downto 0);
end record;
end package;
@@ -1,177 +1,177 @@
-------------------------------------------------------------------------------
--
-- File: ECC.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
-- Description: The error correcting code used is a 7+1bits Hamming-modified
-- code (72,64) and the subset of it is 5+1bits or (30,24).
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ECC is
Port (
StreamClk : in std_logic;
sHeaderIn : in std_logic_vector(31 downto 0);
sCE : in std_logic;
sReady : out std_logic;
sHeaderOut : out std_logic_vector(31 downto 0);
sValid: out std_logic; --asserted for one cycle when ECC processing is done and correct data is present on sHeaderOut
sError: out std_logic; --asserted for one cycle when ECC processing detected an error
sRst : in std_logic
);
end ECC;
architecture Behavioral of ECC is
type bit_parity is array ( 0 to 23 ) of std_logic_vector(7 downto 0);
constant syndrome : bit_parity := ( "00000111", "00001011", "00001101", "00001110", "00010011", "00010101", "00010110", "00011001",
"00011010", "00011100", "00100011", "00100101", "00100110", "00101001", "00101010", "00101100",
"00110001", "00110010", "00110100", "00111000", "00011111", "00101111", "00110111", "00111011");
type state_type is (stReset, stIdle, stGenParity, stCorrect);
signal sState, sNstate : state_type;
signal sProcessing : std_logic;
signal sDataIn : std_logic_vector(23 downto 0); --24-bit data
signal sECCIn, sParity, sErrSyndrome : std_logic_vector(5 downto 0); --6-bit ECC
begin
sReady <= '1' when sState = stIdle else
'0';
InputRegister: process(StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sState = stIdle and sCE = '1') then
sECCIn <= sHeaderIn(29 downto 24);
sDataIn <= sHeaderIn(23 downto 0);
end if;
end if;
end process;
-- The syndrome table is used to determine which bits of data participate in
-- each parity bit. There are 24 syndromes, one for each data bit. Each syndrome
-- encodes which parity bits does the data bit participate in. For example,
-- syndrome(0)=00000111 means that sDataIn(0) and many other data bits are XOR'd
-- together to calculate parity(2), parity(1) and parity(0) (where the syndrome
-- bits are 1).
ParityGen: process(StreamClk)
variable parity : std_logic_vector(sParity'range);
begin
if Rising_Edge(StreamClk) then
if (sState = stGenParity) then
parity := (others => '0');
for iP in 0 to 5 loop
for iD in 0 to 23 loop
if (syndrome(iD)(iP) = '1') then
parity(iP) := parity(iP) xor sDataIn(iD);
end if;
end loop;
end loop;
sParity <= parity;
sErrSyndrome <= parity xor sECCIn;
end if;
end if;
end process;
Correction: process(StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sState = stCorrect) then
sValid <= '0'; sError <= '1'; -- unrecoverable error
sHeaderOut <= "00" & sErrSyndrome & sDataIn; -- debug output
case (sErrSyndrome) is
when "000000" => --no error
sHeaderOut <= "00" & sECCIn & sDataIn;
sValid <= '1'; sError <= '0';
when "000001" | "000010" | "000100" | "001000" | "010000" | "100000" =>
--if error syndrome only has one bit set, it indicates that the ECC is incorrect
sHeaderOut <= "00" & (sECCIn xor sErrSyndrome) & sDataIn; --flip the bit
sValid <= '1'; sError <= '1';
when others =>
--error in data, try to correct
for iD in 0 to 23 loop
-- if error syndrome matches a value in the syndrome matrix, the
-- corresponding data bit is incorrect
if (syndrome(iD)(5 downto 0) = sErrSyndrome) then
sHeaderOut <= "00" & sECCIn & sDataIn;
sHeaderOut(iD) <= not sDataIn(iD);
sValid <= '1'; sError <= '1';
end if;
end loop;
end case;
else --sState/=stCorrect
sValid <= '0'; sError <= '0';
end if;
end if;
end process;
SYNC_PROC: process (StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sRst = '1') then
sState <= stReset;
else
sState <= sNstate;
end if;
end if;
end process;
NEXT_STATE_DECODE: process (sState, sCE)
begin
sNstate <= sState; --default is to stay in current sState
case (sState) is
when stReset =>
sNstate <= stIdle;
when stIdle =>
if (sCE = '1') then
sNstate <= stGenParity;
end if;
when stGenParity => -- calculate all parity bits
sNstate <= stCorrect;
when stCorrect => -- compare ECC, calculate error syndrome and correct data, if possible
sNstate <= stIdle;
when others =>
sNstate <= stReset;
end case;
end process;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: ECC.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
-- Description: The error correcting code used is a 7+1bits Hamming-modified
-- code (72,64) and the subset of it is 5+1bits or (30,24).
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ECC is
Port (
StreamClk : in std_logic;
sHeaderIn : in std_logic_vector(31 downto 0);
sCE : in std_logic;
sReady : out std_logic;
sHeaderOut : out std_logic_vector(31 downto 0);
sValid: out std_logic; --asserted for one cycle when ECC processing is done and correct data is present on sHeaderOut
sError: out std_logic; --asserted for one cycle when ECC processing detected an error
sRst : in std_logic
);
end ECC;
architecture Behavioral of ECC is
type bit_parity is array ( 0 to 23 ) of std_logic_vector(7 downto 0);
constant syndrome : bit_parity := ( "00000111", "00001011", "00001101", "00001110", "00010011", "00010101", "00010110", "00011001",
"00011010", "00011100", "00100011", "00100101", "00100110", "00101001", "00101010", "00101100",
"00110001", "00110010", "00110100", "00111000", "00011111", "00101111", "00110111", "00111011");
type state_type is (stReset, stIdle, stGenParity, stCorrect);
signal sState, sNstate : state_type;
signal sProcessing : std_logic;
signal sDataIn : std_logic_vector(23 downto 0); --24-bit data
signal sECCIn, sParity, sErrSyndrome : std_logic_vector(5 downto 0); --6-bit ECC
begin
sReady <= '1' when sState = stIdle else
'0';
InputRegister: process(StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sState = stIdle and sCE = '1') then
sECCIn <= sHeaderIn(29 downto 24);
sDataIn <= sHeaderIn(23 downto 0);
end if;
end if;
end process;
-- The syndrome table is used to determine which bits of data participate in
-- each parity bit. There are 24 syndromes, one for each data bit. Each syndrome
-- encodes which parity bits does the data bit participate in. For example,
-- syndrome(0)=00000111 means that sDataIn(0) and many other data bits are XOR'd
-- together to calculate parity(2), parity(1) and parity(0) (where the syndrome
-- bits are 1).
ParityGen: process(StreamClk)
variable parity : std_logic_vector(sParity'range);
begin
if Rising_Edge(StreamClk) then
if (sState = stGenParity) then
parity := (others => '0');
for iP in 0 to 5 loop
for iD in 0 to 23 loop
if (syndrome(iD)(iP) = '1') then
parity(iP) := parity(iP) xor sDataIn(iD);
end if;
end loop;
end loop;
sParity <= parity;
sErrSyndrome <= parity xor sECCIn;
end if;
end if;
end process;
Correction: process(StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sState = stCorrect) then
sValid <= '0'; sError <= '1'; -- unrecoverable error
sHeaderOut <= "00" & sErrSyndrome & sDataIn; -- debug output
case (sErrSyndrome) is
when "000000" => --no error
sHeaderOut <= "00" & sECCIn & sDataIn;
sValid <= '1'; sError <= '0';
when "000001" | "000010" | "000100" | "001000" | "010000" | "100000" =>
--if error syndrome only has one bit set, it indicates that the ECC is incorrect
sHeaderOut <= "00" & (sECCIn xor sErrSyndrome) & sDataIn; --flip the bit
sValid <= '1'; sError <= '1';
when others =>
--error in data, try to correct
for iD in 0 to 23 loop
-- if error syndrome matches a value in the syndrome matrix, the
-- corresponding data bit is incorrect
if (syndrome(iD)(5 downto 0) = sErrSyndrome) then
sHeaderOut <= "00" & sECCIn & sDataIn;
sHeaderOut(iD) <= not sDataIn(iD);
sValid <= '1'; sError <= '1';
end if;
end loop;
end case;
else --sState/=stCorrect
sValid <= '0'; sError <= '0';
end if;
end if;
end process;
SYNC_PROC: process (StreamClk)
begin
if Rising_Edge(StreamClk) then
if (sRst = '1') then
sState <= stReset;
else
sState <= sNstate;
end if;
end if;
end process;
NEXT_STATE_DECODE: process (sState, sCE)
begin
sNstate <= sState; --default is to stay in current sState
case (sState) is
when stReset =>
sNstate <= stIdle;
when stIdle =>
if (sCE = '1') then
sNstate <= stGenParity;
end if;
when stGenParity => -- calculate all parity bits
sNstate <= stCorrect;
when stCorrect => -- compare ECC, calculate error syndrome and correct data, if possible
sNstate <= stIdle;
when others =>
sNstate <= stReset;
end case;
end process;
end Behavioral;
File diff suppressed because it is too large Load Diff
@@ -1,339 +1,339 @@
-------------------------------------------------------------------------------
--
-- File: LM.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.SimpleFIFO;
use work.DebugLib;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic;
dbgLMLane : out DebugLib.DebugLMLanes_t;
dbgLM : out DebugLib.DebugLM_t
);
end LM;
architecture Behavioral of LM is
type state_t is (stReset, stIdle, stWaitForReady, stWaitForValid, stReceive, stEndReceive, stError);
signal rbState, rbNstate : state_t;
signal rbByteCnt : natural range 0 to kMaxLaneCount - 1 := 0;
signal rbTvalidInt, rbMAxisTvalidInt, rbTlastInt, rbPartial : std_logic;
signal rbTdataInt : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal rbTkeepInt : std_logic_vector(kMaxLaneCount - 1 downto 0);
constant kAllOnes : std_logic_vector(kMaxLaneCount - 1 downto 0) := (others => '1');
alias rbDataHSInt is RxDataHS;
alias rbSyncHSInt is RxSyncHS;
alias rbValidHSInt is RxValidHS;
alias rbActiveHSInt is RxActiveHS;
signal rbRdEn, rbWrEn, rbFull : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbEnInt : std_logic;
-- De-skewed PPI data lanes
signal rbDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbActiveHS, rbActiveHS_q : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
-- VHDL-2008 back-port
function orv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '0';
begin
for i in vec'range loop
result := result or vec(i);
end loop;
return result;
end orv;
-- VHDL-2008 back-port
function andv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '1';
begin
for i in vec'range loop
result := result and vec(i);
end loop;
return result;
end andv;
begin
dbgLM.state <= std_logic_vector(to_unsigned(state_t'pos(rbState), 3));
dbgLM.rbByteCnt <= std_logic_vector(to_unsigned(rbByteCnt, 2));
-- Shallow, synchronous FIFOs for each data lane are used to delay data
-- on those that transmit earlier than the rest. Thus, data lanes
-- are de-skewed and their RxActiveHS edges aligned. This approach relies
-- on the timing of RxValidHS relative to the corresponding RxActiveHS to be
-- the same for all lanes.
DeskewFIFOs: for i in 0 to kLaneCount - 1 generate
dbgLMLane(i).rbSkwRdEn <= rbRdEn(i);
dbgLMLane(i).rbSkwWrEn <= rbEn;
dbgLMLane(i).rbSkwFull <= rbFull(i);
dbgLMLane(i).rbActiveHS <= rbActiveHS(i);
dbgLMLane(i).rbSyncHS <= rbSyncHS(i);
dbgLMLane(i).rbValidHS <= rbValidHS(i);
dbgLMLane(i).rbDataHS <= rbDataHS((i+1)*8-1 downto i*8);
DeskewFIFOx: entity work.SimpleFIFO
Generic map (kDataWidth => 11)
Port map (
InClk => RxByteClkHS,
iRst => rbRst,
iDataIn => rbActiveHSInt(i) & rbSyncHSInt(i) & rbValidHSInt(i) & rbDataHSInt((i+1)*8-1 downto i*8),
iWrEn => rbWrEn(i),
iRdEn => rbRdEn(i),
iFull => rbFull(i),
iEmpty => open,
iDataOut(10) => rbActiveHS(i),
iDataOut(9) => rbSyncHS(i),
iDataOut(8) => rbValidHS(i),
iDataOut(7 downto 0) => rbDataHS((i+1)*8-1 downto i*8)
);
rbWrEn(i) <= rbEnInt;
rbRdEn(i) <= '0' when (rbState = stReset) else
'0' when (rbActiveHS(i) = '1' and andv(rbActiveHS) = '0' and andv(rbActiveHS_q) = '0') else -- lane is active while others not, pause it
'0' when (andv(rbActiveHS) = '1' and rbState = stWaitForReady) else -- all lanes active, but we are held up by rbMAxisTready
'1';
process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRdEn(i) = '1') then
rbActiveHS_q(i) <= rbActiveHS(i);
end if;
end if;
end process;
end generate DeskewFIFOs;
InternalEnable: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbState = stReset) then
rbEnInt <= '0';
else
rbEnInt <= rbEn;
end if;
end if;
end process;
-- The deskew error flag is set when one of the lanes was halted for so long awaiting valid data on the
-- other lanes that the FIFOs filled up. Possible causes:
-- not all lanes in the specified kLaneCount are receiving data, or
-- lane skew larger than 8 RxByteClkHS periods.
DeskewFullFlag: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbErrSkew <= '0';
elsif (rbEnInt = '1' and orv(rbFull) = '1') then
rbErrSkew <= '1';
end if;
end if;
end process;
-- The overflow error flag set whenever we provide valid data on the AXI-Stream
-- and the slave is not ready to receive. Buffering should be done downstream.
OverflowFlag: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbErrOvf <= '0';
elsif (rbMAxisTvalidInt = '1' and rbMAxisTready = '0') then
rbErrOvf <= '1';
end if;
end if;
end process;
SYNC_PROC: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbState <= stReset;
else
rbState <= rbNstate;
end if;
end if;
end process;
ByteRegisters: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbTdataInt <= (others => '0');
rbTkeepInt <= (others => '0');
else
if (rbState = stReceive or rbState = stWaitForValid) then
--Walk the valid signals, register valid bytes and set keep bits
--Order is important: last bytes are filled from low-order lanes to high-order ones
if (rbTvalidInt = '1') then
rbTkeepInt <= (others => '0');
end if;
for i in 0 to kLaneCount - 1 loop
if (rbValidHS(i) = '0') then
exit;
end if;
rbTdataInt((i+rbByteCnt+1)*8-1 downto (i+rbByteCnt)*8) <= rbDataHS((i+1)*8-1 downto i*8);
rbTkeepInt(i+rbByteCnt) <= '1';
end loop;
end if;
end if;
end if;
end process;
BufferCounter: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbState = stIdle) then
rbByteCnt <= 0;
else
if (rbState = stWaitForValid and orv(rbValidHS) = '1') or (rbState = stReceive) then
if (rbByteCnt = kMaxLaneCount - kLaneCount) then
rbByteCnt <= 0;
else
rbByteCnt <= rbByteCnt + kLaneCount;
end if;
end if;
end if;
end if;
end process;
rbTValidInt <= '1' when ((rbState = stReceive and (rbByteCnt = 0 or orv(rbValidHS) = '0')) -- buffer full, or no more bytes
or (rbState = stEndReceive)) -- flush partial packet
else '0';
rbTlastInt <= '1' when (rbState = stReceive and orv(rbValidHS) = '0') -- no more bytes
or (rbState = stEndReceive) -- partial packet is last
else '0';
OutputRegister: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbMAxisTdata <= rbTdataInt;
rbMAxisTkeep <= rbTkeepInt;
rbMAxisTvalidInt <= rbTvalidInt;
rbMAxisTlast <= rbTlastInt;
else
rbMAxisTvalidInt <= rbTvalidInt;
if (rbTvalidInt = '1') then
rbMAxisTdata <= rbTdataInt;
rbMAxisTkeep <= rbTkeepInt;
rbMAxisTlast <= rbTlastInt;
end if;
end if;
end if;
end process;
rbMAxisTvalid <= rbMAxisTvalidInt;
NEXT_STATE_DECODE: process (rbState, rbActiveHS, rbValidHS, rbFull, rbMAxisTready)
begin
rbNstate <= rbState; --default is to stay in current rbState
case (rbState) is
when stReset =>
if (orv(rbFull) = '0') then
rbNstate <= stWaitForReady;
end if;
when stWaitForReady =>
if (orv(rbFull) = '1') then
rbNstate <= stError;
elsif (rbMAxisTready = '1') then
rbNstate <= stIdle;
end if;
when stIdle =>
if (orv(rbFull) = '1') then --deskew overflow
rbNstate <= stError;
elsif (andv(rbActiveHS) = '1') then --when all channels present active
rbNstate <= stWaitForValid;
end if;
when stWaitForValid => -- in High-Speed reception but no data yet
if (andv(rbValidHS) = '1') then -- first full data
rbNstate <= stReceive;
elsif (orv(rbValidHS) = '1') then -- partial data; first is also the last
rbNstate <= stEndReceive;
end if;
when stReceive => -- we are receiving High-Speed data
if (orv(rbValidHS) = '0') then
rbNstate <= stIdle; --no more data
elsif (andv(rbValidHS) = '0') then -- partial data; last packet
rbNstate <= stEndReceive;
end if;
when stEndReceive =>
rbNstate <= stIdle; -- last packet seen
when stError =>
if (orv(rbActiveHS) = '0') then
rbNstate <= stIdle;
end if;
when others =>
rbNstate <= stIdle;
end case;
end process;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: LM.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library work;
use work.SimpleFIFO;
use work.DebugLib;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic;
dbgLMLane : out DebugLib.DebugLMLanes_t;
dbgLM : out DebugLib.DebugLM_t
);
end LM;
architecture Behavioral of LM is
type state_t is (stReset, stIdle, stWaitForReady, stWaitForValid, stReceive, stEndReceive, stError);
signal rbState, rbNstate : state_t;
signal rbByteCnt : natural range 0 to kMaxLaneCount - 1 := 0;
signal rbTvalidInt, rbMAxisTvalidInt, rbTlastInt, rbPartial : std_logic;
signal rbTdataInt : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal rbTkeepInt : std_logic_vector(kMaxLaneCount - 1 downto 0);
constant kAllOnes : std_logic_vector(kMaxLaneCount - 1 downto 0) := (others => '1');
alias rbDataHSInt is RxDataHS;
alias rbSyncHSInt is RxSyncHS;
alias rbValidHSInt is RxValidHS;
alias rbActiveHSInt is RxActiveHS;
signal rbRdEn, rbWrEn, rbFull : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbEnInt : std_logic;
-- De-skewed PPI data lanes
signal rbDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbActiveHS, rbActiveHS_q : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
-- VHDL-2008 back-port
function orv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '0';
begin
for i in vec'range loop
result := result or vec(i);
end loop;
return result;
end orv;
-- VHDL-2008 back-port
function andv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '1';
begin
for i in vec'range loop
result := result and vec(i);
end loop;
return result;
end andv;
begin
dbgLM.state <= std_logic_vector(to_unsigned(state_t'pos(rbState), 3));
dbgLM.rbByteCnt <= std_logic_vector(to_unsigned(rbByteCnt, 2));
-- Shallow, synchronous FIFOs for each data lane are used to delay data
-- on those that transmit earlier than the rest. Thus, data lanes
-- are de-skewed and their RxActiveHS edges aligned. This approach relies
-- on the timing of RxValidHS relative to the corresponding RxActiveHS to be
-- the same for all lanes.
DeskewFIFOs: for i in 0 to kLaneCount - 1 generate
dbgLMLane(i).rbSkwRdEn <= rbRdEn(i);
dbgLMLane(i).rbSkwWrEn <= rbEn;
dbgLMLane(i).rbSkwFull <= rbFull(i);
dbgLMLane(i).rbActiveHS <= rbActiveHS(i);
dbgLMLane(i).rbSyncHS <= rbSyncHS(i);
dbgLMLane(i).rbValidHS <= rbValidHS(i);
dbgLMLane(i).rbDataHS <= rbDataHS((i+1)*8-1 downto i*8);
DeskewFIFOx: entity work.SimpleFIFO
Generic map (kDataWidth => 11)
Port map (
InClk => RxByteClkHS,
iRst => rbRst,
iDataIn => rbActiveHSInt(i) & rbSyncHSInt(i) & rbValidHSInt(i) & rbDataHSInt((i+1)*8-1 downto i*8),
iWrEn => rbWrEn(i),
iRdEn => rbRdEn(i),
iFull => rbFull(i),
iEmpty => open,
iDataOut(10) => rbActiveHS(i),
iDataOut(9) => rbSyncHS(i),
iDataOut(8) => rbValidHS(i),
iDataOut(7 downto 0) => rbDataHS((i+1)*8-1 downto i*8)
);
rbWrEn(i) <= rbEnInt;
rbRdEn(i) <= '0' when (rbState = stReset) else
'0' when (rbActiveHS(i) = '1' and andv(rbActiveHS) = '0' and andv(rbActiveHS_q) = '0') else -- lane is active while others not, pause it
'0' when (andv(rbActiveHS) = '1' and rbState = stWaitForReady) else -- all lanes active, but we are held up by rbMAxisTready
'1';
process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRdEn(i) = '1') then
rbActiveHS_q(i) <= rbActiveHS(i);
end if;
end if;
end process;
end generate DeskewFIFOs;
InternalEnable: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbState = stReset) then
rbEnInt <= '0';
else
rbEnInt <= rbEn;
end if;
end if;
end process;
-- The deskew error flag is set when one of the lanes was halted for so long awaiting valid data on the
-- other lanes that the FIFOs filled up. Possible causes:
-- not all lanes in the specified kLaneCount are receiving data, or
-- lane skew larger than 8 RxByteClkHS periods.
DeskewFullFlag: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbErrSkew <= '0';
elsif (rbEnInt = '1' and orv(rbFull) = '1') then
rbErrSkew <= '1';
end if;
end if;
end process;
-- The overflow error flag set whenever we provide valid data on the AXI-Stream
-- and the slave is not ready to receive. Buffering should be done downstream.
OverflowFlag: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbErrOvf <= '0';
elsif (rbMAxisTvalidInt = '1' and rbMAxisTready = '0') then
rbErrOvf <= '1';
end if;
end if;
end process;
SYNC_PROC: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbState <= stReset;
else
rbState <= rbNstate;
end if;
end if;
end process;
ByteRegisters: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbTdataInt <= (others => '0');
rbTkeepInt <= (others => '0');
else
if (rbState = stReceive or rbState = stWaitForValid) then
--Walk the valid signals, register valid bytes and set keep bits
--Order is important: last bytes are filled from low-order lanes to high-order ones
if (rbTvalidInt = '1') then
rbTkeepInt <= (others => '0');
end if;
for i in 0 to kLaneCount - 1 loop
if (rbValidHS(i) = '0') then
exit;
end if;
rbTdataInt((i+rbByteCnt+1)*8-1 downto (i+rbByteCnt)*8) <= rbDataHS((i+1)*8-1 downto i*8);
rbTkeepInt(i+rbByteCnt) <= '1';
end loop;
end if;
end if;
end if;
end process;
BufferCounter: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbState = stIdle) then
rbByteCnt <= 0;
else
if (rbState = stWaitForValid and orv(rbValidHS) = '1') or (rbState = stReceive) then
if (rbByteCnt = kMaxLaneCount - kLaneCount) then
rbByteCnt <= 0;
else
rbByteCnt <= rbByteCnt + kLaneCount;
end if;
end if;
end if;
end if;
end process;
rbTValidInt <= '1' when ((rbState = stReceive and (rbByteCnt = 0 or orv(rbValidHS) = '0')) -- buffer full, or no more bytes
or (rbState = stEndReceive)) -- flush partial packet
else '0';
rbTlastInt <= '1' when (rbState = stReceive and orv(rbValidHS) = '0') -- no more bytes
or (rbState = stEndReceive) -- partial packet is last
else '0';
OutputRegister: process (RxByteClkHS)
begin
if Rising_Edge(RxByteClkHS) then
if (rbRst = '1') then
rbMAxisTdata <= rbTdataInt;
rbMAxisTkeep <= rbTkeepInt;
rbMAxisTvalidInt <= rbTvalidInt;
rbMAxisTlast <= rbTlastInt;
else
rbMAxisTvalidInt <= rbTvalidInt;
if (rbTvalidInt = '1') then
rbMAxisTdata <= rbTdataInt;
rbMAxisTkeep <= rbTkeepInt;
rbMAxisTlast <= rbTlastInt;
end if;
end if;
end if;
end process;
rbMAxisTvalid <= rbMAxisTvalidInt;
NEXT_STATE_DECODE: process (rbState, rbActiveHS, rbValidHS, rbFull, rbMAxisTready)
begin
rbNstate <= rbState; --default is to stay in current rbState
case (rbState) is
when stReset =>
if (orv(rbFull) = '0') then
rbNstate <= stWaitForReady;
end if;
when stWaitForReady =>
if (orv(rbFull) = '1') then
rbNstate <= stError;
elsif (rbMAxisTready = '1') then
rbNstate <= stIdle;
end if;
when stIdle =>
if (orv(rbFull) = '1') then --deskew overflow
rbNstate <= stError;
elsif (andv(rbActiveHS) = '1') then --when all channels present active
rbNstate <= stWaitForValid;
end if;
when stWaitForValid => -- in High-Speed reception but no data yet
if (andv(rbValidHS) = '1') then -- first full data
rbNstate <= stReceive;
elsif (orv(rbValidHS) = '1') then -- partial data; first is also the last
rbNstate <= stEndReceive;
end if;
when stReceive => -- we are receiving High-Speed data
if (orv(rbValidHS) = '0') then
rbNstate <= stIdle; --no more data
elsif (andv(rbValidHS) = '0') then -- partial data; last packet
rbNstate <= stEndReceive;
end if;
when stEndReceive =>
rbNstate <= stIdle; -- last packet seen
when stError =>
if (orv(rbActiveHS) = '0') then
rbNstate <= stIdle;
end if;
when others =>
rbNstate <= stIdle;
end case;
end process;
end Behavioral;
@@ -1,438 +1,438 @@
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI2_Rx.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.DebugLib.all;
entity MIPI_CSI2_Rx is
Generic (
kTargetDT : string := "RAW10";
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
rbRxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
rbRxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aDEnable : out STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic;
video_aclk : in std_logic;
vEnable : in std_logic --TODO proper buffer flushing on disable, perhaps waiting on active transfer to end
);
end MIPI_CSI2_Rx;
architecture Behavioral of MIPI_CSI2_Rx is
component LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic;
dbgLMLane : out DebugLMLanes_t;
dbgLM : out DebugLM_t
);
end component LM;
component LLP is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4];
kTargetDT : string := "RAW10"
);
Port (
SAxisClk : in STD_LOGIC;
--Slave AXI-Stream
sAxisTdata : in std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
sAxisTkeep : in std_logic_vector(kMaxLaneCount - 1 downto 0);
sAxisTvalid : in std_logic;
sAxisTready : out std_logic;
sAxisTlast : in std_logic;
MAxisClk : in std_logic;
--Master AXI-Stream
mAxisTdata : out std_logic_vector(40 - 1 downto 0);
mAxisTvalid : out std_logic;
mAxisTready : in std_logic;
mAxisTlast : out std_logic;
mAxisTuser : out std_logic_vector(0 downto 0);
sOverflow : out std_logic;
aRst : in std_logic; -- global asynchronous reset; synchronized internally to both clock domains
dbgLLP : out DebugLLP_t
);
end component;
-- VHDL-2008 back-port
function orv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '0';
begin
for i in vec'range loop
result := result or vec(i);
end loop;
return result;
end orv;
-- VHDL-2008 back-port
function andv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '1';
begin
for i in vec'range loop
result := result and vec(i);
end loop;
return result;
end andv;
constant kMaxLaneCount : natural := 4;
signal rbLMAxisTdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal rbLMAxisTkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal rbLMAxisTvalid, rbLMAxisTlast : std_logic;
signal rbLMErrOvf, rbLMErrSkew : std_logic;
signal rbLLPAxisTready : std_logic;
signal rbRst_n, rbEn : std_logic;
signal vTready, vRst : std_logic;
signal dbgLMLane : DebugLMLanes_t;
signal dbgLM : DebugLM_t;
signal dbgLLP : DebugLLP_t;
signal rbRxClkTrigOut, vRxClkTrigOut, vTrigIn, vTrigInAck, rbTrigInAck : std_logic;
signal rbRxClkLaneTrigOut, vRxClkLaneTrigOut : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal aClkEnableInt : std_logic;
signal aDEnableInt : std_logic_vector(kMaxLaneCount - 1 downto 0);
begin
-- Synchronize video_aresetn into the RxByteClkHS domain
SyncReset: entity work.ResetBridge
generic map (
kPolarity => '0')
port map (
aRst => video_aresetn,
OutClk => RxByteClkHS,
oRst => rbRst_n);
-- Synchronize vEnable into the RxByteClkHS domain
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2, --use double FF synchronizer
kResetPolarity => '0')
port map (
aReset => rbRst_n,
aIn => vEnable,
OutClk => RxByteClkHS,
oOut => rbEn);
GlitchFree_vRst: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
vRst <= not video_aresetn;
end if;
end process;
PPI_Clock_Enable: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
aClkEnableInt <= vEnable and video_aresetn;
aDEnableInt <= (others => vEnable and video_aresetn);
end if;
end process;
aClkEnable <= aClkEnableInt;
-- Initially data lanes were only enabled when the LLP module below doing
-- data buffering was ready to receive data. However, this was problematic for
-- two reasons:
-- 1. not all lanes (clock and data) were enabled simultaneously and
-- 2. since LLP requires a few RxByteClkHS clock cycles to assert ready on its
-- slave port, the data lanes were only enabled after the clock lane was already
-- transmitting clock. The data lanes still needed Stop state of T_INIT long
-- at least to complete initialization after enablement, resulting in loss of
-- the first data packets.
-- Instead, we rely on LM to do a limited buffering upon exit from reset and
-- on T_CLK_PRE
--PPI_Data_Enable: process(video_aclk)
--begin
-- if Rising_Edge(video_aclk) then
-- if (video_aresetn = '0') then
-- aDEnableInt <= (others => '0');
-- else
-- if (vEnable = '0') then
-- aDEnableInt <= (others => '0');
-- elsif (vTready = '1') then --LLP buffer should be ready to receive data before enabling the PHY
-- aDEnableInt <= (others => '1');
-- end if;
-- end if;
-- end if;
--end process;
aDEnable <= aDEnableInt(kLaneCount-1 downto 0);
SyncAsyncTready: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2, --use double FF synchronizer
kResetPolarity => '0')
port map (
aReset => video_aresetn,
aIn => rbLLPAxisTready,
OutClk => video_aclk,
oOut => vTready);
-- Lane merger compacts the CSI-2 lane into a wide AXI-Stream bus
-- Both the input and output interfaces are synchronous to RxByteClkHS
-- and it does not buffer data
LM_inst: LM
Generic Map(
kMaxLaneCount => kMaxLaneCount,
kLaneCount => kLaneCount
)
Port Map(
RxByteClkHS => RxByteClkHS,
RxDataHS => rbRxDataHS,
RxSyncHS => rbRxSyncHS,
RxValidHS => rbRxValidHS,
RxActiveHS => rbRxActiveHS,
rbMAxisTdata => rbLMAxisTdata,
rbMAxisTkeep => rbLMAxisTkeep,
rbMAxisTvalid => rbLMAxisTvalid,
rbMAxisTready => rbLLPAxisTready,
rbMAxisTlast => rbLMAxisTlast,
rbErrSkew => rbLMErrSkew,
rbErrOvf => rbLMErrOvf,
rbEn => rbEn,
rbRst => not rbRst_n,
dbgLMLane => dbgLMLane,
dbgLM => dbgLM
);
-- Link-level protocol decodes short and long packets into frames, lines
-- and pixels. It synchronizes data from the MIPI clock domain (RxByteClkHS)
-- to the video pipeline domain video_aclk. It does error detection
-- and correction, filters data according to the target data type and
-- formats it according to UG934, ready to source a video processing
-- pipeline.
LLP_inst: LLP
Generic map (
kMaxLaneCount => kMaxLaneCount,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
kTargetDT => kTargetDT
)
Port map (
SAxisClk => RxByteClkHS,
--Slave AXI-Stream
sAxisTdata => rbLMAxisTdata,
sAxisTkeep => rbLMAxisTkeep,
sAxisTvalid => rbLMAxisTvalid,
sAxisTready => rbLLPAxisTready,
sAxisTlast => rbLMAxisTlast,
MAxisClk => video_aclk,
--Master AXI-Stream
mAxisTdata => m_axis_video_tdata,
mAxisTvalid => m_axis_video_tvalid,
mAxisTready => m_axis_video_tready,
mAxisTlast => m_axis_video_tlast,
mAxisTuser => m_axis_video_tuser,
aRst => vRst,
sOverflow => open,
dbgLLP => dbgLLP
);
----------------------------------------------------------------------------------
-- Debug modules
----------------------------------------------------------------------------------
GenerateDebug: if kDebug generate
ILARxClk : ila_rxclk
PORT MAP (
clk => RxByteClkHS,
trig_out => rbRxClkTrigOut,
trig_out_ack => rbTrigInAck,
probe0 => dbgLM.state,
probe1 => dbgLM.rbByteCnt,
probe2 => rbLMAxisTdata,
probe3 => rbLMAxisTkeep,
probe4(0) => rbLMAxisTvalid,
probe5(0) => rbLLPAxisTready,
probe6(0) => rbLMAxisTlast,
probe7(0) => rbLMErrSkew,
probe8(0) => rbLMErrOvf,
probe9(0) => dbgLLP.rbRst,
probe10(0) => dbgLLP.rbOvf,
probe11(0) => dbgLLP.rbFIFO_Rstn,
probe12(0) => rbRst_n,
probe13(0) => rbEn
);
ILAVidClk : ila_vidclk
PORT MAP (
clk => video_aclk,
trig_in => vTrigIn,
trig_in_ack => vTrigInAck,
probe0(0) => dbgLLP.mRst,
probe1(0) => dbgLLP.mFIFO_Tvalid,
probe2(0) => dbgLLP.mFIFO_Tready,
probe3(0) => dbgLLP.mFIFO_Tlast,
probe4 => dbgLLP.mFIFO_Tdata,
probe5 => dbgLLP.mFIFO_Tkeep,
probe6(0) => dbgLLP.mIsHeader,
probe7(0) => dbgLLP.mECC_En,
probe8(0) => dbgLLP.mECC_Ready,
probe9(0) => dbgLLP.mECC_Valid,
probe10(0) => dbgLLP.mECC_Error,
probe11 => dbgLLP.mWC,
probe12 => dbgLLP.mDT,
probe13(0) => dbgLLP.mFlush,
probe14(0) => dbgLLP.mKeep,
probe15 => dbgLLP.mWordCount,
probe16(0) => dbgLLP.mReg_Tvalid,
probe17(0) => dbgLLP.mReg_Tready,
probe18(0) => dbgLLP.mReg_Tlast,
probe19(0) => dbgLLP.mReg_Tuser,
probe20 => dbgLLP.mReg_Tdata,
probe21 => dbgLLP.mReg_Tkeep,
probe22 => dbgLLP.mCRC_Sent,
probe23(0) => dbgLLP.mCRC_En,
probe24(0) => dbgLLP.mCRC_Rst,
probe25 => dbgLLP.mCRC_Out,
probe26(0) => dbgLLP.mFmt_Tvalid,
probe27(0) => dbgLLP.mFmt_Tready,
probe28(0) => dbgLLP.mFmt_Tlast,
probe29(0) => dbgLLP.mFmt_Tuser,
probe30 => dbgLLP.mFmt_Tdata,
probe31 => dbgLLP.mFmt_cnt,
probe32 => dbgLLP.mBufDataCnt,
probe33(0) => aClkEnableInt,
probe34 => aDEnableInt,
probe35(0) => vTready
);
SyncAsyncTrigOut: entity work.SyncAsync
port map (
aReset => '0',
aIn => rbRxClkTrigOut,
OutClk => video_aclk,
oOut => vRxClkTrigOut);
SyncAsyncTrigAck: entity work.SyncAsync
port map (
aReset => '0',
aIn => vTrigInAck,
OutClk => RxByteClkHS,
oOut => rbTrigInAck);
ILA_LaneGen: for i in kLaneCount-1 downto 0 generate
ILARxClk_Lane : ila_rxclk_lane
PORT MAP (
clk => RxByteClkHS,
trig_out => rbRxClkLaneTrigOut(i),
trig_out_ack => rbTrigInAck,
probe0(0) => dbgLMLane(i).rbSkwRdEn,
probe1(0) => dbgLMLane(i).rbSkwWrEn,
probe2(0) => dbgLMLane(i).rbSkwFull,
probe3(0) => dbgLMLane(i).rbActiveHS,
probe4(0) => dbgLMLane(i).rbSyncHS,
probe5(0) => dbgLMLane(i).rbValidHS,
probe6 => dbgLMLane(i).rbDataHS
);
SyncAsyncTrigOut: entity work.SyncAsync
port map (
aReset => '0',
aIn => rbRxClkLaneTrigOut(i),
OutClk => video_aclk,
oOut => vRxClkLaneTrigOut(i));
end generate ILA_LaneGen;
vTrigIn <= orv(vRxClkLaneTrigOut) or vRxClkTrigOut;
end generate;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI2_Rx.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use work.DebugLib.all;
entity MIPI_CSI2_Rx is
Generic (
kTargetDT : string := "RAW10";
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
rbRxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
rbRxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aDEnable : out STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic;
video_aclk : in std_logic;
vEnable : in std_logic --TODO proper buffer flushing on disable, perhaps waiting on active transfer to end
);
end MIPI_CSI2_Rx;
architecture Behavioral of MIPI_CSI2_Rx is
component LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic;
dbgLMLane : out DebugLMLanes_t;
dbgLM : out DebugLM_t
);
end component LM;
component LLP is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4];
kTargetDT : string := "RAW10"
);
Port (
SAxisClk : in STD_LOGIC;
--Slave AXI-Stream
sAxisTdata : in std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
sAxisTkeep : in std_logic_vector(kMaxLaneCount - 1 downto 0);
sAxisTvalid : in std_logic;
sAxisTready : out std_logic;
sAxisTlast : in std_logic;
MAxisClk : in std_logic;
--Master AXI-Stream
mAxisTdata : out std_logic_vector(40 - 1 downto 0);
mAxisTvalid : out std_logic;
mAxisTready : in std_logic;
mAxisTlast : out std_logic;
mAxisTuser : out std_logic_vector(0 downto 0);
sOverflow : out std_logic;
aRst : in std_logic; -- global asynchronous reset; synchronized internally to both clock domains
dbgLLP : out DebugLLP_t
);
end component;
-- VHDL-2008 back-port
function orv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '0';
begin
for i in vec'range loop
result := result or vec(i);
end loop;
return result;
end orv;
-- VHDL-2008 back-port
function andv(vec : std_logic_vector) return std_logic is
variable result : std_logic := '1';
begin
for i in vec'range loop
result := result and vec(i);
end loop;
return result;
end andv;
constant kMaxLaneCount : natural := 4;
signal rbLMAxisTdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal rbLMAxisTkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal rbLMAxisTvalid, rbLMAxisTlast : std_logic;
signal rbLMErrOvf, rbLMErrSkew : std_logic;
signal rbLLPAxisTready : std_logic;
signal rbRst_n, rbEn : std_logic;
signal vTready, vRst : std_logic;
signal dbgLMLane : DebugLMLanes_t;
signal dbgLM : DebugLM_t;
signal dbgLLP : DebugLLP_t;
signal rbRxClkTrigOut, vRxClkTrigOut, vTrigIn, vTrigInAck, rbTrigInAck : std_logic;
signal rbRxClkLaneTrigOut, vRxClkLaneTrigOut : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal aClkEnableInt : std_logic;
signal aDEnableInt : std_logic_vector(kMaxLaneCount - 1 downto 0);
begin
-- Synchronize video_aresetn into the RxByteClkHS domain
SyncReset: entity work.ResetBridge
generic map (
kPolarity => '0')
port map (
aRst => video_aresetn,
OutClk => RxByteClkHS,
oRst => rbRst_n);
-- Synchronize vEnable into the RxByteClkHS domain
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2, --use double FF synchronizer
kResetPolarity => '0')
port map (
aReset => rbRst_n,
aIn => vEnable,
OutClk => RxByteClkHS,
oOut => rbEn);
GlitchFree_vRst: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
vRst <= not video_aresetn;
end if;
end process;
PPI_Clock_Enable: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
aClkEnableInt <= vEnable and video_aresetn;
aDEnableInt <= (others => vEnable and video_aresetn);
end if;
end process;
aClkEnable <= aClkEnableInt;
-- Initially data lanes were only enabled when the LLP module below doing
-- data buffering was ready to receive data. However, this was problematic for
-- two reasons:
-- 1. not all lanes (clock and data) were enabled simultaneously and
-- 2. since LLP requires a few RxByteClkHS clock cycles to assert ready on its
-- slave port, the data lanes were only enabled after the clock lane was already
-- transmitting clock. The data lanes still needed Stop state of T_INIT long
-- at least to complete initialization after enablement, resulting in loss of
-- the first data packets.
-- Instead, we rely on LM to do a limited buffering upon exit from reset and
-- on T_CLK_PRE
--PPI_Data_Enable: process(video_aclk)
--begin
-- if Rising_Edge(video_aclk) then
-- if (video_aresetn = '0') then
-- aDEnableInt <= (others => '0');
-- else
-- if (vEnable = '0') then
-- aDEnableInt <= (others => '0');
-- elsif (vTready = '1') then --LLP buffer should be ready to receive data before enabling the PHY
-- aDEnableInt <= (others => '1');
-- end if;
-- end if;
-- end if;
--end process;
aDEnable <= aDEnableInt(kLaneCount-1 downto 0);
SyncAsyncTready: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2, --use double FF synchronizer
kResetPolarity => '0')
port map (
aReset => video_aresetn,
aIn => rbLLPAxisTready,
OutClk => video_aclk,
oOut => vTready);
-- Lane merger compacts the CSI-2 lane into a wide AXI-Stream bus
-- Both the input and output interfaces are synchronous to RxByteClkHS
-- and it does not buffer data
LM_inst: LM
Generic Map(
kMaxLaneCount => kMaxLaneCount,
kLaneCount => kLaneCount
)
Port Map(
RxByteClkHS => RxByteClkHS,
RxDataHS => rbRxDataHS,
RxSyncHS => rbRxSyncHS,
RxValidHS => rbRxValidHS,
RxActiveHS => rbRxActiveHS,
rbMAxisTdata => rbLMAxisTdata,
rbMAxisTkeep => rbLMAxisTkeep,
rbMAxisTvalid => rbLMAxisTvalid,
rbMAxisTready => rbLLPAxisTready,
rbMAxisTlast => rbLMAxisTlast,
rbErrSkew => rbLMErrSkew,
rbErrOvf => rbLMErrOvf,
rbEn => rbEn,
rbRst => not rbRst_n,
dbgLMLane => dbgLMLane,
dbgLM => dbgLM
);
-- Link-level protocol decodes short and long packets into frames, lines
-- and pixels. It synchronizes data from the MIPI clock domain (RxByteClkHS)
-- to the video pipeline domain video_aclk. It does error detection
-- and correction, filters data according to the target data type and
-- formats it according to UG934, ready to source a video processing
-- pipeline.
LLP_inst: LLP
Generic map (
kMaxLaneCount => kMaxLaneCount,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
kTargetDT => kTargetDT
)
Port map (
SAxisClk => RxByteClkHS,
--Slave AXI-Stream
sAxisTdata => rbLMAxisTdata,
sAxisTkeep => rbLMAxisTkeep,
sAxisTvalid => rbLMAxisTvalid,
sAxisTready => rbLLPAxisTready,
sAxisTlast => rbLMAxisTlast,
MAxisClk => video_aclk,
--Master AXI-Stream
mAxisTdata => m_axis_video_tdata,
mAxisTvalid => m_axis_video_tvalid,
mAxisTready => m_axis_video_tready,
mAxisTlast => m_axis_video_tlast,
mAxisTuser => m_axis_video_tuser,
aRst => vRst,
sOverflow => open,
dbgLLP => dbgLLP
);
----------------------------------------------------------------------------------
-- Debug modules
----------------------------------------------------------------------------------
GenerateDebug: if kDebug generate
ILARxClk : ila_rxclk
PORT MAP (
clk => RxByteClkHS,
trig_out => rbRxClkTrigOut,
trig_out_ack => rbTrigInAck,
probe0 => dbgLM.state,
probe1 => dbgLM.rbByteCnt,
probe2 => rbLMAxisTdata,
probe3 => rbLMAxisTkeep,
probe4(0) => rbLMAxisTvalid,
probe5(0) => rbLLPAxisTready,
probe6(0) => rbLMAxisTlast,
probe7(0) => rbLMErrSkew,
probe8(0) => rbLMErrOvf,
probe9(0) => dbgLLP.rbRst,
probe10(0) => dbgLLP.rbOvf,
probe11(0) => dbgLLP.rbFIFO_Rstn,
probe12(0) => rbRst_n,
probe13(0) => rbEn
);
ILAVidClk : ila_vidclk
PORT MAP (
clk => video_aclk,
trig_in => vTrigIn,
trig_in_ack => vTrigInAck,
probe0(0) => dbgLLP.mRst,
probe1(0) => dbgLLP.mFIFO_Tvalid,
probe2(0) => dbgLLP.mFIFO_Tready,
probe3(0) => dbgLLP.mFIFO_Tlast,
probe4 => dbgLLP.mFIFO_Tdata,
probe5 => dbgLLP.mFIFO_Tkeep,
probe6(0) => dbgLLP.mIsHeader,
probe7(0) => dbgLLP.mECC_En,
probe8(0) => dbgLLP.mECC_Ready,
probe9(0) => dbgLLP.mECC_Valid,
probe10(0) => dbgLLP.mECC_Error,
probe11 => dbgLLP.mWC,
probe12 => dbgLLP.mDT,
probe13(0) => dbgLLP.mFlush,
probe14(0) => dbgLLP.mKeep,
probe15 => dbgLLP.mWordCount,
probe16(0) => dbgLLP.mReg_Tvalid,
probe17(0) => dbgLLP.mReg_Tready,
probe18(0) => dbgLLP.mReg_Tlast,
probe19(0) => dbgLLP.mReg_Tuser,
probe20 => dbgLLP.mReg_Tdata,
probe21 => dbgLLP.mReg_Tkeep,
probe22 => dbgLLP.mCRC_Sent,
probe23(0) => dbgLLP.mCRC_En,
probe24(0) => dbgLLP.mCRC_Rst,
probe25 => dbgLLP.mCRC_Out,
probe26(0) => dbgLLP.mFmt_Tvalid,
probe27(0) => dbgLLP.mFmt_Tready,
probe28(0) => dbgLLP.mFmt_Tlast,
probe29(0) => dbgLLP.mFmt_Tuser,
probe30 => dbgLLP.mFmt_Tdata,
probe31 => dbgLLP.mFmt_cnt,
probe32 => dbgLLP.mBufDataCnt,
probe33(0) => aClkEnableInt,
probe34 => aDEnableInt,
probe35(0) => vTready
);
SyncAsyncTrigOut: entity work.SyncAsync
port map (
aReset => '0',
aIn => rbRxClkTrigOut,
OutClk => video_aclk,
oOut => vRxClkTrigOut);
SyncAsyncTrigAck: entity work.SyncAsync
port map (
aReset => '0',
aIn => vTrigInAck,
OutClk => RxByteClkHS,
oOut => rbTrigInAck);
ILA_LaneGen: for i in kLaneCount-1 downto 0 generate
ILARxClk_Lane : ila_rxclk_lane
PORT MAP (
clk => RxByteClkHS,
trig_out => rbRxClkLaneTrigOut(i),
trig_out_ack => rbTrigInAck,
probe0(0) => dbgLMLane(i).rbSkwRdEn,
probe1(0) => dbgLMLane(i).rbSkwWrEn,
probe2(0) => dbgLMLane(i).rbSkwFull,
probe3(0) => dbgLMLane(i).rbActiveHS,
probe4(0) => dbgLMLane(i).rbSyncHS,
probe5(0) => dbgLMLane(i).rbValidHS,
probe6 => dbgLMLane(i).rbDataHS
);
SyncAsyncTrigOut: entity work.SyncAsync
port map (
aReset => '0',
aIn => rbRxClkLaneTrigOut(i),
OutClk => video_aclk,
oOut => vRxClkLaneTrigOut(i));
end generate ILA_LaneGen;
vTrigIn <= orv(vRxClkLaneTrigOut) or vRxClkTrigOut;
end generate;
end Behavioral;
@@ -1,279 +1,279 @@
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI2_RxTop.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mipi_csi2_rx_top is
Generic (
kVersionMajor : natural := 0; -- TCL-propagated from VLNV
kVersionMinor : natural := 0; -- TCL-propagated from VLNV
kTargetDT : string := "RAW10";
kGenerateAXIL : boolean := false;
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4;
-- Parameters of Axi Slave Bus Interface S_AXI_LITE
C_S_AXI_LITE_DATA_WIDTH : integer := 32;
C_S_AXI_LITE_ADDR_WIDTH : integer := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
RxDataHSD0 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD0 : in STD_LOGIC;
RxValidHSD0 : in STD_LOGIC;
RxActiveHSD0 : in STD_LOGIC;
aD0Enable : out STD_LOGIC;
RxDataHSD1 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD1 : in STD_LOGIC;
RxValidHSD1 : in STD_LOGIC;
RxActiveHSD1 : in STD_LOGIC;
aD1Enable : out STD_LOGIC;
RxDataHSD2 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD2 : in STD_LOGIC;
RxValidHSD2 : in STD_LOGIC;
RxActiveHSD2 : in STD_LOGIC;
aD2Enable : out STD_LOGIC;
RxDataHSD3 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD3 : in STD_LOGIC;
RxValidHSD3 : in STD_LOGIC;
RxActiveHSD3 : in STD_LOGIC;
aD3Enable : out STD_LOGIC;
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic; --available when the AXI-Lite interface is disabled
video_aclk : in std_logic;
-- Ports of Axi Slave Bus Interface S_AXI_LITE
s_axi_lite_aclk : in std_logic;
s_axi_lite_aresetn : in std_logic;
s_axi_lite_awaddr : in std_logic_vector(C_S_AXI_LITE_ADDR_WIDTH-1 downto 0);
s_axi_lite_awprot : in std_logic_vector(2 downto 0);
s_axi_lite_awvalid : in std_logic;
s_axi_lite_awready : out std_logic;
s_axi_lite_wdata : in std_logic_vector(C_S_AXI_LITE_DATA_WIDTH-1 downto 0);
s_axi_lite_wstrb : in std_logic_vector((C_S_AXI_LITE_DATA_WIDTH/8)-1 downto 0);
s_axi_lite_wvalid : in std_logic;
s_axi_lite_wready : out std_logic;
s_axi_lite_bresp : out std_logic_vector(1 downto 0);
s_axi_lite_bvalid : out std_logic;
s_axi_lite_bready : in std_logic;
s_axi_lite_araddr : in std_logic_vector(C_S_AXI_LITE_ADDR_WIDTH-1 downto 0);
s_axi_lite_arprot : in std_logic_vector(2 downto 0);
s_axi_lite_arvalid : in std_logic;
s_axi_lite_arready : out std_logic;
s_axi_lite_rdata : out std_logic_vector(C_S_AXI_LITE_DATA_WIDTH-1 downto 0);
s_axi_lite_rresp : out std_logic_vector(1 downto 0);
s_axi_lite_rvalid : out std_logic;
s_axi_lite_rready : in std_logic
);
end mipi_csi2_rx_top;
architecture Behavioral of mipi_csi2_rx_top is
constant kMaxLaneCount : natural := 4;
signal rbRxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbRxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal aDEnable : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal xSoftEnable, xSoftRst, vSoftEnable, vSoftRst, vRst_n : std_logic;
begin
InputDataGen: for i in 0 to kLaneCount-1 generate
DataLane0: if i = 0 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD0;
rbRxValidHS(i) <= RxValidHSD0;
rbRxActiveHS(i) <= RxActiveHSD0;
rbRxSyncHS(i) <= RxSyncHSD0;
aD0Enable <= aDEnable(i);
end generate;
DataLane1: if i = 1 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD1;
rbRxValidHS(i) <= RxValidHSD1;
rbRxActiveHS(i) <= RxActiveHSD1;
rbRxSyncHS(i) <= RxSyncHSD1;
aD1Enable <= aDEnable(i);
end generate;
DataLane2: if i = 2 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD2;
rbRxValidHS(i) <= RxValidHSD2;
rbRxActiveHS(i) <= RxActiveHSD2;
rbRxSyncHS(i) <= RxSyncHSD2;
aD2Enable <= aDEnable(i);
end generate;
DataLane3: if i = 3 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD3;
rbRxValidHS(i) <= RxValidHSD3;
rbRxActiveHS(i) <= RxActiveHSD3;
rbRxSyncHS(i) <= RxSyncHSD3;
aD3Enable <= aDEnable(i);
end generate;
end generate InputDataGen;
MIPI_CSI2_Rx_inst: entity work.MIPI_CSI2_Rx
Generic map(
kTargetDT => kTargetDT,
kDebug => kDebug,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH => C_M_AXIS_COMPONENT_WIDTH, -- [8,10]
C_M_AXIS_TDATA_WIDTH => C_M_AXIS_TDATA_WIDTH,
C_M_MAX_SAMPLES_PER_CLOCK => C_M_MAX_SAMPLES_PER_CLOCK
)
Port map(
--PPI
RxByteClkHS => RxByteClkHS,
aClkStopstate => aClkStopstate,
aRxClkActiveHS => aRxClkActiveHS,
rbRxDataHS => rbRxDataHS,
rbRxSyncHS => rbRxSyncHS,
rbRxValidHS => rbRxValidHS,
rbRxActiveHS => rbRxActiveHS,
aDEnable => aDEnable,
aClkEnable => aClkEnable,
--axi stream signals
m_axis_video_tdata => m_axis_video_tdata,
m_axis_video_tvalid => m_axis_video_tvalid,
m_axis_video_tready => m_axis_video_tready,
m_axis_video_tlast => m_axis_video_tlast,
m_axis_video_tuser => m_axis_video_tuser,
video_aresetn => vRst_n,
video_aclk => video_aclk,
vEnable => vSoftEnable
);
-------------------------------------------------------------------------------
-- AXI-Lite interface for control and status
-------------------------------------------------------------------------------
YesAXILITE: if kGenerateAXIL generate
AXI_Lite_Control: entity work.MIPI_CSI_2_RX_S_AXI_LITE
generic map (
kVersionMajor => kVersionMajor,
kVersionMinor => kVersionMinor,
C_S_AXI_DATA_WIDTH => C_S_AXI_LITE_DATA_WIDTH,
C_S_AXI_ADDR_WIDTH => C_S_AXI_LITE_ADDR_WIDTH
)
port map (
xEnable => xSoftEnable,
xRst => xSoftRst,
S_AXI_ACLK => s_axi_lite_aclk,
S_AXI_ARESETN => s_axi_lite_aresetn,
S_AXI_AWADDR => s_axi_lite_awaddr,
S_AXI_AWPROT => s_axi_lite_awprot,
S_AXI_AWVALID => s_axi_lite_awvalid,
S_AXI_AWREADY => s_axi_lite_awready,
S_AXI_WDATA => s_axi_lite_wdata,
S_AXI_WSTRB => s_axi_lite_wstrb,
S_AXI_WVALID => s_axi_lite_wvalid,
S_AXI_WREADY => s_axi_lite_wready,
S_AXI_BRESP => s_axi_lite_bresp,
S_AXI_BVALID => s_axi_lite_bvalid,
S_AXI_BREADY => s_axi_lite_bready,
S_AXI_ARADDR => s_axi_lite_araddr,
S_AXI_ARPROT => s_axi_lite_arprot,
S_AXI_ARVALID => s_axi_lite_arvalid,
S_AXI_ARREADY => s_axi_lite_arready,
S_AXI_RDATA => s_axi_lite_rdata,
S_AXI_RRESP => s_axi_lite_rresp,
S_AXI_RVALID => s_axi_lite_rvalid,
S_AXI_RREADY => s_axi_lite_rready
);
CoreSoftReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => xSoftRst,
OutClk => video_aclk,
oRst => vSoftRst);
SyncAsyncClkEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0', --lane-level enable
aIn => xSoftEnable,
OutClk => video_aclk,
oOut => vSoftEnable);
GlitchFreeReset: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
vRst_n <= video_aresetn and not vSoftRst; --combinational logic can produce glitches
end if;
end process;
end generate;
NoAXILITE: if not kGenerateAXIL generate
vSoftEnable <= '1';
vRst_n <= video_aresetn;
end generate;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI2_RxTop.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity mipi_csi2_rx_top is
Generic (
kVersionMajor : natural := 0; -- TCL-propagated from VLNV
kVersionMinor : natural := 0; -- TCL-propagated from VLNV
kTargetDT : string := "RAW10";
kGenerateAXIL : boolean := false;
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4;
-- Parameters of Axi Slave Bus Interface S_AXI_LITE
C_S_AXI_LITE_DATA_WIDTH : integer := 32;
C_S_AXI_LITE_ADDR_WIDTH : integer := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
RxDataHSD0 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD0 : in STD_LOGIC;
RxValidHSD0 : in STD_LOGIC;
RxActiveHSD0 : in STD_LOGIC;
aD0Enable : out STD_LOGIC;
RxDataHSD1 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD1 : in STD_LOGIC;
RxValidHSD1 : in STD_LOGIC;
RxActiveHSD1 : in STD_LOGIC;
aD1Enable : out STD_LOGIC;
RxDataHSD2 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD2 : in STD_LOGIC;
RxValidHSD2 : in STD_LOGIC;
RxActiveHSD2 : in STD_LOGIC;
aD2Enable : out STD_LOGIC;
RxDataHSD3 : in STD_LOGIC_VECTOR (7 downto 0);
RxSyncHSD3 : in STD_LOGIC;
RxValidHSD3 : in STD_LOGIC;
RxActiveHSD3 : in STD_LOGIC;
aD3Enable : out STD_LOGIC;
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic; --available when the AXI-Lite interface is disabled
video_aclk : in std_logic;
-- Ports of Axi Slave Bus Interface S_AXI_LITE
s_axi_lite_aclk : in std_logic;
s_axi_lite_aresetn : in std_logic;
s_axi_lite_awaddr : in std_logic_vector(C_S_AXI_LITE_ADDR_WIDTH-1 downto 0);
s_axi_lite_awprot : in std_logic_vector(2 downto 0);
s_axi_lite_awvalid : in std_logic;
s_axi_lite_awready : out std_logic;
s_axi_lite_wdata : in std_logic_vector(C_S_AXI_LITE_DATA_WIDTH-1 downto 0);
s_axi_lite_wstrb : in std_logic_vector((C_S_AXI_LITE_DATA_WIDTH/8)-1 downto 0);
s_axi_lite_wvalid : in std_logic;
s_axi_lite_wready : out std_logic;
s_axi_lite_bresp : out std_logic_vector(1 downto 0);
s_axi_lite_bvalid : out std_logic;
s_axi_lite_bready : in std_logic;
s_axi_lite_araddr : in std_logic_vector(C_S_AXI_LITE_ADDR_WIDTH-1 downto 0);
s_axi_lite_arprot : in std_logic_vector(2 downto 0);
s_axi_lite_arvalid : in std_logic;
s_axi_lite_arready : out std_logic;
s_axi_lite_rdata : out std_logic_vector(C_S_AXI_LITE_DATA_WIDTH-1 downto 0);
s_axi_lite_rresp : out std_logic_vector(1 downto 0);
s_axi_lite_rvalid : out std_logic;
s_axi_lite_rready : in std_logic
);
end mipi_csi2_rx_top;
architecture Behavioral of mipi_csi2_rx_top is
constant kMaxLaneCount : natural := 4;
signal rbRxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbRxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal aDEnable : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal xSoftEnable, xSoftRst, vSoftEnable, vSoftRst, vRst_n : std_logic;
begin
InputDataGen: for i in 0 to kLaneCount-1 generate
DataLane0: if i = 0 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD0;
rbRxValidHS(i) <= RxValidHSD0;
rbRxActiveHS(i) <= RxActiveHSD0;
rbRxSyncHS(i) <= RxSyncHSD0;
aD0Enable <= aDEnable(i);
end generate;
DataLane1: if i = 1 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD1;
rbRxValidHS(i) <= RxValidHSD1;
rbRxActiveHS(i) <= RxActiveHSD1;
rbRxSyncHS(i) <= RxSyncHSD1;
aD1Enable <= aDEnable(i);
end generate;
DataLane2: if i = 2 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD2;
rbRxValidHS(i) <= RxValidHSD2;
rbRxActiveHS(i) <= RxActiveHSD2;
rbRxSyncHS(i) <= RxSyncHSD2;
aD2Enable <= aDEnable(i);
end generate;
DataLane3: if i = 3 generate
rbRxDataHS(8 * (i + 1) - 1 downto 8 * i) <= RxDataHSD3;
rbRxValidHS(i) <= RxValidHSD3;
rbRxActiveHS(i) <= RxActiveHSD3;
rbRxSyncHS(i) <= RxSyncHSD3;
aD3Enable <= aDEnable(i);
end generate;
end generate InputDataGen;
MIPI_CSI2_Rx_inst: entity work.MIPI_CSI2_Rx
Generic map(
kTargetDT => kTargetDT,
kDebug => kDebug,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH => C_M_AXIS_COMPONENT_WIDTH, -- [8,10]
C_M_AXIS_TDATA_WIDTH => C_M_AXIS_TDATA_WIDTH,
C_M_MAX_SAMPLES_PER_CLOCK => C_M_MAX_SAMPLES_PER_CLOCK
)
Port map(
--PPI
RxByteClkHS => RxByteClkHS,
aClkStopstate => aClkStopstate,
aRxClkActiveHS => aRxClkActiveHS,
rbRxDataHS => rbRxDataHS,
rbRxSyncHS => rbRxSyncHS,
rbRxValidHS => rbRxValidHS,
rbRxActiveHS => rbRxActiveHS,
aDEnable => aDEnable,
aClkEnable => aClkEnable,
--axi stream signals
m_axis_video_tdata => m_axis_video_tdata,
m_axis_video_tvalid => m_axis_video_tvalid,
m_axis_video_tready => m_axis_video_tready,
m_axis_video_tlast => m_axis_video_tlast,
m_axis_video_tuser => m_axis_video_tuser,
video_aresetn => vRst_n,
video_aclk => video_aclk,
vEnable => vSoftEnable
);
-------------------------------------------------------------------------------
-- AXI-Lite interface for control and status
-------------------------------------------------------------------------------
YesAXILITE: if kGenerateAXIL generate
AXI_Lite_Control: entity work.MIPI_CSI_2_RX_S_AXI_LITE
generic map (
kVersionMajor => kVersionMajor,
kVersionMinor => kVersionMinor,
C_S_AXI_DATA_WIDTH => C_S_AXI_LITE_DATA_WIDTH,
C_S_AXI_ADDR_WIDTH => C_S_AXI_LITE_ADDR_WIDTH
)
port map (
xEnable => xSoftEnable,
xRst => xSoftRst,
S_AXI_ACLK => s_axi_lite_aclk,
S_AXI_ARESETN => s_axi_lite_aresetn,
S_AXI_AWADDR => s_axi_lite_awaddr,
S_AXI_AWPROT => s_axi_lite_awprot,
S_AXI_AWVALID => s_axi_lite_awvalid,
S_AXI_AWREADY => s_axi_lite_awready,
S_AXI_WDATA => s_axi_lite_wdata,
S_AXI_WSTRB => s_axi_lite_wstrb,
S_AXI_WVALID => s_axi_lite_wvalid,
S_AXI_WREADY => s_axi_lite_wready,
S_AXI_BRESP => s_axi_lite_bresp,
S_AXI_BVALID => s_axi_lite_bvalid,
S_AXI_BREADY => s_axi_lite_bready,
S_AXI_ARADDR => s_axi_lite_araddr,
S_AXI_ARPROT => s_axi_lite_arprot,
S_AXI_ARVALID => s_axi_lite_arvalid,
S_AXI_ARREADY => s_axi_lite_arready,
S_AXI_RDATA => s_axi_lite_rdata,
S_AXI_RRESP => s_axi_lite_rresp,
S_AXI_RVALID => s_axi_lite_rvalid,
S_AXI_RREADY => s_axi_lite_rready
);
CoreSoftReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => xSoftRst,
OutClk => video_aclk,
oRst => vSoftRst);
SyncAsyncClkEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0', --lane-level enable
aIn => xSoftEnable,
OutClk => video_aclk,
oOut => vSoftEnable);
GlitchFreeReset: process(video_aclk)
begin
if Rising_Edge(video_aclk) then
vRst_n <= video_aresetn and not vSoftRst; --combinational logic can produce glitches
end if;
end process;
end generate;
NoAXILITE: if not kGenerateAXIL generate
vSoftEnable <= '1';
vRst_n <= video_aresetn;
end generate;
end Behavioral;
@@ -1,384 +1,384 @@
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI_2_RX_v1_0_S_AXI_LITE.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MIPI_CSI_2_RX_S_AXI_LITE is
generic (
-- Users to add parameters here
kVersionMajor : natural := 0;
kVersionMinor : natural := 0;
-- User parameters ends
-- Do not modify the parameters beyond this line
-- Width of S_AXI data bus
C_S_AXI_DATA_WIDTH : integer := 32;
-- Width of S_AXI address bus
C_S_AXI_ADDR_WIDTH : integer := 4
);
port (
-- Users to add ports here
xEnable : out std_logic;
xRst : out std_logic;
-- User ports ends
-- Do not modify the ports beyond this line
-- Global Clock Signal
S_AXI_ACLK : in std_logic;
-- Global Reset Signal. This Signal is Active LOW
S_AXI_ARESETN : in std_logic;
-- Write address (issued by master, acceped by Slave)
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Write channel Protection type. This signal indicates the
-- privilege and security level of the transaction, and whether
-- the transaction is a data access or an instruction access.
S_AXI_AWPROT : in std_logic_vector(2 downto 0);
-- Write address valid. This signal indicates that the master signaling
-- valid write address and control information.
S_AXI_AWVALID : in std_logic;
-- Write address ready. This signal indicates that the slave is ready
-- to accept an address and associated control signals.
S_AXI_AWREADY : out std_logic;
-- Write data (issued by master, acceped by Slave)
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Write strobes. This signal indicates which byte lanes hold
-- valid data. There is one write strobe bit for each eight
-- bits of the write data bus.
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
-- Write valid. This signal indicates that valid write
-- data and strobes are available.
S_AXI_WVALID : in std_logic;
-- Write ready. This signal indicates that the slave
-- can accept the write data.
S_AXI_WREADY : out std_logic;
-- Write response. This signal indicates the status
-- of the write transaction.
S_AXI_BRESP : out std_logic_vector(1 downto 0);
-- Write response valid. This signal indicates that the channel
-- is signaling a valid write response.
S_AXI_BVALID : out std_logic;
-- Response ready. This signal indicates that the master
-- can accept a write response.
S_AXI_BREADY : in std_logic;
-- Read address (issued by master, acceped by Slave)
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Protection type. This signal indicates the privilege
-- and security level of the transaction, and whether the
-- transaction is a data access or an instruction access.
S_AXI_ARPROT : in std_logic_vector(2 downto 0);
-- Read address valid. This signal indicates that the channel
-- is signaling valid read address and control information.
S_AXI_ARVALID : in std_logic;
-- Read address ready. This signal indicates that the slave is
-- ready to accept an address and associated control signals.
S_AXI_ARREADY : out std_logic;
-- Read data (issued by slave)
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Read response. This signal indicates the status of the
-- read transfer.
S_AXI_RRESP : out std_logic_vector(1 downto 0);
-- Read valid. This signal indicates that the channel is
-- signaling the required read data.
S_AXI_RVALID : out std_logic;
-- Read ready. This signal indicates that the master can
-- accept the read data and response information.
S_AXI_RREADY : in std_logic
);
end MIPI_CSI_2_RX_S_AXI_LITE;
architecture arch_imp of MIPI_CSI_2_RX_S_AXI_LITE is
constant kCTRL_EN : natural := 1;
constant kCTRL_RST : natural := 0;
constant kVersion : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(kVersionMajor,16)) & std_logic_vector(to_unsigned(kVersionMinor,16));
-- AXI4LITE signals
signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_awready : std_logic;
signal axi_wready : std_logic;
signal axi_bresp : std_logic_vector(1 downto 0);
signal axi_bvalid : std_logic;
signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_arready : std_logic;
signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal axi_rresp : std_logic_vector(1 downto 0);
signal axi_rvalid : std_logic;
-- Example-specific design signals
-- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
-- ADDR_LSB is used for addressing 32/64 bit registers/memories
-- ADDR_LSB = 2 for 32 bits (n downto 2)
-- ADDR_LSB = 3 for 64 bits (n downto 3)
constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
constant OPT_MEM_ADDR_BITS : integer := 1;
------------------------------------------------
---- Signals for user logic register space example
--------------------------------------------------
---- Number of Slave Registers 1
signal control_reg :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg_rden : std_logic;
signal slv_reg_wren : std_logic;
signal reg_data_out :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal byte_index : integer;
begin
-- I/O Connections assignments
S_AXI_AWREADY <= axi_awready;
S_AXI_WREADY <= axi_wready;
S_AXI_BRESP <= axi_bresp;
S_AXI_BVALID <= axi_bvalid;
S_AXI_ARREADY <= axi_arready;
S_AXI_RDATA <= axi_rdata;
S_AXI_RRESP <= axi_rresp;
S_AXI_RVALID <= axi_rvalid;
-- Implement axi_awready generation
-- axi_awready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awready <= '0';
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- slave is ready to accept write address when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_awready <= '1';
else
axi_awready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_awaddr latching
-- This process is used to latch the address when both
-- S_AXI_AWVALID and S_AXI_WVALID are valid.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awaddr <= (others => '0');
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end if;
end if;
end if;
end process;
-- Implement axi_wready generation
-- axi_wready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_wready <= '0';
else
if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1') then
-- slave is ready to accept write data when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_wready <= '1';
else
axi_wready <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and write logic generation
-- The write data is accepted and written to memory mapped registers when
-- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
-- select byte enables of slave registers while writing.
-- These registers are cleared when reset (active low) is applied.
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
control_reg <= (kCTRL_RST => '0', kCTRL_EN => '1', others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"00" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
control_reg(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when others =>
control_reg <= control_reg;
end case;
end if;
end if;
end if;
end process;
-- Implement write response logic generation
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_bvalid <= '0';
axi_bresp <= "00"; --need to work more on the responses
else
if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then
axi_bvalid <= '1';
axi_bresp <= "00";
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high)
axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high)
end if;
end if;
end if;
end process;
-- Implement axi_arready generation
-- axi_arready is asserted for one S_AXI_ACLK clock cycle when
-- S_AXI_ARVALID is asserted. axi_awready is
-- de-asserted when reset (active low) is asserted.
-- The read address is also latched when S_AXI_ARVALID is
-- asserted. axi_araddr is reset to zero on reset assertion.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_arready <= '0';
axi_araddr <= (others => '1');
else
if (axi_arready = '0' and S_AXI_ARVALID = '1') then
-- indicates that the slave has acceped the valid read address
axi_arready <= '1';
-- Read Address latching
axi_araddr <= S_AXI_ARADDR;
else
axi_arready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_arvalid generation
-- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_ARVALID and axi_arready are asserted. The slave registers
-- data are available on the axi_rdata bus at this instance. The
-- assertion of axi_rvalid marks the validity of read data on the
-- bus and axi_rresp indicates the status of read transaction.axi_rvalid
-- is deasserted on reset (active low). axi_rresp and axi_rdata are
-- cleared to zero on reset (active low).
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_rvalid <= '0';
axi_rresp <= "00";
else
if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
-- Valid read data is available at the read data bus
axi_rvalid <= '1';
axi_rresp <= "00"; -- 'OKAY' response
elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
-- Read data is accepted by the master
axi_rvalid <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and read logic generation
-- Slave register read enable is asserted when valid address is available
-- and the slave is ready to accept the read address.
slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
process (control_reg, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
-- Address decoding for reading registers
loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
case loc_addr is
when b"00" =>
reg_data_out <= control_reg;
when b"11" =>
reg_data_out <= kVersion;
when others =>
reg_data_out <= (others => '0');
end case;
end process;
-- Output register or memory read data
process( S_AXI_ACLK ) is
begin
if (rising_edge (S_AXI_ACLK)) then
if ( S_AXI_ARESETN = '0' ) then
axi_rdata <= (others => '0');
else
if (slv_reg_rden = '1') then
-- When there is a valid read address (S_AXI_ARVALID) with
-- acceptance of read address by the slave (axi_arready),
-- output the read dada
-- Read address mux
axi_rdata <= reg_data_out; -- register read data
end if;
end if;
end if;
end process;
-- Add user logic here
xEnable <= control_reg(kCTRL_EN);
xRst <= control_reg(kCTRL_RST);
-- User logic ends
end arch_imp;
-------------------------------------------------------------------------------
--
-- File: MIPI_CSI_2_RX_v1_0_S_AXI_LITE.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MIPI_CSI_2_RX_S_AXI_LITE is
generic (
-- Users to add parameters here
kVersionMajor : natural := 0;
kVersionMinor : natural := 0;
-- User parameters ends
-- Do not modify the parameters beyond this line
-- Width of S_AXI data bus
C_S_AXI_DATA_WIDTH : integer := 32;
-- Width of S_AXI address bus
C_S_AXI_ADDR_WIDTH : integer := 4
);
port (
-- Users to add ports here
xEnable : out std_logic;
xRst : out std_logic;
-- User ports ends
-- Do not modify the ports beyond this line
-- Global Clock Signal
S_AXI_ACLK : in std_logic;
-- Global Reset Signal. This Signal is Active LOW
S_AXI_ARESETN : in std_logic;
-- Write address (issued by master, acceped by Slave)
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Write channel Protection type. This signal indicates the
-- privilege and security level of the transaction, and whether
-- the transaction is a data access or an instruction access.
S_AXI_AWPROT : in std_logic_vector(2 downto 0);
-- Write address valid. This signal indicates that the master signaling
-- valid write address and control information.
S_AXI_AWVALID : in std_logic;
-- Write address ready. This signal indicates that the slave is ready
-- to accept an address and associated control signals.
S_AXI_AWREADY : out std_logic;
-- Write data (issued by master, acceped by Slave)
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Write strobes. This signal indicates which byte lanes hold
-- valid data. There is one write strobe bit for each eight
-- bits of the write data bus.
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
-- Write valid. This signal indicates that valid write
-- data and strobes are available.
S_AXI_WVALID : in std_logic;
-- Write ready. This signal indicates that the slave
-- can accept the write data.
S_AXI_WREADY : out std_logic;
-- Write response. This signal indicates the status
-- of the write transaction.
S_AXI_BRESP : out std_logic_vector(1 downto 0);
-- Write response valid. This signal indicates that the channel
-- is signaling a valid write response.
S_AXI_BVALID : out std_logic;
-- Response ready. This signal indicates that the master
-- can accept a write response.
S_AXI_BREADY : in std_logic;
-- Read address (issued by master, acceped by Slave)
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Protection type. This signal indicates the privilege
-- and security level of the transaction, and whether the
-- transaction is a data access or an instruction access.
S_AXI_ARPROT : in std_logic_vector(2 downto 0);
-- Read address valid. This signal indicates that the channel
-- is signaling valid read address and control information.
S_AXI_ARVALID : in std_logic;
-- Read address ready. This signal indicates that the slave is
-- ready to accept an address and associated control signals.
S_AXI_ARREADY : out std_logic;
-- Read data (issued by slave)
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Read response. This signal indicates the status of the
-- read transfer.
S_AXI_RRESP : out std_logic_vector(1 downto 0);
-- Read valid. This signal indicates that the channel is
-- signaling the required read data.
S_AXI_RVALID : out std_logic;
-- Read ready. This signal indicates that the master can
-- accept the read data and response information.
S_AXI_RREADY : in std_logic
);
end MIPI_CSI_2_RX_S_AXI_LITE;
architecture arch_imp of MIPI_CSI_2_RX_S_AXI_LITE is
constant kCTRL_EN : natural := 1;
constant kCTRL_RST : natural := 0;
constant kVersion : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(kVersionMajor,16)) & std_logic_vector(to_unsigned(kVersionMinor,16));
-- AXI4LITE signals
signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_awready : std_logic;
signal axi_wready : std_logic;
signal axi_bresp : std_logic_vector(1 downto 0);
signal axi_bvalid : std_logic;
signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_arready : std_logic;
signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal axi_rresp : std_logic_vector(1 downto 0);
signal axi_rvalid : std_logic;
-- Example-specific design signals
-- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
-- ADDR_LSB is used for addressing 32/64 bit registers/memories
-- ADDR_LSB = 2 for 32 bits (n downto 2)
-- ADDR_LSB = 3 for 64 bits (n downto 3)
constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
constant OPT_MEM_ADDR_BITS : integer := 1;
------------------------------------------------
---- Signals for user logic register space example
--------------------------------------------------
---- Number of Slave Registers 1
signal control_reg :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg_rden : std_logic;
signal slv_reg_wren : std_logic;
signal reg_data_out :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal byte_index : integer;
begin
-- I/O Connections assignments
S_AXI_AWREADY <= axi_awready;
S_AXI_WREADY <= axi_wready;
S_AXI_BRESP <= axi_bresp;
S_AXI_BVALID <= axi_bvalid;
S_AXI_ARREADY <= axi_arready;
S_AXI_RDATA <= axi_rdata;
S_AXI_RRESP <= axi_rresp;
S_AXI_RVALID <= axi_rvalid;
-- Implement axi_awready generation
-- axi_awready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awready <= '0';
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- slave is ready to accept write address when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_awready <= '1';
else
axi_awready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_awaddr latching
-- This process is used to latch the address when both
-- S_AXI_AWVALID and S_AXI_WVALID are valid.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awaddr <= (others => '0');
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end if;
end if;
end if;
end process;
-- Implement axi_wready generation
-- axi_wready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_wready <= '0';
else
if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1') then
-- slave is ready to accept write data when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_wready <= '1';
else
axi_wready <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and write logic generation
-- The write data is accepted and written to memory mapped registers when
-- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
-- select byte enables of slave registers while writing.
-- These registers are cleared when reset (active low) is applied.
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
control_reg <= (kCTRL_RST => '0', kCTRL_EN => '1', others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"00" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
control_reg(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when others =>
control_reg <= control_reg;
end case;
end if;
end if;
end if;
end process;
-- Implement write response logic generation
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_bvalid <= '0';
axi_bresp <= "00"; --need to work more on the responses
else
if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then
axi_bvalid <= '1';
axi_bresp <= "00";
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high)
axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high)
end if;
end if;
end if;
end process;
-- Implement axi_arready generation
-- axi_arready is asserted for one S_AXI_ACLK clock cycle when
-- S_AXI_ARVALID is asserted. axi_awready is
-- de-asserted when reset (active low) is asserted.
-- The read address is also latched when S_AXI_ARVALID is
-- asserted. axi_araddr is reset to zero on reset assertion.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_arready <= '0';
axi_araddr <= (others => '1');
else
if (axi_arready = '0' and S_AXI_ARVALID = '1') then
-- indicates that the slave has acceped the valid read address
axi_arready <= '1';
-- Read Address latching
axi_araddr <= S_AXI_ARADDR;
else
axi_arready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_arvalid generation
-- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_ARVALID and axi_arready are asserted. The slave registers
-- data are available on the axi_rdata bus at this instance. The
-- assertion of axi_rvalid marks the validity of read data on the
-- bus and axi_rresp indicates the status of read transaction.axi_rvalid
-- is deasserted on reset (active low). axi_rresp and axi_rdata are
-- cleared to zero on reset (active low).
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_rvalid <= '0';
axi_rresp <= "00";
else
if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
-- Valid read data is available at the read data bus
axi_rvalid <= '1';
axi_rresp <= "00"; -- 'OKAY' response
elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
-- Read data is accepted by the master
axi_rvalid <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and read logic generation
-- Slave register read enable is asserted when valid address is available
-- and the slave is ready to accept the read address.
slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
process (control_reg, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
-- Address decoding for reading registers
loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
case loc_addr is
when b"00" =>
reg_data_out <= control_reg;
when b"11" =>
reg_data_out <= kVersion;
when others =>
reg_data_out <= (others => '0');
end case;
end process;
-- Output register or memory read data
process( S_AXI_ACLK ) is
begin
if (rising_edge (S_AXI_ACLK)) then
if ( S_AXI_ARESETN = '0' ) then
axi_rdata <= (others => '0');
else
if (slv_reg_rden = '1') then
-- When there is a valid read address (S_AXI_ARVALID) with
-- acceptance of read address by the slave (axi_arready),
-- output the read dada
-- Read address mux
axi_rdata <= reg_data_out; -- register read data
end if;
end if;
end if;
end process;
-- Add user logic here
xEnable <= control_reg(kCTRL_EN);
xRst <= control_reg(kCTRL_RST);
-- User logic ends
end arch_imp;
@@ -1,145 +1,145 @@
-------------------------------------------------------------------------------
--
-- File: SimpleFIFO.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SimpleFIFO is
Generic (
kDataWidth : natural
);
Port (
InClk : in std_logic;
iRst : in std_logic;
iDataIn : in std_logic_vector(kDataWidth-1 downto 0);
iWrEn : in std_logic;
iRdEn : in std_logic;
iFull : out std_logic;
iEmpty : out std_logic;
iDataOut : out std_logic_vector(kDataWidth-1 downto 0)
);
end SimpleFIFO;
architecture Behavioral of SimpleFIFO is
constant kFIFO_Depth : natural := 2**5; --implementation assumes power of 2
subtype FIFO_data_t is std_logic_vector(kDataWidth-1 downto 0);
type FIFO_t is array (0 to kFIFO_Depth-1) of FIFO_data_t;
signal FIFO : FIFO_t;
signal iRdA, iWrA : natural range 0 to kFIFO_Depth-1; --read and write addresses
signal iFullInt, iEmptyInt : std_logic := '1';
begin
-- The process below should result in a dual-port distributed RAM
FIFOProc: process (InClk)
begin
if Rising_Edge(InClk) then
if (iWrEn = '1') then
FIFO(iWrA) <= iDataIn;
end if;
end if;
end process FIFOProc;
iDataOut <= FIFO(iRdA);
-- FIFO address counters
FIFO_WrA: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iWrA <= 0;
elsif (iFullInt = '0' or iWrEn = '1') then
if (iWrA = kFIFO_Depth - 1) then
iWrA <= 0;
else
iWrA <= iWrA + 1;
end if;
end if;
end if;
end process FIFO_WrA;
FIFO_RdA: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iRdA <= 0;
elsif (iRdEn = '1' and iEmptyInt = '0') then
if (iRdA = kFIFO_Depth - 1) then
iRdA <= 0;
else
iRdA <= iRdA + 1;
end if;
end if;
end if;
end process FIFO_RdA;
FullFlag: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iFullInt <= '1';
elsif (iEmptyInt = '1') then
iFullInt <= '0';
elsif (iFullInt = '1' and iRdEn = '1') then
iFullInt <= '0';
elsif (((iWrA + 1) mod kFIFO_Depth = iRdA) and iWrEn = '1' and iRdEn = '0') then
iFullInt <= '1';
end if;
end if;
end process;
EmptyFlag: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iEmptyInt <= '1';
elsif (iWrEn = '1') then
iEmptyInt <= '0';
elsif (((iRdA + 1) mod kFIFO_Depth = iWrA) and iRdEn = '1' and iWrEn = '0') then
iEmptyInt <= '1';
end if;
end if;
end process;
iFull <= iFullInt;
iEmpty <= iEmptyInt;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SimpleFIFO.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI CSI-2 Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SimpleFIFO is
Generic (
kDataWidth : natural
);
Port (
InClk : in std_logic;
iRst : in std_logic;
iDataIn : in std_logic_vector(kDataWidth-1 downto 0);
iWrEn : in std_logic;
iRdEn : in std_logic;
iFull : out std_logic;
iEmpty : out std_logic;
iDataOut : out std_logic_vector(kDataWidth-1 downto 0)
);
end SimpleFIFO;
architecture Behavioral of SimpleFIFO is
constant kFIFO_Depth : natural := 2**5; --implementation assumes power of 2
subtype FIFO_data_t is std_logic_vector(kDataWidth-1 downto 0);
type FIFO_t is array (0 to kFIFO_Depth-1) of FIFO_data_t;
signal FIFO : FIFO_t;
signal iRdA, iWrA : natural range 0 to kFIFO_Depth-1; --read and write addresses
signal iFullInt, iEmptyInt : std_logic := '1';
begin
-- The process below should result in a dual-port distributed RAM
FIFOProc: process (InClk)
begin
if Rising_Edge(InClk) then
if (iWrEn = '1') then
FIFO(iWrA) <= iDataIn;
end if;
end if;
end process FIFOProc;
iDataOut <= FIFO(iRdA);
-- FIFO address counters
FIFO_WrA: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iWrA <= 0;
elsif (iFullInt = '0' or iWrEn = '1') then
if (iWrA = kFIFO_Depth - 1) then
iWrA <= 0;
else
iWrA <= iWrA + 1;
end if;
end if;
end if;
end process FIFO_WrA;
FIFO_RdA: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iRdA <= 0;
elsif (iRdEn = '1' and iEmptyInt = '0') then
if (iRdA = kFIFO_Depth - 1) then
iRdA <= 0;
else
iRdA <= iRdA + 1;
end if;
end if;
end if;
end process FIFO_RdA;
FullFlag: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iFullInt <= '1';
elsif (iEmptyInt = '1') then
iFullInt <= '0';
elsif (iFullInt = '1' and iRdEn = '1') then
iFullInt <= '0';
elsif (((iWrA + 1) mod kFIFO_Depth = iRdA) and iWrEn = '1' and iRdEn = '0') then
iFullInt <= '1';
end if;
end if;
end process;
EmptyFlag: process (InClk)
begin
if Rising_Edge(InClk) then
if (iRst = '1') then
iEmptyInt <= '1';
elsif (iWrEn = '1') then
iEmptyInt <= '0';
elsif (((iRdA + 1) mod kFIFO_Depth = iWrA) and iRdEn = '1' and iWrEn = '0') then
iEmptyInt <= '1';
end if;
end if;
end process;
iFull <= iFullInt;
iEmpty <= iEmptyInt;
end Behavioral;
@@ -1,82 +1,82 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2; --double sync by default
kResetPolarity : std_logic := '1'); --aReset active-high by default
Port (
aReset : in STD_LOGIC; -- active-high/active-low asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = kResetPolarity) then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2; --double sync by default
kResetPolarity : std_logic := '1'); --aReset active-high by default
Port (
aReset : in STD_LOGIC; -- active-high/active-low asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = kResetPolarity) then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
@@ -1,79 +1,79 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
begin
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2,
kResetPolarity => kPolarity) --use double FF synchronizer
port map (
aReset => aRst,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
begin
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2,
kResetPolarity => kPolarity) --use double FF synchronizer
port map (
aReset => aRst,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;
@@ -1,137 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>xilinx.com</spirit:vendor>
<spirit:library>xci</spirit:library>
<spirit:name>unknown</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:componentInstances>
<spirit:componentInstance>
<spirit:instanceName>line_buffer</spirit:instanceName>
<spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="axis_data_fifo" spirit:version="2.0"/>
<spirit:configurableElementValues>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.LAYERED_METADATA">undef</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKENIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.ASSOCIATED_RESET"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.LAYERED_METADATA">undef</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKENIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.ASSOCIATED_RESET"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_RSTIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_RSTIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_ACLKEN_CONV_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_SIGNAL_SET">0b00000000000000000000000010010011</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TDATA_WIDTH">40</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TDEST_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TID_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_ECC_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FAMILY">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_DEPTH">2048</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_MEMORY_TYPE">auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_MODE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_IS_ACLK_ASYNC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PROG_EMPTY_THRESH">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PROG_FULL_THRESH">11</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_SYNCHRONIZER_STAGE">3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_USE_ADV_FEATURES">825503796</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ACLKEN_CONV_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">line_buffer</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ENABLE_ECC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_DEPTH">2048</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_MEMORY_TYPE">auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_MODE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_AEMPTY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_AFULL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_ECC_ERR_INJECT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_PROG_EMPTY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_PROG_FULL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_RD_DATA_COUNT">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_WR_DATA_COUNT">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.IS_ACLK_ASYNC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PROG_EMPTY_THRESH">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PROG_FULL_THRESH">11</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.SYNCHRONIZATION_STAGES">3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BASE_BOARD_PART">em.avnet.com:zed:part0:1.4</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD_CONNECTIONS"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xc7z020</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">clg484</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VHDL</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.STATIC_POWER"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPCONTEXT">IP_Flow</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SELECTEDSIMMODEL"/>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SHAREDDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2019.1.3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">OUT_OF_CONTEXT</spirit:configurableElementValue>
</spirit:configurableElementValues>
<spirit:vendorExtensions>
<xilinx:componentInstanceExtensions>
<xilinx:configElementInfos>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TLAST" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDATA_NUM_BYTES" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.TUSER_WIDTH" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TLAST" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDATA_NUM_BYTES" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.TUSER_WIDTH" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.FIFO_DEPTH" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_RD_DATA_COUNT" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_TKEEP" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_TLAST" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_WR_DATA_COUNT" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.SYNCHRONIZATION_STAGES" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.TDATA_NUM_BYTES" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.TUSER_WIDTH" xilinx:valueSource="user"/>
</xilinx:configElementInfos>
</xilinx:componentInstanceExtensions>
</spirit:vendorExtensions>
</spirit:componentInstance>
</spirit:componentInstances>
</spirit:design>
<?xml version="1.0" encoding="UTF-8"?>
<spirit:design xmlns:xilinx="http://www.xilinx.com" xmlns:spirit="http://www.spiritconsortium.org/XMLSchema/SPIRIT/1685-2009" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<spirit:vendor>xilinx.com</spirit:vendor>
<spirit:library>xci</spirit:library>
<spirit:name>unknown</spirit:name>
<spirit:version>1.0</spirit:version>
<spirit:componentInstances>
<spirit:componentInstance>
<spirit:instanceName>line_buffer</spirit:instanceName>
<spirit:componentRef spirit:vendor="xilinx.com" spirit:library="ip" spirit:name="axis_data_fifo" spirit:version="2.0"/>
<spirit:configurableElementValues>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.LAYERED_METADATA">undef</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_AXIS.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKENIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.ASSOCIATED_RESET"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.M_CLKIF.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.LAYERED_METADATA">undef</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_AXIS.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKENIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.ASSOCIATED_RESET"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.CLK_DOMAIN"/>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.FREQ_HZ">100000000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_CLKIF.PHASE">0.000</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_RSTIF.INSERT_VIP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="BUSIFPARAM_VALUE.S_RSTIF.POLARITY">ACTIVE_LOW</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_ACLKEN_CONV_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_SIGNAL_SET">0b00000000000000000000000010010011</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TDATA_WIDTH">40</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TDEST_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TID_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_AXIS_TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_ECC_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FAMILY">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_DEPTH">2048</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_MEMORY_TYPE">auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_FIFO_MODE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_IS_ACLK_ASYNC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PROG_EMPTY_THRESH">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_PROG_FULL_THRESH">11</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_SYNCHRONIZER_STAGE">3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="MODELPARAM_VALUE.C_USE_ADV_FEATURES">825503796</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ACLKEN_CONV_MODE">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.Component_Name">line_buffer</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.ENABLE_ECC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_DEPTH">2048</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_MEMORY_TYPE">auto</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.FIFO_MODE">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_AEMPTY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_AFULL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_ECC_ERR_INJECT">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_PROG_EMPTY">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_PROG_FULL">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_RD_DATA_COUNT">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TKEEP">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TLAST">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TREADY">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_TSTRB">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.HAS_WR_DATA_COUNT">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.IS_ACLK_ASYNC">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PROG_EMPTY_THRESH">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.PROG_FULL_THRESH">11</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.SYNCHRONIZATION_STAGES">3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TDATA_NUM_BYTES">5</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TDEST_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TID_WIDTH">0</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PARAM_VALUE.TUSER_WIDTH">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.ARCHITECTURE">zynq</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BASE_BOARD_PART">em.avnet.com:zed:part0:1.4</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.BOARD_CONNECTIONS"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.DEVICE">xc7z020</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PACKAGE">clg484</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.PREFHDL">VHDL</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SILICON_REVISION"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SIMULATOR_LANGUAGE">MIXED</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.SPEEDGRADE">-1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.STATIC_POWER"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.TEMPERATURE_GRADE"/>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_CUSTOMIZATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="PROJECT_PARAM.USE_RDI_GENERATION">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPCONTEXT">IP_Flow</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.IPREVISION">1</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.MANAGED">TRUE</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.OUTPUTDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SELECTEDSIMMODEL"/>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SHAREDDIR">.</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SWVERSION">2019.1.3</spirit:configurableElementValue>
<spirit:configurableElementValue spirit:referenceId="RUNTIME_PARAM.SYNTHESISFLOW">OUT_OF_CONTEXT</spirit:configurableElementValue>
</spirit:configurableElementValues>
<spirit:vendorExtensions>
<xilinx:componentInstanceExtensions>
<xilinx:configElementInfos>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.HAS_TLAST" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.TDATA_NUM_BYTES" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.M_AXIS.TUSER_WIDTH" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.HAS_TLAST" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.TDATA_NUM_BYTES" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="BUSIFPARAM_VALUE.S_AXIS.TUSER_WIDTH" xilinx:valueSource="auto"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.FIFO_DEPTH" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_RD_DATA_COUNT" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_TKEEP" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_TLAST" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.HAS_WR_DATA_COUNT" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.SYNCHRONIZATION_STAGES" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.TDATA_NUM_BYTES" xilinx:valueSource="user"/>
<xilinx:configElementInfo xilinx:referenceId="PARAM_VALUE.TUSER_WIDTH" xilinx:valueSource="user"/>
</xilinx:configElementInfos>
</xilinx:componentInstanceExtensions>
</spirit:vendorExtensions>
</spirit:componentInstance>
</spirit:componentInstances>
</spirit:design>
@@ -1,56 +1,56 @@
###############################################################################
##
## File: mipi_csi2_rx.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR || NAME =~ *SyncAsync*/oSyncStages_reg[0]/D} -hier]
#set_false_path -through [get_pins -filter {NAME =~ */SyncBase*/iIn_q*/PRE || NAME =~ */SyncBase*/iIn_q*/CLR} -hier]
# The handshake module does not need recovery check on aReset
#set_false_path -through [get_pins HandshakeData*/*/CLR]
# 2017.4 - 2018.2 workaround
##
## Match Unit Configuration to Match Output false path
##
set_false_path -from [get_pins -hierarchical -filter {NAME =~ *allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK}] -to [get_pins -hierarchical -filter {NAME =~ *allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/I_IS_TERMINATION_SLICE_W_OUTPUT_REG.DOUT_O_reg/D}]
##
## ILA Sample Counter Match Condition out False Paths
##
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_sample_counter/u_scnt_cmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_sample_counter/u_scnt_cmp_q*" && IS_SEQUENTIAL } ]
##
## ILA Window Counter Match Condition out False Paths
##
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_lcmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_lcmp_q*" && IS_SEQUENTIAL } ]
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_hcmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_hcmp_q*" && IS_SEQUENTIAL } ]
###############################################################################
##
## File: mipi_csi2_rx.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR || NAME =~ *SyncAsync*/oSyncStages_reg[0]/D} -hier]
#set_false_path -through [get_pins -filter {NAME =~ */SyncBase*/iIn_q*/PRE || NAME =~ */SyncBase*/iIn_q*/CLR} -hier]
# The handshake module does not need recovery check on aReset
#set_false_path -through [get_pins HandshakeData*/*/CLR]
# 2017.4 - 2018.2 workaround
##
## Match Unit Configuration to Match Output false path
##
set_false_path -from [get_pins -hierarchical -filter {NAME =~ *allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK}] -to [get_pins -hierarchical -filter {NAME =~ *allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/I_IS_TERMINATION_SLICE_W_OUTPUT_REG.DOUT_O_reg/D}]
##
## ILA Sample Counter Match Condition out False Paths
##
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_sample_counter/u_scnt_cmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_sample_counter/u_scnt_cmp_q*" && IS_SEQUENTIAL } ]
##
## ILA Window Counter Match Condition out False Paths
##
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_lcmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_lcmp_q*" && IS_SEQUENTIAL } ]
set_false_path -from [get_pins -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_hcmp/allx_typeA_match_detection.ltlib_v1_0_0_allx_typeA_inst/DUT/I_WHOLE_SLICE.G_SLICE_IDX[*].U_ALL_SRL_SLICE/u_srl*/S*/CLK*"}] -to [get_cells -hierarchical -filter { NAME =~ "*ila_core_inst/u_ila_cap_ctrl/u_cap_addrgen/u_cap_window_counter/u_wcnt_hcmp_q*" && IS_SEQUENTIAL } ]
@@ -1,37 +1,37 @@
###############################################################################
##
## File: mipi_csi2_rx_clocks.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# Uncomment below when data needs to be handshaked into the s_axi_lite_aclk domain
# Make sure the path from the iData_int register to oData register is smaller than 2 OutClk (s00_axi_aclk) periods
#set OutClk [get_clocks -of [get_ports s_axi_lite_aclk]]
###############################################################################
##
## File: mipi_csi2_rx_clocks.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# Uncomment below when data needs to be handshaked into the s_axi_lite_aclk domain
# Make sure the path from the iData_int register to oData register is smaller than 2 OutClk (s00_axi_aclk) periods
#set OutClk [get_clocks -of [get_ports s_axi_lite_aclk]]
#set_max_delay -datapath_only -from [get_pins -filter {NAME =~ */HandshakeData*/iData_int_reg[*]/C} -hier] -to [get_pins -filter {NAME =~ */HandshakeData*/oData_reg[*]/D} -hier] [expr [get_property -min PERIOD $OutClk] * 2]
@@ -1,35 +1,35 @@
###############################################################################
##
## File: mipi_csi2_rx_ooc.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
create_clock -period 10.000 -name video_aclk -waveform {0.000 5.000} [get_ports video_aclk]
create_clock -period 10.000 -name s_axil_aclk -waveform {0.000 5.000} [get_ports s_axi_lite_aclk]
create_clock -period 10.000 -name RxByteClkHS -waveform {0.000 5.000} [get_ports RxByteClkHS]
###############################################################################
##
## File: mipi_csi2_rx_ooc.xdc
## Author: Elod Gyorgy
## Original Project: MIPI CSI-2 Rx IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
create_clock -period 10.000 -name video_aclk -waveform {0.000 5.000} [get_ports video_aclk]
create_clock -period 10.000 -name s_axil_aclk -waveform {0.000 5.000} [get_ports s_axi_lite_aclk]
create_clock -period 10.000 -name RxByteClkHS -waveform {0.000 5.000} [get_ports RxByteClkHS]
@@ -1,56 +1,56 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07/26/2017 12:11:15 PM
-- Design Name:
-- Module Name: mypkg - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package mypkg is
function max (a,b : integer) return integer;
function max (a,b : time) return time;
end mypkg;
package body mypkg is
function max (a,b : integer) return integer is
begin
if (a > b) then
return a;
else
return b;
end if;
end function max;
function max (a,b : time) return time is
begin
if (a > b) then
return a;
else
return b;
end if;
end function max;
end mypkg;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07/26/2017 12:11:15 PM
-- Design Name:
-- Module Name: mypkg - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package mypkg is
function max (a,b : integer) return integer;
function max (a,b : time) return time;
end mypkg;
package body mypkg is
function max (a,b : integer) return integer is
begin
if (a > b) then
return a;
else
return b;
end if;
end function max;
function max (a,b : time) return time is
begin
if (a > b) then
return a;
else
return b;
end if;
end function max;
end mypkg;
@@ -1,141 +1,141 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 06/27/2017 03:44:54 PM
-- Design Name:
-- Module Name: tb_ECC - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library STD;
use STD.textio.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_ECC is
-- Port ( );
end tb_ECC;
architecture Behavioral of tb_ECC is
component ECC is
Port (
StreamClk : in std_logic;
sHeaderIn : in std_logic_vector(31 downto 0);
sCE : in std_logic;
sReady : out std_logic;
sHeaderOut : out std_logic_vector(31 downto 0);
sValid: out std_logic; --asserted for one cycle when ECC processing is done and correct data is present on sHeaderOut
sError: out std_logic; --asserted for one cycle when ECC processing detected an error
sRst : in std_logic
);
end component;
constant kClkPeriod : time := 10ns;
type stimulus_t is array (natural range <>) of std_logic_vector(31 downto 0);
constant kStimulus : stimulus_t := (x"3F01F037", x"3F01F037");
signal StreamClk, sRst, sCE, sReady, sValid, sError : std_logic := '0';
signal sHeaderIn, sHeaderOut : std_logic_vector(31 downto 0);
begin
StreamClk <= not StreamClk after kClkPeriod / 2;
process
variable temp : std_logic_vector(31 downto 0);
begin
sRst <= '1';
wait for 5*kClkPeriod;
sCE <= '0';
sRst <= '0';
wait until Rising_Edge(StreamClk);
for i in kStimulus'range loop
wait until Rising_Edge(StreamClk);
-- unmodified stimulus
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
sHeaderIn <= kStimulus(i);
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '1' and sError = '0' and sHeaderOut = sHeaderIn) report "ECC error where there should not be one" severity failure;
for iBit in 29 downto 0 loop -- Bits 31 and 30 (7 and 6 of ECC) are always 0
wait until Rising_Edge(StreamClk);
-- modified stimulus (one bit flipped)
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
temp := kStimulus(i);
temp(iBit) := not temp(iBit);
sHeaderIn <= temp;
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '1' and sError = '1' and sHeaderOut = kStimulus(i)) report "ECC one-bit error was not fixed" severity failure;
end loop;
for iBit in 29 downto 0 loop
for iBit2 in 29 downto 0 loop
if (iBit /= iBit2) then
wait until Rising_Edge(StreamClk);
-- modified stimulus (one bit flipped)
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
temp := kStimulus(i);
temp(iBit) := not temp(iBit);
temp(iBit2) := not temp(iBit2);
sHeaderIn <= temp;
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '0' and sError = '1') report "ECC two-bit error was not detected" severity failure;
end if;
end loop;
end loop;
end loop;
wait;
end process;
DUT: ECC
Port map (
StreamClk => StreamClk,
sHeaderIn => sHeaderIn,
sCE => sCE,
sReady => sReady,
sHeaderOut => sHeaderOut,
sValid => sValid,
sError => sError,
sRst => sRst
);
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 06/27/2017 03:44:54 PM
-- Design Name:
-- Module Name: tb_ECC - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library STD;
use STD.textio.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_ECC is
-- Port ( );
end tb_ECC;
architecture Behavioral of tb_ECC is
component ECC is
Port (
StreamClk : in std_logic;
sHeaderIn : in std_logic_vector(31 downto 0);
sCE : in std_logic;
sReady : out std_logic;
sHeaderOut : out std_logic_vector(31 downto 0);
sValid: out std_logic; --asserted for one cycle when ECC processing is done and correct data is present on sHeaderOut
sError: out std_logic; --asserted for one cycle when ECC processing detected an error
sRst : in std_logic
);
end component;
constant kClkPeriod : time := 10ns;
type stimulus_t is array (natural range <>) of std_logic_vector(31 downto 0);
constant kStimulus : stimulus_t := (x"3F01F037", x"3F01F037");
signal StreamClk, sRst, sCE, sReady, sValid, sError : std_logic := '0';
signal sHeaderIn, sHeaderOut : std_logic_vector(31 downto 0);
begin
StreamClk <= not StreamClk after kClkPeriod / 2;
process
variable temp : std_logic_vector(31 downto 0);
begin
sRst <= '1';
wait for 5*kClkPeriod;
sCE <= '0';
sRst <= '0';
wait until Rising_Edge(StreamClk);
for i in kStimulus'range loop
wait until Rising_Edge(StreamClk);
-- unmodified stimulus
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
sHeaderIn <= kStimulus(i);
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '1' and sError = '0' and sHeaderOut = sHeaderIn) report "ECC error where there should not be one" severity failure;
for iBit in 29 downto 0 loop -- Bits 31 and 30 (7 and 6 of ECC) are always 0
wait until Rising_Edge(StreamClk);
-- modified stimulus (one bit flipped)
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
temp := kStimulus(i);
temp(iBit) := not temp(iBit);
sHeaderIn <= temp;
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '1' and sError = '1' and sHeaderOut = kStimulus(i)) report "ECC one-bit error was not fixed" severity failure;
end loop;
for iBit in 29 downto 0 loop
for iBit2 in 29 downto 0 loop
if (iBit /= iBit2) then
wait until Rising_Edge(StreamClk);
-- modified stimulus (one bit flipped)
assert (sReady = '1') report "DUT ECC is not ready when it should be" severity failure;
sCE <= '1';
temp := kStimulus(i);
temp(iBit) := not temp(iBit);
temp(iBit2) := not temp(iBit2);
sHeaderIn <= temp;
wait until Rising_Edge(StreamClk);
sCE <= '0';
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
wait until Rising_Edge(StreamClk);
assert (sValid = '0' and sError = '1') report "ECC two-bit error was not detected" severity failure;
end if;
end loop;
end loop;
end loop;
wait;
end process;
DUT: ECC
Port map (
StreamClk => StreamClk,
sHeaderIn => sHeaderIn,
sCE => sCE,
sReady => sReady,
sHeaderOut => sHeaderOut,
sValid => sValid,
sError => sError,
sRst => sRst
);
end Behavioral;
@@ -1,200 +1,200 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07/23/2017 08:00:19 PM
-- Design Name:
-- Module Name: tb_LLP - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.mypkg.all;
entity tb_LLP is
-- Port ( );
end tb_LLP;
architecture Behavioral of tb_LLP is
component LLP is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
SAxisClk : in STD_LOGIC;
--Slave AXI-Stream
sAxisTdata : in std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
sAxisTkeep : in std_logic_vector(kMaxLaneCount - 1 downto 0);
sAxisTvalid : in std_logic;
sAxisTready : out std_logic;
sAxisTlast : in std_logic;
--TODO: sAxisTdest : in std_logic;
MAxisClk : in std_logic;
--Master AXI-Stream
mAxisTdata : out std_logic_vector(40 - 1 downto 0);
mAxisTvalid : out std_logic;
mAxisTready : in std_logic;
mAxisTlast : out std_logic;
mAxisTuser : out std_logic_vector(0 downto 0);
sOverflow : out std_logic;
aRst : in std_logic
);
end component LLP;
constant kSClkPeriod : time := 10ns;
constant kMClkPeriod : time := 13ns;
constant kMaxLaneCount : natural := 4;
constant kPixPerBeat : natural := 4;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant fs_err : mem := (x"00", x"01", x"C0", x"1A", x"EF", x"BE"); --frame start with two ECC errors and extra bytes (if no EoT processing is done in PHY)
constant fs : mem := (x"00", x"01", x"00", x"1A"); --frame start with no ECC errors
constant longRAW10_cnt_err : mem := (x"2B", x"01", x"00", x"0D", x"00", x"00", x"00"); --shorter line
constant longRAW10_err : mem := (x"2B", x"0A", x"80", x"2E", x"00", x"00", x"00", x"00", x"E4", x"01", x"01", x"01", x"01", x"E4", x"E9", x"FB", x"EF", x"BE", x"AD", x"DE"); --active line RAW8, error in third byte 00, extra bytes
constant fe : mem := (x"01", x"01", x"00", x"0D"); --frame end with one ECC error (error in last byte 1D)
signal sAxisTdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal sAxisTkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal sAxisTvalid, sAxisTready, sAxisTlast : std_logic;
signal MAxisClk, SAxisClk : std_logic := '0';
signal mAxisTdata : std_logic_vector(kPixPerBeat*10 - 1 downto 0);
signal mAxisTvalid, mAxisTready, mAxisTlast : std_logic;
signal mAxisTuser : std_logic_vector(0 downto 0);
signal aRst : std_logic;
begin
--TODO generate for all lane counts
SAxisClk <= not SAxisClk after kSClkPeriod / 2;
MAxisClk <= not MAxisClk after kMClkPeriod / 2;
WriteProc: process
variable iLane : natural := 0;
procedure SendPacket(test_vect : in mem) is
begin
sAxisTkeep <= (others => '0');
sAxisTlast <= '0';
iLane := 0;
for i in 0 to test_vect'length - 1 loop
sAxisTdata((iLane+1)*8-1 downto iLane*8) <= test_vect(i);
sAxisTkeep(iLane) <= '1';
if (iLane = 3 or i = test_vect'length - 1) then
sAxisTvalid <= '1';
if (i = test_vect'length - 1) then
sAxisTlast <= '1';
end if;
wait until Rising_Edge(SAxisClk) and sAxisTready = '1';
iLane := 0;
sAxisTkeep <= (others => '0');
else
iLane := iLane + 1;
end if;
end loop;
sAxisTvalid <= '0';
end procedure;
begin
sAxisTvalid <= '0';
sAxisTdata <= (others => '0');
sAxisTkeep <= (others => '0');
aRst <= '1';
wait for max(kSclkPeriod, kMClkPeriod)*5;
aRst <= '1';
wait for max(kSclkPeriod, kMClkPeriod)*5;
aRst <= '0';
wait until Rising_Edge(SAxisClk) and sAxisTready = '1'; --wait for LLP to complete reset
SendPacket(fs_err);
--switch to low-power state between packets
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(fs);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(longRAW10_cnt_err);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(longRAW10_err);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(fe);
wait;
end process;
ReadProc: process
begin
mAxisTready <= '0';
wait until sAxisTvalid = '1' and sAxisTready = '1' and Rising_Edge(SAxisClk); --first write
mAxisTready <= '1';
for i in 0 to 8 - 1 loop
if (i mod kPixPerBeat = 0) then
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
end if;
if (i/kPixPerBeat = 0) then
assert(mAxisTuser="1") report "Tuser not asserted at SOF" severity failure;
else
assert(mAxisTuser="0") report "Tuser asserted mid-frame" severity failure;
end if;
assert (to_unsigned(i,10)=unsigned(mAxisTdata(((i mod kPixPerBeat)+1)*10-1 downto (i mod kPixPerBeat)*10))) report "Output data does not match input" severity failure;
if (i/kPixPerBeat = (8-1)/kPixPerBeat) then
assert(mAxisTlast='1') report "Tlast not asserted at EOL" severity failure;
else
assert(mAxisTlast='0') report "Tlast asserted mid-line" severity failure;
end if;
end loop;
end process;
DUT: LLP
Generic map(
kMaxLaneCount => 4,
kLaneCount => 2 --[1,2,4]
)
Port map(
SAxisClk => SAxisClk,
--Slave AXI-Stream
sAxisTdata => sAxisTdata,
sAxisTkeep => sAxisTkeep,
sAxisTvalid => sAxisTvalid,
sAxisTready => sAxisTready,
sAxisTlast => sAxisTlast,
MAxisClk => MAxisClk,
--Master AXI-Stream
mAxisTdata => mAxisTdata,
mAxisTvalid => mAxisTvalid,
mAxisTready => mAxisTready,
mAxisTlast => mAxisTlast,
mAxisTuser => mAxisTuser,
sOverflow => open,
aRst => aRst
);
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 07/23/2017 08:00:19 PM
-- Design Name:
-- Module Name: tb_LLP - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
use work.mypkg.all;
entity tb_LLP is
-- Port ( );
end tb_LLP;
architecture Behavioral of tb_LLP is
component LLP is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
SAxisClk : in STD_LOGIC;
--Slave AXI-Stream
sAxisTdata : in std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
sAxisTkeep : in std_logic_vector(kMaxLaneCount - 1 downto 0);
sAxisTvalid : in std_logic;
sAxisTready : out std_logic;
sAxisTlast : in std_logic;
--TODO: sAxisTdest : in std_logic;
MAxisClk : in std_logic;
--Master AXI-Stream
mAxisTdata : out std_logic_vector(40 - 1 downto 0);
mAxisTvalid : out std_logic;
mAxisTready : in std_logic;
mAxisTlast : out std_logic;
mAxisTuser : out std_logic_vector(0 downto 0);
sOverflow : out std_logic;
aRst : in std_logic
);
end component LLP;
constant kSClkPeriod : time := 10ns;
constant kMClkPeriod : time := 13ns;
constant kMaxLaneCount : natural := 4;
constant kPixPerBeat : natural := 4;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant fs_err : mem := (x"00", x"01", x"C0", x"1A", x"EF", x"BE"); --frame start with two ECC errors and extra bytes (if no EoT processing is done in PHY)
constant fs : mem := (x"00", x"01", x"00", x"1A"); --frame start with no ECC errors
constant longRAW10_cnt_err : mem := (x"2B", x"01", x"00", x"0D", x"00", x"00", x"00"); --shorter line
constant longRAW10_err : mem := (x"2B", x"0A", x"80", x"2E", x"00", x"00", x"00", x"00", x"E4", x"01", x"01", x"01", x"01", x"E4", x"E9", x"FB", x"EF", x"BE", x"AD", x"DE"); --active line RAW8, error in third byte 00, extra bytes
constant fe : mem := (x"01", x"01", x"00", x"0D"); --frame end with one ECC error (error in last byte 1D)
signal sAxisTdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal sAxisTkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal sAxisTvalid, sAxisTready, sAxisTlast : std_logic;
signal MAxisClk, SAxisClk : std_logic := '0';
signal mAxisTdata : std_logic_vector(kPixPerBeat*10 - 1 downto 0);
signal mAxisTvalid, mAxisTready, mAxisTlast : std_logic;
signal mAxisTuser : std_logic_vector(0 downto 0);
signal aRst : std_logic;
begin
--TODO generate for all lane counts
SAxisClk <= not SAxisClk after kSClkPeriod / 2;
MAxisClk <= not MAxisClk after kMClkPeriod / 2;
WriteProc: process
variable iLane : natural := 0;
procedure SendPacket(test_vect : in mem) is
begin
sAxisTkeep <= (others => '0');
sAxisTlast <= '0';
iLane := 0;
for i in 0 to test_vect'length - 1 loop
sAxisTdata((iLane+1)*8-1 downto iLane*8) <= test_vect(i);
sAxisTkeep(iLane) <= '1';
if (iLane = 3 or i = test_vect'length - 1) then
sAxisTvalid <= '1';
if (i = test_vect'length - 1) then
sAxisTlast <= '1';
end if;
wait until Rising_Edge(SAxisClk) and sAxisTready = '1';
iLane := 0;
sAxisTkeep <= (others => '0');
else
iLane := iLane + 1;
end if;
end loop;
sAxisTvalid <= '0';
end procedure;
begin
sAxisTvalid <= '0';
sAxisTdata <= (others => '0');
sAxisTkeep <= (others => '0');
aRst <= '1';
wait for max(kSclkPeriod, kMClkPeriod)*5;
aRst <= '1';
wait for max(kSclkPeriod, kMClkPeriod)*5;
aRst <= '0';
wait until Rising_Edge(SAxisClk) and sAxisTready = '1'; --wait for LLP to complete reset
SendPacket(fs_err);
--switch to low-power state between packets
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(fs);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(longRAW10_cnt_err);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(longRAW10_err);
wait until Rising_Edge(SAxisClk);
wait until Rising_Edge(SAxisClk);
SendPacket(fe);
wait;
end process;
ReadProc: process
begin
mAxisTready <= '0';
wait until sAxisTvalid = '1' and sAxisTready = '1' and Rising_Edge(SAxisClk); --first write
mAxisTready <= '1';
for i in 0 to 8 - 1 loop
if (i mod kPixPerBeat = 0) then
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
end if;
if (i/kPixPerBeat = 0) then
assert(mAxisTuser="1") report "Tuser not asserted at SOF" severity failure;
else
assert(mAxisTuser="0") report "Tuser asserted mid-frame" severity failure;
end if;
assert (to_unsigned(i,10)=unsigned(mAxisTdata(((i mod kPixPerBeat)+1)*10-1 downto (i mod kPixPerBeat)*10))) report "Output data does not match input" severity failure;
if (i/kPixPerBeat = (8-1)/kPixPerBeat) then
assert(mAxisTlast='1') report "Tlast not asserted at EOL" severity failure;
else
assert(mAxisTlast='0') report "Tlast asserted mid-line" severity failure;
end if;
end loop;
end process;
DUT: LLP
Generic map(
kMaxLaneCount => 4,
kLaneCount => 2 --[1,2,4]
)
Port map(
SAxisClk => SAxisClk,
--Slave AXI-Stream
sAxisTdata => sAxisTdata,
sAxisTkeep => sAxisTkeep,
sAxisTvalid => sAxisTvalid,
sAxisTready => sAxisTready,
sAxisTlast => sAxisTlast,
MAxisClk => MAxisClk,
--Master AXI-Stream
mAxisTdata => mAxisTdata,
mAxisTvalid => mAxisTvalid,
mAxisTready => mAxisTready,
mAxisTlast => mAxisTlast,
mAxisTuser => mAxisTuser,
sOverflow => open,
aRst => aRst
);
end Behavioral;
@@ -1,233 +1,233 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 05/31/2017 07:40:43 PM
-- Design Name:
-- Module Name: tb_LM - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library STD;
use STD.textio.all; -- basic I/O
use ieee.std_logic_textio.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_LM is
-- Port ( );
end tb_LM;
architecture Behavioral of tb_LM is
component LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic
);
end component LM;
constant kLaneCount : natural := 4;
constant kMaxLaneCount : natural := 4;
signal RxByteClkHS : STD_LOGIC := '0';
signal RxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal RxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal RxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal RxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal m_axis_tdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal m_axis_tkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal m_axis_tvalid : std_logic;
signal m_axis_tready : std_logic;
signal m_axis_tlast : std_logic;
signal m_axis_tid : std_logic;
signal rbRst, rbEn : std_logic;
constant kClkPeriod : time := 10 ns;
procedure Idle(dur : in time; signal RxValidHS : out std_logic; signal RxSyncHS : out std_logic;
signal RxActiveHS : out std_logic; signal RxDataHS : out std_logic_vector) is
begin
RxValidHS <= '0';
RxSyncHS <= '0';
RxActiveHS <= '0';
RxDataHS <= (others => '-');
wait for dur;
end procedure;
procedure SetFor(cPeriods : in natural; signal Rx: out std_logic; value : in std_logic; signal RxClk: in std_logic) is
begin
Rx <= value;
for i in 1 to cPeriods loop
wait until Rising_Edge(RxClk);
end loop;
end procedure;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant data_stim : mem := (x"CC", x"78", x"00", x"0F",
x"FF", x"00", x"00", x"02", x"B9", x"DC", x"F3", x"72", x"BB", x"D4", x"B8", x"5A", x"C8", x"75", x"C2", x"7C", x"81", x"F8", x"05", x"DF", x"FF", x"00", x"00", x"01",
x"F0", x"00",
--dummy data
x"fc", x"04", x"29", x"37"
);
begin
--TODO generate for all lane counts
RxByteClkHS <= not RxByteClkHS after kClkPeriod / 2;
Lanes: for iLane in 0 to kLaneCount-1 generate
LaneStimulus: process
begin
Idle(100ns, RxValidHS(iLane), RxSyncHS(iLane), RxActiveHS(iLane), RxDataHS((iLane+1)*8-1 downto iLane*8));
wait until Rising_Edge(RxByteClkHS);
if (iLane = 0) then
--lane skew
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
end if;
if (iLane = 1) then
--lane skew
wait until Rising_Edge(RxByteClkHS);
end if;
RxActiveHS(iLane) <= '1';
SetFor(1, RxSyncHS(iLane), '1', RxByteClkHS);
RxSyncHS(iLane) <= '0';
SendData: for i in 0 to data_stim'length/kLaneCount loop
if (kLaneCount*i + iLane > data_stim'length-1) then
RxDataHS((iLane+1)*8-1 downto iLane*8) <= (others => '-');
RxValidHS(iLane) <= '0';
RxActiveHS(iLane) <= '0';
else
RxDataHS((iLane+1)*8-1 downto iLane*8) <= data_stim(kLaneCount*i+iLane);
RxValidHS(iLane) <= '1';
end if;
wait until Rising_Edge(RxByteClkHS);
end loop SendData;
RxActiveHS(iLane) <= '0';
RxValidHS(iLane) <= '0';
wait;
end process;
end generate Lanes;
process
begin
rbRst <= '1';
rbEn <= '0';
m_axis_tready <= '0';
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
rbRst <= '0';
rbEn <= '1';
SetFor(17, m_axis_tready, '0', RxByteClkHS);
m_axis_tready <= '1';
wait;
end process;
Verification: process (RxByteClkHS)
variable cnt_byte : natural := 0;
variable my_line : line; -- type 'line' comes from textio
begin
if Rising_Edge(RxByteClkHS) then
if (m_axis_tvalid = '1') then
if (m_axis_tready = '1') then
for i in 0 to kMaxLaneCount - 1 loop
if (m_axis_tkeep(i) = '1') then
if m_axis_tdata((i+1)*8-1 downto i*8) /= data_stim(cnt_byte) then
write(my_line, string'("Error at byte "));
write(my_line, cnt_byte);
write(my_line, string'(", data: "));
write(my_line, m_axis_tdata((i+1)*8-1 downto i*8));
write(my_line, string'(", stim: "));
write(my_line, data_stim(cnt_byte));
writeline(output, my_line);
end if;
cnt_byte := cnt_byte + 1;
end if;
end loop;
if (m_axis_tlast = '1' and cnt_byte < data_stim'length) or
(m_axis_tlast = '0' and cnt_byte >= data_stim'length) then
write(my_line, string'("Error at last byte; misaligned cnt_byte="));
write(my_line, cnt_byte);
writeline(output, my_line);
end if;
if (m_axis_tlast = '1' and cnt_byte = data_stim'length) then
write(my_line, string'("Success, received last byte"));
writeline(output, my_line);
end if;
else
write(my_line, string'("Error, overflow"));
writeline(output, my_line);
assert (false) report "Error, overflow" severity failure;
end if;
end if;
end if;
end process;
DUT: LM
generic map (
kLaneCount => kLaneCount
)
port map (
RxByteClkHS => RxByteClkHS,
RxDataHS => RxDataHS,
RxSyncHS => RxSyncHS,
RxValidHS => RxValidHS,
RxActiveHS => RxActiveHS,
rbMAxisTdata => m_axis_tdata,
rbMAxisTkeep => m_axis_tkeep,
rbMAxisTvalid => m_axis_tvalid,
rbMAxisTready => m_axis_tready,
rbMAxisTlast => m_axis_tlast,
rbErrSkew => open,
rbErrOvf => open,
rbEn => rbEn,
rbRst => rbRst
);
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 05/31/2017 07:40:43 PM
-- Design Name:
-- Module Name: tb_LM - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library STD;
use STD.textio.all; -- basic I/O
use ieee.std_logic_textio.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_LM is
-- Port ( );
end tb_LM;
architecture Behavioral of tb_LM is
component LM is
Generic(
kMaxLaneCount : natural := 4;
--PPI
kLaneCount : natural range 1 to 4 := 2 --[1,2,4]
);
Port (
RxByteClkHS : in STD_LOGIC;
RxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
RxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
RxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
--Master AXI-Stream
rbMAxisTdata : out std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
rbMAxisTkeep : out std_logic_vector(kMaxLaneCount - 1 downto 0);
rbMAxisTvalid : out std_logic;
rbMAxisTready : in std_logic;
rbMAxisTlast : out std_logic;
rbErrSkew : out std_logic;
rbErrOvf : out std_logic;
rbEn : in std_logic;
rbRst : in std_logic
);
end component LM;
constant kLaneCount : natural := 4;
constant kMaxLaneCount : natural := 4;
signal RxByteClkHS : STD_LOGIC := '0';
signal RxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal RxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal RxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal RxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal m_axis_tdata : std_logic_vector(8 * kMaxLaneCount - 1 downto 0);
signal m_axis_tkeep : std_logic_vector(kMaxLaneCount - 1 downto 0);
signal m_axis_tvalid : std_logic;
signal m_axis_tready : std_logic;
signal m_axis_tlast : std_logic;
signal m_axis_tid : std_logic;
signal rbRst, rbEn : std_logic;
constant kClkPeriod : time := 10 ns;
procedure Idle(dur : in time; signal RxValidHS : out std_logic; signal RxSyncHS : out std_logic;
signal RxActiveHS : out std_logic; signal RxDataHS : out std_logic_vector) is
begin
RxValidHS <= '0';
RxSyncHS <= '0';
RxActiveHS <= '0';
RxDataHS <= (others => '-');
wait for dur;
end procedure;
procedure SetFor(cPeriods : in natural; signal Rx: out std_logic; value : in std_logic; signal RxClk: in std_logic) is
begin
Rx <= value;
for i in 1 to cPeriods loop
wait until Rising_Edge(RxClk);
end loop;
end procedure;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant data_stim : mem := (x"CC", x"78", x"00", x"0F",
x"FF", x"00", x"00", x"02", x"B9", x"DC", x"F3", x"72", x"BB", x"D4", x"B8", x"5A", x"C8", x"75", x"C2", x"7C", x"81", x"F8", x"05", x"DF", x"FF", x"00", x"00", x"01",
x"F0", x"00",
--dummy data
x"fc", x"04", x"29", x"37"
);
begin
--TODO generate for all lane counts
RxByteClkHS <= not RxByteClkHS after kClkPeriod / 2;
Lanes: for iLane in 0 to kLaneCount-1 generate
LaneStimulus: process
begin
Idle(100ns, RxValidHS(iLane), RxSyncHS(iLane), RxActiveHS(iLane), RxDataHS((iLane+1)*8-1 downto iLane*8));
wait until Rising_Edge(RxByteClkHS);
if (iLane = 0) then
--lane skew
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
end if;
if (iLane = 1) then
--lane skew
wait until Rising_Edge(RxByteClkHS);
end if;
RxActiveHS(iLane) <= '1';
SetFor(1, RxSyncHS(iLane), '1', RxByteClkHS);
RxSyncHS(iLane) <= '0';
SendData: for i in 0 to data_stim'length/kLaneCount loop
if (kLaneCount*i + iLane > data_stim'length-1) then
RxDataHS((iLane+1)*8-1 downto iLane*8) <= (others => '-');
RxValidHS(iLane) <= '0';
RxActiveHS(iLane) <= '0';
else
RxDataHS((iLane+1)*8-1 downto iLane*8) <= data_stim(kLaneCount*i+iLane);
RxValidHS(iLane) <= '1';
end if;
wait until Rising_Edge(RxByteClkHS);
end loop SendData;
RxActiveHS(iLane) <= '0';
RxValidHS(iLane) <= '0';
wait;
end process;
end generate Lanes;
process
begin
rbRst <= '1';
rbEn <= '0';
m_axis_tready <= '0';
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
wait until Rising_Edge(RxByteClkHS);
rbRst <= '0';
rbEn <= '1';
SetFor(17, m_axis_tready, '0', RxByteClkHS);
m_axis_tready <= '1';
wait;
end process;
Verification: process (RxByteClkHS)
variable cnt_byte : natural := 0;
variable my_line : line; -- type 'line' comes from textio
begin
if Rising_Edge(RxByteClkHS) then
if (m_axis_tvalid = '1') then
if (m_axis_tready = '1') then
for i in 0 to kMaxLaneCount - 1 loop
if (m_axis_tkeep(i) = '1') then
if m_axis_tdata((i+1)*8-1 downto i*8) /= data_stim(cnt_byte) then
write(my_line, string'("Error at byte "));
write(my_line, cnt_byte);
write(my_line, string'(", data: "));
write(my_line, m_axis_tdata((i+1)*8-1 downto i*8));
write(my_line, string'(", stim: "));
write(my_line, data_stim(cnt_byte));
writeline(output, my_line);
end if;
cnt_byte := cnt_byte + 1;
end if;
end loop;
if (m_axis_tlast = '1' and cnt_byte < data_stim'length) or
(m_axis_tlast = '0' and cnt_byte >= data_stim'length) then
write(my_line, string'("Error at last byte; misaligned cnt_byte="));
write(my_line, cnt_byte);
writeline(output, my_line);
end if;
if (m_axis_tlast = '1' and cnt_byte = data_stim'length) then
write(my_line, string'("Success, received last byte"));
writeline(output, my_line);
end if;
else
write(my_line, string'("Error, overflow"));
writeline(output, my_line);
assert (false) report "Error, overflow" severity failure;
end if;
end if;
end if;
end process;
DUT: LM
generic map (
kLaneCount => kLaneCount
)
port map (
RxByteClkHS => RxByteClkHS,
RxDataHS => RxDataHS,
RxSyncHS => RxSyncHS,
RxValidHS => RxValidHS,
RxActiveHS => RxActiveHS,
rbMAxisTdata => m_axis_tdata,
rbMAxisTkeep => m_axis_tkeep,
rbMAxisTvalid => m_axis_tvalid,
rbMAxisTready => m_axis_tready,
rbMAxisTlast => m_axis_tlast,
rbErrSkew => open,
rbErrOvf => open,
rbEn => rbEn,
rbRst => rbRst
);
end Behavioral;
@@ -1,252 +1,252 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09/13/2017 06:22:52 PM
-- Design Name:
-- Module Name: tb_MIPI_CSI2 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_MIPI_CSI2 is
-- Port ( );
end tb_MIPI_CSI2;
architecture Behavioral of tb_MIPI_CSI2 is
component MIPI_CSI2_Rx is
Generic (
kTargetDT : string := "RAW10";
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
rbRxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
rbRxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aDEnable : out STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic;
video_aclk : in std_logic;
vEnable : in std_logic --TODO proper buffer flushing on disable, perhaps waiting on active transfer to end
);
end component MIPI_CSI2_Rx;
constant kTargetDT : string := "RAW10";
constant kLaneCount : natural := 2;
constant C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
constant C_M_AXIS_TDATA_WIDTH : natural := 40;
constant C_M_MAX_SAMPLES_PER_CLOCK : natural := 4;
constant kRxClkPeriod : time := 10 ns;
constant kVidClkPeriod : time := 20ns;
signal mRst_n : std_logic;
signal RxByteClkHS : STD_LOGIC := '0';
signal rbRxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbRxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal aDEnable : std_logic_vector(kLaneCount - 1 downto 0);
signal aClkEnable : std_logic;
signal mAxisTdata : std_logic_vector(C_M_AXIS_TDATA_WIDTH - 1 downto 0);
signal mAxisTvalid, mAxisTready, mAxisTlast : std_logic;
signal mAxisTuser : std_logic_vector(0 downto 0);
signal MAxisClk : std_logic := '0';
procedure Idle(signal RxValidHS : out std_logic; signal RxSyncHS : out std_logic;
signal RxActiveHS : out std_logic; signal RxDataHS : out std_logic_vector) is
begin
RxValidHS <= '0';
RxSyncHS <= '0';
RxActiveHS <= '0';
RxDataHS <= (others => '-');
end procedure;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant fs_err : mem := (x"00", x"01", x"C0", x"1A", x"EF", x"BE"); --frame start with two ECC errors and extra bytes (if no EoT processing is done in PHY)
constant fs : mem := (x"00", x"01", x"00", x"1A"); --frame start with no ECC errors
constant long_err : mem := (x"2B", x"FF", x"FF", x"00", x"00", x"00", x"00", x"00", x"E4", x"E4", x"E4", x"E4"); --uncorrectable error
constant length_err : mem := (x"2B", x"FF", x"FF", x"2D", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00"); --correct header, incorrect length
constant longRAW10_err : mem := (x"2B", x"0A", x"80", x"2E", x"00", x"00", x"00", x"00", x"E4", x"01", x"01", x"01", x"01", x"E4", x"E9", x"FB", x"EF", x"BE", x"AD", x"DE"); --active line RAW8, error in third byte 00, extra bytes
constant fe : mem := (x"01", x"01", x"00", x"0D"); --frame end with one ECC error (error in last byte 1D)
begin
RxByteClkHS <= not RxByteClkHS after kRxClkPeriod / 2 when aClkEnable = '1' else
'0';
MAxisClk <= not MAxisClk after kVidClkPeriod / 2;
ResetGen: process
begin
mRst_n <= '0';
-- Reset of 16 clock periods is recommended for AXI IP
for i in 1 to 16 loop
wait until Rising_Edge(MAxisClk);
end loop;
mRst_n <= '1';
wait;
end process;
WriteProc: process
procedure SendPacket(test_vect : in mem) is
variable iLane : natural range test_vect'range := 0;
begin
--Put all lanes in idle then activate them
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait for 100ns;
for iLane in 0 to kLaneCount - 1 loop
rbRxActiveHS(iLane) <= '1';
rbRxSyncHS(iLane) <= '1' ;
end loop;
wait until Rising_Edge(RxByteClkHS);
for iLane in 0 to kLaneCount - 1 loop
rbRxSyncHS(iLane) <= '0';
end loop;
iLane := 0;
SendData: for i in test_vect'range loop
rbRxDataHS((iLane+1)*8-1 downto iLane*8) <= test_vect(i);
rbRxValidHS(iLane) <= '1';
if (iLane = kLaneCount - 1) then
iLane := 0;
wait until Rising_Edge(RxByteClkHS);
else
iLane := iLane + 1;
end if;
end loop SendData;
-- EoT on remainder lanes for last packet
for i in iLane to kLaneCount - 1 loop
rbRxValidHS(i) <= '0';
rbRxActiveHS(i) <= '0';
end loop;
wait until Rising_Edge(RxByteClkHS);
-- EoT on all lanes
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait until Rising_Edge(RxByteClkHS);
end procedure;
begin
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait until aDEnable = "11";
SendPacket(fs_err);
SendPacket(long_err);
SendPacket(length_err);
SendPacket(fs);
SendPacket(longRAW10_err);
SendPacket(long_err);
SendPacket(fe);
wait;
end process;
ReadProc: process
begin
mAxisTready <= '1';
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
assert (unsigned(mAxisTdata)=to_unsigned(0,C_M_AXIS_TDATA_WIDTH)) report "Expected throw-away data has unexpected value" severity failure;
for i in 0 to 8 - 1 loop
if (i mod C_M_MAX_SAMPLES_PER_CLOCK = 0) then
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
end if;
if (i/C_M_MAX_SAMPLES_PER_CLOCK = 0) then
assert(mAxisTuser="1") report "Tuser not asserted at SOF" severity failure;
else
assert(mAxisTuser="0") report "Tuser asserted mid-frame" severity failure;
end if;
assert (to_unsigned(i,10)=unsigned(mAxisTdata(((i mod C_M_MAX_SAMPLES_PER_CLOCK)+1)*10-1 downto (i mod C_M_MAX_SAMPLES_PER_CLOCK)*10))) report "Output data does not match input" severity failure;
if (i/C_M_MAX_SAMPLES_PER_CLOCK = (8-1)/C_M_MAX_SAMPLES_PER_CLOCK) then
assert(mAxisTlast='1') report "Tlast not asserted at EOL" severity failure;
else
assert(mAxisTlast='0') report "Tlast asserted mid-line" severity failure;
end if;
end loop;
report "Testbench executed successfully" severity note;
wait;
end process;
DUT: MIPI_CSI2_Rx
Generic map(
kTargetDT => kTargetDT,
kDebug => false,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH => C_M_AXIS_COMPONENT_WIDTH, -- [8,10]
C_M_AXIS_TDATA_WIDTH => C_M_AXIS_TDATA_WIDTH,
C_M_MAX_SAMPLES_PER_CLOCK => C_M_MAX_SAMPLES_PER_CLOCK
)
Port map(
--PPI
RxByteClkHS => RxByteClkHS,
aClkStopstate => '0',
aRxClkActiveHS => '1',
rbRxDataHS => rbRxDataHS,
rbRxSyncHS => rbRxSyncHS,
rbRxValidHS => rbRxValidHS,
rbRxActiveHS => rbRxActiveHS,
aDEnable => aDEnable,
aClkEnable => aClkEnable,
--axi stream signals
m_axis_video_tdata => mAxisTdata,
m_axis_video_tvalid => mAxisTvalid,
m_axis_video_tready => mAxisTready,
m_axis_video_tlast => mAxisTlast,
m_axis_video_tuser => mAxisTuser,
video_aresetn => mRst_n,
video_aclk => MAxisClk,
vEnable => '1'
);
end Behavioral;
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 09/13/2017 06:22:52 PM
-- Design Name:
-- Module Name: tb_MIPI_CSI2 - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity tb_MIPI_CSI2 is
-- Port ( );
end tb_MIPI_CSI2;
architecture Behavioral of tb_MIPI_CSI2 is
component MIPI_CSI2_Rx is
Generic (
kTargetDT : string := "RAW10";
kDebug : boolean := true;
--PPI
kLaneCount : natural range 1 to 4 := 2; --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
C_M_AXIS_TDATA_WIDTH : natural := 40;
C_M_MAX_SAMPLES_PER_CLOCK : natural := 4
);
Port (
--PPI
RxByteClkHS : in STD_LOGIC;
aClkStopstate : in std_logic;
aRxClkActiveHS : in std_logic;
rbRxDataHS : in STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
rbRxSyncHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxValidHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
rbRxActiveHS : in STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aDEnable : out STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
aClkEnable : out STD_LOGIC;
--axi stream signals
m_axis_video_tdata : out std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0);
m_axis_video_tvalid : out std_logic;
m_axis_video_tready : in std_logic;
m_axis_video_tlast : out std_logic;
m_axis_video_tuser : out std_logic_vector(0 downto 0);
video_aresetn : in std_logic;
video_aclk : in std_logic;
vEnable : in std_logic --TODO proper buffer flushing on disable, perhaps waiting on active transfer to end
);
end component MIPI_CSI2_Rx;
constant kTargetDT : string := "RAW10";
constant kLaneCount : natural := 2;
constant C_M_AXIS_COMPONENT_WIDTH : natural := 10; -- [8,10]
constant C_M_AXIS_TDATA_WIDTH : natural := 40;
constant C_M_MAX_SAMPLES_PER_CLOCK : natural := 4;
constant kRxClkPeriod : time := 10 ns;
constant kVidClkPeriod : time := 20ns;
signal mRst_n : std_logic;
signal RxByteClkHS : STD_LOGIC := '0';
signal rbRxDataHS : STD_LOGIC_VECTOR (8 * kLaneCount - 1 downto 0);
signal rbRxSyncHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxValidHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal rbRxActiveHS : STD_LOGIC_VECTOR (kLaneCount - 1 downto 0);
signal aDEnable : std_logic_vector(kLaneCount - 1 downto 0);
signal aClkEnable : std_logic;
signal mAxisTdata : std_logic_vector(C_M_AXIS_TDATA_WIDTH - 1 downto 0);
signal mAxisTvalid, mAxisTready, mAxisTlast : std_logic;
signal mAxisTuser : std_logic_vector(0 downto 0);
signal MAxisClk : std_logic := '0';
procedure Idle(signal RxValidHS : out std_logic; signal RxSyncHS : out std_logic;
signal RxActiveHS : out std_logic; signal RxDataHS : out std_logic_vector) is
begin
RxValidHS <= '0';
RxSyncHS <= '0';
RxActiveHS <= '0';
RxDataHS <= (others => '-');
end procedure;
type mem is array (natural range <>) of std_logic_vector(7 downto 0);
--LSByte first
constant fs_err : mem := (x"00", x"01", x"C0", x"1A", x"EF", x"BE"); --frame start with two ECC errors and extra bytes (if no EoT processing is done in PHY)
constant fs : mem := (x"00", x"01", x"00", x"1A"); --frame start with no ECC errors
constant long_err : mem := (x"2B", x"FF", x"FF", x"00", x"00", x"00", x"00", x"00", x"E4", x"E4", x"E4", x"E4"); --uncorrectable error
constant length_err : mem := (x"2B", x"FF", x"FF", x"2D", x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00"); --correct header, incorrect length
constant longRAW10_err : mem := (x"2B", x"0A", x"80", x"2E", x"00", x"00", x"00", x"00", x"E4", x"01", x"01", x"01", x"01", x"E4", x"E9", x"FB", x"EF", x"BE", x"AD", x"DE"); --active line RAW8, error in third byte 00, extra bytes
constant fe : mem := (x"01", x"01", x"00", x"0D"); --frame end with one ECC error (error in last byte 1D)
begin
RxByteClkHS <= not RxByteClkHS after kRxClkPeriod / 2 when aClkEnable = '1' else
'0';
MAxisClk <= not MAxisClk after kVidClkPeriod / 2;
ResetGen: process
begin
mRst_n <= '0';
-- Reset of 16 clock periods is recommended for AXI IP
for i in 1 to 16 loop
wait until Rising_Edge(MAxisClk);
end loop;
mRst_n <= '1';
wait;
end process;
WriteProc: process
procedure SendPacket(test_vect : in mem) is
variable iLane : natural range test_vect'range := 0;
begin
--Put all lanes in idle then activate them
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait for 100ns;
for iLane in 0 to kLaneCount - 1 loop
rbRxActiveHS(iLane) <= '1';
rbRxSyncHS(iLane) <= '1' ;
end loop;
wait until Rising_Edge(RxByteClkHS);
for iLane in 0 to kLaneCount - 1 loop
rbRxSyncHS(iLane) <= '0';
end loop;
iLane := 0;
SendData: for i in test_vect'range loop
rbRxDataHS((iLane+1)*8-1 downto iLane*8) <= test_vect(i);
rbRxValidHS(iLane) <= '1';
if (iLane = kLaneCount - 1) then
iLane := 0;
wait until Rising_Edge(RxByteClkHS);
else
iLane := iLane + 1;
end if;
end loop SendData;
-- EoT on remainder lanes for last packet
for i in iLane to kLaneCount - 1 loop
rbRxValidHS(i) <= '0';
rbRxActiveHS(i) <= '0';
end loop;
wait until Rising_Edge(RxByteClkHS);
-- EoT on all lanes
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait until Rising_Edge(RxByteClkHS);
end procedure;
begin
for iLane in 0 to kLaneCount - 1 loop
Idle(rbRxValidHS(iLane), rbRxSyncHS(iLane), rbRxActiveHS(iLane), rbRxDataHS((iLane+1)*8-1 downto iLane*8));
end loop;
wait until aDEnable = "11";
SendPacket(fs_err);
SendPacket(long_err);
SendPacket(length_err);
SendPacket(fs);
SendPacket(longRAW10_err);
SendPacket(long_err);
SendPacket(fe);
wait;
end process;
ReadProc: process
begin
mAxisTready <= '1';
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
assert (unsigned(mAxisTdata)=to_unsigned(0,C_M_AXIS_TDATA_WIDTH)) report "Expected throw-away data has unexpected value" severity failure;
for i in 0 to 8 - 1 loop
if (i mod C_M_MAX_SAMPLES_PER_CLOCK = 0) then
wait until Rising_Edge(MAxisClk) and mAxisTready = '1' and mAxisTvalid = '1';
end if;
if (i/C_M_MAX_SAMPLES_PER_CLOCK = 0) then
assert(mAxisTuser="1") report "Tuser not asserted at SOF" severity failure;
else
assert(mAxisTuser="0") report "Tuser asserted mid-frame" severity failure;
end if;
assert (to_unsigned(i,10)=unsigned(mAxisTdata(((i mod C_M_MAX_SAMPLES_PER_CLOCK)+1)*10-1 downto (i mod C_M_MAX_SAMPLES_PER_CLOCK)*10))) report "Output data does not match input" severity failure;
if (i/C_M_MAX_SAMPLES_PER_CLOCK = (8-1)/C_M_MAX_SAMPLES_PER_CLOCK) then
assert(mAxisTlast='1') report "Tlast not asserted at EOL" severity failure;
else
assert(mAxisTlast='0') report "Tlast asserted mid-line" severity failure;
end if;
end loop;
report "Testbench executed successfully" severity note;
wait;
end process;
DUT: MIPI_CSI2_Rx
Generic map(
kTargetDT => kTargetDT,
kDebug => false,
--PPI
kLaneCount => kLaneCount, --[1,2,4]
--Video Format
C_M_AXIS_COMPONENT_WIDTH => C_M_AXIS_COMPONENT_WIDTH, -- [8,10]
C_M_AXIS_TDATA_WIDTH => C_M_AXIS_TDATA_WIDTH,
C_M_MAX_SAMPLES_PER_CLOCK => C_M_MAX_SAMPLES_PER_CLOCK
)
Port map(
--PPI
RxByteClkHS => RxByteClkHS,
aClkStopstate => '0',
aRxClkActiveHS => '1',
rbRxDataHS => rbRxDataHS,
rbRxSyncHS => rbRxSyncHS,
rbRxValidHS => rbRxValidHS,
rbRxActiveHS => rbRxActiveHS,
aDEnable => aDEnable,
aClkEnable => aClkEnable,
--axi stream signals
m_axis_video_tdata => mAxisTdata,
m_axis_video_tvalid => mAxisTvalid,
m_axis_video_tready => mAxisTready,
m_axis_video_tlast => mAxisTlast,
m_axis_video_tuser => mAxisTuser,
video_aresetn => mRst_n,
video_aclk => MAxisClk,
vEnable => '1'
);
end Behavioral;
@@ -1,219 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="tb_MIPI_CSI2_behav.wdb" id="1">
<top_modules>
<top_module name="debuglib" />
<top_module name="glbl" />
<top_module name="tb_MIPI_CSI2" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1025000000fs"></ZoomStartTime>
<ZoomEndTime time="1645000001fs"></ZoomEndTime>
<Cursor1Time time="1516547000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="184"></NameColumnWidth>
<ValueColumnWidth column_width="103"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="48" />
<wave_markers>
<marker time="165000000" label="" />
</wave_markers>
<wvobject fp_name="/tb_MIPI_CSI2/mRst_n" type="logic">
<obj_property name="ElementShortName">mRst_n</obj_property>
<obj_property name="ObjectShortName">mRst_n</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/RxByteClkHS" type="logic">
<obj_property name="ElementShortName">RxByteClkHS</obj_property>
<obj_property name="ObjectShortName">RxByteClkHS</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxDataHS" type="array">
<obj_property name="ElementShortName">rbRxDataHS[15:0]</obj_property>
<obj_property name="ObjectShortName">rbRxDataHS[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxSyncHS" type="array">
<obj_property name="ElementShortName">rbRxSyncHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxSyncHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxValidHS" type="array">
<obj_property name="ElementShortName">rbRxValidHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxValidHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxActiveHS" type="array">
<obj_property name="ElementShortName">rbRxActiveHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxActiveHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/aDEnable" type="array">
<obj_property name="ElementShortName">aDEnable[1:0]</obj_property>
<obj_property name="ObjectShortName">aDEnable[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/aClkEnable" type="logic">
<obj_property name="ElementShortName">aClkEnable</obj_property>
<obj_property name="ObjectShortName">aClkEnable</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTdata" type="array">
<obj_property name="ElementShortName">rbMAxisTdata[31:0]</obj_property>
<obj_property name="ObjectShortName">rbMAxisTdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTkeep" type="array">
<obj_property name="ElementShortName">rbMAxisTkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">rbMAxisTkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTvalid" type="logic">
<obj_property name="ElementShortName">rbMAxisTvalid</obj_property>
<obj_property name="ObjectShortName">rbMAxisTvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTready" type="logic">
<obj_property name="ElementShortName">rbMAxisTready</obj_property>
<obj_property name="ObjectShortName">rbMAxisTready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTlast" type="logic">
<obj_property name="ElementShortName">rbMAxisTlast</obj_property>
<obj_property name="ObjectShortName">rbMAxisTlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbErrSkew" type="logic">
<obj_property name="ElementShortName">rbErrSkew</obj_property>
<obj_property name="ObjectShortName">rbErrSkew</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbErrOvf" type="logic">
<obj_property name="ElementShortName">rbErrOvf</obj_property>
<obj_property name="ObjectShortName">rbErrOvf</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tdata" type="array">
<obj_property name="ElementShortName">mFIFO_Tdata[31:0]</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tlast" type="logic">
<obj_property name="ElementShortName">mFIFO_Tlast</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tvalid" type="logic">
<obj_property name="ElementShortName">mFIFO_Tvalid</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tready" type="logic">
<obj_property name="ElementShortName">mFIFO_Tready</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tkeep" type="array">
<obj_property name="ElementShortName">mFIFO_Tkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_HeaderOut" type="array">
<obj_property name="ElementShortName">mECC_HeaderOut[31:0]</obj_property>
<obj_property name="ObjectShortName">mECC_HeaderOut[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_Valid" type="logic">
<obj_property name="ElementShortName">mECC_Valid</obj_property>
<obj_property name="ObjectShortName">mECC_Valid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_Error" type="logic">
<obj_property name="ElementShortName">mECC_Error</obj_property>
<obj_property name="ObjectShortName">mECC_Error</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFlush" type="logic">
<obj_property name="ElementShortName">mFlush</obj_property>
<obj_property name="ObjectShortName">mFlush</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mKeep" type="logic">
<obj_property name="ElementShortName">mKeep</obj_property>
<obj_property name="ObjectShortName">mKeep</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mIsHeader" type="logic">
<obj_property name="ElementShortName">mIsHeader</obj_property>
<obj_property name="ObjectShortName">mIsHeader</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tdata" type="array">
<obj_property name="ElementShortName">mPkt_Tdata[31:0]</obj_property>
<obj_property name="ObjectShortName">mPkt_Tdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tlast" type="logic">
<obj_property name="ElementShortName">mPkt_Tlast</obj_property>
<obj_property name="ObjectShortName">mPkt_Tlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tvalid" type="logic">
<obj_property name="ElementShortName">mPkt_Tvalid</obj_property>
<obj_property name="ObjectShortName">mPkt_Tvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tready" type="logic">
<obj_property name="ElementShortName">mPkt_Tready</obj_property>
<obj_property name="ObjectShortName">mPkt_Tready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tkeep" type="array">
<obj_property name="ElementShortName">mPkt_Tkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">mPkt_Tkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTdata" type="array">
<obj_property name="ElementShortName">mAxisTdata[39:0]</obj_property>
<obj_property name="ObjectShortName">mAxisTdata[39:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTvalid" type="logic">
<obj_property name="ElementShortName">mAxisTvalid</obj_property>
<obj_property name="ObjectShortName">mAxisTvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTready" type="logic">
<obj_property name="ElementShortName">mAxisTready</obj_property>
<obj_property name="ObjectShortName">mAxisTready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTlast" type="logic">
<obj_property name="ElementShortName">mAxisTlast</obj_property>
<obj_property name="ObjectShortName">mAxisTlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTuser" type="array">
<obj_property name="ElementShortName">mAxisTuser[0:0]</obj_property>
<obj_property name="ObjectShortName">mAxisTuser[0:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/MAxisClk" type="logic">
<obj_property name="ElementShortName">MAxisClk</obj_property>
<obj_property name="ObjectShortName">MAxisClk</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kTargetDT" type="array">
<obj_property name="ElementShortName">kTargetDT[1:5]</obj_property>
<obj_property name="ObjectShortName">kTargetDT[1:5]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kLaneCount" type="other">
<obj_property name="ElementShortName">kLaneCount</obj_property>
<obj_property name="ObjectShortName">kLaneCount</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_AXIS_COMPONENT_WIDTH" type="other">
<obj_property name="ElementShortName">C_M_AXIS_COMPONENT_WIDTH</obj_property>
<obj_property name="ObjectShortName">C_M_AXIS_COMPONENT_WIDTH</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_AXIS_TDATA_WIDTH" type="other">
<obj_property name="ElementShortName">C_M_AXIS_TDATA_WIDTH</obj_property>
<obj_property name="ObjectShortName">C_M_AXIS_TDATA_WIDTH</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_MAX_SAMPLES_PER_CLOCK" type="other">
<obj_property name="ElementShortName">C_M_MAX_SAMPLES_PER_CLOCK</obj_property>
<obj_property name="ObjectShortName">C_M_MAX_SAMPLES_PER_CLOCK</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kRxClkPeriod" type="other">
<obj_property name="ElementShortName">kRxClkPeriod</obj_property>
<obj_property name="ObjectShortName">kRxClkPeriod</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kVidClkPeriod" type="other">
<obj_property name="ElementShortName">kVidClkPeriod</obj_property>
<obj_property name="ObjectShortName">kVidClkPeriod</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fs_err" type="array">
<obj_property name="ElementShortName">fs_err[0:5][7:0]</obj_property>
<obj_property name="ObjectShortName">fs_err[0:5][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fs" type="array">
<obj_property name="ElementShortName">fs[0:3][7:0]</obj_property>
<obj_property name="ObjectShortName">fs[0:3][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/longRAW10_err" type="array">
<obj_property name="ElementShortName">longRAW10_err[0:19][7:0]</obj_property>
<obj_property name="ObjectShortName">longRAW10_err[0:19][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fe" type="array">
<obj_property name="ElementShortName">fe[0:3][7:0]</obj_property>
<obj_property name="ObjectShortName">fe[0:3][7:0]</obj_property>
</wvobject>
</wave_config>
<?xml version="1.0" encoding="UTF-8"?>
<wave_config>
<wave_state>
</wave_state>
<db_ref_list>
<db_ref path="tb_MIPI_CSI2_behav.wdb" id="1">
<top_modules>
<top_module name="debuglib" />
<top_module name="glbl" />
<top_module name="tb_MIPI_CSI2" />
</top_modules>
</db_ref>
</db_ref_list>
<zoom_setting>
<ZoomStartTime time="1025000000fs"></ZoomStartTime>
<ZoomEndTime time="1645000001fs"></ZoomEndTime>
<Cursor1Time time="1516547000fs"></Cursor1Time>
</zoom_setting>
<column_width_setting>
<NameColumnWidth column_width="184"></NameColumnWidth>
<ValueColumnWidth column_width="103"></ValueColumnWidth>
</column_width_setting>
<WVObjectSize size="48" />
<wave_markers>
<marker time="165000000" label="" />
</wave_markers>
<wvobject fp_name="/tb_MIPI_CSI2/mRst_n" type="logic">
<obj_property name="ElementShortName">mRst_n</obj_property>
<obj_property name="ObjectShortName">mRst_n</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/RxByteClkHS" type="logic">
<obj_property name="ElementShortName">RxByteClkHS</obj_property>
<obj_property name="ObjectShortName">RxByteClkHS</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxDataHS" type="array">
<obj_property name="ElementShortName">rbRxDataHS[15:0]</obj_property>
<obj_property name="ObjectShortName">rbRxDataHS[15:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxSyncHS" type="array">
<obj_property name="ElementShortName">rbRxSyncHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxSyncHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxValidHS" type="array">
<obj_property name="ElementShortName">rbRxValidHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxValidHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/rbRxActiveHS" type="array">
<obj_property name="ElementShortName">rbRxActiveHS[1:0]</obj_property>
<obj_property name="ObjectShortName">rbRxActiveHS[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/aDEnable" type="array">
<obj_property name="ElementShortName">aDEnable[1:0]</obj_property>
<obj_property name="ObjectShortName">aDEnable[1:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/aClkEnable" type="logic">
<obj_property name="ElementShortName">aClkEnable</obj_property>
<obj_property name="ObjectShortName">aClkEnable</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTdata" type="array">
<obj_property name="ElementShortName">rbMAxisTdata[31:0]</obj_property>
<obj_property name="ObjectShortName">rbMAxisTdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTkeep" type="array">
<obj_property name="ElementShortName">rbMAxisTkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">rbMAxisTkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTvalid" type="logic">
<obj_property name="ElementShortName">rbMAxisTvalid</obj_property>
<obj_property name="ObjectShortName">rbMAxisTvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTready" type="logic">
<obj_property name="ElementShortName">rbMAxisTready</obj_property>
<obj_property name="ObjectShortName">rbMAxisTready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbMAxisTlast" type="logic">
<obj_property name="ElementShortName">rbMAxisTlast</obj_property>
<obj_property name="ObjectShortName">rbMAxisTlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbErrSkew" type="logic">
<obj_property name="ElementShortName">rbErrSkew</obj_property>
<obj_property name="ObjectShortName">rbErrSkew</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LM_inst/rbErrOvf" type="logic">
<obj_property name="ElementShortName">rbErrOvf</obj_property>
<obj_property name="ObjectShortName">rbErrOvf</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tdata" type="array">
<obj_property name="ElementShortName">mFIFO_Tdata[31:0]</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tlast" type="logic">
<obj_property name="ElementShortName">mFIFO_Tlast</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tvalid" type="logic">
<obj_property name="ElementShortName">mFIFO_Tvalid</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tready" type="logic">
<obj_property name="ElementShortName">mFIFO_Tready</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFIFO_Tkeep" type="array">
<obj_property name="ElementShortName">mFIFO_Tkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">mFIFO_Tkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_HeaderOut" type="array">
<obj_property name="ElementShortName">mECC_HeaderOut[31:0]</obj_property>
<obj_property name="ObjectShortName">mECC_HeaderOut[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_Valid" type="logic">
<obj_property name="ElementShortName">mECC_Valid</obj_property>
<obj_property name="ObjectShortName">mECC_Valid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mECC_Error" type="logic">
<obj_property name="ElementShortName">mECC_Error</obj_property>
<obj_property name="ObjectShortName">mECC_Error</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mFlush" type="logic">
<obj_property name="ElementShortName">mFlush</obj_property>
<obj_property name="ObjectShortName">mFlush</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mKeep" type="logic">
<obj_property name="ElementShortName">mKeep</obj_property>
<obj_property name="ObjectShortName">mKeep</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mIsHeader" type="logic">
<obj_property name="ElementShortName">mIsHeader</obj_property>
<obj_property name="ObjectShortName">mIsHeader</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tdata" type="array">
<obj_property name="ElementShortName">mPkt_Tdata[31:0]</obj_property>
<obj_property name="ObjectShortName">mPkt_Tdata[31:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tlast" type="logic">
<obj_property name="ElementShortName">mPkt_Tlast</obj_property>
<obj_property name="ObjectShortName">mPkt_Tlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tvalid" type="logic">
<obj_property name="ElementShortName">mPkt_Tvalid</obj_property>
<obj_property name="ObjectShortName">mPkt_Tvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tready" type="logic">
<obj_property name="ElementShortName">mPkt_Tready</obj_property>
<obj_property name="ObjectShortName">mPkt_Tready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/DUT/LLP_inst/mPkt_Tkeep" type="array">
<obj_property name="ElementShortName">mPkt_Tkeep[3:0]</obj_property>
<obj_property name="ObjectShortName">mPkt_Tkeep[3:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTdata" type="array">
<obj_property name="ElementShortName">mAxisTdata[39:0]</obj_property>
<obj_property name="ObjectShortName">mAxisTdata[39:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTvalid" type="logic">
<obj_property name="ElementShortName">mAxisTvalid</obj_property>
<obj_property name="ObjectShortName">mAxisTvalid</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTready" type="logic">
<obj_property name="ElementShortName">mAxisTready</obj_property>
<obj_property name="ObjectShortName">mAxisTready</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTlast" type="logic">
<obj_property name="ElementShortName">mAxisTlast</obj_property>
<obj_property name="ObjectShortName">mAxisTlast</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/mAxisTuser" type="array">
<obj_property name="ElementShortName">mAxisTuser[0:0]</obj_property>
<obj_property name="ObjectShortName">mAxisTuser[0:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/MAxisClk" type="logic">
<obj_property name="ElementShortName">MAxisClk</obj_property>
<obj_property name="ObjectShortName">MAxisClk</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kTargetDT" type="array">
<obj_property name="ElementShortName">kTargetDT[1:5]</obj_property>
<obj_property name="ObjectShortName">kTargetDT[1:5]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kLaneCount" type="other">
<obj_property name="ElementShortName">kLaneCount</obj_property>
<obj_property name="ObjectShortName">kLaneCount</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_AXIS_COMPONENT_WIDTH" type="other">
<obj_property name="ElementShortName">C_M_AXIS_COMPONENT_WIDTH</obj_property>
<obj_property name="ObjectShortName">C_M_AXIS_COMPONENT_WIDTH</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_AXIS_TDATA_WIDTH" type="other">
<obj_property name="ElementShortName">C_M_AXIS_TDATA_WIDTH</obj_property>
<obj_property name="ObjectShortName">C_M_AXIS_TDATA_WIDTH</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/C_M_MAX_SAMPLES_PER_CLOCK" type="other">
<obj_property name="ElementShortName">C_M_MAX_SAMPLES_PER_CLOCK</obj_property>
<obj_property name="ObjectShortName">C_M_MAX_SAMPLES_PER_CLOCK</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kRxClkPeriod" type="other">
<obj_property name="ElementShortName">kRxClkPeriod</obj_property>
<obj_property name="ObjectShortName">kRxClkPeriod</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/kVidClkPeriod" type="other">
<obj_property name="ElementShortName">kVidClkPeriod</obj_property>
<obj_property name="ObjectShortName">kVidClkPeriod</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fs_err" type="array">
<obj_property name="ElementShortName">fs_err[0:5][7:0]</obj_property>
<obj_property name="ObjectShortName">fs_err[0:5][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fs" type="array">
<obj_property name="ElementShortName">fs[0:3][7:0]</obj_property>
<obj_property name="ObjectShortName">fs[0:3][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/longRAW10_err" type="array">
<obj_property name="ElementShortName">longRAW10_err[0:19][7:0]</obj_property>
<obj_property name="ObjectShortName">longRAW10_err[0:19][7:0]</obj_property>
</wvobject>
<wvobject fp_name="/tb_MIPI_CSI2/fe" type="array">
<obj_property name="ElementShortName">fe[0:3][7:0]</obj_property>
<obj_property name="ObjectShortName">fe[0:3][7:0]</obj_property>
</wvobject>
</wave_config>
@@ -1,192 +1,192 @@
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
@@ -1,192 +1,192 @@
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
@@ -1,192 +1,192 @@
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
# Definitional proc to organize widgets for parameters.
proc init_gui { IPINST } {
ipgui::add_param $IPINST -name "Component_Name"
#Adding Page
set Page_0 [ipgui::add_page $IPINST -name "Page 0" -display_name {Control}]
ipgui::add_param $IPINST -name "kGenerateAXIL" -parent ${Page_0}
ipgui::add_param $IPINST -name "kDebug" -parent ${Page_0}
#Adding Page
set MIPI [ipgui::add_page $IPINST -name "MIPI"]
ipgui::add_param $IPINST -name "kLaneCount" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "kTargetDT" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_COMPONENT_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_AXIS_TDATA_WIDTH" -parent ${MIPI} -widget comboBox
ipgui::add_param $IPINST -name "C_M_MAX_SAMPLES_PER_CLOCK" -parent ${MIPI} -widget comboBox
}
proc update_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to update C_M_AXIS_COMPONENT_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to validate C_M_AXIS_COMPONENT_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to update C_M_AXIS_TDATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_AXIS_TDATA_WIDTH { PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to validate C_M_AXIS_TDATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to update C_M_MAX_SAMPLES_PER_CLOCK when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to validate C_M_MAX_SAMPLES_PER_CLOCK
return true
}
proc update_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to update kDebug when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kDebug { PARAM_VALUE.kDebug } {
# Procedure called to validate kDebug
return true
}
proc update_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to update kGenerateAXIL when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kGenerateAXIL { PARAM_VALUE.kGenerateAXIL } {
# Procedure called to validate kGenerateAXIL
return true
}
proc update_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to update kLaneCount when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kLaneCount { PARAM_VALUE.kLaneCount } {
# Procedure called to validate kLaneCount
return true
}
proc update_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to update kTargetDT when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kTargetDT { PARAM_VALUE.kTargetDT } {
# Procedure called to validate kTargetDT
return true
}
proc update_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to update kVersionMajor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMajor { PARAM_VALUE.kVersionMajor } {
# Procedure called to validate kVersionMajor
return true
}
proc update_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to update kVersionMinor when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.kVersionMinor { PARAM_VALUE.kVersionMinor } {
# Procedure called to validate kVersionMinor
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to update C_S_AXI_LITE_DATA_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_DATA_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to update C_S_AXI_LITE_ADDR_WIDTH when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to validate C_S_AXI_LITE_ADDR_WIDTH
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to update C_S_AXI_LITE_BASEADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_BASEADDR { PARAM_VALUE.C_S_AXI_LITE_BASEADDR } {
# Procedure called to validate C_S_AXI_LITE_BASEADDR
return true
}
proc update_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to update C_S_AXI_LITE_HIGHADDR when any of the dependent parameters in the arguments change
}
proc validate_PARAM_VALUE.C_S_AXI_LITE_HIGHADDR { PARAM_VALUE.C_S_AXI_LITE_HIGHADDR } {
# Procedure called to validate C_S_AXI_LITE_HIGHADDR
return true
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_DATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH { MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}] ${MODELPARAM_VALUE.C_S_AXI_LITE_ADDR_WIDTH}
}
proc update_MODELPARAM_VALUE.kVersionMajor { MODELPARAM_VALUE.kVersionMajor PARAM_VALUE.kVersionMajor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMajor}] ${MODELPARAM_VALUE.kVersionMajor}
}
proc update_MODELPARAM_VALUE.kVersionMinor { MODELPARAM_VALUE.kVersionMinor PARAM_VALUE.kVersionMinor } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kVersionMinor}] ${MODELPARAM_VALUE.kVersionMinor}
}
proc update_MODELPARAM_VALUE.kTargetDT { MODELPARAM_VALUE.kTargetDT PARAM_VALUE.kTargetDT } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kTargetDT}] ${MODELPARAM_VALUE.kTargetDT}
}
proc update_MODELPARAM_VALUE.kGenerateAXIL { MODELPARAM_VALUE.kGenerateAXIL PARAM_VALUE.kGenerateAXIL } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kGenerateAXIL}] ${MODELPARAM_VALUE.kGenerateAXIL}
}
proc update_MODELPARAM_VALUE.kDebug { MODELPARAM_VALUE.kDebug PARAM_VALUE.kDebug } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kDebug}] ${MODELPARAM_VALUE.kDebug}
}
proc update_MODELPARAM_VALUE.kLaneCount { MODELPARAM_VALUE.kLaneCount PARAM_VALUE.kLaneCount } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.kLaneCount}] ${MODELPARAM_VALUE.kLaneCount}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH { MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_COMPONENT_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH { MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH PARAM_VALUE.C_M_AXIS_TDATA_WIDTH } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_AXIS_TDATA_WIDTH}] ${MODELPARAM_VALUE.C_M_AXIS_TDATA_WIDTH}
}
proc update_MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK { MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK } {
# Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value
set_property value [get_property value ${PARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}] ${MODELPARAM_VALUE.C_M_MAX_SAMPLES_PER_CLOCK}
}
@@ -1,136 +1,136 @@
proc init { cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
set full_sbusif_list [list ]
foreach busif $all_busif {
if { [string equal -nocase [get_property MODE $busif] "slave"] == 1 } {
set busif_param_list [list]
set busif_name [get_property NAME $busif]
if { [lsearch -exact -nocase $full_sbusif_list $busif_name ] == -1 } {
continue
}
foreach tparam $axi_standard_param_list {
lappend busif_param_list "C_${busif_name}_${tparam}"
}
bd::mark_propagate_only $cell_handle $busif_param_list
}
}
bd::mark_propagate_only $cell_handle C_dphy_hs_clk_FREQ_HZ
}
proc pre_propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "master"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
if { $val_on_cell != "" } {
set_property CONFIG.${tparam} $val_on_cell $busif
}
}
}
}
}
proc propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "slave"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
#override property of bd_interface_net to bd_cell -- only for slaves. May check for supported values..
if { $val_on_cell_intf_pin != "" } {
set_property CONFIG.${busif_param_name} $val_on_cell_intf_pin $cell_handle
}
}
}
}
# Propagate from one interface to the other
set dphy_clk [get_property CONFIG.FREQ_HZ [get_bd_intf_pins $cellpath/dphy_hs_clock]]
if { $dphy_clk != "" } {
set byte_clk [expr int($dphy_clk) / 4]
set_property CONFIG.FREQ_HZ $byte_clk [get_bd_pins $cellpath/RxByteClkHS]
}
}
# Do FREQ_HZ propagation here
proc post_propagate {cellpath otherInfo } {
set ip [get_bd_cells $cellpath]
set ref_clk_offset 10000000
set ref_clk_expected 200000000
set clk_lite [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/s_axi_lite_aclk]]
set clk_lite_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/s_axi_lite_aclk]]
set clk_lite_phase [get_property CONFIG.PHASE [get_bd_pins $ip/s_axi_lite_aclk]]
set ref_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RefClk]]
set ref_clk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/RefClk]]
set ref_clk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/RefClk]]
set byte_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RxByteClkHS]]
if { $clk_lite == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to s_axi_lite_aclk" $ip
} else {
set_property CONFIG.C_S_AXI_LITE_FREQ_HZ [expr int($clk_lite)] $ip
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $clk_lite propagated into CONFIG.C_S_AXI_LITE_FREQ_HZ"
}
if { $ref_clk == "" } {
set_property MSG.ERROR "Please connect a valid 200MHz clock signal to RefClk" $ip
} elseif { [expr {abs($ref_clk - $ref_clk_expected)}] > $ref_clk_offset} {
set_property MSG.ERROR "RefClk frequency must be in the range of 200MHz +-10MHz" $ip
} else {
set_property CONFIG.kRefClkFreqHz [expr int($ref_clk)] $ip
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $ref_clk propagated into CONFIG.kRefClkFreqHz"
}
if { $byte_clk != "" } {
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $byte_clk propagated onto RxByteClkHS"
}
set vlnv [get_property VLNV $ip]
set ver [split [lindex [split $vlnv :] 3] .]
set ver_major [lindex $ver 0]
set ver_minor [lindex $ver 1]
set_property CONFIG.kVersionMajor [expr int($ver_major)] $ip
set_property CONFIG.kVersionMinor [expr int($ver_minor)] $ip
}
proc init { cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
set full_sbusif_list [list ]
foreach busif $all_busif {
if { [string equal -nocase [get_property MODE $busif] "slave"] == 1 } {
set busif_param_list [list]
set busif_name [get_property NAME $busif]
if { [lsearch -exact -nocase $full_sbusif_list $busif_name ] == -1 } {
continue
}
foreach tparam $axi_standard_param_list {
lappend busif_param_list "C_${busif_name}_${tparam}"
}
bd::mark_propagate_only $cell_handle $busif_param_list
}
}
bd::mark_propagate_only $cell_handle C_dphy_hs_clk_FREQ_HZ
}
proc pre_propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "master"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
if { $val_on_cell != "" } {
set_property CONFIG.${tparam} $val_on_cell $busif
}
}
}
}
}
proc propagate {cellpath otherInfo } {
set cell_handle [get_bd_cells $cellpath]
set all_busif [get_bd_intf_pins $cellpath/*]
set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH]
foreach busif $all_busif {
if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } {
continue
}
if { [string equal -nocase [get_property MODE $busif] "slave"] != 1 } {
continue
}
set busif_name [get_property NAME $busif]
foreach tparam $axi_standard_param_list {
set busif_param_name "C_${busif_name}_${tparam}"
set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif]
set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle]
if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } {
#override property of bd_interface_net to bd_cell -- only for slaves. May check for supported values..
if { $val_on_cell_intf_pin != "" } {
set_property CONFIG.${busif_param_name} $val_on_cell_intf_pin $cell_handle
}
}
}
}
# Propagate from one interface to the other
set dphy_clk [get_property CONFIG.FREQ_HZ [get_bd_intf_pins $cellpath/dphy_hs_clock]]
if { $dphy_clk != "" } {
set byte_clk [expr int($dphy_clk) / 4]
set_property CONFIG.FREQ_HZ $byte_clk [get_bd_pins $cellpath/RxByteClkHS]
}
}
# Do FREQ_HZ propagation here
proc post_propagate {cellpath otherInfo } {
set ip [get_bd_cells $cellpath]
set ref_clk_offset 10000000
set ref_clk_expected 200000000
set clk_lite [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/s_axi_lite_aclk]]
set clk_lite_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/s_axi_lite_aclk]]
set clk_lite_phase [get_property CONFIG.PHASE [get_bd_pins $ip/s_axi_lite_aclk]]
set ref_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RefClk]]
set ref_clk_domain [get_property CONFIG.CLK_DOMAIN [get_bd_pins $ip/RefClk]]
set ref_clk_phase [get_property CONFIG.PHASE [get_bd_pins $ip/RefClk]]
set byte_clk [get_property CONFIG.FREQ_HZ [get_bd_pins $ip/RxByteClkHS]]
if { $clk_lite == "" } {
set_property MSG.ERROR "Please connect a valid clock signal to s_axi_lite_aclk" $ip
} else {
set_property CONFIG.C_S_AXI_LITE_FREQ_HZ [expr int($clk_lite)] $ip
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $clk_lite propagated into CONFIG.C_S_AXI_LITE_FREQ_HZ"
}
if { $ref_clk == "" } {
set_property MSG.ERROR "Please connect a valid 200MHz clock signal to RefClk" $ip
} elseif { [expr {abs($ref_clk - $ref_clk_expected)}] > $ref_clk_offset} {
set_property MSG.ERROR "RefClk frequency must be in the range of 200MHz +-10MHz" $ip
} else {
set_property CONFIG.kRefClkFreqHz [expr int($ref_clk)] $ip
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $ref_clk propagated into CONFIG.kRefClkFreqHz"
}
if { $byte_clk != "" } {
bd::send_msg -of $cellpath -type INFO -msg_id 17 -text "FREQ_HZ of $byte_clk propagated onto RxByteClkHS"
}
set vlnv [get_property VLNV $ip]
set ver [split [lindex [split $vlnv :] 3] .]
set ver_major [lindex $ver 0]
set ver_minor [lindex $ver 1]
set_property CONFIG.kVersionMajor [expr int($ver_major)] $ip
set_property CONFIG.kVersionMinor [expr int($ver_minor)] $ip
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "MIPI_D_PHY_RX" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_LITE_BASEADDR" "C_S_AXI_LITE_HIGHADDR"
}
proc generate {drv_handle} {
xdefine_include_file $drv_handle "xparameters.h" "MIPI_D_PHY_RX" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_LITE_BASEADDR" "C_S_AXI_LITE_HIGHADDR"
}
@@ -1,6 +1,6 @@
/***************************** Include Files *******************************/
#include "MIPI_D_PHY_RX.h"
/************************** Function Definitions ***************************/
/***************************** Include Files *******************************/
#include "MIPI_D_PHY_RX.h"
/************************** Function Definitions ***************************/
@@ -1,86 +1,86 @@
#ifndef MIPI_D_PHY_RX_H
#define MIPI_D_PHY_RX_H
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define MAJOR_VERSION (1)
#define MINOR_VERSION (0)
/****************** Register map ********************/
#define CR_OFFSET 0x0
#define VERSION_OFFSET 0xC
/****************** Bit map ********************/
#define CR_ENABLE_MASK 0x2
#define CR_RESET_MASK 0x1
#define VERSION_MAJOR_MASK 0xFFFF0000
#define VERSION_MAJOR_SHIFT 16
#define VERSION_MINOR_MASK 0x0000FFFF
#define VERSION_MINOR_SHIFT 0
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a MIPI_D_PHY_RX register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the MIPI_D_PHY_RXdevice.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MIPI_D_PHY_RX_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
*
*/
#define MIPI_D_PHY_RX_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/**
*
* Read a value from a MIPI_D_PHY_RX register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the MIPI_D_PHY_RX device.
* @param RegOffset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* u32 MIPI_D_PHY_RX_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
*/
#define MIPI_D_PHY_RX_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ****************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_D_PHY_RX instance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_D_PHY_RX_SelfTest(void * baseaddr_p);
#endif // MIPI_D_PHY_RX_H
#ifndef MIPI_D_PHY_RX_H
#define MIPI_D_PHY_RX_H
/****************** Include Files ********************/
#include "xil_types.h"
#include "xstatus.h"
#define MAJOR_VERSION (1)
#define MINOR_VERSION (0)
/****************** Register map ********************/
#define CR_OFFSET 0x0
#define VERSION_OFFSET 0xC
/****************** Bit map ********************/
#define CR_ENABLE_MASK 0x2
#define CR_RESET_MASK 0x1
#define VERSION_MAJOR_MASK 0xFFFF0000
#define VERSION_MAJOR_SHIFT 16
#define VERSION_MINOR_MASK 0x0000FFFF
#define VERSION_MINOR_SHIFT 0
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a MIPI_D_PHY_RX register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param BaseAddress is the base address of the MIPI_D_PHY_RXdevice.
* @param RegOffset is the register offset from the base to write to.
* @param Data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MIPI_D_PHY_RX_mWriteReg(u32 BaseAddress, unsigned RegOffset, u32 Data)
*
*/
#define MIPI_D_PHY_RX_mWriteReg(BaseAddress, RegOffset, Data) \
Xil_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/**
*
* Read a value from a MIPI_D_PHY_RX register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param BaseAddress is the base address of the MIPI_D_PHY_RX device.
* @param RegOffset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* u32 MIPI_D_PHY_RX_mReadReg(u32 BaseAddress, unsigned RegOffset)
*
*/
#define MIPI_D_PHY_RX_mReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ****************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_D_PHY_RX instance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_D_PHY_RX_SelfTest(void * baseaddr_p);
#endif // MIPI_D_PHY_RX_H
@@ -1,47 +1,47 @@
/***************************** Include Files *******************************/
#include "MIPI_D_PHY_RX.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_D_PHY_RXinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_D_PHY_RX_SelfTest(void * baseaddr_p)
{
u32 baseaddr;
u32 version;
baseaddr = (u32) baseaddr_p;
version = MIPI_D_PHY_RX_mReadReg(baseaddr, VERSION_OFFSET);
if (!(((version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT == MAJOR_VERSION) &&
((version & VERSION_MINOR_MASK) >> VERSION_MINOR_SHIFT == MINOR_VERSION)))
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
/***************************** Include Files *******************************/
#include "MIPI_D_PHY_RX.h"
#include "xparameters.h"
#include "stdio.h"
#include "xil_io.h"
/************************** Constant Definitions ***************************/
#define READ_WRITE_MUL_FACTOR 0x10
/************************** Function Definitions ***************************/
/**
*
* Run a self-test on the driver/device. Note this may be a destructive test if
* resets of the device are performed.
*
* If the hardware system is not built correctly, this function may never
* return to the caller.
*
* @param baseaddr_p is the base address of the MIPI_D_PHY_RXinstance to be worked on.
*
* @return
*
* - XST_SUCCESS if all self-test code passed
* - XST_FAILURE if any self-test code failed
*
* @note Caching must be turned off for this function to work.
* @note Self test may fail if data memory and device are not on the same bus.
*
*/
XStatus MIPI_D_PHY_RX_SelfTest(void * baseaddr_p)
{
u32 baseaddr;
u32 version;
baseaddr = (u32) baseaddr_p;
version = MIPI_D_PHY_RX_mReadReg(baseaddr, VERSION_OFFSET);
if (!(((version & VERSION_MAJOR_MASK) >> VERSION_MAJOR_SHIFT == MAJOR_VERSION) &&
((version & VERSION_MINOR_MASK) >> VERSION_MINOR_SHIFT == MINOR_VERSION)))
{
return XST_FAILURE;
}
return XST_SUCCESS;
}
@@ -1,185 +1,185 @@
`timescale 1 ns / 1 ps
`include "MIPI_D_PHY_RX_v1_0_tb_include.vh"
// lite_response Type Defines
`define RESPONSE_OKAY 2'b00
`define RESPONSE_EXOKAY 2'b01
`define RESP_BUS_WIDTH 2
`define BURST_TYPE_INCR 2'b01
`define BURST_TYPE_WRAP 2'b10
// AMBA AXI4 Lite Range Constants
`define S_AXI_LITE_MAX_BURST_LENGTH 1
`define S_AXI_LITE_DATA_BUS_WIDTH 32
`define S_AXI_LITE_ADDRESS_BUS_WIDTH 32
`define S_AXI_LITE_MAX_DATA_SIZE (`S_AXI_LITE_DATA_BUS_WIDTH*`S_AXI_LITE_MAX_BURST_LENGTH)/8
module MIPI_D_PHY_RX_v1_0_tb;
reg tb_ACLK;
reg tb_ARESETn;
// Create an instance of the example tb
`BD_WRAPPER dut (.ACLK(tb_ACLK),
.ARESETN(tb_ARESETn));
// Local Variables
// AMBA S_AXI_LITE AXI4 Lite Local Reg
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_rd_data_lite;
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_test_data_lite [3:0];
reg [`RESP_BUS_WIDTH-1:0] S_AXI_LITE_lite_response;
reg [`S_AXI_LITE_ADDRESS_BUS_WIDTH-1:0] S_AXI_LITE_mtestAddress;
reg [3-1:0] S_AXI_LITE_mtestProtection_lite;
integer S_AXI_LITE_mtestvectorlite; // Master side testvector
integer S_AXI_LITE_mtestdatasizelite;
integer result_slave_lite;
// Simple Reset Generator and test
initial begin
tb_ARESETn = 1'b0;
#500;
// Release the reset on the posedge of the clk.
@(posedge tb_ACLK);
tb_ARESETn = 1'b1;
@(posedge tb_ACLK);
end
// Simple Clock Generator
initial tb_ACLK = 1'b0;
always #10 tb_ACLK = !tb_ACLK;
//------------------------------------------------------------------------
// TEST LEVEL API: CHECK_RESPONSE_OKAY
//------------------------------------------------------------------------
// Description:
// CHECK_RESPONSE_OKAY(lite_response)
// This task checks if the return lite_response is equal to OKAY
//------------------------------------------------------------------------
task automatic CHECK_RESPONSE_OKAY;
input [`RESP_BUS_WIDTH-1:0] response;
begin
if (response !== `RESPONSE_OKAY) begin
$display("TESTBENCH ERROR! lite_response is not OKAY",
"\n expected = 0x%h",`RESPONSE_OKAY,
"\n actual = 0x%h",response);
$stop;
end
end
endtask
//------------------------------------------------------------------------
// TEST LEVEL API: COMPARE_LITE_DATA
//------------------------------------------------------------------------
// Description:
// COMPARE_LITE_DATA(expected,actual)
// This task checks if the actual data is equal to the expected data.
// X is used as don't care but it is not permitted for the full vector
// to be don't care.
//------------------------------------------------------------------------
`define S_AXI_DATA_BUS_WIDTH 32
task automatic COMPARE_LITE_DATA;
input [`S_AXI_DATA_BUS_WIDTH-1:0]expected;
input [`S_AXI_DATA_BUS_WIDTH-1:0]actual;
begin
if (expected === 'hx || actual === 'hx) begin
$display("TESTBENCH ERROR! COMPARE_LITE_DATA cannot be performed with an expected or actual vector that is all 'x'!");
result_slave_lite = 0;
$stop;
end
if (actual != expected) begin
$display("TESTBENCH ERROR! Data expected is not equal to actual.",
"\nexpected = 0x%h",expected,
"\nactual = 0x%h",actual);
result_slave_lite = 0;
$stop;
end
else
begin
$display("TESTBENCH Passed! Data expected is equal to actual.",
"\n expected = 0x%h",expected,
"\n actual = 0x%h",actual);
end
end
endtask
task automatic S_AXI_LITE_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_LITE");
$display("Simple register write and read example");
$display("---------------------------------------------------------");
S_AXI_LITE_mtestvectorlite = 0;
S_AXI_LITE_mtestAddress = `S_AXI_LITE_SLAVE_ADDRESS;
S_AXI_LITE_mtestProtection_lite = 0;
S_AXI_LITE_mtestdatasizelite = `S_AXI_LITE_MAX_DATA_SIZE;
result_slave_lite = 1;
for (S_AXI_LITE_mtestvectorlite = 0; S_AXI_LITE_mtestvectorlite <= 3; S_AXI_LITE_mtestvectorlite = S_AXI_LITE_mtestvectorlite + 1)
begin
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT( S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],
S_AXI_LITE_mtestdatasizelite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d write : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_rd_data_lite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d read : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_rd_data_lite,S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
COMPARE_LITE_DATA(S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_rd_data_lite);
$display("EXAMPLE TEST %d : Sequential write and read burst transfers complete from the master side. %d",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_mtestvectorlite);
S_AXI_LITE_mtestAddress = S_AXI_LITE_mtestAddress + 32'h00000004;
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_LITE: PTGEN_TEST_FINISHED!");
if ( result_slave_lite ) begin
$display("PTGEN_TEST: PASSED!");
end else begin
$display("PTGEN_TEST: FAILED!");
end
$display("---------------------------------------------------------");
end
endtask
// Create the test vectors
initial begin
// When performing debug enable all levels of INFO messages.
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.set_channel_level_info(1);
// Create test data vectors
S_AXI_LITE_test_data_lite[0] = 32'h0101FFFF;
S_AXI_LITE_test_data_lite[1] = 32'habcd0001;
S_AXI_LITE_test_data_lite[2] = 32'hdead0011;
S_AXI_LITE_test_data_lite[3] = 32'hbeef0011;
end
// Drive the BFM
initial begin
// Wait for end of reset
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
S_AXI_LITE_TEST();
end
endmodule
`timescale 1 ns / 1 ps
`include "MIPI_D_PHY_RX_v1_0_tb_include.vh"
// lite_response Type Defines
`define RESPONSE_OKAY 2'b00
`define RESPONSE_EXOKAY 2'b01
`define RESP_BUS_WIDTH 2
`define BURST_TYPE_INCR 2'b01
`define BURST_TYPE_WRAP 2'b10
// AMBA AXI4 Lite Range Constants
`define S_AXI_LITE_MAX_BURST_LENGTH 1
`define S_AXI_LITE_DATA_BUS_WIDTH 32
`define S_AXI_LITE_ADDRESS_BUS_WIDTH 32
`define S_AXI_LITE_MAX_DATA_SIZE (`S_AXI_LITE_DATA_BUS_WIDTH*`S_AXI_LITE_MAX_BURST_LENGTH)/8
module MIPI_D_PHY_RX_v1_0_tb;
reg tb_ACLK;
reg tb_ARESETn;
// Create an instance of the example tb
`BD_WRAPPER dut (.ACLK(tb_ACLK),
.ARESETN(tb_ARESETn));
// Local Variables
// AMBA S_AXI_LITE AXI4 Lite Local Reg
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_rd_data_lite;
reg [`S_AXI_LITE_DATA_BUS_WIDTH-1:0] S_AXI_LITE_test_data_lite [3:0];
reg [`RESP_BUS_WIDTH-1:0] S_AXI_LITE_lite_response;
reg [`S_AXI_LITE_ADDRESS_BUS_WIDTH-1:0] S_AXI_LITE_mtestAddress;
reg [3-1:0] S_AXI_LITE_mtestProtection_lite;
integer S_AXI_LITE_mtestvectorlite; // Master side testvector
integer S_AXI_LITE_mtestdatasizelite;
integer result_slave_lite;
// Simple Reset Generator and test
initial begin
tb_ARESETn = 1'b0;
#500;
// Release the reset on the posedge of the clk.
@(posedge tb_ACLK);
tb_ARESETn = 1'b1;
@(posedge tb_ACLK);
end
// Simple Clock Generator
initial tb_ACLK = 1'b0;
always #10 tb_ACLK = !tb_ACLK;
//------------------------------------------------------------------------
// TEST LEVEL API: CHECK_RESPONSE_OKAY
//------------------------------------------------------------------------
// Description:
// CHECK_RESPONSE_OKAY(lite_response)
// This task checks if the return lite_response is equal to OKAY
//------------------------------------------------------------------------
task automatic CHECK_RESPONSE_OKAY;
input [`RESP_BUS_WIDTH-1:0] response;
begin
if (response !== `RESPONSE_OKAY) begin
$display("TESTBENCH ERROR! lite_response is not OKAY",
"\n expected = 0x%h",`RESPONSE_OKAY,
"\n actual = 0x%h",response);
$stop;
end
end
endtask
//------------------------------------------------------------------------
// TEST LEVEL API: COMPARE_LITE_DATA
//------------------------------------------------------------------------
// Description:
// COMPARE_LITE_DATA(expected,actual)
// This task checks if the actual data is equal to the expected data.
// X is used as don't care but it is not permitted for the full vector
// to be don't care.
//------------------------------------------------------------------------
`define S_AXI_DATA_BUS_WIDTH 32
task automatic COMPARE_LITE_DATA;
input [`S_AXI_DATA_BUS_WIDTH-1:0]expected;
input [`S_AXI_DATA_BUS_WIDTH-1:0]actual;
begin
if (expected === 'hx || actual === 'hx) begin
$display("TESTBENCH ERROR! COMPARE_LITE_DATA cannot be performed with an expected or actual vector that is all 'x'!");
result_slave_lite = 0;
$stop;
end
if (actual != expected) begin
$display("TESTBENCH ERROR! Data expected is not equal to actual.",
"\nexpected = 0x%h",expected,
"\nactual = 0x%h",actual);
result_slave_lite = 0;
$stop;
end
else
begin
$display("TESTBENCH Passed! Data expected is equal to actual.",
"\n expected = 0x%h",expected,
"\n actual = 0x%h",actual);
end
end
endtask
task automatic S_AXI_LITE_TEST;
begin
$display("---------------------------------------------------------");
$display("EXAMPLE TEST : S_AXI_LITE");
$display("Simple register write and read example");
$display("---------------------------------------------------------");
S_AXI_LITE_mtestvectorlite = 0;
S_AXI_LITE_mtestAddress = `S_AXI_LITE_SLAVE_ADDRESS;
S_AXI_LITE_mtestProtection_lite = 0;
S_AXI_LITE_mtestdatasizelite = `S_AXI_LITE_MAX_DATA_SIZE;
result_slave_lite = 1;
for (S_AXI_LITE_mtestvectorlite = 0; S_AXI_LITE_mtestvectorlite <= 3; S_AXI_LITE_mtestvectorlite = S_AXI_LITE_mtestvectorlite + 1)
begin
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.WRITE_BURST_CONCURRENT( S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],
S_AXI_LITE_mtestdatasizelite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d write : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.READ_BURST(S_AXI_LITE_mtestAddress,
S_AXI_LITE_mtestProtection_lite,
S_AXI_LITE_rd_data_lite,
S_AXI_LITE_lite_response);
$display("EXAMPLE TEST %d read : DATA = 0x%h, lite_response = 0x%h",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_rd_data_lite,S_AXI_LITE_lite_response);
CHECK_RESPONSE_OKAY(S_AXI_LITE_lite_response);
COMPARE_LITE_DATA(S_AXI_LITE_test_data_lite[S_AXI_LITE_mtestvectorlite],S_AXI_LITE_rd_data_lite);
$display("EXAMPLE TEST %d : Sequential write and read burst transfers complete from the master side. %d",S_AXI_LITE_mtestvectorlite,S_AXI_LITE_mtestvectorlite);
S_AXI_LITE_mtestAddress = S_AXI_LITE_mtestAddress + 32'h00000004;
end
$display("---------------------------------------------------------");
$display("EXAMPLE TEST S_AXI_LITE: PTGEN_TEST_FINISHED!");
if ( result_slave_lite ) begin
$display("PTGEN_TEST: PASSED!");
end else begin
$display("PTGEN_TEST: FAILED!");
end
$display("---------------------------------------------------------");
end
endtask
// Create the test vectors
initial begin
// When performing debug enable all levels of INFO messages.
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
dut.`BD_INST_NAME.master_0.cdn_axi4_lite_master_bfm_inst.set_channel_level_info(1);
// Create test data vectors
S_AXI_LITE_test_data_lite[0] = 32'h0101FFFF;
S_AXI_LITE_test_data_lite[1] = 32'habcd0001;
S_AXI_LITE_test_data_lite[2] = 32'hdead0011;
S_AXI_LITE_test_data_lite[3] = 32'hbeef0011;
end
// Drive the BFM
initial begin
// Wait for end of reset
wait(tb_ARESETn === 0) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
wait(tb_ARESETn === 1) @(posedge tb_ACLK);
S_AXI_LITE_TEST();
end
endmodule
@@ -1,91 +1,91 @@
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create Clock and Reset Ports
set ACLK [ create_bd_port -dir I -type clk ACLK ]
set_property -dict [ list CONFIG.FREQ_HZ {100000000} CONFIG.PHASE {0.000} CONFIG.CLK_DOMAIN "${design_name}_ACLK" ] $ACLK
set ARESETN [ create_bd_port -dir I -type rst ARESETN ]
set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $ARESETN
set_property CONFIG.ASSOCIATED_RESET ARESETN $ACLK
# Create instance: MIPI_D_PHY_RX_0, and set properties
set MIPI_D_PHY_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_D_PHY_RX:1.0 MIPI_D_PHY_RX_0]
# Create instance: master_0, and set properties
set master_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_0]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_0
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_0/M_AXI_LITE] [get_bd_intf_pins MIPI_D_PHY_RX_0/S_AXI_LITE]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_0/M_AXI_LITE_ACLK] [get_bd_pins MIPI_D_PHY_RX_0/S_AXI_LITE_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_0/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_D_PHY_RX_0/S_AXI_LITE_ARESETN]
# Auto assign address
assign_bd_address
# Copy all address to interface_address.vh file
set bd_path [file dirname [get_property NAME [get_files ${design_name}.bd]]]
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_D_PHY_RX_v1_0_tb_include.vh"
set fp [open $offset_file "w"]
puts $fp "`ifndef MIPI_D_PHY_RX_v1_0_tb_include_vh_"
puts $fp "`define MIPI_D_PHY_RX_v1_0_tb_include_vh_\n"
puts $fp "//Configuration current bd names"
puts $fp "`define BD_INST_NAME ${design_name}_i"
puts $fp "`define BD_WRAPPER ${design_name}_wrapper\n"
puts $fp "//Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_0/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_LITE_SLAVE_ADDRESS ${offset_hex}"
puts $fp "`endif"
close $fp
}
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_D_PHY_RX:1.0]]]]
set test_bench_file ${ip_path}/example_designs/bfm_design/MIPI_D_PHY_RX_v1_0_tb.v
set interface_address_vh_file ""
# Set IP Repository and Update IP Catalogue
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_D_PHY_RX_v1_0_bfm_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
create_ipi_design interface_address_vh_file ${design_name}
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
set_property SOURCE_SET sources_1 [get_filesets sim_1]
import_files -fileset sim_1 -norecurse -force $test_bench_file
remove_files -quiet -fileset sim_1 MIPI_D_PHY_RX_v1_0_tb_include.vh
import_files -fileset sim_1 -norecurse -force $interface_address_vh_file
set_property top MIPI_D_PHY_RX_v1_0_tb [get_filesets sim_1]
set_property top_lib {} [get_filesets sim_1]
set_property top_file {} [get_filesets sim_1]
launch_xsim -simset sim_1 -mode behavioral
restart
run 1000 us
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create Clock and Reset Ports
set ACLK [ create_bd_port -dir I -type clk ACLK ]
set_property -dict [ list CONFIG.FREQ_HZ {100000000} CONFIG.PHASE {0.000} CONFIG.CLK_DOMAIN "${design_name}_ACLK" ] $ACLK
set ARESETN [ create_bd_port -dir I -type rst ARESETN ]
set_property -dict [ list CONFIG.POLARITY {ACTIVE_LOW} ] $ARESETN
set_property CONFIG.ASSOCIATED_RESET ARESETN $ACLK
# Create instance: MIPI_D_PHY_RX_0, and set properties
set MIPI_D_PHY_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_D_PHY_RX:1.0 MIPI_D_PHY_RX_0]
# Create instance: master_0, and set properties
set master_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:cdn_axi_bfm master_0]
set_property -dict [ list CONFIG.C_PROTOCOL_SELECTION {2} ] $master_0
# Create interface connections
connect_bd_intf_net [get_bd_intf_pins master_0/M_AXI_LITE] [get_bd_intf_pins MIPI_D_PHY_RX_0/S_AXI_LITE]
# Create port connections
connect_bd_net -net aclk_net [get_bd_ports ACLK] [get_bd_pins master_0/M_AXI_LITE_ACLK] [get_bd_pins MIPI_D_PHY_RX_0/S_AXI_LITE_ACLK]
connect_bd_net -net aresetn_net [get_bd_ports ARESETN] [get_bd_pins master_0/M_AXI_LITE_ARESETN] [get_bd_pins MIPI_D_PHY_RX_0/S_AXI_LITE_ARESETN]
# Auto assign address
assign_bd_address
# Copy all address to interface_address.vh file
set bd_path [file dirname [get_property NAME [get_files ${design_name}.bd]]]
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_D_PHY_RX_v1_0_tb_include.vh"
set fp [open $offset_file "w"]
puts $fp "`ifndef MIPI_D_PHY_RX_v1_0_tb_include_vh_"
puts $fp "`define MIPI_D_PHY_RX_v1_0_tb_include_vh_\n"
puts $fp "//Configuration current bd names"
puts $fp "`define BD_INST_NAME ${design_name}_i"
puts $fp "`define BD_WRAPPER ${design_name}_wrapper\n"
puts $fp "//Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs -of_objects [get_bd_addr_spaces master_0/Data_lite]]]
set offset_hex [string replace $offset 0 1 "32'h"]
puts $fp "`define S_AXI_LITE_SLAVE_ADDRESS ${offset_hex}"
puts $fp "`endif"
close $fp
}
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_D_PHY_RX:1.0]]]]
set test_bench_file ${ip_path}/example_designs/bfm_design/MIPI_D_PHY_RX_v1_0_tb.v
set interface_address_vh_file ""
# Set IP Repository and Update IP Catalogue
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_D_PHY_RX_v1_0_bfm_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
create_ipi_design interface_address_vh_file ${design_name}
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
set_property SOURCE_SET sources_1 [get_filesets sim_1]
import_files -fileset sim_1 -norecurse -force $test_bench_file
remove_files -quiet -fileset sim_1 MIPI_D_PHY_RX_v1_0_tb_include.vh
import_files -fileset sim_1 -norecurse -force $interface_address_vh_file
set_property top MIPI_D_PHY_RX_v1_0_tb [get_filesets sim_1]
set_property top_lib {} [get_filesets sim_1]
set_property top_file {} [get_filesets sim_1]
launch_xsim -simset sim_1 -mode behavioral
restart
run 1000 us
@@ -1,45 +1,45 @@
# Runtime Tcl commands to interact with - MIPI_D_PHY_RX_v1_0
# Sourcing design address info tcl
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
source ${bd_path}/MIPI_D_PHY_RX_v1_0_include.tcl
# jtag axi master interface hardware name, change as per your design.
set jtag_axi_master hw_axi_1
set ec 0
# hw test script
# Delete all previous axis transactions
if { [llength [get_hw_axi_txns -quiet]] } {
delete_hw_axi_txn [get_hw_axi_txns -quiet]
}
# Test all lite slaves.
set wdata_1 abcd1234
# Test: S_AXI_LITE
# Create a write transaction at s_axi_lite_addr address
create_hw_axi_txn w_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type write -address $s_axi_lite_addr -data $wdata_1
# Create a read transaction at s_axi_lite_addr address
create_hw_axi_txn r_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type read -address $s_axi_lite_addr
# Initiate transactions
run_hw_axi r_s_axi_lite_addr
run_hw_axi w_s_axi_lite_addr
run_hw_axi r_s_axi_lite_addr
set rdata_tmp [get_property DATA [get_hw_axi_txn r_s_axi_lite_addr]]
# Compare read data
if { $rdata_tmp == $wdata_1 } {
puts "Data comparison test pass for - S_AXI_LITE"
} else {
puts "Data comparison test fail for - S_AXI_LITE, expected-$wdata_1 actual-$rdata_tmp"
inc ec
}
# Check error flag
if { $ec == 0 } {
puts "PTGEN_TEST: PASSED!"
} else {
puts "PTGEN_TEST: FAILED!"
}
# Runtime Tcl commands to interact with - MIPI_D_PHY_RX_v1_0
# Sourcing design address info tcl
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
source ${bd_path}/MIPI_D_PHY_RX_v1_0_include.tcl
# jtag axi master interface hardware name, change as per your design.
set jtag_axi_master hw_axi_1
set ec 0
# hw test script
# Delete all previous axis transactions
if { [llength [get_hw_axi_txns -quiet]] } {
delete_hw_axi_txn [get_hw_axi_txns -quiet]
}
# Test all lite slaves.
set wdata_1 abcd1234
# Test: S_AXI_LITE
# Create a write transaction at s_axi_lite_addr address
create_hw_axi_txn w_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type write -address $s_axi_lite_addr -data $wdata_1
# Create a read transaction at s_axi_lite_addr address
create_hw_axi_txn r_s_axi_lite_addr [get_hw_axis $jtag_axi_master] -type read -address $s_axi_lite_addr
# Initiate transactions
run_hw_axi r_s_axi_lite_addr
run_hw_axi w_s_axi_lite_addr
run_hw_axi r_s_axi_lite_addr
set rdata_tmp [get_property DATA [get_hw_axi_txn r_s_axi_lite_addr]]
# Compare read data
if { $rdata_tmp == $wdata_1 } {
puts "Data comparison test pass for - S_AXI_LITE"
} else {
puts "Data comparison test fail for - S_AXI_LITE, expected-$wdata_1 actual-$rdata_tmp"
inc ec
}
# Check error flag
if { $ec == 0 } {
puts "PTGEN_TEST: PASSED!"
} else {
puts "PTGEN_TEST: FAILED!"
}
@@ -1,175 +1,175 @@
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create and configure Clock/Reset
create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz sys_clk_0
create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset sys_reset_0
#check if current_board is set, if true - figure out required clocks.
set is_board_clock_found 0
set is_board_reset_found 0
set external_reset_port ""
set external_clock_port ""
if { [current_board_part -quiet] != "" } {
#check if any reset interface exists in board.
set board_reset [lindex [get_board_part_interfaces -filter { BUSDEF_NAME == reset_rtl && MODE == slave }] 0 ]
if { $board_reset ne "" } {
set is_board_reset_found 1
apply_board_connection -board_interface $board_reset -ip_intf sys_clk_0/reset -diagram [current_bd_design]
apply_board_connection -board_interface $board_reset -ip_intf sys_reset_0/ext_reset -diagram [current_bd_design]
set external_rst [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/reset]]]
if { $external_rst ne "" } {
set external_reset_port [get_property NAME $external_rst]
}
} else {
send_msg "ptgen 51-200" WARNING "No reset interface found in current_board, Users may need to specify the location constraints manually."
}
# check for differential clock, exclude any special clocks which has TYPE property.
set board_clock_busifs ""
foreach busif [get_board_part_interfaces -filter "BUSDEF_NAME == diff_clock_rtl"] {
set type [get_property PARAM.TYPE $busif]
if { $type == "" } {
set board_clock_busifs $busif
break
}
}
if { $board_clock_busifs ne "" } {
apply_board_connection -board_interface $board_clock_busifs -ip_intf sys_clk_0/CLK_IN1_D -diagram [current_bd_design]
set is_board_clock_found 1
} else {
# check for single ended clock
set board_sclock_busifs [lindex [get_board_part_interfaces -filter "BUSDEF_NAME == clock_rtl"] 0 ]
if { $board_sclock_busifs ne "" } {
apply_board_connection -board_interface $board_sclock_busifs -ip_intf sys_clk_0/clock_CLK_IN1 -diagram [current_bd_design]
set external_clk [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/clk_in1]]]
if { $external_clk ne "" } {
set external_clock_port [get_property NAME $external_clk]
}
set is_board_clock_found 1
} else {
send_msg "ptgen 51-200" WARNING "No clock interface found in current_board, Users may need to specify the location constraints manually."
}
}
} else {
send_msg "ptgen 51-201" WARNING "No board selected in current_project. Users may need to specify the location constraints manually."
}
#if there is no corresponding board interface found, assume constraints will be provided manually while pin planning.
if { $is_board_reset_found == 0 } {
create_bd_port -dir I -type rst reset_rtl
set_property CONFIG.POLARITY [get_property CONFIG.POLARITY [get_bd_pins sys_clk_0/reset]] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_pins sys_reset_0/ext_reset_in] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_ports reset_rtl] [get_bd_pins sys_clk_0/reset]
set external_reset_port reset_rtl
}
if { $is_board_clock_found == 0 } {
create_bd_port -dir I -type clk clock_rtl
connect_bd_net [get_bd_pins sys_clk_0/clk_in1] [get_bd_ports clock_rtl]
set external_clock_port clock_rtl
}
#Avoid IPI DRC, make clock port synchronous to reset
if { $external_clock_port ne "" && $external_reset_port ne "" } {
set_property CONFIG.ASSOCIATED_RESET $external_reset_port [get_bd_ports $external_clock_port]
}
# Connect other sys_reset pins
connect_bd_net [get_bd_pins sys_reset_0/slowest_sync_clk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins sys_clk_0/locked] [get_bd_pins sys_reset_0/dcm_locked]
# Create instance: MIPI_D_PHY_RX_0, and set properties
set MIPI_D_PHY_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_D_PHY_RX:1.0 MIPI_D_PHY_RX_0 ]
# Create instance: jtag_axi_0, and set properties
set jtag_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:jtag_axi jtag_axi_0 ]
set_property -dict [list CONFIG.PROTOCOL {0}] [get_bd_cells jtag_axi_0]
connect_bd_net [get_bd_pins jtag_axi_0/aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins jtag_axi_0/aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_peri_interconnect, and set properties
set axi_peri_interconnect [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect axi_peri_interconnect ]
connect_bd_net [get_bd_pins axi_peri_interconnect/ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/ARESETN] [get_bd_pins sys_reset_0/interconnect_aresetn]
set_property -dict [ list CONFIG.NUM_SI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins jtag_axi_0/M_AXI] [get_bd_intf_pins axi_peri_interconnect/S00_AXI]
set_property -dict [ list CONFIG.NUM_MI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Connect all clock & reset of MIPI_D_PHY_RX_0 slave interfaces..
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M00_AXI] [get_bd_intf_pins MIPI_D_PHY_RX_0/S_AXI_LITE]
connect_bd_net [get_bd_pins MIPI_D_PHY_RX_0/s_axi_lite_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_D_PHY_RX_0/s_axi_lite_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Auto assign address
assign_bd_address
# Copy all address to MIPI_D_PHY_RX_v1_0_include.tcl file
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_D_PHY_RX_v1_0_include.tcl"
set fp [open $offset_file "w"]
puts $fp "# Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_D_PHY_RX_0_S_AXI_LITE_* ]]
puts $fp "set s_axi_lite_addr ${offset}"
close $fp
}
# Set IP Repository and Update IP Catalogue
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_D_PHY_RX:1.0]]]]
set hw_test_file ${ip_path}/example_designs/debug_hw_design/MIPI_D_PHY_RX_v1_0_hw_test.tcl
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_D_PHY_RX_v1_0_hw_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
set intf_address_include_file ""
create_ipi_design intf_address_include_file ${design_name}
save_bd_design
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
puts "-------------------------------------------------------------------------------------------------"
puts "INFO NEXT STEPS : Until this stage, debug hardware design has been created, "
puts " please perform following steps to test design in targeted board."
puts "1. Generate bitstream"
puts "2. Setup your targeted board, open hardware manager and open new(or existing) hardware target"
puts "3. Download generated bitstream"
puts "4. Run generated hardware test using below command, this invokes basic read/write operation"
puts " to every interface present in the peripheral : xilinx.com:user:myip:1.0"
puts " : source -notrace ${hw_test_file}"
puts "-------------------------------------------------------------------------------------------------"
proc create_ipi_design { offsetfile design_name } {
create_bd_design $design_name
open_bd_design $design_name
# Create and configure Clock/Reset
create_bd_cell -type ip -vlnv xilinx.com:ip:clk_wiz sys_clk_0
create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset sys_reset_0
#check if current_board is set, if true - figure out required clocks.
set is_board_clock_found 0
set is_board_reset_found 0
set external_reset_port ""
set external_clock_port ""
if { [current_board_part -quiet] != "" } {
#check if any reset interface exists in board.
set board_reset [lindex [get_board_part_interfaces -filter { BUSDEF_NAME == reset_rtl && MODE == slave }] 0 ]
if { $board_reset ne "" } {
set is_board_reset_found 1
apply_board_connection -board_interface $board_reset -ip_intf sys_clk_0/reset -diagram [current_bd_design]
apply_board_connection -board_interface $board_reset -ip_intf sys_reset_0/ext_reset -diagram [current_bd_design]
set external_rst [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/reset]]]
if { $external_rst ne "" } {
set external_reset_port [get_property NAME $external_rst]
}
} else {
send_msg "ptgen 51-200" WARNING "No reset interface found in current_board, Users may need to specify the location constraints manually."
}
# check for differential clock, exclude any special clocks which has TYPE property.
set board_clock_busifs ""
foreach busif [get_board_part_interfaces -filter "BUSDEF_NAME == diff_clock_rtl"] {
set type [get_property PARAM.TYPE $busif]
if { $type == "" } {
set board_clock_busifs $busif
break
}
}
if { $board_clock_busifs ne "" } {
apply_board_connection -board_interface $board_clock_busifs -ip_intf sys_clk_0/CLK_IN1_D -diagram [current_bd_design]
set is_board_clock_found 1
} else {
# check for single ended clock
set board_sclock_busifs [lindex [get_board_part_interfaces -filter "BUSDEF_NAME == clock_rtl"] 0 ]
if { $board_sclock_busifs ne "" } {
apply_board_connection -board_interface $board_sclock_busifs -ip_intf sys_clk_0/clock_CLK_IN1 -diagram [current_bd_design]
set external_clk [get_bd_ports -quiet -of_objects [get_bd_nets -quiet -of_objects [get_bd_pins -quiet sys_clk_0/clk_in1]]]
if { $external_clk ne "" } {
set external_clock_port [get_property NAME $external_clk]
}
set is_board_clock_found 1
} else {
send_msg "ptgen 51-200" WARNING "No clock interface found in current_board, Users may need to specify the location constraints manually."
}
}
} else {
send_msg "ptgen 51-201" WARNING "No board selected in current_project. Users may need to specify the location constraints manually."
}
#if there is no corresponding board interface found, assume constraints will be provided manually while pin planning.
if { $is_board_reset_found == 0 } {
create_bd_port -dir I -type rst reset_rtl
set_property CONFIG.POLARITY [get_property CONFIG.POLARITY [get_bd_pins sys_clk_0/reset]] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_pins sys_reset_0/ext_reset_in] [get_bd_ports reset_rtl]
connect_bd_net [get_bd_ports reset_rtl] [get_bd_pins sys_clk_0/reset]
set external_reset_port reset_rtl
}
if { $is_board_clock_found == 0 } {
create_bd_port -dir I -type clk clock_rtl
connect_bd_net [get_bd_pins sys_clk_0/clk_in1] [get_bd_ports clock_rtl]
set external_clock_port clock_rtl
}
#Avoid IPI DRC, make clock port synchronous to reset
if { $external_clock_port ne "" && $external_reset_port ne "" } {
set_property CONFIG.ASSOCIATED_RESET $external_reset_port [get_bd_ports $external_clock_port]
}
# Connect other sys_reset pins
connect_bd_net [get_bd_pins sys_reset_0/slowest_sync_clk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins sys_clk_0/locked] [get_bd_pins sys_reset_0/dcm_locked]
# Create instance: MIPI_D_PHY_RX_0, and set properties
set MIPI_D_PHY_RX_0 [ create_bd_cell -type ip -vlnv natinst.com:user:MIPI_D_PHY_RX:1.0 MIPI_D_PHY_RX_0 ]
# Create instance: jtag_axi_0, and set properties
set jtag_axi_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:jtag_axi jtag_axi_0 ]
set_property -dict [list CONFIG.PROTOCOL {0}] [get_bd_cells jtag_axi_0]
connect_bd_net [get_bd_pins jtag_axi_0/aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins jtag_axi_0/aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Create instance: axi_peri_interconnect, and set properties
set axi_peri_interconnect [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect axi_peri_interconnect ]
connect_bd_net [get_bd_pins axi_peri_interconnect/ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/ARESETN] [get_bd_pins sys_reset_0/interconnect_aresetn]
set_property -dict [ list CONFIG.NUM_SI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/S00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
connect_bd_intf_net [get_bd_intf_pins jtag_axi_0/M_AXI] [get_bd_intf_pins axi_peri_interconnect/S00_AXI]
set_property -dict [ list CONFIG.NUM_MI {1} ] $axi_peri_interconnect
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ACLK] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins axi_peri_interconnect/M00_ARESETN] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Connect all clock & reset of MIPI_D_PHY_RX_0 slave interfaces..
connect_bd_intf_net [get_bd_intf_pins axi_peri_interconnect/M00_AXI] [get_bd_intf_pins MIPI_D_PHY_RX_0/S_AXI_LITE]
connect_bd_net [get_bd_pins MIPI_D_PHY_RX_0/s_axi_lite_aclk] [get_bd_pins sys_clk_0/clk_out1]
connect_bd_net [get_bd_pins MIPI_D_PHY_RX_0/s_axi_lite_aresetn] [get_bd_pins sys_reset_0/peripheral_aresetn]
# Auto assign address
assign_bd_address
# Copy all address to MIPI_D_PHY_RX_v1_0_include.tcl file
set bd_path [get_property DIRECTORY [current_project]]/[current_project].srcs/[current_fileset]/bd
upvar 1 $offsetfile offset_file
set offset_file "${bd_path}/MIPI_D_PHY_RX_v1_0_include.tcl"
set fp [open $offset_file "w"]
puts $fp "# Configuration address parameters"
set offset [get_property OFFSET [get_bd_addr_segs /jtag_axi_0/Data/SEG_MIPI_D_PHY_RX_0_S_AXI_LITE_* ]]
puts $fp "set s_axi_lite_addr ${offset}"
close $fp
}
# Set IP Repository and Update IP Catalogue
set ip_path [file dirname [file normalize [get_property XML_FILE_NAME [ipx::get_cores natinst.com:user:MIPI_D_PHY_RX:1.0]]]]
set hw_test_file ${ip_path}/example_designs/debug_hw_design/MIPI_D_PHY_RX_v1_0_hw_test.tcl
set repo_paths [get_property ip_repo_paths [current_fileset]]
if { [lsearch -exact -nocase $repo_paths $ip_path ] == -1 } {
set_property ip_repo_paths "$ip_path [get_property ip_repo_paths [current_fileset]]" [current_fileset]
update_ip_catalog
}
set design_name ""
set all_bd {}
set all_bd_files [get_files *.bd -quiet]
foreach file $all_bd_files {
set file_name [string range $file [expr {[string last "/" $file] + 1}] end]
set bd_name [string range $file_name 0 [expr {[string last "." $file_name] -1}]]
lappend all_bd $bd_name
}
for { set i 1 } { 1 } { incr i } {
set design_name "MIPI_D_PHY_RX_v1_0_hw_${i}"
if { [lsearch -exact -nocase $all_bd $design_name ] == -1 } {
break
}
}
set intf_address_include_file ""
create_ipi_design intf_address_include_file ${design_name}
save_bd_design
validate_bd_design
set wrapper_file [make_wrapper -files [get_files ${design_name}.bd] -top -force]
import_files -force -norecurse $wrapper_file
puts "-------------------------------------------------------------------------------------------------"
puts "INFO NEXT STEPS : Until this stage, debug hardware design has been created, "
puts " please perform following steps to test design in targeted board."
puts "1. Generate bitstream"
puts "2. Setup your targeted board, open hardware manager and open new(or existing) hardware target"
puts "3. Download generated bitstream"
puts "4. Run generated hardware test using below command, this invokes basic read/write operation"
puts " to every interface present in the peripheral : xilinx.com:user:myip:1.0"
puts " : source -notrace ${hw_test_file}"
puts "-------------------------------------------------------------------------------------------------"
@@ -1,300 +1,300 @@
-------------------------------------------------------------------------------
--
-- File: DPHY_LaneSCNN.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module implements a MIPI D-PHY 1.0 CIL-SCNN lane: slave (receiver) clock.
-- It is architecture-independent by itself, but the instantiated HS-Clocking has
-- its own requirements. The D-PHY physical interface is assumed to be de-multiplexed
-- into low-power LP(1:0) and high-speed HS inputs by external circuitry (outside
-- the FPGA). On the logic side data is forwarded via the PPI interface as
-- described in the D-PHY spec Annex A.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
use work.DebugLib.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DPHY_LaneSCNN is
Generic (
kGenerateMMCM : boolean := false;
kRefClkFreqHz : natural := 200_000_000;
kAddDelay_ps : integer := 0
);
Port (
aLP : in STD_LOGIC_VECTOR (1 downto 0);
aHS : in STD_LOGIC;
RefClk : in STD_LOGIC; --200MHz
RxDDRClkHS : out STD_LOGIC;
RxByteClkHS : out STD_LOGIC;
aRxClkActiveHS : out STD_LOGIC;
aForceRxmode : in STD_LOGIC;
aStopstate : out STD_LOGIC;
aEnable : in STD_LOGIC;
aRxUlpsClkNot : out std_logic; --Receive Ultra-Low Power State on Clock Lane.
aUlpsActiveNot : out std_logic; --ULP State (not) Active.
debug : out DebugSCNN_Type
);
end DPHY_LaneSCNN;
architecture Behavioral of DPHY_LaneSCNN is
function MAX(LEFT, RIGHT: INTEGER) return INTEGER is
begin
if LEFT > RIGHT then return LEFT;
else return RIGHT;
end if;
end;
type state_type is (stInit, stStop, stHS_Prpr, stHS_Term, stHS_Clk, stHS_End, stULPS, stULPS_Exit, stULPS_Rqst);
signal state, nstate : state_type := stInit;
attribute fsm_encoding : string;
attribute fsm_encoding of state : signal is "one_hot";
signal cLP, cLPGlitch : std_logic_vector(1 downto 0);
signal cIntRst : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of cLP: signal is "TRUE";
alias CtlClk : std_logic is RefClk;
alias kCtlClkFreqHz : natural is kRefClkFreqHz;
constant kTInit : natural := natural(ceil(100.0 / 10.0**6 * real(kCtlClkFreqHz))); --100us
constant kTClkTermEn : natural := natural(ceil(38.0 / 10.0**9 * real(kCtlClkFreqHz))); --38ns
constant kTClkSettle : natural := natural(ceil(95.0 / 10.0**9 * real(kCtlClkFreqHz))); --95ns min
constant kTMinRx : natural := natural(ceil(20.0 / 10.0**9 * real(kCtlClkFreqHz))); --20ns
signal cClkSettleTout : std_logic;
signal cDelayCnt : natural range 0 to MAX(kTInit,MAX(kTClkTermEn, kTClkSettle)) := 0;
signal aClkLocked, cClkLocked, cHSRst, cDelayCntEn, aHSClkLocked, cHSClkLocked, cHSClkLocked_q, cHSClkLost : std_logic;
signal cEnable : std_logic;
begin
debug.cIntRst <= cIntRst;
debug.cLP <= cLP;
debug.cHSRst <= cHSRst;
debug.cHSClkLocked <= cHSClkLocked;
debug.state <= std_logic_vector(to_unsigned(state_type'pos(state), 4));
debug.cClkSettleTout <= cClkSettleTout;
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aEnable,
OutClk => CtlClk,
oOut => cEnable);
cIntRst <= not cEnable;
aStopstate <= '1' when state = stStop else
'0';
aRxUlpsClkNot <= '0' when state = stULPS or state = stULPS_Exit else
'1';
aUlpsActiveNot <= '0' when state = stULPS else
'1';
aRxClkActiveHS <= aHSClkLocked;
-------------------------------------------------------------------------------
-- Synchronize LP signals into the CtlClk domain, then filter glitches
-------------------------------------------------------------------------------
GenSyncLP: for i in 0 to 1 generate
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aLP(i),
OutClk => CtlClk,
oOut => cLPGlitch(i));
--TODO: LP 0 not in sync with LP 1; OK? because on HS-entry LPs don't change
-- simultaneously, only on HS-exit, where they both rise to 1 together.
-- On HS-exit only the "11" condition is used, so this skew at most delays exit.
GlitchFilterLP: entity work.GlitchFilter
generic map (
kNoOfPeriodsToFilter => kTMinRx)
port map (
SampleClk => CtlClk,
sIn => cLPGlitch(i),
sOut => cLP(i),
sRst => cIntRst);
end generate GenSyncLP;
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
elsif (cDelayCntEn = '1') then
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cClkSettleTout <= '1' when cDelayCnt = kTClkSettle-1
else '0';
--Outputs
cDelayCntEn <= '1' when state = stHS_Term else
'0';
ModeFSM_SyncProc: process (CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cIntRst = '1') then
state <= stInit;
else
state <= nstate;
end if;
end if;
end process;
cHSRst <= '0' when state = stHS_Clk and cIntRst = '0' else
'1';
ModeFSM_NextStateProc: process (state, cLP, cClkSettleTout, cClkLocked, cHSClkLost)
begin
nstate <= state;
case (state) is
when stInit =>
if cLP = "11" then
nstate <= stStop;
end if;
when stStop =>
if cLP = "01" then -- HS-Rqst
nstate <= stHS_Prpr;
elsif cLP = "10" then -- ULPS-Rqst
nstate <= stULPS_Rqst;
end if;
when stULPS_Rqst =>
if (cLP = "11" or cLP = "01") then
nstate <= stStop;
elsif (cLP = "00") then
nstate <= stULPS;
end if;
when stULPS =>
if (cLP = "10") then
nstate <= stULPS_Exit;
end if;
when stULPS_Exit =>
if (cLP = "11") then
nstate <= stStop;
end if;
when stHS_Prpr =>
if (cLP = "11") then
nstate <= stStop;
elsif cLP = "00" then -- Bridge
nstate <= stHS_Term;
end if;
when stHS_Term =>
if (cLP = "11") then
nstate <= stStop;
elsif (cLP = "00" and cClkSettleTout = '1') then -- Bridge
nstate <= stHS_Clk;
end if;
when stHS_Clk =>
if (cHSClkLost = '1') then --Clock lost
nstate <= stHS_End;
elsif (cLP = "11") then -- Stop, we might not have seen the loss of clock
nstate <= stStop;
end if;
when stHS_End =>
if (cLP = "11") then -- Stop
nstate <= stStop;
end if;
end case;
end process;
HSClockingX: entity work.HS_Clocking
Generic map (
kGenerateMMCM => kGenerateMMCM,
kCtlClkFreqHz => kCtlClkFreqHz,
kRefClkFreqHz => kRefClkFreqHz,
kAddDelay_ps => kAddDelay_ps
)
Port map (
HS_Clock => aHS,
HS_SerClk => RxDDRClkHS,
HS_Div4Clk => RxByteClkHS,
CtlClk => CtlClk,
cRst => cHSRst,
aLocked => aHSClkLocked,
dbg_cBUFR_Rst => debug.cBUFR_Rst,
dbg_cMMCM_Rst => debug.cMMCM_Rst,
dbg_cMMCM_RstTout => debug.cMMCM_RstTout,
dbg_cMMCM_Locked => debug.cMMCM_Locked
);
SyncAsyncLocked: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cHSRst,
aIn => aHSClkLocked,
OutClk => CtlClk,
oOut => cHSClkLocked);
process(CtlClk)
begin
if Rising_Edge(CtlClk) then
cHSClkLocked_q <= cHSClkLocked;
end if;
end process;
cHSClkLost <= cHSClkLocked_q and not cHSClkLocked;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: DPHY_LaneSCNN.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module implements a MIPI D-PHY 1.0 CIL-SCNN lane: slave (receiver) clock.
-- It is architecture-independent by itself, but the instantiated HS-Clocking has
-- its own requirements. The D-PHY physical interface is assumed to be de-multiplexed
-- into low-power LP(1:0) and high-speed HS inputs by external circuitry (outside
-- the FPGA). On the logic side data is forwarded via the PPI interface as
-- described in the D-PHY spec Annex A.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
use work.DebugLib.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DPHY_LaneSCNN is
Generic (
kGenerateMMCM : boolean := false;
kRefClkFreqHz : natural := 200_000_000;
kAddDelay_ps : integer := 0
);
Port (
aLP : in STD_LOGIC_VECTOR (1 downto 0);
aHS : in STD_LOGIC;
RefClk : in STD_LOGIC; --200MHz
RxDDRClkHS : out STD_LOGIC;
RxByteClkHS : out STD_LOGIC;
aRxClkActiveHS : out STD_LOGIC;
aForceRxmode : in STD_LOGIC;
aStopstate : out STD_LOGIC;
aEnable : in STD_LOGIC;
aRxUlpsClkNot : out std_logic; --Receive Ultra-Low Power State on Clock Lane.
aUlpsActiveNot : out std_logic; --ULP State (not) Active.
debug : out DebugSCNN_Type
);
end DPHY_LaneSCNN;
architecture Behavioral of DPHY_LaneSCNN is
function MAX(LEFT, RIGHT: INTEGER) return INTEGER is
begin
if LEFT > RIGHT then return LEFT;
else return RIGHT;
end if;
end;
type state_type is (stInit, stStop, stHS_Prpr, stHS_Term, stHS_Clk, stHS_End, stULPS, stULPS_Exit, stULPS_Rqst);
signal state, nstate : state_type := stInit;
attribute fsm_encoding : string;
attribute fsm_encoding of state : signal is "one_hot";
signal cLP, cLPGlitch : std_logic_vector(1 downto 0);
signal cIntRst : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of cLP: signal is "TRUE";
alias CtlClk : std_logic is RefClk;
alias kCtlClkFreqHz : natural is kRefClkFreqHz;
constant kTInit : natural := natural(ceil(100.0 / 10.0**6 * real(kCtlClkFreqHz))); --100us
constant kTClkTermEn : natural := natural(ceil(38.0 / 10.0**9 * real(kCtlClkFreqHz))); --38ns
constant kTClkSettle : natural := natural(ceil(95.0 / 10.0**9 * real(kCtlClkFreqHz))); --95ns min
constant kTMinRx : natural := natural(ceil(20.0 / 10.0**9 * real(kCtlClkFreqHz))); --20ns
signal cClkSettleTout : std_logic;
signal cDelayCnt : natural range 0 to MAX(kTInit,MAX(kTClkTermEn, kTClkSettle)) := 0;
signal aClkLocked, cClkLocked, cHSRst, cDelayCntEn, aHSClkLocked, cHSClkLocked, cHSClkLocked_q, cHSClkLost : std_logic;
signal cEnable : std_logic;
begin
debug.cIntRst <= cIntRst;
debug.cLP <= cLP;
debug.cHSRst <= cHSRst;
debug.cHSClkLocked <= cHSClkLocked;
debug.state <= std_logic_vector(to_unsigned(state_type'pos(state), 4));
debug.cClkSettleTout <= cClkSettleTout;
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aEnable,
OutClk => CtlClk,
oOut => cEnable);
cIntRst <= not cEnable;
aStopstate <= '1' when state = stStop else
'0';
aRxUlpsClkNot <= '0' when state = stULPS or state = stULPS_Exit else
'1';
aUlpsActiveNot <= '0' when state = stULPS else
'1';
aRxClkActiveHS <= aHSClkLocked;
-------------------------------------------------------------------------------
-- Synchronize LP signals into the CtlClk domain, then filter glitches
-------------------------------------------------------------------------------
GenSyncLP: for i in 0 to 1 generate
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aLP(i),
OutClk => CtlClk,
oOut => cLPGlitch(i));
--TODO: LP 0 not in sync with LP 1; OK? because on HS-entry LPs don't change
-- simultaneously, only on HS-exit, where they both rise to 1 together.
-- On HS-exit only the "11" condition is used, so this skew at most delays exit.
GlitchFilterLP: entity work.GlitchFilter
generic map (
kNoOfPeriodsToFilter => kTMinRx)
port map (
SampleClk => CtlClk,
sIn => cLPGlitch(i),
sOut => cLP(i),
sRst => cIntRst);
end generate GenSyncLP;
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
elsif (cDelayCntEn = '1') then
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cClkSettleTout <= '1' when cDelayCnt = kTClkSettle-1
else '0';
--Outputs
cDelayCntEn <= '1' when state = stHS_Term else
'0';
ModeFSM_SyncProc: process (CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cIntRst = '1') then
state <= stInit;
else
state <= nstate;
end if;
end if;
end process;
cHSRst <= '0' when state = stHS_Clk and cIntRst = '0' else
'1';
ModeFSM_NextStateProc: process (state, cLP, cClkSettleTout, cClkLocked, cHSClkLost)
begin
nstate <= state;
case (state) is
when stInit =>
if cLP = "11" then
nstate <= stStop;
end if;
when stStop =>
if cLP = "01" then -- HS-Rqst
nstate <= stHS_Prpr;
elsif cLP = "10" then -- ULPS-Rqst
nstate <= stULPS_Rqst;
end if;
when stULPS_Rqst =>
if (cLP = "11" or cLP = "01") then
nstate <= stStop;
elsif (cLP = "00") then
nstate <= stULPS;
end if;
when stULPS =>
if (cLP = "10") then
nstate <= stULPS_Exit;
end if;
when stULPS_Exit =>
if (cLP = "11") then
nstate <= stStop;
end if;
when stHS_Prpr =>
if (cLP = "11") then
nstate <= stStop;
elsif cLP = "00" then -- Bridge
nstate <= stHS_Term;
end if;
when stHS_Term =>
if (cLP = "11") then
nstate <= stStop;
elsif (cLP = "00" and cClkSettleTout = '1') then -- Bridge
nstate <= stHS_Clk;
end if;
when stHS_Clk =>
if (cHSClkLost = '1') then --Clock lost
nstate <= stHS_End;
elsif (cLP = "11") then -- Stop, we might not have seen the loss of clock
nstate <= stStop;
end if;
when stHS_End =>
if (cLP = "11") then -- Stop
nstate <= stStop;
end if;
end case;
end process;
HSClockingX: entity work.HS_Clocking
Generic map (
kGenerateMMCM => kGenerateMMCM,
kCtlClkFreqHz => kCtlClkFreqHz,
kRefClkFreqHz => kRefClkFreqHz,
kAddDelay_ps => kAddDelay_ps
)
Port map (
HS_Clock => aHS,
HS_SerClk => RxDDRClkHS,
HS_Div4Clk => RxByteClkHS,
CtlClk => CtlClk,
cRst => cHSRst,
aLocked => aHSClkLocked,
dbg_cBUFR_Rst => debug.cBUFR_Rst,
dbg_cMMCM_Rst => debug.cMMCM_Rst,
dbg_cMMCM_RstTout => debug.cMMCM_RstTout,
dbg_cMMCM_Locked => debug.cMMCM_Locked
);
SyncAsyncLocked: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cHSRst,
aIn => aHSClkLocked,
OutClk => CtlClk,
oOut => cHSClkLocked);
process(CtlClk)
begin
if Rising_Edge(CtlClk) then
cHSClkLocked_q <= cHSClkLocked;
end if;
end process;
cHSClkLost <= cHSClkLocked_q and not cHSClkLocked;
end Behavioral;
@@ -1,386 +1,386 @@
-------------------------------------------------------------------------------
--
-- File: DPHY_LaneSFEN.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module implements a MIPI D-PHY 1.0 CIL-SFEN lane: slave (receiver),
-- forward high-speed, events forward escape mode (future work), no reverse
-- direction. It is architecture-independent by itself, but the instantiated
-- HS-Deserializer has its own requirements. The D-PHY physical interface is
-- assumed to be de-multiplexed into low-power LP(1:0) and high-speed HS inputs
-- by external circuitry (outside the FPGA). On the logic side data is forwarded
-- via the PPI interface as described in the D-PHY spec Annex A.
-- This data lane module requires high-speed serial and divided parallel clocks
-- as provided by the accompanying SCNN clock lane module.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
use work.DebugLib.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DPHY_LaneSFEN is
Generic (
kRefClkFreqHz : natural := 200_000_000;
kAddDelay_ps : integer := 0;
kNoLP : boolean := false
);
Port (
dLP0_in : in std_logic_vector(7 downto 0);
dLP1_in : in std_logic_vector(7 downto 0);
dLP0_out : out std_logic_vector(7 downto 0);
dLP1_out : out std_logic_vector(7 downto 0);
cLP_in : in STD_LOGIC_VECTOR (1 downto 0);
cLP_out : out STD_LOGIC_VECTOR (1 downto 0);
aLP : in STD_LOGIC_VECTOR (1 downto 0);
aHS : in STD_LOGIC;
RefClk : in STD_LOGIC;
SerClkHS : in STD_LOGIC;
DivClk : in STD_LOGIC;
aRxClkActiveHS : in STD_LOGIC;
--PPI
RxByteClkHS : out std_logic;
rbRxDataHS : out std_logic_vector(7 downto 0);
rbRxValidHS : out std_logic;
rbRxActiveHS : out std_logic;
rbRxSyncHS : out std_logic;
rbErrSotHS : out std_logic;
rbErrSotSyncHS : out std_logic;
aEnable : in std_logic; --Enable Lane Module. DivClk&SerClkHS must be stable
aForceRxmode : in std_logic; --Force Lane Module Into Receive mode / Wait for Stop state
aStopstate : out std_logic; --Lane is in Stop state.
aErrEsc : out std_logic; --Escape Entry Error.
aErrControl : out std_logic; --Control Error.
debug : out DebugSFEN_Type
-- dbg_cIntRst : out std_logic;
-- dbg_cLP : out std_logic_vector(1 downto 0);
-- dbg_state : out std_logic_vector(2 downto 0);
-- dbg_cHSClkRst : out std_logic;
-- dbg_cForceRxmode : out std_logic;
-- dbg_cInitTout : out std_logic;
-- dbg_cHSSettleTout : out std_logic;
-- dbg_cHSSettled : out std_logic;
-- dbg_cHSReset : out std_logic;
-- dbg_dSyncHard : out std_logic;
-- dbg_dSyncSoft : out std_logic;
-- dbg_dSyncErr : out std_logic
);
end DPHY_LaneSFEN;
architecture Behavioral of DPHY_LaneSFEN is
function MAX(LEFT, RIGHT: INTEGER) return INTEGER is
begin
if LEFT > RIGHT then return LEFT;
else return RIGHT;
end if;
end;
type state_type is (stInitCountDown, stWaitForStop, stStop, stHS_Rqst, stHS_Settle, stHS_Rcv);
signal state, nstate : state_type := stInitCountDown;
alias CtlClk : std_logic is RefClk;
alias kCtlClkFreqHz : natural is kRefClkFreqHz;
signal aLP_int, cLP, cLPGlitch: std_logic_vector(1 downto 0);
constant kTInit : natural := natural(ceil(100.0 * real(kCtlClkFreqHz) / 1_000_000.0)); --100us
constant kTHSSettle : natural := natural(ceil(85.0 * real(kCtlClkFreqHz) / 1_000_000_000.0)); --85ns
constant kTMinRx : natural := natural(ceil(20.0 * real(kCtlClkFreqHz) / 1_000_000_000.0)); --20ns
constant kOffset : natural := 3 + 1 ; -- adjust timeout values above to account for late start due to CtlClk sync
signal cDelayCnt : natural range 0 to MAX(kTInit,kTHSSettle) := 0;
signal cHS_Trail, cHSReset, dDelayCntEn, cDelayCntEn : std_logic;
signal dSyncHard, dSyncSoft, dSyncErr, dIntRst, dHSReset, dStopstate, dValid : std_logic;
signal cEnable, cIntRst, cHSClkRst, cForceRxmode, cInitDone, cHSSettled, cValid : std_logic;
signal cInitTout, cHSSettleTout: std_logic; --CtlClk timeout flags
signal dSyncHard_reg, dSyncSoft_reg, dSyncErr_reg, dInitDone : std_logic; -- for pulse generation
signal dDataOut : std_logic_vector(7 downto 0);
signal aNotEnable, aNotRxClkActiveHS : std_logic;
begin
debug.cIntRst <= cIntRst;
debug.cHSClkRst <= cHSClkRst;
debug.cLP <= cLP;
debug.state <= std_logic_vector(to_unsigned(state_type'pos(state), 3));
debug.cForceRxmode <= cForceRxmode;
debug.cInitTout <= cInitTout;
debug.cHSSettleTout <= cHSSettleTout;
debug.cHSSettled <= cHSSettled;
debug.cHSReset <= cHSReset;
debug.dSyncHard <= dSyncHard;
debug.dSyncSoft <= dSyncSoft;
debug.dSyncErr <= dSyncErr;
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aEnable,
OutClk => CtlClk,
oOut => cEnable);
cIntRst <= not cEnable;
aNotRxClkActiveHS <= not aRxClkActiveHS;
RxClkActiveHSResetBridge: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aNotRxClkActiveHS,
OutClk => CtlClk,
oRst => cHSClkRst);
SyncAsyncForceRxMode: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cIntRst,
aIn => aForceRxmode,
OutClk => CtlClk,
oOut => cForceRxmode);
UseOwnLP: if not kNoLP generate
-- Sync LP with CtlClk
-- T_LPX_min = 50ns = 4*UI_max
-- Synchronizing the LP bits separately is OK, because entering HS is done by
-- LP-11, LP-01, LP-00 sequences, so only one bit changes from one LPX period
-- to another.
-- At the end of HS, LP-00 goes to LP-11, but this is the only valid transition. So
-- spurious LP-01 or LP-10 between them can be ignored, until it stabilizes in LP-11.
GenSyncLP: for i in 0 to 1 generate
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aLP_int(i),
OutClk => CtlClk,
oOut => cLPGlitch(i));
GlitchFilterLPC: entity work.GlitchFilter
generic map (
kNoOfPeriodsToFilter => kTMinRx)
port map (
SampleClk => CtlClk,
sIn => cLPGlitch(i),
sOut => cLP(i),
sRst => '0');
end generate GenSyncLP;
end generate UseOwnLP;
cLP_out <= cLP;
ShareLPFromOtherLane: if kNoLP generate
cLP <= cLP_in;
end generate ShareLPFromOtherLane;
-- Time delay counter running on CtlClk, because it has a known, fixed frequency
-- We use it to keep track of timing parameters in time units rather than UIs.
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
else
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cInitTout <= '1' when cDelayCnt = kTInit else '0';
cHSSettleTout <= '1' when cDelayCnt = kTHSSettle-1 else '0';
--Outputs
cDelayCntEn <= '1' when state = stInitCountDown or nstate = stHS_Settle else
'0';
ModeFSM_SyncProc: process (CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cIntRst = '1') then
state <= stInitCountDown;
else
state <= nstate;
end if;
end if;
end process;
process(CtlClk, cHSClkRst)
begin
if (cHSClkRst = '1') then
cHSReset <= '1';
elsif Rising_Edge(CtlClk) then
if nstate = stHS_Settle then
cHSReset <= '0';
elsif state = stStop and cValid = '0' then
cHSReset <= '1';
end if;
end if;
end process;
process(CtlClk, cHSClkRst)
begin
if (cHSClkRst = '1') then
cHSSettled <= '0';
elsif Rising_Edge(CtlClk) then
if state = stHS_Settle and cHSSettleTout = '1' then
cHSSettled <= '1';
elsif state = stStop and cValid = '0' then
cHSSettled <= '0';
end if;
end if;
end process;
ModeFSM_NextStateProc: process (state, cLP, cInitTout, cForceRxmode, cHSSettleTout)
begin
nstate <= state;
case (state) is
when stInitCountDown =>
if cInitTout = '1' or cForceRxmode = '1' then
nstate <= stWaitForStop;
end if;
when stWaitForStop =>
if cLP = "11" then
nstate <= stStop;
end if;
when stStop =>
if cLP = "01" then -- HS-Rqst
nstate <= stHS_Rqst;
end if;
when stHS_Rqst =>
if cLP = "11" then
nstate <= stStop;
elsif cLP = "00" then
nstate <= stHS_Settle;
end if;
when stHS_Settle =>
if cLP = "11" then
nstate <= stStop;
elsif (cHSSettleTout = '1') then
nstate <= stHS_Rcv;
end if;
when stHS_Rcv =>
if cLP = "11" then
nstate <= stStop;
end if;
when others =>
null;
end case;
end process;
-----------------------------------------------------------------
-- PPI
-----------------------------------------------------------------
aStopstate <= '1' when state = stStop else '0';
RxByteClkHS <= DivClk;
--PPI requires least-significant bit to be the first one received
MakeLSF: for i in rbRxDataHS'range generate
rbRxDataHS(i) <= dDataOut(rbRxDataHS'length-1-i);
end generate MakeLSF;
rbRxValidHS <= dValid;
rbRxActiveHS <= dSyncHard or dSyncSoft;
rbRxSyncHS <= (dSyncHard and not dSyncHard_reg) or (dSyncSoft and not dSyncSoft_reg);
rbErrSotSyncHS <= (dSyncSoft and not dSyncSoft_reg);
rbErrSotHS <= dSyncErr and not dSyncErr_reg;
GenSyncPulse: process(DivClk)
begin
if Rising_Edge(DivClk) then
dSyncHard_reg <= dSyncHard;
dSyncSoft_reg <= dSyncSoft;
dSyncErr_reg <= dSyncErr;
end if;
end process;
HSDeserializerX: entity work.HS_Deserializer
Generic map (
kIs8b9b => false,
kAddDelay_ps => kAddDelay_ps,
kNoLP => kNoLP
)
Port map (
dLP0_in => dLP0_in,
dLP1_in => dLP1_in,
dLP0_out => dLP0_out,
dLP1_out => dLP1_out,
SerClk => SerClkHS,
DivClk => DivClk,
aHSIn => aHS,
aLPIn => aLP,
aLPOut => aLP_int,
dDataOut8 => dDataOut,
dValid => dValid,
dSyncHard => dSyncHard,
dSyncSoft => dSyncSoft,
dSyncErr => dSyncErr,
CtlClk => CtlClk,
cIDLY_LD => '0', --IDELAYE2 Load
cIDLY_CE => '0', --IDELAYE2 CE
cIDLY_INC => '0', --IDELAYE2 Tap Increment
cIDLY_CNT => open, --IDELAYE2 Current Tap Count
aRst => cHSReset,
aSettled => cHSSettled
);
SyncAsyncValid: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cHSClkRst,
aIn => dValid,
OutClk => CtlClk,
oOut => cValid);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: DPHY_LaneSFEN.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module implements a MIPI D-PHY 1.0 CIL-SFEN lane: slave (receiver),
-- forward high-speed, events forward escape mode (future work), no reverse
-- direction. It is architecture-independent by itself, but the instantiated
-- HS-Deserializer has its own requirements. The D-PHY physical interface is
-- assumed to be de-multiplexed into low-power LP(1:0) and high-speed HS inputs
-- by external circuitry (outside the FPGA). On the logic side data is forwarded
-- via the PPI interface as described in the D-PHY spec Annex A.
-- This data lane module requires high-speed serial and divided parallel clocks
-- as provided by the accompanying SCNN clock lane module.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
use work.DebugLib.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DPHY_LaneSFEN is
Generic (
kRefClkFreqHz : natural := 200_000_000;
kAddDelay_ps : integer := 0;
kNoLP : boolean := false
);
Port (
dLP0_in : in std_logic_vector(7 downto 0);
dLP1_in : in std_logic_vector(7 downto 0);
dLP0_out : out std_logic_vector(7 downto 0);
dLP1_out : out std_logic_vector(7 downto 0);
cLP_in : in STD_LOGIC_VECTOR (1 downto 0);
cLP_out : out STD_LOGIC_VECTOR (1 downto 0);
aLP : in STD_LOGIC_VECTOR (1 downto 0);
aHS : in STD_LOGIC;
RefClk : in STD_LOGIC;
SerClkHS : in STD_LOGIC;
DivClk : in STD_LOGIC;
aRxClkActiveHS : in STD_LOGIC;
--PPI
RxByteClkHS : out std_logic;
rbRxDataHS : out std_logic_vector(7 downto 0);
rbRxValidHS : out std_logic;
rbRxActiveHS : out std_logic;
rbRxSyncHS : out std_logic;
rbErrSotHS : out std_logic;
rbErrSotSyncHS : out std_logic;
aEnable : in std_logic; --Enable Lane Module. DivClk&SerClkHS must be stable
aForceRxmode : in std_logic; --Force Lane Module Into Receive mode / Wait for Stop state
aStopstate : out std_logic; --Lane is in Stop state.
aErrEsc : out std_logic; --Escape Entry Error.
aErrControl : out std_logic; --Control Error.
debug : out DebugSFEN_Type
-- dbg_cIntRst : out std_logic;
-- dbg_cLP : out std_logic_vector(1 downto 0);
-- dbg_state : out std_logic_vector(2 downto 0);
-- dbg_cHSClkRst : out std_logic;
-- dbg_cForceRxmode : out std_logic;
-- dbg_cInitTout : out std_logic;
-- dbg_cHSSettleTout : out std_logic;
-- dbg_cHSSettled : out std_logic;
-- dbg_cHSReset : out std_logic;
-- dbg_dSyncHard : out std_logic;
-- dbg_dSyncSoft : out std_logic;
-- dbg_dSyncErr : out std_logic
);
end DPHY_LaneSFEN;
architecture Behavioral of DPHY_LaneSFEN is
function MAX(LEFT, RIGHT: INTEGER) return INTEGER is
begin
if LEFT > RIGHT then return LEFT;
else return RIGHT;
end if;
end;
type state_type is (stInitCountDown, stWaitForStop, stStop, stHS_Rqst, stHS_Settle, stHS_Rcv);
signal state, nstate : state_type := stInitCountDown;
alias CtlClk : std_logic is RefClk;
alias kCtlClkFreqHz : natural is kRefClkFreqHz;
signal aLP_int, cLP, cLPGlitch: std_logic_vector(1 downto 0);
constant kTInit : natural := natural(ceil(100.0 * real(kCtlClkFreqHz) / 1_000_000.0)); --100us
constant kTHSSettle : natural := natural(ceil(85.0 * real(kCtlClkFreqHz) / 1_000_000_000.0)); --85ns
constant kTMinRx : natural := natural(ceil(20.0 * real(kCtlClkFreqHz) / 1_000_000_000.0)); --20ns
constant kOffset : natural := 3 + 1 ; -- adjust timeout values above to account for late start due to CtlClk sync
signal cDelayCnt : natural range 0 to MAX(kTInit,kTHSSettle) := 0;
signal cHS_Trail, cHSReset, dDelayCntEn, cDelayCntEn : std_logic;
signal dSyncHard, dSyncSoft, dSyncErr, dIntRst, dHSReset, dStopstate, dValid : std_logic;
signal cEnable, cIntRst, cHSClkRst, cForceRxmode, cInitDone, cHSSettled, cValid : std_logic;
signal cInitTout, cHSSettleTout: std_logic; --CtlClk timeout flags
signal dSyncHard_reg, dSyncSoft_reg, dSyncErr_reg, dInitDone : std_logic; -- for pulse generation
signal dDataOut : std_logic_vector(7 downto 0);
signal aNotEnable, aNotRxClkActiveHS : std_logic;
begin
debug.cIntRst <= cIntRst;
debug.cHSClkRst <= cHSClkRst;
debug.cLP <= cLP;
debug.state <= std_logic_vector(to_unsigned(state_type'pos(state), 3));
debug.cForceRxmode <= cForceRxmode;
debug.cInitTout <= cInitTout;
debug.cHSSettleTout <= cHSSettleTout;
debug.cHSSettled <= cHSSettled;
debug.cHSReset <= cHSReset;
debug.dSyncHard <= dSyncHard;
debug.dSyncSoft <= dSyncSoft;
debug.dSyncErr <= dSyncErr;
SyncAsyncEnable: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aEnable,
OutClk => CtlClk,
oOut => cEnable);
cIntRst <= not cEnable;
aNotRxClkActiveHS <= not aRxClkActiveHS;
RxClkActiveHSResetBridge: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aNotRxClkActiveHS,
OutClk => CtlClk,
oRst => cHSClkRst);
SyncAsyncForceRxMode: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cIntRst,
aIn => aForceRxmode,
OutClk => CtlClk,
oOut => cForceRxmode);
UseOwnLP: if not kNoLP generate
-- Sync LP with CtlClk
-- T_LPX_min = 50ns = 4*UI_max
-- Synchronizing the LP bits separately is OK, because entering HS is done by
-- LP-11, LP-01, LP-00 sequences, so only one bit changes from one LPX period
-- to another.
-- At the end of HS, LP-00 goes to LP-11, but this is the only valid transition. So
-- spurious LP-01 or LP-10 between them can be ignored, until it stabilizes in LP-11.
GenSyncLP: for i in 0 to 1 generate
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => '0',
aIn => aLP_int(i),
OutClk => CtlClk,
oOut => cLPGlitch(i));
GlitchFilterLPC: entity work.GlitchFilter
generic map (
kNoOfPeriodsToFilter => kTMinRx)
port map (
SampleClk => CtlClk,
sIn => cLPGlitch(i),
sOut => cLP(i),
sRst => '0');
end generate GenSyncLP;
end generate UseOwnLP;
cLP_out <= cLP;
ShareLPFromOtherLane: if kNoLP generate
cLP <= cLP_in;
end generate ShareLPFromOtherLane;
-- Time delay counter running on CtlClk, because it has a known, fixed frequency
-- We use it to keep track of timing parameters in time units rather than UIs.
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
else
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cInitTout <= '1' when cDelayCnt = kTInit else '0';
cHSSettleTout <= '1' when cDelayCnt = kTHSSettle-1 else '0';
--Outputs
cDelayCntEn <= '1' when state = stInitCountDown or nstate = stHS_Settle else
'0';
ModeFSM_SyncProc: process (CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cIntRst = '1') then
state <= stInitCountDown;
else
state <= nstate;
end if;
end if;
end process;
process(CtlClk, cHSClkRst)
begin
if (cHSClkRst = '1') then
cHSReset <= '1';
elsif Rising_Edge(CtlClk) then
if nstate = stHS_Settle then
cHSReset <= '0';
elsif state = stStop and cValid = '0' then
cHSReset <= '1';
end if;
end if;
end process;
process(CtlClk, cHSClkRst)
begin
if (cHSClkRst = '1') then
cHSSettled <= '0';
elsif Rising_Edge(CtlClk) then
if state = stHS_Settle and cHSSettleTout = '1' then
cHSSettled <= '1';
elsif state = stStop and cValid = '0' then
cHSSettled <= '0';
end if;
end if;
end process;
ModeFSM_NextStateProc: process (state, cLP, cInitTout, cForceRxmode, cHSSettleTout)
begin
nstate <= state;
case (state) is
when stInitCountDown =>
if cInitTout = '1' or cForceRxmode = '1' then
nstate <= stWaitForStop;
end if;
when stWaitForStop =>
if cLP = "11" then
nstate <= stStop;
end if;
when stStop =>
if cLP = "01" then -- HS-Rqst
nstate <= stHS_Rqst;
end if;
when stHS_Rqst =>
if cLP = "11" then
nstate <= stStop;
elsif cLP = "00" then
nstate <= stHS_Settle;
end if;
when stHS_Settle =>
if cLP = "11" then
nstate <= stStop;
elsif (cHSSettleTout = '1') then
nstate <= stHS_Rcv;
end if;
when stHS_Rcv =>
if cLP = "11" then
nstate <= stStop;
end if;
when others =>
null;
end case;
end process;
-----------------------------------------------------------------
-- PPI
-----------------------------------------------------------------
aStopstate <= '1' when state = stStop else '0';
RxByteClkHS <= DivClk;
--PPI requires least-significant bit to be the first one received
MakeLSF: for i in rbRxDataHS'range generate
rbRxDataHS(i) <= dDataOut(rbRxDataHS'length-1-i);
end generate MakeLSF;
rbRxValidHS <= dValid;
rbRxActiveHS <= dSyncHard or dSyncSoft;
rbRxSyncHS <= (dSyncHard and not dSyncHard_reg) or (dSyncSoft and not dSyncSoft_reg);
rbErrSotSyncHS <= (dSyncSoft and not dSyncSoft_reg);
rbErrSotHS <= dSyncErr and not dSyncErr_reg;
GenSyncPulse: process(DivClk)
begin
if Rising_Edge(DivClk) then
dSyncHard_reg <= dSyncHard;
dSyncSoft_reg <= dSyncSoft;
dSyncErr_reg <= dSyncErr;
end if;
end process;
HSDeserializerX: entity work.HS_Deserializer
Generic map (
kIs8b9b => false,
kAddDelay_ps => kAddDelay_ps,
kNoLP => kNoLP
)
Port map (
dLP0_in => dLP0_in,
dLP1_in => dLP1_in,
dLP0_out => dLP0_out,
dLP1_out => dLP1_out,
SerClk => SerClkHS,
DivClk => DivClk,
aHSIn => aHS,
aLPIn => aLP,
aLPOut => aLP_int,
dDataOut8 => dDataOut,
dValid => dValid,
dSyncHard => dSyncHard,
dSyncSoft => dSyncSoft,
dSyncErr => dSyncErr,
CtlClk => CtlClk,
cIDLY_LD => '0', --IDELAYE2 Load
cIDLY_CE => '0', --IDELAYE2 CE
cIDLY_INC => '0', --IDELAYE2 Tap Increment
cIDLY_CNT => open, --IDELAYE2 Current Tap Count
aRst => cHSReset,
aSettled => cHSSettled
);
SyncAsyncValid: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cHSClkRst,
aIn => dValid,
OutClk => CtlClk,
oOut => cValid);
end Behavioral;
@@ -1,51 +1,51 @@
-------------------------------------------------------------------------------
--
-- File: DPHY_Pkg.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DPHY_types is
type vector1 is array (natural range <>) of std_logic;
type vector2 is array (natural range <>) of std_logic_vector(1 downto 0);
type vector4 is array (natural range <>) of std_logic_vector(3 downto 0);
type vector8 is array (natural range <>) of std_logic_vector(7 downto 0);
end package;
-------------------------------------------------------------------------------
--
-- File: DPHY_Pkg.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DPHY_types is
type vector1 is array (natural range <>) of std_logic;
type vector2 is array (natural range <>) of std_logic_vector(1 downto 0);
type vector4 is array (natural range <>) of std_logic_vector(3 downto 0);
type vector8 is array (natural range <>) of std_logic_vector(7 downto 0);
end package;
@@ -1,133 +1,133 @@
-------------------------------------------------------------------------------
--
-- File: DebugLib.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DebugLib is
COMPONENT ila_scnn_refclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_sfen_refclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_sfen_rxclk
PORT (
clk : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT ;
type DebugSCNN_Type is record
cIntRst : std_logic;
cLP : std_logic_vector(1 downto 0);
cHSRst : std_logic;
cHSClkLocked : std_logic;
state : std_logic_vector(3 downto 0);
cClkSettleTout : std_logic;
cBUFR_Rst : std_logic;
cMMCM_Rst : std_logic;
cMMCM_RstTout : std_logic;
cMMCM_Locked : std_logic;
end record;
type DebugSFEN_Type is record
cIntRst : std_logic;
cLP : std_logic_vector(1 downto 0);
state : std_logic_vector(2 downto 0);
cHSClkRst : std_logic;
cForceRxmode : std_logic;
cInitTout : std_logic;
cHSSettleTout : std_logic;
cHSSettled : std_logic;
cHSReset : std_logic;
dSyncHard : std_logic;
dSyncSoft : std_logic;
dSyncErr : std_logic;
end record;
end package;
-------------------------------------------------------------------------------
--
-- File: DebugLib.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
package DebugLib is
COMPONENT ila_scnn_refclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe9 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_sfen_refclk
PORT (
clk : IN STD_LOGIC;
trig_out : OUT STD_LOGIC;
trig_out_ack : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(0 DOWNTO 0)
);
END COMPONENT ;
COMPONENT ila_sfen_rxclk
PORT (
clk : IN STD_LOGIC;
trig_in : IN STD_LOGIC;
trig_in_ack : OUT STD_LOGIC;
probe0 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe1 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe2 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe3 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe4 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe5 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe6 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe7 : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
probe8 : IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT ;
type DebugSCNN_Type is record
cIntRst : std_logic;
cLP : std_logic_vector(1 downto 0);
cHSRst : std_logic;
cHSClkLocked : std_logic;
state : std_logic_vector(3 downto 0);
cClkSettleTout : std_logic;
cBUFR_Rst : std_logic;
cMMCM_Rst : std_logic;
cMMCM_RstTout : std_logic;
cMMCM_Locked : std_logic;
end record;
type DebugSFEN_Type is record
cIntRst : std_logic;
cLP : std_logic_vector(1 downto 0);
state : std_logic_vector(2 downto 0);
cHSClkRst : std_logic;
cForceRxmode : std_logic;
cInitTout : std_logic;
cHSSettleTout : std_logic;
cHSSettled : std_logic;
cHSReset : std_logic;
dSyncHard : std_logic;
dSyncSoft : std_logic;
dSyncErr : std_logic;
end record;
end package;
@@ -1,94 +1,94 @@
-------------------------------------------------------------------------------
--
-- File: GlitchFilter.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module filters any pulses on sIn lasting less than the number of
-- periods specified in kNoOfPeriodsToFilter. The output sOut will be
-- delayed by kNoOfPeriodsToFilter cycles, but glitch-free.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity GlitchFilter is
Generic (
kNoOfPeriodsToFilter : natural);
Port (
SampleClk : in STD_LOGIC;
sIn : in STD_LOGIC;
sOut : out STD_LOGIC;
sRst : in STD_LOGIC);
end GlitchFilter;
architecture Behavioral of GlitchFilter is
signal cntPeriods : natural range 0 to kNoOfPeriodsToFilter - 1 := kNoOfPeriodsToFilter - 1;
signal sIn_q : std_logic;
begin
Bypass: if kNoOfPeriodsToFilter = 0 generate
sOut <= sIn;
end generate Bypass;
Filter: if kNoOfPeriodsToFilter > 0 generate
process (SampleClk)
begin
if Rising_Edge(SampleClk) then
sIn_q <= sIn;
if (cntPeriods = 0) then
sOut <= sIn_q;
end if;
end if;
end process;
PeriodCounter: process (SampleClk)
begin
if Rising_Edge(SampleClk) then
if (sIn_q /= sIn or sRst = '1') then --edge detected
cntPeriods <= kNoOfPeriodsToFilter - 1; --reset counter
elsif (cntPeriods /= 0) then
cntPeriods <= cntPeriods - 1; --count down
end if;
end if;
end process PeriodCounter;
end generate Filter;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: GlitchFilter.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module filters any pulses on sIn lasting less than the number of
-- periods specified in kNoOfPeriodsToFilter. The output sOut will be
-- delayed by kNoOfPeriodsToFilter cycles, but glitch-free.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity GlitchFilter is
Generic (
kNoOfPeriodsToFilter : natural);
Port (
SampleClk : in STD_LOGIC;
sIn : in STD_LOGIC;
sOut : out STD_LOGIC;
sRst : in STD_LOGIC);
end GlitchFilter;
architecture Behavioral of GlitchFilter is
signal cntPeriods : natural range 0 to kNoOfPeriodsToFilter - 1 := kNoOfPeriodsToFilter - 1;
signal sIn_q : std_logic;
begin
Bypass: if kNoOfPeriodsToFilter = 0 generate
sOut <= sIn;
end generate Bypass;
Filter: if kNoOfPeriodsToFilter > 0 generate
process (SampleClk)
begin
if Rising_Edge(SampleClk) then
sIn_q <= sIn;
if (cntPeriods = 0) then
sOut <= sIn_q;
end if;
end if;
end process;
PeriodCounter: process (SampleClk)
begin
if Rising_Edge(SampleClk) then
if (sIn_q /= sIn or sRst = '1') then --edge detected
cntPeriods <= kNoOfPeriodsToFilter - 1; --reset counter
elsif (cntPeriods /= 0) then
cntPeriods <= cntPeriods - 1; --count down
end if;
end if;
end process PeriodCounter;
end generate Filter;
end Behavioral;
@@ -1,298 +1,298 @@
-------------------------------------------------------------------------------
--
-- File: HS_Clocking.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module instantiates all the necessary primitives to obtain a fast
-- serial clock and a divided parallel clock from the the D-PHY high-speed
-- clock input. It also instantiates logic for IDELAYE2 primitives to be
-- usable throughout the design.
-- Connect this module to the output of the HS clock lane input buffer. Connect
-- an architecture-dependent 200/300 MHz reference clock for IDELAYCTRL
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity HS_Clocking is
Generic (
kGenerateMMCM : boolean := false;
kCtlClkFreqHz : integer := 100_000_000;
kRefClkFreqHz : integer := 200_000_000;
kAddDelay_ps : integer := 0
);
Port (
HS_Clock : in STD_LOGIC;
HS_SerClk : out STD_LOGIC;
HS_Div4Clk : out STD_LOGIC;
CtlClk : in STD_LOGIC;
cRst : in std_logic; --Must be asserted when CtlClk or HS_Clk are not present/stable; must be de-asserted synchronously with CtlClk
aLocked : out std_logic;
dbg_cBUFR_Rst : out std_logic;
dbg_cMMCM_Rst : out std_logic;
dbg_cMMCM_RstTout : out std_logic;
dbg_cMMCM_Locked : out std_logic
);
end HS_Clocking;
architecture Behavioral of HS_Clocking is
constant kRefClkFreqInMHz : real := real(kRefClkFreqHz) / 1_000_000.0;
constant kDelayTaps : natural := natural(ceil(real(kAddDelay_ps) * (kRefClkFreqInMHz*2.0*32.0) / 1_000_000.0));
constant kMMCM_RSTMINPULSE : real := 5.0; --ns; Artix-7 spec
constant kTMMCM_Rst : natural := natural(ceil(kMMCM_RSTMINPULSE / (10.0**9) * real(kCtlClkFreqHz)));
signal cBUFR_Rst, cExtRst, cMMCM_Rst : std_logic;
signal cDelayCnt : natural range 0 to kTMMCM_Rst := 0;
signal cMMCM_RstTout, cDelayCntEn : std_logic;
signal aMMCM_Locked, cMMCM_Locked, cMMCM_LockedFalling, cMMCM_LockedRising : std_logic;
signal cMMCM_Reset_q : std_logic_vector(1 downto 0);
signal cMMCM_Locked_q : std_logic_vector(1 downto 0);
signal dDiv4ClkActive : std_logic;
signal ClkFbOut, ClkFbIn, HS_Clock_1X, HS_Div4Clk_int, HS_Clock_Buf, HS_ClockDly : std_logic;
signal divclk_dbg : std_logic;
begin
dbg_cBUFR_Rst <= cBUFR_Rst;
dbg_cMMCM_Rst <= cMMCM_Rst;
dbg_cMMCM_RstTout <= cMMCM_RstTout;
dbg_cMMCM_Locked <= cMMCM_Locked;
cExtRst <= cRst;
-- Time delay counter running on CtlClk, because it has a known, fixed frequency
-- We use it to keep track of timing parameters in time units rather than UIs.
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
else
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cMMCM_RstTout <= '1' when cDelayCnt = kTMMCM_Rst else '0';
-- Delay element for phase alignment of serial data
InputDelay: IDELAYE2
generic map (
CINVCTRL_SEL => "FALSE", -- TRUE, FALSE
DELAY_SRC => "IDATAIN", -- IDATAIN, DATAIN
HIGH_PERFORMANCE_MODE => "TRUE", -- TRUE, FALSE
IDELAY_TYPE => "FIXED", -- FIXED, VARIABLE, or VAR_LOADABLE
IDELAY_VALUE => kDelayTaps,
REFCLK_FREQUENCY => kRefClkFreqInMHz,
PIPE_SEL => "FALSE",
SIGNAL_PATTERN => "CLOCK") -- CLOCK, DATA
port map (
DATAOUT => HS_ClockDly, -- Delayed signal
DATAIN => '0', -- Not used; IDATAIN instead
C => CtlClk, -- Not used in FIXED mode
CE => '0', -- Not used in FIXED mode
INC => '0', -- Not used in FIXED mode
IDATAIN => HS_Clock, -- Driven by IOB
LD => '0', -- Not used in FIXED mode
REGRST => '0', --not used in VARIABLE mode
LDPIPEEN => '0',
CNTVALUEIN => "00000", -- Not used in FIXED mode
CNTVALUEOUT => open, -- Not used in FIXED mode
CINVCTRL => '0' -- Not used in FIXED mode
);
--Complex use case, with MMCM
GenMMCM: if kGenerateMMCM generate
SerClockGen: MMCME2_ADV
generic map
(BANDWIDTH => "OPTIMIZED",
CLKOUT4_CASCADE => FALSE,
COMPENSATION => "ZHOLD",
STARTUP_WAIT => FALSE,
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT_F => 15.0,
CLKFBOUT_PHASE => 0.000,
CLKFBOUT_USE_FINE_PS => FALSE,
CLKOUT0_DIVIDE_F => 15.0,
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT0_USE_FINE_PS => FALSE,
CLKIN1_PERIOD => 16.666, --60MHz for now
REF_JITTER1 => 0.010)
port map
-- Output clocks
(
CLKFBOUT => ClkFbOut,
CLKFBOUTB => open,
CLKOUT0 => HS_Clock_1X,
CLKOUT0B => open,
CLKOUT1 => open,
CLKOUT1B => open,
CLKOUT2 => open,
CLKOUT2B => open,
CLKOUT3 => open,
CLKOUT3B => open,
CLKOUT4 => open,
CLKOUT5 => open,
CLKOUT6 => open,
-- Input clock control
CLKFBIN => ClkFbIn,
CLKIN1 => HS_ClockDly,
CLKIN2 => '0',
-- Tied to always select the primary input clock
CLKINSEL => '1',
-- Ports for dynamic reconfiguration
DADDR => (others => '0'),
DCLK => '0',
DEN => '0',
DI => (others => '0'),
DO => open,
DRDY => open,
DWE => '0',
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => aMMCM_Locked,
CLKINSTOPPED => open,
CLKFBSTOPPED => open,
PWRDWN => '0',
RST => cMMCM_Rst);
-- To make sure the MMCM output is phase-aligned to its input, we need to replicate the buffers from clock output
-- in the feedback loop. Since we use a BUFIO/BUFR pair at the MMCM output, we add a BUFR to the feedback loop
FeedbackBuffer: BUFR
generic map (
BUFR_DIVIDE => "1", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES"
)
port map (
O => ClkFbIn, -- 1-bit output: Clock output port
CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only)
CLR => cMMCM_Rst, -- 1-bit input: Active high, asynchronous clear (Divided modes only)
I => ClkFbOut -- 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);
-- Synchronize MMCM Locked into the CtlClk domain
MMCM_LockSync: entity work.SyncAsync
port map (
aReset => '0',
aIn => aMMCM_Locked,
OutClk => CtlClk,
oOut => cMMCM_Locked);
-- Edge detector for MMCM Locked flag;
MMCM_LockedDetect: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
cMMCM_Locked_q <= cMMCM_Locked & cMMCM_Locked_q(1);
cMMCM_LockedFalling <= cMMCM_Locked_q(1) and not cMMCM_Locked;
cMMCM_LockedRising <= not cMMCM_Locked_q(1) and cMMCM_Locked;
end if;
end process MMCM_LockedDetect;
-- Generate MMCM reset on external reset or lock lost event
MMCM_Reset: process(cExtRst, CtlClk)
begin
if (cExtRst = '1') then
cMMCM_Rst <= '1';
cDelayCntEn <= '1';
elsif Rising_Edge(CtlClk) then
if (cMMCM_LockedFalling = '1') then
cMMCM_Rst <= '1';
cDelayCntEn <= '1';
elsif cMMCM_RstTout = '1' then --count down to minimum reset pulse width
cMMCM_Rst <= '0';
cDelayCntEn <= '0';
end if;
end if;
end process MMCM_Reset;
cBUFR_Rst <= not cMMCM_Locked;
HS_Clock_Buf <= HS_Clock_1X;
end generate GenMMCM;
GenNoMMCM: if not kGenerateMMCM generate
--Simple use case, no PLL, just BUFIO and BUFR
HS_Clock_Buf <= HS_ClockDly;
cBUFR_Rst <= cExtRst when Rising_Edge(CtlClk); --make external reset glitch free
cDelayCntEn <= '0';
cMMCM_Rst <= '0';
cMMCM_Locked <= '1';
end generate GenNoMMCM;
--Fast serial clock
SerialClkBuffer: BUFIO
port map (
O => HS_SerClk, -- 1-bit output: Clock output (connect to I/O clock loads).
I => HS_Clock_Buf -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
);
-- 1x slow parallel clock
DivClkBuffer: BUFR
generic map (
BUFR_DIVIDE => "4", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES"
)
port map (
O => HS_Div4Clk_int, -- 1-bit output: Clock output port
CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only)
CLR => cBUFR_Rst, -- 1-bit input: Active high, asynchronous clear (Divided modes only)
I => HS_Clock_Buf -- 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);
SyncAsyncLocked: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cBUFR_Rst,
aIn => '1',
OutClk => HS_Div4Clk_int,
oOut => dDiv4ClkActive);
HS_Div4Clk <= HS_Div4Clk_int;
aLocked <= dDiv4ClkActive;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: HS_Clocking.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module instantiates all the necessary primitives to obtain a fast
-- serial clock and a divided parallel clock from the the D-PHY high-speed
-- clock input. It also instantiates logic for IDELAYE2 primitives to be
-- usable throughout the design.
-- Connect this module to the output of the HS clock lane input buffer. Connect
-- an architecture-dependent 200/300 MHz reference clock for IDELAYCTRL
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.math_real.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity HS_Clocking is
Generic (
kGenerateMMCM : boolean := false;
kCtlClkFreqHz : integer := 100_000_000;
kRefClkFreqHz : integer := 200_000_000;
kAddDelay_ps : integer := 0
);
Port (
HS_Clock : in STD_LOGIC;
HS_SerClk : out STD_LOGIC;
HS_Div4Clk : out STD_LOGIC;
CtlClk : in STD_LOGIC;
cRst : in std_logic; --Must be asserted when CtlClk or HS_Clk are not present/stable; must be de-asserted synchronously with CtlClk
aLocked : out std_logic;
dbg_cBUFR_Rst : out std_logic;
dbg_cMMCM_Rst : out std_logic;
dbg_cMMCM_RstTout : out std_logic;
dbg_cMMCM_Locked : out std_logic
);
end HS_Clocking;
architecture Behavioral of HS_Clocking is
constant kRefClkFreqInMHz : real := real(kRefClkFreqHz) / 1_000_000.0;
constant kDelayTaps : natural := natural(ceil(real(kAddDelay_ps) * (kRefClkFreqInMHz*2.0*32.0) / 1_000_000.0));
constant kMMCM_RSTMINPULSE : real := 5.0; --ns; Artix-7 spec
constant kTMMCM_Rst : natural := natural(ceil(kMMCM_RSTMINPULSE / (10.0**9) * real(kCtlClkFreqHz)));
signal cBUFR_Rst, cExtRst, cMMCM_Rst : std_logic;
signal cDelayCnt : natural range 0 to kTMMCM_Rst := 0;
signal cMMCM_RstTout, cDelayCntEn : std_logic;
signal aMMCM_Locked, cMMCM_Locked, cMMCM_LockedFalling, cMMCM_LockedRising : std_logic;
signal cMMCM_Reset_q : std_logic_vector(1 downto 0);
signal cMMCM_Locked_q : std_logic_vector(1 downto 0);
signal dDiv4ClkActive : std_logic;
signal ClkFbOut, ClkFbIn, HS_Clock_1X, HS_Div4Clk_int, HS_Clock_Buf, HS_ClockDly : std_logic;
signal divclk_dbg : std_logic;
begin
dbg_cBUFR_Rst <= cBUFR_Rst;
dbg_cMMCM_Rst <= cMMCM_Rst;
dbg_cMMCM_RstTout <= cMMCM_RstTout;
dbg_cMMCM_Locked <= cMMCM_Locked;
cExtRst <= cRst;
-- Time delay counter running on CtlClk, because it has a known, fixed frequency
-- We use it to keep track of timing parameters in time units rather than UIs.
DelayCounter: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
if (cDelayCntEn = '0') then
cDelayCnt <= 0;
else
cDelayCnt <= cDelayCnt + 1;
end if;
end if;
end process DelayCounter;
cMMCM_RstTout <= '1' when cDelayCnt = kTMMCM_Rst else '0';
-- Delay element for phase alignment of serial data
InputDelay: IDELAYE2
generic map (
CINVCTRL_SEL => "FALSE", -- TRUE, FALSE
DELAY_SRC => "IDATAIN", -- IDATAIN, DATAIN
HIGH_PERFORMANCE_MODE => "TRUE", -- TRUE, FALSE
IDELAY_TYPE => "FIXED", -- FIXED, VARIABLE, or VAR_LOADABLE
IDELAY_VALUE => kDelayTaps,
REFCLK_FREQUENCY => kRefClkFreqInMHz,
PIPE_SEL => "FALSE",
SIGNAL_PATTERN => "CLOCK") -- CLOCK, DATA
port map (
DATAOUT => HS_ClockDly, -- Delayed signal
DATAIN => '0', -- Not used; IDATAIN instead
C => CtlClk, -- Not used in FIXED mode
CE => '0', -- Not used in FIXED mode
INC => '0', -- Not used in FIXED mode
IDATAIN => HS_Clock, -- Driven by IOB
LD => '0', -- Not used in FIXED mode
REGRST => '0', --not used in VARIABLE mode
LDPIPEEN => '0',
CNTVALUEIN => "00000", -- Not used in FIXED mode
CNTVALUEOUT => open, -- Not used in FIXED mode
CINVCTRL => '0' -- Not used in FIXED mode
);
--Complex use case, with MMCM
GenMMCM: if kGenerateMMCM generate
SerClockGen: MMCME2_ADV
generic map
(BANDWIDTH => "OPTIMIZED",
CLKOUT4_CASCADE => FALSE,
COMPENSATION => "ZHOLD",
STARTUP_WAIT => FALSE,
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT_F => 15.0,
CLKFBOUT_PHASE => 0.000,
CLKFBOUT_USE_FINE_PS => FALSE,
CLKOUT0_DIVIDE_F => 15.0,
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT0_USE_FINE_PS => FALSE,
CLKIN1_PERIOD => 16.666, --60MHz for now
REF_JITTER1 => 0.010)
port map
-- Output clocks
(
CLKFBOUT => ClkFbOut,
CLKFBOUTB => open,
CLKOUT0 => HS_Clock_1X,
CLKOUT0B => open,
CLKOUT1 => open,
CLKOUT1B => open,
CLKOUT2 => open,
CLKOUT2B => open,
CLKOUT3 => open,
CLKOUT3B => open,
CLKOUT4 => open,
CLKOUT5 => open,
CLKOUT6 => open,
-- Input clock control
CLKFBIN => ClkFbIn,
CLKIN1 => HS_ClockDly,
CLKIN2 => '0',
-- Tied to always select the primary input clock
CLKINSEL => '1',
-- Ports for dynamic reconfiguration
DADDR => (others => '0'),
DCLK => '0',
DEN => '0',
DI => (others => '0'),
DO => open,
DRDY => open,
DWE => '0',
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => aMMCM_Locked,
CLKINSTOPPED => open,
CLKFBSTOPPED => open,
PWRDWN => '0',
RST => cMMCM_Rst);
-- To make sure the MMCM output is phase-aligned to its input, we need to replicate the buffers from clock output
-- in the feedback loop. Since we use a BUFIO/BUFR pair at the MMCM output, we add a BUFR to the feedback loop
FeedbackBuffer: BUFR
generic map (
BUFR_DIVIDE => "1", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES"
)
port map (
O => ClkFbIn, -- 1-bit output: Clock output port
CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only)
CLR => cMMCM_Rst, -- 1-bit input: Active high, asynchronous clear (Divided modes only)
I => ClkFbOut -- 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);
-- Synchronize MMCM Locked into the CtlClk domain
MMCM_LockSync: entity work.SyncAsync
port map (
aReset => '0',
aIn => aMMCM_Locked,
OutClk => CtlClk,
oOut => cMMCM_Locked);
-- Edge detector for MMCM Locked flag;
MMCM_LockedDetect: process(CtlClk)
begin
if Rising_Edge(CtlClk) then
cMMCM_Locked_q <= cMMCM_Locked & cMMCM_Locked_q(1);
cMMCM_LockedFalling <= cMMCM_Locked_q(1) and not cMMCM_Locked;
cMMCM_LockedRising <= not cMMCM_Locked_q(1) and cMMCM_Locked;
end if;
end process MMCM_LockedDetect;
-- Generate MMCM reset on external reset or lock lost event
MMCM_Reset: process(cExtRst, CtlClk)
begin
if (cExtRst = '1') then
cMMCM_Rst <= '1';
cDelayCntEn <= '1';
elsif Rising_Edge(CtlClk) then
if (cMMCM_LockedFalling = '1') then
cMMCM_Rst <= '1';
cDelayCntEn <= '1';
elsif cMMCM_RstTout = '1' then --count down to minimum reset pulse width
cMMCM_Rst <= '0';
cDelayCntEn <= '0';
end if;
end if;
end process MMCM_Reset;
cBUFR_Rst <= not cMMCM_Locked;
HS_Clock_Buf <= HS_Clock_1X;
end generate GenMMCM;
GenNoMMCM: if not kGenerateMMCM generate
--Simple use case, no PLL, just BUFIO and BUFR
HS_Clock_Buf <= HS_ClockDly;
cBUFR_Rst <= cExtRst when Rising_Edge(CtlClk); --make external reset glitch free
cDelayCntEn <= '0';
cMMCM_Rst <= '0';
cMMCM_Locked <= '1';
end generate GenNoMMCM;
--Fast serial clock
SerialClkBuffer: BUFIO
port map (
O => HS_SerClk, -- 1-bit output: Clock output (connect to I/O clock loads).
I => HS_Clock_Buf -- 1-bit input: Clock input (connect to an IBUF or BUFMR).
);
-- 1x slow parallel clock
DivClkBuffer: BUFR
generic map (
BUFR_DIVIDE => "4", -- Values: "BYPASS, 1, 2, 3, 4, 5, 6, 7, 8"
SIM_DEVICE => "7SERIES" -- Must be set to "7SERIES"
)
port map (
O => HS_Div4Clk_int, -- 1-bit output: Clock output port
CE => '1', -- 1-bit input: Active high, clock enable (Divided modes only)
CLR => cBUFR_Rst, -- 1-bit input: Active high, asynchronous clear (Divided modes only)
I => HS_Clock_Buf -- 1-bit input: Clock buffer input driven by an IBUF, MMCM or local interconnect
);
SyncAsyncLocked: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 2) --use double FF synchronizer
port map (
aReset => cBUFR_Rst,
aIn => '1',
OutClk => HS_Div4Clk_int,
oOut => dDiv4ClkActive);
HS_Div4Clk <= HS_Div4Clk_int;
aLocked <= dDiv4ClkActive;
end Behavioral;
@@ -1,479 +1,479 @@
-------------------------------------------------------------------------------
--
-- File: HS_Deserializer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- HS_Deserializer instantiates 7-series-specific primitives for deserialization
-- of a high-speed data burst on a D-PHY data lane. Once enabled it looks
-- for the sync sequence (SoT) and performs necessary alignment to the byte
-- boundary. It outputs either valid de-serialized data, or reports a synchronization
-- error. It is expected to be clocked according to the clocking requirements
-- of the ISERDESE2 primitives.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.math_real.all;
use work.DPHY_types.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity HS_Deserializer is
Generic (
kIs8b9b : boolean := false;
kIDLY_TapWidth : natural := 5;
kAddDelay_ps : integer := 0;
kNoLP : boolean := false
);
Port (
dLP0_in : in std_logic_vector(7 downto 0);
dLP1_in : in std_logic_vector(7 downto 0);
dLP0_out : out std_logic_vector(7 downto 0);
dLP1_out : out std_logic_vector(7 downto 0);
SerClk : in STD_LOGIC; -- DDR serial clock
DivClk : in STD_LOGIC; -- SDR parallel clock; 1:8 factor => par clock = ser clock/4
aHSIn : in std_logic;
aLPIn : in std_logic_vector(1 downto 0);
aLPOut : out std_logic_vector(1 downto 0);
dDataOut8 : out std_logic_vector(7 downto 0); --if !kIs8b9b
dDataOut9 : out std_logic_vector(8 downto 0); --if kIs8b9b
dValid : out std_logic;
dSyncHard : out std_logic;
dSyncSoft : out std_logic;
dSyncErr : out std_logic;
--Control for phase alignment
CtlClk : in std_logic;
cIDLY_LD : in STD_LOGIC; --IDELAYE2 Load
cIDLY_CE : in STD_LOGIC; --IDELAYE2 CE
cIDLY_INC : in STD_LOGIC; --IDELAYE2 Tap Increment
cIDLY_CNT : out std_logic_vector(kIDLY_TapWidth-1 downto 0); --IDELAYE2 Current Tap Count
aRst : in std_logic; -- should be de-asserted only when SerClk and DivClk are stable
aSettled : in std_logic --should be asserted when T_HS_SETTLE expired
);
end HS_Deserializer;
architecture Behavioral of HS_Deserializer is
constant kRefClkFreqInMHz : real := 200.0;
constant kAddDelayTaps : natural := natural(ceil(real(kAddDelay_ps) * (kRefClkFreqInMHz*2.0*32.0) / 1_000_000.0));
constant kDelayTaps : natural := 12 + kAddDelayTaps; -- 12*(1/(32*2*F_REF)) = 937.5 ps
function isSoftMatch(mask : std_logic_vector(7 downto 0); word : std_logic_vector(7 downto 0)) return boolean is
variable diff : std_logic_vector(7 downto 0);
variable sum : unsigned(3 downto 0) := "0000";
begin
diff := mask xor word;
SumDiff: for i in diff'high downto diff'low loop
sum := sum + unsigned(diff(i downto i));
end loop;
if (sum = 1) then
return true;
else
return false;
end if;
end isSoftMatch;
procedure findMatch (
constant mask : in std_logic_vector(7 downto 0); --sequence to find
signal word : in std_logic_vector(15 downto 0); --two words most significant first
variable hard : inout std_logic;
variable soft : inout std_logic;
variable alignment : inout natural range 0 to 7
) is
begin
hard := '0';
soft := '0';
--The sync word is constructed in such a way that either there is a match
--or a soft match with 1 bit error, but not both
FindHardLoop: for i in 0 to 7 loop
if (mask = word(i+7 downto i)) then
alignment := i;
hard := '1';
soft := '0';
end if;
end loop FindHardLoop;
if (hard = '0') then
FindSoftLoop: for i in 0 to 7 loop
if (isSoftMatch(mask, word(i+7 downto i))) then
alignment := i;
soft := '1';
end if;
end loop FindSoftLoop;
end if;
end procedure findMatch;
-- Synq sequence as written in the spec (most significant last)
constant kSyncSeq : std_logic_vector(7 downto 0) := "00011101";
signal DataInDly, SerClkInv : std_logic;
signal dDataIn_int : std_logic_vector(7 downto 0);
signal dDataIn_reg : vector8(0 to 3); --data byte pipeline for sync detection and alignment
signal dValid_reg : vector1(0 to 3); --sync flag pipeline
signal dSyncHard_int, dSyncSoft_int, dSyncErr_int : std_logic;
signal dSettled, dSerdesRst, dLogicRst: std_logic;
signal dAlignment_int : natural range 0 to 7 := 0;
signal wordToAlign : std_logic_vector(15 downto 0);
-- LP sampled at high-speed as a nibble
type dLP_t is array (0 to 1) of std_logic_vector(7 downto 0);
signal dLP : dLP_t;
signal dLPBridge, dLPStop : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of dLP: signal is "TRUE";
begin
-- Delay element for phase alignment of serial data
InputDelay: IDELAYE2
generic map (
CINVCTRL_SEL => "FALSE", -- TRUE, FALSE
DELAY_SRC => "IDATAIN", -- IDATAIN, DATAIN
HIGH_PERFORMANCE_MODE => "TRUE", -- TRUE, FALSE
IDELAY_TYPE => "VARIABLE", -- FIXED, VARIABLE, or VAR_LOADABLE
IDELAY_VALUE => kDelayTaps,
REFCLK_FREQUENCY => kRefClkFreqInMHz,
PIPE_SEL => "FALSE",
SIGNAL_PATTERN => "DATA") -- CLOCK, DATA
port map (
DATAOUT => DataInDly, -- Delayed signal
DATAIN => '0', -- Not used; IDATAIN instead
C => CtlClk, -- Clock for control signals (CE,INC...)
CE => cIDLY_CE,
INC => cIDLY_INC,
IDATAIN => aHSIn, -- Driven by IOB
LD => cIDLY_LD,
REGRST => '0', --not used in VARIABLE mode
LDPIPEEN => '0',
CNTVALUEIN => "00000", --not used in VARIABLE mode
CNTVALUEOUT => cIDLY_CNT, -- current tap value
CINVCTRL => '0');
assert (not kIs8b9b) report "8b9b encoding not supported yet" severity failure;
--Invert locally for ISERDESE2
SerClkInv <= not SerClk;
-- De-serializer, 1:8 DDR, non-cascaded,
-- Least-significant first: bit sent first should be bit(0) in PPI byte
Deserializer: ISERDESE2
generic map (
DATA_RATE => "DDR",
DATA_WIDTH => 8,
INTERFACE_TYPE => "NETWORKING",
DYN_CLKDIV_INV_EN => "FALSE",
DYN_CLK_INV_EN => "FALSE",
NUM_CE => 1,
OFB_USED => "FALSE",
IOBDELAY => "IFD", -- Use input at DDLY to output the data on Q1-Q6
SERDES_MODE => "MASTER",
INIT_Q1 => '0',
INIT_Q2 => '0',
INIT_Q3 => '0',
INIT_Q4 => '0',
SRVAL_Q1 => '0',
SRVAL_Q2 => '0',
SRVAL_Q3 => '0',
SRVAL_Q4 => '0')
port map (
Q1 => dDataIn_int(0),
Q2 => dDataIn_int(1),
Q3 => dDataIn_int(2),
Q4 => dDataIn_int(3),
Q5 => dDataIn_int(4),
Q6 => dDataIn_int(5),
Q7 => dDataIn_int(6),
Q8 => dDataIn_int(7), -- bit sent first
SHIFTOUT1 => open, -- Cascade connection to Slave ISERDES
SHIFTOUT2 => open, -- Cascade connection to Slave ISERDES
BITSLIP => '0', -- 1-bit Invoke Bitslip. This can be used with any
CE1 => '1', -- 1-bit Clock enable input
CE2 => '1', -- 1-bit Clock enable input
CLK => SerClk, -- Fast Source Synchronous SERDES clock from BUFIO
CLKB => SerClkInv, -- Locally inverted clock
CLKDIV => DivClk, -- Slow clock driven by BUFR
CLKDIVP => '0', --Not used here
D => '0',
DDLY => DataInDly, -- 1-bit Input signal from IODELAYE1.
RST => dSerdesRst, -- 1-bit Asynchronous reset only.
SHIFTIN1 => '0',
SHIFTIN2 => '0',
-- unused connections
DYNCLKDIVSEL => '0',
DYNCLKSEL => '0',
OFB => '0',
OCLK => '0',
OCLKB => '0',
O => open); -- unregistered output of ISERDESE1
-- We need a reset bridge to use the asynchronous aRst signal to reset our
-- ISERDESE2
SerdesReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aRst,
OutClk => DivClk,
oRst => dSerdesRst);
-- We do not have a lot of time to bring aSettled into the DivClk domain
-- T_HS_SETTLE_max = 145ns + 10*UI
-- T_HS_SETTLE_min = 85ns + 6*UI
-- aSettled measures 85ns, and we synchronize it with only one flip-flop
-- dSettled should be used downstream in simple combinational logic only
SyncAsyncSettled: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 1) --see above
port map (
aReset => not aSettled,
aIn => '1',
OutClk => DivClk,
oOut => dSettled);
-- LP de-serializer, 1:8 DDR, non-cascaded,
-- Although LP signals are low-speed and not synchronous with the HS clock, we need to detect LP
-- state changes as soon as possible due to tight timing between LP states and HS start.
UseOwnLP: if not kNoLP generate
LPxx: for i in 0 to 1 generate
LP_DeserializerX: ISERDESE2
generic map (
DATA_RATE => "DDR",
DATA_WIDTH => 8,
INTERFACE_TYPE => "NETWORKING",
DYN_CLKDIV_INV_EN => "FALSE",
DYN_CLK_INV_EN => "FALSE",
NUM_CE => 1,
OFB_USED => "FALSE",
IOBDELAY => "NONE", -- combinatorial output = D, registered output = D
SERDES_MODE => "MASTER",
INIT_Q1 => '1',
INIT_Q2 => '1',
INIT_Q3 => '1',
INIT_Q4 => '1',
SRVAL_Q1 => '1',
SRVAL_Q2 => '1',
SRVAL_Q3 => '1',
SRVAL_Q4 => '1')
port map (
Q1 => dLP(i)(0),
Q2 => dLP(i)(1),
Q3 => dLP(i)(2),
Q4 => dLP(i)(3),
Q5 => dLP(i)(4),
Q6 => dLP(i)(5),
Q7 => dLP(i)(6),
Q8 => dLP(i)(7), -- bit sent first
SHIFTOUT1 => open, -- Cascade connection to Slave ISERDES
SHIFTOUT2 => open, -- Cascade connection to Slave ISERDES
BITSLIP => '0', -- 1-bit Invoke Bitslip. This can be used with any
CE1 => '1', -- 1-bit Clock enable input
CE2 => '1', -- 1-bit Clock enable input
CLK => SerClk, -- Fast Source Synchronous SERDES clock from BUFIO
CLKB => SerClkInv, -- Locally inverted clock
CLKDIV => DivClk, -- Slow clock driven by BUFR
CLKDIVP => '0', --Not used here
D => aLPIn(i),
DDLY => '0', -- 1-bit Input signal from IODELAYE1.
RST => dSerdesRst, -- 1-bit Asynchronous reset only.
SHIFTIN1 => '0',
SHIFTIN2 => '0',
-- unused connections
DYNCLKDIVSEL => '0',
DYNCLKSEL => '0',
OFB => '0',
OCLK => '0',
OCLKB => '0',
O => aLPOut(i)); -- unregistered output of ISERDESE1
end generate LPxx;
dLP0_out <= dLP(0);
dLP1_out <= dLP(1);
end generate UseOwnLP;
ShareLPFromOtherLane: if kNoLP generate
dLP(0) <= dLP0_in;
dLP(1) <= dLP1_in;
aLPOut <= aLPIn;
end generate ShareLPFromOtherLane;
-- We are in Bridge (or HS) state when we sampled 0 at least 2 times on both LP1 on and LP0
-- TODO: glitch filtering? problematic, because serial clock frequency changes dynamically
dLPBridge <= '1' when dLP(0)(1 downto 0) = "00" and dLP(1)(1 downto 0) = "00" else
'0';
-- We are in Stop state when we sampled 1 at least 2 times on both LP1 on and LP0
-- TODO: glitch filtering? problematic, because serial clock frequency changes dynamically
dLPStop <= '1' when dLP(0)(1 downto 0) = "11" and dLP(1)(1 downto 0) = "11" else
'0';
-- Logic should be held in reset for one more period, because ISERDES output
-- is only valid starting from the second DivClk period
process(DivClk, dSerdesRst)
variable dSerdesRst_q : std_logic;
begin
if (dSerdesRst = '1') then
dLogicRst <= '1';
dSerdesRst_q := '1';
elsif Rising_Edge(DivClk) then
if (dSerdesRst_q = '0' and dSettled = '1') then
dLogicRst <= '0';
elsif (dValid_reg(3) = '0') then
dLogicRst <= '1';
end if;
dSerdesRst_q := dSerdesRst;
end if;
end process;
-------------------------------------------------------------
-- Buffer data to detect sync sequence early enough
-------------------------------------------------------------
DataPipeline: process(DivClk)
begin
if Rising_Edge(DivClk) then
if dLogicRst = '1' then
dDataIn_reg <= (others => (others => '0'));
else
for i in dDataIn_reg'low to dDataIn_reg'high-1 loop
dDataIn_reg(i+1) <= dDataIn_reg(i);
end loop;
dDataIn_reg(0) <= dDataIn_int;
end if;
end if;
end process;
AlignFlagPipeline: process(DivClk)
begin
if Rising_Edge(DivClk) then
if dLogicRst = '1' then
dValid_reg <= (others => '0');
else
for i in 2 to dValid_reg'high-1 loop
dValid_reg(i+1) <= dValid_reg(i);
end loop;
dValid_reg(2) <= (dSyncHard_int or dSyncSoft_int) and not dLPStop;
end if;
end if;
end process;
wordToAlign <= dDataIn_reg(1) & dDataIn_reg(0);
process(DivClk)
variable nextMust : boolean;
variable hard, soft : std_logic;
variable alignment : natural range 0 to 7;
begin
if Rising_Edge(DivClk) then
if (dLogicRst = '1') then
dSyncHard_int <= '0';
dSyncSoft_int <= '0';
dAlignment_int <= 0;
dSyncErr_int <= '0';
nextMust := false;
elsif (dSyncHard_int = '0' and dSyncSoft_int = '0' and dSyncErr_int = '0') then
--If we are seeing ones in the early part of the word, or we saw ones in the latter part of the
--word in the previous period, we must find a sequence or error out
if (dDataIn_reg(0)(7 downto 4) /= "0000" or nextMust) then
findMatch(kSyncSeq, wordToAlign, hard, soft, alignment);
if (hard = '0' and soft = '0') then
dSyncErr_int <= '1';
end if;
dSyncHard_int <= hard;
dSyncSoft_int <= soft;
dAlignment_int <= alignment;
end if;
--If we are seeing ones, we must find the sequence in the next period
if (dDataIn_reg(0)(3 downto 0) /= "0000") then
nextMust := true;
end if;
end if;
end if;
end process;
dSyncErr <= dSyncErr_int;
dSyncHard <= dSyncHard_int;
dSyncSoft <= dSyncSoft_int;
-------------------------------------------------------------
-- Since the sync sequence is short and it is immediately followed by data, using
-- bitslip is out of question because it is slow and would lead to the loss of the first
-- words in the transmission
-------------------------------------------------------------
WordAlignment: process(DivClk)
constant kPos : natural := 3;
variable delay : natural range 0 to kPos := kPos;
begin
if Rising_Edge(DivClk) then
if (dValid_reg(kPos) = '0' or dLogicRst = '1') then
dDataOut8 <= (others => '0');
dValid <= '0';
else
case (dAlignment_int) is
-- 76543210|76543210|76543210
-- 00000000|00011101|abcdefgh
when 0 =>
dDataOut8 <= dDataIn_reg(kPos-1);
-- 00000000|0011101a|bcdefgha
when 1 =>
dDataOut8 <= dDataIn_reg(kPos)(0 downto 0) & dDataIn_reg(kPos-1)(7 downto 1);
-- 00000000|011101ab|cdefghab
when 2 =>
dDataOut8 <= dDataIn_reg(kPos)(1 downto 0) & dDataIn_reg(kPos-1)(7 downto 2);
-- 00000000|11101abc|defghabc
when 3 =>
dDataOut8 <= dDataIn_reg(kPos)(2 downto 0) & dDataIn_reg(kPos-1)(7 downto 3);
-- 00000001|1101abcd|efghabcd
when 4 =>
dDataOut8 <= dDataIn_reg(kPos)(3 downto 0) & dDataIn_reg(kPos-1)(7 downto 4);
-- 00000011|101abcde|fghabcde
when 5 =>
dDataOut8 <= dDataIn_reg(kPos)(4 downto 0) & dDataIn_reg(kPos-1)(7 downto 5);
-- 00000111|01abcdef|ghabcdef
when 6 =>
dDataOut8 <= dDataIn_reg(kPos)(5 downto 0) & dDataIn_reg(kPos-1)(7 downto 6);
-- 00001110|1abcdefg|habcdefg
when 7 =>
dDataOut8 <= dDataIn_reg(kPos)(6 downto 0) & dDataIn_reg(kPos-1)(7 downto 7);
end case;
dValid <= dValid_reg(kPos);
end if;
end if;
end process;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: HS_Deserializer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- HS_Deserializer instantiates 7-series-specific primitives for deserialization
-- of a high-speed data burst on a D-PHY data lane. Once enabled it looks
-- for the sync sequence (SoT) and performs necessary alignment to the byte
-- boundary. It outputs either valid de-serialized data, or reports a synchronization
-- error. It is expected to be clocked according to the clocking requirements
-- of the ISERDESE2 primitives.
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use ieee.math_real.all;
use work.DPHY_types.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity HS_Deserializer is
Generic (
kIs8b9b : boolean := false;
kIDLY_TapWidth : natural := 5;
kAddDelay_ps : integer := 0;
kNoLP : boolean := false
);
Port (
dLP0_in : in std_logic_vector(7 downto 0);
dLP1_in : in std_logic_vector(7 downto 0);
dLP0_out : out std_logic_vector(7 downto 0);
dLP1_out : out std_logic_vector(7 downto 0);
SerClk : in STD_LOGIC; -- DDR serial clock
DivClk : in STD_LOGIC; -- SDR parallel clock; 1:8 factor => par clock = ser clock/4
aHSIn : in std_logic;
aLPIn : in std_logic_vector(1 downto 0);
aLPOut : out std_logic_vector(1 downto 0);
dDataOut8 : out std_logic_vector(7 downto 0); --if !kIs8b9b
dDataOut9 : out std_logic_vector(8 downto 0); --if kIs8b9b
dValid : out std_logic;
dSyncHard : out std_logic;
dSyncSoft : out std_logic;
dSyncErr : out std_logic;
--Control for phase alignment
CtlClk : in std_logic;
cIDLY_LD : in STD_LOGIC; --IDELAYE2 Load
cIDLY_CE : in STD_LOGIC; --IDELAYE2 CE
cIDLY_INC : in STD_LOGIC; --IDELAYE2 Tap Increment
cIDLY_CNT : out std_logic_vector(kIDLY_TapWidth-1 downto 0); --IDELAYE2 Current Tap Count
aRst : in std_logic; -- should be de-asserted only when SerClk and DivClk are stable
aSettled : in std_logic --should be asserted when T_HS_SETTLE expired
);
end HS_Deserializer;
architecture Behavioral of HS_Deserializer is
constant kRefClkFreqInMHz : real := 200.0;
constant kAddDelayTaps : natural := natural(ceil(real(kAddDelay_ps) * (kRefClkFreqInMHz*2.0*32.0) / 1_000_000.0));
constant kDelayTaps : natural := 12 + kAddDelayTaps; -- 12*(1/(32*2*F_REF)) = 937.5 ps
function isSoftMatch(mask : std_logic_vector(7 downto 0); word : std_logic_vector(7 downto 0)) return boolean is
variable diff : std_logic_vector(7 downto 0);
variable sum : unsigned(3 downto 0) := "0000";
begin
diff := mask xor word;
SumDiff: for i in diff'high downto diff'low loop
sum := sum + unsigned(diff(i downto i));
end loop;
if (sum = 1) then
return true;
else
return false;
end if;
end isSoftMatch;
procedure findMatch (
constant mask : in std_logic_vector(7 downto 0); --sequence to find
signal word : in std_logic_vector(15 downto 0); --two words most significant first
variable hard : inout std_logic;
variable soft : inout std_logic;
variable alignment : inout natural range 0 to 7
) is
begin
hard := '0';
soft := '0';
--The sync word is constructed in such a way that either there is a match
--or a soft match with 1 bit error, but not both
FindHardLoop: for i in 0 to 7 loop
if (mask = word(i+7 downto i)) then
alignment := i;
hard := '1';
soft := '0';
end if;
end loop FindHardLoop;
if (hard = '0') then
FindSoftLoop: for i in 0 to 7 loop
if (isSoftMatch(mask, word(i+7 downto i))) then
alignment := i;
soft := '1';
end if;
end loop FindSoftLoop;
end if;
end procedure findMatch;
-- Synq sequence as written in the spec (most significant last)
constant kSyncSeq : std_logic_vector(7 downto 0) := "00011101";
signal DataInDly, SerClkInv : std_logic;
signal dDataIn_int : std_logic_vector(7 downto 0);
signal dDataIn_reg : vector8(0 to 3); --data byte pipeline for sync detection and alignment
signal dValid_reg : vector1(0 to 3); --sync flag pipeline
signal dSyncHard_int, dSyncSoft_int, dSyncErr_int : std_logic;
signal dSettled, dSerdesRst, dLogicRst: std_logic;
signal dAlignment_int : natural range 0 to 7 := 0;
signal wordToAlign : std_logic_vector(15 downto 0);
-- LP sampled at high-speed as a nibble
type dLP_t is array (0 to 1) of std_logic_vector(7 downto 0);
signal dLP : dLP_t;
signal dLPBridge, dLPStop : std_logic;
attribute DONT_TOUCH : string;
attribute DONT_TOUCH of dLP: signal is "TRUE";
begin
-- Delay element for phase alignment of serial data
InputDelay: IDELAYE2
generic map (
CINVCTRL_SEL => "FALSE", -- TRUE, FALSE
DELAY_SRC => "IDATAIN", -- IDATAIN, DATAIN
HIGH_PERFORMANCE_MODE => "TRUE", -- TRUE, FALSE
IDELAY_TYPE => "VARIABLE", -- FIXED, VARIABLE, or VAR_LOADABLE
IDELAY_VALUE => kDelayTaps,
REFCLK_FREQUENCY => kRefClkFreqInMHz,
PIPE_SEL => "FALSE",
SIGNAL_PATTERN => "DATA") -- CLOCK, DATA
port map (
DATAOUT => DataInDly, -- Delayed signal
DATAIN => '0', -- Not used; IDATAIN instead
C => CtlClk, -- Clock for control signals (CE,INC...)
CE => cIDLY_CE,
INC => cIDLY_INC,
IDATAIN => aHSIn, -- Driven by IOB
LD => cIDLY_LD,
REGRST => '0', --not used in VARIABLE mode
LDPIPEEN => '0',
CNTVALUEIN => "00000", --not used in VARIABLE mode
CNTVALUEOUT => cIDLY_CNT, -- current tap value
CINVCTRL => '0');
assert (not kIs8b9b) report "8b9b encoding not supported yet" severity failure;
--Invert locally for ISERDESE2
SerClkInv <= not SerClk;
-- De-serializer, 1:8 DDR, non-cascaded,
-- Least-significant first: bit sent first should be bit(0) in PPI byte
Deserializer: ISERDESE2
generic map (
DATA_RATE => "DDR",
DATA_WIDTH => 8,
INTERFACE_TYPE => "NETWORKING",
DYN_CLKDIV_INV_EN => "FALSE",
DYN_CLK_INV_EN => "FALSE",
NUM_CE => 1,
OFB_USED => "FALSE",
IOBDELAY => "IFD", -- Use input at DDLY to output the data on Q1-Q6
SERDES_MODE => "MASTER",
INIT_Q1 => '0',
INIT_Q2 => '0',
INIT_Q3 => '0',
INIT_Q4 => '0',
SRVAL_Q1 => '0',
SRVAL_Q2 => '0',
SRVAL_Q3 => '0',
SRVAL_Q4 => '0')
port map (
Q1 => dDataIn_int(0),
Q2 => dDataIn_int(1),
Q3 => dDataIn_int(2),
Q4 => dDataIn_int(3),
Q5 => dDataIn_int(4),
Q6 => dDataIn_int(5),
Q7 => dDataIn_int(6),
Q8 => dDataIn_int(7), -- bit sent first
SHIFTOUT1 => open, -- Cascade connection to Slave ISERDES
SHIFTOUT2 => open, -- Cascade connection to Slave ISERDES
BITSLIP => '0', -- 1-bit Invoke Bitslip. This can be used with any
CE1 => '1', -- 1-bit Clock enable input
CE2 => '1', -- 1-bit Clock enable input
CLK => SerClk, -- Fast Source Synchronous SERDES clock from BUFIO
CLKB => SerClkInv, -- Locally inverted clock
CLKDIV => DivClk, -- Slow clock driven by BUFR
CLKDIVP => '0', --Not used here
D => '0',
DDLY => DataInDly, -- 1-bit Input signal from IODELAYE1.
RST => dSerdesRst, -- 1-bit Asynchronous reset only.
SHIFTIN1 => '0',
SHIFTIN2 => '0',
-- unused connections
DYNCLKDIVSEL => '0',
DYNCLKSEL => '0',
OFB => '0',
OCLK => '0',
OCLKB => '0',
O => open); -- unregistered output of ISERDESE1
-- We need a reset bridge to use the asynchronous aRst signal to reset our
-- ISERDESE2
SerdesReset: entity work.ResetBridge
generic map (
kPolarity => '1')
port map (
aRst => aRst,
OutClk => DivClk,
oRst => dSerdesRst);
-- We do not have a lot of time to bring aSettled into the DivClk domain
-- T_HS_SETTLE_max = 145ns + 10*UI
-- T_HS_SETTLE_min = 85ns + 6*UI
-- aSettled measures 85ns, and we synchronize it with only one flip-flop
-- dSettled should be used downstream in simple combinational logic only
SyncAsyncSettled: entity work.SyncAsync
generic map (
kResetTo => '0',
kStages => 1) --see above
port map (
aReset => not aSettled,
aIn => '1',
OutClk => DivClk,
oOut => dSettled);
-- LP de-serializer, 1:8 DDR, non-cascaded,
-- Although LP signals are low-speed and not synchronous with the HS clock, we need to detect LP
-- state changes as soon as possible due to tight timing between LP states and HS start.
UseOwnLP: if not kNoLP generate
LPxx: for i in 0 to 1 generate
LP_DeserializerX: ISERDESE2
generic map (
DATA_RATE => "DDR",
DATA_WIDTH => 8,
INTERFACE_TYPE => "NETWORKING",
DYN_CLKDIV_INV_EN => "FALSE",
DYN_CLK_INV_EN => "FALSE",
NUM_CE => 1,
OFB_USED => "FALSE",
IOBDELAY => "NONE", -- combinatorial output = D, registered output = D
SERDES_MODE => "MASTER",
INIT_Q1 => '1',
INIT_Q2 => '1',
INIT_Q3 => '1',
INIT_Q4 => '1',
SRVAL_Q1 => '1',
SRVAL_Q2 => '1',
SRVAL_Q3 => '1',
SRVAL_Q4 => '1')
port map (
Q1 => dLP(i)(0),
Q2 => dLP(i)(1),
Q3 => dLP(i)(2),
Q4 => dLP(i)(3),
Q5 => dLP(i)(4),
Q6 => dLP(i)(5),
Q7 => dLP(i)(6),
Q8 => dLP(i)(7), -- bit sent first
SHIFTOUT1 => open, -- Cascade connection to Slave ISERDES
SHIFTOUT2 => open, -- Cascade connection to Slave ISERDES
BITSLIP => '0', -- 1-bit Invoke Bitslip. This can be used with any
CE1 => '1', -- 1-bit Clock enable input
CE2 => '1', -- 1-bit Clock enable input
CLK => SerClk, -- Fast Source Synchronous SERDES clock from BUFIO
CLKB => SerClkInv, -- Locally inverted clock
CLKDIV => DivClk, -- Slow clock driven by BUFR
CLKDIVP => '0', --Not used here
D => aLPIn(i),
DDLY => '0', -- 1-bit Input signal from IODELAYE1.
RST => dSerdesRst, -- 1-bit Asynchronous reset only.
SHIFTIN1 => '0',
SHIFTIN2 => '0',
-- unused connections
DYNCLKDIVSEL => '0',
DYNCLKSEL => '0',
OFB => '0',
OCLK => '0',
OCLKB => '0',
O => aLPOut(i)); -- unregistered output of ISERDESE1
end generate LPxx;
dLP0_out <= dLP(0);
dLP1_out <= dLP(1);
end generate UseOwnLP;
ShareLPFromOtherLane: if kNoLP generate
dLP(0) <= dLP0_in;
dLP(1) <= dLP1_in;
aLPOut <= aLPIn;
end generate ShareLPFromOtherLane;
-- We are in Bridge (or HS) state when we sampled 0 at least 2 times on both LP1 on and LP0
-- TODO: glitch filtering? problematic, because serial clock frequency changes dynamically
dLPBridge <= '1' when dLP(0)(1 downto 0) = "00" and dLP(1)(1 downto 0) = "00" else
'0';
-- We are in Stop state when we sampled 1 at least 2 times on both LP1 on and LP0
-- TODO: glitch filtering? problematic, because serial clock frequency changes dynamically
dLPStop <= '1' when dLP(0)(1 downto 0) = "11" and dLP(1)(1 downto 0) = "11" else
'0';
-- Logic should be held in reset for one more period, because ISERDES output
-- is only valid starting from the second DivClk period
process(DivClk, dSerdesRst)
variable dSerdesRst_q : std_logic;
begin
if (dSerdesRst = '1') then
dLogicRst <= '1';
dSerdesRst_q := '1';
elsif Rising_Edge(DivClk) then
if (dSerdesRst_q = '0' and dSettled = '1') then
dLogicRst <= '0';
elsif (dValid_reg(3) = '0') then
dLogicRst <= '1';
end if;
dSerdesRst_q := dSerdesRst;
end if;
end process;
-------------------------------------------------------------
-- Buffer data to detect sync sequence early enough
-------------------------------------------------------------
DataPipeline: process(DivClk)
begin
if Rising_Edge(DivClk) then
if dLogicRst = '1' then
dDataIn_reg <= (others => (others => '0'));
else
for i in dDataIn_reg'low to dDataIn_reg'high-1 loop
dDataIn_reg(i+1) <= dDataIn_reg(i);
end loop;
dDataIn_reg(0) <= dDataIn_int;
end if;
end if;
end process;
AlignFlagPipeline: process(DivClk)
begin
if Rising_Edge(DivClk) then
if dLogicRst = '1' then
dValid_reg <= (others => '0');
else
for i in 2 to dValid_reg'high-1 loop
dValid_reg(i+1) <= dValid_reg(i);
end loop;
dValid_reg(2) <= (dSyncHard_int or dSyncSoft_int) and not dLPStop;
end if;
end if;
end process;
wordToAlign <= dDataIn_reg(1) & dDataIn_reg(0);
process(DivClk)
variable nextMust : boolean;
variable hard, soft : std_logic;
variable alignment : natural range 0 to 7;
begin
if Rising_Edge(DivClk) then
if (dLogicRst = '1') then
dSyncHard_int <= '0';
dSyncSoft_int <= '0';
dAlignment_int <= 0;
dSyncErr_int <= '0';
nextMust := false;
elsif (dSyncHard_int = '0' and dSyncSoft_int = '0' and dSyncErr_int = '0') then
--If we are seeing ones in the early part of the word, or we saw ones in the latter part of the
--word in the previous period, we must find a sequence or error out
if (dDataIn_reg(0)(7 downto 4) /= "0000" or nextMust) then
findMatch(kSyncSeq, wordToAlign, hard, soft, alignment);
if (hard = '0' and soft = '0') then
dSyncErr_int <= '1';
end if;
dSyncHard_int <= hard;
dSyncSoft_int <= soft;
dAlignment_int <= alignment;
end if;
--If we are seeing ones, we must find the sequence in the next period
if (dDataIn_reg(0)(3 downto 0) /= "0000") then
nextMust := true;
end if;
end if;
end if;
end process;
dSyncErr <= dSyncErr_int;
dSyncHard <= dSyncHard_int;
dSyncSoft <= dSyncSoft_int;
-------------------------------------------------------------
-- Since the sync sequence is short and it is immediately followed by data, using
-- bitslip is out of question because it is slow and would lead to the loss of the first
-- words in the transmission
-------------------------------------------------------------
WordAlignment: process(DivClk)
constant kPos : natural := 3;
variable delay : natural range 0 to kPos := kPos;
begin
if Rising_Edge(DivClk) then
if (dValid_reg(kPos) = '0' or dLogicRst = '1') then
dDataOut8 <= (others => '0');
dValid <= '0';
else
case (dAlignment_int) is
-- 76543210|76543210|76543210
-- 00000000|00011101|abcdefgh
when 0 =>
dDataOut8 <= dDataIn_reg(kPos-1);
-- 00000000|0011101a|bcdefgha
when 1 =>
dDataOut8 <= dDataIn_reg(kPos)(0 downto 0) & dDataIn_reg(kPos-1)(7 downto 1);
-- 00000000|011101ab|cdefghab
when 2 =>
dDataOut8 <= dDataIn_reg(kPos)(1 downto 0) & dDataIn_reg(kPos-1)(7 downto 2);
-- 00000000|11101abc|defghabc
when 3 =>
dDataOut8 <= dDataIn_reg(kPos)(2 downto 0) & dDataIn_reg(kPos-1)(7 downto 3);
-- 00000001|1101abcd|efghabcd
when 4 =>
dDataOut8 <= dDataIn_reg(kPos)(3 downto 0) & dDataIn_reg(kPos-1)(7 downto 4);
-- 00000011|101abcde|fghabcde
when 5 =>
dDataOut8 <= dDataIn_reg(kPos)(4 downto 0) & dDataIn_reg(kPos-1)(7 downto 5);
-- 00000111|01abcdef|ghabcdef
when 6 =>
dDataOut8 <= dDataIn_reg(kPos)(5 downto 0) & dDataIn_reg(kPos-1)(7 downto 6);
-- 00001110|1abcdefg|habcdefg
when 7 =>
dDataOut8 <= dDataIn_reg(kPos)(6 downto 0) & dDataIn_reg(kPos-1)(7 downto 7);
end case;
dValid <= dValid_reg(kPos);
end if;
end if;
end process;
end Behavioral;
@@ -1,105 +1,105 @@
-------------------------------------------------------------------------------
--
-- File: InputBuffer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module instantiates the input buffers of the required I/O standard
-- for the LP(1:0) and HS pins. The D-PHY lane is expected to be connected
-- to the FPGA according to Xilinx App Note 894:
-- http://www.xilinx.com/support/documentation/application_notes/xapp894-d-phy-solutions.pdf
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity InputBuffer is
Generic (
kNoLP : boolean := false
);
Port (
HS_p : in std_logic;
HS_n : in std_logic;
LP_n : in std_logic;
LP_p : in std_logic;
aHS : out std_logic;
aLP : out std_logic_vector(1 downto 0)
);
end InputBuffer;
architecture Behavioral of InputBuffer is
begin
LaneHighSpeed: IBUFDS
generic map (
DIFF_TERM => FALSE, -- Differential Termination
IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "LVDS_25")
port map (
O => aHS, -- Buffer output
I => HS_p, -- Diff_p buffer input (connect directly to top-level port)
IB => HS_n -- Diff_n buffer input (connect directly to top-level port)
);
LaneWithLP: if not kNoLP generate
LaneLowPower0: IBUF
generic map (
IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "HSUL_12")
port map (
O => aLP(0), -- Buffer output
I => LP_n -- Buffer input (connect directly to top-level port)
);
LaneLowPower1: IBUF
generic map (
IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "HSUL_12")
port map (
O => aLP(1), -- Buffer output
I => LP_p -- Buffer input (connect directly to top-level port)
);
end generate LaneWithLP;
LaneWithoutLP: if kNoLP generate
aLP <= "11";
end generate LaneWithoutLP;
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: InputBuffer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module instantiates the input buffers of the required I/O standard
-- for the LP(1:0) and HS pins. The D-PHY lane is expected to be connected
-- to the FPGA according to Xilinx App Note 894:
-- http://www.xilinx.com/support/documentation/application_notes/xapp894-d-phy-solutions.pdf
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
library UNISIM;
use UNISIM.VComponents.all;
entity InputBuffer is
Generic (
kNoLP : boolean := false
);
Port (
HS_p : in std_logic;
HS_n : in std_logic;
LP_n : in std_logic;
LP_p : in std_logic;
aHS : out std_logic;
aLP : out std_logic_vector(1 downto 0)
);
end InputBuffer;
architecture Behavioral of InputBuffer is
begin
LaneHighSpeed: IBUFDS
generic map (
DIFF_TERM => FALSE, -- Differential Termination
IBUF_LOW_PWR => FALSE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "LVDS_25")
port map (
O => aHS, -- Buffer output
I => HS_p, -- Diff_p buffer input (connect directly to top-level port)
IB => HS_n -- Diff_n buffer input (connect directly to top-level port)
);
LaneWithLP: if not kNoLP generate
LaneLowPower0: IBUF
generic map (
IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "HSUL_12")
port map (
O => aLP(0), -- Buffer output
I => LP_n -- Buffer input (connect directly to top-level port)
);
LaneLowPower1: IBUF
generic map (
IBUF_LOW_PWR => TRUE, -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards
IOSTANDARD => "HSUL_12")
port map (
O => aLP(1), -- Buffer output
I => LP_p -- Buffer input (connect directly to top-level port)
);
end generate LaneWithLP;
LaneWithoutLP: if kNoLP generate
aLP <= "11";
end generate LaneWithoutLP;
end Behavioral;
@@ -1,38 +1,38 @@
###############################################################################
##
## File: MIPI_DPHY_Receiver.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
#Associate IDELAYCTRL with IDELAYE2 primitives
set_property IODELAY_GROUP MIPI_DPHY [get_cells {*GenIDELAYCTRL.IDelayCtrlX *DPHY_LaneSFEN_X/HSDeserializerX/InputDelay *ClockLane/HSClockingX/InputDelay }]
### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR || NAME =~ *SyncAsync*/oSyncStages_reg[0]/D} -hier]
###############################################################################
##
## File: MIPI_DPHY_Receiver.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
#Associate IDELAYCTRL with IDELAYE2 primitives
set_property IODELAY_GROUP MIPI_DPHY [get_cells {*GenIDELAYCTRL.IDelayCtrlX *DPHY_LaneSFEN_X/HSDeserializerX/InputDelay *ClockLane/HSClockingX/InputDelay }]
### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ *SyncAsync*/oSyncStages*/PRE || NAME =~ *SyncAsync*/oSyncStages*/CLR || NAME =~ *SyncAsync*/oSyncStages_reg[0]/D} -hier]
#set_false_path -through [get_pins -filter {NAME =~ *SyncBase*/iIn_q*/PRE || NAME =~ *SyncBase*/iIn_q*/CLR} -hier]
@@ -1,41 +1,41 @@
###############################################################################
##
## File: MIPI_DPHY_Receiver_clocks.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# setup, hold = 0.15*UI = 0.75ns
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -min -add_delay 0.750 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -max -add_delay 4.250 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -min -add_delay 0.750 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -max -add_delay 4.250 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -min -add_delay 0.750 [get_ports {dphy_data_hs_p[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -max -add_delay 4.250 [get_ports {dphy_data_hs_p[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -min -add_delay 0.750 [get_ports {dphy_data_hs_p[*]}]
###############################################################################
##
## File: MIPI_DPHY_Receiver_clocks.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# setup, hold = 0.15*UI = 0.75ns
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -min -add_delay 0.750 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -max -add_delay 4.250 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -min -add_delay 0.750 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -max -add_delay 4.250 [get_ports {dphy_data_hs_n[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -min -add_delay 0.750 [get_ports {dphy_data_hs_p[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -clock_fall -max -add_delay 4.250 [get_ports {dphy_data_hs_p[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -min -add_delay 0.750 [get_ports {dphy_data_hs_p[*]}]
set_input_delay -clock [get_clocks -of_objects [get_ports dphy_clk_hs_p]] -max -add_delay 4.250 [get_ports {dphy_data_hs_p[*]}]
@@ -1,34 +1,34 @@
###############################################################################
##
## File: MIPI_DPHY_Receiver_ooc.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# Example 200Mbps data rate per lane UI = 5ns
###############################################################################
##
## File: MIPI_DPHY_Receiver_ooc.xdc
## Author: Elod Gyorgy
## Original Project: MIPI D-PHY Receiver IP
## Date: 15 December 2017
##
###############################################################################
##MIT License
##
##Copyright (c) 2016 Digilent
##
##Permission is hereby granted, free of charge, to any person obtaining a copy
##of this software and associated documentation files (the "Software"), to deal
##in the Software without restriction, including without limitation the rights
##to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
##copies of the Software, and to permit persons to whom the Software is
##furnished to do so, subject to the following conditions:
##
##The above copyright notice and this permission notice shall be included in all
##copies or substantial portions of the Software.
##
##THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
##IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
##FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
##AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
##LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
##OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
##SOFTWARE.
##
###############################################################################
# Example 200Mbps data rate per lane UI = 5ns
create_clock -period 10.000 -name dphy_clk_hs_p -waveform {0.000 5.000} [get_ports dphy_clk_hs_p]
@@ -1,385 +1,385 @@
-------------------------------------------------------------------------------
--
-- File: InputBuffer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MIPI_DPHY_Receiver_S_AXI_Lite is
generic (
-- Users to add parameters here
kVersionMajor : natural := 0;
kVersionMinor : natural := 0;
-- User parameters ends
-- Do not modify the parameters beyond this line
-- Width of S_AXI data bus
C_S_AXI_DATA_WIDTH : integer := 32;
-- Width of S_AXI address bus
C_S_AXI_ADDR_WIDTH : integer := 4
);
port (
-- Users to add ports here
xEnable : out std_logic;
xRst : out std_logic;
-- User ports ends
-- Do not modify the ports beyond this line
-- Global Clock Signal
S_AXI_ACLK : in std_logic;
-- Global Reset Signal. This Signal is Active LOW
S_AXI_ARESETN : in std_logic;
-- Write address (issued by master, acceped by Slave)
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Write channel Protection type. This signal indicates the
-- privilege and security level of the transaction, and whether
-- the transaction is a data access or an instruction access.
S_AXI_AWPROT : in std_logic_vector(2 downto 0);
-- Write address valid. This signal indicates that the master signaling
-- valid write address and control information.
S_AXI_AWVALID : in std_logic;
-- Write address ready. This signal indicates that the slave is ready
-- to accept an address and associated control signals.
S_AXI_AWREADY : out std_logic;
-- Write data (issued by master, acceped by Slave)
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Write strobes. This signal indicates which byte lanes hold
-- valid data. There is one write strobe bit for each eight
-- bits of the write data bus.
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
-- Write valid. This signal indicates that valid write
-- data and strobes are available.
S_AXI_WVALID : in std_logic;
-- Write ready. This signal indicates that the slave
-- can accept the write data.
S_AXI_WREADY : out std_logic;
-- Write response. This signal indicates the status
-- of the write transaction.
S_AXI_BRESP : out std_logic_vector(1 downto 0);
-- Write response valid. This signal indicates that the channel
-- is signaling a valid write response.
S_AXI_BVALID : out std_logic;
-- Response ready. This signal indicates that the master
-- can accept a write response.
S_AXI_BREADY : in std_logic;
-- Read address (issued by master, acceped by Slave)
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Protection type. This signal indicates the privilege
-- and security level of the transaction, and whether the
-- transaction is a data access or an instruction access.
S_AXI_ARPROT : in std_logic_vector(2 downto 0);
-- Read address valid. This signal indicates that the channel
-- is signaling valid read address and control information.
S_AXI_ARVALID : in std_logic;
-- Read address ready. This signal indicates that the slave is
-- ready to accept an address and associated control signals.
S_AXI_ARREADY : out std_logic;
-- Read data (issued by slave)
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Read response. This signal indicates the status of the
-- read transfer.
S_AXI_RRESP : out std_logic_vector(1 downto 0);
-- Read valid. This signal indicates that the channel is
-- signaling the required read data.
S_AXI_RVALID : out std_logic;
-- Read ready. This signal indicates that the master can
-- accept the read data and response information.
S_AXI_RREADY : in std_logic
);
end MIPI_DPHY_Receiver_S_AXI_Lite;
architecture arch_imp of MIPI_DPHY_Receiver_S_AXI_Lite is
constant kCTRL_EN : natural := 1;
constant kCTRL_RST : natural := 0;
constant kVersion : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(kVersionMajor,16)) & std_logic_vector(to_unsigned(kVersionMinor,16));
-- AXI4LITE signals
signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_awready : std_logic;
signal axi_wready : std_logic;
signal axi_bresp : std_logic_vector(1 downto 0);
signal axi_bvalid : std_logic;
signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_arready : std_logic;
signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal axi_rresp : std_logic_vector(1 downto 0);
signal axi_rvalid : std_logic;
-- Example-specific design signals
-- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
-- ADDR_LSB is used for addressing 32/64 bit registers/memories
-- ADDR_LSB = 2 for 32 bits (n downto 2)
-- ADDR_LSB = 3 for 64 bits (n downto 3)
constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
constant OPT_MEM_ADDR_BITS : integer := 1;
------------------------------------------------
---- Signals for user logic register space example
--------------------------------------------------
---- Number of Slave Registers 1
signal control_reg :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg_rden : std_logic;
signal slv_reg_wren : std_logic;
signal reg_data_out :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal byte_index : integer;
begin
-- I/O Connections assignments
S_AXI_AWREADY <= axi_awready;
S_AXI_WREADY <= axi_wready;
S_AXI_BRESP <= axi_bresp;
S_AXI_BVALID <= axi_bvalid;
S_AXI_ARREADY <= axi_arready;
S_AXI_RDATA <= axi_rdata;
S_AXI_RRESP <= axi_rresp;
S_AXI_RVALID <= axi_rvalid;
-- Implement axi_awready generation
-- axi_awready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awready <= '0';
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- slave is ready to accept write address when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_awready <= '1';
else
axi_awready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_awaddr latching
-- This process is used to latch the address when both
-- S_AXI_AWVALID and S_AXI_WVALID are valid.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awaddr <= (others => '0');
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end if;
end if;
end if;
end process;
-- Implement axi_wready generation
-- axi_wready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_wready <= '0';
else
if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1') then
-- slave is ready to accept write data when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_wready <= '1';
else
axi_wready <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and write logic generation
-- The write data is accepted and written to memory mapped registers when
-- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
-- select byte enables of slave registers while writing.
-- These registers are cleared when reset (active low) is applied.
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
control_reg <= (kCTRL_RST => '0', kCTRL_EN => '1', others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"00" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
control_reg(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when others =>
control_reg <= control_reg;
end case;
end if;
end if;
end if;
end process;
-- Implement write response logic generation
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_bvalid <= '0';
axi_bresp <= "00"; --need to work more on the responses
else
if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then
axi_bvalid <= '1';
axi_bresp <= "00";
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high)
axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high)
end if;
end if;
end if;
end process;
-- Implement axi_arready generation
-- axi_arready is asserted for one S_AXI_ACLK clock cycle when
-- S_AXI_ARVALID is asserted. axi_awready is
-- de-asserted when reset (active low) is asserted.
-- The read address is also latched when S_AXI_ARVALID is
-- asserted. axi_araddr is reset to zero on reset assertion.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_arready <= '0';
axi_araddr <= (others => '1');
else
if (axi_arready = '0' and S_AXI_ARVALID = '1') then
-- indicates that the slave has acceped the valid read address
axi_arready <= '1';
-- Read Address latching
axi_araddr <= S_AXI_ARADDR;
else
axi_arready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_arvalid generation
-- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_ARVALID and axi_arready are asserted. The slave registers
-- data are available on the axi_rdata bus at this instance. The
-- assertion of axi_rvalid marks the validity of read data on the
-- bus and axi_rresp indicates the status of read transaction.axi_rvalid
-- is deasserted on reset (active low). axi_rresp and axi_rdata are
-- cleared to zero on reset (active low).
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_rvalid <= '0';
axi_rresp <= "00";
else
if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
-- Valid read data is available at the read data bus
axi_rvalid <= '1';
axi_rresp <= "00"; -- 'OKAY' response
elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
-- Read data is accepted by the master
axi_rvalid <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and read logic generation
-- Slave register read enable is asserted when valid address is available
-- and the slave is ready to accept the read address.
slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
process (control_reg, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
-- Address decoding for reading registers
loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
case loc_addr is
when b"00" =>
reg_data_out <= control_reg;
when b"11" =>
reg_data_out <= kVersion;
when others =>
reg_data_out <= (others => '0');
end case;
end process;
-- Output register or memory read data
process( S_AXI_ACLK ) is
begin
if (rising_edge (S_AXI_ACLK)) then
if ( S_AXI_ARESETN = '0' ) then
axi_rdata <= (others => '0');
else
if (slv_reg_rden = '1') then
-- When there is a valid read address (S_AXI_ARVALID) with
-- acceptance of read address by the slave (axi_arready),
-- output the read dada
-- Read address mux
axi_rdata <= reg_data_out; -- register read data
end if;
end if;
end if;
end process;
-- Add user logic here
xEnable <= control_reg(kCTRL_EN);
xRst <= control_reg(kCTRL_RST);
-- User logic ends
end arch_imp;
-------------------------------------------------------------------------------
--
-- File: InputBuffer.vhd
-- Author: Elod Gyorgy
-- Original Project: MIPI D-PHY Receiver IP
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MIPI_DPHY_Receiver_S_AXI_Lite is
generic (
-- Users to add parameters here
kVersionMajor : natural := 0;
kVersionMinor : natural := 0;
-- User parameters ends
-- Do not modify the parameters beyond this line
-- Width of S_AXI data bus
C_S_AXI_DATA_WIDTH : integer := 32;
-- Width of S_AXI address bus
C_S_AXI_ADDR_WIDTH : integer := 4
);
port (
-- Users to add ports here
xEnable : out std_logic;
xRst : out std_logic;
-- User ports ends
-- Do not modify the ports beyond this line
-- Global Clock Signal
S_AXI_ACLK : in std_logic;
-- Global Reset Signal. This Signal is Active LOW
S_AXI_ARESETN : in std_logic;
-- Write address (issued by master, acceped by Slave)
S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Write channel Protection type. This signal indicates the
-- privilege and security level of the transaction, and whether
-- the transaction is a data access or an instruction access.
S_AXI_AWPROT : in std_logic_vector(2 downto 0);
-- Write address valid. This signal indicates that the master signaling
-- valid write address and control information.
S_AXI_AWVALID : in std_logic;
-- Write address ready. This signal indicates that the slave is ready
-- to accept an address and associated control signals.
S_AXI_AWREADY : out std_logic;
-- Write data (issued by master, acceped by Slave)
S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Write strobes. This signal indicates which byte lanes hold
-- valid data. There is one write strobe bit for each eight
-- bits of the write data bus.
S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0);
-- Write valid. This signal indicates that valid write
-- data and strobes are available.
S_AXI_WVALID : in std_logic;
-- Write ready. This signal indicates that the slave
-- can accept the write data.
S_AXI_WREADY : out std_logic;
-- Write response. This signal indicates the status
-- of the write transaction.
S_AXI_BRESP : out std_logic_vector(1 downto 0);
-- Write response valid. This signal indicates that the channel
-- is signaling a valid write response.
S_AXI_BVALID : out std_logic;
-- Response ready. This signal indicates that the master
-- can accept a write response.
S_AXI_BREADY : in std_logic;
-- Read address (issued by master, acceped by Slave)
S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
-- Protection type. This signal indicates the privilege
-- and security level of the transaction, and whether the
-- transaction is a data access or an instruction access.
S_AXI_ARPROT : in std_logic_vector(2 downto 0);
-- Read address valid. This signal indicates that the channel
-- is signaling valid read address and control information.
S_AXI_ARVALID : in std_logic;
-- Read address ready. This signal indicates that the slave is
-- ready to accept an address and associated control signals.
S_AXI_ARREADY : out std_logic;
-- Read data (issued by slave)
S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
-- Read response. This signal indicates the status of the
-- read transfer.
S_AXI_RRESP : out std_logic_vector(1 downto 0);
-- Read valid. This signal indicates that the channel is
-- signaling the required read data.
S_AXI_RVALID : out std_logic;
-- Read ready. This signal indicates that the master can
-- accept the read data and response information.
S_AXI_RREADY : in std_logic
);
end MIPI_DPHY_Receiver_S_AXI_Lite;
architecture arch_imp of MIPI_DPHY_Receiver_S_AXI_Lite is
constant kCTRL_EN : natural := 1;
constant kCTRL_RST : natural := 0;
constant kVersion : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(kVersionMajor,16)) & std_logic_vector(to_unsigned(kVersionMinor,16));
-- AXI4LITE signals
signal axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_awready : std_logic;
signal axi_wready : std_logic;
signal axi_bresp : std_logic_vector(1 downto 0);
signal axi_bvalid : std_logic;
signal axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0);
signal axi_arready : std_logic;
signal axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal axi_rresp : std_logic_vector(1 downto 0);
signal axi_rvalid : std_logic;
-- Example-specific design signals
-- local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
-- ADDR_LSB is used for addressing 32/64 bit registers/memories
-- ADDR_LSB = 2 for 32 bits (n downto 2)
-- ADDR_LSB = 3 for 64 bits (n downto 3)
constant ADDR_LSB : integer := (C_S_AXI_DATA_WIDTH/32)+ 1;
constant OPT_MEM_ADDR_BITS : integer := 1;
------------------------------------------------
---- Signals for user logic register space example
--------------------------------------------------
---- Number of Slave Registers 1
signal control_reg :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal slv_reg_rden : std_logic;
signal slv_reg_wren : std_logic;
signal reg_data_out :std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0);
signal byte_index : integer;
begin
-- I/O Connections assignments
S_AXI_AWREADY <= axi_awready;
S_AXI_WREADY <= axi_wready;
S_AXI_BRESP <= axi_bresp;
S_AXI_BVALID <= axi_bvalid;
S_AXI_ARREADY <= axi_arready;
S_AXI_RDATA <= axi_rdata;
S_AXI_RRESP <= axi_rresp;
S_AXI_RVALID <= axi_rvalid;
-- Implement axi_awready generation
-- axi_awready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awready <= '0';
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- slave is ready to accept write address when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_awready <= '1';
else
axi_awready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_awaddr latching
-- This process is used to latch the address when both
-- S_AXI_AWVALID and S_AXI_WVALID are valid.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_awaddr <= (others => '0');
else
if (axi_awready = '0' and S_AXI_AWVALID = '1' and S_AXI_WVALID = '1') then
-- Write Address latching
axi_awaddr <= S_AXI_AWADDR;
end if;
end if;
end if;
end process;
-- Implement axi_wready generation
-- axi_wready is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
-- de-asserted when reset is low.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_wready <= '0';
else
if (axi_wready = '0' and S_AXI_WVALID = '1' and S_AXI_AWVALID = '1') then
-- slave is ready to accept write data when
-- there is a valid write address and write data
-- on the write address and data bus. This design
-- expects no outstanding transactions.
axi_wready <= '1';
else
axi_wready <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and write logic generation
-- The write data is accepted and written to memory mapped registers when
-- axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
-- select byte enables of slave registers while writing.
-- These registers are cleared when reset (active low) is applied.
-- Slave register write enable is asserted when valid address and data are available
-- and the slave is ready to accept the write address and write data.
slv_reg_wren <= axi_wready and S_AXI_WVALID and axi_awready and S_AXI_AWVALID ;
process (S_AXI_ACLK)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
control_reg <= (kCTRL_RST => '0', kCTRL_EN => '1', others => '0');
else
loc_addr := axi_awaddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
if (slv_reg_wren = '1') then
case loc_addr is
when b"00" =>
for byte_index in 0 to (C_S_AXI_DATA_WIDTH/8-1) loop
if ( S_AXI_WSTRB(byte_index) = '1' ) then
-- Respective byte enables are asserted as per write strobes
-- slave registor 0
control_reg(byte_index*8+7 downto byte_index*8) <= S_AXI_WDATA(byte_index*8+7 downto byte_index*8);
end if;
end loop;
when others =>
control_reg <= control_reg;
end case;
end if;
end if;
end if;
end process;
-- Implement write response logic generation
-- The write response and response valid signals are asserted by the slave
-- when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.
-- This marks the acceptance of address and indicates the status of
-- write transaction.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_bvalid <= '0';
axi_bresp <= "00"; --need to work more on the responses
else
if (axi_awready = '1' and S_AXI_AWVALID = '1' and axi_wready = '1' and S_AXI_WVALID = '1' and axi_bvalid = '0' ) then
axi_bvalid <= '1';
axi_bresp <= "00";
elsif (S_AXI_BREADY = '1' and axi_bvalid = '1') then --check if bready is asserted while bvalid is high)
axi_bvalid <= '0'; -- (there is a possibility that bready is always asserted high)
end if;
end if;
end if;
end process;
-- Implement axi_arready generation
-- axi_arready is asserted for one S_AXI_ACLK clock cycle when
-- S_AXI_ARVALID is asserted. axi_awready is
-- de-asserted when reset (active low) is asserted.
-- The read address is also latched when S_AXI_ARVALID is
-- asserted. axi_araddr is reset to zero on reset assertion.
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_arready <= '0';
axi_araddr <= (others => '1');
else
if (axi_arready = '0' and S_AXI_ARVALID = '1') then
-- indicates that the slave has acceped the valid read address
axi_arready <= '1';
-- Read Address latching
axi_araddr <= S_AXI_ARADDR;
else
axi_arready <= '0';
end if;
end if;
end if;
end process;
-- Implement axi_arvalid generation
-- axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both
-- S_AXI_ARVALID and axi_arready are asserted. The slave registers
-- data are available on the axi_rdata bus at this instance. The
-- assertion of axi_rvalid marks the validity of read data on the
-- bus and axi_rresp indicates the status of read transaction.axi_rvalid
-- is deasserted on reset (active low). axi_rresp and axi_rdata are
-- cleared to zero on reset (active low).
process (S_AXI_ACLK)
begin
if rising_edge(S_AXI_ACLK) then
if S_AXI_ARESETN = '0' then
axi_rvalid <= '0';
axi_rresp <= "00";
else
if (axi_arready = '1' and S_AXI_ARVALID = '1' and axi_rvalid = '0') then
-- Valid read data is available at the read data bus
axi_rvalid <= '1';
axi_rresp <= "00"; -- 'OKAY' response
elsif (axi_rvalid = '1' and S_AXI_RREADY = '1') then
-- Read data is accepted by the master
axi_rvalid <= '0';
end if;
end if;
end if;
end process;
-- Implement memory mapped register select and read logic generation
-- Slave register read enable is asserted when valid address is available
-- and the slave is ready to accept the read address.
slv_reg_rden <= axi_arready and S_AXI_ARVALID and (not axi_rvalid) ;
process (control_reg, axi_araddr, S_AXI_ARESETN, slv_reg_rden)
variable loc_addr :std_logic_vector(OPT_MEM_ADDR_BITS downto 0);
begin
-- Address decoding for reading registers
loc_addr := axi_araddr(ADDR_LSB + OPT_MEM_ADDR_BITS downto ADDR_LSB);
case loc_addr is
when b"00" =>
reg_data_out <= control_reg;
when b"11" =>
reg_data_out <= kVersion;
when others =>
reg_data_out <= (others => '0');
end case;
end process;
-- Output register or memory read data
process( S_AXI_ACLK ) is
begin
if (rising_edge (S_AXI_ACLK)) then
if ( S_AXI_ARESETN = '0' ) then
axi_rdata <= (others => '0');
else
if (slv_reg_rden = '1') then
-- When there is a valid read address (S_AXI_ARVALID) with
-- acceptance of read address by the slave (axi_arready),
-- output the read dada
-- Read address mux
axi_rdata <= reg_data_out; -- register read data
end if;
end if;
end if;
end process;
-- Add user logic here
xEnable <= control_reg(kCTRL_EN);
xRst <= control_reg(kCTRL_RST);
-- User logic ends
end arch_imp;
@@ -1,82 +1,82 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2; --double sync by default
kResetPolarity : std_logic := '1'); --aReset active-high by default
Port (
aReset : in STD_LOGIC; -- active-high/active-low asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = kResetPolarity) then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsync.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module synchronizes the asynchronous signal (aIn) with the OutClk clock
-- domain and provides it on oOut. The number of FFs in the synchronizer chain
-- can be configured with kStages. The reset value for oOut can be configured
-- with kResetTo. The asynchronous reset (aReset) is always active-high.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity SyncAsync is
Generic (
kResetTo : std_logic := '0'; --value when reset and upon init
kStages : natural := 2; --double sync by default
kResetPolarity : std_logic := '1'); --aReset active-high by default
Port (
aReset : in STD_LOGIC; -- active-high/active-low asynchronous reset
aIn : in STD_LOGIC;
OutClk : in STD_LOGIC;
oOut : out STD_LOGIC);
end SyncAsync;
architecture Behavioral of SyncAsync is
signal oSyncStages : std_logic_vector(kStages-1 downto 0) := (others => kResetTo);
attribute ASYNC_REG : string;
attribute ASYNC_REG of oSyncStages: signal is "TRUE";
begin
Sync: process (OutClk, aReset)
begin
if (aReset = kResetPolarity) then
oSyncStages <= (others => kResetTo);
elsif Rising_Edge(OutClk) then
oSyncStages <= oSyncStages(oSyncStages'high-1 downto 0) & aIn;
end if;
end process Sync;
oOut <= oSyncStages(oSyncStages'high);
end Behavioral;
@@ -1,79 +1,79 @@
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
begin
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2,
kResetPolarity => kPolarity) --use double FF synchronizer
port map (
aReset => aRst,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;
-------------------------------------------------------------------------------
--
-- File: SyncAsyncReset.vhd
-- Author: Elod Gyorgy
-- Original Project: HDMI input on 7-series Xilinx FPGA
-- Date: 15 December 2017
--
-------------------------------------------------------------------------------
--MIT License
--
--Copyright (c) 2016 Digilent
--
--Permission is hereby granted, free of charge, to any person obtaining a copy
--of this software and associated documentation files (the "Software"), to deal
--in the Software without restriction, including without limitation the rights
--to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
--copies of the Software, and to permit persons to whom the Software is
--furnished to do so, subject to the following conditions:
--
--The above copyright notice and this permission notice shall be included in all
--copies or substantial portions of the Software.
--
--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
--IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
--FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
--AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
--LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
--OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
--SOFTWARE.
--
-------------------------------------------------------------------------------
--
-- Purpose:
-- This module is a reset-bridge. It takes a reset signal asynchronous to the
-- target clock domain (OutClk) and provides a safe asynchronous or synchronous
-- reset for the OutClk domain (oRst). The signal oRst is asserted immediately
-- as aRst arrives, but is de-asserted synchronously with the OutClk rising
-- edge. This means it can be used to safely reset any FF in the OutClk domain,
-- respecting recovery time specs for FFs.
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity ResetBridge is
Generic (
kPolarity : std_logic := '1');
Port (
aRst : in STD_LOGIC; -- asynchronous reset; active-high, if kPolarity=1
OutClk : in STD_LOGIC;
oRst : out STD_LOGIC);
end ResetBridge;
architecture Behavioral of ResetBridge is
begin
SyncAsyncx: entity work.SyncAsync
generic map (
kResetTo => kPolarity,
kStages => 2,
kResetPolarity => kPolarity) --use double FF synchronizer
port map (
aReset => aRst,
aIn => not kPolarity,
OutClk => OutClk,
oOut => oRst);
end Behavioral;

Some files were not shown because too many files have changed in this diff Show More