diff --git a/README.md b/README.md index 32d9944..351369a 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,79 @@ -# Vivado MODULE NAME +# AXI Stream compatible Skidbuffer in VHDL +--- -This repo contains scripts to recreate **DESCRIBE THE MODULE HERE**. The project is setup for Zedboard, although it would be easy to change to other boards assuming you have some basic TCL skills. +## AXI4 to AXIS converter -# Module/IP design +The purpose of the entire project is to build an IP core to convert the AXI4 write channel to AXIS interface. +To achieve this, the incomming AXI4 slave port must be registered. Registering a handshake bus protocol comes with the requirement for a skidbuffer. +See below for the details on the skidbuffer implementation. +Once the skidbuffer is operational, the AXI4 write channel can just be passed to an AXIS master interface (including handshake compatibility with `tready` and `wready` signals). +However, the AXI4 port still requires some additional features like aknowledging requests on the AW channel and sending positive write responses on the B channel (`bresp`). All of this is taken care of in this IP core. -Describe here your module interface and protocols. +### Features -![Place here a nice picture of your design](my-awesome-module.png) +- accepts `S_AXI4` write request handshakes on AW-channel + + accepts up to one additional AW request while a write burst is still in progress allowing for... + + back-to-back write transactions +- supports full AXI4 thorughput for burst transfers without wait cycles +- `S_AXI4` W to `M_AXIS` conversion +- supports `tready` backpressure forwarded to upstream `S_AXI4` (both `wready` and `awready`) +- `S_AXI4` write acknowledgement (`bresp` = OK) after burst transfer (after `tlast`) -# How to use this repository +![img/gtkwave_axi-to-axis.png](img/gtkwave_axi-to-axis.png) -These scripts presented here are quite reusable if you keep the same dir structure. It should be useful for other Vivado/SDK projects with minor efforts. For this reason this repository is a template. Just click in **Use this Template** button to replicate it for your own project. +--- +## Skidbuffer Idea -In command line, create an empty repository called ** in github and follow these steps to use it as a template: +### Passthrough Skid Buffer -``` -mkdir -cd -git clone https://github.com/amamory/vivado-base-project.git . -rm -rf .git -git init -git remote set-url origin https://github.com// -git add * .gitignore -git commit -m "my initial commit" -git push origin master -``` +Only the reply signal from downstream slave to upstream master (`tready`) is pipelined. -Each directory has instructions related to the kind of file you have to place in them. +All other signals from upstream master to downstream slave (`tvalid`, `tdata`, `tlast`) are *combinatorial*. +It therefore has 0 latency in the best case and maximum 1 clock cycle latency in case of a stall. +However, it increases combinatorial logic in the master -> slave path which can make it harder to meet timing requirements. -# How to run it +#### Schematic +![img/skidbuf_passthru.png](img/skidbuf_passthru.png) -These scripts are assuming Linux operation system (Ubuntu 18.04) and Vivado 2018.2. +#### Waveform +![img/skidbuf_passthru_wave.svg](img/skidbuf_passthru_wave.svg) +![img/gtkwave_passthru.png](img/gtkwave_passthru.png) -Follow these instructions to recreate the Vivado and SDK projects: - - Open the **build.sh** script and edit the first lines to setup these environment variables: - - **VIVADO**: path to the Vivado install dir; - - **VIVADO_DESIGN_NAME**: mandatory name of the design; - - **XIL_APP_NAME**: used only in projects with software; - - **VIVADO_TOP_NAME**: set the top name (optional). - - run *build.sh* +### Fully Pipelined Skid Buffer -These scripts will recreate the entire Vivado project, compile the design, generate the bitstream, export the hardware to SDK, create the SDK projects, import the source files, build all projects, and finally download both the bitstream and the elf application. Hopefully, all these steps will be executed automatically. +With registered outputs for all signals. +It therefore has a minimum latency of 1 clock cycle and a maximum of 2 clock cycles in case of a stall. +This is a pipeline register to help reach timing closure. -# How to update the scripts +#### Schematic +![img/skidbuf_fullreg.png](img/skidbuf_fullreg.png) -These scripts come from a template repository and they get updated and improved over time. If you wish to get the latest script version, then follow these steps: +#### Waveform +![img/skidbuf_fullreg_wave.svg](img/skidbuf_fullreg_wave.svg) +![img/gtkwave_fullreg.png](img/gtkwave_fullreg.png) +## Simulation + +Assuming `ghdl` and `gtkwave` installed on Windows. + +Run in powershell: + +```batch +.\compile.bat ``` -git remote add template https://github.com/amamory/vivado-base-project.git -git fetch --all -git merge --no-commit --no-ff template/master --allow-unrelated-histories -``` -Solve any conflict manually and then commit. +# Acknowledgements + +https://zipcpu.com/blog/2019/05/22/skidbuffer.html + + +### Anti-Acknowledgements + +This article did **NOT** help: it is confusing since the code does not match the schematic. -# Future work +https://www.itdev.co.uk/blog/pipelining-axi-buses-registered-ready-signals - - update the scripts to Vitis - - support or test with Windows (help required !!! :D ) +# Tools -# Credits +Simulated using GHDL 3.7 / implemented and tested with Xilinx Vivado 2021.2 -The scripts are based on the excellent scripts from [fpgadesigner](https://github.com/fpgadeveloper/zedboard-axi-dma) plus few increments from my own such as project generalization, support to SDK project creation and compilation and other minor improvements. diff --git a/build.sh b/build.sh deleted file mode 100755 index 2fe002d..0000000 --- a/build.sh +++ /dev/null @@ -1,85 +0,0 @@ -# Set these variables accordingly before executing the script -#export VIVADO=/opt/Xilinx/Vivado/2018.2/bin/vivado -export VIVADO=/home/lsa/xilinx/2018.2/Vivado/2018.2/bin/vivado -export VIVADO_DESIGN_NAME=skid_ip -export VIVADO_TOP_NAME=${VIVADO_DESIGN_NAME}_wrapper -export XIL_APP_NAME=dma_test - -if [ -f $VIVADO ]; then - echo "###################################" - echo "### Creating the Vivado Project ###" - echo "###################################" - $VIVADO -mode batch -source build.tcl -notrace - echo "#########################" - echo "######## Synthesis ######" - echo "#########################" - $VIVADO -mode batch -source build_bitstream_export_sdk.tcl -notrace - # count xml files to decide whether this project is a leaf custom IP or a design that uses custom IPs - # For instance, considering this command executed in the project root dir: - #$ find hw/ips/*/ -name *.xml - # This is a typical output of a design that uses 3 custom IPs - #hw/ips/hermes-router-axis-ip/hw/ips/hermes_router_axis_ip/component.xml - #hw/ips/m-axis-dip-ip/hw/ips/m_axis_dip_ip/component.xml - #hw/ips/s-axis-led-ip/hw/ips/s_axis_led_ip/component.xml - # However, a leaf custom IP (i.e. and IP that does not use other custom IPs) would have this kind of file tree - #hw/ips/axis_s_const/component.xml - # In summary, if the component.xml is found 3 dir layers below the root dir, then this project is a leaf custom IP - # if the component.xml is found in more than 3 dir layers, then this project uses custom IPs - # Finally, there is no component.xml at all under hw/ips, then this project does not use any custom IP - leafIPs=$(find hw/ips/*/ -maxdepth 1 -name *.xml | wc -l) - if [ "$leafIPs" -eq 0 ]; - then - echo "#########################" - echo "### Loading bitstream ###" - echo "#########################" - $VIVADO -mode batch -source download_bitstream.tcl -notrace - echo "#########################" - echo "### Bitstream loaded ####" - echo "#########################" - fi; - # check whether there is any software to be compiled, i.e., if there is any dir inside src/ - list_dirs=`ls -d ./src/*/ 2> /dev/null` - # build a bash list - has_software=($list_dirs) - # check if len(list) > 0 - if [ "${#has_software[@]}" -gt 0 ]; - then - echo "#########################" - echo "### Compiling w SDK ###" - echo "#########################" - xsct sdk.tcl - echo "####################################" - echo "### End of software compilation ###" - echo "####################################" - echo "execute the following command to launch SDK GUI" - echo "xsdk -workspace ./vivado/${VIVADO_DESIGN_NAME}/${VIVADO_DESIGN_NAME}.sdk/ -hwspec ./vivado/${VIVADO_DESIGN_NAME}/${VIVADO_DESIGN_NAME}.sdk/${VIVADO_DESIGN_NAME}.hdf" - echo "#########################" - echo "## Loading application ##" - echo "#########################" - xsct download_elf.tcl - echo "#########################" - echo "## Application loaded ###" - echo "#########################" - fi; -elif [ -f ~/.bash_aliases ]; then - echo "" - echo "###############################" - echo "### Failed to locate Vivado ###" - echo "###############################" - echo "" - echo "This script file 'build.sh' did not find Vivado installed in:" - echo "" - echo " $VIVADO" - echo "" - echo "Fix the problem by doing one of the following:" - echo "" - echo " 1. If you do not have this version of Vivado installed," - echo " please install it or download the project sources from" - echo " a commit of the Git repository that was intended for" - echo " your version of Vivado." - echo "" - echo " 2. If Vivado is installed in a different location on your" - echo " PC, please modify the first line of this batch file " - echo " to specify the correct location." - echo "" -fi diff --git a/build.tcl b/build.tcl deleted file mode 100644 index 653f3fc..0000000 --- a/build.tcl +++ /dev/null @@ -1,272 +0,0 @@ -# -# build.tcl: re-creating a Vivado project -# -#***************************************************************************************** - -# Check the version of Vivado used -set version_required "2018.2" -set vivado_dir $::env(XILINX_VIVADO) -if {[string first $version_required $vivado_dir] == -1} { - puts "###############################" - puts "### Failed to build project ###" - puts "###############################" - puts "This project was designed for use with Vivado $version_required." - puts "Please install Vivado $version_required, or download the project" - puts "sources from a commit of the Git repository that was intended for" - puts "your version of Vivado." - return -} - -if { ![info exists env(VIVADO_DESIGN_NAME)] } { - puts "ERROR: Please set the environment variable VIVADO_DESIGN_NAME before running the script" - return -} -set design_name $::env(VIVADO_DESIGN_NAME) -puts "Using design name: ${design_name}" - -if { ![info exists env(VIVADO_TOP_NAME)] } { - puts "WARNING: No top design defined. Using the default top name ${design_name}_wrapper" - set top_name ${design_name}_wrapper -} else { - set top_name $::env(VIVADO_TOP_NAME) - puts "Using top name: ${top_name}" -} - -# Set the reference directory for source file relative paths (by default the value is script directory path) -set origin_dir "." - -# Set the directory path for the original project from where this script was exported -set orig_proj_dir "[file normalize "$origin_dir/vivado/$design_name"]" - -# Create a fresh project -file delete -force ${orig_proj_dir} -file mkdir ${orig_proj_dir} -create_project -force $design_name $orig_proj_dir -part xc7z020clg484-1 - - -# Set the directory path for the new project -set proj_dir [get_property directory [current_project]] - -# Set project properties -set obj [current_project] -set_property -name "board_part" -value "em.avnet.com:zed:part0:1.4" -objects $obj -set_property -name "default_lib" -value "xil_defaultlib" -objects $obj -set_property -name "dsa.accelerator_binary_content" -value "bitstream" -objects $obj -set_property -name "dsa.accelerator_binary_format" -value "xclbin2" -objects $obj -set_property -name "dsa.board_id" -value "zed" -objects $obj -set_property -name "dsa.description" -value "Vivado generated DSA" -objects $obj -set_property -name "dsa.dr_bd_base_address" -value "0" -objects $obj -set_property -name "dsa.emu_dir" -value "emu" -objects $obj -set_property -name "dsa.flash_interface_type" -value "bpix16" -objects $obj -set_property -name "dsa.flash_offset_address" -value "0" -objects $obj -set_property -name "dsa.flash_size" -value "1024" -objects $obj -set_property -name "dsa.host_architecture" -value "x86_64" -objects $obj -set_property -name "dsa.host_interface" -value "pcie" -objects $obj -set_property -name "dsa.num_compute_units" -value "60" -objects $obj -set_property -name "dsa.platform_state" -value "pre_synth" -objects $obj -set_property -name "dsa.uses_pr" -value "1" -objects $obj -set_property -name "dsa.vendor" -value "xilinx" -objects $obj -set_property -name "dsa.version" -value "0.0" -objects $obj -set_property -name "enable_vhdl_2008" -value "1" -objects $obj -set_property -name "ip_cache_permissions" -value "read write" -objects $obj -set_property -name "ip_output_repo" -value "$proj_dir/${design_name}.cache/ip" -objects $obj -set_property -name "mem.enable_memory_map_generation" -value "1" -objects $obj -set_property -name "sim.central_dir" -value "$proj_dir/${design_name}.ip_user_files" -objects $obj -set_property -name "sim.ip.auto_export_scripts" -value "1" -objects $obj -set_property -name "simulator_language" -value "Mixed" -objects $obj -set_property -name "webtalk.xsim_launch_sim" -value "102" -objects $obj - -# set path to custom IPs -set_property ip_repo_paths ./hw/ips [current_project] -update_ip_catalog - - -# Create 'sources_1' fileset (if not found) -if {[string equal [get_filesets -quiet sources_1] ""]} { - create_fileset -srcset sources_1 -} - - -# Set 'sources_1' fileset properties -set obj [get_filesets sources_1] -set_property "top" "${top_name}" $obj - - -# Insert all the vhdl, sv, and verilog source files from ./hw/hdl into the project -set hdl_files [glob -nocomplain -directory $origin_dir/hw/hdl/ *{*.vhd,*.v,*.sv}*] -puts $hdl_files - -foreach hdl_file $hdl_files { - set file "[file normalize "$hdl_file"]" - add_files -quiet -fileset sources_1 $file - set file_obj [get_files -of_objects [get_filesets sources_1] $file] - set extension [string tolower [file extension $file]] - if {$extension == ".vhd"} { - set hdl_type "VHDL" - # this property is only valid for vhdl - set_property -name "library" -value "work" -objects $file_obj - } elseif {$extension == ".v"} { - set hdl_type "Verilog" - } elseif {$extension == ".sv"} { - set hdl_type "SystemVerilog" - } else { - puts "ERROR: HDL extension $extension is not supported" - return - } - set_property -name "file_type" -value $hdl_type -objects $file_obj -} - -# Import IP-XACT config files if they exist -# There are two situations where there will be subdirs inside hw/ips/: -# - this project is an IP project: In this case, the component.xml file -# will be in hw/ips//component.xml and this search will find -# the xml files -# - this project is using a custom IP: In this case, the subdirs inside -# hw/ips/ will be a git submodule of an IP repo. This structure -# is required when the command -# 'generate_target all [get_files ${design_name}.bd]' -# is executed to regenerate the IP's output products -set ip_files [glob -nocomplain -directory $origin_dir/hw/ips/ "**/*.xml"] -foreach ip_file $ip_files { - set file "[file normalize "$ip_file"]" - add_files -quiet -fileset sources_1 $file - set file_obj [get_files -of_objects [get_filesets sources_1] $file] - set_property -name "file_type" -value "IP-XACT" -objects $file_obj -} - - -# Create 'constrs_1' fileset (if not found) -if {[string equal [get_filesets -quiet constrs_1] ""]} { - create_fileset -constrset constrs_1 -} - -# Set 'constrs_1' fileset object -set obj [get_filesets constrs_1] - -# Add/Import constrs file and set constrs file properties -set constr_files [glob -nocomplain -directory $origin_dir/hw/xdc/ "*.xdc"] - -foreach constr_file $constr_files { - set file "[file normalize "$constr_file"]" - add_files -quiet -fileset $obj [list $file] - set file_obj [get_files -of_objects [get_filesets constrs_1] $file] - set_property -name "file_type" -value "XDC" -objects $file_obj - - # Set 'constrs_1' fileset properties - set obj [get_filesets constrs_1] - set_property -name "target_constrs_file" -value "[get_files $file]" -objects $obj - set_property -name "target_ucf" -value "[get_files $file]" -objects $obj -} - - -# Create 'sim_1' fileset (if not found) -if {[string equal [get_filesets -quiet sim_1] ""]} { - create_fileset -simset sim_1 -} - -# Set 'sim_1' fileset object -# Import testbenches, waveform files, etc if they exist -set obj [get_filesets sim_1] -set sim_files [glob -nocomplain -directory $origin_dir/hw/hdl/sim *{*.vhd,*.v,*.sv}*] - -# if there is a testbench, then add few more properties -if {[llength $sim_files] > 0} { - set_property -name "sim_mode" -value "post-implementation" -objects $obj - #TODO assuming the testbench name is tb. is it possible to find it out automatically ? - set_property -name "top" -value "tb" -objects $obj - set_property -name "top_lib" -value "xil_defaultlib" -objects $obj - - foreach sim_file $sim_files { - set file "[file normalize "$sim_file"]" - add_files -quiet -fileset sim_1 $file - set file_obj [get_files -of_objects [get_filesets sim_1] $file] - set extension [string tolower [file extension $file]] - if {$extension == ".vhd"} { - set hdl_type "VHDL" - } elseif {$extension == ".v"} { - set hdl_type "Verilog" - } elseif {$extension == ".sv"} { - set hdl_type "SystemVerilog" - } else { - puts "ERROR: HDL extension $extension is not supported" - return - } - set_property -name "file_type" -value $hdl_type -objects $file_obj - #TODO can i replace the lib by work ? - set_property -name "library" -value "work" -objects $file_obj - } -} - -# waveform files are simply added to the project. no property is set -set wcfg_files [glob -nocomplain -directory $origin_dir/hw/hdl/sim "*.wcfg"] -add_files -quiet -fileset sim_1 $wcfg_files - - -# Create 'synth_1' run (if not found) -if {[string equal [get_runs -quiet synth_1] ""]} { - create_run -name synth_1 -part xc7z020clg484-1 -flow {Vivado Synthesis 2018} -strategy "Vivado Synthesis Defaults" -constrset constrs_1 -} else { - set_property strategy "Vivado Synthesis Defaults" [get_runs synth_1] - set_property flow "Vivado Synthesis 2018" [get_runs synth_1] -} -set obj [get_runs synth_1] - -# set the current synth run -current_run -synthesis [get_runs synth_1] - -# Create 'impl_1' run (if not found) -if {[string equal [get_runs -quiet impl_1] ""]} { - create_run -name impl_1 -part xc7z020clg484-1 -flow {Vivado Implementation 2018} -strategy "Vivado Implementation Defaults" -constrset constrs_1 -parent_run synth_1 -} else { - set_property strategy "Vivado Implementation Defaults" [get_runs impl_1] - set_property flow "Vivado Implementation 2018" [get_runs impl_1] -} -set obj [get_runs impl_1] -set_property -name "steps.write_bitstream.args.readback_file" -value "0" -objects $obj -set_property -name "steps.write_bitstream.args.verbose" -value "0" -objects $obj - -# set the current impl run -current_run -implementation [get_runs impl_1] - -puts "INFO: Project created:${design_name}" - -# Prepare to create a block design -# CHECKING IF PROJECT EXISTS -if { [get_projects -quiet] eq "" } { - puts "ERROR: Please open or create a project!" - return 1 -} - - -# Find the block tcl script and create the block design -set block_files [glob -nocomplain -directory $origin_dir/hw/bd/ "*.tcl"] - -if {[llength $block_files] == 1} { - # Create and empty block design - create_bd_design $design_name - current_bd_design $design_name - source $block_files - create_root_design "" - - # Generate the wrapper - make_wrapper -files [get_files *${design_name}.bd] -top - # It is asuming that if there is a block file, its wrapper will be the top - add_files -norecurse ./vivado/${design_name}/${design_name}.srcs/sources_1/bd/${design_name}/hdl/${design_name}_wrapper.v -} elseif {[llength $block_files] > 1} { - puts "ERROR: multiple block files found. The script only supports one block per design" - return -} - -# Update the compile order -update_compile_order -fileset sources_1 -update_compile_order -fileset sim_1 - -# If this design is block-basedm then ensure parameter propagation has been performed -if {[llength $block_files] == 1} { - close_bd_design [current_bd_design] - open_bd_design [get_files ${design_name}.bd] - validate_bd_design -force - # generate target for IPs, includig the custom IPs - generate_target all [get_files ${design_name}.bd] - save_bd_design -} diff --git a/build_bitstream_export_sdk.tcl b/build_bitstream_export_sdk.tcl deleted file mode 100644 index ebec6ab..0000000 --- a/build_bitstream_export_sdk.tcl +++ /dev/null @@ -1,45 +0,0 @@ -if { ![info exists env(VIVADO_DESIGN_NAME)] } { - puts "Please set the environment variable VIVADO_DESIGN_NAME before running the script" - return -} -set design_name $::env(VIVADO_DESIGN_NAME) -puts "Using design name: ${design_name}" - -if { ![info exists env(VIVADO_TOP_NAME)] } { - puts "No top design defined. Using the default top name ${design_name}_wrapper" - set top_name ${design_name}_wrapper -} else { - set top_name $::env(VIVADO_TOP_NAME) - puts "Using top name: ${top_name}" -} - -# change here if you want to change the systhesis step. -# check the command 'launch_runs' learn more -# the valid steps are: -# - opt_design, power_opt_design, place_design, route_design, phys_opt_design, and write_bitstream -set systesis_step opt_design - -# Generate bitstream -open_project ./vivado/${design_name}/${design_name}.xpr -update_compile_order -fileset sources_1 -reset_run -quiet impl_1 -launch_runs impl_1 -to_step $systesis_step -jobs 8 -wait_on_run impl_1 - -# If the src dir has not apps to be compiled, then this is a hardware only project. -# no need to export the hardware to SDK and to run SDK -set app_list [glob -nocomplain -type d -dir src "*"] -if {[llength $app_list] != 0} { - # exporting hw design to SDK - file mkdir ./vivado/${design_name}/${design_name}.sdk - file copy -force ./vivado/${design_name}/${design_name}.runs/impl_1/${top_name}.sysdef ./vivado/${design_name}/${design_name}.sdk/${design_name}.hdf - puts "========================" - puts "Hardware exported to SDK" - puts "========================" -} else { - puts "===================================" - puts "There is no software to be compiled" - puts "===================================" -} - -close_design -quiet diff --git a/download_bitstream.tcl b/download_bitstream.tcl deleted file mode 100644 index d33edc6..0000000 --- a/download_bitstream.tcl +++ /dev/null @@ -1,27 +0,0 @@ -if { ![info exists env(VIVADO_DESIGN_NAME)] } { - puts "ERROR: Please set the environment variable VIVADO_DESIGN_NAME before running the script" - return -} -set design_name $::env(VIVADO_DESIGN_NAME) -puts "Using design name: ${design_name}" - -if { ![info exists env(VIVADO_TOP_NAME)] } { - puts "WARNING: No top design defined. Using the default top name ${design_name}_wrapper" - set top_name ${design_name}_wrapper -} else { - set top_name $::env(VIVADO_TOP_NAME) - puts "Using top name: ${top_name}" -} - -open_project vivado/${design_name}/${design_name}.xpr -update_compile_order -fileset sources_1 -open_hw -connect_hw_server -open_hw_target -set_property PROGRAM.FILE ./vivado/${design_name}/${design_name}.runs/impl_1/${top_name}.bit [get_hw_devices xc7z020_1] -current_hw_device [get_hw_devices xc7z020_1] -refresh_hw_device -update_hw_probes false [lindex [get_hw_devices xc7z020_1] 0] -set_property PROBES.FILE {} [get_hw_devices xc7z020_1] -set_property FULL_PROBES.FILE {} [get_hw_devices xc7z020_1] -program_hw_devices [get_hw_devices xc7z020_1] -#refresh_hw_device [lindex [get_hw_devices xc7z020_1] 0] diff --git a/download_elf.tcl b/download_elf.tcl deleted file mode 100644 index 82e0a1a..0000000 --- a/download_elf.tcl +++ /dev/null @@ -1,31 +0,0 @@ -if { ![info exists env(VIVADO_DESIGN_NAME)] } { - puts "ERROR: Please set the environment variable VIVADO_DESIGN_NAME before running the script" - return -} -set design_name $::env(VIVADO_DESIGN_NAME) -puts "Using design name: ${design_name}" - -# a design might have multiple applications. So the users must choose one to execute -if { ![info exists env(XIL_APP_NAME)] } { - puts "ERROR: Please set the environment variable XIL_APP_NAME before running the script" - return -} -set app_name $::env(XIL_APP_NAME) -puts "Using application name: ${app_name}" - -connect -url tcp:127.0.0.1:3121 -source ./vivado/${design_name}/${design_name}.sdk/hw1/ps7_init.tcl -targets -set -nocase -filter {name =~"APU*" && jtag_cable_name =~ "Digilent Zed 210248470434"} -index 0 -loadhw -hw ./vivado/${design_name}/${design_name}.sdk/hw1/system.hdf -mem-ranges [list {0x40000000 0xbfffffff}] -configparams force-mem-access 1 -targets -set -nocase -filter {name =~"APU*" && jtag_cable_name =~ "Digilent Zed 210248470434"} -index 0 -stop -ps7_init -ps7_post_config -targets -set -nocase -filter {name =~ "ARM*#0" && jtag_cable_name =~ "Digilent Zed 210248470434"} -index 0 -rst -processor -targets -set -nocase -filter {name =~ "ARM*#0" && jtag_cable_name =~ "Digilent Zed 210248470434"} -index 0 -dow ./vivado/${design_name}/${design_name}.sdk/${app_name}/Debug/${app_name}.elf -configparams force-mem-access 0 -targets -set -nocase -filter {name =~ "ARM*#0" && jtag_cable_name =~ "Digilent Zed 210248470434"} -index 0 -con diff --git a/ghdl/axi4-to-axis/axi4_to_axis.vhd b/ghdl/axi4-to-axis/axi4_to_axis.vhd new file mode 100644 index 0000000..9b4e32e --- /dev/null +++ b/ghdl/axi4-to-axis/axi4_to_axis.vhd @@ -0,0 +1,447 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS axi4_to_axis +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: bidirectional AXIS pipeline register +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity axi4_to_axis is + generic ( + -- Users to add parameters here + + -- User parameters ends + -- Do not modify the parameters beyond this line + -- Width of ID for for write address, write data, read address and read data + C_S_AXI_ID_WIDTH : integer := 1; + -- Width of S_AXI data bus + C_S_AXI_DATA_WIDTH : integer := 512; + -- Width of S_AXI address bus + C_S_AXI_ADDR_WIDTH : integer := 20; + -- Width of optional user defined signal in write address channel + C_S_AXI_AWUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in read address channel + C_S_AXI_ARUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in write data channel + C_S_AXI_WUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in read data channel + C_S_AXI_RUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in write response channel + C_S_AXI_BUSER_WIDTH : integer := 0 + + ); + port ( + -- Users to add ports here + + -- User ports ends + -- Global ports + AXIS_ACLK : in std_logic; + AXIS_ARESETN : in std_logic; + + -- AXI4 (full) Slave + -- Write Address ID + S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + -- Write address + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + -- Burst length. The burst length gives the exact number of transfers in a burst + S_AXI_AWLEN : in std_logic_vector(7 downto 0); + -- Burst size. This signal indicates the size of each transfer in the burst + S_AXI_AWSIZE : in std_logic_vector(2 downto 0); + -- Burst type. The burst type and the size information, + -- determine how the address for each transfer within the burst is calculated. + S_AXI_AWBURST : in std_logic_vector(1 downto 0); + -- Lock type. Provides additional information about the + -- atomic characteristics of the transfer. + S_AXI_AWLOCK : in std_logic; + -- Memory type. This signal indicates how transactions + -- are required to progress through a system. + S_AXI_AWCACHE : in std_logic_vector(3 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_AWPROT : in std_logic_vector(2 downto 0); + -- Quality of Service, QoS identifier sent for each + -- write transaction. + S_AXI_AWQOS : in std_logic_vector(3 downto 0); + -- Region identifier. Permits a single physical interface + -- on a slave to be used for multiple logical interfaces. + S_AXI_AWREGION : in std_logic_vector(3 downto 0); + -- Optional User-defined signal in the write address channel. + S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); + -- Write address valid. This signal indicates that + -- the channel is 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 + 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 last. This signal indicates the last transfer + -- in a write burst. + S_AXI_WLAST : in std_logic; + -- Optional User-defined signal in the write data channel. + S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-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; + -- Response ID tag. This signal is the ID tag of the + -- write response. + S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + -- Write response. This signal indicates the status + -- of the write transaction. + S_AXI_BRESP : out std_logic_vector(1 downto 0); + -- Optional User-defined signal in the write response channel. + S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-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 ID. This signal is the identification + -- tag for the read address group of signals. + S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + -- Read address. This signal indicates the initial + -- address of a read burst transaction. + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + -- Burst length. The burst length gives the exact number of transfers in a burst + S_AXI_ARLEN : in std_logic_vector(7 downto 0); + -- Burst size. This signal indicates the size of each transfer in the burst + S_AXI_ARSIZE : in std_logic_vector(2 downto 0); + -- Burst type. The burst type and the size information, + -- determine how the address for each transfer within the burst is calculated. + S_AXI_ARBURST : in std_logic_vector(1 downto 0); + -- Lock type. Provides additional information about the + -- atomic characteristics of the transfer. + S_AXI_ARLOCK : in std_logic; + -- Memory type. This signal indicates how transactions + -- are required to progress through a system. + S_AXI_ARCACHE : in std_logic_vector(3 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); + -- Quality of Service, QoS identifier sent for each + -- read transaction. + S_AXI_ARQOS : in std_logic_vector(3 downto 0); + -- Region identifier. Permits a single physical interface + -- on a slave to be used for multiple logical interfaces. + S_AXI_ARREGION : in std_logic_vector(3 downto 0); + -- Optional User-defined signal in the read address channel. + S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); + -- Write 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 ID tag. This signal is the identification tag + -- for the read data group of signals generated by the slave. + S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + -- Read Data + 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 last. This signal indicates the last transfer + -- in a read burst. + S_AXI_RLAST : out std_logic; + -- Optional User-defined signal in the read address channel. + S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-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; + + -- AXI STREAM + -- Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. + M_AXIS_TVALID : out std_logic; + -- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. + M_AXIS_TDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + -- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte. + M_AXIS_TSTRB : out std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + -- TLAST indicates the boundary of a packet. + M_AXIS_TLAST : out std_logic; + -- TREADY indicates that the slave can accept a transfer in the current cycle. + M_AXIS_TREADY : in std_logic + ); +end axi4_to_axis; + +architecture arch_imp of axi4_to_axis is + -- skidbuffer component + component skidbuffer is + generic ( + DATA_WIDTH : natural; + OPT_DATA_REG : boolean); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector((C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)) - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector((C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)) - 1 downto 0)); + end component; + + type axi_rx_state_t is (AXI_RX_STATE_IDLE, AXI_RX_STATE_SIMPLE, AXI_RX_STATE_MULTI); + signal state_axi_rx : axi_rx_state_t; + + -- signals + signal aclk : std_logic; + signal aresetn : std_logic; + + signal i_s_axis_tvalid : std_logic := '0'; + signal i_s_axis_tdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal i_s_axis_data_strb : std_logic_vector(C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tstrb : std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tlast : std_logic; + signal o_s_axis_tready : std_logic; + + signal o_m_axis_tvalid : std_logic; + signal o_m_axis_tdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal o_m_axis_data_strb : std_logic_vector(C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tstrb : std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tlast : std_logic; + signal i_m_axis_tready : std_logic := '0'; + + -- Write Response + --signal o_axi_bresp : std_logic_vector(1 downto 0); + --signal o_axi_bvalid : std_logic; + --signal o_axi_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + --signal i_axi_bready : std_logic; + + signal temp_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal bresp_pending : std_logic; + signal debug_state : std_logic_vector(1 downto 0); + + signal i_axi_awid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal i_axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + signal i_axi_awlen : std_logic_vector(7 downto 0); + signal i_axi_awsize : std_logic_vector(2 downto 0); + signal i_axi_awburst : std_logic_vector(1 downto 0); + signal i_axi_awlock : std_logic; + signal i_axi_awcache : std_logic_vector(3 downto 0); + signal i_axi_awprot : std_logic_vector(2 downto 0); + signal i_axi_awqos : std_logic_vector(3 downto 0); + signal i_axi_awregion : std_logic_vector(3 downto 0); + signal i_axi_awuser : std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); + signal i_axi_awvalid : std_logic; + signal o_axi_awready : std_logic; + + signal i_axi_wdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal i_axi_wstrb : std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal i_axi_wlast : std_logic; + signal i_axi_wuser : std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); + signal i_axi_wvalid : std_logic; + signal o_axi_wready : std_logic; + + signal o_axi_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal o_axi_bresp : std_logic_vector(1 downto 0); + signal o_axi_buser : std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); + signal o_axi_bvalid : std_logic; + signal i_axi_bready : std_logic; + signal i_axi_arid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal i_axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + signal i_axi_arlen : std_logic_vector(7 downto 0); + signal i_axi_arsize : std_logic_vector(2 downto 0); + signal i_axi_arburst : std_logic_vector(1 downto 0); + signal i_axi_arlock : std_logic; + signal i_axi_arcache : std_logic_vector(3 downto 0); + signal i_axi_arprot : std_logic_vector(2 downto 0); + signal i_axi_arqos : std_logic_vector(3 downto 0); + signal i_axi_arregion : std_logic_vector(3 downto 0); + signal i_axi_aruser : std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); + signal i_axi_arvalid : std_logic; + signal o_axi_arready : std_logic; + signal o_axi_rid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal o_axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal o_axi_rresp : std_logic_vector(1 downto 0); + signal o_axi_rlast : std_logic; + signal o_axi_ruser : std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); + signal o_axi_rvalid : std_logic; + signal i_axi_rready : std_logic; + +begin + -- I/O connections assignments + aclk <= AXIS_ACLK; + aresetn <= AXIS_ARESETN; + + -- inputs + o_axi_wready <= o_s_axis_tready; + + i_m_axis_tready <= M_AXIS_TREADY; + i_s_axis_tvalid <= S_AXI_WVALID; + i_s_axis_tdata <= S_AXI_WDATA; + i_s_axis_tstrb <= S_AXI_WSTRB; + i_s_axis_tlast <= S_AXI_WLAST; + i_axi_bready <= S_AXI_BREADY; + + i_axi_awid <= S_AXI_AWID; + i_axi_awaddr <= S_AXI_AWADDR; + i_axi_awlen <= S_AXI_AWLEN; + i_axi_awsize <= S_AXI_AWSIZE; + i_axi_awburst <= S_AXI_AWBURST; + i_axi_awlock <= S_AXI_AWLOCK; + i_axi_awcache <= S_AXI_AWCACHE; + i_axi_awprot <= S_AXI_AWPROT; + i_axi_awqos <= S_AXI_AWQOS; + i_axi_awregion <= S_AXI_AWREGION; + i_axi_awuser <= S_AXI_AWUSER; + i_axi_awvalid <= S_AXI_AWVALID; + S_AXI_AWREADY <= o_axi_awready; + + -- outputs + S_AXI_WREADY <= o_s_axis_tready; + M_AXIS_TVALID <= o_m_axis_tvalid; + M_AXIS_TDATA <= o_m_axis_tdata; + M_AXIS_TSTRB <= o_m_axis_tstrb; + M_AXIS_TLAST <= o_m_axis_tlast; + S_AXI_BRESP <= o_axi_bresp; + S_AXI_BVALID <= o_axi_bvalid; + S_AXI_BID <= o_axi_bid; + + i_axi_wdata <= S_AXI_WDATA; + i_axi_wstrb <= S_AXI_WSTRB; + i_axi_wlast <= S_AXI_WLAST; + i_axi_wuser <= S_AXI_WUSER; + i_axi_wvalid <= S_AXI_WVALID; + S_AXI_WREADY <= o_axi_wready; + + -- combine strobe and data signals into single "data" channel + i_s_axis_data_strb <= i_s_axis_tdata & i_s_axis_tstrb; + o_m_axis_tdata <= o_m_axis_data_strb( (C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)) - 1 downto (C_S_AXI_DATA_WIDTH/8) ); + o_m_axis_tstrb <= o_m_axis_data_strb( (C_S_AXI_DATA_WIDTH/8) - 1 downto 0 ); + + p_axi_rx_flow_state : process(aclk) + begin + if rising_edge(aclk) then + if aresetn = '0' then + state_axi_rx <= AXI_RX_STATE_IDLE; + o_axi_bvalid <= '0'; + o_axi_bresp <= (others => '0'); + o_axi_bid <= (others => '0'); + o_axi_awready <= '1'; -- "always" ready to accept AW (because address gets discarded anyways) + bresp_pending <= '0'; + debug_state <= "00"; + else + -- state machine that can accept up to 2 requests over AW channel + case state_axi_rx is + -- IDLE: wait for AW request, remember AWID for BID, go to RX_SIMPLE + when AXI_RX_STATE_IDLE => + debug_state <= "01"; + if i_axi_awvalid = '1' and o_axi_awready = '1' then -- accept incomming AW request + state_axi_rx <= AXI_RX_STATE_SIMPLE; + o_axi_bid <= i_axi_awid; + o_axi_awready <= '0'; + end if; + if i_s_axis_tlast = '1' then + -- tlast signals that the transfer can be aknowledged via BRESP channel + o_axi_bvalid <= '1'; + end if; + if o_axi_bvalid = '1' and i_axi_bready = '1' then + -- deasert, if BRESP is aknowledged + o_axi_bvalid <= '0'; + end if; + + -- RX_SIMPLE: only 1 incomming xfer, AXI Slave can still accept AW requests + -- when another AW reqest is incomming go to RX_MULTI + when AXI_RX_STATE_SIMPLE => + debug_state <= "10"; + if i_axi_awvalid = '1' and o_axi_awready = '1' then -- accept ANOTHER incomming AW request + state_axi_rx <= AXI_RX_STATE_MULTI; + -- signal the pending signal, if awvalid, awready and tlast assert at the same time + bresp_pending <= o_m_axis_tlast; + temp_bid <= i_axi_awid; + o_axi_bvalid <= '0'; + o_axi_awready <= '0'; + elsif o_m_axis_tlast = '1' then + -- tlast signals that the transfer is complete and can be aknowledged via BRESP channel + state_axi_rx <= AXI_RX_STATE_IDLE; + o_axi_bvalid <= '1'; + o_axi_awready <= '1'; + else + -- wait for transfer to be complete + state_axi_rx <= AXI_RX_STATE_SIMPLE; + o_axi_bvalid <= '0'; + o_axi_awready <= '1'; + end if; + if o_axi_bvalid = '1' and i_axi_bready = '1' then + -- deasert, if BRESP is aknowledged + o_axi_bvalid <= '0'; + end if; + + -- RX_MULTI: multiple xfers pending, AXI Slave AW is stalled + when AXI_RX_STATE_MULTI => + debug_state <= "11"; + if bresp_pending = '1' then + bresp_pending <= '0'; + state_axi_rx <= AXI_RX_STATE_SIMPLE; + o_axi_awready <= '1'; + o_axi_bvalid <= '1'; + elsif o_m_axis_tlast = '1' then + state_axi_rx <= AXI_RX_STATE_SIMPLE; + o_axi_awready <= '1'; + o_axi_bid <= temp_bid; + o_axi_bvalid <= '1'; + else + o_axi_awready <= '0'; + end if; + end case; + end if; + end if; + end process; + + skidbuffer_inst : skidbuffer + generic map ( + DATA_WIDTH => (C_S_AXI_DATA_WIDTH+(C_S_AXI_DATA_WIDTH/8)), + OPT_DATA_REG => True + ) + port map ( + clock => aclk, + reset_n => aresetn, + + s_valid_i => i_s_axis_tvalid, + s_last_i => i_s_axis_tlast, + s_ready_o => o_s_axis_tready, + s_data_i => i_s_axis_data_strb, + + m_valid_o => o_m_axis_tvalid, + m_last_o => o_m_axis_tlast, + m_ready_i => i_m_axis_tready, + m_data_o => o_m_axis_data_strb + ); + +end arch_imp; diff --git a/ghdl/axi4-to-axis/axis_pipeline.vhd b/ghdl/axi4-to-axis/axis_pipeline.vhd new file mode 100644 index 0000000..9b7d453 --- /dev/null +++ b/ghdl/axi4-to-axis/axis_pipeline.vhd @@ -0,0 +1,149 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS axis_pipeline +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: bidirectional AXIS pipeline register +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity axis_pipeline is + generic ( + -- Users to add parameters here + + -- User parameters ends + -- Do not modify the parameters beyond this line + + -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_S_AXIS_TDATA_WIDTH. + C_S_AXIS_TDATA_WIDTH : integer := 32 + ); + port ( + -- Users to add ports here + + -- User ports ends + -- Global ports + AXIS_ACLK : in std_logic; + AXIS_ARESETN : in std_logic; + + -- Slave Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. + S_AXIS_TVALID : in std_logic; + -- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. + S_AXIS_TDATA : in std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + -- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte. + S_AXIS_TSTRB : in std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + -- TLAST indicates the boundary of a packet. + S_AXIS_TLAST : in std_logic; + -- TREADY indicates that the slave can accept a transfer in the current cycle. + S_AXIS_TREADY : out std_logic; + + -- Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. + M_AXIS_TVALID : out std_logic; + -- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. + M_AXIS_TDATA : out std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + -- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte. + M_AXIS_TSTRB : out std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + -- TLAST indicates the boundary of a packet. + M_AXIS_TLAST : out std_logic; + -- TREADY indicates that the slave can accept a transfer in the current cycle. + M_AXIS_TREADY : in std_logic + ); +end axis_pipeline; + +architecture arch_imp of axis_pipeline is + -- skidbuffer component + component skidbuffer is + generic ( + DATA_WIDTH : natural; + OPT_DATA_REG : boolean); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector((C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector((C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto 0)); + end component; + + -- signals + signal aclk : std_logic; + signal aresetn : std_logic; + + signal i_s_axis_tvalid : std_logic := '0'; + signal i_s_axis_tdata : std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + signal i_axis_data_strb : std_logic_vector(C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tstrb : std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tlast : std_logic; + signal o_s_axis_tready : std_logic; + + signal o_m_axis_tvalid : std_logic; + signal o_m_axis_tdata : std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + signal o_axis_data_strb : std_logic_vector(C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tstrb : std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tlast : std_logic; + signal i_m_axis_tready : std_logic := '0'; + +begin + -- I/O connections assignments + aclk <= AXIS_ACLK; + aresetn <= AXIS_ARESETN; + + -- inputs + i_m_axis_tready <= M_AXIS_TREADY; + i_s_axis_tvalid <= S_AXIS_TVALID; + i_s_axis_tdata <= S_AXIS_TDATA; + i_s_axis_tstrb <= S_AXIS_TSTRB; + i_s_axis_tlast <= S_AXIS_TLAST; + + -- outputs + S_AXIS_TREADY <= o_s_axis_tready; + M_AXIS_TVALID <= o_m_axis_tvalid; + M_AXIS_TDATA <= o_m_axis_tdata; + M_AXIS_TSTRB <= o_m_axis_tstrb; + M_AXIS_TLAST <= o_m_axis_tlast; + + -- combine strobe and data signals into single "data" channel + i_axis_data_strb <= s_axis_tdata & s_axis_tstrb; + o_m_axis_tdata <= o_axis_data_strb( (C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto (C_S_AXIS_TDATA_WIDTH/8) ); + o_m_axis_tstrb <= o_axis_data_strb( (C_S_AXIS_TDATA_WIDTH/8) - 1 downto 0 ); + + skidbuffer_inst : skidbuffer + generic map ( + DATA_WIDTH => (C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)), + OPT_DATA_REG => True + ) + port map ( + clock => aclk, + reset_n => aresetn, + + s_valid_i => i_s_axis_tvalid, + s_last_i => i_s_axis_tlast, + s_ready_o => o_s_axis_tready, + s_data_i => i_axis_data_strb, + + m_valid_o => o_m_axis_tvalid, + m_last_o => o_m_axis_tlast, + m_ready_i => i_m_axis_tready, + m_data_o => o_axis_data_strb + ); + +end arch_imp; diff --git a/ghdl/axi4-to-axis/compile.bat b/ghdl/axi4-to-axis/compile.bat new file mode 100644 index 0000000..3401075 --- /dev/null +++ b/ghdl/axi4-to-axis/compile.bat @@ -0,0 +1,27 @@ + +ghdl --version + +:: delete +del /Q *.vcd & +del /Q *.o & +del /Q *.exe & +del /Q *.cf & + +:: analyze +ghdl -a skidbuffer.vhd +ghdl -a axis_pipeline.vhd +ghdl -a axi4_to_axis.vhd +ghdl -a tb_axis.vhd +:: elaborate +ghdl -e skidbuffer +ghdl -e axis_pipeline +ghdl -e axi4_to_axis +ghdl -e tb_axis +:: run +ghdl -r tb_axis --vcd=wave.vcd --stop-time=1us +gtkwave wave.vcd waveform.gtkw + +:: delete +del /Q *.o & +del /Q *.exe & +del /Q *.cf & diff --git a/ghdl/axi4-to-axis/skidbuffer.vhd b/ghdl/axi4-to-axis/skidbuffer.vhd new file mode 100644 index 0000000..f71abcf --- /dev/null +++ b/ghdl/axi4-to-axis/skidbuffer.vhd @@ -0,0 +1,147 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS skidbuffer +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: skidbuffer for pipelining a bus handshake +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DATA_WIDTH : integer := 32; + OPT_DATA_REG : boolean := True + ); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0) + ); +end skidbuffer; + +architecture arch_imp of skidbuffer is + -- register signals + signal reg_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals (only used when OPT_DATA_REG = '1') + signal skd_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal skd_last : std_logic; + + -- output signals for output multiplexer + signal out_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal out_last : std_logic; + +begin + -- I/O connections assignments + m_valid_o <= reg_valid; + s_ready_o <= reg_ready; + m_data_o <= out_data; + m_last_o <= out_last; + + -- ready is always registered + p_reg_ready : process(clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_ready <= '0'; + else + reg_ready <= m_ready_i; + end if; + end if; + end process; + +-- NOT REGISTERED OUTPUT ------------------------------------------------------- + gen_no_register : if not OPT_DATA_REG generate + reg_valid <= s_valid_i; -- valid is not registered + -- output multiplexer + out_data <= reg_data when (reg_ready = '0') else s_data_i; + out_last <= reg_last when (reg_ready = '0') else s_last_i; + + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= reg_data; + reg_last <= reg_last; + end if; + end if; + end if; + end process; + + end generate; + +-- FULLY REGISTERED OUTPUT ----------------------------------------------------- + gen_data_register : if OPT_DATA_REG generate + out_data <= reg_data; + out_last <= reg_last; + -- registered output signals + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + skd_data <= (others => '0'); + skd_last <= '0'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if reg_ready = '1' then + skd_data <= s_data_i; + skd_last <= s_last_i; + else + skd_data <= skd_data; + skd_last <= skd_last; + end if; + + if m_ready_i = '0' then + reg_data <= reg_data; + reg_last <= reg_last; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= skd_data; + reg_last <= skd_last; + end if; + end if; + end if; + end if; + end process; + end generate; + +end arch_imp; diff --git a/ghdl/axi4-to-axis/tb_axis.vhd b/ghdl/axi4-to-axis/tb_axis.vhd new file mode 100644 index 0000000..59b0278 --- /dev/null +++ b/ghdl/axi4-to-axis/tb_axis.vhd @@ -0,0 +1,522 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: skid buffer testbench +-- Module Name: tb_axis - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- this testbench acts as a streaming master, sending bursts of data +-- counting from 1-4, also asserting tlast on the 4th data packet + +-- the testbench itself acts as a correct streaming master which keeps the data +-- until it is acknowledged by the DUT by asserting tready. + +-- the data pattern can be influenced by the user in 2 ways +-- + Tx requests are generated by changing the pattern in p_stimuli_tready +-- the master will try to send data for as long as sim_valid_data = '1' +-- + Rx acknowledgements are generated by changing the pattern in p_stimuli_tready +-- the downstream slave after the DUT will signal ready-to-receive +-- when sim_ready_data = '1' + +-- simulate both with OPT_DATA_REG = True / False +entity tb_axis is + generic + ( + OPT_DATA_REG : boolean := True; + -- Width of ID for for write address, write data, read address and read data + C_S_AXI_ID_WIDTH : integer := 3; + -- Width of S_AXI data bus + C_S_AXI_DATA_WIDTH : integer := 8; + -- Width of S_AXI address bus + C_S_AXI_ADDR_WIDTH : integer := 8; + -- Width of optional user defined signal in write address channel + C_S_AXI_AWUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in read address channel + C_S_AXI_ARUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in write data channel + C_S_AXI_WUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in read data channel + C_S_AXI_RUSER_WIDTH : integer := 0; + -- Width of optional user defined signal in write response channel + C_S_AXI_BUSER_WIDTH : integer := 0 + ); +end tb_axis; + +architecture bh of tb_axis is + -- DUT component declaration + component axi4_to_axis is + generic ( + C_S_AXI_ID_WIDTH : integer; + C_S_AXI_DATA_WIDTH : integer; + C_S_AXI_ADDR_WIDTH : integer; + C_S_AXI_AWUSER_WIDTH : integer; + C_S_AXI_ARUSER_WIDTH : integer; + C_S_AXI_WUSER_WIDTH : integer; + C_S_AXI_RUSER_WIDTH : integer; + C_S_AXI_BUSER_WIDTH : integer + ); + port ( + AXIS_ACLK : in std_logic; + AXIS_ARESETN : in std_logic; + + S_AXI_AWID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_AWADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + S_AXI_AWLEN : in std_logic_vector(7 downto 0); + S_AXI_AWSIZE : in std_logic_vector(2 downto 0); + S_AXI_AWBURST : in std_logic_vector(1 downto 0); + S_AXI_AWLOCK : in std_logic; + S_AXI_AWCACHE : in std_logic_vector(3 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWQOS : in std_logic_vector(3 downto 0); + S_AXI_AWREGION : in std_logic_vector(3 downto 0); + S_AXI_AWUSER : in std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + S_AXI_WSTRB : in std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + S_AXI_WLAST : in std_logic; + S_AXI_WUSER : in std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BUSER : out std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARID : in std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_ARADDR : in std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + S_AXI_ARLEN : in std_logic_vector(7 downto 0); + S_AXI_ARSIZE : in std_logic_vector(2 downto 0); + S_AXI_ARBURST : in std_logic_vector(1 downto 0); + S_AXI_ARLOCK : in std_logic; + S_AXI_ARCACHE : in std_logic_vector(3 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARQOS : in std_logic_vector(3 downto 0); + S_AXI_ARREGION : in std_logic_vector(3 downto 0); + S_AXI_ARUSER : in std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RID : out std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + S_AXI_RDATA : out std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RLAST : out std_logic; + S_AXI_RUSER : out std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic; + + M_AXIS_TVALID : out std_logic; + M_AXIS_TDATA : out std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + M_AXIS_TSTRB : out std_logic_vector((C_S_AXI_ADDR_WIDTH/8)-1 downto 0); + M_AXIS_TLAST : out std_logic; + M_AXIS_TREADY : in std_logic + ); + end component; + + constant CLK_PERIOD: TIME := 5 ns; + + signal sim_start_write : std_logic := '0'; -- request AW channel + signal sim_start_ready : std_logic := '0'; -- signal ready to receive from slave + signal sim_valid_data : std_logic := '0'; -- AW complete, now send W channel + signal sim_data : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + + signal o_axis_tvalid : std_logic; + signal o_axis_tdata : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + signal o_axis_tstrb : std_logic_vector((C_S_AXI_ADDR_WIDTH/8)-1 downto 0); + signal o_axis_tlast : std_logic; + signal i_axis_tready : std_logic := '0'; + + signal clk : std_logic; + signal rst_n : std_logic; + + signal o_axi_awid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal o_axi_awaddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + signal o_axi_awlen : std_logic_vector(7 downto 0); + signal o_axi_awsize : std_logic_vector(2 downto 0); + signal o_axi_awburst : std_logic_vector(1 downto 0); + signal o_axi_awlock : std_logic; + signal o_axi_awcache : std_logic_vector(3 downto 0); + signal o_axi_awprot : std_logic_vector(2 downto 0); + signal o_axi_awqos : std_logic_vector(3 downto 0); + signal o_axi_awregion : std_logic_vector(3 downto 0); + signal o_axi_awuser : std_logic_vector(C_S_AXI_AWUSER_WIDTH-1 downto 0); + signal o_axi_awvalid : std_logic; + signal i_axi_awready : std_logic; + + signal o_axi_wdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal o_axi_wstrb : std_logic_vector((C_S_AXI_DATA_WIDTH/8)-1 downto 0); + signal o_axi_wlast : std_logic; + signal o_axi_wuser : std_logic_vector(C_S_AXI_WUSER_WIDTH-1 downto 0); + signal o_axi_wvalid : std_logic; + signal i_axi_wready : std_logic; + + signal i_axi_bid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal i_axi_bresp : std_logic_vector(1 downto 0); + signal i_axi_buser : std_logic_vector(C_S_AXI_BUSER_WIDTH-1 downto 0); + signal i_axi_bvalid : std_logic; + signal o_axi_bready : std_logic; + signal o_axi_arid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal o_axi_araddr : std_logic_vector(C_S_AXI_ADDR_WIDTH-1 downto 0); + signal o_axi_arlen : std_logic_vector(7 downto 0); + signal o_axi_arsize : std_logic_vector(2 downto 0); + signal o_axi_arburst : std_logic_vector(1 downto 0); + signal o_axi_arlock : std_logic; + signal o_axi_arcache : std_logic_vector(3 downto 0); + signal o_axi_arprot : std_logic_vector(2 downto 0); + signal o_axi_arqos : std_logic_vector(3 downto 0); + signal o_axi_arregion : std_logic_vector(3 downto 0); + signal o_axi_aruser : std_logic_vector(C_S_AXI_ARUSER_WIDTH-1 downto 0); + signal o_axi_arvalid : std_logic; + signal i_axi_arready : std_logic; + signal i_axi_rid : std_logic_vector(C_S_AXI_ID_WIDTH-1 downto 0); + signal i_axi_rdata : std_logic_vector(C_S_AXI_DATA_WIDTH-1 downto 0); + signal i_axi_rresp : std_logic_vector(1 downto 0); + signal i_axi_rlast : std_logic; + signal i_axi_ruser : std_logic_vector(C_S_AXI_RUSER_WIDTH-1 downto 0); + signal i_axi_rvalid : std_logic; + signal o_axi_rready : std_logic; + + signal clk_count : std_logic_vector(7 downto 0) := (others => '0'); + signal outstanding_xfers : std_logic_vector(7 downto 0) := (others => '0'); +begin + + -- generate clk signal + p_clk_gen : process + begin + clk <= '1'; + wait for (CLK_PERIOD / 2); + clk <= '0'; + wait for (CLK_PERIOD / 2); + clk_count <= std_logic_vector(unsigned(clk_count) + 1); + end process; + + -- generate initial reset + p_reset_gen : process + begin + rst_n <= '0'; + wait until rising_edge(clk); + wait for (CLK_PERIOD / 4); + rst_n <= '1'; + wait; + end process; + + -- generate AW request + p_aw_stimuli : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + o_axi_awid <= (others => '0'); + o_axi_awaddr <= (others => '0'); + o_axi_awlen <= (others => '0'); + o_axi_awsize <= (others => '0'); + o_axi_awburst <= (others => '0'); + o_axi_awlock <= '0'; + o_axi_awcache <= (others => '0'); + o_axi_awprot <= (others => '0'); + o_axi_awqos <= (others => '0'); + o_axi_awregion <= (others => '0'); + o_axi_awuser <= (others => '0'); + o_axi_awvalid <= '0'; + sim_valid_data <= '0'; + else + if o_axi_awvalid = '1' then -- AW handshake ongoing, wait for slave to ack + if i_axi_awready = '1' then -- slave is able to receive AW reqest + o_axi_awid <= "000"; + o_axi_awaddr <= (others => '0'); + o_axi_awlen <= (others => '0'); + o_axi_awsize <= "000"; + o_axi_awburst <= "00"; + o_axi_awvalid <= '0'; + sim_valid_data <= '1'; + end if; + else + if sim_start_write = '1' then -- AW handshake requested by simulation + o_axi_awid <= "101"; + o_axi_awaddr <= x"42"; + o_axi_awlen <= x"3f"; -- 63+1 bytes + o_axi_awsize <= "110"; -- 64 bytes + o_axi_awburst <= "01"; -- INCR + o_axi_awvalid <= '1'; + --sim_valid_data <= '0'; + end if; + end if; + if sim_valid_data = '1' then + if o_axi_wlast = '1' and i_axi_wready = '1' then + if unsigned(outstanding_xfers) = 1 then + sim_valid_data <= '0'; + end if; + end if; + end if; + end if; + end if; + end process; + + -- generate counter data when successfully acknowledged (tready) by slave + p_stimuli_tdata : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + o_axi_wdata <= (others => '0'); + o_axi_wstrb <= (others => '0'); + sim_data <= (others => '0'); + o_axi_wlast <= '0'; + o_axi_wvalid <= '0'; + else + if (sim_valid_data = '1' or o_axi_awvalid='1') then -- and o_axi_wlast = '0' then -- OK from a valid AW handshake + -- if o_axi_wlast = '0' then + if i_axi_wready = '1' then -- wready from slave + if unsigned(o_axi_wdata) = 15 then + o_axi_wlast <= '1'; + else + o_axi_wlast <= '0'; + end if; + + if unsigned(outstanding_xfers) /= 0 and o_axi_wlast = '0' then + if unsigned(o_axi_wdata) = 16 then + -- restart counter at "1" + o_axi_wdata(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); + o_axi_wdata(0) <= '1'; + sim_data(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + if (unsigned(sim_data) > unsigned(o_axi_wdata)) and (unsigned(sim_data) < 4) then + o_axi_wdata <= std_logic_vector(unsigned(sim_data) + 1); + else + o_axi_wdata <= std_logic_vector(unsigned(o_axi_wdata) + 1); + end if; + + if unsigned(sim_data) = 16 then + sim_data(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + sim_data <= std_logic_vector(unsigned(sim_data) + 1); + end if; + end if; + o_axi_wvalid <= '1'; + o_axi_wstrb <= "1"; + else + if unsigned(outstanding_xfers) = 1 then + o_axi_wdata <= (others => '0'); + sim_data <= (others => '0'); + o_axi_wvalid <= '0'; + o_axi_wstrb <= "0"; + else + o_axi_wdata(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); + o_axi_wdata(0) <= '1'; + sim_data(C_S_AXI_DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + end if; + end if; + else + o_axi_wdata <= o_axi_wdata; + sim_data <= sim_data; + end if; + -- end if; + else + o_axi_wvalid <= '0'; + o_axi_wstrb <= "0"; + o_axi_wlast <= '0'; + o_axi_wdata <= (others => '0'); + sim_data <= sim_data; + end if; + end if; + end if; + end process; + + -- accept and ack BRESP + p_ack_bresp : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + o_axi_bready <= '1'; + else + if i_axi_bvalid = '1' then + o_axi_bready <= '0'; + else + o_axi_bready <= '1'; + end if; + end if; + end if; + end process; + + -- generate ready signal + p_slave_tready : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + i_axis_tready <= '0'; + else + if sim_start_ready = '1' then + i_axis_tready <= '1'; + else + i_axis_tready <= '0'; + end if; + end if; + end if; + end process; + + -- generate valid signal + p_stimuli_valid : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + sim_start_write <= '0'; + else + if o_axi_wlast = '1' and i_axi_wready = '1' then + outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) - 1); + else + if unsigned(clk_count) = 3 then + sim_start_write <= '1'; + outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) + 1); + end if; + if unsigned(clk_count) = 5 then + sim_start_write <= '0'; + end if; + + if unsigned(clk_count) = 20 then + sim_start_write <= '1'; + outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) + 1); + end if; + if unsigned(clk_count) = 22 then + sim_start_write <= '0'; + end if; + + if unsigned(clk_count) = 46 then + sim_start_write <= '1'; + outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) + 1); + end if; + if unsigned(clk_count) = 48 then + sim_start_write <= '0'; + end if; + if unsigned(clk_count) = 56 then + sim_start_write <= '1'; + outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) + 1); + end if; + if unsigned(clk_count) = 58 then + sim_start_write <= '0'; + end if; + +-- if unsigned(clk_count) = 78 then +-- sim_start_write <= '1'; +-- outstanding_xfers <= std_logic_vector(unsigned(outstanding_xfers) + 1); +-- end if; +-- if unsigned(clk_count) = 85 then +-- sim_start_write <= '0'; +-- end if; + end if; + end if; + end if; + end process; + + -- generate ready signal + p_stimuli_ready : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + sim_start_ready <= '0'; + else + if unsigned(clk_count) = 2 then + sim_start_ready <= '1'; + end if; + if unsigned(clk_count) = 52 then + sim_start_ready <= '0'; + end if; + if unsigned(clk_count) = 70 then + sim_start_ready <= '1'; + end if; +-- if unsigned(clk_count) = 27 then +-- sim_start_ready <= '0'; +-- end if; +-- if unsigned(clk_count) = 38 then +-- sim_start_ready <= '1'; +-- end if; + end if; + end if; + end process; + +-- DUT instance and connections + axi_converter_inst : axi4_to_axis + generic map ( + C_S_AXI_ID_WIDTH => C_S_AXI_ID_WIDTH, + C_S_AXI_DATA_WIDTH => C_S_AXI_DATA_WIDTH, + C_S_AXI_ADDR_WIDTH => C_S_AXI_ADDR_WIDTH, + C_S_AXI_AWUSER_WIDTH => C_S_AXI_AWUSER_WIDTH, + C_S_AXI_ARUSER_WIDTH => C_S_AXI_ARUSER_WIDTH, + C_S_AXI_WUSER_WIDTH => C_S_AXI_WUSER_WIDTH, + C_S_AXI_RUSER_WIDTH => C_S_AXI_RUSER_WIDTH, + C_S_AXI_BUSER_WIDTH => C_S_AXI_BUSER_WIDTH + ) + port map ( + AXIS_ACLK => clk, + AXIS_ARESETN => rst_n, + + S_AXI_AWID => o_axi_awid, + S_AXI_AWADDR => o_axi_awaddr, + S_AXI_AWLEN => o_axi_awlen, + S_AXI_AWSIZE => o_axi_awsize, + S_AXI_AWBURST => o_axi_awburst, + S_AXI_AWLOCK => o_axi_awlock, + S_AXI_AWCACHE => o_axi_awcache, + S_AXI_AWPROT => o_axi_awprot, + S_AXI_AWQOS => o_axi_awqos, + S_AXI_AWREGION => o_axi_awregion, + S_AXI_AWUSER => o_axi_awuser, + S_AXI_AWVALID => o_axi_awvalid, + S_AXI_AWREADY => i_axi_awready, + S_AXI_WDATA => o_axi_wdata, + S_AXI_WSTRB => o_axi_wstrb, + S_AXI_WLAST => o_axi_wlast, + S_AXI_WUSER => o_axi_wuser, + S_AXI_WVALID => o_axi_wvalid, + S_AXI_WREADY => i_axi_wready, + + S_AXI_BID => i_axi_bid, + S_AXI_BRESP => i_axi_bresp, + S_AXI_BUSER => i_axi_buser, + S_AXI_BVALID => i_axi_bvalid, + S_AXI_BREADY => o_axi_bready, + S_AXI_ARID => o_axi_arid, + S_AXI_ARADDR => o_axi_araddr, + S_AXI_ARLEN => o_axi_arlen, + S_AXI_ARSIZE => o_axi_arsize, + S_AXI_ARBURST => o_axi_arburst, + S_AXI_ARLOCK => o_axi_arlock, + S_AXI_ARCACHE => o_axi_arcache, + S_AXI_ARPROT => o_axi_arprot, + S_AXI_ARQOS => o_axi_arqos, + S_AXI_ARREGION => o_axi_arregion, + S_AXI_ARUSER => o_axi_aruser, + S_AXI_ARVALID => o_axi_arvalid, + S_AXI_ARREADY => i_axi_arready, + S_AXI_RID => i_axi_rid, + S_AXI_RDATA => i_axi_rdata, + S_AXI_RRESP => i_axi_rresp, + S_AXI_RLAST => i_axi_rlast, + S_AXI_RUSER => i_axi_ruser, + S_AXI_RVALID => i_axi_rvalid, + S_AXI_RREADY => o_axi_rready, + + M_AXIS_TVALID => o_axis_tvalid, + M_AXIS_TDATA => o_axis_tdata, + M_AXIS_TSTRB => o_axis_tstrb, + M_AXIS_TLAST => o_axis_tlast, + M_AXIS_TREADY => i_axis_tready + ); + +end bh; diff --git a/ghdl/axi4-to-axis/wave.vcd b/ghdl/axi4-to-axis/wave.vcd new file mode 100644 index 0000000..4cb5e68 --- /dev/null +++ b/ghdl/axi4-to-axis/wave.vcd @@ -0,0 +1,4128 @@ +$date + Thu May 04 16:43:42 2023 +$end +$version + GHDL v0 +$end +$timescale + 1 fs +$end +$scope module standard $end +$upscope $end +$scope module std_logic_1164 $end +$upscope $end +$scope module numeric_std $end +$upscope $end +$scope module tb_axis $end +$var reg 1 ! sim_start_write $end +$var reg 1 " sim_start_ready $end +$var reg 1 # sim_valid_data $end +$var reg 8 $ sim_data[7:0] $end +$var reg 1 % o_axis_tvalid $end +$var reg 8 & o_axis_tdata[7:0] $end +$var reg 1 ' o_axis_tstrb[0:0] $end +$var reg 1 ( o_axis_tlast $end +$var reg 1 ) i_axis_tready $end +$var reg 1 * clk $end +$var reg 1 + rst_n $end +$var reg 3 , o_axi_awid[2:0] $end +$var reg 8 - o_axi_awaddr[7:0] $end +$var reg 8 . o_axi_awlen[7:0] $end +$var reg 3 / o_axi_awsize[2:0] $end +$var reg 2 0 o_axi_awburst[1:0] $end +$var reg 1 1 o_axi_awlock $end +$var reg 4 2 o_axi_awcache[3:0] $end +$var reg 3 3 o_axi_awprot[2:0] $end +$var reg 4 4 o_axi_awqos[3:0] $end +$var reg 4 5 o_axi_awregion[3:0] $end +$comment o_axi_awuser is not handled $end +$var reg 1 6 o_axi_awvalid $end +$var reg 1 7 i_axi_awready $end +$var reg 8 8 o_axi_wdata[7:0] $end +$var reg 1 9 o_axi_wstrb[0:0] $end +$var reg 1 : o_axi_wlast $end +$comment o_axi_wuser is not handled $end +$var reg 1 ; o_axi_wvalid $end +$var reg 1 < i_axi_wready $end +$var reg 3 = i_axi_bid[2:0] $end +$var reg 2 > i_axi_bresp[1:0] $end +$comment i_axi_buser is not handled $end +$var reg 1 ? i_axi_bvalid $end +$var reg 1 @ o_axi_bready $end +$var reg 3 A o_axi_arid[2:0] $end +$var reg 8 B o_axi_araddr[7:0] $end +$var reg 8 C o_axi_arlen[7:0] $end +$var reg 3 D o_axi_arsize[2:0] $end +$var reg 2 E o_axi_arburst[1:0] $end +$var reg 1 F o_axi_arlock $end +$var reg 4 G o_axi_arcache[3:0] $end +$var reg 3 H o_axi_arprot[2:0] $end +$var reg 4 I o_axi_arqos[3:0] $end +$var reg 4 J o_axi_arregion[3:0] $end +$comment o_axi_aruser is not handled $end +$var reg 1 K o_axi_arvalid $end +$var reg 1 L i_axi_arready $end +$var reg 3 M i_axi_rid[2:0] $end +$var reg 8 N i_axi_rdata[7:0] $end +$var reg 2 O i_axi_rresp[1:0] $end +$var reg 1 P i_axi_rlast $end +$comment i_axi_ruser is not handled $end +$var reg 1 Q i_axi_rvalid $end +$var reg 1 R o_axi_rready $end +$var reg 8 S clk_count[7:0] $end +$var reg 8 T outstanding_xfers[7:0] $end +$scope module axi_converter_inst $end +$var reg 1 U axis_aclk $end +$var reg 1 V axis_aresetn $end +$var reg 3 W s_axi_awid[2:0] $end +$var reg 8 X s_axi_awaddr[7:0] $end +$var reg 8 Y s_axi_awlen[7:0] $end +$var reg 3 Z s_axi_awsize[2:0] $end +$var reg 2 [ s_axi_awburst[1:0] $end +$var reg 1 \ s_axi_awlock $end +$var reg 4 ] s_axi_awcache[3:0] $end +$var reg 3 ^ s_axi_awprot[2:0] $end +$var reg 4 _ s_axi_awqos[3:0] $end +$var reg 4 ` s_axi_awregion[3:0] $end +$comment s_axi_awuser is not handled $end +$var reg 1 a s_axi_awvalid $end +$var reg 1 b s_axi_awready $end +$var reg 8 c s_axi_wdata[7:0] $end +$var reg 1 d s_axi_wstrb[0:0] $end +$var reg 1 e s_axi_wlast $end +$comment s_axi_wuser is not handled $end +$var reg 1 f s_axi_wvalid $end +$var reg 1 g s_axi_wready $end +$var reg 3 h s_axi_bid[2:0] $end +$var reg 2 i s_axi_bresp[1:0] $end +$comment s_axi_buser is not handled $end +$var reg 1 j s_axi_bvalid $end +$var reg 1 k s_axi_bready $end +$var reg 3 l s_axi_arid[2:0] $end +$var reg 8 m s_axi_araddr[7:0] $end +$var reg 8 n s_axi_arlen[7:0] $end +$var reg 3 o s_axi_arsize[2:0] $end +$var reg 2 p s_axi_arburst[1:0] $end +$var reg 1 q s_axi_arlock $end +$var reg 4 r s_axi_arcache[3:0] $end +$var reg 3 s s_axi_arprot[2:0] $end +$var reg 4 t s_axi_arqos[3:0] $end +$var reg 4 u s_axi_arregion[3:0] $end +$comment s_axi_aruser is not handled $end +$var reg 1 v s_axi_arvalid $end +$var reg 1 w s_axi_arready $end +$var reg 3 x s_axi_rid[2:0] $end +$var reg 8 y s_axi_rdata[7:0] $end +$var reg 2 z s_axi_rresp[1:0] $end +$var reg 1 { s_axi_rlast $end +$comment s_axi_ruser is not handled $end +$var reg 1 | s_axi_rvalid $end +$var reg 1 } s_axi_rready $end +$var reg 1 !" m_axis_tvalid $end +$var reg 8 "" m_axis_tdata[7:0] $end +$var reg 1 #" m_axis_tstrb[0:0] $end +$var reg 1 $" m_axis_tlast $end +$var reg 1 %" m_axis_tready $end +$comment state_axi_rx is not handled $end +$var reg 1 &" aclk $end +$var reg 1 '" aresetn $end +$var reg 1 (" i_s_axis_tvalid $end +$var reg 8 )" i_s_axis_tdata[7:0] $end +$var reg 9 *" i_s_axis_data_strb[8:0] $end +$var reg 1 +" i_s_axis_tstrb[0:0] $end +$var reg 1 ," i_s_axis_tlast $end +$var reg 1 -" o_s_axis_tready $end +$var reg 1 ." o_m_axis_tvalid $end +$var reg 8 /" o_m_axis_tdata[7:0] $end +$var reg 9 0" o_m_axis_data_strb[8:0] $end +$var reg 1 1" o_m_axis_tstrb[0:0] $end +$var reg 1 2" o_m_axis_tlast $end +$var reg 1 3" i_m_axis_tready $end +$var reg 3 4" temp_bid[2:0] $end +$var reg 1 5" bresp_pending $end +$var reg 2 6" debug_state[1:0] $end +$var reg 3 7" i_axi_awid[2:0] $end +$var reg 8 8" i_axi_awaddr[7:0] $end +$var reg 8 9" i_axi_awlen[7:0] $end +$var reg 3 :" i_axi_awsize[2:0] $end +$var reg 2 ;" i_axi_awburst[1:0] $end +$var reg 1 <" i_axi_awlock $end +$var reg 4 =" i_axi_awcache[3:0] $end +$var reg 3 >" i_axi_awprot[2:0] $end +$var reg 4 ?" i_axi_awqos[3:0] $end +$var reg 4 @" i_axi_awregion[3:0] $end +$comment i_axi_awuser is not handled $end +$var reg 1 A" i_axi_awvalid $end +$var reg 1 B" o_axi_awready $end +$var reg 8 C" i_axi_wdata[7:0] $end +$var reg 1 D" i_axi_wstrb[0:0] $end +$var reg 1 E" i_axi_wlast $end +$comment i_axi_wuser is not handled $end +$var reg 1 F" i_axi_wvalid $end +$var reg 1 G" o_axi_wready $end +$var reg 3 H" o_axi_bid[2:0] $end +$var reg 2 I" o_axi_bresp[1:0] $end +$comment o_axi_buser is not handled $end +$var reg 1 J" o_axi_bvalid $end +$var reg 1 K" i_axi_bready $end +$var reg 3 L" i_axi_arid[2:0] $end +$var reg 8 M" i_axi_araddr[7:0] $end +$var reg 8 N" i_axi_arlen[7:0] $end +$var reg 3 O" i_axi_arsize[2:0] $end +$var reg 2 P" i_axi_arburst[1:0] $end +$var reg 1 Q" i_axi_arlock $end +$var reg 4 R" i_axi_arcache[3:0] $end +$var reg 3 S" i_axi_arprot[2:0] $end +$var reg 4 T" i_axi_arqos[3:0] $end +$var reg 4 U" i_axi_arregion[3:0] $end +$comment i_axi_aruser is not handled $end +$var reg 1 V" i_axi_arvalid $end +$var reg 1 W" o_axi_arready $end +$var reg 3 X" o_axi_rid[2:0] $end +$var reg 8 Y" o_axi_rdata[7:0] $end +$var reg 2 Z" o_axi_rresp[1:0] $end +$var reg 1 [" o_axi_rlast $end +$comment o_axi_ruser is not handled $end +$var reg 1 \" o_axi_rvalid $end +$var reg 1 ]" i_axi_rready $end +$scope module skidbuffer_inst $end +$var reg 1 ^" clock $end +$var reg 1 _" reset_n $end +$var reg 1 `" s_valid_i $end +$var reg 1 a" s_last_i $end +$var reg 1 b" s_ready_o $end +$var reg 9 c" s_data_i[8:0] $end +$var reg 1 d" m_valid_o $end +$var reg 1 e" m_last_o $end +$var reg 1 f" m_ready_i $end +$var reg 9 g" m_data_o[8:0] $end +$var reg 9 h" reg_data[8:0] $end +$var reg 1 i" reg_last $end +$var reg 1 j" reg_valid $end +$var reg 1 k" reg_ready $end +$var reg 9 l" skd_data[8:0] $end +$var reg 1 m" skd_last $end +$var reg 9 n" out_data[8:0] $end +$var reg 1 o" out_last $end +$scope module gen_data_register $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +0! +0" +0# +bUUUUUUUU $ +U% +bUUUUUUUU & +bU ' +U( +0) +1* +0+ +bUUU , +bUUUUUUUU - +bUUUUUUUU . +bUUU / +bUU 0 +U1 +bUUUU 2 +bUUU 3 +bUUUU 4 +bUUUU 5 +U6 +U7 +bUUUUUUUU 8 +bU 9 +U: +U; +U< +bUUU = +bUU > +U? +U@ +bUUU A +bUUUUUUUU B +bUUUUUUUU C +bUUU D +bUU E +UF +bUUUU G +bUUU H +bUUUU I +bUUUU J +UK +UL +bUUU M +bUUUUUUUU N +bUU O +UP +UQ +UR +b00000000 S +b00000000 T +1U +0V +bUUU W +bUUUUUUUU X +bUUUUUUUU Y +bUUU Z +bUU [ +U\ +bUUUU ] +bUUU ^ +bUUUU _ +bUUUU ` +Ua +Ub +bUUUUUUUU c +bU d +Ue +Uf +Ug +bUUU h +bUU i +Uj +Uk +bUUU l +bUUUUUUUU m +bUUUUUUUU n +bUUU o +bUU p +Uq +bUUUU r +bUUU s +bUUUU t +bUUUU u +Uv +Uw +bUUU x +bUUUUUUUU y +bUU z +U{ +U| +U} +U!" +bUUUUUUUU "" +bU #" +U$" +0%" +1&" +0'" +U(" +bUUUUUUUU )" +bUUUUUUUUU *" +bU +" +U," +U-" +U." +bUUUUUUUU /" +bUUUUUUUUU 0" +bU 1" +U2" +03" +bUUU 4" +U5" +bUU 6" +bUUU 7" +bUUUUUUUU 8" +bUUUUUUUU 9" +bUUU :" +bUU ;" +U<" +bUUUU =" +bUUU >" +bUUUU ?" +bUUUU @" +UA" +UB" +bUUUUUUUU C" +bU D" +UE" +UF" +UG" +bUUU H" +bUU I" +UJ" +UK" +bUUU L" +bUUUUUUUU M" +bUUUUUUUU N" +bUUU O" +bUU P" +UQ" +bUUUU R" +bUUU S" +bUUUU T" +bUUUU U" +UV" +UW" +bUUU X" +bUUUUUUUU Y" +bUU Z" +U[" +U\" +U]" +1^" +0_" +U`" +Ua" +Ub" +bUUUUUUUUU c" +Ud" +Ue" +0f" +bUUUUUUUUU g" +bUUUUUUUUU h" +Ui" +Uj" +Uk" +bUUUUUUUUU l" +Um" +bUUUUUUUUU n" +Uo" +#2500000 +0* +0U +0&" +0^" +#5000000 +b00000000 $ +0% +b00000000 & +b0 ' +0( +1* +b000 , +b00000000 - +b00000000 . +b000 / +b00 0 +01 +b0000 2 +b000 3 +b0000 4 +b0000 5 +06 +17 +b00000000 8 +b0 9 +0: +0; +0< +b000 = +b00 > +0? +1@ +b00000001 S +1U +b000 W +b00000000 X +b00000000 Y +b000 Z +b00 [ +0\ +b0000 ] +b000 ^ +b0000 _ +b0000 ` +0a +1b +b00000000 c +b0 d +0e +0f +0g +b000 h +b00 i +0j +1k +0!" +b00000000 "" +b0 #" +0$" +1&" +0(" +b00000000 )" +b000000000 *" +b0 +" +0," +0-" +0." +b00000000 /" +b000000000 0" +b0 1" +02" +05" +b00 6" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0<" +b0000 =" +b000 >" +b0000 ?" +b0000 @" +0A" +1B" +b00000000 C" +b0 D" +0E" +0F" +0G" +b000 H" +b00 I" +0J" +1K" +1^" +0`" +0a" +0b" +b000000000 c" +0d" +0e" +b000000000 g" +b000000000 h" +0i" +0j" +0k" +b000000000 l" +0m" +b000000000 n" +0o" +#6250000 +1+ +1V +1'" +1_" +#7500000 +0* +0U +0&" +0^" +#10000000 +1" +1* +b00000010 S +1U +1&" +b01 6" +1^" +#12500000 +0* +0U +0&" +0^" +#15000000 +1! +1) +1* +b00000011 S +b00000001 T +1U +1%" +1&" +13" +1^" +1f" +#17500000 +0* +0U +0&" +0^" +#20000000 +1* +b101 , +b01000010 - +b00111111 . +b110 / +b01 0 +16 +1< +b00000100 S +1U +b101 W +b01000010 X +b00111111 Y +b110 Z +b01 [ +1a +1g +1&" +1-" +b101 7" +b01000010 8" +b00111111 9" +b110 :" +b01 ;" +1A" +1G" +1^" +1b" +1k" +#22500000 +0* +0U +0&" +0^" +#25000000 +0! +1# +b00000001 $ +1* +b000 , +b00000000 - +b00000000 . +b000 / +b00 0 +06 +07 +b00000001 8 +b1 9 +1; +b101 = +b00000101 S +1U +b000 W +b00000000 X +b00000000 Y +b000 Z +b00 [ +0a +0b +b00000001 c +b1 d +1f +b101 h +1&" +1(" +b00000001 )" +b000000011 *" +b1 +" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0A" +0B" +b00000001 C" +b1 D" +1F" +b101 H" +1^" +1`" +b000000011 c" +#27500000 +0* +0U +0&" +0^" +#30000000 +b00000010 $ +1% +b00000001 & +b1 ' +1* +17 +b00000010 8 +b00000110 S +1U +1b +b00000010 c +1!" +b00000001 "" +b1 #" +1&" +b00000010 )" +b000000101 *" +1." +b00000001 /" +b000000011 0" +b1 1" +b10 6" +1B" +b00000010 C" +1^" +b000000101 c" +1d" +b000000011 g" +b000000011 h" +1j" +b000000011 l" +b000000011 n" +#32500000 +0* +0U +0&" +0^" +#35000000 +b00000011 $ +b00000010 & +1* +b00000011 8 +b00000111 S +1U +b00000011 c +b00000010 "" +1&" +b00000011 )" +b000000111 *" +b00000010 /" +b000000101 0" +b00000011 C" +1^" +b000000111 c" +b000000101 g" +b000000101 h" +b000000101 l" +b000000101 n" +#37500000 +0* +0U +0&" +0^" +#40000000 +b00000100 $ +b00000011 & +1* +b00000100 8 +b00001000 S +1U +b00000100 c +b00000011 "" +1&" +b00000100 )" +b000001001 *" +b00000011 /" +b000000111 0" +b00000100 C" +1^" +b000001001 c" +b000000111 g" +b000000111 h" +b000000111 l" +b000000111 n" +#42500000 +0* +0U +0&" +0^" +#45000000 +b00000101 $ +b00000100 & +1* +b00000101 8 +b00001001 S +1U +b00000101 c +b00000100 "" +1&" +b00000101 )" +b000001011 *" +b00000100 /" +b000001001 0" +b00000101 C" +1^" +b000001011 c" +b000001001 g" +b000001001 h" +b000001001 l" +b000001001 n" +#47500000 +0* +0U +0&" +0^" +#50000000 +b00000110 $ +b00000101 & +1* +b00000110 8 +b00001010 S +1U +b00000110 c +b00000101 "" +1&" +b00000110 )" +b000001101 *" +b00000101 /" +b000001011 0" +b00000110 C" +1^" +b000001101 c" +b000001011 g" +b000001011 h" +b000001011 l" +b000001011 n" +#52500000 +0* +0U +0&" +0^" +#55000000 +b00000111 $ +b00000110 & +1* +b00000111 8 +b00001011 S +1U +b00000111 c +b00000110 "" +1&" +b00000111 )" +b000001111 *" +b00000110 /" +b000001101 0" +b00000111 C" +1^" +b000001111 c" +b000001101 g" +b000001101 h" +b000001101 l" +b000001101 n" +#57500000 +0* +0U +0&" +0^" +#60000000 +b00001000 $ +b00000111 & +1* +b00001000 8 +b00001100 S +1U +b00001000 c +b00000111 "" +1&" +b00001000 )" +b000010001 *" +b00000111 /" +b000001111 0" +b00001000 C" +1^" +b000010001 c" +b000001111 g" +b000001111 h" +b000001111 l" +b000001111 n" +#62500000 +0* +0U +0&" +0^" +#65000000 +b00001001 $ +b00001000 & +1* +b00001001 8 +b00001101 S +1U +b00001001 c +b00001000 "" +1&" +b00001001 )" +b000010011 *" +b00001000 /" +b000010001 0" +b00001001 C" +1^" +b000010011 c" +b000010001 g" +b000010001 h" +b000010001 l" +b000010001 n" +#67500000 +0* +0U +0&" +0^" +#70000000 +b00001010 $ +b00001001 & +1* +b00001010 8 +b00001110 S +1U +b00001010 c +b00001001 "" +1&" +b00001010 )" +b000010101 *" +b00001001 /" +b000010011 0" +b00001010 C" +1^" +b000010101 c" +b000010011 g" +b000010011 h" +b000010011 l" +b000010011 n" +#72500000 +0* +0U +0&" +0^" +#75000000 +b00001011 $ +b00001010 & +1* +b00001011 8 +b00001111 S +1U +b00001011 c +b00001010 "" +1&" +b00001011 )" +b000010111 *" +b00001010 /" +b000010101 0" +b00001011 C" +1^" +b000010111 c" +b000010101 g" +b000010101 h" +b000010101 l" +b000010101 n" +#77500000 +0* +0U +0&" +0^" +#80000000 +b00001100 $ +b00001011 & +1* +b00001100 8 +b00010000 S +1U +b00001100 c +b00001011 "" +1&" +b00001100 )" +b000011001 *" +b00001011 /" +b000010111 0" +b00001100 C" +1^" +b000011001 c" +b000010111 g" +b000010111 h" +b000010111 l" +b000010111 n" +#82500000 +0* +0U +0&" +0^" +#85000000 +b00001101 $ +b00001100 & +1* +b00001101 8 +b00010001 S +1U +b00001101 c +b00001100 "" +1&" +b00001101 )" +b000011011 *" +b00001100 /" +b000011001 0" +b00001101 C" +1^" +b000011011 c" +b000011001 g" +b000011001 h" +b000011001 l" +b000011001 n" +#87500000 +0* +0U +0&" +0^" +#90000000 +b00001110 $ +b00001101 & +1* +b00001110 8 +b00010010 S +1U +b00001110 c +b00001101 "" +1&" +b00001110 )" +b000011101 *" +b00001101 /" +b000011011 0" +b00001110 C" +1^" +b000011101 c" +b000011011 g" +b000011011 h" +b000011011 l" +b000011011 n" +#92500000 +0* +0U +0&" +0^" +#95000000 +b00001111 $ +b00001110 & +1* +b00001111 8 +b00010011 S +1U +b00001111 c +b00001110 "" +1&" +b00001111 )" +b000011111 *" +b00001110 /" +b000011101 0" +b00001111 C" +1^" +b000011111 c" +b000011101 g" +b000011101 h" +b000011101 l" +b000011101 n" +#97500000 +0* +0U +0&" +0^" +#100000000 +1! +b00010000 $ +b00001111 & +1* +b00010000 8 +1: +b00010100 S +b00000010 T +1U +b00010000 c +1e +b00001111 "" +1&" +b00010000 )" +b000100001 *" +1," +b00001111 /" +b000011111 0" +b00010000 C" +1E" +1^" +1a" +b000100001 c" +b000011111 g" +b000011111 h" +b000011111 l" +b000011111 n" +#102500000 +0* +0U +0&" +0^" +#105000000 +b00000001 $ +b00010000 & +1( +1* +b101 , +b01000010 - +b00111111 . +b110 / +b01 0 +16 +b00000001 8 +0: +b00010101 S +b00000001 T +1U +b101 W +b01000010 X +b00111111 Y +b110 Z +b01 [ +1a +b00000001 c +0e +b00010000 "" +1$" +1&" +b00000001 )" +b000000011 *" +0," +b00010000 /" +b000100001 0" +12" +b101 7" +b01000010 8" +b00111111 9" +b110 :" +b01 ;" +1A" +b00000001 C" +0E" +1^" +0a" +b000000011 c" +1e" +b000100001 g" +b000100001 h" +1i" +b000100001 l" +1m" +b000100001 n" +1o" +#107500000 +0* +0U +0&" +0^" +#110000000 +0! +b00000010 $ +b00000001 & +0( +1* +b000 , +b00000000 - +b00000000 . +b000 / +b00 0 +06 +07 +b00000010 8 +b00010110 S +1U +b000 W +b00000000 X +b00000000 Y +b000 Z +b00 [ +0a +0b +b00000010 c +b00000001 "" +0$" +1&" +b00000010 )" +b000000101 *" +b00000001 /" +b000000011 0" +02" +b101 4" +15" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0A" +0B" +b00000010 C" +1^" +b000000101 c" +0e" +b000000011 g" +b000000011 h" +0i" +b000000011 l" +0m" +b000000011 n" +0o" +#112500000 +0* +0U +0&" +0^" +#115000000 +b00000011 $ +b00000010 & +1* +17 +b00000011 8 +1? +b00010111 S +1U +1b +b00000011 c +1j +b00000010 "" +1&" +b00000011 )" +b000000111 *" +b00000010 /" +b000000101 0" +05" +b11 6" +1B" +b00000011 C" +1J" +1^" +b000000111 c" +b000000101 g" +b000000101 h" +b000000101 l" +b000000101 n" +#117500000 +0* +0U +0&" +0^" +#120000000 +b00000100 $ +b00000011 & +1* +b00000100 8 +0? +0@ +b00011000 S +1U +b00000100 c +0j +0k +b00000011 "" +1&" +b00000100 )" +b000001001 *" +b00000011 /" +b000000111 0" +b10 6" +b00000100 C" +0J" +0K" +1^" +b000001001 c" +b000000111 g" +b000000111 h" +b000000111 l" +b000000111 n" +#122500000 +0* +0U +0&" +0^" +#125000000 +b00000101 $ +b00000100 & +1* +b00000101 8 +1@ +b00011001 S +1U +b00000101 c +1k +b00000100 "" +1&" +b00000101 )" +b000001011 *" +b00000100 /" +b000001001 0" +b00000101 C" +1K" +1^" +b000001011 c" +b000001001 g" +b000001001 h" +b000001001 l" +b000001001 n" +#127500000 +0* +0U +0&" +0^" +#130000000 +b00000110 $ +b00000101 & +1* +b00000110 8 +b00011010 S +1U +b00000110 c +b00000101 "" +1&" +b00000110 )" +b000001101 *" +b00000101 /" +b000001011 0" +b00000110 C" +1^" +b000001101 c" +b000001011 g" +b000001011 h" +b000001011 l" +b000001011 n" +#132500000 +0* +0U +0&" +0^" +#135000000 +b00000111 $ +b00000110 & +1* +b00000111 8 +b00011011 S +1U +b00000111 c +b00000110 "" +1&" +b00000111 )" +b000001111 *" +b00000110 /" +b000001101 0" +b00000111 C" +1^" +b000001111 c" +b000001101 g" +b000001101 h" +b000001101 l" +b000001101 n" +#137500000 +0* +0U +0&" +0^" +#140000000 +b00001000 $ +b00000111 & +1* +b00001000 8 +b00011100 S +1U +b00001000 c +b00000111 "" +1&" +b00001000 )" +b000010001 *" +b00000111 /" +b000001111 0" +b00001000 C" +1^" +b000010001 c" +b000001111 g" +b000001111 h" +b000001111 l" +b000001111 n" +#142500000 +0* +0U +0&" +0^" +#145000000 +b00001001 $ +b00001000 & +1* +b00001001 8 +b00011101 S +1U +b00001001 c +b00001000 "" +1&" +b00001001 )" +b000010011 *" +b00001000 /" +b000010001 0" +b00001001 C" +1^" +b000010011 c" +b000010001 g" +b000010001 h" +b000010001 l" +b000010001 n" +#147500000 +0* +0U +0&" +0^" +#150000000 +b00001010 $ +b00001001 & +1* +b00001010 8 +b00011110 S +1U +b00001010 c +b00001001 "" +1&" +b00001010 )" +b000010101 *" +b00001001 /" +b000010011 0" +b00001010 C" +1^" +b000010101 c" +b000010011 g" +b000010011 h" +b000010011 l" +b000010011 n" +#152500000 +0* +0U +0&" +0^" +#155000000 +b00001011 $ +b00001010 & +1* +b00001011 8 +b00011111 S +1U +b00001011 c +b00001010 "" +1&" +b00001011 )" +b000010111 *" +b00001010 /" +b000010101 0" +b00001011 C" +1^" +b000010111 c" +b000010101 g" +b000010101 h" +b000010101 l" +b000010101 n" +#157500000 +0* +0U +0&" +0^" +#160000000 +b00001100 $ +b00001011 & +1* +b00001100 8 +b00100000 S +1U +b00001100 c +b00001011 "" +1&" +b00001100 )" +b000011001 *" +b00001011 /" +b000010111 0" +b00001100 C" +1^" +b000011001 c" +b000010111 g" +b000010111 h" +b000010111 l" +b000010111 n" +#162500000 +0* +0U +0&" +0^" +#165000000 +b00001101 $ +b00001100 & +1* +b00001101 8 +b00100001 S +1U +b00001101 c +b00001100 "" +1&" +b00001101 )" +b000011011 *" +b00001100 /" +b000011001 0" +b00001101 C" +1^" +b000011011 c" +b000011001 g" +b000011001 h" +b000011001 l" +b000011001 n" +#167500000 +0* +0U +0&" +0^" +#170000000 +b00001110 $ +b00001101 & +1* +b00001110 8 +b00100010 S +1U +b00001110 c +b00001101 "" +1&" +b00001110 )" +b000011101 *" +b00001101 /" +b000011011 0" +b00001110 C" +1^" +b000011101 c" +b000011011 g" +b000011011 h" +b000011011 l" +b000011011 n" +#172500000 +0* +0U +0&" +0^" +#175000000 +b00001111 $ +b00001110 & +1* +b00001111 8 +b00100011 S +1U +b00001111 c +b00001110 "" +1&" +b00001111 )" +b000011111 *" +b00001110 /" +b000011101 0" +b00001111 C" +1^" +b000011111 c" +b000011101 g" +b000011101 h" +b000011101 l" +b000011101 n" +#177500000 +0* +0U +0&" +0^" +#180000000 +b00010000 $ +b00001111 & +1* +b00010000 8 +1: +b00100100 S +1U +b00010000 c +1e +b00001111 "" +1&" +b00010000 )" +b000100001 *" +1," +b00001111 /" +b000011111 0" +b00010000 C" +1E" +1^" +1a" +b000100001 c" +b000011111 g" +b000011111 h" +b000011111 l" +b000011111 n" +#182500000 +0* +0U +0&" +0^" +#185000000 +0# +b00000000 $ +b00010000 & +1( +1* +b00000000 8 +b0 9 +0: +0; +b00100101 S +b00000000 T +1U +b00000000 c +b0 d +0e +0f +b00010000 "" +1$" +1&" +0(" +b00000000 )" +b000000000 *" +b0 +" +0," +b00010000 /" +b000100001 0" +12" +b00000000 C" +b0 D" +0E" +0F" +1^" +0`" +0a" +b000000000 c" +1e" +b000100001 g" +b000100001 h" +1i" +b000100001 l" +1m" +b000100001 n" +1o" +#187500000 +0* +0U +0&" +0^" +#190000000 +0% +b00000000 & +b0 ' +0( +1* +1? +b00100110 S +1U +1j +0!" +b00000000 "" +b0 #" +0$" +1&" +0." +b00000000 /" +b000000000 0" +b0 1" +02" +1J" +1^" +0d" +0e" +b000000000 g" +b000000000 h" +0i" +0j" +b000000000 l" +0m" +b000000000 n" +0o" +#192500000 +0* +0U +0&" +0^" +#195000000 +1* +0? +0@ +b00100111 S +1U +0j +0k +1&" +b01 6" +0J" +0K" +1^" +#197500000 +0* +0U +0&" +0^" +#200000000 +1* +1@ +b00101000 S +1U +1k +1&" +1K" +1^" +#202500000 +0* +0U +0&" +0^" +#205000000 +1* +b00101001 S +1U +1&" +1^" +#207500000 +0* +0U +0&" +0^" +#210000000 +1* +b00101010 S +1U +1&" +1^" +#212500000 +0* +0U +0&" +0^" +#215000000 +1* +b00101011 S +1U +1&" +1^" +#217500000 +0* +0U +0&" +0^" +#220000000 +1* +b00101100 S +1U +1&" +1^" +#222500000 +0* +0U +0&" +0^" +#225000000 +1* +b00101101 S +1U +1&" +1^" +#227500000 +0* +0U +0&" +0^" +#230000000 +1! +1* +b00101110 S +b00000001 T +1U +1&" +1^" +#232500000 +0* +0U +0&" +0^" +#235000000 +1* +b101 , +b01000010 - +b00111111 . +b110 / +b01 0 +16 +b00101111 S +1U +b101 W +b01000010 X +b00111111 Y +b110 Z +b01 [ +1a +1&" +b101 7" +b01000010 8" +b00111111 9" +b110 :" +b01 ;" +1A" +1^" +#237500000 +0* +0U +0&" +0^" +#240000000 +0! +1# +b00000001 $ +1* +b000 , +b00000000 - +b00000000 . +b000 / +b00 0 +06 +07 +b00000001 8 +b1 9 +1; +b00110000 S +1U +b000 W +b00000000 X +b00000000 Y +b000 Z +b00 [ +0a +0b +b00000001 c +b1 d +1f +1&" +1(" +b00000001 )" +b000000011 *" +b1 +" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0A" +0B" +b00000001 C" +b1 D" +1F" +1^" +1`" +b000000011 c" +#242500000 +0* +0U +0&" +0^" +#245000000 +b00000010 $ +1% +b00000001 & +b1 ' +1* +17 +b00000010 8 +b00110001 S +1U +1b +b00000010 c +1!" +b00000001 "" +b1 #" +1&" +b00000010 )" +b000000101 *" +1." +b00000001 /" +b000000011 0" +b1 1" +b10 6" +1B" +b00000010 C" +1^" +b000000101 c" +1d" +b000000011 g" +b000000011 h" +1j" +b000000011 l" +b000000011 n" +#247500000 +0* +0U +0&" +0^" +#250000000 +b00000011 $ +b00000010 & +1* +b00000011 8 +b00110010 S +1U +b00000011 c +b00000010 "" +1&" +b00000011 )" +b000000111 *" +b00000010 /" +b000000101 0" +b00000011 C" +1^" +b000000111 c" +b000000101 g" +b000000101 h" +b000000101 l" +b000000101 n" +#252500000 +0* +0U +0&" +0^" +#255000000 +b00000100 $ +b00000011 & +1* +b00000100 8 +b00110011 S +1U +b00000100 c +b00000011 "" +1&" +b00000100 )" +b000001001 *" +b00000011 /" +b000000111 0" +b00000100 C" +1^" +b000001001 c" +b000000111 g" +b000000111 h" +b000000111 l" +b000000111 n" +#257500000 +0* +0U +0&" +0^" +#260000000 +0" +b00000101 $ +b00000100 & +1* +b00000101 8 +b00110100 S +1U +b00000101 c +b00000100 "" +1&" +b00000101 )" +b000001011 *" +b00000100 /" +b000001001 0" +b00000101 C" +1^" +b000001011 c" +b000001001 g" +b000001001 h" +b000001001 l" +b000001001 n" +#262500000 +0* +0U +0&" +0^" +#265000000 +b00000110 $ +b00000101 & +0) +1* +b00000110 8 +b00110101 S +1U +b00000110 c +b00000101 "" +0%" +1&" +b00000110 )" +b000001101 *" +b00000101 /" +b000001011 0" +03" +b00000110 C" +1^" +b000001101 c" +0f" +b000001011 g" +b000001011 h" +b000001011 l" +b000001011 n" +#267500000 +0* +0U +0&" +0^" +#270000000 +b00000111 $ +1* +b00000111 8 +0< +b00110110 S +1U +b00000111 c +0g +1&" +b00000111 )" +b000001111 *" +0-" +b00000111 C" +0G" +1^" +0b" +b000001111 c" +0k" +b000001101 l" +#272500000 +0* +0U +0&" +0^" +#275000000 +1* +b00110111 S +1U +1&" +1^" +#277500000 +0* +0U +0&" +0^" +#280000000 +1! +1* +b00111000 S +b00000010 T +1U +1&" +1^" +#282500000 +0* +0U +0&" +0^" +#285000000 +1* +b101 , +b01000010 - +b00111111 . +b110 / +b01 0 +16 +b00111001 S +1U +b101 W +b01000010 X +b00111111 Y +b110 Z +b01 [ +1a +1&" +b101 7" +b01000010 8" +b00111111 9" +b110 :" +b01 ;" +1A" +1^" +#287500000 +0* +0U +0&" +0^" +#290000000 +0! +1* +b000 , +b00000000 - +b00000000 . +b000 / +b00 0 +06 +07 +b00111010 S +1U +b000 W +b00000000 X +b00000000 Y +b000 Z +b00 [ +0a +0b +1&" +b000 7" +b00000000 8" +b00000000 9" +b000 :" +b00 ;" +0A" +0B" +1^" +#292500000 +0* +0U +0&" +0^" +#295000000 +1* +b00111011 S +1U +1&" +b11 6" +1^" +#297500000 +0* +0U +0&" +0^" +#300000000 +1* +b00111100 S +1U +1&" +1^" +#302500000 +0* +0U +0&" +0^" +#305000000 +1* +b00111101 S +1U +1&" +1^" +#307500000 +0* +0U +0&" +0^" +#310000000 +1* +b00111110 S +1U +1&" +1^" +#312500000 +0* +0U +0&" +0^" +#315000000 +1* +b00111111 S +1U +1&" +1^" +#317500000 +0* +0U +0&" +0^" +#320000000 +1* +b01000000 S +1U +1&" +1^" +#322500000 +0* +0U +0&" +0^" +#325000000 +1* +b01000001 S +1U +1&" +1^" +#327500000 +0* +0U +0&" +0^" +#330000000 +1* +b01000010 S +1U +1&" +1^" +#332500000 +0* +0U +0&" +0^" +#335000000 +1* +b01000011 S +1U +1&" +1^" +#337500000 +0* +0U +0&" +0^" +#340000000 +1* +b01000100 S +1U +1&" +1^" +#342500000 +0* +0U +0&" +0^" +#345000000 +1* +b01000101 S +1U +1&" +1^" +#347500000 +0* +0U +0&" +0^" +#350000000 +1" +1* +b01000110 S +1U +1&" +1^" +#352500000 +0* +0U +0&" +0^" +#355000000 +1) +1* +b01000111 S +1U +1%" +1&" +13" +1^" +1f" +#357500000 +0* +0U +0&" +0^" +#360000000 +b00000110 & +1* +1< +b01001000 S +1U +1g +b00000110 "" +1&" +1-" +b00000110 /" +b000001101 0" +1G" +1^" +1b" +b000001101 g" +b000001101 h" +1k" +b000001101 n" +#362500000 +0* +0U +0&" +0^" +#365000000 +b00001000 $ +b00000111 & +1* +b00001000 8 +b01001001 S +1U +b00001000 c +b00000111 "" +1&" +b00001000 )" +b000010001 *" +b00000111 /" +b000001111 0" +b00001000 C" +1^" +b000010001 c" +b000001111 g" +b000001111 h" +b000001111 l" +b000001111 n" +#367500000 +0* +0U +0&" +0^" +#370000000 +b00001001 $ +b00001000 & +1* +b00001001 8 +b01001010 S +1U +b00001001 c +b00001000 "" +1&" +b00001001 )" +b000010011 *" +b00001000 /" +b000010001 0" +b00001001 C" +1^" +b000010011 c" +b000010001 g" +b000010001 h" +b000010001 l" +b000010001 n" +#372500000 +0* +0U +0&" +0^" +#375000000 +b00001010 $ +b00001001 & +1* +b00001010 8 +b01001011 S +1U +b00001010 c +b00001001 "" +1&" +b00001010 )" +b000010101 *" +b00001001 /" +b000010011 0" +b00001010 C" +1^" +b000010101 c" +b000010011 g" +b000010011 h" +b000010011 l" +b000010011 n" +#377500000 +0* +0U +0&" +0^" +#380000000 +b00001011 $ +b00001010 & +1* +b00001011 8 +b01001100 S +1U +b00001011 c +b00001010 "" +1&" +b00001011 )" +b000010111 *" +b00001010 /" +b000010101 0" +b00001011 C" +1^" +b000010111 c" +b000010101 g" +b000010101 h" +b000010101 l" +b000010101 n" +#382500000 +0* +0U +0&" +0^" +#385000000 +b00001100 $ +b00001011 & +1* +b00001100 8 +b01001101 S +1U +b00001100 c +b00001011 "" +1&" +b00001100 )" +b000011001 *" +b00001011 /" +b000010111 0" +b00001100 C" +1^" +b000011001 c" +b000010111 g" +b000010111 h" +b000010111 l" +b000010111 n" +#387500000 +0* +0U +0&" +0^" +#390000000 +b00001101 $ +b00001100 & +1* +b00001101 8 +b01001110 S +1U +b00001101 c +b00001100 "" +1&" +b00001101 )" +b000011011 *" +b00001100 /" +b000011001 0" +b00001101 C" +1^" +b000011011 c" +b000011001 g" +b000011001 h" +b000011001 l" +b000011001 n" +#392500000 +0* +0U +0&" +0^" +#395000000 +b00001110 $ +b00001101 & +1* +b00001110 8 +b01001111 S +1U +b00001110 c +b00001101 "" +1&" +b00001110 )" +b000011101 *" +b00001101 /" +b000011011 0" +b00001110 C" +1^" +b000011101 c" +b000011011 g" +b000011011 h" +b000011011 l" +b000011011 n" +#397500000 +0* +0U +0&" +0^" +#400000000 +b00001111 $ +b00001110 & +1* +b00001111 8 +b01010000 S +1U +b00001111 c +b00001110 "" +1&" +b00001111 )" +b000011111 *" +b00001110 /" +b000011101 0" +b00001111 C" +1^" +b000011111 c" +b000011101 g" +b000011101 h" +b000011101 l" +b000011101 n" +#402500000 +0* +0U +0&" +0^" +#405000000 +b00010000 $ +b00001111 & +1* +b00010000 8 +1: +b01010001 S +1U +b00010000 c +1e +b00001111 "" +1&" +b00010000 )" +b000100001 *" +1," +b00001111 /" +b000011111 0" +b00010000 C" +1E" +1^" +1a" +b000100001 c" +b000011111 g" +b000011111 h" +b000011111 l" +b000011111 n" +#407500000 +0* +0U +0&" +0^" +#410000000 +b00000001 $ +b00010000 & +1( +1* +b00000001 8 +0: +b01010010 S +b00000001 T +1U +b00000001 c +0e +b00010000 "" +1$" +1&" +b00000001 )" +b000000011 *" +0," +b00010000 /" +b000100001 0" +12" +b00000001 C" +0E" +1^" +0a" +b000000011 c" +1e" +b000100001 g" +b000100001 h" +1i" +b000100001 l" +1m" +b000100001 n" +1o" +#412500000 +0* +0U +0&" +0^" +#415000000 +b00000010 $ +b00000001 & +0( +1* +17 +b00000010 8 +1? +b01010011 S +1U +1b +b00000010 c +1j +b00000001 "" +0$" +1&" +b00000010 )" +b000000101 *" +b00000001 /" +b000000011 0" +02" +1B" +b00000010 C" +1J" +1^" +b000000101 c" +0e" +b000000011 g" +b000000011 h" +0i" +b000000011 l" +0m" +b000000011 n" +0o" +#417500000 +0* +0U +0&" +0^" +#420000000 +b00000011 $ +b00000010 & +1* +b00000011 8 +0? +0@ +b01010100 S +1U +b00000011 c +0j +0k +b00000010 "" +1&" +b00000011 )" +b000000111 *" +b00000010 /" +b000000101 0" +b10 6" +b00000011 C" +0J" +0K" +1^" +b000000111 c" +b000000101 g" +b000000101 h" +b000000101 l" +b000000101 n" +#422500000 +0* +0U +0&" +0^" +#425000000 +b00000100 $ +b00000011 & +1* +b00000100 8 +1@ +b01010101 S +1U +b00000100 c +1k +b00000011 "" +1&" +b00000100 )" +b000001001 *" +b00000011 /" +b000000111 0" +b00000100 C" +1K" +1^" +b000001001 c" +b000000111 g" +b000000111 h" +b000000111 l" +b000000111 n" +#427500000 +0* +0U +0&" +0^" +#430000000 +b00000101 $ +b00000100 & +1* +b00000101 8 +b01010110 S +1U +b00000101 c +b00000100 "" +1&" +b00000101 )" +b000001011 *" +b00000100 /" +b000001001 0" +b00000101 C" +1^" +b000001011 c" +b000001001 g" +b000001001 h" +b000001001 l" +b000001001 n" +#432500000 +0* +0U +0&" +0^" +#435000000 +b00000110 $ +b00000101 & +1* +b00000110 8 +b01010111 S +1U +b00000110 c +b00000101 "" +1&" +b00000110 )" +b000001101 *" +b00000101 /" +b000001011 0" +b00000110 C" +1^" +b000001101 c" +b000001011 g" +b000001011 h" +b000001011 l" +b000001011 n" +#437500000 +0* +0U +0&" +0^" +#440000000 +b00000111 $ +b00000110 & +1* +b00000111 8 +b01011000 S +1U +b00000111 c +b00000110 "" +1&" +b00000111 )" +b000001111 *" +b00000110 /" +b000001101 0" +b00000111 C" +1^" +b000001111 c" +b000001101 g" +b000001101 h" +b000001101 l" +b000001101 n" +#442500000 +0* +0U +0&" +0^" +#445000000 +b00001000 $ +b00000111 & +1* +b00001000 8 +b01011001 S +1U +b00001000 c +b00000111 "" +1&" +b00001000 )" +b000010001 *" +b00000111 /" +b000001111 0" +b00001000 C" +1^" +b000010001 c" +b000001111 g" +b000001111 h" +b000001111 l" +b000001111 n" +#447500000 +0* +0U +0&" +0^" +#450000000 +b00001001 $ +b00001000 & +1* +b00001001 8 +b01011010 S +1U +b00001001 c +b00001000 "" +1&" +b00001001 )" +b000010011 *" +b00001000 /" +b000010001 0" +b00001001 C" +1^" +b000010011 c" +b000010001 g" +b000010001 h" +b000010001 l" +b000010001 n" +#452500000 +0* +0U +0&" +0^" +#455000000 +b00001010 $ +b00001001 & +1* +b00001010 8 +b01011011 S +1U +b00001010 c +b00001001 "" +1&" +b00001010 )" +b000010101 *" +b00001001 /" +b000010011 0" +b00001010 C" +1^" +b000010101 c" +b000010011 g" +b000010011 h" +b000010011 l" +b000010011 n" +#457500000 +0* +0U +0&" +0^" +#460000000 +b00001011 $ +b00001010 & +1* +b00001011 8 +b01011100 S +1U +b00001011 c +b00001010 "" +1&" +b00001011 )" +b000010111 *" +b00001010 /" +b000010101 0" +b00001011 C" +1^" +b000010111 c" +b000010101 g" +b000010101 h" +b000010101 l" +b000010101 n" +#462500000 +0* +0U +0&" +0^" +#465000000 +b00001100 $ +b00001011 & +1* +b00001100 8 +b01011101 S +1U +b00001100 c +b00001011 "" +1&" +b00001100 )" +b000011001 *" +b00001011 /" +b000010111 0" +b00001100 C" +1^" +b000011001 c" +b000010111 g" +b000010111 h" +b000010111 l" +b000010111 n" +#467500000 +0* +0U +0&" +0^" +#470000000 +b00001101 $ +b00001100 & +1* +b00001101 8 +b01011110 S +1U +b00001101 c +b00001100 "" +1&" +b00001101 )" +b000011011 *" +b00001100 /" +b000011001 0" +b00001101 C" +1^" +b000011011 c" +b000011001 g" +b000011001 h" +b000011001 l" +b000011001 n" +#472500000 +0* +0U +0&" +0^" +#475000000 +b00001110 $ +b00001101 & +1* +b00001110 8 +b01011111 S +1U +b00001110 c +b00001101 "" +1&" +b00001110 )" +b000011101 *" +b00001101 /" +b000011011 0" +b00001110 C" +1^" +b000011101 c" +b000011011 g" +b000011011 h" +b000011011 l" +b000011011 n" +#477500000 +0* +0U +0&" +0^" +#480000000 +b00001111 $ +b00001110 & +1* +b00001111 8 +b01100000 S +1U +b00001111 c +b00001110 "" +1&" +b00001111 )" +b000011111 *" +b00001110 /" +b000011101 0" +b00001111 C" +1^" +b000011111 c" +b000011101 g" +b000011101 h" +b000011101 l" +b000011101 n" +#482500000 +0* +0U +0&" +0^" +#485000000 +b00010000 $ +b00001111 & +1* +b00010000 8 +1: +b01100001 S +1U +b00010000 c +1e +b00001111 "" +1&" +b00010000 )" +b000100001 *" +1," +b00001111 /" +b000011111 0" +b00010000 C" +1E" +1^" +1a" +b000100001 c" +b000011111 g" +b000011111 h" +b000011111 l" +b000011111 n" +#487500000 +0* +0U +0&" +0^" +#490000000 +0# +b00000000 $ +b00010000 & +1( +1* +b00000000 8 +b0 9 +0: +0; +b01100010 S +b00000000 T +1U +b00000000 c +b0 d +0e +0f +b00010000 "" +1$" +1&" +0(" +b00000000 )" +b000000000 *" +b0 +" +0," +b00010000 /" +b000100001 0" +12" +b00000000 C" +b0 D" +0E" +0F" +1^" +0`" +0a" +b000000000 c" +1e" +b000100001 g" +b000100001 h" +1i" +b000100001 l" +1m" +b000100001 n" +1o" +#492500000 +0* +0U +0&" +0^" +#495000000 +0% +b00000000 & +b0 ' +0( +1* +1? +b01100011 S +1U +1j +0!" +b00000000 "" +b0 #" +0$" +1&" +0." +b00000000 /" +b000000000 0" +b0 1" +02" +1J" +1^" +0d" +0e" +b000000000 g" +b000000000 h" +0i" +0j" +b000000000 l" +0m" +b000000000 n" +0o" +#497500000 +0* +0U +0&" +0^" +#500000000 +1* +0? +0@ +b01100100 S +1U +0j +0k +1&" +b01 6" +0J" +0K" +1^" +#502500000 +0* +0U +0&" +0^" +#505000000 +1* +1@ +b01100101 S +1U +1k +1&" +1K" +1^" +#507500000 +0* +0U +0&" +0^" +#510000000 +1* +b01100110 S +1U +1&" +1^" +#512500000 +0* +0U +0&" +0^" +#515000000 +1* +b01100111 S +1U +1&" +1^" +#517500000 +0* +0U +0&" +0^" +#520000000 +1* +b01101000 S +1U +1&" +1^" +#522500000 +0* +0U +0&" +0^" +#525000000 +1* +b01101001 S +1U +1&" +1^" +#527500000 +0* +0U +0&" +0^" +#530000000 +1* +b01101010 S +1U +1&" +1^" +#532500000 +0* +0U +0&" +0^" +#535000000 +1* +b01101011 S +1U +1&" +1^" +#537500000 +0* +0U +0&" +0^" +#540000000 +1* +b01101100 S +1U +1&" +1^" +#542500000 +0* +0U +0&" +0^" +#545000000 +1* +b01101101 S +1U +1&" +1^" +#547500000 +0* +0U +0&" +0^" +#550000000 +1* +b01101110 S +1U +1&" +1^" +#552500000 +0* +0U +0&" +0^" +#555000000 +1* +b01101111 S +1U +1&" +1^" +#557500000 +0* +0U +0&" +0^" +#560000000 +1* +b01110000 S +1U +1&" +1^" +#562500000 +0* +0U +0&" +0^" +#565000000 +1* +b01110001 S +1U +1&" +1^" +#567500000 +0* +0U +0&" +0^" +#570000000 +1* +b01110010 S +1U +1&" +1^" +#572500000 +0* +0U +0&" +0^" +#575000000 +1* +b01110011 S +1U +1&" +1^" +#577500000 +0* +0U +0&" +0^" +#580000000 +1* +b01110100 S +1U +1&" +1^" +#582500000 +0* +0U +0&" +0^" +#585000000 +1* +b01110101 S +1U +1&" +1^" +#587500000 +0* +0U +0&" +0^" +#590000000 +1* +b01110110 S +1U +1&" +1^" +#592500000 +0* +0U +0&" +0^" +#595000000 +1* +b01110111 S +1U +1&" +1^" +#597500000 +0* +0U +0&" +0^" +#600000000 +1* +b01111000 S +1U +1&" +1^" +#602500000 +0* +0U +0&" +0^" +#605000000 +1* +b01111001 S +1U +1&" +1^" +#607500000 +0* +0U +0&" +0^" +#610000000 +1* +b01111010 S +1U +1&" +1^" +#612500000 +0* +0U +0&" +0^" +#615000000 +1* +b01111011 S +1U +1&" +1^" +#617500000 +0* +0U +0&" +0^" +#620000000 +1* +b01111100 S +1U +1&" +1^" +#622500000 +0* +0U +0&" +0^" +#625000000 +1* +b01111101 S +1U +1&" +1^" +#627500000 +0* +0U +0&" +0^" +#630000000 +1* +b01111110 S +1U +1&" +1^" +#632500000 +0* +0U +0&" +0^" +#635000000 +1* +b01111111 S +1U +1&" +1^" +#637500000 +0* +0U +0&" +0^" +#640000000 +1* +b10000000 S +1U +1&" +1^" +#642500000 +0* +0U +0&" +0^" +#645000000 +1* +b10000001 S +1U +1&" +1^" +#647500000 +0* +0U +0&" +0^" +#650000000 +1* +b10000010 S +1U +1&" +1^" +#652500000 +0* +0U +0&" +0^" +#655000000 +1* +b10000011 S +1U +1&" +1^" +#657500000 +0* +0U +0&" +0^" +#660000000 +1* +b10000100 S +1U +1&" +1^" +#662500000 +0* +0U +0&" +0^" +#665000000 +1* +b10000101 S +1U +1&" +1^" +#667500000 +0* +0U +0&" +0^" +#670000000 +1* +b10000110 S +1U +1&" +1^" +#672500000 +0* +0U +0&" +0^" +#675000000 +1* +b10000111 S +1U +1&" +1^" +#677500000 +0* +0U +0&" +0^" +#680000000 +1* +b10001000 S +1U +1&" +1^" +#682500000 +0* +0U +0&" +0^" +#685000000 +1* +b10001001 S +1U +1&" +1^" +#687500000 +0* +0U +0&" +0^" +#690000000 +1* +b10001010 S +1U +1&" +1^" +#692500000 +0* +0U +0&" +0^" +#695000000 +1* +b10001011 S +1U +1&" +1^" +#697500000 +0* +0U +0&" +0^" +#700000000 +1* +b10001100 S +1U +1&" +1^" +#702500000 +0* +0U +0&" +0^" +#705000000 +1* +b10001101 S +1U +1&" +1^" +#707500000 +0* +0U +0&" +0^" +#710000000 +1* +b10001110 S +1U +1&" +1^" +#712500000 +0* +0U +0&" +0^" +#715000000 +1* +b10001111 S +1U +1&" +1^" +#717500000 +0* +0U +0&" +0^" +#720000000 +1* +b10010000 S +1U +1&" +1^" +#722500000 +0* +0U +0&" +0^" +#725000000 +1* +b10010001 S +1U +1&" +1^" +#727500000 +0* +0U +0&" +0^" +#730000000 +1* +b10010010 S +1U +1&" +1^" +#732500000 +0* +0U +0&" +0^" +#735000000 +1* +b10010011 S +1U +1&" +1^" +#737500000 +0* +0U +0&" +0^" +#740000000 +1* +b10010100 S +1U +1&" +1^" +#742500000 +0* +0U +0&" +0^" +#745000000 +1* +b10010101 S +1U +1&" +1^" +#747500000 +0* +0U +0&" +0^" +#750000000 +1* +b10010110 S +1U +1&" +1^" +#752500000 +0* +0U +0&" +0^" +#755000000 +1* +b10010111 S +1U +1&" +1^" +#757500000 +0* +0U +0&" +0^" +#760000000 +1* +b10011000 S +1U +1&" +1^" +#762500000 +0* +0U +0&" +0^" +#765000000 +1* +b10011001 S +1U +1&" +1^" +#767500000 +0* +0U +0&" +0^" +#770000000 +1* +b10011010 S +1U +1&" +1^" +#772500000 +0* +0U +0&" +0^" +#775000000 +1* +b10011011 S +1U +1&" +1^" +#777500000 +0* +0U +0&" +0^" +#780000000 +1* +b10011100 S +1U +1&" +1^" +#782500000 +0* +0U +0&" +0^" +#785000000 +1* +b10011101 S +1U +1&" +1^" +#787500000 +0* +0U +0&" +0^" +#790000000 +1* +b10011110 S +1U +1&" +1^" +#792500000 +0* +0U +0&" +0^" +#795000000 +1* +b10011111 S +1U +1&" +1^" +#797500000 +0* +0U +0&" +0^" +#800000000 +1* +b10100000 S +1U +1&" +1^" +#802500000 +0* +0U +0&" +0^" +#805000000 +1* +b10100001 S +1U +1&" +1^" +#807500000 +0* +0U +0&" +0^" +#810000000 +1* +b10100010 S +1U +1&" +1^" +#812500000 +0* +0U +0&" +0^" +#815000000 +1* +b10100011 S +1U +1&" +1^" +#817500000 +0* +0U +0&" +0^" +#820000000 +1* +b10100100 S +1U +1&" +1^" +#822500000 +0* +0U +0&" +0^" +#825000000 +1* +b10100101 S +1U +1&" +1^" +#827500000 +0* +0U +0&" +0^" +#830000000 +1* +b10100110 S +1U +1&" +1^" +#832500000 +0* +0U +0&" +0^" +#835000000 +1* +b10100111 S +1U +1&" +1^" +#837500000 +0* +0U +0&" +0^" +#840000000 +1* +b10101000 S +1U +1&" +1^" +#842500000 +0* +0U +0&" +0^" +#845000000 +1* +b10101001 S +1U +1&" +1^" +#847500000 +0* +0U +0&" +0^" +#850000000 +1* +b10101010 S +1U +1&" +1^" +#852500000 +0* +0U +0&" +0^" +#855000000 +1* +b10101011 S +1U +1&" +1^" +#857500000 +0* +0U +0&" +0^" +#860000000 +1* +b10101100 S +1U +1&" +1^" +#862500000 +0* +0U +0&" +0^" +#865000000 +1* +b10101101 S +1U +1&" +1^" +#867500000 +0* +0U +0&" +0^" +#870000000 +1* +b10101110 S +1U +1&" +1^" +#872500000 +0* +0U +0&" +0^" +#875000000 +1* +b10101111 S +1U +1&" +1^" +#877500000 +0* +0U +0&" +0^" +#880000000 +1* +b10110000 S +1U +1&" +1^" +#882500000 +0* +0U +0&" +0^" +#885000000 +1* +b10110001 S +1U +1&" +1^" +#887500000 +0* +0U +0&" +0^" +#890000000 +1* +b10110010 S +1U +1&" +1^" +#892500000 +0* +0U +0&" +0^" +#895000000 +1* +b10110011 S +1U +1&" +1^" +#897500000 +0* +0U +0&" +0^" +#900000000 +1* +b10110100 S +1U +1&" +1^" +#902500000 +0* +0U +0&" +0^" +#905000000 +1* +b10110101 S +1U +1&" +1^" +#907500000 +0* +0U +0&" +0^" +#910000000 +1* +b10110110 S +1U +1&" +1^" +#912500000 +0* +0U +0&" +0^" +#915000000 +1* +b10110111 S +1U +1&" +1^" +#917500000 +0* +0U +0&" +0^" +#920000000 +1* +b10111000 S +1U +1&" +1^" +#922500000 +0* +0U +0&" +0^" +#925000000 +1* +b10111001 S +1U +1&" +1^" +#927500000 +0* +0U +0&" +0^" +#930000000 +1* +b10111010 S +1U +1&" +1^" +#932500000 +0* +0U +0&" +0^" +#935000000 +1* +b10111011 S +1U +1&" +1^" +#937500000 +0* +0U +0&" +0^" +#940000000 +1* +b10111100 S +1U +1&" +1^" +#942500000 +0* +0U +0&" +0^" +#945000000 +1* +b10111101 S +1U +1&" +1^" +#947500000 +0* +0U +0&" +0^" +#950000000 +1* +b10111110 S +1U +1&" +1^" +#952500000 +0* +0U +0&" +0^" +#955000000 +1* +b10111111 S +1U +1&" +1^" +#957500000 +0* +0U +0&" +0^" +#960000000 +1* +b11000000 S +1U +1&" +1^" +#962500000 +0* +0U +0&" +0^" +#965000000 +1* +b11000001 S +1U +1&" +1^" +#967500000 +0* +0U +0&" +0^" +#970000000 +1* +b11000010 S +1U +1&" +1^" +#972500000 +0* +0U +0&" +0^" +#975000000 +1* +b11000011 S +1U +1&" +1^" +#977500000 +0* +0U +0&" +0^" +#980000000 +1* +b11000100 S +1U +1&" +1^" +#982500000 +0* +0U +0&" +0^" +#985000000 +1* +b11000101 S +1U +1&" +1^" +#987500000 +0* +0U +0&" +0^" +#990000000 +1* +b11000110 S +1U +1&" +1^" +#992500000 +0* +0U +0&" +0^" +#995000000 +1* +b11000111 S +1U +1&" +1^" +#997500000 +0* +0U +0&" +0^" +#1000000000 +1* +b11001000 S +1U +1&" +1^" diff --git a/ghdl/axi4-to-axis/waveform.gtkw b/ghdl/axi4-to-axis/waveform.gtkw new file mode 100644 index 0000000..0145bb7 --- /dev/null +++ b/ghdl/axi4-to-axis/waveform.gtkw @@ -0,0 +1,65 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Mon Apr 24 14:50:47 2023 +[*] +[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axi4-to-axis\wave.vcd" +[dumpfile_mtime] "Mon Apr 24 14:02:53 2023" +[dumpfile_size] 40720 +[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axi4-to-axis\waveform.gtkw" +[timestart] 0 +[size] 1858 1057 +[pos] -1929 -9 +*-26.000000 238500000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] tb_axis. +[sst_width] 224 +[signals_width] 214 +[sst_expanded] 1 +[sst_vpaned_height] 314 +@24 +[color] 5 +tb_axis.clk_count[7:0] +@28 +[color] 3 +tb_axis.clk +[color] 3 +tb_axis.rst_n +tb_axis.axi_converter_inst.s_axi_awvalid +tb_axis.axi_converter_inst.s_axi_awready +tb_axis.axi_converter_inst.s_axi_awburst[1:0] +@22 +tb_axis.axi_converter_inst.s_axi_awlen[7:0] +@28 +tb_axis.axi_converter_inst.s_axi_awsize[2:0] +tb_axis.axi_converter_inst.s_axi_awid[2:0] +[color] 2 +tb_axis.axi_converter_inst.s_axi_wvalid +[color] 2 +tb_axis.axi_converter_inst.s_axi_wready +@24 +[color] 2 +tb_axis.axi_converter_inst.s_axi_wdata[7:0] +@28 +[color] 2 +tb_axis.axi_converter_inst.s_axi_wlast +[color] 2 +tb_axis.axi_converter_inst.s_axi_wstrb[0] +[color] 3 +tb_axis.axi_converter_inst.s_axi_bvalid +[color] 3 +tb_axis.axi_converter_inst.s_axi_bready +[color] 3 +tb_axis.axi_converter_inst.s_axi_bresp[1:0] +[color] 3 +tb_axis.axi_converter_inst.s_axi_bid[2:0] +tb_axis.axi_converter_inst.m_axis_tvalid +@24 +tb_axis.axi_converter_inst.m_axis_tready +tb_axis.axi_converter_inst.m_axis_tdata[7:0] +@28 +tb_axis.axi_converter_inst.m_axis_tlast +tb_axis.axi_converter_inst.debug_state[1:0] +tb_axis.axi_converter_inst.bresp_pending +@24 +tb_axis.outstanding_xfers[7:0] +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/ghdl/axis/axis_pipeline.vhd b/ghdl/axis/axis_pipeline.vhd new file mode 100644 index 0000000..9b7d453 --- /dev/null +++ b/ghdl/axis/axis_pipeline.vhd @@ -0,0 +1,149 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS axis_pipeline +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: bidirectional AXIS pipeline register +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity axis_pipeline is + generic ( + -- Users to add parameters here + + -- User parameters ends + -- Do not modify the parameters beyond this line + + -- Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_S_AXIS_TDATA_WIDTH. + C_S_AXIS_TDATA_WIDTH : integer := 32 + ); + port ( + -- Users to add ports here + + -- User ports ends + -- Global ports + AXIS_ACLK : in std_logic; + AXIS_ARESETN : in std_logic; + + -- Slave Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. + S_AXIS_TVALID : in std_logic; + -- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. + S_AXIS_TDATA : in std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + -- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte. + S_AXIS_TSTRB : in std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + -- TLAST indicates the boundary of a packet. + S_AXIS_TLAST : in std_logic; + -- TREADY indicates that the slave can accept a transfer in the current cycle. + S_AXIS_TREADY : out std_logic; + + -- Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. + M_AXIS_TVALID : out std_logic; + -- TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. + M_AXIS_TDATA : out std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + -- TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte. + M_AXIS_TSTRB : out std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + -- TLAST indicates the boundary of a packet. + M_AXIS_TLAST : out std_logic; + -- TREADY indicates that the slave can accept a transfer in the current cycle. + M_AXIS_TREADY : in std_logic + ); +end axis_pipeline; + +architecture arch_imp of axis_pipeline is + -- skidbuffer component + component skidbuffer is + generic ( + DATA_WIDTH : natural; + OPT_DATA_REG : boolean); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector((C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector((C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto 0)); + end component; + + -- signals + signal aclk : std_logic; + signal aresetn : std_logic; + + signal i_s_axis_tvalid : std_logic := '0'; + signal i_s_axis_tdata : std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + signal i_axis_data_strb : std_logic_vector(C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tstrb : std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal i_s_axis_tlast : std_logic; + signal o_s_axis_tready : std_logic; + + signal o_m_axis_tvalid : std_logic; + signal o_m_axis_tdata : std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + signal o_axis_data_strb : std_logic_vector(C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tstrb : std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + signal o_m_axis_tlast : std_logic; + signal i_m_axis_tready : std_logic := '0'; + +begin + -- I/O connections assignments + aclk <= AXIS_ACLK; + aresetn <= AXIS_ARESETN; + + -- inputs + i_m_axis_tready <= M_AXIS_TREADY; + i_s_axis_tvalid <= S_AXIS_TVALID; + i_s_axis_tdata <= S_AXIS_TDATA; + i_s_axis_tstrb <= S_AXIS_TSTRB; + i_s_axis_tlast <= S_AXIS_TLAST; + + -- outputs + S_AXIS_TREADY <= o_s_axis_tready; + M_AXIS_TVALID <= o_m_axis_tvalid; + M_AXIS_TDATA <= o_m_axis_tdata; + M_AXIS_TSTRB <= o_m_axis_tstrb; + M_AXIS_TLAST <= o_m_axis_tlast; + + -- combine strobe and data signals into single "data" channel + i_axis_data_strb <= s_axis_tdata & s_axis_tstrb; + o_m_axis_tdata <= o_axis_data_strb( (C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)) - 1 downto (C_S_AXIS_TDATA_WIDTH/8) ); + o_m_axis_tstrb <= o_axis_data_strb( (C_S_AXIS_TDATA_WIDTH/8) - 1 downto 0 ); + + skidbuffer_inst : skidbuffer + generic map ( + DATA_WIDTH => (C_S_AXIS_TDATA_WIDTH+(C_S_AXIS_TDATA_WIDTH/8)), + OPT_DATA_REG => True + ) + port map ( + clock => aclk, + reset_n => aresetn, + + s_valid_i => i_s_axis_tvalid, + s_last_i => i_s_axis_tlast, + s_ready_o => o_s_axis_tready, + s_data_i => i_axis_data_strb, + + m_valid_o => o_m_axis_tvalid, + m_last_o => o_m_axis_tlast, + m_ready_i => i_m_axis_tready, + m_data_o => o_axis_data_strb + ); + +end arch_imp; diff --git a/ghdl/axis/compile.bat b/ghdl/axis/compile.bat new file mode 100644 index 0000000..40db981 --- /dev/null +++ b/ghdl/axis/compile.bat @@ -0,0 +1,25 @@ + +ghdl --version + +:: delete +del /Q *.vcd & +del /Q *.o & +del /Q *.exe & +del /Q *.cf & + +:: analyze +ghdl -a skidbuffer.vhd +ghdl -a axis_pipeline.vhd +ghdl -a tb_axis.vhd +:: elaborate +ghdl -e skidbuffer +ghdl -e axis_pipeline +ghdl -e tb_axis +:: run +ghdl -r tb_axis --vcd=wave.vcd --stop-time=1us +gtkwave wave.vcd waveform.gtkw + +:: delete +del /Q *.o & +del /Q *.exe & +del /Q *.cf & diff --git a/ghdl/axis/skidbuffer.vhd b/ghdl/axis/skidbuffer.vhd new file mode 100644 index 0000000..f71abcf --- /dev/null +++ b/ghdl/axis/skidbuffer.vhd @@ -0,0 +1,147 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS skidbuffer +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: skidbuffer for pipelining a bus handshake +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DATA_WIDTH : integer := 32; + OPT_DATA_REG : boolean := True + ); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0) + ); +end skidbuffer; + +architecture arch_imp of skidbuffer is + -- register signals + signal reg_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals (only used when OPT_DATA_REG = '1') + signal skd_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal skd_last : std_logic; + + -- output signals for output multiplexer + signal out_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal out_last : std_logic; + +begin + -- I/O connections assignments + m_valid_o <= reg_valid; + s_ready_o <= reg_ready; + m_data_o <= out_data; + m_last_o <= out_last; + + -- ready is always registered + p_reg_ready : process(clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_ready <= '0'; + else + reg_ready <= m_ready_i; + end if; + end if; + end process; + +-- NOT REGISTERED OUTPUT ------------------------------------------------------- + gen_no_register : if not OPT_DATA_REG generate + reg_valid <= s_valid_i; -- valid is not registered + -- output multiplexer + out_data <= reg_data when (reg_ready = '0') else s_data_i; + out_last <= reg_last when (reg_ready = '0') else s_last_i; + + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= reg_data; + reg_last <= reg_last; + end if; + end if; + end if; + end process; + + end generate; + +-- FULLY REGISTERED OUTPUT ----------------------------------------------------- + gen_data_register : if OPT_DATA_REG generate + out_data <= reg_data; + out_last <= reg_last; + -- registered output signals + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + skd_data <= (others => '0'); + skd_last <= '0'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if reg_ready = '1' then + skd_data <= s_data_i; + skd_last <= s_last_i; + else + skd_data <= skd_data; + skd_last <= skd_last; + end if; + + if m_ready_i = '0' then + reg_data <= reg_data; + reg_last <= reg_last; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= skd_data; + reg_last <= skd_last; + end if; + end if; + end if; + end if; + end process; + end generate; + +end arch_imp; diff --git a/ghdl/axis/tb_axis.vhd b/ghdl/axis/tb_axis.vhd new file mode 100644 index 0000000..957fdf9 --- /dev/null +++ b/ghdl/axis/tb_axis.vhd @@ -0,0 +1,254 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: skid buffer testbench +-- Module Name: tb_axis - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- this testbench acts as a streaming master, sending bursts of data +-- counting from 1-4, also asserting tlast on the 4th data packet + +-- the testbench itself acts as a correct streaming master which keeps the data +-- until it is acknowledged by the DUT by asserting tready. + +-- the data pattern can be influenced by the user in 2 ways +-- + Tx requests are generated by changing the pattern in p_stimuli_tready +-- the master will try to send data for as long as sim_valid_data = '1' +-- + Rx acknowledgements are generated by changing the pattern in p_stimuli_tready +-- the downstream slave after the DUT will signal ready-to-receive +-- when sim_ready_data = '1' + +-- simulate both with OPT_DATA_REG = True / False +entity tb_axis is + generic + ( + DATA_WIDTH : natural := 8; + OPT_DATA_REG : boolean := True + ); +end tb_axis; + +architecture bh of tb_axis is + -- DUT component declaration + component axis_pipeline is + generic ( + C_S_AXIS_TDATA_WIDTH : integer := 32 + ); + port ( + AXIS_ACLK : in std_logic; + AXIS_ARESETN : in std_logic; + + S_AXIS_TVALID : in std_logic; + S_AXIS_TDATA : in std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + S_AXIS_TSTRB : in std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + S_AXIS_TLAST : in std_logic; + S_AXIS_TREADY : out std_logic; + + M_AXIS_TVALID : out std_logic; + M_AXIS_TDATA : out std_logic_vector(C_S_AXIS_TDATA_WIDTH-1 downto 0); + M_AXIS_TSTRB : out std_logic_vector((C_S_AXIS_TDATA_WIDTH/8)-1 downto 0); + M_AXIS_TLAST : out std_logic; + M_AXIS_TREADY : in std_logic + ); + end component; + + constant CLK_PERIOD: TIME := 5 ns; + + signal sim_valid_data : std_logic := '0'; + signal sim_ready_data : std_logic := '1'; + signal sim_data : std_logic_vector(DATA_WIDTH-1 downto 0); + + signal s_axis_tvalid : std_logic := '0'; + signal s_axis_tdata : std_logic_vector(DATA_WIDTH-1 downto 0); + signal s_axis_tstrb : std_logic_vector((DATA_WIDTH/8)-1 downto 0); + signal s_axis_tlast : std_logic; + signal s_axis_tready : std_logic; + + signal m_axis_tvalid : std_logic; + signal m_axis_tdata : std_logic_vector(DATA_WIDTH-1 downto 0); + signal m_axis_tstrb : std_logic_vector((DATA_WIDTH/8)-1 downto 0); + signal m_axis_tlast : std_logic; + signal m_axis_tready : std_logic := '0'; + + signal clk : std_logic; + signal rst_n : std_logic; + + signal clk_count : std_logic_vector(7 downto 0) := (others => '0'); +begin + + -- generate clk signal + p_clk_gen : process + begin + clk <= '1'; + wait for (CLK_PERIOD / 2); + clk <= '0'; + wait for (CLK_PERIOD / 2); + clk_count <= std_logic_vector(unsigned(clk_count) + 1); + end process; + + -- generate initial reset + p_reset_gen : process + begin + rst_n <= '0'; + wait until rising_edge(clk); + wait for (CLK_PERIOD / 4); + rst_n <= '1'; + wait; + end process; + + -- generate ready signal + p_stimuli_tready : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + m_axis_tready <= '1'; + else + m_axis_tready <= sim_ready_data; + if unsigned(clk_count) = 2 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 7 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 8 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 11 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 13 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 14 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 15 then + sim_ready_data <= '1'; + end if; + end if; + end if; + end process; + + -- generate valid signal + p_stimuli_tvalid : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + sim_valid_data <= '0'; + else + if unsigned(clk_count) = 2 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 18 then + sim_valid_data <= '0'; + end if; + if unsigned(clk_count) = 21 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 23 then + sim_valid_data <= '0'; + end if; + if unsigned(clk_count) = 24 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 26 then + sim_valid_data <= '0'; + end if; + end if; + end if; + end process; + + -- generate counter data when successfully acknowledged (tready) by slave + p_stimuli_tdata : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + s_axis_tdata <= (others => '0'); + s_axis_tstrb <= (others => '0'); + sim_data <= (others => '0'); + s_axis_tlast <= '0'; + else + if sim_valid_data = '1' then -- VALID can be controlled + if s_axis_tready = '1' then -- READY can be controlled + if unsigned(s_axis_tdata) = 3 then + s_axis_tlast <= '1'; + else + s_axis_tlast <= '0'; + end if; + + if unsigned(s_axis_tdata) = 4 then + -- restart counter at "1" + s_axis_tdata(DATA_WIDTH-1 downto 1) <= (others => '0'); + s_axis_tdata(0) <= '1'; + sim_data(DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + if (unsigned(sim_data) > unsigned(s_axis_tdata)) and (unsigned(sim_data) < 4) then + s_axis_tdata <= std_logic_vector(unsigned(sim_data) + 1); + else + s_axis_tdata <= std_logic_vector(unsigned(s_axis_tdata) + 1); + end if; + + if unsigned(sim_data) = 4 then + sim_data(DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + sim_data <= std_logic_vector(unsigned(sim_data) + 1); + end if; + end if; + else + s_axis_tdata <= s_axis_tdata; + sim_data <= sim_data; + end if; + s_axis_tvalid <= '1'; + s_axis_tstrb <= "1"; + else + s_axis_tvalid <= '0'; + s_axis_tstrb <= "0"; + s_axis_tlast <= '0'; + s_axis_tdata <= (others => '0'); + sim_data <= sim_data; + end if; + end if; + end if; + end process; + +-- DUT instance and connections + skidbuffer_inst : axis_pipeline + generic map ( + C_S_AXIS_TDATA_WIDTH => DATA_WIDTH + ) + port map ( + AXIS_ACLK => clk, + AXIS_ARESETN => rst_n, + + S_AXIS_TVALID => s_axis_tvalid, + S_AXIS_TDATA => s_axis_tdata, + S_AXIS_TSTRB => s_axis_tstrb, + S_AXIS_TLAST => s_axis_tlast, + S_AXIS_TREADY => s_axis_tready, + + M_AXIS_TVALID => m_axis_tvalid, + M_AXIS_TDATA => m_axis_tdata, + M_AXIS_TSTRB => m_axis_tstrb, + M_AXIS_TLAST => m_axis_tlast, + M_AXIS_TREADY => m_axis_tready + ); + +end bh; diff --git a/ghdl/axis/wave.vcd b/ghdl/axis/wave.vcd new file mode 100644 index 0000000..c7855c7 --- /dev/null +++ b/ghdl/axis/wave.vcd @@ -0,0 +1,2907 @@ +$date + Fri Apr 21 10:06:02 2023 +$end +$version + GHDL v0 +$end +$timescale + 1 fs +$end +$scope module standard $end +$upscope $end +$scope module std_logic_1164 $end +$upscope $end +$scope module numeric_std $end +$upscope $end +$scope module tb_axis $end +$var reg 1 ! sim_valid_data $end +$var reg 1 " sim_ready_data $end +$var reg 8 # sim_data[7:0] $end +$var reg 1 $ s_axis_tvalid $end +$var reg 8 % s_axis_tdata[7:0] $end +$var reg 1 & s_axis_tstrb[0:0] $end +$var reg 1 ' s_axis_tlast $end +$var reg 1 ( s_axis_tready $end +$var reg 1 ) m_axis_tvalid $end +$var reg 8 * m_axis_tdata[7:0] $end +$var reg 1 + m_axis_tstrb[0:0] $end +$var reg 1 , m_axis_tlast $end +$var reg 1 - m_axis_tready $end +$var reg 1 . clk $end +$var reg 1 / rst_n $end +$var reg 8 0 clk_count[7:0] $end +$scope module skidbuffer_inst $end +$var reg 1 1 axis_aclk $end +$var reg 1 2 axis_aresetn $end +$var reg 1 3 s_axis_tvalid $end +$var reg 8 4 s_axis_tdata[7:0] $end +$var reg 1 5 s_axis_tstrb[0:0] $end +$var reg 1 6 s_axis_tlast $end +$var reg 1 7 s_axis_tready $end +$var reg 1 8 m_axis_tvalid $end +$var reg 8 9 m_axis_tdata[7:0] $end +$var reg 1 : m_axis_tstrb[0:0] $end +$var reg 1 ; m_axis_tlast $end +$var reg 1 < m_axis_tready $end +$var reg 1 = aclk $end +$var reg 1 > aresetn $end +$var reg 1 ? i_s_axis_tvalid $end +$var reg 8 @ i_s_axis_tdata[7:0] $end +$var reg 9 A i_axis_data_strb[8:0] $end +$var reg 1 B i_s_axis_tstrb[0:0] $end +$var reg 1 C i_s_axis_tlast $end +$var reg 1 D o_s_axis_tready $end +$var reg 1 E o_m_axis_tvalid $end +$var reg 8 F o_m_axis_tdata[7:0] $end +$var reg 9 G o_axis_data_strb[8:0] $end +$var reg 1 H o_m_axis_tstrb[0:0] $end +$var reg 1 I o_m_axis_tlast $end +$var reg 1 J i_m_axis_tready $end +$scope module skidbuffer_inst $end +$var reg 1 K clock $end +$var reg 1 L reset_n $end +$var reg 1 M s_valid_i $end +$var reg 1 N s_last_i $end +$var reg 1 O s_ready_o $end +$var reg 9 P s_data_i[8:0] $end +$var reg 1 Q m_valid_o $end +$var reg 1 R m_last_o $end +$var reg 1 S m_ready_i $end +$var reg 9 T m_data_o[8:0] $end +$var reg 9 U reg_data[8:0] $end +$var reg 1 V reg_last $end +$var reg 1 W reg_valid $end +$var reg 1 X reg_ready $end +$var reg 9 Y skd_data[8:0] $end +$var reg 1 Z skd_last $end +$var reg 9 [ out_data[8:0] $end +$var reg 1 \ out_last $end +$scope module gen_data_register $end +$upscope $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +0! +1" +bUUUUUUUU # +0$ +bUUUUUUUU % +bU & +U' +U( +U) +bUUUUUUUU * +bU + +U, +0- +1. +0/ +b00000000 0 +11 +02 +03 +bUUUUUUUU 4 +bU 5 +U6 +U7 +U8 +bUUUUUUUU 9 +bU : +U; +0< +1= +0> +0? +bUUUUUUUU @ +bUUUUUUUUU A +bU B +UC +UD +UE +bUUUUUUUU F +bUUUUUUUUU G +bU H +UI +0J +1K +0L +0M +UN +UO +bUUUUUUUUU P +UQ +UR +0S +bUUUUUUUUU T +bUUUUUUUUU U +UV +UW +UX +bUUUUUUUUU Y +UZ +bUUUUUUUUU [ +U\ +#2500000 +0. +01 +0= +0K +#5000000 +b00000000 # +b00000000 % +b0 & +0' +0( +0) +b00000000 * +b0 + +0, +1- +1. +b00000001 0 +11 +b00000000 4 +b0 5 +06 +07 +08 +b00000000 9 +b0 : +0; +1< +1= +b00000000 @ +b000000000 A +b0 B +0C +0D +0E +b00000000 F +b000000000 G +b0 H +0I +1J +1K +0N +0O +b000000000 P +0Q +0R +1S +b000000000 T +b000000000 U +0V +0W +0X +b000000000 Y +0Z +b000000000 [ +0\ +#6250000 +1/ +12 +1> +1L +#7500000 +0. +01 +0= +0K +#10000000 +1! +1( +1. +b00000010 0 +11 +17 +1= +1D +1K +1O +1X +#12500000 +0. +01 +0= +0K +#15000000 +b00000001 # +1$ +b00000001 % +b1 & +1. +b00000011 0 +11 +13 +b00000001 4 +b1 5 +1= +1? +b00000001 @ +b000000011 A +b1 B +1K +1M +b000000011 P +#17500000 +0. +01 +0= +0K +#20000000 +b00000010 # +b00000010 % +1) +b00000001 * +b1 + +1. +b00000100 0 +11 +b00000010 4 +18 +b00000001 9 +b1 : +1= +b00000010 @ +b000000101 A +1E +b00000001 F +b000000011 G +b1 H +1K +b000000101 P +1Q +b000000011 T +b000000011 U +1W +b000000011 Y +b000000011 [ +#22500000 +0. +01 +0= +0K +#25000000 +b00000011 # +b00000011 % +b00000010 * +1. +b00000101 0 +11 +b00000011 4 +b00000010 9 +1= +b00000011 @ +b000000111 A +b00000010 F +b000000101 G +1K +b000000111 P +b000000101 T +b000000101 U +b000000101 Y +b000000101 [ +#27500000 +0. +01 +0= +0K +#30000000 +b00000100 # +b00000100 % +1' +b00000011 * +1. +b00000110 0 +11 +b00000100 4 +16 +b00000011 9 +1= +b00000100 @ +b000001001 A +1C +b00000011 F +b000000111 G +1K +1N +b000001001 P +b000000111 T +b000000111 U +b000000111 Y +b000000111 [ +#32500000 +0. +01 +0= +0K +#35000000 +0" +b00000001 # +b00000001 % +0' +b00000100 * +1, +1. +b00000111 0 +11 +b00000001 4 +06 +b00000100 9 +1; +1= +b00000001 @ +b000000011 A +0C +b00000100 F +b000001001 G +1I +1K +0N +b000000011 P +1R +b000001001 T +b000001001 U +1V +b000001001 Y +1Z +b000001001 [ +1\ +#37500000 +0. +01 +0= +0K +#40000000 +1" +b00000010 # +b00000010 % +b00000001 * +0, +0- +1. +b00001000 0 +11 +b00000010 4 +b00000001 9 +0; +0< +1= +b00000010 @ +b000000101 A +b00000001 F +b000000011 G +0I +0J +1K +b000000101 P +0R +0S +b000000011 T +b000000011 U +0V +b000000011 Y +0Z +b000000011 [ +0\ +#42500000 +0. +01 +0= +0K +#45000000 +b00000011 # +b00000011 % +0( +1- +1. +b00001001 0 +11 +b00000011 4 +07 +1< +1= +b00000011 @ +b000000111 A +0D +1J +1K +0O +b000000111 P +1S +0X +b000000101 Y +#47500000 +0. +01 +0= +0K +#50000000 +1( +b00000010 * +1. +b00001010 0 +11 +17 +b00000010 9 +1= +1D +b00000010 F +b000000101 G +1K +1O +b000000101 T +b000000101 U +1X +b000000101 [ +#52500000 +0. +01 +0= +0K +#55000000 +0" +b00000100 # +b00000100 % +1' +b00000011 * +1. +b00001011 0 +11 +b00000100 4 +16 +b00000011 9 +1= +b00000100 @ +b000001001 A +1C +b00000011 F +b000000111 G +1K +1N +b000001001 P +b000000111 T +b000000111 U +b000000111 Y +b000000111 [ +#57500000 +0. +01 +0= +0K +#60000000 +b00000001 # +b00000001 % +0' +b00000100 * +1, +0- +1. +b00001100 0 +11 +b00000001 4 +06 +b00000100 9 +1; +0< +1= +b00000001 @ +b000000011 A +0C +b00000100 F +b000001001 G +1I +0J +1K +0N +b000000011 P +1R +0S +b000001001 T +b000001001 U +1V +b000001001 Y +1Z +b000001001 [ +1\ +#62500000 +0. +01 +0= +0K +#65000000 +1" +b00000010 # +b00000010 % +0( +1. +b00001101 0 +11 +b00000010 4 +07 +1= +b00000010 @ +b000000101 A +0D +1K +0O +b000000101 P +0X +b000000011 Y +0Z +#67500000 +0. +01 +0= +0K +#70000000 +0" +1- +1. +b00001110 0 +11 +1< +1= +1J +1K +1S +#72500000 +0. +01 +0= +0K +#75000000 +1" +1( +b00000001 * +0, +0- +1. +b00001111 0 +11 +17 +b00000001 9 +0; +0< +1= +1D +b00000001 F +b000000011 G +0I +0J +1K +1O +0R +0S +b000000011 T +b000000011 U +0V +1X +b000000011 [ +0\ +#77500000 +0. +01 +0= +0K +#80000000 +b00000011 # +b00000011 % +0( +1- +1. +b00010000 0 +11 +b00000011 4 +07 +1< +1= +b00000011 @ +b000000111 A +0D +1J +1K +0O +b000000111 P +1S +0X +b000000101 Y +#82500000 +0. +01 +0= +0K +#85000000 +1( +b00000010 * +1. +b00010001 0 +11 +17 +b00000010 9 +1= +1D +b00000010 F +b000000101 G +1K +1O +b000000101 T +b000000101 U +1X +b000000101 [ +#87500000 +0. +01 +0= +0K +#90000000 +0! +b00000100 # +b00000100 % +1' +b00000011 * +1. +b00010010 0 +11 +b00000100 4 +16 +b00000011 9 +1= +b00000100 @ +b000001001 A +1C +b00000011 F +b000000111 G +1K +1N +b000001001 P +b000000111 T +b000000111 U +b000000111 Y +b000000111 [ +#92500000 +0. +01 +0= +0K +#95000000 +0$ +b00000000 % +b0 & +0' +b00000100 * +1, +1. +b00010011 0 +11 +03 +b00000000 4 +b0 5 +06 +b00000100 9 +1; +1= +0? +b00000000 @ +b000000000 A +b0 B +0C +b00000100 F +b000001001 G +1I +1K +0M +0N +b000000000 P +1R +b000001001 T +b000001001 U +1V +b000001001 Y +1Z +b000001001 [ +1\ +#97500000 +0. +01 +0= +0K +#100000000 +0) +b00000000 * +b0 + +0, +1. +b00010100 0 +11 +08 +b00000000 9 +b0 : +0; +1= +0E +b00000000 F +b000000000 G +b0 H +0I +1K +0Q +0R +b000000000 T +b000000000 U +0V +0W +b000000000 Y +0Z +b000000000 [ +0\ +#102500000 +0. +01 +0= +0K +#105000000 +1! +1. +b00010101 0 +11 +1= +1K +#107500000 +0. +01 +0= +0K +#110000000 +b00000001 # +1$ +b00000001 % +b1 & +1. +b00010110 0 +11 +13 +b00000001 4 +b1 5 +1= +1? +b00000001 @ +b000000011 A +b1 B +1K +1M +b000000011 P +#112500000 +0. +01 +0= +0K +#115000000 +0! +b00000010 # +b00000010 % +1) +b00000001 * +b1 + +1. +b00010111 0 +11 +b00000010 4 +18 +b00000001 9 +b1 : +1= +b00000010 @ +b000000101 A +1E +b00000001 F +b000000011 G +b1 H +1K +b000000101 P +1Q +b000000011 T +b000000011 U +1W +b000000011 Y +b000000011 [ +#117500000 +0. +01 +0= +0K +#120000000 +1! +0$ +b00000000 % +b0 & +b00000010 * +1. +b00011000 0 +11 +03 +b00000000 4 +b0 5 +b00000010 9 +1= +0? +b00000000 @ +b000000000 A +b0 B +b00000010 F +b000000101 G +1K +0M +b000000000 P +b000000101 T +b000000101 U +b000000101 Y +b000000101 [ +#122500000 +0. +01 +0= +0K +#125000000 +b00000011 # +1$ +b00000011 % +b1 & +0) +b00000000 * +b0 + +1. +b00011001 0 +11 +13 +b00000011 4 +b1 5 +08 +b00000000 9 +b0 : +1= +1? +b00000011 @ +b000000111 A +b1 B +0E +b00000000 F +b000000000 G +b0 H +1K +1M +b000000111 P +0Q +b000000000 T +b000000000 U +0W +b000000000 Y +b000000000 [ +#127500000 +0. +01 +0= +0K +#130000000 +0! +b00000100 # +b00000100 % +1' +1) +b00000011 * +b1 + +1. +b00011010 0 +11 +b00000100 4 +16 +18 +b00000011 9 +b1 : +1= +b00000100 @ +b000001001 A +1C +1E +b00000011 F +b000000111 G +b1 H +1K +1N +b000001001 P +1Q +b000000111 T +b000000111 U +1W +b000000111 Y +b000000111 [ +#132500000 +0. +01 +0= +0K +#135000000 +0$ +b00000000 % +b0 & +0' +b00000100 * +1, +1. +b00011011 0 +11 +03 +b00000000 4 +b0 5 +06 +b00000100 9 +1; +1= +0? +b00000000 @ +b000000000 A +b0 B +0C +b00000100 F +b000001001 G +1I +1K +0M +0N +b000000000 P +1R +b000001001 T +b000001001 U +1V +b000001001 Y +1Z +b000001001 [ +1\ +#137500000 +0. +01 +0= +0K +#140000000 +0) +b00000000 * +b0 + +0, +1. +b00011100 0 +11 +08 +b00000000 9 +b0 : +0; +1= +0E +b00000000 F +b000000000 G +b0 H +0I +1K +0Q +0R +b000000000 T +b000000000 U +0V +0W +b000000000 Y +0Z +b000000000 [ +0\ +#142500000 +0. +01 +0= +0K +#145000000 +1. +b00011101 0 +11 +1= +1K +#147500000 +0. +01 +0= +0K +#150000000 +1. +b00011110 0 +11 +1= +1K +#152500000 +0. +01 +0= +0K +#155000000 +1. +b00011111 0 +11 +1= +1K +#157500000 +0. +01 +0= +0K +#160000000 +1. +b00100000 0 +11 +1= +1K +#162500000 +0. +01 +0= +0K +#165000000 +1. +b00100001 0 +11 +1= +1K +#167500000 +0. +01 +0= +0K +#170000000 +1. +b00100010 0 +11 +1= +1K +#172500000 +0. +01 +0= +0K +#175000000 +1. +b00100011 0 +11 +1= +1K +#177500000 +0. +01 +0= +0K +#180000000 +1. +b00100100 0 +11 +1= +1K +#182500000 +0. +01 +0= +0K +#185000000 +1. +b00100101 0 +11 +1= +1K +#187500000 +0. +01 +0= +0K +#190000000 +1. +b00100110 0 +11 +1= +1K +#192500000 +0. +01 +0= +0K +#195000000 +1. +b00100111 0 +11 +1= +1K +#197500000 +0. +01 +0= +0K +#200000000 +1. +b00101000 0 +11 +1= +1K +#202500000 +0. +01 +0= +0K +#205000000 +1. +b00101001 0 +11 +1= +1K +#207500000 +0. +01 +0= +0K +#210000000 +1. +b00101010 0 +11 +1= +1K +#212500000 +0. +01 +0= +0K +#215000000 +1. +b00101011 0 +11 +1= +1K +#217500000 +0. +01 +0= +0K +#220000000 +1. +b00101100 0 +11 +1= +1K +#222500000 +0. +01 +0= +0K +#225000000 +1. +b00101101 0 +11 +1= +1K +#227500000 +0. +01 +0= +0K +#230000000 +1. +b00101110 0 +11 +1= +1K +#232500000 +0. +01 +0= +0K +#235000000 +1. +b00101111 0 +11 +1= +1K +#237500000 +0. +01 +0= +0K +#240000000 +1. +b00110000 0 +11 +1= +1K +#242500000 +0. +01 +0= +0K +#245000000 +1. +b00110001 0 +11 +1= +1K +#247500000 +0. +01 +0= +0K +#250000000 +1. +b00110010 0 +11 +1= +1K +#252500000 +0. +01 +0= +0K +#255000000 +1. +b00110011 0 +11 +1= +1K +#257500000 +0. +01 +0= +0K +#260000000 +1. +b00110100 0 +11 +1= +1K +#262500000 +0. +01 +0= +0K +#265000000 +1. +b00110101 0 +11 +1= +1K +#267500000 +0. +01 +0= +0K +#270000000 +1. +b00110110 0 +11 +1= +1K +#272500000 +0. +01 +0= +0K +#275000000 +1. +b00110111 0 +11 +1= +1K +#277500000 +0. +01 +0= +0K +#280000000 +1. +b00111000 0 +11 +1= +1K +#282500000 +0. +01 +0= +0K +#285000000 +1. +b00111001 0 +11 +1= +1K +#287500000 +0. +01 +0= +0K +#290000000 +1. +b00111010 0 +11 +1= +1K +#292500000 +0. +01 +0= +0K +#295000000 +1. +b00111011 0 +11 +1= +1K +#297500000 +0. +01 +0= +0K +#300000000 +1. +b00111100 0 +11 +1= +1K +#302500000 +0. +01 +0= +0K +#305000000 +1. +b00111101 0 +11 +1= +1K +#307500000 +0. +01 +0= +0K +#310000000 +1. +b00111110 0 +11 +1= +1K +#312500000 +0. +01 +0= +0K +#315000000 +1. +b00111111 0 +11 +1= +1K +#317500000 +0. +01 +0= +0K +#320000000 +1. +b01000000 0 +11 +1= +1K +#322500000 +0. +01 +0= +0K +#325000000 +1. +b01000001 0 +11 +1= +1K +#327500000 +0. +01 +0= +0K +#330000000 +1. +b01000010 0 +11 +1= +1K +#332500000 +0. +01 +0= +0K +#335000000 +1. +b01000011 0 +11 +1= +1K +#337500000 +0. +01 +0= +0K +#340000000 +1. +b01000100 0 +11 +1= +1K +#342500000 +0. +01 +0= +0K +#345000000 +1. +b01000101 0 +11 +1= +1K +#347500000 +0. +01 +0= +0K +#350000000 +1. +b01000110 0 +11 +1= +1K +#352500000 +0. +01 +0= +0K +#355000000 +1. +b01000111 0 +11 +1= +1K +#357500000 +0. +01 +0= +0K +#360000000 +1. +b01001000 0 +11 +1= +1K +#362500000 +0. +01 +0= +0K +#365000000 +1. +b01001001 0 +11 +1= +1K +#367500000 +0. +01 +0= +0K +#370000000 +1. +b01001010 0 +11 +1= +1K +#372500000 +0. +01 +0= +0K +#375000000 +1. +b01001011 0 +11 +1= +1K +#377500000 +0. +01 +0= +0K +#380000000 +1. +b01001100 0 +11 +1= +1K +#382500000 +0. +01 +0= +0K +#385000000 +1. +b01001101 0 +11 +1= +1K +#387500000 +0. +01 +0= +0K +#390000000 +1. +b01001110 0 +11 +1= +1K +#392500000 +0. +01 +0= +0K +#395000000 +1. +b01001111 0 +11 +1= +1K +#397500000 +0. +01 +0= +0K +#400000000 +1. +b01010000 0 +11 +1= +1K +#402500000 +0. +01 +0= +0K +#405000000 +1. +b01010001 0 +11 +1= +1K +#407500000 +0. +01 +0= +0K +#410000000 +1. +b01010010 0 +11 +1= +1K +#412500000 +0. +01 +0= +0K +#415000000 +1. +b01010011 0 +11 +1= +1K +#417500000 +0. +01 +0= +0K +#420000000 +1. +b01010100 0 +11 +1= +1K +#422500000 +0. +01 +0= +0K +#425000000 +1. +b01010101 0 +11 +1= +1K +#427500000 +0. +01 +0= +0K +#430000000 +1. +b01010110 0 +11 +1= +1K +#432500000 +0. +01 +0= +0K +#435000000 +1. +b01010111 0 +11 +1= +1K +#437500000 +0. +01 +0= +0K +#440000000 +1. +b01011000 0 +11 +1= +1K +#442500000 +0. +01 +0= +0K +#445000000 +1. +b01011001 0 +11 +1= +1K +#447500000 +0. +01 +0= +0K +#450000000 +1. +b01011010 0 +11 +1= +1K +#452500000 +0. +01 +0= +0K +#455000000 +1. +b01011011 0 +11 +1= +1K +#457500000 +0. +01 +0= +0K +#460000000 +1. +b01011100 0 +11 +1= +1K +#462500000 +0. +01 +0= +0K +#465000000 +1. +b01011101 0 +11 +1= +1K +#467500000 +0. +01 +0= +0K +#470000000 +1. +b01011110 0 +11 +1= +1K +#472500000 +0. +01 +0= +0K +#475000000 +1. +b01011111 0 +11 +1= +1K +#477500000 +0. +01 +0= +0K +#480000000 +1. +b01100000 0 +11 +1= +1K +#482500000 +0. +01 +0= +0K +#485000000 +1. +b01100001 0 +11 +1= +1K +#487500000 +0. +01 +0= +0K +#490000000 +1. +b01100010 0 +11 +1= +1K +#492500000 +0. +01 +0= +0K +#495000000 +1. +b01100011 0 +11 +1= +1K +#497500000 +0. +01 +0= +0K +#500000000 +1. +b01100100 0 +11 +1= +1K +#502500000 +0. +01 +0= +0K +#505000000 +1. +b01100101 0 +11 +1= +1K +#507500000 +0. +01 +0= +0K +#510000000 +1. +b01100110 0 +11 +1= +1K +#512500000 +0. +01 +0= +0K +#515000000 +1. +b01100111 0 +11 +1= +1K +#517500000 +0. +01 +0= +0K +#520000000 +1. +b01101000 0 +11 +1= +1K +#522500000 +0. +01 +0= +0K +#525000000 +1. +b01101001 0 +11 +1= +1K +#527500000 +0. +01 +0= +0K +#530000000 +1. +b01101010 0 +11 +1= +1K +#532500000 +0. +01 +0= +0K +#535000000 +1. +b01101011 0 +11 +1= +1K +#537500000 +0. +01 +0= +0K +#540000000 +1. +b01101100 0 +11 +1= +1K +#542500000 +0. +01 +0= +0K +#545000000 +1. +b01101101 0 +11 +1= +1K +#547500000 +0. +01 +0= +0K +#550000000 +1. +b01101110 0 +11 +1= +1K +#552500000 +0. +01 +0= +0K +#555000000 +1. +b01101111 0 +11 +1= +1K +#557500000 +0. +01 +0= +0K +#560000000 +1. +b01110000 0 +11 +1= +1K +#562500000 +0. +01 +0= +0K +#565000000 +1. +b01110001 0 +11 +1= +1K +#567500000 +0. +01 +0= +0K +#570000000 +1. +b01110010 0 +11 +1= +1K +#572500000 +0. +01 +0= +0K +#575000000 +1. +b01110011 0 +11 +1= +1K +#577500000 +0. +01 +0= +0K +#580000000 +1. +b01110100 0 +11 +1= +1K +#582500000 +0. +01 +0= +0K +#585000000 +1. +b01110101 0 +11 +1= +1K +#587500000 +0. +01 +0= +0K +#590000000 +1. +b01110110 0 +11 +1= +1K +#592500000 +0. +01 +0= +0K +#595000000 +1. +b01110111 0 +11 +1= +1K +#597500000 +0. +01 +0= +0K +#600000000 +1. +b01111000 0 +11 +1= +1K +#602500000 +0. +01 +0= +0K +#605000000 +1. +b01111001 0 +11 +1= +1K +#607500000 +0. +01 +0= +0K +#610000000 +1. +b01111010 0 +11 +1= +1K +#612500000 +0. +01 +0= +0K +#615000000 +1. +b01111011 0 +11 +1= +1K +#617500000 +0. +01 +0= +0K +#620000000 +1. +b01111100 0 +11 +1= +1K +#622500000 +0. +01 +0= +0K +#625000000 +1. +b01111101 0 +11 +1= +1K +#627500000 +0. +01 +0= +0K +#630000000 +1. +b01111110 0 +11 +1= +1K +#632500000 +0. +01 +0= +0K +#635000000 +1. +b01111111 0 +11 +1= +1K +#637500000 +0. +01 +0= +0K +#640000000 +1. +b10000000 0 +11 +1= +1K +#642500000 +0. +01 +0= +0K +#645000000 +1. +b10000001 0 +11 +1= +1K +#647500000 +0. +01 +0= +0K +#650000000 +1. +b10000010 0 +11 +1= +1K +#652500000 +0. +01 +0= +0K +#655000000 +1. +b10000011 0 +11 +1= +1K +#657500000 +0. +01 +0= +0K +#660000000 +1. +b10000100 0 +11 +1= +1K +#662500000 +0. +01 +0= +0K +#665000000 +1. +b10000101 0 +11 +1= +1K +#667500000 +0. +01 +0= +0K +#670000000 +1. +b10000110 0 +11 +1= +1K +#672500000 +0. +01 +0= +0K +#675000000 +1. +b10000111 0 +11 +1= +1K +#677500000 +0. +01 +0= +0K +#680000000 +1. +b10001000 0 +11 +1= +1K +#682500000 +0. +01 +0= +0K +#685000000 +1. +b10001001 0 +11 +1= +1K +#687500000 +0. +01 +0= +0K +#690000000 +1. +b10001010 0 +11 +1= +1K +#692500000 +0. +01 +0= +0K +#695000000 +1. +b10001011 0 +11 +1= +1K +#697500000 +0. +01 +0= +0K +#700000000 +1. +b10001100 0 +11 +1= +1K +#702500000 +0. +01 +0= +0K +#705000000 +1. +b10001101 0 +11 +1= +1K +#707500000 +0. +01 +0= +0K +#710000000 +1. +b10001110 0 +11 +1= +1K +#712500000 +0. +01 +0= +0K +#715000000 +1. +b10001111 0 +11 +1= +1K +#717500000 +0. +01 +0= +0K +#720000000 +1. +b10010000 0 +11 +1= +1K +#722500000 +0. +01 +0= +0K +#725000000 +1. +b10010001 0 +11 +1= +1K +#727500000 +0. +01 +0= +0K +#730000000 +1. +b10010010 0 +11 +1= +1K +#732500000 +0. +01 +0= +0K +#735000000 +1. +b10010011 0 +11 +1= +1K +#737500000 +0. +01 +0= +0K +#740000000 +1. +b10010100 0 +11 +1= +1K +#742500000 +0. +01 +0= +0K +#745000000 +1. +b10010101 0 +11 +1= +1K +#747500000 +0. +01 +0= +0K +#750000000 +1. +b10010110 0 +11 +1= +1K +#752500000 +0. +01 +0= +0K +#755000000 +1. +b10010111 0 +11 +1= +1K +#757500000 +0. +01 +0= +0K +#760000000 +1. +b10011000 0 +11 +1= +1K +#762500000 +0. +01 +0= +0K +#765000000 +1. +b10011001 0 +11 +1= +1K +#767500000 +0. +01 +0= +0K +#770000000 +1. +b10011010 0 +11 +1= +1K +#772500000 +0. +01 +0= +0K +#775000000 +1. +b10011011 0 +11 +1= +1K +#777500000 +0. +01 +0= +0K +#780000000 +1. +b10011100 0 +11 +1= +1K +#782500000 +0. +01 +0= +0K +#785000000 +1. +b10011101 0 +11 +1= +1K +#787500000 +0. +01 +0= +0K +#790000000 +1. +b10011110 0 +11 +1= +1K +#792500000 +0. +01 +0= +0K +#795000000 +1. +b10011111 0 +11 +1= +1K +#797500000 +0. +01 +0= +0K +#800000000 +1. +b10100000 0 +11 +1= +1K +#802500000 +0. +01 +0= +0K +#805000000 +1. +b10100001 0 +11 +1= +1K +#807500000 +0. +01 +0= +0K +#810000000 +1. +b10100010 0 +11 +1= +1K +#812500000 +0. +01 +0= +0K +#815000000 +1. +b10100011 0 +11 +1= +1K +#817500000 +0. +01 +0= +0K +#820000000 +1. +b10100100 0 +11 +1= +1K +#822500000 +0. +01 +0= +0K +#825000000 +1. +b10100101 0 +11 +1= +1K +#827500000 +0. +01 +0= +0K +#830000000 +1. +b10100110 0 +11 +1= +1K +#832500000 +0. +01 +0= +0K +#835000000 +1. +b10100111 0 +11 +1= +1K +#837500000 +0. +01 +0= +0K +#840000000 +1. +b10101000 0 +11 +1= +1K +#842500000 +0. +01 +0= +0K +#845000000 +1. +b10101001 0 +11 +1= +1K +#847500000 +0. +01 +0= +0K +#850000000 +1. +b10101010 0 +11 +1= +1K +#852500000 +0. +01 +0= +0K +#855000000 +1. +b10101011 0 +11 +1= +1K +#857500000 +0. +01 +0= +0K +#860000000 +1. +b10101100 0 +11 +1= +1K +#862500000 +0. +01 +0= +0K +#865000000 +1. +b10101101 0 +11 +1= +1K +#867500000 +0. +01 +0= +0K +#870000000 +1. +b10101110 0 +11 +1= +1K +#872500000 +0. +01 +0= +0K +#875000000 +1. +b10101111 0 +11 +1= +1K +#877500000 +0. +01 +0= +0K +#880000000 +1. +b10110000 0 +11 +1= +1K +#882500000 +0. +01 +0= +0K +#885000000 +1. +b10110001 0 +11 +1= +1K +#887500000 +0. +01 +0= +0K +#890000000 +1. +b10110010 0 +11 +1= +1K +#892500000 +0. +01 +0= +0K +#895000000 +1. +b10110011 0 +11 +1= +1K +#897500000 +0. +01 +0= +0K +#900000000 +1. +b10110100 0 +11 +1= +1K +#902500000 +0. +01 +0= +0K +#905000000 +1. +b10110101 0 +11 +1= +1K +#907500000 +0. +01 +0= +0K +#910000000 +1. +b10110110 0 +11 +1= +1K +#912500000 +0. +01 +0= +0K +#915000000 +1. +b10110111 0 +11 +1= +1K +#917500000 +0. +01 +0= +0K +#920000000 +1. +b10111000 0 +11 +1= +1K +#922500000 +0. +01 +0= +0K +#925000000 +1. +b10111001 0 +11 +1= +1K +#927500000 +0. +01 +0= +0K +#930000000 +1. +b10111010 0 +11 +1= +1K +#932500000 +0. +01 +0= +0K +#935000000 +1. +b10111011 0 +11 +1= +1K +#937500000 +0. +01 +0= +0K +#940000000 +1. +b10111100 0 +11 +1= +1K +#942500000 +0. +01 +0= +0K +#945000000 +1. +b10111101 0 +11 +1= +1K +#947500000 +0. +01 +0= +0K +#950000000 +1. +b10111110 0 +11 +1= +1K +#952500000 +0. +01 +0= +0K +#955000000 +1. +b10111111 0 +11 +1= +1K +#957500000 +0. +01 +0= +0K +#960000000 +1. +b11000000 0 +11 +1= +1K +#962500000 +0. +01 +0= +0K +#965000000 +1. +b11000001 0 +11 +1= +1K +#967500000 +0. +01 +0= +0K +#970000000 +1. +b11000010 0 +11 +1= +1K +#972500000 +0. +01 +0= +0K +#975000000 +1. +b11000011 0 +11 +1= +1K +#977500000 +0. +01 +0= +0K +#980000000 +1. +b11000100 0 +11 +1= +1K +#982500000 +0. +01 +0= +0K +#985000000 +1. +b11000101 0 +11 +1= +1K +#987500000 +0. +01 +0= +0K +#990000000 +1. +b11000110 0 +11 +1= +1K +#992500000 +0. +01 +0= +0K +#995000000 +1. +b11000111 0 +11 +1= +1K +#997500000 +0. +01 +0= +0K +#1000000000 +1. +b11001000 0 +11 +1= +1K diff --git a/ghdl/axis/waveform.gtkw b/ghdl/axis/waveform.gtkw new file mode 100644 index 0000000..00cb77a --- /dev/null +++ b/ghdl/axis/waveform.gtkw @@ -0,0 +1,43 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Fri Apr 21 08:04:46 2023 +[*] +[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axis\wave.vcd" +[dumpfile_mtime] "Fri Apr 21 08:04:23 2023" +[dumpfile_size] 21363 +[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\axis\waveform.gtkw" +[timestart] 0 +[size] 1920 1057 +[pos] -1 -1 +*-25.000000 90900000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[sst_width] 197 +[signals_width] 166 +[sst_expanded] 1 +[sst_vpaned_height] 314 +@22 +[color] 5 +tb_axis.clk_count[7:0] +@28 +[color] 3 +tb_axis.clk +[color] 3 +tb_axis.rst_n +tb_axis.m_axis_tvalid +@22 +tb_axis.m_axis_tdata[7:0] +@28 +tb_axis.m_axis_tstrb[0] +tb_axis.m_axis_tready +[color] 2 +tb_axis.s_axis_tvalid +@22 +[color] 2 +tb_axis.s_axis_tdata[7:0] +@29 +[color] 2 +tb_axis.s_axis_tstrb[0] +@28 +[color] 2 +tb_axis.s_axis_tready +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/ghdl/basic/compile.bat b/ghdl/basic/compile.bat new file mode 100644 index 0000000..cfa2e99 --- /dev/null +++ b/ghdl/basic/compile.bat @@ -0,0 +1,23 @@ + +ghdl --version + +:: delete +del /Q *.vcd & +del /Q *.o & +del /Q *.exe & +del /Q *.cf & + +:: analyze +ghdl -a skidbuffer.vhd +ghdl -a tb_skid.vhd +:: elaborate +ghdl -e skidbuffer +ghdl -e tb_skid +:: run +ghdl -r tb_skid --vcd=wave.vcd --stop-time=1us +gtkwave wave.vcd waveform.gtkw + +:: delete +del /Q *.o & +del /Q *.exe & +del /Q *.cf & diff --git a/ghdl/basic/skidbuffer.vhd b/ghdl/basic/skidbuffer.vhd new file mode 100644 index 0000000..f71abcf --- /dev/null +++ b/ghdl/basic/skidbuffer.vhd @@ -0,0 +1,147 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: AXIS skidbuffer +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: skidbuffer for pipelining a bus handshake +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity skidbuffer is + generic ( + DATA_WIDTH : integer := 32; + OPT_DATA_REG : boolean := True + ); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0) + ); +end skidbuffer; + +architecture arch_imp of skidbuffer is + -- register signals + signal reg_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal reg_last : std_logic; + signal reg_valid : std_logic; + signal reg_ready : std_logic; + + -- skid buffer signals (only used when OPT_DATA_REG = '1') + signal skd_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal skd_last : std_logic; + + -- output signals for output multiplexer + signal out_data : std_logic_vector(DATA_WIDTH-1 downto 0); + signal out_last : std_logic; + +begin + -- I/O connections assignments + m_valid_o <= reg_valid; + s_ready_o <= reg_ready; + m_data_o <= out_data; + m_last_o <= out_last; + + -- ready is always registered + p_reg_ready : process(clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_ready <= '0'; + else + reg_ready <= m_ready_i; + end if; + end if; + end process; + +-- NOT REGISTERED OUTPUT ------------------------------------------------------- + gen_no_register : if not OPT_DATA_REG generate + reg_valid <= s_valid_i; -- valid is not registered + -- output multiplexer + out_data <= reg_data when (reg_ready = '0') else s_data_i; + out_last <= reg_last when (reg_ready = '0') else s_last_i; + + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= reg_data; + reg_last <= reg_last; + end if; + end if; + end if; + end process; + + end generate; + +-- FULLY REGISTERED OUTPUT ----------------------------------------------------- + gen_data_register : if OPT_DATA_REG generate + out_data <= reg_data; + out_last <= reg_last; + -- registered output signals + p_reg : process (clock) + begin + if rising_edge(clock) then + if reset_n = '0' then + reg_data <= (others => '0'); + reg_last <= '0'; + skd_data <= (others => '0'); + skd_last <= '0'; + reg_valid <= '0'; + else + reg_valid <= s_valid_i; + if reg_ready = '1' then + skd_data <= s_data_i; + skd_last <= s_last_i; + else + skd_data <= skd_data; + skd_last <= skd_last; + end if; + + if m_ready_i = '0' then + reg_data <= reg_data; + reg_last <= reg_last; + else + if reg_ready = '1' then + reg_data <= s_data_i; + reg_last <= s_last_i; + else + reg_data <= skd_data; + reg_last <= skd_last; + end if; + end if; + end if; + end if; + end process; + end generate; + +end arch_imp; diff --git a/ghdl/basic/tb_skid.vhd b/ghdl/basic/tb_skid.vhd new file mode 100644 index 0000000..6dd7a94 --- /dev/null +++ b/ghdl/basic/tb_skid.vhd @@ -0,0 +1,245 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: simon.burkhardt +-- +-- Create Date: 2023-04-21 +-- Design Name: skid buffer testbench +-- Module Name: tb_skid - bh +-- Project Name: +-- Target Devices: +-- Tool Versions: GHDL 0.37 +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +-- this testbench acts as a streaming master, sending bursts of data +-- counting from 1-4, also asserting tlast on the 4th data packet + +-- the testbench itself acts as a correct streaming master which keeps the data +-- until it is acknowledged by the DUT by asserting tready. + +-- the data pattern can be influenced by the user in 2 ways +-- + Tx requests are generated by changing the pattern in p_stimuli_tready +-- the master will try to send data for as long as sim_valid_data = '1' +-- + Rx acknowledgements are generated by changing the pattern in p_stimuli_tready +-- the downstream slave after the DUT will signal ready-to-receive +-- when sim_ready_data = '1' + +-- simulate both with OPT_DATA_REG = True / False +entity tb_skid is + generic + ( + DATA_WIDTH : natural := 8; + OPT_DATA_REG : boolean := True + ); +end tb_skid; + +architecture bh of tb_skid is + -- DUT component declaration + component skidbuffer is + generic ( + DATA_WIDTH : natural; + OPT_DATA_REG : boolean); + port ( + clock : in std_logic; + reset_n : in std_logic; + + s_valid_i : in std_logic; + s_last_i : in std_logic; + s_ready_o : out std_logic; + s_data_i : in std_logic_vector(DATA_WIDTH - 1 downto 0); + + m_valid_o : out std_logic; + m_last_o : out std_logic; + m_ready_i : in std_logic; + m_data_o : out std_logic_vector(DATA_WIDTH - 1 downto 0)); + end component; + + constant CLK_PERIOD: TIME := 5 ns; + + signal sim_valid_data : std_logic := '0'; + signal sim_ready_data : std_logic := '1'; + signal sim_data : std_logic_vector(DATA_WIDTH-1 downto 0); + + signal s_axis_tvalid : std_logic := '0'; + signal s_axis_tdata : std_logic_vector(DATA_WIDTH-1 downto 0); + signal s_axis_tlast : std_logic; + signal s_axis_tready : std_logic; + + signal m_axis_tvalid : std_logic; + signal m_axis_tdata : std_logic_vector(DATA_WIDTH-1 downto 0); + signal m_axis_tlast : std_logic; + signal m_axis_tready : std_logic := '0'; + + signal clk : std_logic; + signal rst_n : std_logic; + + signal clk_count : std_logic_vector(7 downto 0) := (others => '0'); +begin + + -- generate clk signal + p_clk_gen : process + begin + clk <= '1'; + wait for (CLK_PERIOD / 2); + clk <= '0'; + wait for (CLK_PERIOD / 2); + clk_count <= std_logic_vector(unsigned(clk_count) + 1); + end process; + + -- generate initial reset + p_reset_gen : process + begin + rst_n <= '0'; + wait until rising_edge(clk); + wait for (CLK_PERIOD / 4); + rst_n <= '1'; + wait; + end process; + + -- generate ready signal + p_stimuli_tready : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + m_axis_tready <= '1'; + else + m_axis_tready <= sim_ready_data; + if unsigned(clk_count) = 2 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 7 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 8 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 11 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 13 then + sim_ready_data <= '1'; + end if; + if unsigned(clk_count) = 14 then + sim_ready_data <= '0'; + end if; + if unsigned(clk_count) = 15 then + sim_ready_data <= '1'; + end if; + end if; + end if; + end process; + + -- generate valid signal + p_stimuli_tvalid : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + sim_valid_data <= '0'; + else + if unsigned(clk_count) = 2 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 18 then + sim_valid_data <= '0'; + end if; + if unsigned(clk_count) = 21 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 23 then + sim_valid_data <= '0'; + end if; + if unsigned(clk_count) = 24 then + sim_valid_data <= '1'; + end if; + if unsigned(clk_count) = 26 then + sim_valid_data <= '0'; + end if; + end if; + end if; + end process; + + -- generate counter data when successfully acknowledged (tready) by slave + p_stimuli_tdata : process(clk) + begin + if rising_edge(clk) then + if rst_n = '0' then + s_axis_tdata <= (others => '0'); + sim_data <= (others => '0'); + s_axis_tlast <= '0'; + else + if sim_valid_data = '1' then -- VALID can be controlled + if s_axis_tready = '1' then -- READY can be controlled + if unsigned(s_axis_tdata) = 3 then + s_axis_tlast <= '1'; + else + s_axis_tlast <= '0'; + end if; + + if unsigned(s_axis_tdata) = 4 then + -- restart counter at "1" + s_axis_tdata(DATA_WIDTH-1 downto 1) <= (others => '0'); + s_axis_tdata(0) <= '1'; + sim_data(DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + if (unsigned(sim_data) > unsigned(s_axis_tdata)) and (unsigned(sim_data) < 4) then + s_axis_tdata <= std_logic_vector(unsigned(sim_data) + 1); + else + s_axis_tdata <= std_logic_vector(unsigned(s_axis_tdata) + 1); + end if; + + if unsigned(sim_data) = 4 then + sim_data(DATA_WIDTH-1 downto 1) <= (others => '0'); + sim_data(0) <= '1'; + else + sim_data <= std_logic_vector(unsigned(sim_data) + 1); + end if; + end if; + else + s_axis_tdata <= s_axis_tdata; + sim_data <= sim_data; + end if; + s_axis_tvalid <= '1'; + else + s_axis_tvalid <= '0'; + s_axis_tlast <= '0'; + s_axis_tdata <= (others => '0'); + sim_data <= sim_data; + end if; + end if; + end if; + end process; + +-- DUT instance and connections + skidbuffer_inst : skidbuffer + generic map ( + DATA_WIDTH => DATA_WIDTH, + OPT_DATA_REG => OPT_DATA_REG + ) + port map ( + clock => clk, + reset_n => rst_n, + + s_valid_i => s_axis_tvalid, + s_last_i => s_axis_tlast, + s_ready_o => s_axis_tready, + s_data_i => s_axis_tdata, + + m_valid_o => m_axis_tvalid, + m_last_o => m_axis_tlast, + m_ready_i => m_axis_tready, + m_data_o => m_axis_tdata + ); + +end bh; diff --git a/ghdl/basic/wave.vcd b/ghdl/basic/wave.vcd new file mode 100644 index 0000000..cce1d8d --- /dev/null +++ b/ghdl/basic/wave.vcd @@ -0,0 +1,1793 @@ +$date + Fri Apr 21 08:48:36 2023 +$end +$version + GHDL v0 +$end +$timescale + 1 fs +$end +$scope module standard $end +$upscope $end +$scope module std_logic_1164 $end +$upscope $end +$scope module numeric_std $end +$upscope $end +$scope module tb_skid $end +$var reg 1 ! sim_valid_data $end +$var reg 1 " sim_ready_data $end +$var reg 8 # sim_data[7:0] $end +$var reg 1 $ s_axis_tvalid $end +$var reg 8 % s_axis_tdata[7:0] $end +$var reg 1 & s_axis_tlast $end +$var reg 1 ' s_axis_tready $end +$var reg 1 ( m_axis_tvalid $end +$var reg 8 ) m_axis_tdata[7:0] $end +$var reg 1 * m_axis_tlast $end +$var reg 1 + m_axis_tready $end +$var reg 1 , clk $end +$var reg 1 - rst_n $end +$var reg 8 . clk_count[7:0] $end +$scope module skidbuffer_inst $end +$var reg 1 / clock $end +$var reg 1 0 reset_n $end +$var reg 1 1 s_valid_i $end +$var reg 1 2 s_last_i $end +$var reg 1 3 s_ready_o $end +$var reg 8 4 s_data_i[7:0] $end +$var reg 1 5 m_valid_o $end +$var reg 1 6 m_last_o $end +$var reg 1 7 m_ready_i $end +$var reg 8 8 m_data_o[7:0] $end +$var reg 8 9 reg_data[7:0] $end +$var reg 1 : reg_last $end +$var reg 1 ; reg_valid $end +$var reg 1 < reg_ready $end +$var reg 8 = skd_data[7:0] $end +$var reg 1 > skd_last $end +$var reg 8 ? out_data[7:0] $end +$var reg 1 @ out_last $end +$scope module gen_data_register $end +$upscope $end +$upscope $end +$upscope $end +$enddefinitions $end +#0 +0! +1" +bUUUUUUUU # +0$ +bUUUUUUUU % +U& +U' +U( +bUUUUUUUU ) +U* +0+ +1, +0- +b00000000 . +1/ +00 +01 +U2 +U3 +bUUUUUUUU 4 +U5 +U6 +07 +bUUUUUUUU 8 +bUUUUUUUU 9 +U: +U; +U< +bUUUUUUUU = +U> +bUUUUUUUU ? +U@ +#2500000 +0, +0/ +#5000000 +b00000000 # +b00000000 % +0& +0' +0( +b00000000 ) +0* +1+ +1, +b00000001 . +1/ +02 +03 +b00000000 4 +05 +06 +17 +b00000000 8 +b00000000 9 +0: +0; +0< +b00000000 = +0> +b00000000 ? +0@ +#6250000 +1- +10 +#7500000 +0, +0/ +#10000000 +1! +1' +1, +b00000010 . +1/ +13 +1< +#12500000 +0, +0/ +#15000000 +b00000001 # +1$ +b00000001 % +1, +b00000011 . +1/ +11 +b00000001 4 +#17500000 +0, +0/ +#20000000 +b00000010 # +b00000010 % +1( +b00000001 ) +1, +b00000100 . +1/ +b00000010 4 +15 +b00000001 8 +b00000001 9 +1; +b00000001 = +b00000001 ? +#22500000 +0, +0/ +#25000000 +b00000011 # +b00000011 % +b00000010 ) +1, +b00000101 . +1/ +b00000011 4 +b00000010 8 +b00000010 9 +b00000010 = +b00000010 ? +#27500000 +0, +0/ +#30000000 +b00000100 # +b00000100 % +1& +b00000011 ) +1, +b00000110 . +1/ +12 +b00000100 4 +b00000011 8 +b00000011 9 +b00000011 = +b00000011 ? +#32500000 +0, +0/ +#35000000 +0" +b00000001 # +b00000001 % +0& +b00000100 ) +1* +1, +b00000111 . +1/ +02 +b00000001 4 +16 +b00000100 8 +b00000100 9 +1: +b00000100 = +1> +b00000100 ? +1@ +#37500000 +0, +0/ +#40000000 +1" +b00000010 # +b00000010 % +b00000001 ) +0* +0+ +1, +b00001000 . +1/ +b00000010 4 +06 +07 +b00000001 8 +b00000001 9 +0: +b00000001 = +0> +b00000001 ? +0@ +#42500000 +0, +0/ +#45000000 +b00000011 # +b00000011 % +0' +1+ +1, +b00001001 . +1/ +03 +b00000011 4 +17 +0< +b00000010 = +#47500000 +0, +0/ +#50000000 +1' +b00000010 ) +1, +b00001010 . +1/ +13 +b00000010 8 +b00000010 9 +1< +b00000010 ? +#52500000 +0, +0/ +#55000000 +0" +b00000100 # +b00000100 % +1& +b00000011 ) +1, +b00001011 . +1/ +12 +b00000100 4 +b00000011 8 +b00000011 9 +b00000011 = +b00000011 ? +#57500000 +0, +0/ +#60000000 +b00000001 # +b00000001 % +0& +b00000100 ) +1* +0+ +1, +b00001100 . +1/ +02 +b00000001 4 +16 +07 +b00000100 8 +b00000100 9 +1: +b00000100 = +1> +b00000100 ? +1@ +#62500000 +0, +0/ +#65000000 +1" +b00000010 # +b00000010 % +0' +1, +b00001101 . +1/ +03 +b00000010 4 +0< +b00000001 = +0> +#67500000 +0, +0/ +#70000000 +0" +1+ +1, +b00001110 . +1/ +17 +#72500000 +0, +0/ +#75000000 +1" +1' +b00000001 ) +0* +0+ +1, +b00001111 . +1/ +13 +06 +07 +b00000001 8 +b00000001 9 +0: +1< +b00000001 ? +0@ +#77500000 +0, +0/ +#80000000 +b00000011 # +b00000011 % +0' +1+ +1, +b00010000 . +1/ +03 +b00000011 4 +17 +0< +b00000010 = +#82500000 +0, +0/ +#85000000 +1' +b00000010 ) +1, +b00010001 . +1/ +13 +b00000010 8 +b00000010 9 +1< +b00000010 ? +#87500000 +0, +0/ +#90000000 +0! +b00000100 # +b00000100 % +1& +b00000011 ) +1, +b00010010 . +1/ +12 +b00000100 4 +b00000011 8 +b00000011 9 +b00000011 = +b00000011 ? +#92500000 +0, +0/ +#95000000 +0$ +b00000000 % +0& +b00000100 ) +1* +1, +b00010011 . +1/ +01 +02 +b00000000 4 +16 +b00000100 8 +b00000100 9 +1: +b00000100 = +1> +b00000100 ? +1@ +#97500000 +0, +0/ +#100000000 +0( +b00000000 ) +0* +1, +b00010100 . +1/ +05 +06 +b00000000 8 +b00000000 9 +0: +0; +b00000000 = +0> +b00000000 ? +0@ +#102500000 +0, +0/ +#105000000 +1! +1, +b00010101 . +1/ +#107500000 +0, +0/ +#110000000 +b00000001 # +1$ +b00000001 % +1, +b00010110 . +1/ +11 +b00000001 4 +#112500000 +0, +0/ +#115000000 +0! +b00000010 # +b00000010 % +1( +b00000001 ) +1, +b00010111 . +1/ +b00000010 4 +15 +b00000001 8 +b00000001 9 +1; +b00000001 = +b00000001 ? +#117500000 +0, +0/ +#120000000 +1! +0$ +b00000000 % +b00000010 ) +1, +b00011000 . +1/ +01 +b00000000 4 +b00000010 8 +b00000010 9 +b00000010 = +b00000010 ? +#122500000 +0, +0/ +#125000000 +b00000011 # +1$ +b00000011 % +0( +b00000000 ) +1, +b00011001 . +1/ +11 +b00000011 4 +05 +b00000000 8 +b00000000 9 +0; +b00000000 = +b00000000 ? +#127500000 +0, +0/ +#130000000 +0! +b00000100 # +b00000100 % +1& +1( +b00000011 ) +1, +b00011010 . +1/ +12 +b00000100 4 +15 +b00000011 8 +b00000011 9 +1; +b00000011 = +b00000011 ? +#132500000 +0, +0/ +#135000000 +0$ +b00000000 % +0& +b00000100 ) +1* +1, +b00011011 . +1/ +01 +02 +b00000000 4 +16 +b00000100 8 +b00000100 9 +1: +b00000100 = +1> +b00000100 ? +1@ +#137500000 +0, +0/ +#140000000 +0( +b00000000 ) +0* +1, +b00011100 . +1/ +05 +06 +b00000000 8 +b00000000 9 +0: +0; +b00000000 = +0> +b00000000 ? +0@ +#142500000 +0, +0/ +#145000000 +1, +b00011101 . +1/ +#147500000 +0, +0/ +#150000000 +1, +b00011110 . +1/ +#152500000 +0, +0/ +#155000000 +1, +b00011111 . +1/ +#157500000 +0, +0/ +#160000000 +1, +b00100000 . +1/ +#162500000 +0, +0/ +#165000000 +1, +b00100001 . +1/ +#167500000 +0, +0/ +#170000000 +1, +b00100010 . +1/ +#172500000 +0, +0/ +#175000000 +1, +b00100011 . +1/ +#177500000 +0, +0/ +#180000000 +1, +b00100100 . +1/ +#182500000 +0, +0/ +#185000000 +1, +b00100101 . +1/ +#187500000 +0, +0/ +#190000000 +1, +b00100110 . +1/ +#192500000 +0, +0/ +#195000000 +1, +b00100111 . +1/ +#197500000 +0, +0/ +#200000000 +1, +b00101000 . +1/ +#202500000 +0, +0/ +#205000000 +1, +b00101001 . +1/ +#207500000 +0, +0/ +#210000000 +1, +b00101010 . +1/ +#212500000 +0, +0/ +#215000000 +1, +b00101011 . +1/ +#217500000 +0, +0/ +#220000000 +1, +b00101100 . +1/ +#222500000 +0, +0/ +#225000000 +1, +b00101101 . +1/ +#227500000 +0, +0/ +#230000000 +1, +b00101110 . +1/ +#232500000 +0, +0/ +#235000000 +1, +b00101111 . +1/ +#237500000 +0, +0/ +#240000000 +1, +b00110000 . +1/ +#242500000 +0, +0/ +#245000000 +1, +b00110001 . +1/ +#247500000 +0, +0/ +#250000000 +1, +b00110010 . +1/ +#252500000 +0, +0/ +#255000000 +1, +b00110011 . +1/ +#257500000 +0, +0/ +#260000000 +1, +b00110100 . +1/ +#262500000 +0, +0/ +#265000000 +1, +b00110101 . +1/ +#267500000 +0, +0/ +#270000000 +1, +b00110110 . +1/ +#272500000 +0, +0/ +#275000000 +1, +b00110111 . +1/ +#277500000 +0, +0/ +#280000000 +1, +b00111000 . +1/ +#282500000 +0, +0/ +#285000000 +1, +b00111001 . +1/ +#287500000 +0, +0/ +#290000000 +1, +b00111010 . +1/ +#292500000 +0, +0/ +#295000000 +1, +b00111011 . +1/ +#297500000 +0, +0/ +#300000000 +1, +b00111100 . +1/ +#302500000 +0, +0/ +#305000000 +1, +b00111101 . +1/ +#307500000 +0, +0/ +#310000000 +1, +b00111110 . +1/ +#312500000 +0, +0/ +#315000000 +1, +b00111111 . +1/ +#317500000 +0, +0/ +#320000000 +1, +b01000000 . +1/ +#322500000 +0, +0/ +#325000000 +1, +b01000001 . +1/ +#327500000 +0, +0/ +#330000000 +1, +b01000010 . +1/ +#332500000 +0, +0/ +#335000000 +1, +b01000011 . +1/ +#337500000 +0, +0/ +#340000000 +1, +b01000100 . +1/ +#342500000 +0, +0/ +#345000000 +1, +b01000101 . +1/ +#347500000 +0, +0/ +#350000000 +1, +b01000110 . +1/ +#352500000 +0, +0/ +#355000000 +1, +b01000111 . +1/ +#357500000 +0, +0/ +#360000000 +1, +b01001000 . +1/ +#362500000 +0, +0/ +#365000000 +1, +b01001001 . +1/ +#367500000 +0, +0/ +#370000000 +1, +b01001010 . +1/ +#372500000 +0, +0/ +#375000000 +1, +b01001011 . +1/ +#377500000 +0, +0/ +#380000000 +1, +b01001100 . +1/ +#382500000 +0, +0/ +#385000000 +1, +b01001101 . +1/ +#387500000 +0, +0/ +#390000000 +1, +b01001110 . +1/ +#392500000 +0, +0/ +#395000000 +1, +b01001111 . +1/ +#397500000 +0, +0/ +#400000000 +1, +b01010000 . +1/ +#402500000 +0, +0/ +#405000000 +1, +b01010001 . +1/ +#407500000 +0, +0/ +#410000000 +1, +b01010010 . +1/ +#412500000 +0, +0/ +#415000000 +1, +b01010011 . +1/ +#417500000 +0, +0/ +#420000000 +1, +b01010100 . +1/ +#422500000 +0, +0/ +#425000000 +1, +b01010101 . +1/ +#427500000 +0, +0/ +#430000000 +1, +b01010110 . +1/ +#432500000 +0, +0/ +#435000000 +1, +b01010111 . +1/ +#437500000 +0, +0/ +#440000000 +1, +b01011000 . +1/ +#442500000 +0, +0/ +#445000000 +1, +b01011001 . +1/ +#447500000 +0, +0/ +#450000000 +1, +b01011010 . +1/ +#452500000 +0, +0/ +#455000000 +1, +b01011011 . +1/ +#457500000 +0, +0/ +#460000000 +1, +b01011100 . +1/ +#462500000 +0, +0/ +#465000000 +1, +b01011101 . +1/ +#467500000 +0, +0/ +#470000000 +1, +b01011110 . +1/ +#472500000 +0, +0/ +#475000000 +1, +b01011111 . +1/ +#477500000 +0, +0/ +#480000000 +1, +b01100000 . +1/ +#482500000 +0, +0/ +#485000000 +1, +b01100001 . +1/ +#487500000 +0, +0/ +#490000000 +1, +b01100010 . +1/ +#492500000 +0, +0/ +#495000000 +1, +b01100011 . +1/ +#497500000 +0, +0/ +#500000000 +1, +b01100100 . +1/ +#502500000 +0, +0/ +#505000000 +1, +b01100101 . +1/ +#507500000 +0, +0/ +#510000000 +1, +b01100110 . +1/ +#512500000 +0, +0/ +#515000000 +1, +b01100111 . +1/ +#517500000 +0, +0/ +#520000000 +1, +b01101000 . +1/ +#522500000 +0, +0/ +#525000000 +1, +b01101001 . +1/ +#527500000 +0, +0/ +#530000000 +1, +b01101010 . +1/ +#532500000 +0, +0/ +#535000000 +1, +b01101011 . +1/ +#537500000 +0, +0/ +#540000000 +1, +b01101100 . +1/ +#542500000 +0, +0/ +#545000000 +1, +b01101101 . +1/ +#547500000 +0, +0/ +#550000000 +1, +b01101110 . +1/ +#552500000 +0, +0/ +#555000000 +1, +b01101111 . +1/ +#557500000 +0, +0/ +#560000000 +1, +b01110000 . +1/ +#562500000 +0, +0/ +#565000000 +1, +b01110001 . +1/ +#567500000 +0, +0/ +#570000000 +1, +b01110010 . +1/ +#572500000 +0, +0/ +#575000000 +1, +b01110011 . +1/ +#577500000 +0, +0/ +#580000000 +1, +b01110100 . +1/ +#582500000 +0, +0/ +#585000000 +1, +b01110101 . +1/ +#587500000 +0, +0/ +#590000000 +1, +b01110110 . +1/ +#592500000 +0, +0/ +#595000000 +1, +b01110111 . +1/ +#597500000 +0, +0/ +#600000000 +1, +b01111000 . +1/ +#602500000 +0, +0/ +#605000000 +1, +b01111001 . +1/ +#607500000 +0, +0/ +#610000000 +1, +b01111010 . +1/ +#612500000 +0, +0/ +#615000000 +1, +b01111011 . +1/ +#617500000 +0, +0/ +#620000000 +1, +b01111100 . +1/ +#622500000 +0, +0/ +#625000000 +1, +b01111101 . +1/ +#627500000 +0, +0/ +#630000000 +1, +b01111110 . +1/ +#632500000 +0, +0/ +#635000000 +1, +b01111111 . +1/ +#637500000 +0, +0/ +#640000000 +1, +b10000000 . +1/ +#642500000 +0, +0/ +#645000000 +1, +b10000001 . +1/ +#647500000 +0, +0/ +#650000000 +1, +b10000010 . +1/ +#652500000 +0, +0/ +#655000000 +1, +b10000011 . +1/ +#657500000 +0, +0/ +#660000000 +1, +b10000100 . +1/ +#662500000 +0, +0/ +#665000000 +1, +b10000101 . +1/ +#667500000 +0, +0/ +#670000000 +1, +b10000110 . +1/ +#672500000 +0, +0/ +#675000000 +1, +b10000111 . +1/ +#677500000 +0, +0/ +#680000000 +1, +b10001000 . +1/ +#682500000 +0, +0/ +#685000000 +1, +b10001001 . +1/ +#687500000 +0, +0/ +#690000000 +1, +b10001010 . +1/ +#692500000 +0, +0/ +#695000000 +1, +b10001011 . +1/ +#697500000 +0, +0/ +#700000000 +1, +b10001100 . +1/ +#702500000 +0, +0/ +#705000000 +1, +b10001101 . +1/ +#707500000 +0, +0/ +#710000000 +1, +b10001110 . +1/ +#712500000 +0, +0/ +#715000000 +1, +b10001111 . +1/ +#717500000 +0, +0/ +#720000000 +1, +b10010000 . +1/ +#722500000 +0, +0/ +#725000000 +1, +b10010001 . +1/ +#727500000 +0, +0/ +#730000000 +1, +b10010010 . +1/ +#732500000 +0, +0/ +#735000000 +1, +b10010011 . +1/ +#737500000 +0, +0/ +#740000000 +1, +b10010100 . +1/ +#742500000 +0, +0/ +#745000000 +1, +b10010101 . +1/ +#747500000 +0, +0/ +#750000000 +1, +b10010110 . +1/ +#752500000 +0, +0/ +#755000000 +1, +b10010111 . +1/ +#757500000 +0, +0/ +#760000000 +1, +b10011000 . +1/ +#762500000 +0, +0/ +#765000000 +1, +b10011001 . +1/ +#767500000 +0, +0/ +#770000000 +1, +b10011010 . +1/ +#772500000 +0, +0/ +#775000000 +1, +b10011011 . +1/ +#777500000 +0, +0/ +#780000000 +1, +b10011100 . +1/ +#782500000 +0, +0/ +#785000000 +1, +b10011101 . +1/ +#787500000 +0, +0/ +#790000000 +1, +b10011110 . +1/ +#792500000 +0, +0/ +#795000000 +1, +b10011111 . +1/ +#797500000 +0, +0/ +#800000000 +1, +b10100000 . +1/ +#802500000 +0, +0/ +#805000000 +1, +b10100001 . +1/ +#807500000 +0, +0/ +#810000000 +1, +b10100010 . +1/ +#812500000 +0, +0/ +#815000000 +1, +b10100011 . +1/ +#817500000 +0, +0/ +#820000000 +1, +b10100100 . +1/ +#822500000 +0, +0/ +#825000000 +1, +b10100101 . +1/ +#827500000 +0, +0/ +#830000000 +1, +b10100110 . +1/ +#832500000 +0, +0/ +#835000000 +1, +b10100111 . +1/ +#837500000 +0, +0/ +#840000000 +1, +b10101000 . +1/ +#842500000 +0, +0/ +#845000000 +1, +b10101001 . +1/ +#847500000 +0, +0/ +#850000000 +1, +b10101010 . +1/ +#852500000 +0, +0/ +#855000000 +1, +b10101011 . +1/ +#857500000 +0, +0/ +#860000000 +1, +b10101100 . +1/ +#862500000 +0, +0/ +#865000000 +1, +b10101101 . +1/ +#867500000 +0, +0/ +#870000000 +1, +b10101110 . +1/ +#872500000 +0, +0/ +#875000000 +1, +b10101111 . +1/ +#877500000 +0, +0/ +#880000000 +1, +b10110000 . +1/ +#882500000 +0, +0/ +#885000000 +1, +b10110001 . +1/ +#887500000 +0, +0/ +#890000000 +1, +b10110010 . +1/ +#892500000 +0, +0/ +#895000000 +1, +b10110011 . +1/ +#897500000 +0, +0/ +#900000000 +1, +b10110100 . +1/ +#902500000 +0, +0/ +#905000000 +1, +b10110101 . +1/ +#907500000 +0, +0/ +#910000000 +1, +b10110110 . +1/ +#912500000 +0, +0/ +#915000000 +1, +b10110111 . +1/ +#917500000 +0, +0/ +#920000000 +1, +b10111000 . +1/ +#922500000 +0, +0/ +#925000000 +1, +b10111001 . +1/ +#927500000 +0, +0/ +#930000000 +1, +b10111010 . +1/ +#932500000 +0, +0/ +#935000000 +1, +b10111011 . +1/ +#937500000 +0, +0/ +#940000000 +1, +b10111100 . +1/ +#942500000 +0, +0/ +#945000000 +1, +b10111101 . +1/ +#947500000 +0, +0/ +#950000000 +1, +b10111110 . +1/ +#952500000 +0, +0/ +#955000000 +1, +b10111111 . +1/ +#957500000 +0, +0/ +#960000000 +1, +b11000000 . +1/ +#962500000 +0, +0/ +#965000000 +1, +b11000001 . +1/ +#967500000 +0, +0/ +#970000000 +1, +b11000010 . +1/ +#972500000 +0, +0/ +#975000000 +1, +b11000011 . +1/ +#977500000 +0, +0/ +#980000000 +1, +b11000100 . +1/ +#982500000 +0, +0/ +#985000000 +1, +b11000101 . +1/ +#987500000 +0, +0/ +#990000000 +1, +b11000110 . +1/ +#992500000 +0, +0/ +#995000000 +1, +b11000111 . +1/ +#997500000 +0, +0/ +#1000000000 +1, +b11001000 . +1/ diff --git a/ghdl/basic/waveform.gtkw b/ghdl/basic/waveform.gtkw new file mode 100644 index 0000000..a140493 --- /dev/null +++ b/ghdl/basic/waveform.gtkw @@ -0,0 +1,45 @@ +[*] +[*] GTKWave Analyzer v3.3.100 (w)1999-2019 BSI +[*] Fri Apr 21 06:49:43 2023 +[*] +[dumpfile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\wave.vcd" +[dumpfile_mtime] "Fri Apr 21 06:48:36 2023" +[dumpfile_size] 14803 +[savefile] "C:\Users\simon\Downloads\P9\ghdl-axi-sim\axis-skidbuffer\ghdl\waveform.gtkw" +[timestart] 0 +[size] 1920 1057 +[pos] -1 -1 +*-25.000000 163500000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] tb_skid. +[sst_width] 197 +[signals_width] 317 +[sst_expanded] 1 +[sst_vpaned_height] 361 +@24 +[color] 5 +tb_skid.clk_count[7:0] +@28 +[color] 3 +tb_skid.clk +[color] 3 +tb_skid.rst_n +tb_skid.s_axis_tvalid +@22 +tb_skid.s_axis_tdata[7:0] +@29 +tb_skid.m_axis_tlast +@28 +tb_skid.s_axis_tready +[color] 2 +tb_skid.m_axis_tvalid +@22 +[color] 2 +tb_skid.m_axis_tdata[7:0] +@29 +[color] 2 +tb_skid.s_axis_tlast +@28 +[color] 2 +tb_skid.m_axis_tready +[pattern_trace] 1 +[pattern_trace] 0 diff --git a/hw/bd/readme b/hw/bd/readme deleted file mode 100644 index 06760e1..0000000 --- a/hw/bd/readme +++ /dev/null @@ -1,5 +0,0 @@ -In case of a block based design, this dir would have a single tcl file to recreate the module. -For now, the scripts only support a single block and this block will be the top, except -for its wrapper which is automatically generated. - -If this design is not block based, then this dir should be left empty. diff --git a/hw/hdl/readme b/hw/hdl/readme deleted file mode 100644 index 133d726..0000000 --- a/hw/hdl/readme +++ /dev/null @@ -1,2 +0,0 @@ - -Place here the HDL sources of the design. It supports VHDL and Verilog files. diff --git a/hw/hdl/sim/readme b/hw/hdl/sim/readme deleted file mode 100644 index 8392f70..0000000 --- a/hw/hdl/sim/readme +++ /dev/null @@ -1,3 +0,0 @@ - -Place here the testbenches and waveform files. If these files dont exist in the design, then -left this dir empty. diff --git a/hw/hdl/skidbuffer.vhd b/hw/hdl/skidbuffer.vhd deleted file mode 100644 index 03577e5..0000000 --- a/hw/hdl/skidbuffer.vhd +++ /dev/null @@ -1,198 +0,0 @@ --- --- DVB IP --- --- source: https://raw.githubusercontent.com/suoto/fpga_cores/master/src/skidbuffer.vhd --- modified by Alexandre Amory - --- Copyright 2019 by Suoto --- --- This file is part of DVB IP. --- --- DVB IP is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- DVB IP is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with DVB IP. If not, see . - --- ########################################################################## --- ## Based on Dan Gisselquist's skidbuffer.v the original can be found in ## --- ## https://github.com/ZipCPU/wb2axip/blob/master/rtl/skidbuffer.v ## --- ########################################################################## - --------------------------------------------------------------------------------- --- --- Filename: skidbuffer.v --- --- Project: WB2AXIPSP: bus bridges and other odds and ends --- --- Purpose: A basic SKID buffer. --- --- Skid buffers are required for high throughput AXI code, since the AXI --- specification requires that all outputs be registered. This means --- that, if there are any stall conditions calculated, it will take a clock --- cycle before the stall can be propagated up stream. This means that --- the data will need to be buffered for a cycle until the stall signal --- can make it to the output. --- --- Handling that buffer is the purpose of this core. --- --- On one end of this core, you have the s_valid_i and s_data_i inputs to --- connect to your bus interface. There's also a registered s_ready_o --- signal to signal stalls for the bus interface. --- --- The other end of the core has the same basic interface, but it isn't --- registered. This allows you to interact with the bus interfaces --- as though they were combinatorial logic, by interacting with this half --- of the core. --- --- If at any time the incoming !stall signal, m_ready_i, signals a stall, --- the incoming data is placed into a buffer. Internally, that buffer --- is held in r_data with the r_valid flag used to indicate that valid --- data is within it. --- --- Parameters: --- DW or data width --- In order to make this core generic, the width of the data in the --- skid buffer is parameterized --- --- --- OPT_OUTREG --- Causes the outputs to be registered --- --- --- Creator: Dan Gisselquist, Ph.D. --- Gisselquist Technology, LLC --- - ---------------- --- Libraries -- ---------------- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity skidbuffer is - generic ( - DW : natural :=8; - OPT_OUTREG : boolean := True); - port ( - clock : in std_logic; - reset_n : in std_logic; - - s_valid_i : in std_logic; - s_last_i : in std_logic; - s_ready_o : out std_logic; - s_data_i : in std_logic_vector(DW - 1 downto 0); - - m_valid_o : out std_logic; - m_last_o : out std_logic; - m_ready_i : in std_logic; - m_data_o : out std_logic_vector(DW - 1 downto 0)); -end skidbuffer; - -architecture skidbuffer of skidbuffer is - signal r_data : std_logic_vector(DW - 1 downto 0); - signal r_valid : std_logic := '0'; - signal o_ready_i : std_logic; - signal o_valid_i : std_logic; - signal o_last_i : std_logic; -begin - - s_ready_o <= o_ready_i; - m_valid_o <= o_valid_i; - m_last_o <= o_last_i; - - process(clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - r_valid <= '0'; - else - if (s_valid_i = '1' and o_ready_i = '1') and (o_valid_i = '1' and m_ready_i = '0') then - -- We have incoming data, but the output is stalled - r_valid <= '1'; - elsif m_ready_i = '1' then - r_valid <= '0'; - end if; - end if; - - end if; - end process; - - process(clock) - begin - if rising_edge(clock) then - if (not OPT_OUTREG or s_valid_i = '1') and (o_ready_i = '1') then - r_data <= s_data_i; - end if; - end if; - end process; - - o_ready_i <= '1' when r_valid = '0' else '0'; - - -- - -- And then move on to the output port - -- - g_not_out_reg : if not OPT_OUTREG generate - o_valid_i <= '1' when reset_n = '1' and (s_valid_i = '1' or r_valid = '1') else '0'; - o_last_i <= '1' when reset_n = '1' and (s_valid_i = '1' or r_valid = '1') and s_last_i = '1' else '0'; - - process(r_valid, r_data, s_data_i, s_valid_i) - begin - if r_valid = '1' then - m_data_o <= r_data; - elsif s_valid_i = '0' then - m_data_o <= s_data_i; - end if; - end process; - end generate g_not_out_reg; - - g_out_reg : if OPT_OUTREG generate - process(clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - o_valid_i <= '0'; - elsif o_valid_i = '0' or m_ready_i = '1' then - o_valid_i <= s_valid_i or r_valid; - end if; - end if; - end process; - - process(clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - o_last_i <= '0'; - elsif o_last_i = '0' or m_ready_i = '1' then - o_last_i <= (s_valid_i or r_valid ) and s_last_i; - end if; - end if; - end process; - - process(clock) - begin - if rising_edge(clock) then - if reset_n = '0' then - m_data_o <= (others => '0'); - elsif o_valid_i = '0' or m_ready_i = '1' then - if r_valid = '1' then - m_data_o <= r_data; - elsif s_valid_i = '1' then - m_data_o <= s_data_i; - end if; - end if; - end if; - end process; - - end generate g_out_reg; - - -end skidbuffer; diff --git a/hw/ips/readme b/hw/ips/readme deleted file mode 100644 index caa2f77..0000000 --- a/hw/ips/readme +++ /dev/null @@ -1,8 +0,0 @@ - -If this design has custom IPs, then this dir would have directories to each custom IPs -linked to the IPs source repository (i.e. it's a git submodule dir). - -If this design is a custom IP, then this dir would have a directory with the IP's -component.xml file to recreate the IP's Vivado design for IP edition. - -Dont place any other dir or file here. diff --git a/hw/ips/skidbuffer/component.xml b/hw/ips/skidbuffer/component.xml deleted file mode 100644 index e764fda..0000000 --- a/hw/ips/skidbuffer/component.xml +++ /dev/null @@ -1,397 +0,0 @@ - - - user.org - user - skidbuffer - 1.0 - - - reset_n - - - - - - - RST - - - reset_n - - - - - - clock - - - - - - - CLK - - - clock - - - - - - ASSOCIATED_BUSIF - m:s - - - FREQ_HZ - 50000000 - - - - - m - - - - - - - TDATA - - - m_data_o - - - - - TVALID - - - m_valid_o - - - - - TLAST - - - m_last_o - - - - - TREADY - - - m_ready_i - - - - - - s - - - - - - - TVALID - - - s_valid_i - - - - - TLAST - - - s_last_i - - - - - TDATA - - - s_data_i - - - - - TREADY - - - s_ready_o - - - - - - - - - xilinx_anylanguagesynthesis - Synthesis - :vivado.xilinx.com:synthesis - VHDL - skidbuffer - - xilinx_anylanguagesynthesis_view_fileset - - - - viewChecksum - c3f0d67d - - - - - xilinx_anylanguagebehavioralsimulation - Simulation - :vivado.xilinx.com:simulation - VHDL - skidbuffer - - xilinx_anylanguagebehavioralsimulation_view_fileset - - - - viewChecksum - c3f0d67d - - - - - xilinx_xpgui - UI Layout - :vivado.xilinx.com:xgui.ui - - xilinx_xpgui_view_fileset - - - - viewChecksum - 924aa2d0 - - - - - - - clock - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - reset_n - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - s_valid_i - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - s_last_i - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - s_ready_o - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - s_data_i - - in - - 7 - 0 - - - - std_logic_vector - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - m_valid_o - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - m_last_o - - out - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - m_ready_i - - in - - - std_logic - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - m_data_o - - out - - 7 - 0 - - - - std_logic_vector - xilinx_anylanguagesynthesis - xilinx_anylanguagebehavioralsimulation - - - - - - - - DW - Dw - 8 - - - OPT_OUTREG - Opt Outreg - True - - - - - - xilinx_anylanguagesynthesis_view_fileset - - ../../hdl/skidbuffer.vhd - vhdlSource - CHECKSUM_8c692632 - IMPORTED_FILE - - - - xilinx_xpgui_view_fileset - - xgui/skidbuffer_v1_0.tcl - tclSource - CHECKSUM_924aa2d0 - XGUI_VERSION_2 - - - - skidbuffer_v1_0 - - - DW - Dw - 8 - - - OPT_OUTREG - Opt Outreg - True - - - Component_Name - skidbuffer_v1_0 - - - - - - zynq - qzynq - azynq - - - /UserIP - - skidbuffer_v1_0 - package_project - 3 - 2020-08-09T15:34:25Z - - /home/lsa/repos/xilinx/hdls/axis-skidbuffer/hw/ips/skidbuffer - - - - 2018.2 - - - - - - - - diff --git a/hw/ips/skidbuffer/xgui/skidbuffer_v1_0.tcl b/hw/ips/skidbuffer/xgui/skidbuffer_v1_0.tcl deleted file mode 100644 index 2ffd4f3..0000000 --- a/hw/ips/skidbuffer/xgui/skidbuffer_v1_0.tcl +++ /dev/null @@ -1,40 +0,0 @@ -# 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 "DW" -parent ${Page_0} - ipgui::add_param $IPINST -name "OPT_OUTREG" -parent ${Page_0} - - -} - -proc update_PARAM_VALUE.DW { PARAM_VALUE.DW } { - # Procedure called to update DW when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.DW { PARAM_VALUE.DW } { - # Procedure called to validate DW - return true -} - -proc update_PARAM_VALUE.OPT_OUTREG { PARAM_VALUE.OPT_OUTREG } { - # Procedure called to update OPT_OUTREG when any of the dependent parameters in the arguments change -} - -proc validate_PARAM_VALUE.OPT_OUTREG { PARAM_VALUE.OPT_OUTREG } { - # Procedure called to validate OPT_OUTREG - return true -} - - -proc update_MODELPARAM_VALUE.DW { MODELPARAM_VALUE.DW PARAM_VALUE.DW } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.DW}] ${MODELPARAM_VALUE.DW} -} - -proc update_MODELPARAM_VALUE.OPT_OUTREG { MODELPARAM_VALUE.OPT_OUTREG PARAM_VALUE.OPT_OUTREG } { - # Procedure called to set VHDL generic/Verilog parameter value(s) based on TCL parameter value - set_property value [get_property value ${PARAM_VALUE.OPT_OUTREG}] ${MODELPARAM_VALUE.OPT_OUTREG} -} - diff --git a/hw/xdc/readme b/hw/xdc/readme deleted file mode 100644 index a66a9e8..0000000 --- a/hw/xdc/readme +++ /dev/null @@ -1,2 +0,0 @@ - -Place here only constraint files (*.xdc) of the design. diff --git a/img/gtkwave_axi-to-axis.png b/img/gtkwave_axi-to-axis.png new file mode 100644 index 0000000..6c620fe Binary files /dev/null and b/img/gtkwave_axi-to-axis.png differ diff --git a/img/gtkwave_fullreg.png b/img/gtkwave_fullreg.png new file mode 100644 index 0000000..5712598 Binary files /dev/null and b/img/gtkwave_fullreg.png differ diff --git a/img/gtkwave_passthru.png b/img/gtkwave_passthru.png new file mode 100644 index 0000000..46fa752 Binary files /dev/null and b/img/gtkwave_passthru.png differ diff --git a/img/skidbuf_fullreg.png b/img/skidbuf_fullreg.png new file mode 100644 index 0000000..c63c136 Binary files /dev/null and b/img/skidbuf_fullreg.png differ diff --git a/img/skidbuf_fullreg.wavedrom.json b/img/skidbuf_fullreg.wavedrom.json new file mode 100644 index 0000000..1cd2010 --- /dev/null +++ b/img/skidbuf_fullreg.wavedrom.json @@ -0,0 +1,20 @@ +{signal: [ + {name: 'aclk', wave: 'P...........................'}, + {name: 'arst_n', wave: '01..........................'}, + {}, + {name: 's_valid 🡲', wave:'x.1...............0..1.01.0.'}, + {name: 's_data 🡲', wave:'x.3456345.634..5.6x..34x56x.', data: [1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]}, + {name: 's_ready 🡠', wave: 'x1......01..00101...........'}, + {}, + {name: 'm_valid 🡲', wave:'x..1...............0..1.01.0'}, + {name: 'm_data 🡲', wave:'x..34563.456..3.456x..34x56x', data: [1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]}, + {name: 'm_ready 🡠', wave: 'x.1....01..00101............'}, + +],config: { hscale: 1 }, + head:{ + text:'fully pipelined skidbuffer', + }, + foot:{ + tock:2 + } +} diff --git a/img/skidbuf_fullreg_wave.svg b/img/skidbuf_fullreg_wave.svg new file mode 100644 index 0000000..a06935c --- /dev/null +++ b/img/skidbuf_fullreg_wave.svg @@ -0,0 +1,4 @@ + + + +fully pipelined skidbuffer234567891011121314151617181920212223242526272829aclkarst_ns_valid 🡲s_data 🡲1234123412341234s_ready 🡠m_valid 🡲m_data 🡲1234123412341234m_ready 🡠 \ No newline at end of file diff --git a/img/skidbuf_passthru.png b/img/skidbuf_passthru.png new file mode 100644 index 0000000..3eba0f4 Binary files /dev/null and b/img/skidbuf_passthru.png differ diff --git a/img/skidbuf_passthru.wavedrom.json b/img/skidbuf_passthru.wavedrom.json new file mode 100644 index 0000000..9682cce --- /dev/null +++ b/img/skidbuf_passthru.wavedrom.json @@ -0,0 +1,20 @@ +{signal: [ + {name: 'aclk', wave: 'P...........................'}, + {name: 'arst_n', wave: '01..........................'}, + {}, + {name: 's_valid 🡲', wave:'x.1...............0..1.01.0.'}, + {name: 's_data 🡲', wave:'x.3456345.634..5.6x..34x56x.', data: [1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]}, + {name: 's_ready 🡠', wave: 'x1......01..00101...........'}, + {}, + {name: 'm_valid 🡲', wave:'x.1...............0..1.01.0'}, + {name: 'm_data 🡲', wave:'x.345634.563..4.56x..34x56x', data: [1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4]}, + {name: 'm_ready 🡠', wave: 'x.1....01..00101............'}, + +],config: { hscale: 1 }, + head:{ + text:'passthrough skidbuffer', + }, + foot:{ + tock:2 + } +} diff --git a/img/skidbuf_passthru_wave.svg b/img/skidbuf_passthru_wave.svg new file mode 100644 index 0000000..2f6ba2b --- /dev/null +++ b/img/skidbuf_passthru_wave.svg @@ -0,0 +1,4 @@ + + + +passthrough skidbuffer234567891011121314151617181920212223242526272829aclkarst_ns_valid 🡲s_data 🡲1234123412341234s_ready 🡠m_valid 🡲m_data 🡲1234123412341234m_ready 🡠 \ No newline at end of file diff --git a/img/skidbuffer-concepts.drawio b/img/skidbuffer-concepts.drawio new file mode 100644 index 0000000..10fa794 --- /dev/null +++ b/img/skidbuffer-concepts.drawio @@ -0,0 +1 @@ +7V1bc5s4FP41eXQHxP0xTu+bzLbTTps8dYiRbTbYooAbu79+hZFsEMJgByQcnM50zEFIQufTuUk6XGk3i/WHyA3nd8iDwRVQvPWV9vYKAMdW8f8pYZMRTMXOCLPI9zKSuid88/9CQlQIdeV7MC4UTBAKEj8sEidouYSTpEBzowg9F4tNUVBsNXRnsET4NnGDMvWn7yXzjGoDa0//CP3ZnLasmk52Z+HSwuRN4rnroeccSXt3pd1ECCXZr8X6Bgbp2NFxyZ57X3F317EILpMmD9x+HY//Ce+/3OmfRtf3H41rJx6NVMKNONnQN4YeHgByiaJkjmZo6Qbv9tRxhFZLD6bVKvhqX+YWoRATVUz8DybJhnDTXSUIk+bJIiB34dpP7nO/H9Kq3hjk6u2a1Ly92JCLKVom792FH6SE29XE91zc7xu0jNG2U+l90qBqpg8vveuU//j6MUCTp+9zf5mR3/vBriPLJNrcb1sHBr1+yN/cd2Z7RXtTHnzCjxitogk8NOKAoNiNZjA5VFDPCqb8yDVBmPsBogXEPcIFIhi4if+nCFiX4H62K7d79AvycaeBQqaoZhGAkhnqKMUaso6Sh/b4woPrbnLFwrRAXN2MbhebUQ0GrnXllcPlNfOF5bVCefwje0N6lRvyPWk7xY6YbjuU9H667WdGflqQpw5MjGOmKWg6TQXMNiql25ttOSQdDxTa7z9usCJNXQEzwG8wfsQ/Zsl2VDJCOqQFTJm/V4jeGMXbwb7GBVQzXGePkfu0ou+0JtzVrLJiA5ica5TBbxGdz3M/gd9Cd8uUZ2wRFJE4xTy9QQGKts9qUyP9R3qao2d/mB4nEXqCuTvm9u8QJP7AKIHrgyykEkbjSwDlea/odUKa53S8rnTFdOv8pMMb6yi92YkWf4F40Mri4eGd//wZ3IeLn58nX8eb67uHH/ZIsztRxscqUcAqReewkiuVt9pVcr/0zfXo4Zf5Yzb69zbwfkeLx83IePUoPgKVDGDagyl36KWAUmUtqRpQlsobAiwvOoQchUr059SdFNVnSTyVFKf/y3MTt1J7MrMAq6WkCNqieluiJWR0JCG5gT/DAHsbZUponOo4H/uo14S+8D1vO4146rc4tVrQm6xMsctq0+KoTdCZ2pQqcPZC5iEvY6QZ1SK0pt7QqKZWbF+Mar1OBtTb0KDChlZ25nnEms97itpUVMRzN0x/JngKw78ofatxCCMfjwOM8vQve2K97b2GNMCmngAqz4/gJPFRKnAwRNKpPo7J/ZYki8aKFrUsWjSOaLG7Ei1Armg5xZbZ2S7n6a87DUULaD069jKgmOdi9HbC8FPRJwAowsKoCmsWGcUqWoqjao5RaIeulLRlPXPdXxryeN1ykMLeliPnBAUemso5roMpVcwdhwPBLjqHoZ246C+zgJ1KC/gSVm4prKyxYWVHcliZOt6thj6Q4NBHAKfyIx8Gy1q9zFpbZOgDaOcjj1+FfwKaridSSdsX/6R6PfEl4c8Iut5m4EIAKLKFQG1Y6yT5Lpi3vYxt83grNLatOTIFvPS4wumCWjMaCmp5DtbBfrcsqHF1uNlhT2ZT9lw2O5HTglnbSx3MYa1QFSw3PjbAfX1UateLd7Nf4t2ulAGXAExH+/oMyfEXSz8/4dDhtj4B0sHkBGO5BamS6HpxCDCLQwYLtorFobZ2P9ln40YMD4JGJxA8ehOfw0do5SY+tnzLy5AHB5WjPePQXVYryykBRqou8S13keqvahu7cJ+rWks7/7L2X7lDxfKcs2FeqEdlXbbniJVqltlQqln9Cn87Uv2zY4ByrgxvX429bKFbkXrS7iIahNvcR++jMor7qAxbgAFjVYcAL+5/V+4/Jzgo1v+XeqxviKKoaXDQaj04yJc1bLjaYDesZ69Ucv/LFak1FXUcR7Cqw5fCHTB2fbpjD6yX6x6GVZZtQhc+rN545OUNC4N0yTmAEOqSO1KD3X07jCdA2dHpXqvsHK1XHhrt9+UwXl8P4+lF0aJzzvkKPYxnn02uqpPTSvVNttCMa2eyiKEBBrI1mQhK5Y9c9Di6fMvpN/hyHlymSV+niaDlZlZ079xGUcvNVNlcwlydhbmAyZct0sJcttww1wAt/6ZbnOl07IvlX7vF+WL5S7X8ARNl1Dk76IRa/k518ibhUSax+z76GXXkpGURGnV0zibFXLfZNo7UX6erGqfp4q5jybFwdcEWrlO9kCt8IYQ9ADLEuLcu+6AeBb58QJRPBA1RR/EAIVRHqUptxsnJzjPc81BTFGs6neZJDcxhpWQOn3KWLIIz0ad+J5jjW6tZLnp2Z0SYpErycloqtYe6+4gewWcRe4IenfmCAsddEgyeWg+7j+ARm1CmL9hhfG1VtiGjKrXHlC/g6Ql4WLWlc/IRCQZPtRncY/AMVG0x6NE4icoEo6d6e2GP0TNMk5n9fpIhPQ28Ur0XsafoQatkmIqLtZhVjslsCgUPNcMu4Dk78BhAHHj42ZGlnjUTtuOmm/TI/KzH4Kq03nAO6ZGlpuMUAoQO8yo3RkJ/Pn1U+hZO8SOSteXtw8XZLyUdWVwVkRqeMuiy16vDvV5s3mFOeLqrvV58pteubdTz2K7gcejGcTLHzJrN03qeUs9ceVxNp9j0GFaWO5XJGqRxTrKKtXS0Fr6gVMX36WrbfuiHMPAxM9K60o9zD4vnzLo2Z6IL5rjUzFGn7eo8IXOUSNu26enk9r9c8zIk1AbnLts25R7YYr9AJPDraXy/uNo07GlMJX7yhhlTAYDraYgIqXC9OXB+Wievcur3YnboR1e7x00CKkCQjjnUy4uK6U7FlGQCB0/VHgkTv+CsGLakYfBlhFIG7mMVeMDmd8iDaYn/AQ== \ No newline at end of file diff --git a/sdk.tcl b/sdk.tcl deleted file mode 100644 index ee5df76..0000000 --- a/sdk.tcl +++ /dev/null @@ -1,66 +0,0 @@ -if { ![info exists env(VIVADO_DESIGN_NAME)] } { - puts "Please set the environment variable VIVADO_DESIGN_NAME before running the script" - return -} -set design_name $::env(VIVADO_DESIGN_NAME) -puts "Using design name: ${design_name}" - -# Set SDK workspace -setws ./vivado/${design_name}/${design_name}.sdk -# get the file exported by vivado -set hdf_file [glob ./vivado/${design_name}/${design_name}.sdk/*.hdf] -set hdf_file_dir "[file normalize "$hdf_file/"]" -# get the full path -puts $hdf_file_dir - -# Create a HW project -set hw_dir ./vivado/${design_name}/${design_name}.sdk/hw1 -if {![file exist $hw_dir]} { - createhw -name hw1 -hwspec $hdf_file_dir -} else { - openhw hw1 -} -# Create a BSP project -set bsp_dir ./vivado/${design_name}/${design_name}.sdk/bsp1 -if {![file exist $bsp_dir]} { - createbsp -name bsp1 -hwproject hw1 -proc ps7_cortexa9_0 -os standalone -} else { - openbsp bsp1 -} - -# Each directory inside the src dir will become and xSDK's Application Project -set list_apps [glob -directory ./src/ -type d *] -puts "$list_apps" -# Now, build each application -foreach app_dir_name $list_apps { - # get the dir path, split it with '/', and then gets the last item of the list - # ATTENTION, it will only work on Linux path. fix it before using for windows - # perhaps a solution like this is sufficient, although a more OS-independt solution would be preferable - # https://stackoverflow.com/questions/3261467/run-common-tcl-script-on-windows-and-linux - set app_prj_name [lindex [split $app_dir_name "/"] end] - #puts "$app_prj_name" - # Create application project - set app_dir ./vivado/${design_name}/${design_name}.sdk/$app_prj_name - # if the app were created before, then we skip to the next one - if {[file exist $app_dir]} { - continue - } - createapp -name $app_prj_name -hwproject hw1 -bsp bsp1 -proc ps7_cortexa9_0 -os standalone -lang C -app {Empty Application} - # SDK does not allow to import sources with symbolic links. - # https://forums.xilinx.com/t5/Embedded-Development-Tools/xsdk-batch-import-sources-link-to-files/td-p/742063 - # So, it is necessary to import with copy and replace the copy by a symbolic link - importsources -name $app_prj_name -path $app_dir_name - # now it's necessary to list the files for their replacement by symbolic links - set source_files [glob $app_dir_name/*] - foreach path_file $source_files { - # get only the file name - set file_name [file tail $path_file] - #puts "$file_name" - exec rm ./vivado/${design_name}/${design_name}.sdk/$app_prj_name/src/$file_name - exec ln -s ../../../../../src/$app_prj_name/$file_name ./vivado/${design_name}/${design_name}.sdk/$app_prj_name/src/ - } -} - -# Build all projects -projects -build - diff --git a/src/readme b/src/readme deleted file mode 100644 index 84a1257..0000000 --- a/src/readme +++ /dev/null @@ -1,5 +0,0 @@ - -If this design uses processors and runs software applications, these applications should be here. -Create a subdir for each application. The name of the dir will be used to name the application. - -Dont place any other dir or file here. diff --git a/vivado/readme b/vivado/readme deleted file mode 100644 index d448319..0000000 --- a/vivado/readme +++ /dev/null @@ -1,9 +0,0 @@ - -This directory is a place holder for the Vivado projects. These projects are not supposed to -be under version control and will be discarded. Save anything relevant to the design. -It is useful to export the TCL of the design to get its configuration. This can be done in -Vivado's GUI via File -> Project -> Write TCL ... - -Dont place any other dir or file here. the .gitignore file deliberately ignores anything -inside this directory -